From 7d1e332d8cc048f7923cf4cb9dc87919fd700f33 Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Mon, 27 Feb 2017 20:14:03 -0600 Subject: [PATCH 001/418] Update documentation --- CHANGELOG.md | 2 +- GettingStarted.md | 46 ++++++++++++++++++++++------------------------ README.md | 8 ++++++-- 3 files changed, 29 insertions(+), 27 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b575e273..8e2c8c72 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,7 +9,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ### Added - Multiple `when` clauses in guards - Kernel.defdelegate/2 -- `js_modules` configuration option has been added. This is a keyword list of JavaScript modules that will be used. +- `js_modules` configuration option has been added. This is a list of JavaScript modules that will be used. ``` js_modules: [ {React, "react"}, diff --git a/GettingStarted.md b/GettingStarted.md index 3691d4ea..f3abfaca 100644 --- a/GettingStarted.md +++ b/GettingStarted.md @@ -29,27 +29,24 @@ This is the help output of elixirscript path to elixir files or the elixir code string if passed the -ex flag options: + --js-module [:] A js module used in your code. ex: React:react + Multiple can be defined -f --format [format] module format of output. options: es (default), common, umd -o --output [path] places output at the given path -ex --elixir read input as elixir code string --full-build informs the compiler to do a full build instead of an incremental one - --core-path import path to the elixirscript standard lib - only used with the [output] option. When used, Elixir.js is not exported -v --version the current version number -h --help this message the `` is the elixir code string or file path you want to convert from elixir to javascript. Below is an example of using a code string and turning it into JavaScript $ elixirscript ":atom" -ex - Symbol.for('atom') - -It changed the elixir code, `:atom` into the JavaScript code `Symbol.for('atom')`. The `-ex` parameter lets the script know that the input is an Elixir code string instead of a file. elixirscript also takes a path to your `.ex` files as well: $ elixirscript "src" -o "dist" -If you look in the dist folder, you should see 2 folders. `app` contains your code and `elixir` contains the elixirscript standard library files. +If you look in the dist folder you'll see a file called `Elixir.App.js` ### Mix dependency @@ -58,7 +55,7 @@ Adding Elixirscript to your mix project gives you the ability to add it to your Add dependency to your deps in mix.exs: ```elixir - {:elixir_script, "~> 0.25"} + {:elixir_script, "~> 0.26"} ``` Elixirscript uses default input, output and module formats if options are not given. If you wish to change any or all options, add an `elixir_script` key to your project configuration. @@ -69,7 +66,15 @@ Add dependency to your deps in mix.exs: version: "0.1.0", elixir: "~> 1.0", deps: deps, - elixir_script: [ input: "lib/elixirscript", output: "priv/elixirscript", format: :es], + elixir_script: [ + input: "lib/elixirscript", + output: "priv/elixirscript", + format: :es, + js_modules: [ + {React, "react"}, + {ReactDOM, "react-dom"} + ] + ], compilers: [:elixir_script] ++ Mix.compilers ] end @@ -88,6 +93,8 @@ Available options are: * `:umd` - UMD +* `js_modules`: A list of JavaScript imports to add. Each item must be 2-tuple or a 3-tuple. The third element is an optional keyword list of options. + ### Macros Elixirscript supports public macros. Private macros are currently unsupported. @@ -117,27 +124,18 @@ You can call globally scoped modules you would an Elixir module Only works if module begins with a captial letter -#### Importing Modules - -To import modules, first you must `require` the `JS` module. Then import the module using `JS.import` - - defmodule MyModule do - require JS - JS.import React, "react" - - def func() do - React.render(my_component) - end - end - #### The JS module The JS module has many other functions and macros. For more information, check out the docs. #### Frontend Project Boilerplate -There is an [elixirscript frontend boilerplate project](https://github.com/bryanjos/elixirscript-project-boilerplate). This setup uses gulp and webpack to build and bundle assets. +There is an [elixirscript frontend boilerplate project](https://github.com/elixirscript/elixirscript-project-boilerplate). This setup uses gulp and webpack to build and bundle assets. + +#### elixirscript-brunch + +There is an Brunch plugin, [elixirscript-brunch](https://www.npmjs.com/package/elixirscript-brunch). -#### ElixirScript-Brunch +#### -There is an Brunch plugin, [ElixirScript-Brunch](https://www.npmjs.com/package/elixirscript-brunch). There are instructions there on how to use it with Phoenix. \ No newline at end of file +There is also a webpack loader, [elixirscript-loader](https://www.npmjs.com/package/elixirscript-loader). \ No newline at end of file diff --git a/README.md b/README.md index dce8097d..89ca4c9f 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ ## ElixirScript [![Documentation](https://img.shields.io/badge/docs-hexpm-blue.svg)](http://hexdocs.pm/elixir_script/) [![Build](https://travis-ci.org/elixirscript/elixirscript.svg?branch=master)](https://travis-ci.org/elixirscript/elixirscript) [![Deps Status](https://beta.hexfaktor.org/badge/all/github/bryanjos/elixirscript.svg)](https://beta.hexfaktor.org/github/bryanjos/elixirscript) [![Join the chat at https://gitter.im/elixirscript/elixirscript](https://badges.gitter.im/elixirscript/elixirscript.svg)](https://gitter.im/elixirscript/elixirscript?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) -The goal is to convert a subset (or full set) of Elixir code to JavaScript, providing the ability to write JavaScript in Elixir. This is done by taking the Elixir AST and converting it into JavaScript AST and then to JavaScript code. This is done using the [Elixir-ESTree](https://github.com/bryanjos/elixir-estree) library. +The goal is to convert a subset (or full set) of Elixir code to JavaScript, providing the ability to write JavaScript in Elixir. This is done by taking the Elixir AST and converting it into JavaScript AST and then to JavaScript code. This is done using the [Elixir-ESTree](https://github.com/elixirscript/elixir-estree) library. Requirements =========== @@ -65,7 +65,7 @@ Please check the [CONTRIBUTING.md](CONTRIBUTING.md) ### Example projects * [hello](https://github.com/bryanjos/hello) Shows using Phoenix + Elixirscript with file watching -* [Elixirscript frontend boilerplate](https://github.com/bryanjos/elixirscript-project-boilerplate) A boilerplate project for elixirscript frontends +* [Elixirscript frontend boilerplate](https://github.com/elixirscript/elixirscript-project-boilerplate) A boilerplate project for elixirscript frontends * [Elixirscript React example](https://github.com/bryanjos/elixirscript_react) An example of using with React * [Elixirscript AWS Lambda example](https://github.com/bryanjos/elixirscript_lambda) @@ -73,5 +73,9 @@ Please check the [CONTRIBUTING.md](CONTRIBUTING.md) There is a plugin for using ElixirScript in your Brunch project [here](https://www.npmjs.com/package/elixirscript-brunch) +#### Using with Webpack +There is a loader for using ElixirScript in your Webpack project +[here](https://www.npmjs.com/package/elixirscript-loader) + #### 1.0 Roadmap There is a [1.0.0 Milestone](https://github.com/bryanjos/elixirscript/milestones/1.0.0) defined which includes issues that are needed to be cleared before 1.0 can be reached. From 4d491efe0371af45bbe2168b19fb54ca71cc3297 Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Mon, 27 Feb 2017 20:17:54 -0600 Subject: [PATCH 002/418] Update GettingStarted --- GettingStarted.md | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/GettingStarted.md b/GettingStarted.md index f3abfaca..ac7b68c0 100644 --- a/GettingStarted.md +++ b/GettingStarted.md @@ -48,6 +48,26 @@ elixirscript also takes a path to your `.ex` files as well: If you look in the dist folder you'll see a file called `Elixir.App.js` +To start your application import the bundle according to whichever module format was selected and +then call start giving it the module and the initial args. + +Ex. If you have a module like so +```elixir +defmodule Example do + start(type, args) do + :console.log("Hello, world") + end +end +``` + +You would start it like so + +```javascript +//ES module example +import Elixir from './Elixir.App' +Elixir.start(Elixir.Example, []) +``` + ### Mix dependency Adding Elixirscript to your mix project gives you the ability to add it to your list of mix compilers. This means when you `mix compile`, Elixirscript will compile your code as well. From e972eab28d234173a648e82b889aac1e6ce8d8ae Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Mon, 27 Feb 2017 20:24:08 -0600 Subject: [PATCH 003/418] Update for translation --- CHANGELOG.md | 6 ++++++ .../translator/kernel/special_forms/for.ex | 11 ++++++++++- mix.exs | 2 +- package.json | 4 ++-- test/translator/for_test.exs | 14 +++++++------- 5 files changed, 26 insertions(+), 11 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8e2c8c72..574e2052 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/) and this project adheres to [Semantic Versioning](http://semver.org/). +## [0.26.1] - 2017-02-27 + +### Fixed +- Fixed `for` translation +- Updated documentation + ## [0.26.0] - 2017-02-27 ### Added diff --git a/lib/elixir_script/translator/kernel/special_forms/for.ex b/lib/elixir_script/translator/kernel/special_forms/for.ex index 45c076da..3c6293e4 100644 --- a/lib/elixir_script/translator/kernel/special_forms/for.ex +++ b/lib/elixir_script/translator/kernel/special_forms/for.ex @@ -6,6 +6,7 @@ defmodule ElixirScript.Translator.For do alias ElixirScript.Translator.Primitive alias ElixirScript.Translator.Function alias ElixirScript.Translator.Utils + alias ElixirScript.Translator.Identifier def make_for(generators, env) do ElixirScript.Translator.State.add_module_reference(env.state, env.module, ElixirScript.Collectable) @@ -17,6 +18,14 @@ defmodule ElixirScript.Translator.For do filter = args.filter || JS.function_expression([], [], JS.block_statement([JS.return_statement(JS.identifier("true"))])) fun = args.fun + members = ["Elixir"] ++ Module.split(ElixirScript.Collectable) ++ ["__load"] + + collectable_module = JS.call_expression( + Identifier.make_namespace_members(members), + [JS.identifier("Elixir")] + ) + + expression = JS.call_expression( JS.member_expression( JS.member_expression( @@ -36,7 +45,7 @@ defmodule ElixirScript.Translator.For do Primitive.special_forms(), JS.identifier("_for") ), - [expression, generators, JS.identifier(Utils.name_to_js_name(ElixirScript.Collectable)), into] + [expression, generators, collectable_module, into] ) {js_ast, env} diff --git a/mix.exs b/mix.exs index 7369fd35..1b14c0dd 100644 --- a/mix.exs +++ b/mix.exs @@ -4,7 +4,7 @@ defmodule ElixirScript.Mixfile do def project do [ app: :elixir_script, - version: "0.26.0", + version: "0.26.1", elixir: "~> 1.0", elixirc_paths: elixirc_paths(), escript: escript_config(), diff --git a/package.json b/package.json index efbbd8d5..5387ddfb 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "elixirscript", - "version": "0.25.0", + "version": "0.26.1", "description": "Convert Elixir to JavaScript", "main": "elixir.js", "bin": { @@ -44,4 +44,4 @@ "rollup-plugin-node-resolve": "^2.0.0", "rollup-plugin-uglify": "^1.0.1" } -} +} \ No newline at end of file diff --git a/test/translator/for_test.exs b/test/translator/for_test.exs index faec216e..6826d704 100644 --- a/test/translator/for_test.exs +++ b/test/translator/for_test.exs @@ -24,7 +24,7 @@ defmodule ElixirScript.Translator.For.Test do Object.freeze([1, 2, 3, 4]) ) ], - Elixir$ElixirScript$Collectable, + Elixir.ElixirScript.Collectable.__load(Elixir), Object.freeze([]) ) """ @@ -54,7 +54,7 @@ defmodule ElixirScript.Translator.For.Test do Object.freeze([1, 2, 3, 4]) ) ], - Elixir$ElixirScript$Collectable, + Elixir.ElixirScript.Collectable.__load(Elixir), Object.freeze([]) ) """ @@ -88,7 +88,7 @@ defmodule ElixirScript.Translator.For.Test do Object.freeze([2, 3]) ) ], - Elixir$ElixirScript$Collectable, + Elixir.ElixirScript.Collectable.__load(Elixir), Object.freeze([]) ) """ @@ -126,7 +126,7 @@ defmodule ElixirScript.Translator.For.Test do Object.freeze([2, 3]) ) ], - Elixir$ElixirScript$Collectable, + Elixir.ElixirScript.Collectable.__load(Elixir), Object.freeze([]) ) ); @@ -157,7 +157,7 @@ defmodule ElixirScript.Translator.For.Test do Object.freeze([1, 2, 3, 4, 5, 6]) ) ], - Elixir$ElixirScript$Collectable, + Elixir.ElixirScript.Collectable.__load(Elixir), Object.freeze([]) ) """ @@ -186,7 +186,7 @@ defmodule ElixirScript.Translator.For.Test do values: [Symbol.for('user'), Bootstrap.Core.Patterns.variable()] }), Object.freeze([new Bootstrap.Core.Tuple(Symbol.for('user'), 'john'), new Bootstrap.Core.Tuple(Symbol.for('admin'), 'john'), new Bootstrap.Core.Tuple(Symbol.for('user'), 'meg')])) ], - Elixir$ElixirScript$Collectable, + Elixir.ElixirScript.Collectable.__load(Elixir), Object.freeze([])) """ @@ -218,7 +218,7 @@ defmodule ElixirScript.Translator.For.Test do 'value': Bootstrap.Core.Patterns.variable() }, 8), Bootstrap.Core.BitString.size({ 'value': Bootstrap.Core.Patterns.variable() - }, 8)), pixels)], Elixir$ElixirScript$Collectable, Object.freeze([])) + }, 8)), pixels)], Elixir.ElixirScript.Collectable.__load(Elixir), Object.freeze([])) """ assert_translation(ex_ast, js_code) From 1d0d512a5d5b6669c512728ccbefbcafe30aa5d8 Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Tue, 28 Feb 2017 10:18:14 -0600 Subject: [PATCH 004/418] Update FAQ.md --- FAQ.md | 1 - 1 file changed, 1 deletion(-) diff --git a/FAQ.md b/FAQ.md index 107cd895..dbc25aae 100644 --- a/FAQ.md +++ b/FAQ.md @@ -59,7 +59,6 @@ The compiler to this point has been focused on translating Kernel.SpecialForms a * List * Atom * Range - * Logger * Map * MapSet From 8c6d35bd31f83526b770059b7388967bfba07194 Mon Sep 17 00:00:00 2001 From: Stephan van Diepen Date: Sat, 4 Mar 2017 18:48:47 +0100 Subject: [PATCH 005/418] Rename -ex alias to -e for --elixir --- GettingStarted.md | 6 +++--- lib/elixir_script/cli.ex | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/GettingStarted.md b/GettingStarted.md index ac7b68c0..8d771930 100644 --- a/GettingStarted.md +++ b/GettingStarted.md @@ -27,20 +27,20 @@ This is the help output of elixirscript usage: elixirscript [options] path to elixir files or - the elixir code string if passed the -ex flag + the elixir code string if passed the -e flag options: --js-module [:] A js module used in your code. ex: React:react Multiple can be defined -f --format [format] module format of output. options: es (default), common, umd -o --output [path] places output at the given path - -ex --elixir read input as elixir code string + -e --elixir read input as elixir code string --full-build informs the compiler to do a full build instead of an incremental one -v --version the current version number -h --help this message the `` is the elixir code string or file path you want to convert from elixir to javascript. Below is an example of using a code string and turning it into JavaScript - $ elixirscript ":atom" -ex + $ elixirscript ":atom" -e elixirscript also takes a path to your `.ex` files as well: diff --git a/lib/elixir_script/cli.ex b/lib/elixir_script/cli.ex index 44e03ed1..5cb750a6 100644 --- a/lib/elixir_script/cli.ex +++ b/lib/elixir_script/cli.ex @@ -10,7 +10,7 @@ defmodule ElixirScript.CLI do ] @aliases [ - o: :output, ex: :elixir, h: :help, v: :version, f: :format + o: :output, e: :elixir, h: :help, v: :version, f: :format ] def main(argv) do @@ -41,14 +41,14 @@ defmodule ElixirScript.CLI do """ usage: elixirscript [options] path to elixir files or - the elixir code string if passed the -ex flag + the elixir code string if passed the -e flag options: --js-module [:] A js module used in your code. ex: React:react Multiple can be defined -f --format [format] module format of output. options: es (default), common, umd -o --output [path] places output at the given path - -ex --elixir read input as elixir code string + -e --elixir read input as elixir code string --full-build informs the compiler to do a full build instead of an incremental one -v --version the current version number -h --help this message From 74e20cb9bb65108d30c16d12788773051a8d0dcf Mon Sep 17 00:00:00 2001 From: Stephan van Diepen Date: Sat, 4 Mar 2017 18:51:18 +0100 Subject: [PATCH 006/418] Add spec for CLI --- test/cli_test.exs | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 test/cli_test.exs diff --git a/test/cli_test.exs b/test/cli_test.exs new file mode 100644 index 00000000..10711ba9 --- /dev/null +++ b/test/cli_test.exs @@ -0,0 +1,9 @@ +defmodule ElixirScript.CLI.Test do + use ExUnit.Case + import ElixirScript.TestHelper + + test "parse_args -e expands to elixir" do + {_, args} = ElixirScript.CLI.parse_args(["1 + 1", "-e"]) + assert args == [elixir: true] + end +end From 340a0e5c5e3a98032e216f4c20a25985ff72bf7e Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Sat, 4 Mar 2017 14:54:12 -0600 Subject: [PATCH 007/418] Allow naming of js file --- lib/elixir_script/passes/handle_output.ex | 18 ++++++++++++++++-- test/cli_test.exs | 1 - test/passes/handle_output_test.exs | 21 +++++++++++++++++++++ 3 files changed, 37 insertions(+), 3 deletions(-) create mode 100644 test/passes/handle_output_test.exs diff --git a/lib/elixir_script/passes/handle_output.ex b/lib/elixir_script/passes/handle_output.ex index 56512ac8..b9e10900 100644 --- a/lib/elixir_script/passes/handle_output.ex +++ b/lib/elixir_script/passes/handle_output.ex @@ -26,7 +26,9 @@ defmodule ElixirScript.Passes.HandleOutput do end defp out(compiler_output, %{output: output_path, core_path: _} = compiler_opts) do - file_name = Path.join([output_path, @generated_name]) + js_name = get_js_name(output_path) + + file_name = Path.join([output_path, js_name]) if !File.exists?(Path.dirname(file_name)) do File.mkdir_p!(Path.dirname(file_name)) @@ -39,10 +41,22 @@ defmodule ElixirScript.Passes.HandleOutput do "'use strict';\n" <> ElixirScript.get_bootstrap_js("iife") <> "\n" <> code end + def get_js_name(nil), do: @generated_name + def get_js_name(:stdout), do: @generated_name + + def get_js_name(output_path) do + case Path.extname(output_path) do + ".js" -> + Path.basename(output_path) + _ -> + @generated_name + end + end + defp process_include_path(compiler_output, compiler_opts) do case compiler_opts.include_path do true -> - {compiler_output.generated, @generated_name} + {compiler_output.generated, get_js_name(compiler_opts.output)} false -> compiler_output.generated end diff --git a/test/cli_test.exs b/test/cli_test.exs index 10711ba9..6fab0232 100644 --- a/test/cli_test.exs +++ b/test/cli_test.exs @@ -1,6 +1,5 @@ defmodule ElixirScript.CLI.Test do use ExUnit.Case - import ElixirScript.TestHelper test "parse_args -e expands to elixir" do {_, args} = ElixirScript.CLI.parse_args(["1 + 1", "-e"]) diff --git a/test/passes/handle_output_test.exs b/test/passes/handle_output_test.exs new file mode 100644 index 00000000..53c8c11f --- /dev/null +++ b/test/passes/handle_output_test.exs @@ -0,0 +1,21 @@ +defmodule ElixirScript.Passes.HandleOutput.Test do + use ExUnit.Case + alias ElixirScript.Passes.HandleOutput + + test "get_js_name output: nil" do + assert HandleOutput.get_js_name(nil) == "Elixir.App.js" + end + + test "get_js_name output: stdout" do + assert HandleOutput.get_js_name(:stdout) == "Elixir.App.js" + end + + test "get_js_name output is directory" do + assert HandleOutput.get_js_name("/path/to/file/") == "Elixir.App.js" + assert HandleOutput.get_js_name("/path/to/file") == "Elixir.App.js" + end + + test "get_js_name output ends in js" do + assert HandleOutput.get_js_name("/path/to/file/myfile.js") == "myfile.js" + end +end \ No newline at end of file From e215e208f64b819de8870292ff1b2d6bf98ddb4d Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Sat, 4 Mar 2017 14:59:11 -0600 Subject: [PATCH 008/418] Fix pathing bug when filename given --- lib/elixir_script/passes/handle_output.ex | 16 +++++++--------- test/passes/handle_output_test.exs | 18 +++++++++--------- 2 files changed, 16 insertions(+), 18 deletions(-) diff --git a/lib/elixir_script/passes/handle_output.ex b/lib/elixir_script/passes/handle_output.ex index b9e10900..30ae42c0 100644 --- a/lib/elixir_script/passes/handle_output.ex +++ b/lib/elixir_script/passes/handle_output.ex @@ -26,9 +26,7 @@ defmodule ElixirScript.Passes.HandleOutput do end defp out(compiler_output, %{output: output_path, core_path: _} = compiler_opts) do - js_name = get_js_name(output_path) - - file_name = Path.join([output_path, js_name]) + file_name = get_js_path(output_path) if !File.exists?(Path.dirname(file_name)) do File.mkdir_p!(Path.dirname(file_name)) @@ -41,22 +39,22 @@ defmodule ElixirScript.Passes.HandleOutput do "'use strict';\n" <> ElixirScript.get_bootstrap_js("iife") <> "\n" <> code end - def get_js_name(nil), do: @generated_name - def get_js_name(:stdout), do: @generated_name + def get_js_path(nil), do: @generated_name + def get_js_path(:stdout), do: @generated_name - def get_js_name(output_path) do + def get_js_path(output_path) do case Path.extname(output_path) do ".js" -> - Path.basename(output_path) + output_path _ -> - @generated_name + Path.join([output_path, @generated_name]) end end defp process_include_path(compiler_output, compiler_opts) do case compiler_opts.include_path do true -> - {compiler_output.generated, get_js_name(compiler_opts.output)} + {compiler_output.generated, get_js_path(compiler_opts.output)} false -> compiler_output.generated end diff --git a/test/passes/handle_output_test.exs b/test/passes/handle_output_test.exs index 53c8c11f..8691a6be 100644 --- a/test/passes/handle_output_test.exs +++ b/test/passes/handle_output_test.exs @@ -2,20 +2,20 @@ defmodule ElixirScript.Passes.HandleOutput.Test do use ExUnit.Case alias ElixirScript.Passes.HandleOutput - test "get_js_name output: nil" do - assert HandleOutput.get_js_name(nil) == "Elixir.App.js" + test "get_js_path output: nil" do + assert HandleOutput.get_js_path(nil) == "Elixir.App.js" end - test "get_js_name output: stdout" do - assert HandleOutput.get_js_name(:stdout) == "Elixir.App.js" + test "get_js_path output: stdout" do + assert HandleOutput.get_js_path(:stdout) == "Elixir.App.js" end - test "get_js_name output is directory" do - assert HandleOutput.get_js_name("/path/to/file/") == "Elixir.App.js" - assert HandleOutput.get_js_name("/path/to/file") == "Elixir.App.js" + test "get_js_path output is directory" do + assert HandleOutput.get_js_path("/path/to/file/") == "/path/to/file/Elixir.App.js" + assert HandleOutput.get_js_path("/path/to/file") == "/path/to/file/Elixir.App.js" end - test "get_js_name output ends in js" do - assert HandleOutput.get_js_name("/path/to/file/myfile.js") == "myfile.js" + test "get_js_path output ends in js" do + assert HandleOutput.get_js_path("/path/to/file/myfile.js") == "/path/to/file/myfile.js" end end \ No newline at end of file From afb69a4299f5f42da4f76cee27a5b140237b9cb9 Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Sat, 4 Mar 2017 15:10:44 -0600 Subject: [PATCH 009/418] Update changelog. Update docs on CLI and mix compile task --- CHANGELOG.md | 6 ++++++ GettingStarted.md | 12 ++++++++---- lib/elixir_script/cli.ex | 3 ++- lib/mix/tasks/compile.elixir_script.ex | 7 +++++-- mix.exs | 2 +- 5 files changed, 22 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 574e2052..c7ba7e10 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/) and this project adheres to [Semantic Versioning](http://semver.org/). +## [0.27.0-dev] + +### Changed +- `-ex` alias is now `-e` +- A filename can be specified for output + ## [0.26.1] - 2017-02-27 ### Fixed diff --git a/GettingStarted.md b/GettingStarted.md index 8d771930..edb35f79 100644 --- a/GettingStarted.md +++ b/GettingStarted.md @@ -31,8 +31,9 @@ This is the help output of elixirscript options: --js-module [:] A js module used in your code. ex: React:react Multiple can be defined - -f --format [format] module format of output. options: es (default), common, umd - -o --output [path] places output at the given path + -f --format [format] module format of output. options: es (default), common, umd + -o --output [path] places output at the given path. + Can be a directory or filename. -e --elixir read input as elixir code string --full-build informs the compiler to do a full build instead of an incremental one -v --version the current version number @@ -88,7 +89,7 @@ Add dependency to your deps in mix.exs: deps: deps, elixir_script: [ input: "lib/elixirscript", - output: "priv/elixirscript", + output: "priv/elixirscript/Elixir.App.js", format: :es, js_modules: [ {React, "react"}, @@ -103,7 +104,10 @@ Available options are: * `input`: The folder to look for Elixirscript files in. (defaults to `lib/elixirscript`) -* `output`: The folder to place generated JavaScript code in. (defaults to `priv/elixirscript`) +* `output`: The path of the generated JavaScript file. (defaults to `priv/elixirscript`) + + If path ends in `.js` then that will be the name of the file. If a directory is given, + file will be named `Elixir.App.js` * `format`: The module format of generated JavaScript code. (defaults to `:es`). Choices are:     diff --git a/lib/elixir_script/cli.ex b/lib/elixir_script/cli.ex index 5cb750a6..e4bbb67e 100644 --- a/lib/elixir_script/cli.ex +++ b/lib/elixir_script/cli.ex @@ -47,7 +47,8 @@ defmodule ElixirScript.CLI do --js-module [:] A js module used in your code. ex: React:react Multiple can be defined -f --format [format] module format of output. options: es (default), common, umd - -o --output [path] places output at the given path + -o --output [path] places output at the given path. + Can be a directory or filename. -e --elixir read input as elixir code string --full-build informs the compiler to do a full build instead of an incremental one -v --version the current version number diff --git a/lib/mix/tasks/compile.elixir_script.ex b/lib/mix/tasks/compile.elixir_script.ex index e5d33169..df25aaa7 100644 --- a/lib/mix/tasks/compile.elixir_script.ex +++ b/lib/mix/tasks/compile.elixir_script.ex @@ -19,7 +19,10 @@ defmodule Mix.Tasks.Compile.ElixirScript do Available options are: * `input`: The folder to look for Elixirscript files in. (defaults to `lib/elixirscript`) - * `output`: The folder to place generated JavaScript code in. (defaults to `priv/elixirscript`) + * `output`: The path of the generated JavaScript file. (defaults to `priv/elixirscript`) + + If path ends in `.js` then that will be the name of the file. If a directory is given, + file will be named `Elixir.App.js` * `format`: The module format of generated JavaScript code. (defaults to `:es`). Choices are: * `:es` - ES Modules @@ -70,7 +73,7 @@ defmodule Mix.Tasks.Compile.ElixirScript do elixirscript_config = get_elixirscript_config() output_path = Keyword.get(elixirscript_config, :output) - path = Path.join([output_path, "Elixir.App.js"]) + path = ElixirScript.Passes.HandleOutput.get_js_path(output_path) if File.exists?(path) do File.rm!(path) diff --git a/mix.exs b/mix.exs index 1b14c0dd..c95354bf 100644 --- a/mix.exs +++ b/mix.exs @@ -4,7 +4,7 @@ defmodule ElixirScript.Mixfile do def project do [ app: :elixir_script, - version: "0.26.1", + version: "0.27.0-dev", elixir: "~> 1.0", elixirc_paths: elixirc_paths(), escript: escript_config(), From a09d6912ebb88be816ee08814c632d426551fd55 Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Sat, 4 Mar 2017 15:29:37 -0600 Subject: [PATCH 010/418] Track module reference use --- lib/elixir_script/passes/handle_output.ex | 2 +- .../translator/kernel/defmodule.ex | 6 -- lib/elixir_script/translator/kernel/js.ex | 19 +----- lib/elixir_script/translator/state.ex | 65 ++++--------------- 4 files changed, 14 insertions(+), 78 deletions(-) diff --git a/lib/elixir_script/passes/handle_output.ex b/lib/elixir_script/passes/handle_output.ex index 30ae42c0..a3bab884 100644 --- a/lib/elixir_script/passes/handle_output.ex +++ b/lib/elixir_script/passes/handle_output.ex @@ -25,7 +25,7 @@ defmodule ElixirScript.Passes.HandleOutput do IO.write(concat(code)) end - defp out(compiler_output, %{output: output_path, core_path: _} = compiler_opts) do + defp out(compiler_output, %{output: output_path, core_path: _}) do file_name = get_js_path(output_path) if !File.exists?(Path.dirname(file_name)) do diff --git a/lib/elixir_script/translator/kernel/defmodule.ex b/lib/elixir_script/translator/kernel/defmodule.ex index 17f1c7c1..d51e62a9 100644 --- a/lib/elixir_script/translator/kernel/defmodule.ex +++ b/lib/elixir_script/translator/kernel/defmodule.ex @@ -78,12 +78,6 @@ defmodule ElixirScript.Translator.Defmodule do {body, exported_object} end - def process_module_refs(module_refs, env) do - Enum.map(module_refs, fn(x) -> - {x, ""} - end) - end - def translate_body(body, env) do { body, env } = Translator.translate(body, env) diff --git a/lib/elixir_script/translator/kernel/js.ex b/lib/elixir_script/translator/kernel/js.ex index 27acde1d..1d7dc8ad 100644 --- a/lib/elixir_script/translator/kernel/js.ex +++ b/lib/elixir_script/translator/kernel/js.ex @@ -3,8 +3,6 @@ defmodule ElixirScript.Translator.JS do alias ESTree.Tools.Builder alias ElixirScript.Translator - alias ElixirScript.Translator.Identifier - alias ElixirScript.Translator.State @doc false def translate_js_function(name, params, env) do @@ -35,7 +33,7 @@ defmodule ElixirScript.Translator.JS do ) end - defp do_translate({:yield, _, []}, env) do + defp do_translate({:yield, _, []}, _) do Builder.yield_expression() end @@ -80,21 +78,6 @@ defmodule ElixirScript.Translator.JS do Translator.translate!(quoted, env) end - defp do_translate({:import, _, [module_name, from, [default: false]]}, env) do - State.add_javascript_module_reference(env.state, env.module, module_name, from, false) - %ElixirScript.Translator.Empty{} - end - - defp do_translate({:import, _, [module_name, from, [default: true]]}, env) do - State.add_javascript_module_reference(env.state, env.module, module_name, from, true) - %ElixirScript.Translator.Empty{} - end - - defp do_translate({:import, _, [module_name, from]}, env) do - State.add_javascript_module_reference(env.state, env.module, module_name, from, true) - %ElixirScript.Translator.Empty{} - end - defp do_translate({:object, _, [args]}, env) do args = Enum.map(args, fn { k, v } when Kernel.is_atom(k) -> diff --git a/lib/elixir_script/translator/state.ex b/lib/elixir_script/translator/state.ex index 25d038a0..85aec85c 100644 --- a/lib/elixir_script/translator/state.ex +++ b/lib/elixir_script/translator/state.ex @@ -15,34 +15,6 @@ defmodule ElixirScript.Translator.State do end) end - def serialize(pid) do - Agent.get(pid, fn(state) -> - modules = state.modules - modules = Enum.map(modules, fn {m, d} -> - d = Map.delete(d, :javascript_ast) - |> Map.delete(:javascript_module) - |> Map.delete(:javascript_code) - |> Map.delete(:javascript_name) - - {m, d} - end) - |> Enum.filter(fn {_, d} -> d.type != :consolidated end) - - state = Map.delete(state, :changed_modules) - |> Map.put(:modules, modules) - - :erlang.term_to_binary(state) - end) - end - - def deserialize(pid, frozen_state, loaded_modules \\ []) do - Agent.update(pid, fn state -> - frozen_state = :erlang.binary_to_term(frozen_state) - modules = Keyword.delete(frozen_state.modules, ElixirScript.Temp) - %{ state | modules: modules, std_lib_map: frozen_state.std_lib_map, loaded_modules: [JS | loaded_modules] } - end) - end - defp build_standard_lib_map() do Map.new |> Map.put(Kernel, ElixirScript.Kernel) @@ -141,11 +113,11 @@ defmodule ElixirScript.Translator.State do def add_module_reference(pid, module_name, module_ref) do Agent.update(pid, fn(state) -> - case Keyword.get(state.modules, do_get_module_name(module_name, state)) do + case Keyword.get(state.modules, do_get_module_name(module_ref, state)) do nil -> state module -> - module = Map.update(module, :deps, [module_ref], fn(x) -> Enum.uniq(x ++ [module_ref]) end) + module = Map.update(module, :refs, [module_name], fn(x) -> Enum.uniq(x ++ [module_name]) end) modules = Keyword.put(state.modules, module.name, module) %{ state | modules: modules } end @@ -157,10 +129,18 @@ defmodule ElixirScript.Translator.State do nil -> [] module -> - Map.get(module, :deps, []) + Map.get(module, :refs, []) end end + def list_module_references(pid) do + Agent.get(pid, fn(state) -> + Enum.map(state.modules, fn {name, module} -> + {name, Map.get(module, :refs, [])} + end) + end) + end + def list_modules(pid) do Agent.get(pid, fn(state) -> Keyword.values(state.modules) @@ -176,26 +156,5 @@ defmodule ElixirScript.Translator.State do def stop(pid) do Agent.stop(pid) end - - def add_javascript_module_reference(pid, module_name, name, path, default \\ true) do - Agent.update(pid, fn(state) -> - case Keyword.get(state.modules, do_get_module_name(module_name, state)) do - nil -> - state - module -> - module = Map.update(module, :js_modules, [{name, path, default}], fn(x) -> Enum.uniq(x ++ [{name, path, default}]) end) - modules = Keyword.put(state.modules, module.name, module) - %{ state | modules: modules } - end - end) - end - - def get_javascript_module_references(pid, module_name) do - case get_module(pid, module_name) do - nil -> - [] - module -> - Map.get(module, :js_modules, []) - end - end end + From 9350d23f15b61b8b23089237f8b7389751783139 Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Sat, 4 Mar 2017 15:54:09 -0600 Subject: [PATCH 011/418] Add __table to root object --- mix.exs | 2 ++ src/javascript/lib/core/functions.js | 40 +++++++++++++++------------- 2 files changed, 24 insertions(+), 18 deletions(-) diff --git a/mix.exs b/mix.exs index c95354bf..e089a658 100644 --- a/mix.exs +++ b/mix.exs @@ -79,6 +79,8 @@ defmodule ElixirScript.Mixfile do File.rm_rf(dist_folder) end + System.cmd("npm", ["run", "build"]) + File.mkdir_p(folder_name <> "/bin") File.cp!("elixirscript", "#{folder_name}/bin/elixirscript") if File.exists?("priv/.DS_Store") do diff --git a/src/javascript/lib/core/functions.js b/src/javascript/lib/core/functions.js index 4ba9945f..8b09d2f0 100644 --- a/src/javascript/lib/core/functions.js +++ b/src/javascript/lib/core/functions.js @@ -1,14 +1,14 @@ -import Protocol from "./protocol"; -import Core from "../core"; +import Protocol from './protocol'; +import Core from '../core'; function call_property(item, property) { let prop = null; if ( - typeof item === "number" || - typeof item === "symbol" || - typeof item === "boolean" || - typeof item === "string" + typeof item === 'number' || + typeof item === 'symbol' || + typeof item === 'boolean' || + typeof item === 'string' ) { if (item[property] !== undefined) { prop = property; @@ -50,15 +50,15 @@ function contains(left, right) { } function get_global() { - if (typeof self !== "undefined") { + if (typeof self !== 'undefined') { return self; - } else if (typeof window !== "undefined") { + } else if (typeof window !== 'undefined') { return window; - } else if (typeof global !== "undefined") { + } else if (typeof global !== 'undefined') { return global; } - throw new Error("No global state found"); + throw new Error('No global state found'); } function defstruct(defaults) { @@ -78,7 +78,7 @@ function defstruct(defaults) { function defexception(defaults) { return class extends Error { constructor(update = {}) { - const message = update.message || ""; + const message = update.message || ''; super(message); const the_values = Object.assign(defaults, update); @@ -86,7 +86,7 @@ function defexception(defaults) { this.name = this.constructor.name; this.message = message; - this[Symbol.for("__exception__")] = true; + this[Symbol.for('__exception__')] = true; Error.captureStackTrace(this, this.constructor.name); } @@ -148,7 +148,7 @@ function update_map(map, property, value) { return add_property_to_map(map, property, value); } - throw "map does not have key"; + throw 'map does not have key'; } function bnot(expr) { @@ -309,9 +309,9 @@ function reverse(list) { function maps_find(key, map) { if (key in get_object_keys(map)) { - return new Core.Tuple(Symbol.for("ok"), map[key]); + return new Core.Tuple(Symbol.for('ok'), map[key]); } - return Symbol.for("error"); + return Symbol.for('error'); } function flatten(list, tail = []) { @@ -378,21 +378,25 @@ function maps_fold(fun, acc, map) { } function build_namespace(ns, ns_string) { - let parts = ns_string.split("."); + let parts = ns_string.split('.'); + const root = ns; let parent = ns; - if (parts[0] === "Elixir") { + if (parts[0] === 'Elixir') { parts = parts.slice(1); } for (const part of parts) { - if (typeof parent[part] === "undefined") { + if (typeof parent[part] === 'undefined') { parent[part] = {}; } parent = parent[part]; } + root.__table = ns.__table || {}; + root.__table[Symbol.for(ns_string)] = parent; + return parent; } From 8a854b612260da503cfb5d2cff488c9bee27582b Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Sat, 4 Mar 2017 18:10:43 -0600 Subject: [PATCH 012/418] Add support for super for defoverridable --- CHANGELOG.md | 4 + FAQ.md | 2 +- lib/elixir_script.ex | 15 ++-- .../passes/handle_overridables.ex | 86 +++++++++++++++++++ lib/elixir_script/translator.ex | 7 ++ priv/std_lib/keyword.ex | 4 + 6 files changed, 109 insertions(+), 9 deletions(-) create mode 100644 lib/elixir_script/passes/handle_overridables.ex diff --git a/CHANGELOG.md b/CHANGELOG.md index c7ba7e10..1f6689ef 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,10 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ## [0.27.0-dev] +### Added +- `super` +- `defoverridable` + ### Changed - `-ex` alias is now `-e` - A filename can be specified for output diff --git a/FAQ.md b/FAQ.md index dbc25aae..3c2ad53e 100644 --- a/FAQ.md +++ b/FAQ.md @@ -38,9 +38,9 @@ The compiler to this point has been focused on translating Kernel.SpecialForms a * `alias` * `__CALLER__` * `__ENV__` + * `super(args)` * Missing - * `super(args)` * `receive` * Caveats diff --git a/lib/elixir_script.ex b/lib/elixir_script.ex index 659fa607..fd218c7c 100644 --- a/lib/elixir_script.ex +++ b/lib/elixir_script.ex @@ -75,8 +75,14 @@ defmodule ElixirScript do %{data: std_lib_quoted ++ data} |> ElixirScript.Passes.Init.execute(opts) + |> shared_passes(opts) + end + + defp shared_passes(compiler_data, opts) do + compiler_data |> ElixirScript.Passes.FindModules.execute(opts) |> ElixirScript.Passes.FindLoadOnly.execute(opts) + |> ElixirScript.Passes.HandleOverridables.execute(opts) |> ElixirScript.Passes.FindFunctions.execute(opts) |> ElixirScript.Passes.JavaScriptAST.execute(opts) |> ElixirScript.Passes.ConsolidateProtocols.execute(opts) @@ -164,14 +170,7 @@ defmodule ElixirScript do |> ElixirScript.Passes.Init.execute(opts) |> ElixirScript.Passes.ASTFromFile.execute(opts) |> ElixirScript.Passes.LoadModules.execute(opts) - |> ElixirScript.Passes.FindModules.execute(opts) - |> ElixirScript.Passes.FindLoadOnly.execute(opts) - |> ElixirScript.Passes.FindFunctions.execute(opts) - |> ElixirScript.Passes.JavaScriptAST.execute(opts) - |> ElixirScript.Passes.ConsolidateProtocols.execute(opts) - |> ElixirScript.Passes.CreateJSModules.execute(opts) - |> ElixirScript.Passes.JavaScriptCode.execute(opts) - |> ElixirScript.Passes.HandleOutput.execute(opts) + |> shared_passes(opts) result end diff --git a/lib/elixir_script/passes/handle_overridables.ex b/lib/elixir_script/passes/handle_overridables.ex new file mode 100644 index 00000000..a226d404 --- /dev/null +++ b/lib/elixir_script/passes/handle_overridables.ex @@ -0,0 +1,86 @@ +defmodule ElixirScript.Passes.HandleOverridables do + @moduledoc false + + def execute(compiler_data, opts) do + new_data = Enum.map(compiler_data.data, fn { module_name, module_data } -> + overridables = get_overridables(module_data.ast) + ast = handle_overridable(module_data.ast, overridables) + module_data = Map.put(module_data, :ast, ast) + + {module_name, module_data} + end) + + Map.put(compiler_data, :data, new_data) + end + + defp get_overridables({:__block__, [], body}) do + defover = Enum.find(body, fn + {:defoverridable, _, _} -> + true + _ -> + false + end) + + if is_nil(defover) do + [] + else + {:defoverridable, _, [overridables]} = defover + overridables + end + end + + defp handle_overridable(ast, []) do + ast + end + + defp handle_overridable({:__block__, [], body}, overridables) do + result = body + |> Enum.reduce(%{overridables: [], overridable_found: false, body: []}, fn + {:def, def_context, [{name, context, params}, function_body] } = ast, %{overridable_found: false} = acc -> + Map.put(acc, :overridables, acc.overridables ++ [ast]) + + {:defoverridable, _, _}, acc -> + Map.put(acc, :overridable_found, true) + x, acc -> + Map.put(acc, :body, acc.body ++ [x]) + end) + + processed_overridables = Enum.map(result.overridables, fn + {:def, def_context, [{name, context, params}, function_body] } = ast -> + arity = get_arity(params) + + found = Enum.any?(result.body, fn + {:def, _, [{name_from_body, _, params_from_body}, _] } -> + if {name, arity} == {name_from_body, get_arity(params_from_body)} do + true + else + false + end + _ -> + false + end) + + if found do + super_name = String.to_atom("__super__" <> to_string(name)) + {:defp, def_context, [{super_name, context, params}, function_body] } + else + ast + end + end) + + body = processed_overridables ++ result.body + {:__block__, [], body} + end + + defp get_arity(params) do + cond do + is_nil(params) -> + 0 + is_atom(params) -> + 0 + true -> + length(params) + end + end + +end \ No newline at end of file diff --git a/lib/elixir_script/translator.ex b/lib/elixir_script/translator.ex index 83d07ff6..a4e30f7b 100644 --- a/lib/elixir_script/translator.ex +++ b/lib/elixir_script/translator.ex @@ -243,6 +243,13 @@ defmodule ElixirScript.Translator do { Map.make_get_property(target, property, env), env } end + defp do_translate({:super, _, params }, env) do + { name, _ } = env.function + super_name = String.to_atom("__super__" <> to_string(name)) + + Call.make_local_function_call(super_name, params, env) + end + defp do_translate({{:., _, [function_name]}, _, params}, env) do Call.make_local_function_call(function_name, params, env) end diff --git a/priv/std_lib/keyword.ex b/priv/std_lib/keyword.ex index c08c71b1..2c91ec9f 100644 --- a/priv/std_lib/keyword.ex +++ b/priv/std_lib/keyword.ex @@ -1,6 +1,10 @@ defmodule ElixirScript.Keyword do @moduledoc false + def new() do + [] + end + def has_key?(kw, key) do do_has_key?(kw, key) end From b715ef98d802389996ef2c67334d7f079a7e406b Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Sat, 4 Mar 2017 18:34:22 -0600 Subject: [PATCH 013/418] Make sure both def and defp are supported --- lib/elixir_script/passes/handle_overridables.ex | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/lib/elixir_script/passes/handle_overridables.ex b/lib/elixir_script/passes/handle_overridables.ex index a226d404..44ae2b90 100644 --- a/lib/elixir_script/passes/handle_overridables.ex +++ b/lib/elixir_script/passes/handle_overridables.ex @@ -1,5 +1,6 @@ defmodule ElixirScript.Passes.HandleOverridables do @moduledoc false + @function_types [:def, :defp] def execute(compiler_data, opts) do new_data = Enum.map(compiler_data.data, fn { module_name, module_data } -> @@ -36,7 +37,7 @@ defmodule ElixirScript.Passes.HandleOverridables do defp handle_overridable({:__block__, [], body}, overridables) do result = body |> Enum.reduce(%{overridables: [], overridable_found: false, body: []}, fn - {:def, def_context, [{name, context, params}, function_body] } = ast, %{overridable_found: false} = acc -> + {type, def_context, [{name, context, params}, function_body] } = ast, %{overridable_found: false} = acc when type in @function_types -> Map.put(acc, :overridables, acc.overridables ++ [ast]) {:defoverridable, _, _}, acc -> @@ -46,11 +47,11 @@ defmodule ElixirScript.Passes.HandleOverridables do end) processed_overridables = Enum.map(result.overridables, fn - {:def, def_context, [{name, context, params}, function_body] } = ast -> + {type, def_context, [{name, context, params}, function_body] } = ast when type in @function_types -> arity = get_arity(params) found = Enum.any?(result.body, fn - {:def, _, [{name_from_body, _, params_from_body}, _] } -> + {type, _, [{name_from_body, _, params_from_body}, _] } -> if {name, arity} == {name_from_body, get_arity(params_from_body)} do true else From 34e81a82149c731a87bbe46d81c7c002875f5204 Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Sun, 5 Mar 2017 15:47:41 -0600 Subject: [PATCH 014/418] Update README.md --- README.md | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 89ca4c9f..12b15a92 100644 --- a/README.md +++ b/README.md @@ -29,7 +29,11 @@ Clone the repo Get dependencies mix deps.get - npm install + yarn + +Create Elixir.Bootstrap.js + + yarn build Compile @@ -38,7 +42,7 @@ Compile Test mix test - npm test + yarn test Build From 09d7205c5a846fbea92d83b709285731e3a7aa58 Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Sun, 5 Mar 2017 15:48:35 -0600 Subject: [PATCH 015/418] Update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 12b15a92..41d5886b 100644 --- a/README.md +++ b/README.md @@ -59,6 +59,7 @@ Communication ======== [gitter room](https://gitter.im/elixirscript/elixirscript) + [#elixirscript](https://elixir-lang.slack.com/messages/elixirscript/) on the elixir-lang Slack Contributing From 574767ba3a6fb4553a0a9768c2ed2a2e1572e80f Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Sun, 5 Mar 2017 16:39:36 -0600 Subject: [PATCH 016/418] Update clean command in package.json --- mix.exs | 4 ++-- package.json | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/mix.exs b/mix.exs index e089a658..5da7fda2 100644 --- a/mix.exs +++ b/mix.exs @@ -6,7 +6,7 @@ defmodule ElixirScript.Mixfile do app: :elixir_script, version: "0.27.0-dev", elixir: "~> 1.0", - elixirc_paths: elixirc_paths(), + elixirc_paths: elixirc_paths(), escript: escript_config(), deps: deps(), description: description(), @@ -37,7 +37,7 @@ defmodule ElixirScript.Mixfile do ] end - defp elixirc_paths(), do: ["lib", "priv/std_lib"] + defp elixirc_paths(), do: ["lib", "priv/std_lib"] defp escript_config do [main_module: ElixirScript.CLI, name: "elixirscript"] diff --git a/package.json b/package.json index 5387ddfb..38b4b280 100644 --- a/package.json +++ b/package.json @@ -10,7 +10,7 @@ "lint": "eslint src/javascript/lib/**/*.js src/javascript/tests/**/*.js", "lint:fix": "eslint src/javascript/lib/**/*.js src/javascript/tests/**/*.js --fix", "build": "rollup -c rollup.config.js", - "clean": "rm -rf priv", + "clean": "rm -rf priv/build", "test": "mocha src/javascript/tests --recursive --compilers js:babel-core/register" }, "repository": { @@ -44,4 +44,4 @@ "rollup-plugin-node-resolve": "^2.0.0", "rollup-plugin-uglify": "^1.0.1" } -} \ No newline at end of file +} From 4210c19d04565723319ceb0c7cea245a8af250bb Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Mon, 6 Mar 2017 21:25:40 -0600 Subject: [PATCH 017/418] Refactor out references to Dict --- lib/elixir_script/translator/kernel/defmodule.ex | 16 ++++++++-------- .../translator/kernel/special_forms/for.ex | 8 ++++---- .../translator/kernel/special_forms/try.ex | 10 +++++----- 3 files changed, 17 insertions(+), 17 deletions(-) diff --git a/lib/elixir_script/translator/kernel/defmodule.ex b/lib/elixir_script/translator/kernel/defmodule.ex index d51e62a9..285eab4b 100644 --- a/lib/elixir_script/translator/kernel/defmodule.ex +++ b/lib/elixir_script/translator/kernel/defmodule.ex @@ -188,28 +188,28 @@ defmodule ElixirScript.Translator.Defmodule do end def process_functions(%{ exported: exported, private: private, exported_generators: exported_generators, private_generators: private_generators }, env) do - exported_functions = Enum.map(Dict.keys(exported), fn(key) -> - functions = Dict.get(exported, key) + exported_functions = Enum.map(Map.keys(exported), fn(key) -> + functions = Map.get(exported, key) { functions, _ } = Def.process_function(key, functions, env) { key, functions } end) - exported_generators = Enum.map(Dict.keys(exported_generators), fn(key) -> - functions = Dict.get(exported_generators, key) + exported_generators = Enum.map(Map.keys(exported_generators), fn(key) -> + functions = Map.get(exported_generators, key) { functions, _ } = Def.process_function(key, functions, %{ env | context: :generator}) { key, functions } end) - private_functions = Enum.map(Dict.keys(private), fn(key) -> - functions = Dict.get(private, key) + private_functions = Enum.map(Map.keys(private), fn(key) -> + functions = Map.get(private, key) { functions, _ } = Def.process_function(key, functions, env) { key, functions } end) - private_generators = Enum.map(Dict.keys(private_generators), fn(key) -> - functions = Dict.get(private_generators, key) + private_generators = Enum.map(Map.keys(private_generators), fn(key) -> + functions = Map.get(private_generators, key) { functions, _ } = Def.process_function(key, functions, %{ env | context: :generator}) { key, functions } end) diff --git a/lib/elixir_script/translator/kernel/special_forms/for.ex b/lib/elixir_script/translator/kernel/special_forms/for.ex index 3c6293e4..e690f710 100644 --- a/lib/elixir_script/translator/kernel/special_forms/for.ex +++ b/lib/elixir_script/translator/kernel/special_forms/for.ex @@ -6,13 +6,13 @@ defmodule ElixirScript.Translator.For do alias ElixirScript.Translator.Primitive alias ElixirScript.Translator.Function alias ElixirScript.Translator.Utils - alias ElixirScript.Translator.Identifier + alias ElixirScript.Translator.Identifier def make_for(generators, env) do ElixirScript.Translator.State.add_module_reference(env.state, env.module, ElixirScript.Collectable) args = handle_args(generators, env) - generators = JS.array_expression(args.generators) + generators = JS.array_expression(args.generators) into = args.into || Primitive.make_list_no_translate([]) filter = args.filter || JS.function_expression([], [], JS.block_statement([JS.return_statement(JS.identifier("true"))])) @@ -54,11 +54,11 @@ defmodule ElixirScript.Translator.For do defp handle_args(generators, env) do Enum.reduce(generators, %{generators: [], args: [], filter: nil, fun: nil, into: nil, patterns: []}, fn - ({:<<>>, [], body}, state) -> + ({:<<>>, _, body}, state) -> {bs_parts, collection} = Enum.map_reduce(body, nil, fn {:::, _, _} = ast, state -> {ast, state} - {:<-, [], [var, collection]}, _ -> + {:<-, _, [var, collection]}, _ -> {var, collection} end) diff --git a/lib/elixir_script/translator/kernel/special_forms/try.ex b/lib/elixir_script/translator/kernel/special_forms/try.ex index 81db4a39..c281b6a6 100644 --- a/lib/elixir_script/translator/kernel/special_forms/try.ex +++ b/lib/elixir_script/translator/kernel/special_forms/try.ex @@ -5,11 +5,11 @@ defmodule ElixirScript.Translator.Try do alias ElixirScript.Translator.Primitive def make_try(blocks, env) do - try_block = Dict.get(blocks, :do) - rescue_block = Dict.get(blocks, :rescue, nil) - catch_block = Dict.get(blocks, :catch, nil) - after_block = Dict.get(blocks, :after, nil) - else_block = Dict.get(blocks, :else, nil) + try_block = Keyword.get(blocks, :do) + rescue_block = Keyword.get(blocks, :rescue, nil) + catch_block = Keyword.get(blocks, :catch, nil) + after_block = Keyword.get(blocks, :after, nil) + else_block = Keyword.get(blocks, :else, nil) { translated_body, _ } = Function.prepare_function_body(try_block, env) From a6e6477c8df11a72167679c5fc25bcd9f5dd2306 Mon Sep 17 00:00:00 2001 From: Jody LeCompte Date: Wed, 8 Mar 2017 13:03:09 -0600 Subject: [PATCH 018/418] Beginning credo cleanup * credo configuration altered so that delibarately placed spaces around certain expresions no longer throw errors * Corrected remaining credo errors in elixir_script.ex --- .credo.exs | 2 +- lib/elixir_script.ex | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/.credo.exs b/.credo.exs index 18abcc24..ea83b9c6 100644 --- a/.credo.exs +++ b/.credo.exs @@ -52,7 +52,7 @@ {Credo.Check.Consistency.MultiAliasImportRequireUse}, {Credo.Check.Consistency.ParameterPatternMatching}, {Credo.Check.Consistency.SpaceAroundOperators}, - {Credo.Check.Consistency.SpaceInParentheses}, + {Credo.Check.Consistency.SpaceInParentheses, false}, {Credo.Check.Consistency.TabsOrSpaces}, # For some checks, like AliasUsage, you can only customize the priority diff --git a/lib/elixir_script.ex b/lib/elixir_script.ex index fd218c7c..bde9904f 100644 --- a/lib/elixir_script.ex +++ b/lib/elixir_script.ex @@ -164,9 +164,9 @@ defmodule ElixirScript do |> Map.to_list |> Enum.map(fn {app, path} -> {app, List.wrap(path)} end) - deps = [{:elixir, List.wrap(get_std_lib_path())}] ++ deps + deps_wrapped = [{:elixir, List.wrap(get_std_lib_path())}] ++ deps - result = %{data: deps} + result = %{data: deps_wrapped} |> ElixirScript.Passes.Init.execute(opts) |> ElixirScript.Passes.ASTFromFile.execute(opts) |> ElixirScript.Passes.LoadModules.execute(opts) @@ -207,6 +207,7 @@ defmodule ElixirScript do @doc """ Returns the contents of the bootrstrap js file """ + @spec get_bootstrap_js(string) :: string def get_bootstrap_js(module_format) do path = Path.join([operating_path, "build", to_string(module_format), "Elixir.Bootstrap.js"]) File.read!(path) From 2f0ccada94bb8a7a1ce1b9262e1e7a877bf227b5 Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Wed, 8 Mar 2017 19:00:55 -0600 Subject: [PATCH 019/418] Make sure mix compiler works in umbrella projects --- .../elixir_script_compile_error.ex | 3 +++ lib/mix/tasks/compile.elixir_script.ex | 21 +++++++++++++------ 2 files changed, 18 insertions(+), 6 deletions(-) create mode 100644 lib/elixir_script/elixir_script_compile_error.ex diff --git a/lib/elixir_script/elixir_script_compile_error.ex b/lib/elixir_script/elixir_script_compile_error.ex new file mode 100644 index 00000000..978d1d84 --- /dev/null +++ b/lib/elixir_script/elixir_script_compile_error.ex @@ -0,0 +1,3 @@ +defmodule ElixirScriptCompileError do + defexception [:message] +end diff --git a/lib/mix/tasks/compile.elixir_script.ex b/lib/mix/tasks/compile.elixir_script.ex index df25aaa7..b02c937d 100644 --- a/lib/mix/tasks/compile.elixir_script.ex +++ b/lib/mix/tasks/compile.elixir_script.ex @@ -1,6 +1,8 @@ defmodule Mix.Tasks.Compile.ElixirScript do use Mix.Task + @recursive true + @moduledoc """ Mix compiler to allow mix to compile Elixirscript source files into JavaScript @@ -16,11 +18,11 @@ defmodule Mix.Tasks.Compile.ElixirScript do compilers: [:elixir_script] ++ Mix.compilers ] end - + Available options are: * `input`: The folder to look for Elixirscript files in. (defaults to `lib/elixirscript`) * `output`: The path of the generated JavaScript file. (defaults to `priv/elixirscript`) - + If path ends in `.js` then that will be the name of the file. If a directory is given, file will be named `Elixir.App.js` * `format`: The module format of generated JavaScript code. (defaults to `:es`). @@ -35,11 +37,19 @@ defmodule Mix.Tasks.Compile.ElixirScript do @spec run(any()) :: :ok def run(_) do - elixirscript_config = get_elixirscript_config() - elixirscript_base = Path.join([Mix.Project.build_path, "elixirscript"]) + do_compile(elixirscript_base, Mix.Project.config[:app]) + :ok + end + + defp do_compile(_, nil) do + raise ElixirScriptCompileError, message: "Unable to find mix project app name" + end + + defp do_compile(elixirscript_base, app) do + elixirscript_config = get_elixirscript_config() File.mkdir_p!(elixirscript_base) - elixirscript_path = Path.join([elixirscript_base, "#{Mix.Project.config[:app]}"]) + elixirscript_path = Path.join([elixirscript_base, "#{app}"]) input_path = elixirscript_config |> Keyword.get(:input) @@ -66,7 +76,6 @@ defmodule Mix.Tasks.Compile.ElixirScript do js_modules = Keyword.get(elixirscript_config, :js_modules, []) ElixirScript.compile_path(paths, %{output: output_path, format: format, js_modules: js_modules}) - :ok end def clean do From 35798f95fea1b9330550f30dc0551bb718d78016 Mon Sep 17 00:00:00 2001 From: Stephan van Diepen Date: Sun, 5 Mar 2017 12:56:45 +0100 Subject: [PATCH 020/418] Add Elixir.load function --- lib/elixir_script/passes/create_js_modules.ex | 22 ++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/lib/elixir_script/passes/create_js_modules.ex b/lib/elixir_script/passes/create_js_modules.ex index 0986ae7c..fa81d145 100644 --- a/lib/elixir_script/passes/create_js_modules.ex +++ b/lib/elixir_script/passes/create_js_modules.ex @@ -92,10 +92,30 @@ defmodule ElixirScript.Passes.CreateJSModules do ) ) + load = JS.assignment_expression( + :=, + JS.member_expression( + JS.identifier("Elixir"), + JS.identifier("load") + ), + JS.function_expression( + [JS.identifier(:module)], + [], + JS.block_statement([ + JS.return_statement( + JS.member_expression( + JS.identifier(:module), + JS.identifier("__exports") + ) + ) + ]) + ) + ) + ast = opts.module_formatter.build( [], opts.js_modules, - [elixir, start] ++ body, + [elixir, start, load] ++ body, JS.identifier("Elixir") ) From d363aa735003eb6d057ae41fa6254de3a49da53c Mon Sep 17 00:00:00 2001 From: Stephan van Diepen Date: Fri, 10 Mar 2017 08:53:16 +0100 Subject: [PATCH 021/418] Make sure the module is loaded --- lib/elixir_script/passes/create_js_modules.ex | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/lib/elixir_script/passes/create_js_modules.ex b/lib/elixir_script/passes/create_js_modules.ex index fa81d145..a2eebd52 100644 --- a/lib/elixir_script/passes/create_js_modules.ex +++ b/lib/elixir_script/passes/create_js_modules.ex @@ -103,9 +103,12 @@ defmodule ElixirScript.Passes.CreateJSModules do [], JS.block_statement([ JS.return_statement( - JS.member_expression( - JS.identifier(:module), - JS.identifier("__exports") + JS.call_expression( + JS.member_expression( + JS.identifier(:module), + JS.identifier("__load") + ), + [JS.identifier("Elixir")] ) ) ]) From fe126162655ceb3eb68efa8751ebd4e1cb5c1047 Mon Sep 17 00:00:00 2001 From: Stephan van Diepen Date: Fri, 10 Mar 2017 09:11:13 +0100 Subject: [PATCH 022/418] Extract load function --- lib/elixir_script/passes/create_js_modules.ex | 23 ++++++++++--------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/lib/elixir_script/passes/create_js_modules.ex b/lib/elixir_script/passes/create_js_modules.ex index a2eebd52..7e483196 100644 --- a/lib/elixir_script/passes/create_js_modules.ex +++ b/lib/elixir_script/passes/create_js_modules.ex @@ -92,7 +92,18 @@ defmodule ElixirScript.Passes.CreateJSModules do ) ) - load = JS.assignment_expression( + ast = opts.module_formatter.build( + [], + opts.js_modules, + [elixir, start, load] ++ body, + JS.identifier("Elixir") + ) + + ast + end + + def load do + JS.assignment_expression( :=, JS.member_expression( JS.identifier("Elixir"), @@ -114,15 +125,5 @@ defmodule ElixirScript.Passes.CreateJSModules do ]) ) ) - - ast = opts.module_formatter.build( - [], - opts.js_modules, - [elixir, start, load] ++ body, - JS.identifier("Elixir") - ) - - ast end - end From 33432ad193b9a04b73595332f5aa5bce977407cb Mon Sep 17 00:00:00 2001 From: Stephan van Diepen Date: Fri, 10 Mar 2017 09:11:21 +0100 Subject: [PATCH 023/418] Add load spec --- test/passes/create_js_modules_test.exs | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 test/passes/create_js_modules_test.exs diff --git a/test/passes/create_js_modules_test.exs b/test/passes/create_js_modules_test.exs new file mode 100644 index 00000000..2b1824d9 --- /dev/null +++ b/test/passes/create_js_modules_test.exs @@ -0,0 +1,20 @@ +defmodule ElixirScript.Passes.CreateJSModules.Test do + use ExUnit.Case + + import ElixirScript.TestHelper + + alias ElixirScript.Passes.CreateJSModules + alias ESTree.Tools.Generator + + test "load" do + load_js = CreateJSModules.load + |> Generator.generate + + expected_js = +"Elixir.load = function(module) { + return module.__load(Elixir); +}" + + assert(load_js == expected_js) + end +end From b04e24d2305ffcfec0c99bc517f6e7172b9489a7 Mon Sep 17 00:00:00 2001 From: Stephan van Diepen Date: Fri, 10 Mar 2017 09:44:41 +0100 Subject: [PATCH 024/418] Extract and test start --- lib/elixir_script/passes/create_js_modules.ex | 22 ++++++++++--------- test/passes/create_js_modules_test.exs | 13 +++++++++++ 2 files changed, 25 insertions(+), 10 deletions(-) diff --git a/lib/elixir_script/passes/create_js_modules.ex b/lib/elixir_script/passes/create_js_modules.ex index 7e483196..dbadb4fe 100644 --- a/lib/elixir_script/passes/create_js_modules.ex +++ b/lib/elixir_script/passes/create_js_modules.ex @@ -65,7 +65,18 @@ defmodule ElixirScript.Passes.CreateJSModules do elixir = JS.variable_declaration([declarator], :const) - start = JS.assignment_expression( + ast = opts.module_formatter.build( + [], + opts.js_modules, + [elixir, start, load] ++ body, + JS.identifier("Elixir") + ) + + ast + end + + def start do + JS.assignment_expression( :=, JS.member_expression( JS.identifier("Elixir"), @@ -91,15 +102,6 @@ defmodule ElixirScript.Passes.CreateJSModules do ]) ) ) - - ast = opts.module_formatter.build( - [], - opts.js_modules, - [elixir, start, load] ++ body, - JS.identifier("Elixir") - ) - - ast end def load do diff --git a/test/passes/create_js_modules_test.exs b/test/passes/create_js_modules_test.exs index 2b1824d9..de07bc1f 100644 --- a/test/passes/create_js_modules_test.exs +++ b/test/passes/create_js_modules_test.exs @@ -6,6 +6,19 @@ defmodule ElixirScript.Passes.CreateJSModules.Test do alias ElixirScript.Passes.CreateJSModules alias ESTree.Tools.Generator + test "start" do + start_js = CreateJSModules.start + |> Generator.generate + + expected_js = +"Elixir.start = function(app, args) { + app.__load(Elixir).start(Symbol.for('normal'), args) +}" + + + assert(start_js == expected_js) + end + test "load" do load_js = CreateJSModules.load |> Generator.generate From 4ca520142ab7b4ef53ce0576f6d3649ca782b624 Mon Sep 17 00:00:00 2001 From: Stephan van Diepen Date: Fri, 10 Mar 2017 09:57:14 +0100 Subject: [PATCH 025/418] Use assert_translation in specs --- test/passes/create_js_modules_test.exs | 35 ++++++++++++-------------- 1 file changed, 16 insertions(+), 19 deletions(-) diff --git a/test/passes/create_js_modules_test.exs b/test/passes/create_js_modules_test.exs index de07bc1f..23b4edc3 100644 --- a/test/passes/create_js_modules_test.exs +++ b/test/passes/create_js_modules_test.exs @@ -7,27 +7,24 @@ defmodule ElixirScript.Passes.CreateJSModules.Test do alias ESTree.Tools.Generator test "start" do - start_js = CreateJSModules.start - |> Generator.generate - - expected_js = -"Elixir.start = function(app, args) { - app.__load(Elixir).start(Symbol.for('normal'), args) -}" - - - assert(start_js == expected_js) + ex_ast = quote do: CreateJSModules.start + js = """ + Elixir.start = function(app, args) { + app.__load(Elixir).start(Symbol.for('normal'), args) + } + """ + + assert_translation(ex_ast, js) end test "load" do - load_js = CreateJSModules.load - |> Generator.generate - - expected_js = -"Elixir.load = function(module) { - return module.__load(Elixir); -}" - - assert(load_js == expected_js) + ex_ast = quote do: CreateJSModules.load + js = """ + Elixir.load = function(module) { + return module.__load(Elixir); + } + """ + + assert_translation(ex_ast, js) end end From fcca1e34cc8de1e50f71eb87d299bfbd2d1f8ee2 Mon Sep 17 00:00:00 2001 From: Stephan van Diepen Date: Fri, 10 Mar 2017 13:35:57 +0100 Subject: [PATCH 026/418] Test elixirscript through executed js --- .gitignore | 1 + test/app/convert-exjs | 3 + test/app/package.json | 19 +++ test/app/spec/main.spec.js | 24 ++++ test/app/spec/setup.spec.js | 15 +++ test/app/src/main.ex | 9 ++ test/app/yarn.lock | 261 ++++++++++++++++++++++++++++++++++++ 7 files changed, 332 insertions(+) create mode 100755 test/app/convert-exjs create mode 100644 test/app/package.json create mode 100644 test/app/spec/main.spec.js create mode 100644 test/app/spec/setup.spec.js create mode 100644 test/app/src/main.ex create mode 100644 test/app/yarn.lock diff --git a/.gitignore b/.gitignore index e0db4469..6eea78e1 100644 --- a/.gitignore +++ b/.gitignore @@ -19,3 +19,4 @@ src/elixirscript priv/**/*.js stdlib_state.bin *.log +test/app/build diff --git a/test/app/convert-exjs b/test/app/convert-exjs new file mode 100755 index 00000000..dc457929 --- /dev/null +++ b/test/app/convert-exjs @@ -0,0 +1,3 @@ +cd ../../ + +mix elixirscript test/app/src/ -f common -o test/app/build/ diff --git a/test/app/package.json b/test/app/package.json new file mode 100644 index 00000000..ca322ce4 --- /dev/null +++ b/test/app/package.json @@ -0,0 +1,19 @@ +{ + "name": "elixirscript-js-app", + "version": "1.0.0", + "description": "", + "main": "index.js", + "scripts": { + "test": "npm run test-unit", + "test-unit": "./convert-exjs && NODE_ENV=test mocha --require co-mocha -R spec --ui bdd 'spec/*.spec.js'" + }, + "author": "", + "license": "ISC", + "devDependencies": { + "chai": "^3.5.0", + "co-mocha": "^1.2.0", + "mocha": "^3.2.0", + "sinon": "^1.17.7", + "sinon-chai": "^2.8.0" + } +} diff --git a/test/app/spec/main.spec.js b/test/app/spec/main.spec.js new file mode 100644 index 00000000..f60c9784 --- /dev/null +++ b/test/app/spec/main.spec.js @@ -0,0 +1,24 @@ +const expect = require('chai').expect; +const sinon = require('sinon'); + +const Elixir = require('../build/Elixir.App'); + +describe('Elixir.start', function () { + it('calls the modules start function', function () { + const callback = sinon.spy(); + + Elixir.start(Elixir.Main, callback); + + expect(callback).to.have.been.calledWith('started'); + }); +}); + +describe('Elixir.load', function () { + it('loads the modules exports', function () { + const main = Elixir.load(Elixir.Main); + + expect(main).to.have.property('start'); + expect(main).to.have.property('hello'); + expect(main.hello()).to.eq('Hello!'); + }); +}); diff --git a/test/app/spec/setup.spec.js b/test/app/spec/setup.spec.js new file mode 100644 index 00000000..b1c0f404 --- /dev/null +++ b/test/app/spec/setup.spec.js @@ -0,0 +1,15 @@ +const sinon = require('sinon'); +const chai = require('chai'); +const sinonChai = require('sinon-chai'); + +before(function () { + chai.use(sinonChai); +}); + +beforeEach(function () { + this.sandbox = sinon.sandbox.create(); +}); + +afterEach(function () { + this.sandbox.restore(); +}); diff --git a/test/app/src/main.ex b/test/app/src/main.ex new file mode 100644 index 00000000..5ddefc6a --- /dev/null +++ b/test/app/src/main.ex @@ -0,0 +1,9 @@ +defmodule Main do + def start(:normal, callback) do + callback.("started") + end + + def hello do + "Hello!" + end +end diff --git a/test/app/yarn.lock b/test/app/yarn.lock new file mode 100644 index 00000000..cb4ea46c --- /dev/null +++ b/test/app/yarn.lock @@ -0,0 +1,261 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +assertion-error@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/assertion-error/-/assertion-error-1.0.2.tgz#13ca515d86206da0bac66e834dd397d87581094c" + +balanced-match@^0.4.1: + version "0.4.2" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-0.4.2.tgz#cb3f3e3c732dc0f01ee70b403f302e61d7709838" + +brace-expansion@^1.0.0: + version "1.1.6" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.6.tgz#7197d7eaa9b87e648390ea61fc66c84427420df9" + dependencies: + balanced-match "^0.4.1" + concat-map "0.0.1" + +browser-stdout@1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/browser-stdout/-/browser-stdout-1.3.0.tgz#f351d32969d32fa5d7a5567154263d928ae3bd1f" + +chai@^3.5.0: + version "3.5.0" + resolved "https://registry.yarnpkg.com/chai/-/chai-3.5.0.tgz#4d02637b067fe958bdbfdd3a40ec56fef7373247" + dependencies: + assertion-error "^1.0.1" + deep-eql "^0.1.3" + type-detect "^1.0.0" + +co-mocha@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/co-mocha/-/co-mocha-1.2.0.tgz#d9be35a2a2d16f4b1b0e83f6973401ca4b6660af" + dependencies: + co "^4.0.0" + is-generator "^1.0.1" + +co@^4.0.0: + version "4.6.0" + resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184" + +commander@2.9.0: + version "2.9.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.9.0.tgz#9c99094176e12240cb22d6c5146098400fe0f7d4" + dependencies: + graceful-readlink ">= 1.0.0" + +concat-map@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" + +debug@2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/debug/-/debug-2.2.0.tgz#f87057e995b1a1f6ae6a4960664137bc56f039da" + dependencies: + ms "0.7.1" + +deep-eql@^0.1.3: + version "0.1.3" + resolved "https://registry.yarnpkg.com/deep-eql/-/deep-eql-0.1.3.tgz#ef558acab8de25206cd713906d74e56930eb69f2" + dependencies: + type-detect "0.1.1" + +diff@1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/diff/-/diff-1.4.0.tgz#7f28d2eb9ee7b15a97efd89ce63dcfdaa3ccbabf" + +escape-string-regexp@1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" + +formatio@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/formatio/-/formatio-1.1.1.tgz#5ed3ccd636551097383465d996199100e86161e9" + dependencies: + samsam "~1.1" + +fs.realpath@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" + +glob@7.0.5: + version "7.0.5" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.0.5.tgz#b4202a69099bbb4d292a7c1b95b6682b67ebdc95" + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.0.2" + once "^1.3.0" + path-is-absolute "^1.0.0" + +"graceful-readlink@>= 1.0.0": + version "1.0.1" + resolved "https://registry.yarnpkg.com/graceful-readlink/-/graceful-readlink-1.0.1.tgz#4cafad76bc62f02fa039b2f94e9a3dd3a391a725" + +growl@1.9.2: + version "1.9.2" + resolved "https://registry.yarnpkg.com/growl/-/growl-1.9.2.tgz#0ea7743715db8d8de2c5ede1775e1b45ac85c02f" + +has-flag@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-1.0.0.tgz#9d9e793165ce017a00f00418c43f942a7b1d11fa" + +inflight@^1.0.4: + version "1.0.6" + resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" + dependencies: + once "^1.3.0" + wrappy "1" + +inherits@2, inherits@2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.1.tgz#b17d08d326b4423e568eff719f91b0b1cbdf69f1" + +is-generator@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/is-generator/-/is-generator-1.0.3.tgz#c14c21057ed36e328db80347966c693f886389f3" + +json3@3.3.2: + version "3.3.2" + resolved "https://registry.yarnpkg.com/json3/-/json3-3.3.2.tgz#3c0434743df93e2f5c42aee7b19bcb483575f4e1" + +lodash._baseassign@^3.0.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/lodash._baseassign/-/lodash._baseassign-3.2.0.tgz#8c38a099500f215ad09e59f1722fd0c52bfe0a4e" + dependencies: + lodash._basecopy "^3.0.0" + lodash.keys "^3.0.0" + +lodash._basecopy@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/lodash._basecopy/-/lodash._basecopy-3.0.1.tgz#8da0e6a876cf344c0ad8a54882111dd3c5c7ca36" + +lodash._basecreate@^3.0.0: + version "3.0.3" + resolved "https://registry.yarnpkg.com/lodash._basecreate/-/lodash._basecreate-3.0.3.tgz#1bc661614daa7fc311b7d03bf16806a0213cf821" + +lodash._getnative@^3.0.0: + version "3.9.1" + resolved "https://registry.yarnpkg.com/lodash._getnative/-/lodash._getnative-3.9.1.tgz#570bc7dede46d61cdcde687d65d3eecbaa3aaff5" + +lodash._isiterateecall@^3.0.0: + version "3.0.9" + resolved "https://registry.yarnpkg.com/lodash._isiterateecall/-/lodash._isiterateecall-3.0.9.tgz#5203ad7ba425fae842460e696db9cf3e6aac057c" + +lodash.create@3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/lodash.create/-/lodash.create-3.1.1.tgz#d7f2849f0dbda7e04682bb8cd72ab022461debe7" + dependencies: + lodash._baseassign "^3.0.0" + lodash._basecreate "^3.0.0" + lodash._isiterateecall "^3.0.0" + +lodash.isarguments@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz#2f573d85c6a24289ff00663b491c1d338ff3458a" + +lodash.isarray@^3.0.0: + version "3.0.4" + resolved "https://registry.yarnpkg.com/lodash.isarray/-/lodash.isarray-3.0.4.tgz#79e4eb88c36a8122af86f844aa9bcd851b5fbb55" + +lodash.keys@^3.0.0: + version "3.1.2" + resolved "https://registry.yarnpkg.com/lodash.keys/-/lodash.keys-3.1.2.tgz#4dbc0472b156be50a0b286855d1bd0b0c656098a" + dependencies: + lodash._getnative "^3.0.0" + lodash.isarguments "^3.0.0" + lodash.isarray "^3.0.0" + +lolex@1.3.2: + version "1.3.2" + resolved "https://registry.yarnpkg.com/lolex/-/lolex-1.3.2.tgz#7c3da62ffcb30f0f5a80a2566ca24e45d8a01f31" + +minimatch@^3.0.2: + version "3.0.3" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.3.tgz#2a4e4090b96b2db06a9d7df01055a62a77c9b774" + dependencies: + brace-expansion "^1.0.0" + +minimist@0.0.8: + version "0.0.8" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" + +mkdirp@0.5.1: + version "0.5.1" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" + dependencies: + minimist "0.0.8" + +mocha@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/mocha/-/mocha-3.2.0.tgz#7dc4f45e5088075171a68896814e6ae9eb7a85e3" + dependencies: + browser-stdout "1.3.0" + commander "2.9.0" + debug "2.2.0" + diff "1.4.0" + escape-string-regexp "1.0.5" + glob "7.0.5" + growl "1.9.2" + json3 "3.3.2" + lodash.create "3.1.1" + mkdirp "0.5.1" + supports-color "3.1.2" + +ms@0.7.1: + version "0.7.1" + resolved "https://registry.yarnpkg.com/ms/-/ms-0.7.1.tgz#9cd13c03adbff25b65effde7ce864ee952017098" + +once@^1.3.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" + dependencies: + wrappy "1" + +path-is-absolute@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" + +samsam@1.1.2, samsam@~1.1: + version "1.1.2" + resolved "https://registry.yarnpkg.com/samsam/-/samsam-1.1.2.tgz#bec11fdc83a9fda063401210e40176c3024d1567" + +sinon-chai@^2.8.0: + version "2.8.0" + resolved "https://registry.yarnpkg.com/sinon-chai/-/sinon-chai-2.8.0.tgz#432a9bbfd51a6fc00798f4d2526a829c060687ac" + +sinon@^1.17.7: + version "1.17.7" + resolved "https://registry.yarnpkg.com/sinon/-/sinon-1.17.7.tgz#4542a4f49ba0c45c05eb2e9dd9d203e2b8efe0bf" + dependencies: + formatio "1.1.1" + lolex "1.3.2" + samsam "1.1.2" + util ">=0.10.3 <1" + +supports-color@3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-3.1.2.tgz#72a262894d9d408b956ca05ff37b2ed8a6e2a2d5" + dependencies: + has-flag "^1.0.0" + +type-detect@0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-0.1.1.tgz#0ba5ec2a885640e470ea4e8505971900dac58822" + +type-detect@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-1.0.0.tgz#762217cc06db258ec48908a1298e8b95121e8ea2" + +"util@>=0.10.3 <1": + version "0.10.3" + resolved "https://registry.yarnpkg.com/util/-/util-0.10.3.tgz#7afb1afe50805246489e3db7fe0ed379336ac0f9" + dependencies: + inherits "2.0.1" + +wrappy@1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" From 91d08f25cdc6768a79c5b5c30481afd6dc75128a Mon Sep 17 00:00:00 2001 From: Stephan van Diepen Date: Fri, 10 Mar 2017 16:20:05 +0100 Subject: [PATCH 027/418] Use root package.json for app specs --- package.json | 7 +- test/app/convert-exjs | 4 +- test/app/package.json | 19 --- test/app/yarn.lock | 261 ------------------------------------------ yarn.lock | 37 ++++++ 5 files changed, 45 insertions(+), 283 deletions(-) delete mode 100644 test/app/package.json delete mode 100644 test/app/yarn.lock diff --git a/package.json b/package.json index 38b4b280..1a5d82c4 100644 --- a/package.json +++ b/package.json @@ -11,7 +11,8 @@ "lint:fix": "eslint src/javascript/lib/**/*.js src/javascript/tests/**/*.js --fix", "build": "rollup -c rollup.config.js", "clean": "rm -rf priv/build", - "test": "mocha src/javascript/tests --recursive --compilers js:babel-core/register" + "test": "mocha src/javascript/tests --recursive --compilers js:babel-core/register", + "test-app": "./test/app/convert-exjs && NODE_ENV=test mocha 'test/app/spec/*.spec.js'" }, "repository": { "type": "git", @@ -42,6 +43,8 @@ "rollup": "^0.41.4", "rollup-plugin-babel": "^2.7.1", "rollup-plugin-node-resolve": "^2.0.0", - "rollup-plugin-uglify": "^1.0.1" + "rollup-plugin-uglify": "^1.0.1", + "sinon": "^1.17.7", + "sinon-chai": "^2.8.0" } } diff --git a/test/app/convert-exjs b/test/app/convert-exjs index dc457929..00bd400b 100755 --- a/test/app/convert-exjs +++ b/test/app/convert-exjs @@ -1,3 +1,5 @@ -cd ../../ +BASEDIR=$(dirname "$0") + +cd "$BASEDIR/../../" mix elixirscript test/app/src/ -f common -o test/app/build/ diff --git a/test/app/package.json b/test/app/package.json deleted file mode 100644 index ca322ce4..00000000 --- a/test/app/package.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "name": "elixirscript-js-app", - "version": "1.0.0", - "description": "", - "main": "index.js", - "scripts": { - "test": "npm run test-unit", - "test-unit": "./convert-exjs && NODE_ENV=test mocha --require co-mocha -R spec --ui bdd 'spec/*.spec.js'" - }, - "author": "", - "license": "ISC", - "devDependencies": { - "chai": "^3.5.0", - "co-mocha": "^1.2.0", - "mocha": "^3.2.0", - "sinon": "^1.17.7", - "sinon-chai": "^2.8.0" - } -} diff --git a/test/app/yarn.lock b/test/app/yarn.lock deleted file mode 100644 index cb4ea46c..00000000 --- a/test/app/yarn.lock +++ /dev/null @@ -1,261 +0,0 @@ -# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. -# yarn lockfile v1 - - -assertion-error@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/assertion-error/-/assertion-error-1.0.2.tgz#13ca515d86206da0bac66e834dd397d87581094c" - -balanced-match@^0.4.1: - version "0.4.2" - resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-0.4.2.tgz#cb3f3e3c732dc0f01ee70b403f302e61d7709838" - -brace-expansion@^1.0.0: - version "1.1.6" - resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.6.tgz#7197d7eaa9b87e648390ea61fc66c84427420df9" - dependencies: - balanced-match "^0.4.1" - concat-map "0.0.1" - -browser-stdout@1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/browser-stdout/-/browser-stdout-1.3.0.tgz#f351d32969d32fa5d7a5567154263d928ae3bd1f" - -chai@^3.5.0: - version "3.5.0" - resolved "https://registry.yarnpkg.com/chai/-/chai-3.5.0.tgz#4d02637b067fe958bdbfdd3a40ec56fef7373247" - dependencies: - assertion-error "^1.0.1" - deep-eql "^0.1.3" - type-detect "^1.0.0" - -co-mocha@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/co-mocha/-/co-mocha-1.2.0.tgz#d9be35a2a2d16f4b1b0e83f6973401ca4b6660af" - dependencies: - co "^4.0.0" - is-generator "^1.0.1" - -co@^4.0.0: - version "4.6.0" - resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184" - -commander@2.9.0: - version "2.9.0" - resolved "https://registry.yarnpkg.com/commander/-/commander-2.9.0.tgz#9c99094176e12240cb22d6c5146098400fe0f7d4" - dependencies: - graceful-readlink ">= 1.0.0" - -concat-map@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" - -debug@2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/debug/-/debug-2.2.0.tgz#f87057e995b1a1f6ae6a4960664137bc56f039da" - dependencies: - ms "0.7.1" - -deep-eql@^0.1.3: - version "0.1.3" - resolved "https://registry.yarnpkg.com/deep-eql/-/deep-eql-0.1.3.tgz#ef558acab8de25206cd713906d74e56930eb69f2" - dependencies: - type-detect "0.1.1" - -diff@1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/diff/-/diff-1.4.0.tgz#7f28d2eb9ee7b15a97efd89ce63dcfdaa3ccbabf" - -escape-string-regexp@1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" - -formatio@1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/formatio/-/formatio-1.1.1.tgz#5ed3ccd636551097383465d996199100e86161e9" - dependencies: - samsam "~1.1" - -fs.realpath@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" - -glob@7.0.5: - version "7.0.5" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.0.5.tgz#b4202a69099bbb4d292a7c1b95b6682b67ebdc95" - dependencies: - fs.realpath "^1.0.0" - inflight "^1.0.4" - inherits "2" - minimatch "^3.0.2" - once "^1.3.0" - path-is-absolute "^1.0.0" - -"graceful-readlink@>= 1.0.0": - version "1.0.1" - resolved "https://registry.yarnpkg.com/graceful-readlink/-/graceful-readlink-1.0.1.tgz#4cafad76bc62f02fa039b2f94e9a3dd3a391a725" - -growl@1.9.2: - version "1.9.2" - resolved "https://registry.yarnpkg.com/growl/-/growl-1.9.2.tgz#0ea7743715db8d8de2c5ede1775e1b45ac85c02f" - -has-flag@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-1.0.0.tgz#9d9e793165ce017a00f00418c43f942a7b1d11fa" - -inflight@^1.0.4: - version "1.0.6" - resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" - dependencies: - once "^1.3.0" - wrappy "1" - -inherits@2, inherits@2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.1.tgz#b17d08d326b4423e568eff719f91b0b1cbdf69f1" - -is-generator@^1.0.1: - version "1.0.3" - resolved "https://registry.yarnpkg.com/is-generator/-/is-generator-1.0.3.tgz#c14c21057ed36e328db80347966c693f886389f3" - -json3@3.3.2: - version "3.3.2" - resolved "https://registry.yarnpkg.com/json3/-/json3-3.3.2.tgz#3c0434743df93e2f5c42aee7b19bcb483575f4e1" - -lodash._baseassign@^3.0.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/lodash._baseassign/-/lodash._baseassign-3.2.0.tgz#8c38a099500f215ad09e59f1722fd0c52bfe0a4e" - dependencies: - lodash._basecopy "^3.0.0" - lodash.keys "^3.0.0" - -lodash._basecopy@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/lodash._basecopy/-/lodash._basecopy-3.0.1.tgz#8da0e6a876cf344c0ad8a54882111dd3c5c7ca36" - -lodash._basecreate@^3.0.0: - version "3.0.3" - resolved "https://registry.yarnpkg.com/lodash._basecreate/-/lodash._basecreate-3.0.3.tgz#1bc661614daa7fc311b7d03bf16806a0213cf821" - -lodash._getnative@^3.0.0: - version "3.9.1" - resolved "https://registry.yarnpkg.com/lodash._getnative/-/lodash._getnative-3.9.1.tgz#570bc7dede46d61cdcde687d65d3eecbaa3aaff5" - -lodash._isiterateecall@^3.0.0: - version "3.0.9" - resolved "https://registry.yarnpkg.com/lodash._isiterateecall/-/lodash._isiterateecall-3.0.9.tgz#5203ad7ba425fae842460e696db9cf3e6aac057c" - -lodash.create@3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/lodash.create/-/lodash.create-3.1.1.tgz#d7f2849f0dbda7e04682bb8cd72ab022461debe7" - dependencies: - lodash._baseassign "^3.0.0" - lodash._basecreate "^3.0.0" - lodash._isiterateecall "^3.0.0" - -lodash.isarguments@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz#2f573d85c6a24289ff00663b491c1d338ff3458a" - -lodash.isarray@^3.0.0: - version "3.0.4" - resolved "https://registry.yarnpkg.com/lodash.isarray/-/lodash.isarray-3.0.4.tgz#79e4eb88c36a8122af86f844aa9bcd851b5fbb55" - -lodash.keys@^3.0.0: - version "3.1.2" - resolved "https://registry.yarnpkg.com/lodash.keys/-/lodash.keys-3.1.2.tgz#4dbc0472b156be50a0b286855d1bd0b0c656098a" - dependencies: - lodash._getnative "^3.0.0" - lodash.isarguments "^3.0.0" - lodash.isarray "^3.0.0" - -lolex@1.3.2: - version "1.3.2" - resolved "https://registry.yarnpkg.com/lolex/-/lolex-1.3.2.tgz#7c3da62ffcb30f0f5a80a2566ca24e45d8a01f31" - -minimatch@^3.0.2: - version "3.0.3" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.3.tgz#2a4e4090b96b2db06a9d7df01055a62a77c9b774" - dependencies: - brace-expansion "^1.0.0" - -minimist@0.0.8: - version "0.0.8" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" - -mkdirp@0.5.1: - version "0.5.1" - resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" - dependencies: - minimist "0.0.8" - -mocha@^3.2.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/mocha/-/mocha-3.2.0.tgz#7dc4f45e5088075171a68896814e6ae9eb7a85e3" - dependencies: - browser-stdout "1.3.0" - commander "2.9.0" - debug "2.2.0" - diff "1.4.0" - escape-string-regexp "1.0.5" - glob "7.0.5" - growl "1.9.2" - json3 "3.3.2" - lodash.create "3.1.1" - mkdirp "0.5.1" - supports-color "3.1.2" - -ms@0.7.1: - version "0.7.1" - resolved "https://registry.yarnpkg.com/ms/-/ms-0.7.1.tgz#9cd13c03adbff25b65effde7ce864ee952017098" - -once@^1.3.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" - dependencies: - wrappy "1" - -path-is-absolute@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" - -samsam@1.1.2, samsam@~1.1: - version "1.1.2" - resolved "https://registry.yarnpkg.com/samsam/-/samsam-1.1.2.tgz#bec11fdc83a9fda063401210e40176c3024d1567" - -sinon-chai@^2.8.0: - version "2.8.0" - resolved "https://registry.yarnpkg.com/sinon-chai/-/sinon-chai-2.8.0.tgz#432a9bbfd51a6fc00798f4d2526a829c060687ac" - -sinon@^1.17.7: - version "1.17.7" - resolved "https://registry.yarnpkg.com/sinon/-/sinon-1.17.7.tgz#4542a4f49ba0c45c05eb2e9dd9d203e2b8efe0bf" - dependencies: - formatio "1.1.1" - lolex "1.3.2" - samsam "1.1.2" - util ">=0.10.3 <1" - -supports-color@3.1.2: - version "3.1.2" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-3.1.2.tgz#72a262894d9d408b956ca05ff37b2ed8a6e2a2d5" - dependencies: - has-flag "^1.0.0" - -type-detect@0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-0.1.1.tgz#0ba5ec2a885640e470ea4e8505971900dac58822" - -type-detect@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-1.0.0.tgz#762217cc06db258ec48908a1298e8b95121e8ea2" - -"util@>=0.10.3 <1": - version "0.10.3" - resolved "https://registry.yarnpkg.com/util/-/util-0.10.3.tgz#7afb1afe50805246489e3db7fe0ed379336ac0f9" - dependencies: - inherits "2.0.1" - -wrappy@1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" diff --git a/yarn.lock b/yarn.lock index 57960d44..dd23136f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1384,6 +1384,12 @@ for-own@^0.1.4: dependencies: for-in "^0.1.5" +formatio@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/formatio/-/formatio-1.1.1.tgz#5ed3ccd636551097383465d996199100e86161e9" + dependencies: + samsam "~1.1" + fs-exists-sync@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/fs-exists-sync/-/fs-exists-sync-0.1.0.tgz#982d6893af918e72d08dec9e8673ff2b5a8d6add" @@ -1673,6 +1679,10 @@ inherits@2, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.1: version "2.0.3" resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" +inherits@2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.1.tgz#b17d08d326b4423e568eff719f91b0b1cbdf69f1" + ini@^1.3.4: version "1.3.4" resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.4.tgz#0537cb79daf59b59a1a517dff706c86ec039162e" @@ -2041,6 +2051,10 @@ lodash@~1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/lodash/-/lodash-1.0.2.tgz#8f57560c83b59fc270bd3d561b690043430e2551" +lolex@1.3.2: + version "1.3.2" + resolved "https://registry.yarnpkg.com/lolex/-/lolex-1.3.2.tgz#7c3da62ffcb30f0f5a80a2566ca24e45d8a01f31" + longest@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/longest/-/longest-1.0.1.tgz#30a0b2da38f73770e8294a0d22e6625ed77d0097" @@ -2556,6 +2570,10 @@ rx-lite@^3.1.2: version "3.1.2" resolved "https://registry.yarnpkg.com/rx-lite/-/rx-lite-3.1.2.tgz#19ce502ca572665f3b647b10939f97fd1615f102" +samsam@1.1.2, samsam@~1.1: + version "1.1.2" + resolved "https://registry.yarnpkg.com/samsam/-/samsam-1.1.2.tgz#bec11fdc83a9fda063401210e40176c3024d1567" + semver@^4.1.0: version "4.3.6" resolved "https://registry.yarnpkg.com/semver/-/semver-4.3.6.tgz#300bc6e0e86374f7ba61068b5b1ecd57fc6532da" @@ -2576,6 +2594,19 @@ sigmund@~1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/sigmund/-/sigmund-1.0.1.tgz#3ff21f198cad2175f9f3b781853fd94d0d19b590" +sinon-chai@^2.8.0: + version "2.8.0" + resolved "https://registry.yarnpkg.com/sinon-chai/-/sinon-chai-2.8.0.tgz#432a9bbfd51a6fc00798f4d2526a829c060687ac" + +sinon@^1.17.7: + version "1.17.7" + resolved "https://registry.yarnpkg.com/sinon/-/sinon-1.17.7.tgz#4542a4f49ba0c45c05eb2e9dd9d203e2b8efe0bf" + dependencies: + formatio "1.1.1" + lolex "1.3.2" + samsam "1.1.2" + util ">=0.10.3 <1" + slash@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/slash/-/slash-1.0.0.tgz#c41f2f6c39fc16d1cd17ad4b5d896114ae470d55" @@ -2795,6 +2826,12 @@ util-deprecate@~1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" +"util@>=0.10.3 <1": + version "0.10.3" + resolved "https://registry.yarnpkg.com/util/-/util-0.10.3.tgz#7afb1afe50805246489e3db7fe0ed379336ac0f9" + dependencies: + inherits "2.0.1" + v8flags@^2.0.2: version "2.0.11" resolved "https://registry.yarnpkg.com/v8flags/-/v8flags-2.0.11.tgz#bca8f30f0d6d60612cc2c00641e6962d42ae6881" From 7aa13788930894e9ca982795f4aa445500756725 Mon Sep 17 00:00:00 2001 From: Stephan van Diepen Date: Fri, 10 Mar 2017 16:23:35 +0100 Subject: [PATCH 028/418] Run app specs in travis --- .travis.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 94a48916..3846cdde 100644 --- a/.travis.yml +++ b/.travis.yml @@ -16,10 +16,11 @@ script: - mix compile - mix test - npm test + - npm run test-app notifications: webhooks: urls: - https://webhooks.gitter.im/e/fbd8944d285c0696dc41 on_success: always # options: [always|never|change] default: always on_failure: always # options: [always|never|change] default: always - on_start: never # options: [always|never|change] default: always \ No newline at end of file + on_start: never # options: [always|never|change] default: always From 7704f48a8e0d098ba8e68a0bcc4afb2059f75b9b Mon Sep 17 00:00:00 2001 From: Dave Seleno Date: Fri, 10 Mar 2017 10:54:53 -0800 Subject: [PATCH 029/418] fix compiler & credo warnings for lib/elixir_script/passes/find_modules.ex --- lib/elixir_script/passes/find_modules.ex | 102 ++++++++++++----------- 1 file changed, 53 insertions(+), 49 deletions(-) diff --git a/lib/elixir_script/passes/find_modules.ex b/lib/elixir_script/passes/find_modules.ex index 0079aadb..143a77f5 100644 --- a/lib/elixir_script/passes/find_modules.ex +++ b/lib/elixir_script/passes/find_modules.ex @@ -3,6 +3,7 @@ defmodule ElixirScript.Passes.FindModules do alias ElixirScript.Translator.Utils alias ElixirScript.Translator.State + @spec execute(map, map) :: map def execute(compiler_data, opts) do data = Enum.reduce(compiler_data.data, [], fn(data, list) -> quoted = update_quoted(data.ast) @@ -53,15 +54,22 @@ defmodule ElixirScript.Passes.FindModules do { ast, state } end - defp do_module_processing({:defmodule, context1, [{:__aliases__, _, name} = the_alias, [do: body]]}, state, opts) do - { body, inner_modules } = make_inner_module_aliases(name, body) + + defp do_module_processing({:defmodule, _context1, [{:__aliases__, _, name} = the_alias, [do: body]]}, state, opts) do + { body, inner_modules } = make_inner_module_aliases(body) aliases = Enum.map(inner_modules, fn - ({:defmodule, _, [{:__aliases__, _, inner_module_name}, [do: inner_module_body]]}) -> + ({:defmodule, _, [{:__aliases__, _, inner_module_name}, [do: _inner_module_body]]}) -> { :alias, [], [{:__aliases__, [alias: false], name ++ inner_module_name}, [as: {:__aliases__, [alias: false], inner_module_name }] ] } end) - state = Enum.reduce(inner_modules, state, fn + state = do_module_processing_state(inner_modules, state, name, aliases, opts) + + [%{name: Utils.quoted_to_name(the_alias), type: :module, ast: do_module_processing_body(body, aliases, opts) }] ++ state + end + + defp do_module_processing_state(inner_modules, state, name, aliases, opts) do + Enum.reduce(inner_modules, state, fn ({:defmodule, context1, [{:__aliases__, context2, inner_module_name}, [do: inner_module_body]]}, state) -> module_name = Utils.quoted_to_name({:__aliases__, [], tl(name) ++ inner_module_name}) @@ -73,39 +81,36 @@ defmodule ElixirScript.Passes.FindModules do {:defmodule, context1, [{:__aliases__, context2, name ++ inner_module_name}, [do: add_aliases_to_body(inner_module_body, this_module_aliases)]]}, state, opts) end) + end - body = case body do - {:__block__, context, list } -> - list = Enum.map(list, fn - {:use, _, [module, _] } = using -> - {:use, handle_use_expression(using, module, opts) } - {:use, _, [module] } = using -> - {:use, handle_use_expression(using, module, opts) } - ast -> - {:expanded, ast} - end) - |> Enum.reduce([], fn - {:use, ast}, state -> - case ast do - {:__block__, _, list} -> - state ++ list - _ -> - state ++ [ast] - end - - {:expanded, ast}, state -> - state ++ [ast] - end) - - {:__block__, context, list} - - _ -> - body - end - - body = add_aliases_to_body(body, aliases) - - [%{name: Utils.quoted_to_name(the_alias), type: :module, ast: body }] ++ state + defp do_module_processing_body(body, aliases, opts) do + body + |> case do + {:__block__, context, list } -> + list = + list + |> Enum.map(fn + {:use, _, [module, _] } = using -> + {:use, handle_use_expression(using, module, opts) } + {:use, _, [module] } = using -> + {:use, handle_use_expression(using, module, opts) } + ast -> + {:expanded, ast} + end) + |> Enum.reduce([], fn + {:use, {:__block__, _, list}}, state -> + state ++ list + {:use, ast}, state -> + state ++ [ast] + {:expanded, ast}, state -> + state ++ [ast] + end) + + {:__block__, context, list} + _ -> + body + end + |> add_aliases_to_body(aliases) end defp add_aliases_to_body(body, aliases) do @@ -117,23 +122,21 @@ defmodule ElixirScript.Passes.FindModules do end end - defp make_inner_module_aliases(name, body) do + defp make_inner_module_aliases(body) do case body do nil -> { { :__block__, [], [] }, [] } {:__block__, context, list2 } -> - { list2, inner_modules } = Enum.partition(list2, fn(x) -> - case x do - {:defmodule, _, [{:__aliases__, _, inner_module_name}, [do: inner_module_body]]} -> + { list2, inner_modules } = Enum.partition(list2, fn + {:defmodule, _, [{:__aliases__, _, _inner_module_name}, [do: _inner_module_body]]} -> false _ -> true - end end) { {:__block__, context, list2}, inner_modules } - {:defmodule, _, [{:__aliases__, context, inner_module_name}, [do: inner_module_body]]} = mod -> + {:defmodule, _, [{:__aliases__, context, _inner_module_name}, [do: _inner_module_body]]} = mod -> { {:__block__, context, [] }, [mod] } _ -> { body, [] } @@ -162,13 +165,14 @@ defmodule ElixirScript.Passes.FindModules do defp update_quoted(quoted) do Macro.prewalk(quoted, fn ({name, context, parms}) -> - context = if context[:import] == Kernel do - context = Keyword.update!(context, :import, fn(_) -> ElixirScript.Kernel end) - else - context - end - - {name, context, parms} + context = + if context[:import] == Kernel do + Keyword.update!(context, :import, fn(_) -> ElixirScript.Kernel end) + else + context + end + + {name, context, parms} (x) -> x end) From 902d36ae5ec0a096b3b484593c282ef9e4ea9317 Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Fri, 10 Mar 2017 13:50:47 -0600 Subject: [PATCH 030/418] Update .travis.yml --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index 3846cdde..0ba9bfe9 100644 --- a/.travis.yml +++ b/.travis.yml @@ -14,6 +14,7 @@ script: - mix local.rebar --force - mix deps.get - mix compile + - npm run build - mix test - npm test - npm run test-app From c87dc7083929e1492807ec314f37693dc480098c Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Sat, 11 Mar 2017 19:17:49 -0600 Subject: [PATCH 031/418] Update test commands. Update Changelog --- CHANGELOG.md | 14 ++++++++++-- GettingStarted.md | 20 ++++++++--------- lib/elixir_script/passes/handle_output.ex | 2 +- .../translator/kernel/special_forms/call.ex | 22 +++++++++---------- package.json | 3 ++- test/app/convert-exjs | 5 ----- 6 files changed, 36 insertions(+), 30 deletions(-) delete mode 100755 test/app/convert-exjs diff --git a/CHANGELOG.md b/CHANGELOG.md index 1f6689ef..9a8ad0db 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,11 +9,21 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ### Added - `super` - `defoverridable` +- `Elixir.load` for loading generated JavaScript modules in bundled output. +Unlike `Elixir.start`, this will only call `__load` on the module and return the functions on it + +```javascript +const exports = Elixir.load(Elixir.MyApp); +exports.hello(); +``` ### Changed - `-ex` alias is now `-e` - A filename can be specified for output +### Fixed +- Make sure mix compiler works in umbrella apps + ## [0.26.1] - 2017-02-27 ### Fixed @@ -46,7 +56,7 @@ elixirscript "app/elixirscript" -o dist --js-module React:react --js-module Reac - Now bundles all output, including the boostrap code. The exported object has Elixir modules in JavaScript namespaces that are lazily loaded when called. - To start your application import the bundle according to whichever module format was selected and + To start your application import the bundle according to whichever module format was selected and then call start giving it the module and the initial args ```javascript @@ -67,7 +77,7 @@ elixirscript "app/elixirscript" -o dist --js-module React:react --js-module Reac - Updated elixir_script mix compiler to support compiling elixir_script paths in dependencies if dependency has mix compiler defined as well - Add `Collectable` protocol implementations - Updated `for` implementation to use `Collectable` -- `format` option. Can now specify the module format of output. +- `format` option. Can now specify the module format of output. Choices are: * `:es` (default) for ES Modules * `:umd` for UMD diff --git a/GettingStarted.md b/GettingStarted.md index edb35f79..6d57e4ed 100644 --- a/GettingStarted.md +++ b/GettingStarted.md @@ -30,9 +30,9 @@ This is the help output of elixirscript the elixir code string if passed the -e flag options: --js-module [:] A js module used in your code. ex: React:react - Multiple can be defined + Multiple can be defined -f --format [format] module format of output. options: es (default), common, umd - -o --output [path] places output at the given path. + -o --output [path] places output at the given path. Can be a directory or filename. -e --elixir read input as elixir code string --full-build informs the compiler to do a full build instead of an incremental one @@ -49,10 +49,10 @@ elixirscript also takes a path to your `.ex` files as well: If you look in the dist folder you'll see a file called `Elixir.App.js` -To start your application import the bundle according to whichever module format was selected and +To start your application import the bundle according to whichever module format was selected and then call start giving it the module and the initial args. -Ex. If you have a module like so +Ex. If you have a module like so ```elixir defmodule Example do start(type, args) do @@ -87,14 +87,14 @@ Add dependency to your deps in mix.exs: version: "0.1.0", elixir: "~> 1.0", deps: deps, - elixir_script: [ - input: "lib/elixirscript", - output: "priv/elixirscript/Elixir.App.js", + elixir_script: [ + input: "lib/elixirscript", + output: "priv/elixirscript/Elixir.App.js", format: :es, js_modules: [ {React, "react"}, {ReactDOM, "react-dom"} - ] + ] ], compilers: [:elixir_script] ++ Mix.compilers ] @@ -160,6 +160,6 @@ There is an [elixirscript frontend boilerplate project](https://github.com/elixi There is an Brunch plugin, [elixirscript-brunch](https://www.npmjs.com/package/elixirscript-brunch). -#### +#### elixirscript-loader -There is also a webpack loader, [elixirscript-loader](https://www.npmjs.com/package/elixirscript-loader). \ No newline at end of file +There is also a webpack loader, [elixirscript-loader](https://www.npmjs.com/package/elixirscript-loader). diff --git a/lib/elixir_script/passes/handle_output.ex b/lib/elixir_script/passes/handle_output.ex index a3bab884..eb956cdf 100644 --- a/lib/elixir_script/passes/handle_output.ex +++ b/lib/elixir_script/passes/handle_output.ex @@ -22,7 +22,7 @@ defmodule ElixirScript.Passes.HandleOutput do code -> code end - IO.write(concat(code)) + IO.write(concat(code)) end defp out(compiler_output, %{output: output_path, core_path: _}) do diff --git a/lib/elixir_script/translator/kernel/special_forms/call.ex b/lib/elixir_script/translator/kernel/special_forms/call.ex index 9225c00d..ca3d04eb 100644 --- a/lib/elixir_script/translator/kernel/special_forms/call.ex +++ b/lib/elixir_script/translator/kernel/special_forms/call.ex @@ -22,7 +22,7 @@ defmodule ElixirScript.Translator.Call do ) {ast, env} - end + end def make_local_function_call(function_name, params, env) do ast = JS.call_expression( @@ -42,7 +42,7 @@ defmodule ElixirScript.Translator.Call do Identifier.make_namespace_members(members), [JS.identifier("Elixir")] ), - Identifier.make_identifier(function_name) + Identifier.make_identifier(function_name) ), Enum.map(params, &Translator.translate!(&1, env)) ) @@ -52,7 +52,7 @@ defmodule ElixirScript.Translator.Call do def make_module_function_call(module_name, function_name, env) do make_module_function_call(module_name, function_name, [], env) - end + end def make_extern_function_or_property_call(module_name, function_name, env) do members = Module.split(module_name) @@ -87,7 +87,7 @@ defmodule ElixirScript.Translator.Call do ) {ast, env} - end + end def make_function_or_property_call(module_name, function_name, env) do js_ast = JS.call_expression( @@ -128,19 +128,19 @@ defmodule ElixirScript.Translator.Call do ] ) - {js_ast, env} + {js_ast, env} end def make_function_call(module_name, function_name, params, env) when is_atom(module_name) and is_atom(function_name) do js_ast = JS.call_expression( JS.member_expression( Identifier.make_identifier(module_name), - Identifier.make_identifier(function_name) + Identifier.make_identifier(function_name) ), Enum.map(params, &Translator.translate!(&1, env)) ) - {js_ast, env} + {js_ast, env} end def make_function_call({{:., _, _}, _, _} = module_name, function_name, [], env) do @@ -161,19 +161,19 @@ defmodule ElixirScript.Translator.Call do ] ) - {js_ast, env} + {js_ast, env} end def make_function_call({{:., _, _}, _, _} = module_name, function_name, params, env) do js_ast = JS.call_expression( JS.member_expression( Translator.translate!(module_name, env), - Identifier.make_identifier(function_name) + Identifier.make_identifier(function_name) ), Enum.map(params, &Translator.translate!(&1, env)) ) - {js_ast, env} + {js_ast, env} end def make_function_call(module_name, function_name, [], env) do @@ -195,7 +195,7 @@ defmodule ElixirScript.Translator.Call do ) {js_ast, env} - end + end def make_function_call(module_name, function_name, params, env) do call = JS.call_expression( diff --git a/package.json b/package.json index 1a5d82c4..fea12f0b 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,8 @@ "build": "rollup -c rollup.config.js", "clean": "rm -rf priv/build", "test": "mocha src/javascript/tests --recursive --compilers js:babel-core/register", - "test-app": "./test/app/convert-exjs && NODE_ENV=test mocha 'test/app/spec/*.spec.js'" + "build:test-app": "mix elixirscript test/app/src/ -f common -o test/app/build/", + "test-app": "yarn run build:test-app && NODE_ENV=test mocha 'test/app/spec/*.spec.js'" }, "repository": { "type": "git", diff --git a/test/app/convert-exjs b/test/app/convert-exjs deleted file mode 100755 index 00bd400b..00000000 --- a/test/app/convert-exjs +++ /dev/null @@ -1,5 +0,0 @@ -BASEDIR=$(dirname "$0") - -cd "$BASEDIR/../../" - -mix elixirscript test/app/src/ -f common -o test/app/build/ From edca7ba8e12e7c940ac36cffa47cc1b41bff92fc Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Sat, 11 Mar 2017 19:19:56 -0600 Subject: [PATCH 032/418] Update travis configuration to use yarn --- .travis.yml | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index 0ba9bfe9..c6facb26 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,16 +8,17 @@ env: - TRAVIS_NODE_VERSION="6" install: - rm -rf ~/.nvm && git clone https://github.com/creationix/nvm.git ~/.nvm && (cd ~/.nvm && git checkout `git describe --abbrev=0 --tags`) && source ~/.nvm/nvm.sh && nvm install $TRAVIS_NODE_VERSION - - npm install + - npm install -g yarn + - yarn script: - mix local.hex --force - mix local.rebar --force - mix deps.get - mix compile - - npm run build + - yarn build - mix test - - npm test - - npm run test-app + - yarn test + - yarn test-app notifications: webhooks: urls: From 23e2aad098789b02542ffe3a0ed6e3a21ae8f974 Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Sat, 11 Mar 2017 20:06:47 -0600 Subject: [PATCH 033/418] Add specs for atom and integer --- priv/std_lib/integer.ex | 10 ++----- test/app/spec/atom.spec.js | 14 +++++++++ test/app/spec/integer.spec.js | 53 +++++++++++++++++++++++++++++++++++ 3 files changed, 70 insertions(+), 7 deletions(-) create mode 100644 test/app/spec/atom.spec.js create mode 100644 test/app/spec/integer.spec.js diff --git a/priv/std_lib/integer.ex b/priv/std_lib/integer.ex index abfee5a2..9aaa64d0 100644 --- a/priv/std_lib/integer.ex +++ b/priv/std_lib/integer.ex @@ -8,16 +8,12 @@ defmodule ElixirScript.Integer do rem(number, 2) != 0 end - def to_char_list(number) do - to_char_list(number, 10) - end - - def to_char_list(number, base) do + def to_char_list(number, base \\ 10) do number.toString(base).split('') end - def parse(bin) do - result = Bootstrap.Core.Functions.get_global().parseInt(bin) + def parse(bin, base \\ 10) do + result = Bootstrap.Core.Functions.get_global().parseInt(bin, base) if Bootstrap.Core.Functions.get_global().isNaN(result) do :error diff --git a/test/app/spec/atom.spec.js b/test/app/spec/atom.spec.js new file mode 100644 index 00000000..89e18673 --- /dev/null +++ b/test/app/spec/atom.spec.js @@ -0,0 +1,14 @@ +const expect = require('chai').expect; +const Elixir = require('../build/Elixir.App'); + +describe('Atom', () => { + it('to_string/1', () => { + const exports = Elixir.load(Elixir.ElixirScript.Atom); + expect(exports.to_string(Symbol.for('héllo'))).to.eq('héllo'); + }); + + it('to_charlist/1', () => { + const exports = Elixir.load(Elixir.ElixirScript.Atom); + expect(exports.to_string(Symbol.for('héllo'))).to.eq('héllo'); + }); +}); diff --git a/test/app/spec/integer.spec.js b/test/app/spec/integer.spec.js new file mode 100644 index 00000000..523d0aca --- /dev/null +++ b/test/app/spec/integer.spec.js @@ -0,0 +1,53 @@ +const expect = require('chai').expect; +const Elixir = require('../build/Elixir.App'); + +describe('Integer', () => { + it('is_odd/1', () => { + const Integer = Elixir.load(Elixir.ElixirScript.Integer); + + expect(Integer.is_odd(0)).to.eq(false); + expect(Integer.is_odd(1)).to.eq(true); + expect(Integer.is_odd(2)).to.eq(false); + expect(Integer.is_odd(3)).to.eq(true); + expect(Integer.is_odd(-1)).to.eq(true); + expect(Integer.is_odd(-2)).to.eq(false); + expect(Integer.is_odd(-3)).to.eq(true); + }); + + it('is_even/1', () => { + const Integer = Elixir.load(Elixir.ElixirScript.Integer); + + expect(Integer.is_even(0)).to.eq(true); + expect(Integer.is_even(1)).to.eq(false); + expect(Integer.is_even(2)).to.eq(true); + expect(Integer.is_even(3)).to.eq(false); + expect(Integer.is_even(-1)).to.eq(false); + expect(Integer.is_even(-2)).to.eq(true); + expect(Integer.is_even(-3)).to.eq(false); + }); + + it('parse/2', () => { + const Integer = Elixir.load(Elixir.ElixirScript.Integer); + expect(Integer.parse('12').values).to.eql([12, '']); + expect(Integer.parse('012').values).to.eql([12, '']); + expect(Integer.parse('+12').values).to.eql([12, '']); + expect(Integer.parse('-12').values).to.eql([-12, '']); + expect(Integer.parse('123456789').values).to.eql([123456789, '']); + expect(Integer.parse('12.5').values).to.eql([12, '.5']); + expect(Integer.parse('7.5e-3').values).to.eql([7, '.5e-3']); + // expect(Integer.parse('12x').values).to.eql([12, 'x']); + expect(Integer.parse('++1')).to.eql(Symbol.for('error')); + expect(Integer.parse('--1')).to.eql(Symbol.for('error')); + expect(Integer.parse('+-1')).to.eql(Symbol.for('error')); + expect(Integer.parse('three')).to.eql(Symbol.for('error')); + + expect(Integer.parse('12', 10).values).to.eql([12, '']); + expect(Integer.parse('-12', 12).values).to.eql([-14, '']); + expect(Integer.parse('12345678', 9).values).to.eql([6053444, '']); + expect(Integer.parse('3.14', 4).values).to.eql([3, '.14']); + expect(Integer.parse('64eb', 16).values).to.eql([25835, '']); + // expect(Integer.parse('64eb', 10).values).to.eql([64, 'eb']); + expect(Integer.parse('10', 2).values).to.eql([2, '']); + expect(Integer.parse('++4', 10)).to.eql(Symbol.for('error')); + }); +}); From 8728ab99c53ef00bac16af8f38c83012ba6dbff7 Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Sat, 11 Mar 2017 20:55:29 -0600 Subject: [PATCH 034/418] Javascript formatting --- gulpfile.js | 16 +++++++--------- rollup.config.js | 14 +++++++------- 2 files changed, 14 insertions(+), 16 deletions(-) diff --git a/gulpfile.js b/gulpfile.js index 8b68b656..ac7ed7db 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -1,13 +1,11 @@ -var gulp = require('gulp'); -var babel = require('gulp-babel'); -var sourcemaps = require('gulp-sourcemaps'); +const gulp = require('gulp'); +const babel = require('gulp-babel'); +const sourcemaps = require('gulp-sourcemaps'); -var path = './src/javascript'; +const path = './src/javascript'; -gulp.task('build', function() { - return gulp.src([path + '/**/*.js', '!' + path + '/dist_build/**/*.js', '!' + path + '/tests/**/*.js']) +gulp.task('build', () => gulp.src([`${path}/**/*.js`, `!${path}/dist_build/**/*.js`, `!${path}/tests/**/*.js`]) .pipe(sourcemaps.init()) - .pipe(babel({ presets: ["react", "stage-0"], babelrc: false })) + .pipe(babel({ presets: ['react', 'stage-0'], babelrc: false })) .pipe(sourcemaps.write()) - .pipe(gulp.dest('./src/elixirscript')); -}); + .pipe(gulp.dest('./src/elixirscript'))); diff --git a/rollup.config.js b/rollup.config.js index 6e2312d3..1f30fafa 100644 --- a/rollup.config.js +++ b/rollup.config.js @@ -1,14 +1,14 @@ -import nodeResolve from "rollup-plugin-node-resolve"; -import babel from "rollup-plugin-babel"; +import nodeResolve from 'rollup-plugin-node-resolve'; +import babel from 'rollup-plugin-babel'; export default { - entry: "src/javascript/elixir.js", - moduleName: "Bootstrap", + entry: 'src/javascript/elixir.js', + moduleName: 'Bootstrap', plugins: [ nodeResolve({ jsnext: true }), babel({ - babelrc: false - }) + babelrc: false, + }), ], - targets: [{ dest: "priv/build/iife/Elixir.Bootstrap.js", format: "iife" }] + targets: [{ dest: 'priv/build/iife/Elixir.Bootstrap.js', format: 'iife' }], }; From 5d2fda04c84860f6b2c80106741672954fc1c994 Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Sun, 12 Mar 2017 20:57:11 -0500 Subject: [PATCH 035/418] Add more tests for standard lib --- package.json | 2 +- priv/std_lib/tuple.ex | 12 ++++++------ test/app/spec/tuple.spec.js | 29 +++++++++++++++++++++++++++++ 3 files changed, 36 insertions(+), 7 deletions(-) create mode 100644 test/app/spec/tuple.spec.js diff --git a/package.json b/package.json index fea12f0b..10150ccb 100644 --- a/package.json +++ b/package.json @@ -13,7 +13,7 @@ "clean": "rm -rf priv/build", "test": "mocha src/javascript/tests --recursive --compilers js:babel-core/register", "build:test-app": "mix elixirscript test/app/src/ -f common -o test/app/build/", - "test-app": "yarn run build:test-app && NODE_ENV=test mocha 'test/app/spec/*.spec.js'" + "test-app": "yarn run build:test-app && NODE_ENV=test mocha 'test/app/spec/*.spec.js' --compilers js:babel-core/register" }, "repository": { "type": "git", diff --git a/priv/std_lib/tuple.ex b/priv/std_lib/tuple.ex index bed5e717..6751dfa6 100644 --- a/priv/std_lib/tuple.ex +++ b/priv/std_lib/tuple.ex @@ -1,5 +1,5 @@ defmodule ElixirScript.Tuple do - @moduledoc false + @moduledoc false require JS def duplicate(data, size) do @@ -15,7 +15,7 @@ defmodule ElixirScript.Tuple do end def to_list(tuple) do - tuple["value"] + tuple.values end def insert_at(tuple, index, value) do @@ -26,14 +26,14 @@ defmodule ElixirScript.Tuple do if current_index == length(tuple) do list else - list = case index == current_index do + new_list = case index == current_index do true -> list ++ [value, tuple.get(current_index)] false -> list ++ [tuple.get(current_index)] end - do_insert_at(tuple, index, value, current_index + 1, list) + do_insert_at(tuple, index, value, current_index + 1, new_list) end end @@ -45,14 +45,14 @@ defmodule ElixirScript.Tuple do if current_index == length(tuple) do list else - list = case index == current_index do + new_list = case index == current_index do true -> list false -> list ++ [tuple.get(current_index)] end - do_delete_at(tuple, index, current_index + 1, list) + do_delete_at(tuple, index, current_index + 1, new_list) end end diff --git a/test/app/spec/tuple.spec.js b/test/app/spec/tuple.spec.js new file mode 100644 index 00000000..c139aecd --- /dev/null +++ b/test/app/spec/tuple.spec.js @@ -0,0 +1,29 @@ +const expect = require('chai').expect; +const Elixir = require('../build/Elixir.App'); +const Tuple = require('../../../src/javascript/lib/core').default.Tuple; + +describe('Tuple', () => { + it('duplicate/2', () => { + const TupleModule = Elixir.load(Elixir.ElixirScript.Tuple); + expect(TupleModule.duplicate(Symbol.for('foo'), 0).values).to.eql([]); + expect(TupleModule.duplicate(Symbol.for('foo'), 3).values).to.eql([Symbol.for('foo'), Symbol.for('foo'), Symbol.for('foo')]); + }); + + it('insert_at/3', () => { + const TupleModule = Elixir.load(Elixir.ElixirScript.Tuple); + const t = new Tuple(Symbol.for('bar'), Symbol.for('baz')); + expect(TupleModule.insert_at(t, 0, Symbol.for('foo')).values).to.eql([Symbol.for('foo'), Symbol.for('bar'), Symbol.for('baz')]); + }); + + it('append/2', () => { + const TupleModule = Elixir.load(Elixir.ElixirScript.Tuple); + const t = new Tuple(Symbol.for('foo'), Symbol.for('bar')); + expect(TupleModule.append(t, Symbol.for('baz')).values).to.eql([Symbol.for('foo'), Symbol.for('bar'), Symbol.for('baz')]); + }); + + it('delete_at/2', () => { + const TupleModule = Elixir.load(Elixir.ElixirScript.Tuple); + const t = new Tuple(Symbol.for('foo'), Symbol.for('bar'), Symbol.for('baz')); + expect(TupleModule.delete_at(t, 0).values).to.eql([Symbol.for('bar'), Symbol.for('baz')]); + }); +}); From 74fc2432635ed610c6c8972ac98acc77c08cc715 Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Mon, 13 Mar 2017 21:15:45 -0500 Subject: [PATCH 036/418] Add IO module --- lib/elixir_script/translator/state.ex | 4 ++-- priv/std_lib/io.ex | 22 ++++++++++++++++++++++ test/translator/try_test.exs | 22 +++++++++++----------- 3 files changed, 35 insertions(+), 13 deletions(-) create mode 100644 priv/std_lib/io.ex diff --git a/lib/elixir_script/translator/state.ex b/lib/elixir_script/translator/state.ex index 85aec85c..bcc7b7ff 100644 --- a/lib/elixir_script/translator/state.ex +++ b/lib/elixir_script/translator/state.ex @@ -38,6 +38,7 @@ defmodule ElixirScript.Translator.State do |> Map.put(List, ElixirScript.List) |> Map.put(Process, ElixirScript.Process) |> Map.put(Regex, ElixirScript.Regex) + |> Map.put(IO, ElixirScript.IO) end def set_module_data(pid, module_data) do @@ -135,7 +136,7 @@ defmodule ElixirScript.Translator.State do def list_module_references(pid) do Agent.get(pid, fn(state) -> - Enum.map(state.modules, fn {name, module} -> + Enum.map(state.modules, fn {name, module} -> {name, Map.get(module, :refs, [])} end) end) @@ -157,4 +158,3 @@ defmodule ElixirScript.Translator.State do Agent.stop(pid) end end - diff --git a/priv/std_lib/io.ex b/priv/std_lib/io.ex new file mode 100644 index 00000000..f7dff45b --- /dev/null +++ b/priv/std_lib/io.ex @@ -0,0 +1,22 @@ +defmodule ElixirScript.IO do + + def inspect(item, opts \\ []) do + :console.log(item) + item + end + + def puts(device \\ :stdio, item) when is_binary(item) do + case device do + :stdio -> + :console.log(item) + :stderr -> + :console.warn(item) + end + end + + def warn(message) when is_binary(message) do + :console.warn("warning: #{message}") + :console.trace() + end + +end diff --git a/test/translator/try_test.exs b/test/translator/try_test.exs index 72c24681..a53ec60c 100644 --- a/test/translator/try_test.exs +++ b/test/translator/try_test.exs @@ -16,7 +16,7 @@ defmodule ElixirScript.Translator.Try.Test do Bootstrap.Core.SpecialForms._try(function() { return 1; }, Bootstrap.Core.Patterns.defmatch(Bootstrap.Core.Patterns.clause([Bootstrap.Core.Patterns.type(ArgumentError, {})], function() { - return IO.puts('Invalid argument given'); + return Elixir.ElixirScript.IO.__load(Elixir).puts('Invalid argument given'); })), null, null, null) """ @@ -38,7 +38,7 @@ defmodule ElixirScript.Translator.Try.Test do Bootstrap.Core.SpecialForms._try(function() { return 1; }, Bootstrap.Core.Patterns.defmatch(Bootstrap.Core.Patterns.clause([Bootstrap.Core.Patterns.type(ArgumentError, {})], function() { - return IO.puts('Invalid argument given'); + return Elixir.ElixirScript.IO.__load(Elixir).puts('Invalid argument given'); })), null, null, null) """ @@ -60,7 +60,7 @@ defmodule ElixirScript.Translator.Try.Test do Bootstrap.Core.SpecialForms._try(function() { return 1; },Bootstrap.Core.Patterns.defmatch(Bootstrap.Core.Patterns.clause([Bootstrap.Core.Patterns.variable()],function(x) { - return IO.puts('Invalid argument given'); + return Elixir.ElixirScript.IO.__load(Elixir).puts('Invalid argument given'); },function(x) { return Bootstrap.Core.Functions.contains(x,Object.freeze([ArgumentError.create(Object.freeze({}))])); })),null,null,null) @@ -84,7 +84,7 @@ defmodule ElixirScript.Translator.Try.Test do Bootstrap.Core.SpecialForms._try(function() { return 1; },Bootstrap.Core.Patterns.defmatch(Bootstrap.Core.Patterns.clause([Bootstrap.Core.Patterns.variable()],function(x) { - return IO.puts('Invalid argument given'); + return Elixir.ElixirScript.IO.__load(Elixir).puts('Invalid argument given'); })),null,null,null) """ @@ -109,9 +109,9 @@ defmodule ElixirScript.Translator.Try.Test do Bootstrap.Core.SpecialForms._try(function() { return 1; }, Bootstrap.Core.Patterns.defmatch(Bootstrap.Core.Patterns.clause([Bootstrap.Core.Patterns.type(ArgumentError, {})], function() { - return IO.puts('ArgumentError'); + return Elixir.ElixirScript.IO.__load(Elixir).puts('ArgumentError'); }), Bootstrap.Core.Patterns.clause([Bootstrap.Core.Patterns.variable()], function(x) { - return IO.puts('x'); + return Elixir.ElixirScript.IO.__load(Elixir).puts('x'); })), null, null, null) """ @@ -135,9 +135,9 @@ defmodule ElixirScript.Translator.Try.Test do Bootstrap.Core.SpecialForms._try(function() { return 1; }, Bootstrap.Core.Patterns.defmatch(Bootstrap.Core.Patterns.clause([Bootstrap.Core.Patterns.type(ArgumentError, {})], function() { - return IO.puts('Invalid argument given'); + return Elixir.ElixirScript.IO.__load(Elixir).puts('Invalid argument given'); })), null, null, function() { - return IO.puts('This is printed regardless if it failed or succeed'); + return Elixir.ElixirScript.IO.__load(Elixir).puts('This is printed regardless if it failed or succeed'); }) """ @@ -158,7 +158,7 @@ defmodule ElixirScript.Translator.Try.Test do Bootstrap.Core.SpecialForms._try(function() { return 1; },null,null,null,function() { - return IO.puts('This is printed regardless if it failed or succeed'); + return Elixir.ElixirScript.IO.__load(Elixir).puts('This is printed regardless if it failed or succeed'); }) """ @@ -210,9 +210,9 @@ defmodule ElixirScript.Translator.Try.Test do Bootstrap.Core.SpecialForms._try(function() { return 1; }, Bootstrap.Core.Patterns.defmatch(Bootstrap.Core.Patterns.clause([Bootstrap.Core.Patterns.type(ArgumentError, {})], function() { - return IO.puts('Invalid argument given'); + return Elixir.ElixirScript.IO.__load(Elixir).puts('Invalid argument given'); })), Bootstrap.Core.Patterns.defmatch(Bootstrap.Core.Patterns.clause([Symbol.for('throw'), Symbol.for('Error')], function() { - return IO.puts('caught error'); + return Elixir.ElixirScript.IO.__load(Elixir).puts('caught error'); })), null, null) """ From 0c060a0321612ab7215e0dc066f322b55a3cb2b5 Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Mon, 13 Mar 2017 21:21:47 -0500 Subject: [PATCH 037/418] Remove unneeded whitespace --- lib/elixir_script/passes/find_functions.ex | 28 +++++++++++----------- lib/elixir_script/passes/load_modules.ex | 10 ++++---- 2 files changed, 19 insertions(+), 19 deletions(-) diff --git a/lib/elixir_script/passes/find_functions.ex b/lib/elixir_script/passes/find_functions.ex index f78e2d38..0d627984 100644 --- a/lib/elixir_script/passes/find_functions.ex +++ b/lib/elixir_script/passes/find_functions.ex @@ -1,16 +1,16 @@ defmodule ElixirScript.Passes.FindFunctions do - @moduledoc false + @moduledoc false @function_types [:def, :defp, :defgen, :defgenp, :defmacro, :defmacrop] def execute(data, _) do new_data = Enum.map(data.data, fn { module_name, module_data } -> %{ - def: functions, - defp: private_functions, - defgen: generators, - defgenp: private_generators, - defmacro: macros, + def: functions, + defp: private_functions, + defgen: generators, + defgenp: private_generators, + defmacro: macros, defmacrop: private_macros, defdelegate: delegates } = get_functions_from_module(module_data.ast) @@ -54,7 +54,7 @@ defmodule ElixirScript.Passes.FindFunctions do ({:defdelegate, _, [{name, _, params}], _}, state) -> arity = length(params) - add_function_to_map(state, :defdelegate, name, arity) + add_function_to_map(state, :defdelegate, name, arity) _, state -> state @@ -63,12 +63,12 @@ defmodule ElixirScript.Passes.FindFunctions do end defp new_function_map() do - %{ - def: Keyword.new, - defp: Keyword.new, - defgen: Keyword.new, - defgenp: Keyword.new, - defmacro: Keyword.new, + %{ + def: Keyword.new, + defp: Keyword.new, + defgen: Keyword.new, + defgenp: Keyword.new, + defmacro: Keyword.new, defmacrop: Keyword.new, defdelegate: Keyword.new } @@ -89,4 +89,4 @@ defmodule ElixirScript.Passes.FindFunctions do end -end \ No newline at end of file +end diff --git a/lib/elixir_script/passes/load_modules.ex b/lib/elixir_script/passes/load_modules.ex index 5e57fe76..85e2edb2 100644 --- a/lib/elixir_script/passes/load_modules.ex +++ b/lib/elixir_script/passes/load_modules.ex @@ -1,18 +1,18 @@ defmodule ElixirScript.Passes.LoadModules do - @moduledoc false + @moduledoc false def execute(compiler_data, _) do ex_files = compiler_data.data - |> Enum.filter(fn + |> Enum.filter(fn {_, %{app: :elixir}} -> false %{app: :elixir} -> - false + false _ -> true - end) + end) |> Enum.map(fn { _, %{path: path} } -> path %{path: path} -> path - end) + end) loaded_modules = case Enum.reverse(ex_files) do [] -> From d90d902e4ae993ce7a18ace62bc4700f7b3d46a5 Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Mon, 13 Mar 2017 21:32:07 -0500 Subject: [PATCH 038/418] Update changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9a8ad0db..7de0f193 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ### Added - `super` - `defoverridable` +- `IO.inspect\1`, `IO.puts\1`, `IO.puts\2`, `IO.warn\1` - `Elixir.load` for loading generated JavaScript modules in bundled output. Unlike `Elixir.start`, this will only call `__load` on the module and return the functions on it From f43dd0296d2a9fb3a6baa9304e43aa5f94b17d9c Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Tue, 14 Mar 2017 22:27:13 -0500 Subject: [PATCH 039/418] Access global js items behind JS module --- CHANGELOG.md | 7 ++ lib/elixir_script/translator.ex | 26 ++++--- lib/elixir_script/translator/kernel/js.ex | 83 +++++++++++++++++++++++ priv/std_lib/atom.ex | 4 +- priv/std_lib/base.ex | 4 +- priv/std_lib/integer.ex | 4 +- priv/std_lib/io.ex | 10 +-- priv/std_lib/kernel.ex | 12 ++-- priv/std_lib/map.ex | 4 +- priv/std_lib/regex.ex | 8 +-- priv/std_lib/string.ex | 10 +-- test/translator/js_test.exs | 55 +++++++++++++++ 12 files changed, 188 insertions(+), 39 deletions(-) create mode 100644 test/translator/js_test.exs diff --git a/CHANGELOG.md b/CHANGELOG.md index 7de0f193..8801c9b3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,6 +21,13 @@ exports.hello(); ### Changed - `-ex` alias is now `-e` - A filename can be specified for output +- To access global JavaScript functions, modules, and properties, use the `JS` module +```elixir +JS.length # translates to 'length' +JS.alert() # translates to 'alert()' +JS.String.raw("hi") # translate to String.raw('hi') +JS.console.log("hi") # translates to console.log('hi') +``` ### Fixed - Make sure mix compiler works in umbrella apps diff --git a/lib/elixir_script/translator.ex b/lib/elixir_script/translator.ex index a4e30f7b..8c0ebae1 100644 --- a/lib/elixir_script/translator.ex +++ b/lib/elixir_script/translator.ex @@ -71,6 +71,18 @@ defmodule ElixirScript.Translator do js_ast end + defp do_translate({{:., _, [{:__aliases__, _, [:JS]}, function_name]}, _, params }, env) when function_name in @generator_types do + do_translate({function_name, [], params}, env) + end + + defp do_translate({{:., _, [{:__aliases__, _, [:JS]}, function_name]}, _, params }, env) do + JSLib.translate_js_function(function_name, params, env) + end + + defp do_translate({{:., _, [{:__aliases__, context, [:JS | rest]}, function_name]}, _, params }, env) do + JSLib.translate_js_function({:__aliases__, context, rest}, function_name, params, env) + end + defp do_translate(ast, env) when is_number(ast) or is_binary(ast) or is_boolean(ast) or is_nil(ast) do { Primitive.make_literal(ast), env } end @@ -247,7 +259,7 @@ defmodule ElixirScript.Translator do { name, _ } = env.function super_name = String.to_atom("__super__" <> to_string(name)) - Call.make_local_function_call(super_name, params, env) + Call.make_local_function_call(super_name, params, env) end defp do_translate({{:., _, [function_name]}, _, params}, env) do @@ -292,14 +304,6 @@ defmodule ElixirScript.Translator do translate({{:., context1, [{:__aliases__, context2, [:Bootstrap, :Enum]}, function_name]}, context3, params }, env) end - defp do_translate({{:., _, [{:__aliases__, _, [:JS]}, function_name]}, _, params }, env) when function_name in @generator_types do - do_translate({function_name, [], params}, env) - end - - defp do_translate({{:., _, [{:__aliases__, _, [:JS]}, function_name]}, _, params }, env) do - JSLib.translate_js_function(function_name, params, env) - end - defp do_translate({{:., _, [{:__aliases__, _, _} = module_name, function_name]}, _, params } = ast, env) do expanded_ast = Macro.expand(ast, env.env) @@ -324,7 +328,7 @@ defmodule ElixirScript.Translator do else translate(expanded_ast, env) end - end + end defp do_translate({{:., _, [module_name, function_name]}, _, params } = ast, env) do expanded_ast = Macro.expand(ast, env.env) @@ -696,7 +700,7 @@ defmodule ElixirScript.Translator do else module_name end - end + end def has_function?(module_name, name_arity, env) do case ElixirScript.Translator.State.get_module(env.state, module_name) do diff --git a/lib/elixir_script/translator/kernel/js.ex b/lib/elixir_script/translator/kernel/js.ex index 1d7dc8ad..af194137 100644 --- a/lib/elixir_script/translator/kernel/js.ex +++ b/lib/elixir_script/translator/kernel/js.ex @@ -3,6 +3,39 @@ defmodule ElixirScript.Translator.JS do alias ESTree.Tools.Builder alias ElixirScript.Translator + alias ElixirScript.Translator.Utils + alias ElixirScript.Translator.Identifier + + def call_property() do + Builder.member_expression( + Builder.member_expression( + Builder.identifier("Bootstrap"), + Builder.member_expression( + Builder.identifier("Core"), + Builder.identifier("Functions") + ) + ), + Builder.identifier("call_property") + ) + end + + def global() do + Builder.member_expression( + Builder.member_expression( + Builder.identifier("Bootstrap"), + Builder.member_expression( + Builder.identifier("Core"), + Builder.identifier("Functions") + ) + ), + Builder.identifier("get_global") + ) + end + + @doc false + def translate_js_function({:__aliases__, _, module}, name, params, env) do + { do_translate(module, {name, [], params}, env), env } + end @doc false def translate_js_function(name, params, env) do @@ -89,4 +122,54 @@ defmodule ElixirScript.Translator.JS do Translator.translate!({ :%{}, [], args }, env) end + defp do_translate({function, _, []}, env) do + Builder.call_expression( + call_property(), + [ + Builder.call_expression(global(), []), + Translator.translate!(to_string(function), env) + ] + ) + end + + defp do_translate({function, _, params}, env) do + Builder.call_expression( + Builder.member_expression( + Builder.call_expression(global(), []), + Builder.identifier(function) + ), + Enum.map(params, &Translator.translate!(&1, env)) + ) + end + + defp do_translate(module, {function, _, []}, env) do + members = Identifier.make_namespace_members(module) + + Builder.call_expression( + call_property(), + [ + Builder.member_expression( + Builder.call_expression(global(), []), + members + ), + Translator.translate!(to_string(function), env) + ] + ) + end + + defp do_translate(module, {function, _, params}, env) do + members = Identifier.make_namespace_members(module) + + Builder.call_expression( + Builder.member_expression( + Builder.member_expression( + Builder.call_expression(global(), []), + members + ), + Builder.identifier(function) + ), + Enum.map(params, &Translator.translate!(&1, env)) + ) + end + end diff --git a/priv/std_lib/atom.ex b/priv/std_lib/atom.ex index f932c1d2..786ded55 100644 --- a/priv/std_lib/atom.ex +++ b/priv/std_lib/atom.ex @@ -1,5 +1,5 @@ defmodule ElixirScript.Atom do - @moduledoc false + @moduledoc false import Kernel, except: [to_string: 1] def to_char_list(atom) do @@ -7,7 +7,7 @@ defmodule ElixirScript.Atom do end def to_string(atom) do - Symbol.keyFor(atom) + JS.Symbol.keyFor(atom) end end diff --git a/priv/std_lib/base.ex b/priv/std_lib/base.ex index 3e02779f..a91978f9 100644 --- a/priv/std_lib/base.ex +++ b/priv/std_lib/base.ex @@ -1,5 +1,5 @@ defmodule ElixirScript.Base do - @moduledoc false + @moduledoc false def encode64(data) do Bootstrap.Core.b64EncodeUnicode(data) @@ -14,7 +14,7 @@ defmodule ElixirScript.Base do end def decode64!(data) do - Bootstrap.Core.get_global().atob(data) + JS.atob(data) end end diff --git a/priv/std_lib/integer.ex b/priv/std_lib/integer.ex index 9aaa64d0..3a5bb41d 100644 --- a/priv/std_lib/integer.ex +++ b/priv/std_lib/integer.ex @@ -13,9 +13,9 @@ defmodule ElixirScript.Integer do end def parse(bin, base \\ 10) do - result = Bootstrap.Core.Functions.get_global().parseInt(bin, base) + result = JS.parseInt(bin, base) - if Bootstrap.Core.Functions.get_global().isNaN(result) do + if JS.isNaN(result) do :error else case bin.indexOf(".") do diff --git a/priv/std_lib/io.ex b/priv/std_lib/io.ex index f7dff45b..0444da1d 100644 --- a/priv/std_lib/io.ex +++ b/priv/std_lib/io.ex @@ -1,22 +1,22 @@ defmodule ElixirScript.IO do def inspect(item, opts \\ []) do - :console.log(item) + JS.console.log(item) item end def puts(device \\ :stdio, item) when is_binary(item) do case device do :stdio -> - :console.log(item) + JS.console.log(item) :stderr -> - :console.warn(item) + JS.console.warn(item) end end def warn(message) when is_binary(message) do - :console.warn("warning: #{message}") - :console.trace() + JS.console.warn("warning: #{message}") + JS.console.trace() end end diff --git a/priv/std_lib/kernel.ex b/priv/std_lib/kernel.ex index 33ad1b81..1c0a7b3e 100644 --- a/priv/std_lib/kernel.ex +++ b/priv/std_lib/kernel.ex @@ -40,7 +40,7 @@ defmodule ElixirScript.Kernel do end def abs(number) do - Math.abs(number) + JS.Math.abs(number) end def apply(fun, args) do @@ -128,23 +128,23 @@ defmodule ElixirScript.Kernel do end def map_size(term) do - Object.keys(term).length + JS.Object.keys(term).length end def max(first, second) do - Math.max(first, second) + JS.Math.max(first, second) end def min(first, second) do - Math.min(first, second) + JS.Math.min(first, second) end def round(number) do - Math.round(number) + JS.Math.round(number) end def trunc(number) do - Math.floor(number) + JS.Math.floor(number) end def tuple_size(tuple) do diff --git a/priv/std_lib/map.ex b/priv/std_lib/map.ex index e2f3b46e..66a61a48 100644 --- a/priv/std_lib/map.ex +++ b/priv/std_lib/map.ex @@ -1,6 +1,6 @@ defmodule ElixirScript.Map do @moduledoc false - + def new() do %{} end @@ -29,7 +29,7 @@ defmodule ElixirScript.Map do end def values(map) do - Object.values(map) + JS.Object.values(map) end def from_struct(struct) do diff --git a/priv/std_lib/regex.ex b/priv/std_lib/regex.ex index 17888909..e395a5d9 100644 --- a/priv/std_lib/regex.ex +++ b/priv/std_lib/regex.ex @@ -4,7 +4,7 @@ defmodule ElixirScript.Regex do def compile(source, options \\ "") do try do - {:ok, JS.new(RegExp, [source, options])} + {:ok, JS.new(JS.RegExp, [source, options])} rescue x -> {:error, x.message} @@ -12,11 +12,11 @@ defmodule ElixirScript.Regex do end def compile!(source, options \\ "") do - JS.new(RegExp, [source, options]) + JS.new(JS.RegExp, [source, options]) end def regex?(term) do - JS.instanceof(term, RegExp) + JS.instanceof(term, JS.RegExp) end def match?(regex, string) do @@ -64,7 +64,7 @@ defmodule ElixirScript.Regex do if String.contains?(opts(regex), "g") do regex else - JS.new(RegExp, [ source(regex), opts(regex) <> "g" ]) + JS.new(JS.RegExp, [ source(regex), opts(regex) <> "g" ]) end end diff --git a/priv/std_lib/string.ex b/priv/std_lib/string.ex index 2997ab63..d267ae51 100644 --- a/priv/std_lib/string.ex +++ b/priv/std_lib/string.ex @@ -3,11 +3,11 @@ defmodule ElixirScript.String do import Kernel, except: [length: 1] def to_atom(str) do - Symbol.for(str) + JS.Symbol.for(str) end def to_existing_atom(str) do - Symbol.for(str) + JS.Symbol.for(str) end def to_char_list(str) do @@ -15,15 +15,15 @@ defmodule ElixirScript.String do end def to_float(str) do - Bootstrap.Core.get_global().parseFloat(str) + JS.parseFloat(str) end def to_integer(str) do - Bootstrap.Core.get_global().parseInt(str, 10) + JS.parseInt(str, 10) end def to_integer(str, base) do - Bootstrap.Core.get_global().parseInt(str, base) + JS.parseInt(str, base) end def upcase(str) do diff --git a/test/translator/js_test.exs b/test/translator/js_test.exs new file mode 100644 index 00000000..2118dba8 --- /dev/null +++ b/test/translator/js_test.exs @@ -0,0 +1,55 @@ +defmodule ElixirScript.Translator.JS.Test do + use ExUnit.Case + import ElixirScript.TestHelper + + + test "translate global function calls" do + ex_ast = quote do: JS.alert("hi") + js_code = "Bootstrap.Core.Functions.get_global().alert('hi')" + + assert_translation(ex_ast, js_code) + + ex_ast = quote do: JS.back() + js_code = "Bootstrap.Core.Functions.call_property(Bootstrap.Core.Functions.get_global(), 'back')" + + assert_translation(ex_ast, js_code) + end + + test "translate global properties" do + ex_ast = quote do: JS.length + js_code = "Bootstrap.Core.Functions.call_property(Bootstrap.Core.Functions.get_global(), 'length')" + + assert_translation(ex_ast, js_code) + end + + test "translate global module" do + ex_ast = quote do: JS.String.toString() + js_code = "Bootstrap.Core.Functions.call_property(Bootstrap.Core.Functions.get_global().String, 'toString')" + + assert_translation(ex_ast, js_code) + + ex_ast = quote do: JS.String.raw("hi") + js_code = "Bootstrap.Core.Functions.get_global().String.raw('hi')" + + assert_translation(ex_ast, js_code) + + ex_ast = quote do: JS.Something.Other.raw("hi") + js_code = "Bootstrap.Core.Functions.get_global().Something.Other.raw('hi')" + + assert_translation(ex_ast, js_code) + end + + test "translate global lowercase" do + ex_ast = quote do: JS.console.log("hi") + js_code = "Bootstrap.Core.Functions.call_property(Bootstrap.Core.Functions.get_global(), 'console').log('hi')" + + assert_translation(ex_ast, js_code) + + ex_ast = quote do: JS.window.length + js_code = "Bootstrap.Core.Functions.call_property(Bootstrap.Core.Functions.call_property(Bootstrap.Core.Functions.get_global(), 'window'), 'length')" + + assert_translation(ex_ast, js_code) + end + + +end From b2b5da7134b15479e90c9733cf2574776227104f Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Fri, 17 Mar 2017 20:13:52 -0500 Subject: [PATCH 040/418] Update for release --- CHANGELOG.md | 2 +- mix.exs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8801c9b3..1e2307f5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,7 +4,7 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/) and this project adheres to [Semantic Versioning](http://semver.org/). -## [0.27.0-dev] +## [0.27.0] - 2017-03-17 ### Added - `super` diff --git a/mix.exs b/mix.exs index 5da7fda2..6023aa53 100644 --- a/mix.exs +++ b/mix.exs @@ -4,7 +4,7 @@ defmodule ElixirScript.Mixfile do def project do [ app: :elixir_script, - version: "0.27.0-dev", + version: "0.27.0", elixir: "~> 1.0", elixirc_paths: elixirc_paths(), escript: escript_config(), From f7cb855381c65039085f524837174c1e017b0e0a Mon Sep 17 00:00:00 2001 From: Stephan van Diepen Date: Sat, 18 Mar 2017 20:16:31 +0100 Subject: [PATCH 041/418] Add js_module default option documentation --- GettingStarted.md | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/GettingStarted.md b/GettingStarted.md index 6d57e4ed..36c5f1f5 100644 --- a/GettingStarted.md +++ b/GettingStarted.md @@ -93,7 +93,8 @@ Add dependency to your deps in mix.exs: format: :es, js_modules: [ {React, "react"}, - {ReactDOM, "react-dom"} + {ReactDOM, "react-dom"}, + {Phoenix, "phoenix", default: false} ] ], compilers: [:elixir_script] ++ Mix.compilers @@ -117,7 +118,9 @@ Available options are: * `:umd` - UMD -* `js_modules`: A list of JavaScript imports to add. Each item must be 2-tuple or a 3-tuple. The third element is an optional keyword list of options. +* `js_modules`: A list of JavaScript imports to add. Each item must be 2-tuple or a 3-tuple. The third element is an optional keyword list of options: + + * `default` - Defaults to true. Set to false if the imported module has no default export. ### Macros From ec2e5abdf37a9e3dc086228c64cbb3f354237c28 Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Sat, 18 Mar 2017 20:08:46 -0500 Subject: [PATCH 042/418] Reducing javascript functions --- lib/elixir_script/translator/rewriter.ex | 62 +++---- priv/std_lib/agent.ex | 16 +- priv/std_lib/base.ex | 4 +- priv/std_lib/bootstrap/functions.ex | 57 ++++++ priv/std_lib/kernel.ex | 16 +- priv/std_lib/list.ex | 6 +- priv/std_lib/map.ex | 2 +- priv/std_lib/store.ex | 45 +++++ priv/std_lib/string.ex | 2 +- src/javascript/lib/core.js | 12 +- src/javascript/lib/core/functions.js | 215 +---------------------- src/javascript/lib/core/store.js | 46 ----- 12 files changed, 151 insertions(+), 332 deletions(-) create mode 100644 priv/std_lib/bootstrap/functions.ex create mode 100644 priv/std_lib/store.ex delete mode 100644 src/javascript/lib/core/store.js diff --git a/lib/elixir_script/translator/rewriter.ex b/lib/elixir_script/translator/rewriter.ex index c4760a7c..afd1f81b 100644 --- a/lib/elixir_script/translator/rewriter.ex +++ b/lib/elixir_script/translator/rewriter.ex @@ -1,5 +1,5 @@ defmodule ElixirScript.Translator.Rewriter do - @moduledoc false + @moduledoc false # :erlang, :lists, :maps, :beam_lib, :binary, :calendar, :digraph, # :epp, :erl_lint, :erl_internal, :erl_expand_records, :erl_eval, @@ -331,35 +331,27 @@ defmodule ElixirScript.Translator.Rewriter do end def rewrite({{:., _, [:lists, :foldl]}, _, [fun, acc, list]}) do - quote do: Bootstrap.Core.Functions.foldl(unquote(fun), unquote(acc), unquote(list)) + quote do: List.foldl(unquote(fun), unquote(acc), unquote(list)) end def rewrite({{:., _, [:lists, :foldr]}, _, [fun, acc, list]}) do - quote do: Bootstrap.Core.Functions.foldr(unquote(fun), unquote(acc), unquote(list)) + quote do: List.foldr(unquote(fun), unquote(acc), unquote(list)) end def rewrite({{:., _, [:lists, :keymember]}, _, [key, n, list]}) do - quote do: Bootstrap.Core.Functions.keymember(unquote(key), unquote(n), unquote(list)) + quote do: List.keymember?(unquote(list), unquote(key), unquote(n)) end def rewrite({{:., _, [:lists, :keydelete]}, _, [key, n, list]}) do - quote do: Bootstrap.Core.Functions.keydelete(unquote(key), unquote(n), unquote(list)) - end - - def rewrite({{:., _, [:lists, :keystore]}, _, [key, n, list, newtuple]}) do - quote do: Bootstrap.Core.Functions.keystore(unquote(key), unquote(n), unquote(list), unquote(newtuple)) - end - - def rewrite({{:., _, [:lists, :keytake]}, _, [key, n, list]}) do - quote do: Bootstrap.Core.Functions.keystore(unquote(key), unquote(n), unquote(list)) + quote do: List.keydelete(unquote(list), unquote(key), unquote(n)) end def rewrite({{:., _, [:lists, :keyfind]}, _, [key, n, list]}) do - quote do: Bootstrap.Core.Functions.keyfind(unquote(key), unquote(n), unquote(list)) + quote do: List.keyfind(unquote(list), unquote(key), unquote(n)) end def rewrite({{:., _, [:lists, :keyreplace]}, _, [key, n, list, newtuple]}) do - quote do: Bootstrap.Core.Functions.keyreplace(unquote(key), unquote(n), unquote(list), unquote(newtuple)) + quote do: List.keyreplace(unquote(list), unquote(key), unquote(n), unquote(newtuple)) end def rewrite({{:., _, [:lists, :keysort]}, _, [n, tuplelist]}) do @@ -368,27 +360,27 @@ defmodule ElixirScript.Translator.Rewriter do end def rewrite({{:., _, [:lists, :reverse]}, _, [list]}) do - quote do: Bootstrap.Core.Functions.reverse(unquote(list)) + quote do: ElixirScript.Bootstrap.Functions.reverse(unquote(list)) end def rewrite({{:., _, [:lists, :reverse]}, _, [list, tail]}) do - quote do: Bootstrap.Core.Functions.reverse(unquote(list)) ++ unquote(tail) + quote do: ElixirScript.Bootstrap.Functions.reverse(unquote(list)) ++ unquote(tail) end def rewrite({{:., _, [:lists, :flatten]}, _, [list]}) do - quote do: Bootstrap.Core.Functions.flatten(unquote(list)) + quote do: List.flatten(unquote(list)) end def rewrite({{:., _, [:lists, :flatten]}, _, [list, tail]}) do - quote do: Bootstrap.Core.Functions.flatten(unquote(list), unquote(tail)) + quote do: List.flatten(unquote(list), unquote(tail)) end def rewrite({{:., _, [:lists, :delete]}, _, [elem, list]}) do - quote do: Bootstrap.Core.Functions.remove_from_list(unquote(list), unquote(elem)) + quote do: List.delete(unquote(list), unquote(elem)) end def rewrite({{:., _, [:lists, :duplicate]}, _, [n, elem]}) do - quote do: Bootstrap.Core.Functions.duplicate(unquote(n), unquote(elem)) + quote do: List.duplicate(unquote(n), unquote(elem)) end def rewrite({{:., _, [:lists, :mapfoldl]}, _, [fun, acc, list]}) do @@ -437,15 +429,15 @@ defmodule ElixirScript.Translator.Rewriter do end def rewrite({{:., _, [:erlang, :list_to_float]}, _, [list]}) do - quote do: parseFloat(unquote(list)) + quote do: JS.parseFloat(unquote(list)) end def rewrite({{:., _, [:erlang, :list_to_integer]}, _, [list]}) do - quote do: parseInt(unquote(list)) + quote do: JS.parseInt(unquote(list)) end def rewrite({{:., _, [:erlang, :list_to_integer]}, _, [list, base]}) do - quote do: parseInt(unquote(list), unquote(base)) + quote do: JS.parseInt(unquote(list), unquote(base)) end def rewrite({{:., _, [:erlang, :integer_to_binary]}, _, [integer]}) do @@ -481,19 +473,19 @@ defmodule ElixirScript.Translator.Rewriter do end def rewrite({{:., _, [:erlang, :binary_to_float]}, _, [binary]}) do - quote do: parseFloat(unquote(binary)) + quote do: JS.parseFloat(unquote(binary)) end def rewrite({{:., _, [:erlang, :binary_to_integer]}, _, [binary]}) do - quote do: parseInt(unquote(binary)) + quote do: JS.parseInt(unquote(binary)) end def rewrite({{:., _, [:erlang, :binary_to_integer]}, _, [binary, base]}) do - quote do: parseInt(unquote(binary), unquote(base)) + quote do: JS.parseInt(unquote(binary), unquote(base)) end def rewrite({{:., _, [:maps, :is_key]}, _, [key, map]}) do - quote do: unquote(key) in Bootstrap.Core.Functions.get_object_keys(unquote(map)) + quote do: unquote(key) in ElixirScript.Bootstrap.Functions.get_object_keys(unquote(map)) end def rewrite({{:., _, [:maps, :put]}, _, [key, value, map]}) do @@ -501,23 +493,11 @@ defmodule ElixirScript.Translator.Rewriter do end def rewrite({{:., _, [:maps, :update]}, _, [key, value, map]}) do - quote do: Bootstrap.Core.Functions.update_map(unquote(map), unquote(key), unquote(value)) - end - - def rewrite({{:., _, [:maps, :find]}, _, [key, map]}) do - quote do: Bootstrap.Core.Functions.maps_find(unquote(key), unquote(map)) + quote do: Map.update!(unquote(map), unquote(key), fn(_) -> unquote(value) end) end def rewrite({{:., _, [:maps, :remove]}, _, [key, map]}) do quote do: Bootstrap.Core.Functions.delete_property_from_map(unquote(map), unquote(key)) end - def rewrite({{:., _, [:maps, :fold]}, _, [fun, init, map]}) do - quote do: Bootstrap.Core.Functions.maps_fold(unquote(fun), unquote(init), unquote(map)) - end - - def rewrite({{:., _, [:maps, :from_list]}, _, [list]}) do - quote do: Bootstrap.Core.Functions.maps_fold(unquote(list)) - end - end diff --git a/priv/std_lib/agent.ex b/priv/std_lib/agent.ex index 6000058f..6b2559de 100644 --- a/priv/std_lib/agent.ex +++ b/priv/std_lib/agent.ex @@ -11,7 +11,7 @@ defmodule ElixirScript.Agent do nil end - Bootstrap.Core.Store.create(pid, fun.(), name) + ElixirScript.Store.create(pid, fun.(), name) { :ok, pid } end @@ -24,30 +24,30 @@ defmodule ElixirScript.Agent do nil end - Bootstrap.Core.Store.create(pid, fun.(), name) + ElixirScript.Store.create(pid, fun.(), name) { :ok, pid } end def stop(agent) do - Bootstrap.Core.Store.remove(agent) + ElixirScript.Store.remove(agent) :ok end def update(agent, fun) do - current_state = Bootstrap.Core.Store.read(agent) - Bootstrap.Core.Store.update(agent, fun.(current_state)) + current_state = ElixirScript.Store.read(agent) + ElixirScript.Store.update(agent, fun.(current_state)) :ok end def get(agent, fun) do - current_state = Bootstrap.Core.Store.read(agent) + current_state = ElixirScript.Store.read(agent) fun.(current_state) end def get_and_update(agent, fun) do - current_state = Bootstrap.Core.Store.read(agent) + current_state = ElixirScript.Store.read(agent) {val, new_state} = fun.(current_state) - Bootstrap.Core.Store.update(agent, new_state) + ElixirScript.Store.update(agent, new_state) val end diff --git a/priv/std_lib/base.ex b/priv/std_lib/base.ex index a91978f9..c74e0678 100644 --- a/priv/std_lib/base.ex +++ b/priv/std_lib/base.ex @@ -2,11 +2,11 @@ defmodule ElixirScript.Base do @moduledoc false def encode64(data) do - Bootstrap.Core.b64EncodeUnicode(data) + ElixirScript.Bootstrap.b64EncodeUnicode(data) end def decode64(data) do - if Bootstrap.Core.can_decode64(data) do + if ElixirScript.Bootstrap.can_decode64(data) do {:ok, decode64!(data) } else :error diff --git a/priv/std_lib/bootstrap/functions.ex b/priv/std_lib/bootstrap/functions.ex new file mode 100644 index 00000000..6d1e225c --- /dev/null +++ b/priv/std_lib/bootstrap/functions.ex @@ -0,0 +1,57 @@ +defmodule ElixirScript.Bootstrap.Functions do + + def contains(left, []) do + false + end + + def contains(left, [right]) do + match?(left, right) + end + + def contains(left, [h|t]) do + case match?(left, h) do + true -> + true + false -> + contains(left, t) + end + end + + def get_object_keys(obj) do + JS.Object.keys(obj).concat(JS.Object.getOwnPropertySymbols(obj)) + end + + def is_valid_character(codepoint) do + try do + JS.String.fromCodePoint(codepoint) != nil + rescue + _ -> + false + end + end + + def b64EncodeUnicode(str) do + {:ok, regex} = Regex.compile("%([0-9A-F]{2})", "g") + + JS.btoa( + JS.encodeURIComponent(str).replace(regex, fn (match, p1) -> + JS.String.fromCharCode("0x#{p1}") + end) + ) + end + + def can_decode64(data) do + try do + JS.atob(data) + true + rescue + _ -> + false + end + end + + def reverse(list) do + list.concat([]).reverse() + end + +end diff --git a/priv/std_lib/kernel.ex b/priv/std_lib/kernel.ex index 1c0a7b3e..f085f075 100644 --- a/priv/std_lib/kernel.ex +++ b/priv/std_lib/kernel.ex @@ -44,11 +44,11 @@ defmodule ElixirScript.Kernel do end def apply(fun, args) do - Bootstrap.Core.Functions.apply(fun, args) + fun.apply(fun, args) end def apply(module, fun, args) do - Bootstrap.Core.Functions.apply(module, Atom.to_string(fun), args) + module[Atom.to_string(fun)].apply(module[Atom.to_string(fun)], args) end def binary_part(binary, start, len) do @@ -80,7 +80,7 @@ defmodule ElixirScript.Kernel do end def is_float(term) do - is_number(term) && !Number.isInteger(term) + is_number(term) && !JS.Number.isInteger(term) end def is_function(term) do @@ -92,11 +92,11 @@ defmodule ElixirScript.Kernel do end def is_integer(term) do - Number.isInteger(term) + JS.Number.isInteger(term) end def is_list(term) do - Array.isArray(term) + JS.Array.isArray(term) end def is_number(term) do @@ -148,11 +148,11 @@ defmodule ElixirScript.Kernel do end def tuple_size(tuple) do - Bootstrap.Core.Functions.size(tuple) + tuple.count() end def elem(tuple, index) do - Bootstrap.Core.Functions.apply(tuple, "get", [index]) + apply(tuple, :get, [index]) end def is_nil(term) do @@ -193,7 +193,7 @@ defmodule ElixirScript.Kernel do defmacro left in right do quote do - Bootstrap.Core.Functions.contains(unquote(left), unquote(right)) + ElixirScript.Bootstrap.Functions.contains(unquote(left), unquote(right)) end end diff --git a/priv/std_lib/list.ex b/priv/std_lib/list.ex index db553ae6..94728a16 100644 --- a/priv/std_lib/list.ex +++ b/priv/std_lib/list.ex @@ -156,11 +156,7 @@ defmodule ElixirScript.List do do_foldl(tl(list), acc, func, new_list ++ [value]) end - def flatten(list) do - do_flatten(list, []) - end - - def flatten(list, tail) do + def flatten(list, tail \\ []) do do_flatten(list, []) ++ tail end diff --git a/priv/std_lib/map.ex b/priv/std_lib/map.ex index 66a61a48..2f0c4319 100644 --- a/priv/std_lib/map.ex +++ b/priv/std_lib/map.ex @@ -6,7 +6,7 @@ defmodule ElixirScript.Map do end def keys(map) do - Bootstrap.Core.Functions.get_object_keys(map) + ElixirScript.Bootstrap.Functions.get_object_keys(map) end def size(map) do diff --git a/priv/std_lib/store.ex b/priv/std_lib/store.ex new file mode 100644 index 00000000..83955381 --- /dev/null +++ b/priv/std_lib/store.ex @@ -0,0 +1,45 @@ +defmodule ElixirScript.Store do + + defp get_key(key) do + + real_key = case JS.__elixirscript_names__.has(key) do + true -> + JS.__elixirscript_names__.get(key) + false -> + key + end + + + case JS.__elixirscript_store__.has(real_key) do + true -> + real_key + false -> + JS.throw JS.new(JS.Error("Key Not Found")) + end + end + + def create(key, value, name \\ nil) do + if name != nil do + JS.__elixirscript_names__.set(name, key) + end + + JS.__elixirscript_store__.set(key, value) + end + + def update(key, value) do + real_key = get_key(key) + JS.__elixirscript_store__.set(real_key, value) + end + + def read(key) do + real_key = get_key(key) + JS.__elixirscript_store__.get(real_key) + end + + def remove(key) do + real_key = get_key(key) + JS.__elixirscript_store__.delete(real_key) + end + + +end diff --git a/priv/std_lib/string.ex b/priv/std_lib/string.ex index d267ae51..1ff6bcee 100644 --- a/priv/std_lib/string.ex +++ b/priv/std_lib/string.ex @@ -199,6 +199,6 @@ defmodule ElixirScript.String do end def valid_character?(codepoint) do - Bootstrap.Core.Functions.is_valid_character(codepoint) + ElixirScript.Bootstrap.Functions.is_valid_character(codepoint) end end diff --git a/src/javascript/lib/core.js b/src/javascript/lib/core.js index d8bccde4..8b488fb8 100644 --- a/src/javascript/lib/core.js +++ b/src/javascript/lib/core.js @@ -1,11 +1,12 @@ -import Patterns from "tailored"; -import ErlangTypes from "erlang-types"; -import Functions from "./core/functions"; -import SpecialForms from "./core/special_forms"; -import Store from "./core/store"; +import Patterns from 'tailored'; +import ErlangTypes from 'erlang-types'; +import Functions from './core/functions'; +import SpecialForms from './core/special_forms'; class Integer {} class Float {} +Functions.get_global().__elixirscript_store__ = new Map(); +Functions.get_global().__elixirscript_names__ = new Map(); export default { Tuple: ErlangTypes.Tuple, @@ -16,5 +17,4 @@ export default { Float, Functions, SpecialForms, - Store }; diff --git a/src/javascript/lib/core/functions.js b/src/javascript/lib/core/functions.js index 8b09d2f0..99d3b8ec 100644 --- a/src/javascript/lib/core/functions.js +++ b/src/javascript/lib/core/functions.js @@ -31,24 +31,6 @@ function call_property(item, property) { return item[prop]; } -function apply(...args) { - if (args.length === 2) { - return args[0].apply(args[0], args.slice(1)); - } else { - return args[0][args[1]].apply(args[0], args.slice(2)); - } -} - -function contains(left, right) { - for (const x of right) { - if (Core.Patterns.match_or_default(left, x) != null) { - return true; - } - } - - return false; -} - function get_global() { if (typeof self !== 'undefined') { return self; @@ -105,26 +87,6 @@ function defimpl(protocol, type, impl) { protocol.implementation(type, impl); } -function get_object_keys(obj) { - return Object.keys(obj).concat(Object.getOwnPropertySymbols(obj)); -} - -function is_valid_character(codepoint) { - try { - return String.fromCodePoint(codepoint) != null; - } catch (e) { - return false; - } -} - -// https://developer.mozilla.org/en-US/docs/Web/API/WindowBase64/Base64_encoding_and_decoding#Solution_2_%E2%80%93_rewrite_the_DOMs_atob()_and_btoa()_using_JavaScript's_TypedArrays_and_UTF-8 -function b64EncodeUnicode(str) { - return btoa( - encodeURIComponent(str).replace(/%([0-9A-F]{2})/g, (match, p1) => - String.fromCharCode(`0x${p1}`)) - ); -} - function delete_property_from_map(map, property) { const new_map = Object.assign(Object.create(map.constructor.prototype), map); delete new_map[property]; @@ -143,14 +105,6 @@ function add_property_to_map(map, property, value) { return Object.freeze(new_map); } -function update_map(map, property, value) { - if (property in get_object_keys(map)) { - return add_property_to_map(map, property, value); - } - - throw 'map does not have key'; -} - function bnot(expr) { return ~expr; } @@ -201,143 +155,6 @@ function zip(list_of_lists) { return Object.freeze(new_value); } -function can_decode64(data) { - try { - atob(data); - return true; - } catch (e) { - return false; - } -} - -function remove_from_list(list, element) { - let found = false; - - return list.filter(elem => { - if (!found && elem === element) { - found = true; - return false; - } - - return true; - }); -} - -function foldl(fun, acc, list) { - let acc1 = acc; - - for (const el of list) { - acc1 = fun(el, acc1); - } - - return acc1; -} - -function foldr(fun, acc, list) { - let acc1 = acc; - - for (let i = list.length - 1; i >= 0; i--) { - acc1 = fun(list[i], acc1); - } - - return acc1; -} - -function keyfind(key, n, tuplelist) { - for (let i = tuplelist.length - 1; i >= 0; i--) { - if (tuplelist[i].get(n) === key) { - return tuplelist[i]; - } - } - - return false; -} - -function keydelete(key, n, tuplelist) { - for (let i = tuplelist.length - 1; i >= 0; i--) { - if (tuplelist[i].get(n) === key) { - return tuplelist.concat([]).splice(i, 1); - } - } - - return tuplelist; -} - -function keystore(key, n, list, newtuple) { - for (let i = list.length - 1; i >= 0; i--) { - if (list[i].get(n) === key) { - return list.concat([]).splice(i, 1, newtuple); - } - } - - return list.concat([]).push(newtuple); -} - -function keymember(key, n, list) { - for (let i = list.length - 1; i >= 0; i--) { - if (list[i].get(n) === key) { - return true; - } - } - - return false; -} - -function keytake(key, n, list) { - if (!keymember(key, n, list)) { - return false; - } - - const tuple = keyfind(key, n, list); - - return new Core.Tuple(tuple.get(n), tuple, keydelete(key, n, list)); -} - -function keyreplace(key, n, list, newtuple) { - for (let i = list.length - 1; i >= 0; i--) { - if (list[i].get(n) === key) { - return list.concat([]).splice(i, 1, newtuple); - } - } - - return list; -} - -function reverse(list) { - return list.concat([]).reverse(); -} - -function maps_find(key, map) { - if (key in get_object_keys(map)) { - return new Core.Tuple(Symbol.for('ok'), map[key]); - } - return Symbol.for('error'); -} - -function flatten(list, tail = []) { - let new_list = []; - - for (const e of list) { - if (Array.isArray(e)) { - new_list = new_list.concat(flatten(e)); - } else { - new_list.push(e); - } - } - - return Object.freeze(new_list.concat(tail)); -} - -function duplicate(n, elem) { - const list = []; - - for (let i = 0; i < n; i++) { - list.push(elem); - } - - return Object.freeze(list); -} - function mapfoldl(fun, acc, list) { const newlist = []; let new_acc = acc; @@ -367,16 +184,6 @@ function filtermap(fun, list) { return Object.freeze(newlist); } -function maps_fold(fun, acc, map) { - let acc1 = acc; - - for (const k of get_object_keys(map)) { - acc1 = fun(k, map[k], acc1); - } - - return acc1; -} - function build_namespace(ns, ns_string) { let parts = ns_string.split('.'); const root = ns; @@ -402,20 +209,14 @@ function build_namespace(ns, ns_string) { export default { call_property, - apply, - contains, get_global, defstruct, defexception, defprotocol, defimpl, - get_object_keys, - is_valid_character, - b64EncodeUnicode, delete_property_from_map, add_property_to_map, class_to_obj, - can_decode64, bnot, band, bor, @@ -423,21 +224,7 @@ export default { bsr, bxor, zip, - foldl, - foldr, - remove_from_list, - keydelete, - keystore, - keyfind, - keytake, - keyreplace, - reverse, - update_map, - maps_find, - flatten, - duplicate, mapfoldl, filtermap, - maps_fold, - build_namespace + build_namespace, }; diff --git a/src/javascript/lib/core/store.js b/src/javascript/lib/core/store.js deleted file mode 100644 index bf8aa04a..00000000 --- a/src/javascript/lib/core/store.js +++ /dev/null @@ -1,46 +0,0 @@ -const store = new Map(); -const names = new Map(); - -function get_key(key) { - let real_key = key; - - if (names.has(key)) { - real_key = names.get(key); - } - - if (store.has(real_key)) { - return real_key; - } - - return new Error('Key Not Found'); -} - -function create(key, value, name = null) { - if (name != null) { - names.set(name, key); - } - - store.set(key, value); -} - -function update(key, value) { - const real_key = get_key(key); - store.set(real_key, value); -} - -function read(key) { - const real_key = get_key(key); - return store.get(real_key); -} - -function remove(key) { - const real_key = get_key(key); - return store.delete(real_key); -} - -export default { - create, - read, - update, - remove, -}; From b570fd80cf8bf3c09a823974ff90d29c72c8874e Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Sun, 19 Mar 2017 10:28:49 -0500 Subject: [PATCH 043/418] Update tests with references to JavaScript modules --- priv/std_lib/store.ex | 2 +- test/translator/case_test.exs | 4 ++-- test/translator/defdelegate_test.exs | 10 +++++----- test/translator/function_test.exs | 4 ++-- test/translator/try_test.exs | 2 +- 5 files changed, 11 insertions(+), 11 deletions(-) diff --git a/priv/std_lib/store.ex b/priv/std_lib/store.ex index 83955381..70634248 100644 --- a/priv/std_lib/store.ex +++ b/priv/std_lib/store.ex @@ -14,7 +14,7 @@ defmodule ElixirScript.Store do true -> real_key false -> - JS.throw JS.new(JS.Error("Key Not Found")) + JS.throw JS.new(JS.Error, ["Key Not Found"]) end end diff --git a/test/translator/case_test.exs b/test/translator/case_test.exs index ccdc4161..9259bb12 100644 --- a/test/translator/case_test.exs +++ b/test/translator/case_test.exs @@ -81,7 +81,7 @@ defmodule ElixirScript.Translator.Case.Test do let [value] = Bootstrap.Core.Patterns.match(Bootstrap.Core.Patterns.variable(),13); return value; },function(number) { - return Bootstrap.Core.Functions.contains(number,Object.freeze([1, 2, 3, 4])); + return Elixir.ElixirScript.Bootstrap.Functions.__load(Elixir).contains(number,Object.freeze([1, 2, 3, 4])); }),Bootstrap.Core.Patterns.clause([Bootstrap.Core.Patterns.wildcard()],function() { return true; })).call(this,data) @@ -106,7 +106,7 @@ defmodule ElixirScript.Translator.Case.Test do let [value] = Bootstrap.Core.Patterns.match(Bootstrap.Core.Patterns.variable(),13); return value; },function(number) { - return Bootstrap.Core.Functions.contains(number,Object.freeze([1, 2, 3, 4])) || Bootstrap.Core.Functions.contains(number,Object.freeze([4, 3, 2, 1])); + return Elixir.ElixirScript.Bootstrap.Functions.__load(Elixir).contains(number,Object.freeze([1, 2, 3, 4])) || Elixir.ElixirScript.Bootstrap.Functions.__load(Elixir).contains(number,Object.freeze([4, 3, 2, 1])); }),Bootstrap.Core.Patterns.clause([Bootstrap.Core.Patterns.wildcard()],function() { return true; })).call(this,data) diff --git a/test/translator/defdelegate_test.exs b/test/translator/defdelegate_test.exs index d6488ab2..52ef6266 100644 --- a/test/translator/defdelegate_test.exs +++ b/test/translator/defdelegate_test.exs @@ -7,8 +7,8 @@ defmodule ElixirScript.Translator.Defdelegate.Test do js_code = """ const reverse = function(list) { - return Bootstrap.Core.Functions.reverse(list); - }; + return Elixir.ElixirScript.Bootstrap.Functions.__load(Elixir).reverse(list); + }; """ assert_translation(ex_ast, js_code) @@ -19,10 +19,10 @@ defmodule ElixirScript.Translator.Defdelegate.Test do js_code = """ const other_reverse = function(list) { - return Bootstrap.Core.Functions.reverse(list); - }; + return Elixir.ElixirScript.Bootstrap.Functions.__load(Elixir).reverse(list); + }; """ assert_translation(ex_ast, js_code) end -end \ No newline at end of file +end diff --git a/test/translator/function_test.exs b/test/translator/function_test.exs index 77748810..c7d2018f 100644 --- a/test/translator/function_test.exs +++ b/test/translator/function_test.exs @@ -342,7 +342,7 @@ defmodule ElixirScript.Translator.Function.Test do const something = Bootstrap.Core.Patterns.defmatch(Bootstrap.Core.Patterns.clause([Bootstrap.Core.Patterns.variable(), Bootstrap.Core.Patterns.variable()],function(one,two) { return null; },function(one,two) { - return Bootstrap.Core.Functions.contains(one,Object.freeze([1, 2, 3])); + return Elixir.ElixirScript.Bootstrap.Functions.__load(Elixir).contains(one,Object.freeze([1, 2, 3])); })); """ @@ -362,7 +362,7 @@ defmodule ElixirScript.Translator.Function.Test do const something = Bootstrap.Core.Patterns.defmatch(Bootstrap.Core.Patterns.clause([Bootstrap.Core.Patterns.variable()],function(one) { return null; },function(one) { - return Bootstrap.Core.Functions.contains(one,Object.freeze([1, 2, 3])); + return Elixir.ElixirScript.Bootstrap.Functions.__load(Elixir).contains(one,Object.freeze([1, 2, 3])); }),Bootstrap.Core.Patterns.clause([Bootstrap.Core.Patterns.variable()],function(one) { return null; },function(one) { diff --git a/test/translator/try_test.exs b/test/translator/try_test.exs index a53ec60c..eaff9c47 100644 --- a/test/translator/try_test.exs +++ b/test/translator/try_test.exs @@ -62,7 +62,7 @@ defmodule ElixirScript.Translator.Try.Test do },Bootstrap.Core.Patterns.defmatch(Bootstrap.Core.Patterns.clause([Bootstrap.Core.Patterns.variable()],function(x) { return Elixir.ElixirScript.IO.__load(Elixir).puts('Invalid argument given'); },function(x) { - return Bootstrap.Core.Functions.contains(x,Object.freeze([ArgumentError.create(Object.freeze({}))])); + return Elixir.ElixirScript.Bootstrap.Functions.__load(Elixir).contains(x,Object.freeze([ArgumentError.create(Object.freeze({}))])); })),null,null,null) """ From 3c9125b85688c61cf245fbdbb8e86df3e1d84f9a Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Sun, 19 Mar 2017 15:37:02 -0500 Subject: [PATCH 044/418] Implementing more functions in Elixir. Add tests --- lib/elixir_script/translator/kernel/js.ex | 75 +++++++++++++-- lib/elixir_script/translator/rewriter.ex | 12 +-- package.json | 4 +- priv/std_lib/base.ex | 12 ++- priv/std_lib/bitwise.ex | 24 ++--- priv/std_lib/bootstrap/functions.ex | 30 +++--- priv/std_lib/js.ex | 19 +++- priv/std_lib/kernel.ex | 6 +- priv/std_lib/list.ex | 21 ++++- priv/std_lib/map.ex | 6 +- src/javascript/lib/core/functions.js | 110 ---------------------- test/app/spec/bootstrap/functions.spec.js | 28 ++++++ 12 files changed, 179 insertions(+), 168 deletions(-) create mode 100644 test/app/spec/bootstrap/functions.spec.js diff --git a/lib/elixir_script/translator/kernel/js.ex b/lib/elixir_script/translator/kernel/js.ex index af194137..74f9f73a 100644 --- a/lib/elixir_script/translator/kernel/js.ex +++ b/lib/elixir_script/translator/kernel/js.ex @@ -89,6 +89,12 @@ defmodule ElixirScript.Translator.JS do ) end + defp do_translate({:throw, _, [term]}, env) do + Builder.throw_statement( + Translator.translate!(term, env) + ) + end + defp do_translate({:new, _, [module_name, params]}, env) when not is_list(params) do Builder.new_expression( Translator.translate!(module_name, env), @@ -105,21 +111,72 @@ defmodule ElixirScript.Translator.JS do defp do_translate({:update, _, [object, map]}, env) do quoted = quote do - Object.assign(unquote(object), unquote(map)) + JS.Object.assign(unquote(object), unquote(map)) end Translator.translate!(quoted, env) end - defp do_translate({:object, _, [args]}, env) do - args = Enum.map(args, fn - { k, v } when Kernel.is_atom(k) -> - { Atom.to_string(k), v } - pair -> - pair - end) + defp do_translate({:update, _, [object, key, value]}, env) do + Builder.assignment_expression( + :=, + Builder.member_expression( + Translator.translate!(object, env), + Translator.translate!(key, env), + true + ), + Translator.translate!(value, env) + ) + end + + defp do_translate({:import, _, [term]}, env) do + Builder.call_expression( + Builder.identifier("import"), + [Translator.translate!(term, env)] + ) + end + + defp do_translate({:debugger, _, _}, env) do + Builder.debugger_statement() + end + + defp do_translate({:this, _, _}, env) do + Builder.this_expression() + end + + defp do_translate({:__delete__, _, [expr]}, env) do + {result, _} = ElixirScript.Translator.Expression.make_unary_expression(:delete, expr, env) + result + end + + defp do_translate({:__bnot__, _, [expr]}, env) do + {result, _} = ElixirScript.Translator.Expression.make_unary_expression(:"~", expr, env) + result + end + + defp do_translate({:__band__, _, [left, right]}, env) do + {result, _} = ElixirScript.Translator.Expression.make_binary_expression(:&, left, right, env) + result + end + + defp do_translate({:__bor__, _, [left, right]}, env) do + {result, _} = ElixirScript.Translator.Expression.make_binary_expression(:|, left, right, env) + result + end + + defp do_translate({:__bsl__, _, [left, right]}, env) do + {result, _} = ElixirScript.Translator.Expression.make_binary_expression(:"<<", left, right, env) + result + end + + defp do_translate({:__bsr__, _, [left, right]}, env) do + {result, _} = ElixirScript.Translator.Expression.make_binary_expression(:">>", left, right, env) + result + end - Translator.translate!({ :%{}, [], args }, env) + defp do_translate({:__bxor__, _, [left, right]}, env) do + {result, _} = ElixirScript.Translator.Expression.make_binary_expression(:^, left, right, env) + result end defp do_translate({function, _, []}, env) do diff --git a/lib/elixir_script/translator/rewriter.ex b/lib/elixir_script/translator/rewriter.ex index afd1f81b..cd018686 100644 --- a/lib/elixir_script/translator/rewriter.ex +++ b/lib/elixir_script/translator/rewriter.ex @@ -383,10 +383,6 @@ defmodule ElixirScript.Translator.Rewriter do quote do: List.duplicate(unquote(n), unquote(elem)) end - def rewrite({{:., _, [:lists, :mapfoldl]}, _, [fun, acc, list]}) do - quote do: Bootstrap.Core.Functions.mapfoldl(unquote(fun), unquote(acc), unquote(list)) - end - def rewrite({{:., _, [:lists, :sort]}, _, [list]}) do quote do: unquote(list).sort() end @@ -400,10 +396,6 @@ defmodule ElixirScript.Translator.Rewriter do quote do: unquote(list).filter(unquote(pred)) end - def rewrite({{:., _, [:lists, :filtermap]}, _, [fun, list]}) do - quote do: Bootstrap.Core.Functions.filtermap(unquote(fun), unquote(list)) - end - def rewrite({{:., _, [:lists, :concat]}, _, [things]}) do quote do: unquote(things).join("") end @@ -489,7 +481,7 @@ defmodule ElixirScript.Translator.Rewriter do end def rewrite({{:., _, [:maps, :put]}, _, [key, value, map]}) do - quote do: Bootstrap.Core.Functions.add_property_to_map(unquote(map), unquote(key), unquote(value)) + quote do: ElixirScript.Bootstrap.Functions.add_property_to_map(unquote(map), unquote(key), unquote(value)) end def rewrite({{:., _, [:maps, :update]}, _, [key, value, map]}) do @@ -497,7 +489,7 @@ defmodule ElixirScript.Translator.Rewriter do end def rewrite({{:., _, [:maps, :remove]}, _, [key, map]}) do - quote do: Bootstrap.Core.Functions.delete_property_from_map(unquote(map), unquote(key)) + quote do: ElixirScript.Bootstrap.Functions.delete_property_from_map(unquote(map), unquote(key)) end end diff --git a/package.json b/package.json index 10150ccb..bf002ba8 100644 --- a/package.json +++ b/package.json @@ -13,7 +13,7 @@ "clean": "rm -rf priv/build", "test": "mocha src/javascript/tests --recursive --compilers js:babel-core/register", "build:test-app": "mix elixirscript test/app/src/ -f common -o test/app/build/", - "test-app": "yarn run build:test-app && NODE_ENV=test mocha 'test/app/spec/*.spec.js' --compilers js:babel-core/register" + "test-app": "yarn run build:test-app && NODE_ENV=test mocha --recursive 'test/app/spec/**/*.spec.js' --compilers js:babel-core/register" }, "repository": { "type": "git", @@ -48,4 +48,4 @@ "sinon": "^1.17.7", "sinon-chai": "^2.8.0" } -} +} \ No newline at end of file diff --git a/priv/std_lib/base.ex b/priv/std_lib/base.ex index c74e0678..721de66e 100644 --- a/priv/std_lib/base.ex +++ b/priv/std_lib/base.ex @@ -5,8 +5,18 @@ defmodule ElixirScript.Base do ElixirScript.Bootstrap.b64EncodeUnicode(data) end + defp can_decode64(data) do + try do + JS.atob(data) + true + rescue + _ -> + false + end + end + def decode64(data) do - if ElixirScript.Bootstrap.can_decode64(data) do + if can_decode64(data) do {:ok, decode64!(data) } else :error diff --git a/priv/std_lib/bitwise.ex b/priv/std_lib/bitwise.ex index 83d5e1d4..bc92799e 100644 --- a/priv/std_lib/bitwise.ex +++ b/priv/std_lib/bitwise.ex @@ -2,73 +2,73 @@ defmodule ElixirScript.Bitwise do @moduledoc false defmacro bnot(expr) do quote do - Bootstrap.Core.bnot(unquote(expr)) + JS.__bnot__(unquote(expr)) end end defmacro ~~~(expr) do quote do - Bootstrap.Core.bnot(unquote(expr)) + JS.__bnot__(unquote(expr)) end end defmacro band(left, right) do quote do - Bootstrap.Core.band(unquote(left), unquote(right)) + JS.__band__(unquote(left), unquote(right)) end end defmacro left &&& right do quote do - Bootstrap.Core.band(unquote(left), unquote(right)) + JS.__band__(unquote(left), unquote(right)) end end defmacro bor(left, right) do quote do - Bootstrap.Core.bor(unquote(left), unquote(right)) + JS.__bor__(unquote(left), unquote(right)) end end defmacro left ||| right do quote do - Bootstrap.Core.bor(unquote(left), unquote(right)) + JS.__bor__(unquote(left), unquote(right)) end end defmacro bxor(left, right) do quote do - Bootstrap.Core.bxor(unquote(left), unquote(right)) + JS.__bxor__(unquote(left), unquote(right)) end end defmacro left ^^^ right do quote do - Bootstrap.Core.bxor(unquote(left), unquote(right)) + JS.__bxor__(unquote(left), unquote(right)) end end defmacro bsl(left, right) do quote do - Bootstrap.Core.bsl(unquote(left), unquote(right)) + JS.__bsl__(unquote(left), unquote(right)) end end defmacro left <<< right do quote do - Bootstrap.Core.bsl(unquote(left), unquote(right)) + JS.__bsl__(unquote(left), unquote(right)) end end defmacro bsr(left, right) do quote do - Bootstrap.Core.bsr(unquote(left), unquote(right)) + JS.__bsr__(unquote(left), unquote(right)) end end defmacro left >>> right do quote do - Bootstrap.Core.bsr(unquote(left), unquote(right)) + JS.__bsr__(unquote(left), unquote(right)) end end end diff --git a/priv/std_lib/bootstrap/functions.ex b/priv/std_lib/bootstrap/functions.ex index 6d1e225c..cae1efce 100644 --- a/priv/std_lib/bootstrap/functions.ex +++ b/priv/std_lib/bootstrap/functions.ex @@ -8,7 +8,7 @@ defmodule ElixirScript.Bootstrap.Functions do match?(left, right) end - def contains(left, [h|t]) do + def contains(left, [h|t]) do case match?(left, h) do true -> true @@ -40,18 +40,26 @@ defmodule ElixirScript.Bootstrap.Functions do ) end - def can_decode64(data) do - try do - JS.atob(data) - true - rescue - _ -> - false - end - end - def reverse(list) do list.concat([]).reverse() end + def class_to_obj(map) do + JS.Object.assign(JS.new(JS.Object, []), map) + |> JS.Object.freeze + end + +def delete_property_from_map(map, property) do + new_map = JS.Object.assign(JS.Object.create(map.constructor.prototype), map) + JS.delete(new_map[property]) + + JS.Object.freeze(new_map) +end + +def add_property_to_map(map, property, value) do + JS.Object.assign(JS.new(JS.Object, []), map) + |> JS.update(property, value) + |> JS.Object.freeze +end + end diff --git a/priv/std_lib/js.ex b/priv/std_lib/js.ex index c1f44142..d9383a9a 100644 --- a/priv/std_lib/js.ex +++ b/priv/std_lib/js.ex @@ -22,6 +22,14 @@ defmodule JS do """ defmacro update(object, map) + @doc """ + Updates an existing JavaScript object. + + ex: + JS.update elem, "width", 100 + """ + defmacro update(object, key, value) + @doc """ Returns the type of the given value """ @@ -89,11 +97,12 @@ defmodule JS do defmacro yield_to(gen) @doc """ - Provides a convenient way to create a string-based map. + Creates a breakpoint for JavaScript debuggers to stop at + """ + defmacro debugger() - Elixirscript, by default turns the following, `%{a: "b"}` into `{[Symbol.for("a")]: "b"}` in JavaScript. In order to get string keys, - one would have to do `%{"a" => "b"}` which turns into `{a: "b"}` in JavaScript. With `Kernel.object`, you can create string keyed maps - conveniently, `object(a: "b")` which turns into `{a: "b"}` + @doc """ + The current JavaScript context """ - defmacro object(args) + defmacro this() end diff --git a/priv/std_lib/kernel.ex b/priv/std_lib/kernel.ex index f085f075..01cc370a 100644 --- a/priv/std_lib/kernel.ex +++ b/priv/std_lib/kernel.ex @@ -166,10 +166,10 @@ defmodule ElixirScript.Kernel do end end - defmacro match?(left, right) do + defmacro match?(pattern, expr) do quote do - case unquote(right) do - unquote(left) -> + case unquote(expr) do + unquote(pattern) -> true _ -> false diff --git a/priv/std_lib/list.ex b/priv/std_lib/list.ex index 94728a16..156475f7 100644 --- a/priv/std_lib/list.ex +++ b/priv/std_lib/list.ex @@ -242,7 +242,24 @@ defmodule ElixirScript.List do do_keyreplace(tl(list), key, position, updated, new_tuple) end - def zip(list_of_lists) do - Bootstrap.Core.Functions.zip(list_of_lists) + def zip([]) do + [] + end + + def zip(list_of_lists) when is_list(list_of_lists) do + lengths = Enum.map(list_of_lists, fn(list) -> length(list) end) + length = apply(JS.Math, :min, lengths) + do_zip(list_of_lists, 0, length, []) + end + + defp do_zip(list_of_lists, index, length, acc) when index == length do + acc + end + + defp do_zip(list_of_lists, index, length, acc) do + values = Enum.map(list_of_lists, fn(list) -> Enum.at(list, index) end) + item = JS.new(Bootstrap.Core.Tuple, values) + + do_zip(list_of_lists, index + 1, length, acc ++ [item]) end end diff --git a/priv/std_lib/map.ex b/priv/std_lib/map.ex index 2f0c4319..2fca8243 100644 --- a/priv/std_lib/map.ex +++ b/priv/std_lib/map.ex @@ -34,13 +34,13 @@ defmodule ElixirScript.Map do def from_struct(struct) do struct - |> Bootstrap.Core.Functions.class_to_obj + |> ElixirScript.Bootstrap.Functions.class_to_obj |> delete(:__struct__) end def delete(map, key) do map - |> Bootstrap.Core.Functions.delete_property_from_map(key) + |> ElixirScript.Bootstrap.Functions.delete_property_from_map(key) end def equal?(map1, map2) do @@ -123,7 +123,7 @@ defmodule ElixirScript.Map do end def put(map, key, value) do - Bootstrap.Core.Functions.add_property_to_map(map, key, value) + ElixirScript.Bootstrap.Functions.add_property_to_map(map, key, value) end def get(map, key) do diff --git a/src/javascript/lib/core/functions.js b/src/javascript/lib/core/functions.js index 99d3b8ec..e8b9da25 100644 --- a/src/javascript/lib/core/functions.js +++ b/src/javascript/lib/core/functions.js @@ -1,5 +1,4 @@ import Protocol from './protocol'; -import Core from '../core'; function call_property(item, property) { let prop = null; @@ -87,103 +86,6 @@ function defimpl(protocol, type, impl) { protocol.implementation(type, impl); } -function delete_property_from_map(map, property) { - const new_map = Object.assign(Object.create(map.constructor.prototype), map); - delete new_map[property]; - - return Object.freeze(new_map); -} - -function class_to_obj(map) { - const new_map = Object.assign({}, map); - return Object.freeze(new_map); -} - -function add_property_to_map(map, property, value) { - const new_map = Object.assign({}, map); - new_map[property] = value; - return Object.freeze(new_map); -} - -function bnot(expr) { - return ~expr; -} - -function band(left, right) { - return left & right; -} - -function bor(left, right) { - return left | right; -} - -function bsl(left, right) { - return left << right; -} - -function bsr(left, right) { - return left >> right; -} - -function bxor(left, right) { - return left ^ right; -} - -function zip(list_of_lists) { - if (list_of_lists.length === 0) { - return Object.freeze([]); - } - - const new_value = []; - let smallest_length = list_of_lists[0]; - - for (const x of list_of_lists) { - if (x.length < smallest_length) { - smallest_length = x.length; - } - } - - for (let i = 0; i < smallest_length; i++) { - const current_value = []; - for (let j = 0; j < list_of_lists.length; j++) { - current_value.push(list_of_lists[j][i]); - } - - new_value.push(new Core.Tuple(...current_value)); - } - - return Object.freeze(new_value); -} - -function mapfoldl(fun, acc, list) { - const newlist = []; - let new_acc = acc; - - for (const x of list) { - const tup = fun(x, new_acc); - newlist.push(tup.get(0)); - new_acc = tup.get(1); - } - - return new Core.Tuple(Object.freeze(newlist), new_acc); -} - -function filtermap(fun, list) { - const newlist = []; - - for (const x of list) { - const result = fun(x); - - if (result === true) { - newlist.push(x); - } else if (result instanceof Core.Tuple) { - newlist.push(result.get(1)); - } - } - - return Object.freeze(newlist); -} - function build_namespace(ns, ns_string) { let parts = ns_string.split('.'); const root = ns; @@ -214,17 +116,5 @@ export default { defexception, defprotocol, defimpl, - delete_property_from_map, - add_property_to_map, - class_to_obj, - bnot, - band, - bor, - bsl, - bsr, - bxor, - zip, - mapfoldl, - filtermap, build_namespace, }; diff --git a/test/app/spec/bootstrap/functions.spec.js b/test/app/spec/bootstrap/functions.spec.js new file mode 100644 index 00000000..e852b388 --- /dev/null +++ b/test/app/spec/bootstrap/functions.spec.js @@ -0,0 +1,28 @@ +const expect = require('chai').expect; +const Elixir = require('../../build/Elixir.App'); + +describe('Functions', () => { + it('contains', () => { + const Functions = Elixir.load(Elixir.ElixirScript.Bootstrap.Functions); + expect(Functions.contains(1, [])).to.eq(false); + expect(Functions.contains(1, [1, 2, 3])).to.eq(true); + expect(Functions.contains(1, [1])).to.eq(true); + + expect(Functions.contains('apple', [1])).to.eq(false); + }); + + it('get_object_keys', () => { + const Functions = Elixir.load(Elixir.ElixirScript.Bootstrap.Functions); + expect(Functions.get_object_keys({})).to.eql([]); + expect(Functions.get_object_keys({ key: 1 })).to.eql(['key']); + expect( + Functions.get_object_keys({ key: 1, [Symbol.for('hi')]: 2 }), + ).to.eql(['key', Symbol.for('hi')]); + }); + + it('is_valid_character', () => { + const Functions = Elixir.load(Elixir.ElixirScript.Bootstrap.Functions); + expect(Functions.is_valid_character(42)).to.eq(true); + expect(Functions.is_valid_character(NaN)).to.eq(false); + }); +}); From fe9950eafa1850a42960a49a7e6d0032143bce85 Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Sun, 19 Mar 2017 18:55:53 -0500 Subject: [PATCH 045/418] Update implementation of contains --- priv/std_lib/bootstrap/functions.ex | 15 ++++++++++----- test/app/spec/bootstrap/functions.spec.js | 5 +++-- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/priv/std_lib/bootstrap/functions.ex b/priv/std_lib/bootstrap/functions.ex index cae1efce..c453e743 100644 --- a/priv/std_lib/bootstrap/functions.ex +++ b/priv/std_lib/bootstrap/functions.ex @@ -5,14 +5,19 @@ defmodule ElixirScript.Bootstrap.Functions do end def contains(left, [right]) do - match?(left, right) + case right do + ^left -> + true + _ -> + false + end end - def contains(left, [h|t]) do - case match?(left, h) do - true -> + def contains(left, [h|t]) do + case h do + ^left -> true - false -> + _ -> contains(left, t) end end diff --git a/test/app/spec/bootstrap/functions.spec.js b/test/app/spec/bootstrap/functions.spec.js index e852b388..2a098233 100644 --- a/test/app/spec/bootstrap/functions.spec.js +++ b/test/app/spec/bootstrap/functions.spec.js @@ -6,8 +6,9 @@ describe('Functions', () => { const Functions = Elixir.load(Elixir.ElixirScript.Bootstrap.Functions); expect(Functions.contains(1, [])).to.eq(false); expect(Functions.contains(1, [1, 2, 3])).to.eq(true); + expect(Functions.contains(4, [1, 2, 3])).to.eq(false); expect(Functions.contains(1, [1])).to.eq(true); - + expect(Functions.contains(4, [1])).to.eq(false); expect(Functions.contains('apple', [1])).to.eq(false); }); @@ -16,7 +17,7 @@ describe('Functions', () => { expect(Functions.get_object_keys({})).to.eql([]); expect(Functions.get_object_keys({ key: 1 })).to.eql(['key']); expect( - Functions.get_object_keys({ key: 1, [Symbol.for('hi')]: 2 }), + Functions.get_object_keys({ key: 1, [Symbol.for('hi')]: 2 }) ).to.eql(['key', Symbol.for('hi')]); }); From 2c90deadad02310b768fe68c9b4ca40775c27b80 Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Mon, 20 Mar 2017 22:15:35 -0500 Subject: [PATCH 046/418] Started adding enum implementation --- lib/elixir_script/translator.ex | 4 + lib/elixir_script/translator/kernel/js.ex | 8 + lib/elixir_script/translator/state.ex | 2 + priv/std_lib/base.ex | 2 +- priv/std_lib/bootstrap/functions.ex | 4 +- priv/std_lib/enum.ex | 289 ++++++++++++++++++++++ priv/std_lib/enum/out_of_bounds_error.ex | 3 + priv/std_lib/enumerable.ex | 4 +- 8 files changed, 311 insertions(+), 5 deletions(-) create mode 100644 priv/std_lib/enum.ex create mode 100644 priv/std_lib/enum/out_of_bounds_error.ex diff --git a/lib/elixir_script/translator.ex b/lib/elixir_script/translator.ex index 8c0ebae1..931ea9b3 100644 --- a/lib/elixir_script/translator.ex +++ b/lib/elixir_script/translator.ex @@ -83,6 +83,10 @@ defmodule ElixirScript.Translator do JSLib.translate_js_function({:__aliases__, context, rest}, function_name, params, env) end + defp do_translate({:__aliases__, context, [:JS | rest]}, env) do + JSLib.translate_js_module({:__aliases__, context, rest}, env) + end + defp do_translate(ast, env) when is_number(ast) or is_binary(ast) or is_boolean(ast) or is_nil(ast) do { Primitive.make_literal(ast), env } end diff --git a/lib/elixir_script/translator/kernel/js.ex b/lib/elixir_script/translator/kernel/js.ex index 74f9f73a..43c1c0d1 100644 --- a/lib/elixir_script/translator/kernel/js.ex +++ b/lib/elixir_script/translator/kernel/js.ex @@ -42,6 +42,14 @@ defmodule ElixirScript.Translator.JS do { do_translate({name, [], params}, env), env } end + def translate_js_module(module, env) do + { do_translate(module, env), env } + end + + defp do_translate({:__aliases__, _, module}, env) do + Identifier.make_namespace_members(module) + end + defp do_translate({op, _, [param]}, env) when op in [:typeof, :delete, :void, :-, :+, :!, :"~"] do Builder.unary_expression( op, diff --git a/lib/elixir_script/translator/state.ex b/lib/elixir_script/translator/state.ex index bcc7b7ff..9f02731f 100644 --- a/lib/elixir_script/translator/state.ex +++ b/lib/elixir_script/translator/state.ex @@ -23,6 +23,8 @@ defmodule ElixirScript.Translator.State do |> Map.put(Collectable, ElixirScript.Collectable) |> Map.put(String.Chars, ElixirScript.String.Chars) |> Map.put(Enumerable, ElixirScript.Enumerable) + |> Map.put(Enum, ElixirScript.Enum) + |> Map.put(Enum.OutOfBoundsError, ElixirScript.Enum.OutOfBoundsError) |> Map.put(Integer, ElixirScript.Integer) |> Map.put(Macro.Env, ElixirScript.Macro.Env) |> Map.put(View, ElixirScript.View) diff --git a/priv/std_lib/base.ex b/priv/std_lib/base.ex index 721de66e..27fcdee9 100644 --- a/priv/std_lib/base.ex +++ b/priv/std_lib/base.ex @@ -2,7 +2,7 @@ defmodule ElixirScript.Base do @moduledoc false def encode64(data) do - ElixirScript.Bootstrap.b64EncodeUnicode(data) + ElixirScript.Bootstrap.Functions.b64EncodeUnicode(data) end defp can_decode64(data) do diff --git a/priv/std_lib/bootstrap/functions.ex b/priv/std_lib/bootstrap/functions.ex index c453e743..e8e0fe93 100644 --- a/priv/std_lib/bootstrap/functions.ex +++ b/priv/std_lib/bootstrap/functions.ex @@ -36,10 +36,10 @@ defmodule ElixirScript.Bootstrap.Functions do end def b64EncodeUnicode(str) do - {:ok, regex} = Regex.compile("%([0-9A-F]{2})", "g") + regex = Regex.compile!("%([0-9A-F]{2})", "g") JS.btoa( - JS.encodeURIComponent(str).replace(regex, fn (match, p1) -> + JS.encodeURIComponent(str).replace(regex, fn (match, p1, _, _) -> JS.String.fromCharCode("0x#{p1}") end) ) diff --git a/priv/std_lib/enum.ex b/priv/std_lib/enum.ex new file mode 100644 index 00000000..a0657478 --- /dev/null +++ b/priv/std_lib/enum.ex @@ -0,0 +1,289 @@ +defmodule ElixirScript.Enum do + + def all?(enumerable, fun \\ fn(x) -> x end) do + {_, acc} = Enumerable.reduce(enumerable, {:cont, true}, fn(item, _) -> + if fun.(item) do + {:cont, true} + else + {:halt, false} + end + end) + + acc + end + + def any?(enumerable, fun \\ fn(x) -> x end) do + {_, acc} = Enumerable.reduce(enumerable, {:cont, true}, fn(item, _) -> + if fun.(item) do + {:halt, true} + else + {:cont, false} + end + end) + + acc + end + + def at(enumerable, n, default \\ nil) do + cond do + n > Enumerable.count(enumerable) -> + default + true -> + result = Enumerable.reduce(enumerable, {:cont, 0}, fn(item, acc) -> + if n == acc do + {:halt, item} + else + {:cont, acc + 1} + end + end) + + case result do + {:cont, _} -> + default + {:halt, item} -> + item + end + end + end + + def concat([enumerable]) do + enumerable + end + + def concat([h | t]) do + h.concat(t) + end + + def count(enumerable) do + {:ok, num} = Enumerable.count(enumerable) + num + end + + def count(enumerable, fun) do + {_, acc} = Enumerable.reduce(enumerable, {:cont, 0}, fn(item, acc) -> + if fun.(item) do + {:cont, acc + 1} + else + {:cont, acc} + end + end) + + acc + end + + def reduce(enumerable, fun) do + {_, result} = Enumerable.reduce(enumerable, {:cont, nil}, fn + item, nil -> + {:cont, {:acc, item}} + item, {:acc, acc} -> + {:cont, {:acc, fun.(item, acc)}} + end) + + result + end + + def reduce(enumerable, acc, fun) do + {_, result} = Enumerable.reduce(enumerable, {:cont, acc}, fn + item, acc -> + {:cont, fun.(item, acc)} + end) + + result + end + + + def map(enumerable, fun) do + reduce(enumerable, [], fn(x, acc) -> + acc ++ fun.(x) + end) + end + + def map_reduce(enumerable, acc, fun) do + reduce(enumerable, {[], acc}, fn(x, {m, acc}) -> + {v, new_acc} = fun.(x, acc) + {m ++ [v], new_acc} + end) + end + + def each(enumerable, fun) do + map(enumerable, fun) + :ok + end + + def empty?(enumerable) do + {:ok, count} = Enumerable.count(enumerable) + count == 0 + end + + def fetch(enumerable, index) do + result = Enumerable.reduce(enumerable, {:cont, 0}, fn(item, acc) -> + if index == acc do + {:halt, {:ok, item}} + else + {:cont, acc + 1} + end + end) + + case result do + {:cont, _} -> + :error + {:halt, item} -> + item + end + end + + def fetch!(enumerable, index) do + case fetch(enumerable, index) do + {:ok, item} -> + item + :error -> + raise Enum.OutOfBoundsError + end + end + + def filter(enumerable, fun) do + reduce(enumerable, [], fn(x, acc) -> + if fun.(x) do + acc ++ [x] + else + acc + end + end) + end + + def filter_map(enumerable, filter, mapper) do + reduce(enumerable, [], fn(x, acc) -> + if filter.(x) do + acc ++ [mapper.(x)] + else + acc + end + end) + end + + def find(enumerable, default \\ nil, fun) do + {_, result} = Enumerable.reduce(enumerable, {:cont, default}, fn(item, acc) -> + if fun.(item) do + {:halt, item} + else + {:cont, default} + end + end) + + result + end + + def member?(enumerable, value) do + {_, result} = Enumerable.reduce(enumerable, {:cont, false}, fn(item, acc) -> + if item == value do + {:halt, true} + else + {:cont, false} + end + end) + + result + end + + def drop(enumerable, count) do + {_, result} = Enumerable.reduce(enumerable, {:cont, {[], 0}}, fn + (item, {taken, drop_count}) -> + if drop_count < count do + {:cont, {[], drop_count + 1 }} + else + {:cont, taken ++ [item]} + end + end) + + result + end + + def drop_while(enumerable, fun) do + {_, result} = Enumerable.reduce(enumerable, {:cont, []}, fn + (item, taken) -> + if fun.(item) do + {:cont, {taken}} + else + {:cont, taken ++ [item]} + end + end) + + result + end + + + def take(enumerable, count) do + if Enumerable.count(enumerable) < count do + enumerable + else + {_, result} = Enumerable.reduce(enumerable, {:cont, {[], 0}}, fn + (item, {taken, taken_count}) -> + if taken_count == count do + {:halt, taken} + else + {:cont, {taken ++ [item], taken_count + 1}} + end + end) + + result + end + end + + def take_every(enumerable, nth) do + {_, {result, _count}} = Enumerable.reduce(enumerable, {:cont, {[], 0}}, fn + (item, {taken, count}) -> + if rem(count, nth) == 0 do + {:cont, {taken ++ [item], count + 1}} + else + {:cont, {taken, count + 1}} + end + end) + + result + end + + def take_while(enumerable, fun) do + {_, result} = Enumerable.reduce(enumerable, {:cont, []}, fn + (item, taken) -> + if fun.(item) do + {:cont, {taken ++ [item]}} + else + {:halt, taken} + end + end) + + result + end + + + def to_list(enumerable) when is_list(enumerable) do + enumerable + end + + def to_list(enumerable) do + map(enumerable, fn x -> x end) + end + + def reverse(enumerable) when is_list(enumerable) do + enumerable.concat([]).reverse() + end + + def reverse(enumerable) do + reduce(enumerable, [], fn(item, acc) -> + [item] ++ acc + end) + end + + def reverse(enumerable, tail) when is_list(enumerable) do + enumerable.concat([]).reverse() ++ tail + end + + def reverse(enumerable, tail) do + result = reduce(enumerable, [], fn(item, acc) -> + [item] ++ acc + end) + + result ++ tail + end + +end \ No newline at end of file diff --git a/priv/std_lib/enum/out_of_bounds_error.ex b/priv/std_lib/enum/out_of_bounds_error.ex new file mode 100644 index 00000000..e8ffb4b2 --- /dev/null +++ b/priv/std_lib/enum/out_of_bounds_error.ex @@ -0,0 +1,3 @@ +defmodule ElixirScript.Enum.OutOfBoundsError do + defexception message: "out of bounds error" +end \ No newline at end of file diff --git a/priv/std_lib/enumerable.ex b/priv/std_lib/enumerable.ex index 0b6d4928..9d7b641d 100644 --- a/priv/std_lib/enumerable.ex +++ b/priv/std_lib/enumerable.ex @@ -7,10 +7,10 @@ end defimpl ElixirScript.Enumerable, for: List do def count(list), - do: length(list) + do: {:ok, length(list) } def member?(list, value), - do: value in list + do: {:ok, value in list } def reduce(_, {:halt, acc}, _fun), do: {:halted, acc} def reduce(list, {:suspend, acc}, fun), do: {:suspended, acc, &reduce(list, &1, fun)} From b452a65c905409c4577c8a53fa6367704f9cb243 Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Tue, 21 Mar 2017 07:38:56 -0500 Subject: [PATCH 047/418] Add more enum functions. Add a way to turn a js iterator to a reducer --- priv/std_lib/enum.ex | 22 ++++++++++++++++++---- priv/std_lib/enumerable.ex | 21 +++++++++------------ src/javascript/lib/core/functions.js | 23 +++++++++++++++++++++++ 3 files changed, 50 insertions(+), 16 deletions(-) diff --git a/priv/std_lib/enum.ex b/priv/std_lib/enum.ex index a0657478..9db72efd 100644 --- a/priv/std_lib/enum.ex +++ b/priv/std_lib/enum.ex @@ -38,9 +38,9 @@ defmodule ElixirScript.Enum do end) case result do - {:cont, _} -> + {:done, _} -> default - {:halt, item} -> + {:halted, item} -> item end end @@ -125,9 +125,9 @@ defmodule ElixirScript.Enum do end) case result do - {:cont, _} -> + {:done, _} -> :error - {:halt, item} -> + {:halted, item} -> item end end @@ -173,6 +173,20 @@ defmodule ElixirScript.Enum do result end + def into(enumerable, collectable) do + {init, fun} = Collectable.into(collectable) + reduce(enumerable, init, fn x, acc -> + fun.(acc, {:cont, x}) + end) + end + + def into(enumerable, collectable, transform) do + {init, fun} = Collectable.into(collectable) + reduce(enumerable, init, fn x, acc -> + fun.(acc, {:cont, transform.(x)}) + end) + end + def member?(enumerable, value) do {_, result} = Enumerable.reduce(enumerable, {:cont, false}, fn(item, acc) -> if item == value do diff --git a/priv/std_lib/enumerable.ex b/priv/std_lib/enumerable.ex index 9d7b641d..889e3f05 100644 --- a/priv/std_lib/enumerable.ex +++ b/priv/std_lib/enumerable.ex @@ -7,24 +7,23 @@ end defimpl ElixirScript.Enumerable, for: List do def count(list), - do: {:ok, length(list) } + do: {:ok, list.length } def member?(list, value), do: {:ok, value in list } - def reduce(_, {:halt, acc}, _fun), do: {:halted, acc} - def reduce(list, {:suspend, acc}, fun), do: {:suspended, acc, &reduce(list, &1, fun)} - def reduce([], {:cont, acc}, _fun), do: {:done, acc} - def reduce([h | t], {:cont, acc}, fun), do: reduce(t, fun.(h, acc), fun) + def reduce(list, acc, fun), do + Bootstrap.Core.Functions.iterator_to_reducer(list, acc, fun) + end end defimpl ElixirScript.Enumerable, for: Map do def count(map) do - {:ok, map_size(map)} + {:ok, map.length} end def member?(map, {key, value}) do - {:ok, match?(^value, Map.get(map, key))} + {:ok, Map.get(map, key) == value } end def member?(_, _) do @@ -32,11 +31,9 @@ defimpl ElixirScript.Enumerable, for: Map do end def reduce(map, acc, fun) do + map + |> Map.to_list + |> Bootstrap.Core.Functions.iterator_to_reducer(acc, fun) do_reduce(Map.to_list(map), acc, fun) end - - defp do_reduce(_, {:halt, acc}, _fun), do: {:halted, acc} - defp do_reduce(list, {:suspend, acc}, fun), do: {:suspended, acc, &do_reduce(list, &1, fun)} - defp do_reduce([], {:cont, acc}, _fun), do: {:done, acc} - defp do_reduce([h | t], {:cont, acc}, fun), do: do_reduce(t, fun.(h, acc), fun) end diff --git a/src/javascript/lib/core/functions.js b/src/javascript/lib/core/functions.js index e8b9da25..52a34def 100644 --- a/src/javascript/lib/core/functions.js +++ b/src/javascript/lib/core/functions.js @@ -1,4 +1,26 @@ import Protocol from './protocol'; +import Core from '../core'; + +function iterator_to_reducer(iterable, acc, fun) { + const iterator = iterable[Symbol.iterator](); + let x = iterator.next(); + let _acc = acc; + + while (x.done === false) { + _acc = fun(x.value, _acc.get(1)); + if (_acc.get(0) === Symbol.for('halt')) { + return new Core.Tuple(Symbol.for('halted'), _acc.get(1)); + } else if (_acc.get(0) === Symbol.for('suspend')) { + return new Core.Tuple(Symbol.for('suspended'), _acc.get(1), new_acc => { + return iterator_to_reducer(iterator, new_acc, fun); + }); + } + + x = iterator.next(); + } + + return new Core.Tuple(Symbol.for('done'), _acc.get(1)); +} function call_property(item, property) { let prop = null; @@ -117,4 +139,5 @@ export default { defprotocol, defimpl, build_namespace, + iterator_to_reducer, }; From acd383fe7073bc0419549fa050f007ae94ce38e2 Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Tue, 21 Mar 2017 07:39:42 -0500 Subject: [PATCH 048/418] Fix incorrect boolean in while statement --- src/javascript/lib/core/functions.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/javascript/lib/core/functions.js b/src/javascript/lib/core/functions.js index 52a34def..1d534464 100644 --- a/src/javascript/lib/core/functions.js +++ b/src/javascript/lib/core/functions.js @@ -6,7 +6,7 @@ function iterator_to_reducer(iterable, acc, fun) { let x = iterator.next(); let _acc = acc; - while (x.done === false) { + while (x.done !== false) { _acc = fun(x.value, _acc.get(1)); if (_acc.get(0) === Symbol.for('halt')) { return new Core.Tuple(Symbol.for('halted'), _acc.get(1)); From f40fc2c7940f20b23f576483351a007d00289a9f Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Tue, 21 Mar 2017 07:40:35 -0500 Subject: [PATCH 049/418] Remove enum.js --- src/javascript/elixir.js | 2 - src/javascript/lib/enum.js | 203 ------------------------------------- 2 files changed, 205 deletions(-) delete mode 100644 src/javascript/lib/enum.js diff --git a/src/javascript/elixir.js b/src/javascript/elixir.js index 1972ade5..3f58d0a3 100644 --- a/src/javascript/elixir.js +++ b/src/javascript/elixir.js @@ -1,7 +1,5 @@ import Core from './lib/core'; -import Enum from './lib/enum'; export default { Core, - Enum }; diff --git a/src/javascript/lib/enum.js b/src/javascript/lib/enum.js deleted file mode 100644 index 13916e50..00000000 --- a/src/javascript/lib/enum.js +++ /dev/null @@ -1,203 +0,0 @@ -import Core from './core'; - -let Enum = { - - all__qmark__: function(collection, fun = (x) => x){ - for(let elem of collection){ - if(!fun(elem)){ - return false; - } - } - - return true; - }, - - any__qmark__: function(collection, fun = (x) => x){ - for(let elem of collection){ - if(fun(elem)){ - return true; - } - } - - return false; - }, - - at: function(collection, n, the_default = null){ - if(n > this.count(collection) || n < 0){ - return the_default; - } - - return collection[n]; - }, - - concat: function(...enumables){ - return enumables[0].concat(enumables[1]); - }, - - count: function(collection, fun = null){ - if(fun == null){ - return collection.length; - } else { - return collection.filter(fun).length; - } - }, - - drop: function(collection, count){ - return collection.slice(count); - }, - - drop_while: function(collection, fun){ - let count = 0; - - for(let elem of collection){ - if(fun(elem)){ - count = count + 1; - }else{ - break; - } - } - - return collection.slice(count); - }, - - each: function(collection, fun){ - for(let elem of collection){ - fun(elem); - } - }, - - empty__qmark__: function(collection){ - return collection.length === 0; - }, - - fetch: function(collection, n){ - if(Array.isArray(collection)){ - if(n < this.count(collection) && n >= 0){ - return new Core.Tuple(Symbol.for("ok"), collection[n]); - }else{ - return Symbol.for("error"); - } - } - - throw new Error("collection is not an Enumerable"); - }, - - fetch__emark__: function(collection, n){ - if(Array.isArray(collection)){ - if(n < this.count(collection) && n >= 0){ - return collection[n]; - }else{ - throw new Error("out of bounds error"); - } - } - - throw new Error("collection is not an Enumerable"); - }, - - filter: function(collection, fun){ - let result = []; - - for(let elem of collection){ - if(fun(elem)){ - result.push(elem); - } - } - - return result; - }, - - filter_map: function(collection, filter, mapper){ - return Enum.map(Enum.filter(collection, filter), mapper); - }, - - find: function(collection, if_none = null, fun){ - for(let elem of collection){ - if(fun(elem)){ - return elem; - } - } - - return if_none; - }, - - into: function(collection, list){ - return list.concat(collection); - }, - - map: function(collection, fun){ - let result = []; - - for(let elem of collection){ - result.push(fun(elem)); - } - - return result; - }, - - map_reduce: function(collection, acc, fun){ - let mapped = Object.freeze([]); - let the_acc = acc; - - for (var i = 0; i < this.count(collection); i++) { - let tuple = fun(collection[i], the_acc); - - the_acc = tuple.get(1); - mapped = Object.freeze(mapped.concat([tuple.get(0)])); - } - - return new Core.Tuple(mapped, the_acc); - }, - - member__qmark__: function(collection, value){ - return collection.includes(value); - }, - - reduce: function(collection, acc, fun){ - let the_acc = acc; - - for (var i = 0; i < this.count(collection); i++) { - let tuple = fun(collection[i], the_acc); - - the_acc = tuple.get(1); - } - - return the_acc; - }, - - take: function(collection, count){ - return collection.slice(0, count); - }, - - take_every: function(collection, nth){ - let result = []; - let index = 0; - - for(let elem of collection){ - if(index % nth === 0){ - result.push(elem); - } - } - - return Object.freeze(result); - }, - - take_while: function(collection, fun){ - let count = 0; - - for(let elem of collection){ - if(fun(elem)){ - count = count + 1; - }else{ - break; - } - } - - return collection.slice(0, count); - }, - - to_list: function(collection){ - return collection; - } -}; - -export default Enum; From 4692ceefecae1c29018997d0042650417d7a9987 Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Tue, 21 Mar 2017 20:17:45 -0500 Subject: [PATCH 050/418] Add tests for Enum module --- lib/elixir_script/translator.ex | 4 - .../translator/pattern_matching.ex | 4 - priv/std_lib/enum.ex | 72 ++++++++++---- priv/std_lib/enumerable.ex | 3 +- priv/std_lib/kernel.ex | 2 +- src/javascript/lib/core/functions.js | 2 +- test/app/spec/enum.spec.js | 94 +++++++++++++++++++ test/translator/kernel_test.exs | 2 +- 8 files changed, 151 insertions(+), 32 deletions(-) create mode 100644 test/app/spec/enum.spec.js diff --git a/lib/elixir_script/translator.ex b/lib/elixir_script/translator.ex index 931ea9b3..10657ef3 100644 --- a/lib/elixir_script/translator.ex +++ b/lib/elixir_script/translator.ex @@ -344,10 +344,6 @@ defmodule ElixirScript.Translator do end end - defp do_translate({:_, _, _}, env) do - { Identifier.make_identifier(:undefined), env } - end - defp do_translate({:__aliases__, _, aliases} = ast, env) do module_name = create_module_name2(ast, env) case module_name do diff --git a/lib/elixir_script/translator/pattern_matching.ex b/lib/elixir_script/translator/pattern_matching.ex index 241b7f45..01abe0b7 100644 --- a/lib/elixir_script/translator/pattern_matching.ex +++ b/lib/elixir_script/translator/pattern_matching.ex @@ -154,10 +154,6 @@ defmodule ElixirScript.Translator.PatternMatching do { [bound(Translator.translate!(value, env))], [nil] } end - defp do_build_match({:_, _, _}, _) do - { [wildcard()], [JS.identifier(:undefined)] } - end - defp do_build_match({:<<>>, _, elements}, env) do params = Enum.reduce(elements, [], fn ({:::, _, [{ variable, _, params }, _]}, state) when is_atom(params) -> diff --git a/priv/std_lib/enum.ex b/priv/std_lib/enum.ex index 9db72efd..caa29e54 100644 --- a/priv/std_lib/enum.ex +++ b/priv/std_lib/enum.ex @@ -25,32 +25,46 @@ defmodule ElixirScript.Enum do end def at(enumerable, n, default \\ nil) do - cond do - n > Enumerable.count(enumerable) -> + index = if n < 0 do + {_, count} = Enumerable.count(enumerable) + count + n + else + n + end + + result = Enumerable.reduce(enumerable, {:cont, 0}, fn(item, acc) -> + if index == acc do + {:halt, item} + else + {:cont, acc + 1} + end + end) + + case result do + {:done, _} -> default - true -> - result = Enumerable.reduce(enumerable, {:cont, 0}, fn(item, acc) -> - if n == acc do - {:halt, item} - else - {:cont, acc + 1} - end - end) + {:halted, item} -> + item + end + end - case result do - {:done, _} -> - default - {:halted, item} -> - item - end - end + def concat([]) do + [] end def concat([enumerable]) do enumerable end + def concat([h, t]) do + h.concat(t) + end + def concat([h | t]) do + h.concat(concat(t)) + end + + def concat(h, t) do h.concat(t) end @@ -199,19 +213,39 @@ defmodule ElixirScript.Enum do result end + def drop(enumerable, count) when count < 0 do + enumerable + |> reverse + |> drop(abs(count)) + |> reverse + end + def drop(enumerable, count) do - {_, result} = Enumerable.reduce(enumerable, {:cont, {[], 0}}, fn + {_, {result, _}} = Enumerable.reduce(enumerable, {:cont, {[], 0}}, fn (item, {taken, drop_count}) -> if drop_count < count do {:cont, {[], drop_count + 1 }} else - {:cont, taken ++ [item]} + {:cont, {taken ++ [item], drop_count}} end end) result end + def drop_every(enumerable, nth) do + {_, {result, _count}} = Enumerable.reduce(enumerable, {:cont, {[], 0}}, fn + (item, {taken, count}) -> + if rem(count, nth) == 0 do + {:cont, {taken, count + 1}} + else + {:cont, {taken ++ [item], count + 1}} + end + end) + + result + end + def drop_while(enumerable, fun) do {_, result} = Enumerable.reduce(enumerable, {:cont, []}, fn (item, taken) -> diff --git a/priv/std_lib/enumerable.ex b/priv/std_lib/enumerable.ex index 889e3f05..b9ff8e7a 100644 --- a/priv/std_lib/enumerable.ex +++ b/priv/std_lib/enumerable.ex @@ -12,7 +12,7 @@ defimpl ElixirScript.Enumerable, for: List do def member?(list, value), do: {:ok, value in list } - def reduce(list, acc, fun), do + def reduce(list, acc, fun) do Bootstrap.Core.Functions.iterator_to_reducer(list, acc, fun) end end @@ -34,6 +34,5 @@ defimpl ElixirScript.Enumerable, for: Map do map |> Map.to_list |> Bootstrap.Core.Functions.iterator_to_reducer(acc, fun) - do_reduce(Map.to_list(map), acc, fun) end end diff --git a/priv/std_lib/kernel.ex b/priv/std_lib/kernel.ex index 01cc370a..1bc4dbe4 100644 --- a/priv/std_lib/kernel.ex +++ b/priv/std_lib/kernel.ex @@ -152,7 +152,7 @@ defmodule ElixirScript.Kernel do end def elem(tuple, index) do - apply(tuple, :get, [index]) + tuple.get(index) end def is_nil(term) do diff --git a/src/javascript/lib/core/functions.js b/src/javascript/lib/core/functions.js index 1d534464..52a34def 100644 --- a/src/javascript/lib/core/functions.js +++ b/src/javascript/lib/core/functions.js @@ -6,7 +6,7 @@ function iterator_to_reducer(iterable, acc, fun) { let x = iterator.next(); let _acc = acc; - while (x.done !== false) { + while (x.done === false) { _acc = fun(x.value, _acc.get(1)); if (_acc.get(0) === Symbol.for('halt')) { return new Core.Tuple(Symbol.for('halted'), _acc.get(1)); diff --git a/test/app/spec/enum.spec.js b/test/app/spec/enum.spec.js new file mode 100644 index 00000000..bbf1757a --- /dev/null +++ b/test/app/spec/enum.spec.js @@ -0,0 +1,94 @@ +const expect = require('chai').expect; +const Elixir = require('../build/Elixir.App'); + +const Enum = Elixir.load(Elixir.ElixirScript.Enum); + +describe('Enum', () => { + it('all?/2', () => { + expect(Enum.all__qmark__([2, 4, 6], x => x % 2 === 0)).to.eql(true); + expect(Enum.all__qmark__([2, 3, 4], x => x % 2 === 0)).to.eql(false); + }); + + it('any?/2', () => { + expect(Enum.any__qmark__([2, 4, 6], x => x % 2 === 1)).to.eql(false); + expect(Enum.any__qmark__([2, 3, 4], x => x % 2 === 1)).to.eql(true); + }); + + it('at/3', () => { + expect(Enum.at([2, 4, 6], 0)).to.eql(2); + expect(Enum.at([2, 4, 6], 2)).to.eql(6); + expect(Enum.at([2, 4, 6], 4)).to.eql(null); + expect(Enum.at([2, 4, 6], 4, Symbol.for('none'))).to.eql( + Symbol.for('none'), + ); + + expect(Enum.at([2, 4, 6], -2)).to.eql(4); + expect(Enum.at([2, 4, 6], -4)).to.eql(null); + }); + + it('concat/1', () => { + expect(Enum.concat([[1, [2], 3], [4], [5, 6]])).to.eql([ + 1, + [2], + 3, + 4, + 5, + 6, + ]); + expect(Enum.concat([[], []])).to.eql([]); + expect(Enum.concat([[]])).to.eql([]); + expect(Enum.concat([])).to.eql([]); + }); + + it('concat/2', () => { + expect(Enum.concat([], [1])).to.eql([1]); + expect(Enum.concat([1, [2], 3], [4, 5])).to.eql([1, [2], 3, 4, 5]); + expect(Enum.concat([], [])).to.eql([]); + }); + + it('count/1', () => { + expect(Enum.count([1, 2, 3])).to.eql(3); + expect(Enum.count([])).to.eql(0); + expect(Enum.count([1, true, false, null])).to.eql(4); + }); + + it('count/2', () => { + expect(Enum.count([1, 2, 3], x => x % 2 === 0)).to.eql(1); + expect(Enum.count([], x => x % 2 === 0)).to.eql(0); + expect(Enum.count([1, true, false, null], x => x)).to.eql(2); + }); + + it('drop/2', () => { + expect(Enum.drop([1, 2, 3], 0)).to.eql([1, 2, 3]); + expect(Enum.drop([1, 2, 3], 1)).to.eql([2, 3]); + expect(Enum.drop([1, 2, 3], 2)).to.eql([3]); + expect(Enum.drop([1, 2, 3], 3)).to.eql([]); + expect(Enum.drop([1, 2, 3], 4)).to.eql([]); + expect(Enum.drop([1, 2, 3], -1)).to.eql([1, 2]); + expect(Enum.drop([1, 2, 3], -2)).to.eql([1]); + expect(Enum.drop([1, 2, 3], -4)).to.eql([]); + }); + + it('drop_every/2', () => { + expect(Enum.drop_every([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 2)).to.eql([ + 2, + 4, + 6, + 8, + 10, + ]); + + expect(Enum.drop_every([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 3)).to.eql([ + 2, + 3, + 5, + 6, + 8, + 9, + ]); + + expect(Enum.drop_every([], 2)).to.eql([]); + expect(Enum.drop_every([1, 2], 2)).to.eql([2]); + expect(Enum.drop_every([1, 2, 3], 0)).to.eql([1, 2, 3]); + }); +}); diff --git a/test/translator/kernel_test.exs b/test/translator/kernel_test.exs index d0041050..7c645f73 100644 --- a/test/translator/kernel_test.exs +++ b/test/translator/kernel_test.exs @@ -54,7 +54,7 @@ defmodule ElixirScript.Translator.Kernel.Test do end js_code = """ - Elixir.ElixirScript.Kernel.__load(Elixir).apply(Enum, Symbol.for('reverse'), Object.freeze([Object.freeze([1, 2, 3])])) + Elixir.ElixirScript.Kernel.__load(Elixir).apply(Elixir.ElixirScript.Enum, Symbol.for('reverse'), Object.freeze([Object.freeze([1, 2, 3])])) """ assert_translation(ex_ast, js_code) From 4864fe43199d8e8b0c1e311f7434f77640afa238 Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Wed, 22 Mar 2017 04:40:44 -0500 Subject: [PATCH 051/418] Update wildcard translation --- .../translator/kernel/special_forms/fn.ex | 1 + .../translator/pattern_matching.ex | 4 + priv/std_lib/enum.ex | 26 ++++-- src/javascript/tests/case.spec.js | 40 +++++---- src/javascript/tests/cond.spec.js | 24 ++--- src/javascript/tests/for.spec.js | 86 +++++++++--------- src/javascript/tests/try.spec.js | 40 +++++---- src/javascript/tests/with.spec.js | 89 ++++++++++--------- test/app/spec/enum.spec.js | 18 ++++ test/translator/case_test.exs | 8 +- test/translator/function_test.exs | 8 +- test/translator/list_test.exs | 2 +- test/translator/match_test.exs | 12 +-- test/translator/pattern_matching_test.exs | 2 +- test/translator/try_test.exs | 2 +- 15 files changed, 206 insertions(+), 156 deletions(-) diff --git a/lib/elixir_script/translator/kernel/special_forms/fn.ex b/lib/elixir_script/translator/kernel/special_forms/fn.ex index ffd6329a..4a8b9736 100644 --- a/lib/elixir_script/translator/kernel/special_forms/fn.ex +++ b/lib/elixir_script/translator/kernel/special_forms/fn.ex @@ -136,6 +136,7 @@ defmodule ElixirScript.Translator.Function do end defp make_function_clause(patterns, params, body, guard_body, is_generator?) do + params = Enum.filter(params, fn(x) -> is_nil(x) == false end) arguments = case guard_body do nil -> diff --git a/lib/elixir_script/translator/pattern_matching.ex b/lib/elixir_script/translator/pattern_matching.ex index 01abe0b7..e90c59e5 100644 --- a/lib/elixir_script/translator/pattern_matching.ex +++ b/lib/elixir_script/translator/pattern_matching.ex @@ -154,6 +154,10 @@ defmodule ElixirScript.Translator.PatternMatching do { [bound(Translator.translate!(value, env))], [nil] } end + defp do_build_match({:_, _, _}, _) do + { [parameter()], [JS.identifier(:__ignored__)] } + end + defp do_build_match({:<<>>, _, elements}, env) do params = Enum.reduce(elements, [], fn ({:::, _, [{ variable, _, params }, _]}, state) when is_atom(params) -> diff --git a/priv/std_lib/enum.ex b/priv/std_lib/enum.ex index caa29e54..28bb4848 100644 --- a/priv/std_lib/enum.ex +++ b/priv/std_lib/enum.ex @@ -9,6 +9,8 @@ defmodule ElixirScript.Enum do end end) + IO.inspect acc + acc end @@ -247,18 +249,32 @@ defmodule ElixirScript.Enum do end def drop_while(enumerable, fun) do - {_, result} = Enumerable.reduce(enumerable, {:cont, []}, fn - (item, taken) -> + {_, result} = Enumerable.reduce(enumerable, {:cont, :dropping}, fn + (item, :dropping) -> if fun.(item) do - {:cont, {taken}} + {:cont, :dropping} else - {:cont, taken ++ [item]} + {:cont, [item]} end + + (item, taken) -> + {:cont, taken ++ [item]} end) - result + case result do + :dropping -> + [] + :done -> + [] + _ -> + result + end end + def empty?(enumerable) do + {:ok, count} = Enumerable.count(enumerable) + count == 0 + end def take(enumerable, count) do if Enumerable.count(enumerable) < count do diff --git a/src/javascript/tests/case.spec.js b/src/javascript/tests/case.spec.js index 963c8f0a..9dc4e43e 100644 --- a/src/javascript/tests/case.spec.js +++ b/src/javascript/tests/case.spec.js @@ -1,32 +1,36 @@ -import Core from "../lib/core"; +import Core from '../lib/core'; +import chai from 'chai'; const Patterns = Core.Patterns; const SpecialForms = Core.SpecialForms; const Tuple = Core.Tuple; -import Enum from "../lib/enum"; - -import chai from 'chai'; -var expect = chai.expect; - +const expect = chai.expect; describe('case', () => { - it('case', () => { - let clauses = [ + const clauses = [ Patterns.clause( - [new Tuple(Symbol.for("selector"), Patterns.variable(), Patterns.variable())], - function(i, value){ return value; }, - function(i){ return Kernel.is_integer(i); } + [ + new Tuple( + Symbol.for('selector'), + Patterns.variable(), + Patterns.variable(), + ), + ], + (i, value) => { + return value; + }, + i => { + return Kernel.is_integer(i); + }, ), - Patterns.clause( - [Patterns.variable()], - function(value){ return value; } - ) + Patterns.clause([Patterns.variable()], value => { + return value; + }), ]; - let result = SpecialForms._case("thing", clauses); + const result = SpecialForms._case('thing', clauses); - expect(result).to.equal("thing"); + expect(result).to.equal('thing'); }); - }); diff --git a/src/javascript/tests/cond.spec.js b/src/javascript/tests/cond.spec.js index 2fea8baa..3e16ad18 100644 --- a/src/javascript/tests/cond.spec.js +++ b/src/javascript/tests/cond.spec.js @@ -1,25 +1,19 @@ -import Core from "../lib/core"; -const Patterns = Core.Patterns; -const SpecialForms = Core.SpecialForms; - -import Enum from "../lib/enum"; - import chai from 'chai'; -var expect = chai.expect; +import Core from '../lib/core'; +const SpecialForms = Core.SpecialForms; +const expect = chai.expect; describe('cond', () => { - it('cond', () => { - let clauses = [ - [ 1 + 1 == 1, () => "This will never match"], - [ 2 * 2 != 4, () => "Nor this"], - [ true, () => "This will"], + const clauses = [ + [1 + 1 === 1, () => 'This will never match'], + [2 * 2 !== 4, () => 'Nor this'], + [true, () => 'This will'], ]; - let result = SpecialForms.cond(clauses); + const result = SpecialForms.cond(clauses); - expect(result).to.equal("This will"); + expect(result).to.equal('This will'); }); - }); diff --git a/src/javascript/tests/for.spec.js b/src/javascript/tests/for.spec.js index f872d649..d43cf9d4 100644 --- a/src/javascript/tests/for.spec.js +++ b/src/javascript/tests/for.spec.js @@ -1,13 +1,11 @@ -import Core from "../lib/core"; +import Core from '../lib/core'; +import chai from 'chai'; const Patterns = Core.Patterns; const SpecialForms = Core.SpecialForms; const Tuple = Core.Tuple; const BitString = Core.BitString; -import Enum from "../lib/enum"; - -import chai from "chai"; -var expect = chai.expect; +const expect = chai.expect; const $ = Patterns.variable(); @@ -18,84 +16,84 @@ const collectable = { [ $, Patterns.type(Tuple, { - values: [Symbol.for("cont"), Patterns.variable()] - }) + values: [Symbol.for('cont'), Patterns.variable()], + }), ], - (list, x) => list.concat([x]) + (list, x) => list.concat([x]), ), - Patterns.clause([$, Symbol.for("done")], list => list) + Patterns.clause([$, Symbol.for('done')], list => list), ); return new Tuple([], fun); - } + }, }; -describe("for", () => { - it("simple for", () => { - let gen = Patterns.list_generator($, [1, 2, 3, 4]); - let result = SpecialForms._for( +describe('for', () => { + it('simple for', () => { + const gen = Patterns.list_generator($, [1, 2, 3, 4]); + const result = SpecialForms._for( Patterns.clause([$], x => x * 2), [gen], - collectable + collectable, ); expect(result).to.eql([2, 4, 6, 8]); }); - it("for with multiple generators", () => { + it('for with multiple generators', () => { //for x <- [1, 2], y <- [2, 3], do: x*y - let gen = Patterns.list_generator($, [1, 2]); - let gen2 = Patterns.list_generator($, [2, 3]); - let result = SpecialForms._for( + const gen = Patterns.list_generator($, [1, 2]); + const gen2 = Patterns.list_generator($, [2, 3]); + const result = SpecialForms._for( Patterns.clause([$, $], (x, y) => x * y), [gen, gen2], - collectable + collectable, ); expect(result).to.eql([2, 3, 4, 6]); }); - it("for with filter", () => { + it('for with filter', () => { //for n <- [1, 2, 3, 4, 5, 6], rem(n, 2) == 0, do: n - let gen = Patterns.list_generator($, [1, 2, 3, 4, 5, 6]); - let result = SpecialForms._for( + const gen = Patterns.list_generator($, [1, 2, 3, 4, 5, 6]); + const result = SpecialForms._for( Patterns.clause([$], x => x, x => x % 2 === 0), [gen], - collectable + collectable, ); expect(result).to.eql([2, 4, 6]); }); - it("for with pattern matching", () => { + it('for with pattern matching', () => { //for {:user, name} <- [user: "john", admin: "john", user: "meg"], do // String.upcase(name) //end - let gen = Patterns.list_generator([Symbol.for("user"), $], [ - [Symbol.for("user"), "john"], - [Symbol.for("admin"), "john"], - [Symbol.for("user"), "meg"] + const gen = Patterns.list_generator([Symbol.for('user'), $], [ + [Symbol.for('user'), 'john'], + [Symbol.for('admin'), 'john'], + [Symbol.for('user'), 'meg'], ]); - let result = SpecialForms._for( - Patterns.clause([[Symbol.for("user"), $]], name => name.toUpperCase()), + const result = SpecialForms._for( + Patterns.clause([[Symbol.for('user'), $]], name => name.toUpperCase()), [gen], - collectable + collectable, ); - expect(result).to.eql(["JOHN", "MEG"]); + expect(result).to.eql(['JOHN', 'MEG']); }); - it("for with bitstring", () => { + it('for with bitstring', () => { //for <> >>, do: {r, g, b} - let gen = Patterns.bitstring_generator( + const gen = Patterns.bitstring_generator( Patterns.bitStringMatch( BitString.integer({ value: $ }), BitString.integer({ value: $ }), - BitString.integer({ value: $ }) + BitString.integer({ value: $ }), ), new BitString( BitString.integer(213), @@ -109,28 +107,28 @@ describe("for", () => { BitString.integer(0), BitString.integer(234), BitString.integer(32), - BitString.integer(15) - ) + BitString.integer(15), + ), ); - let expression = Patterns.clause( + const expression = Patterns.clause( [ Patterns.bitStringMatch( BitString.integer({ value: $ }), BitString.integer({ value: $ }), - BitString.integer({ value: $ }) - ) + BitString.integer({ value: $ }), + ), ], - (r, g, b) => new Tuple(r, g, b) + (r, g, b) => new Tuple(r, g, b), ); - let result = SpecialForms._for(expression, [gen], collectable); + const result = SpecialForms._for(expression, [gen], collectable); expect(result).to.eql([ new Tuple(213, 45, 132), new Tuple(64, 76, 32), new Tuple(76, 0, 0), - new Tuple(234, 32, 15) + new Tuple(234, 32, 15), ]); }); }); diff --git a/src/javascript/tests/try.spec.js b/src/javascript/tests/try.spec.js index d4b7cf60..b5d9c658 100644 --- a/src/javascript/tests/try.spec.js +++ b/src/javascript/tests/try.spec.js @@ -1,15 +1,11 @@ -import Core from "../lib/core"; +import Core from '../lib/core'; const Patterns = Core.Patterns; const SpecialForms = Core.SpecialForms; -import Enum from "../lib/enum"; - import chai from 'chai'; -var expect = chai.expect; - +const expect = chai.expect; describe('try', () => { - it('try', () => { /* try do @@ -23,19 +19,31 @@ describe('try', () => { */ - let x = 1; + const x = 1; - let value = SpecialForms._try(function() { + const value = SpecialForms._try( + () => { return 1 / x; - }, null, null, Patterns.defmatch(Patterns.clause([Patterns.variable()], function(y) { - return Symbol.for('small'); - }, function(y) { - return (y < 1) && (y > -1); - }), Patterns.clause([Patterns.wildcard()], function() { - return Symbol.for('large'); - })), null); + }, + null, + null, + Patterns.defmatch( + Patterns.clause( + [Patterns.variable()], + y => { + return Symbol.for('small'); + }, + y => { + return y < 1 && y > -1; + }, + ), + Patterns.clause([Patterns.wildcard()], () => { + return Symbol.for('large'); + }), + ), + null, + ); expect(value).to.equal(Symbol.for('large')); }); - }); diff --git a/src/javascript/tests/with.spec.js b/src/javascript/tests/with.spec.js index 70f5c233..9d5a6609 100644 --- a/src/javascript/tests/with.spec.js +++ b/src/javascript/tests/with.spec.js @@ -1,18 +1,16 @@ -import Core from "../lib/core"; +import Core from '../lib/core'; +import chai from 'chai'; const Patterns = Core.Patterns; const SpecialForms = Core.SpecialForms; const Tuple = Core.Tuple; const MatchError = Core.Patterns.MatchError; -import Enum from "../lib/enum"; - -import chai from 'chai'; -var expect = chai.expect; +const expect = chai.expect; const $ = Patterns.variable(); -function map_fetch(map, key){ - if(key in map){ +function map_fetch(map, key) { + if (key in map) { return new Tuple(Symbol.for('ok'), map[key]); } @@ -20,7 +18,6 @@ function map_fetch(map, key){ } describe('with', () => { - it('normal', () => { /* opts = %{width: 10, height: 15} @@ -32,18 +29,17 @@ describe('with', () => { {:ok, 150} */ - let opts = { width: 10, height: 15 }; + const opts = { width: 10, height: 15 }; - let value = SpecialForms._with( - [new Tuple(Symbol.for('ok'), $), () => map_fetch(opts, "width")], - [new Tuple(Symbol.for('ok'), $), (width) => map_fetch(opts, "height")], - (width, height) => new Tuple(Symbol.for('ok'), width * height) + const value = SpecialForms._with( + [new Tuple(Symbol.for('ok'), $), () => map_fetch(opts, 'width')], + [new Tuple(Symbol.for('ok'), $), width => map_fetch(opts, 'height')], + (width, height) => new Tuple(Symbol.for('ok'), width * height), ); expect(value).to.eql(new Tuple(Symbol.for('ok'), 150)); }); - it('without match', () => { /* opts = %{width: 10} @@ -55,18 +51,17 @@ describe('with', () => { :error */ - let opts = { width: 10 }; + const opts = { width: 10 }; - let value = SpecialForms._with( - [new Tuple(Symbol.for('ok'), $), () => map_fetch(opts, "width")], - [new Tuple(Symbol.for('ok'), $), (width) => map_fetch(opts, "height")], - (width, height) => new Tuple(Symbol.for('ok'), width * height) + const value = SpecialForms._with( + [new Tuple(Symbol.for('ok'), $), () => map_fetch(opts, 'width')], + [new Tuple(Symbol.for('ok'), $), width => map_fetch(opts, 'height')], + (width, height) => new Tuple(Symbol.for('ok'), width * height), ); expect(value).to.eql(Symbol.for('error')); }); - it('bare expression', () => { /* opts = %{width: 10} @@ -79,19 +74,22 @@ describe('with', () => { {:ok, 300} */ - let opts = { width: 10, height: 15 }; - - let value = SpecialForms._with( - [new Tuple(Symbol.for('ok'), $), () => map_fetch(opts, "width")], - [$, (width) => width * 2], - [new Tuple(Symbol.for('ok'), $), (width, double_width) => map_fetch(opts, "height")], - (width, double_width, height) => new Tuple(Symbol.for('ok'), double_width * height) + const opts = { width: 10, height: 15 }; + + const value = SpecialForms._with( + [new Tuple(Symbol.for('ok'), $), () => map_fetch(opts, 'width')], + [$, width => width * 2], + [ + new Tuple(Symbol.for('ok'), $), + (width, double_width) => map_fetch(opts, 'height'), + ], + (width, double_width, height) => + new Tuple(Symbol.for('ok'), double_width * height), ); expect(value).to.eql(new Tuple(Symbol.for('ok'), 300)); }); - it('with else', () => { /* opts = %{width: 10} @@ -106,18 +104,24 @@ describe('with', () => { {:error, :wrong_data} */ - let opts = { width: 10 }; + const opts = { width: 10 }; - let value = SpecialForms._with( - [new Tuple(Symbol.for('ok'), $), () => map_fetch(opts, "width")], - [new Tuple(Symbol.for('ok'), $), (width) => map_fetch(opts, "height")], + const value = SpecialForms._with( + [new Tuple(Symbol.for('ok'), $), () => map_fetch(opts, 'width')], + [new Tuple(Symbol.for('ok'), $), width => map_fetch(opts, 'height')], (width, height) => new Tuple(Symbol.for('ok'), width * height), Patterns.defmatch( - Patterns.clause([Symbol.for('error')], () => new Tuple(Symbol.for('error'), Symbol.for('wrong_data'))) - ) + Patterns.clause( + [Symbol.for('error')], + () => new Tuple(Symbol.for('error'), Symbol.for('wrong_data')), + ), + ), ); - expect(value).to.eql(new Tuple(Symbol.for('error'), Symbol.for('wrong_data'))); + expect(value).to.eql(new Tuple( + Symbol.for('error'), + Symbol.for('wrong_data'), + )); }); it('with else that don`t match', () => { @@ -134,16 +138,19 @@ describe('with', () => { {:error, :wrong_data} */ - let opts = { width: 10 }; + const opts = { width: 10 }; - let withFunction = SpecialForms._with.bind( + const withFunction = SpecialForms._with.bind( null, - [new Tuple(Symbol.for('ok'), $), () => map_fetch(opts, "width")], - [new Tuple(Symbol.for('ok'), $), (width) => map_fetch(opts, "height")], + [new Tuple(Symbol.for('ok'), $), () => map_fetch(opts, 'width')], + [new Tuple(Symbol.for('ok'), $), width => map_fetch(opts, 'height')], (width, height) => new Tuple(Symbol.for('ok'), width * height), Patterns.defmatch( - Patterns.clause([Symbol.for('fail')], () => new Tuple(Symbol.for('error'), Symbol.for('wrong_data'))) - ) + Patterns.clause( + [Symbol.for('fail')], + () => new Tuple(Symbol.for('error'), Symbol.for('wrong_data')), + ), + ), ); expect(withFunction).to.throw(MatchError, 'No match for: Symbol(error)'); diff --git a/test/app/spec/enum.spec.js b/test/app/spec/enum.spec.js index bbf1757a..57d9f212 100644 --- a/test/app/spec/enum.spec.js +++ b/test/app/spec/enum.spec.js @@ -91,4 +91,22 @@ describe('Enum', () => { expect(Enum.drop_every([1, 2], 2)).to.eql([2]); expect(Enum.drop_every([1, 2, 3], 0)).to.eql([1, 2, 3]); }); + + it('drop_while/2', () => { + expect(Enum.drop_while([1, 2, 3, 4, 3, 2, 1], x => x <= 3)).to.eql([ + 4, + 3, + 2, + 1, + ]); + + expect(Enum.drop_while([1, 2, 3], _ => false)).to.eql([1, 2, 3]); + expect(Enum.drop_while([1, 2, 3], x => x <= 3)).to.eql([]); + expect(Enum.drop_while([], _ => false)).to.eql([]); + }); + + it('empty?/1', () => { + expect(Enum.empty__qmark__([])).to.eql(true); + expect(Enum.empty__qmark__([1, 2, 3])).to.eql(false); + }); }); diff --git a/test/translator/case_test.exs b/test/translator/case_test.exs index 9259bb12..08bb8fbb 100644 --- a/test/translator/case_test.exs +++ b/test/translator/case_test.exs @@ -57,7 +57,7 @@ defmodule ElixirScript.Translator.Case.Test do Bootstrap.Core.Patterns.defmatch(Bootstrap.Core.Patterns.clause([false],function() { let [value] = Bootstrap.Core.Patterns.match(Bootstrap.Core.Patterns.variable(),13); return value; - }),Bootstrap.Core.Patterns.clause([Bootstrap.Core.Patterns.wildcard()],function() { + }),Bootstrap.Core.Patterns.clause([Bootstrap.Core.Patterns.variable()],function(__ignored__) { return true; })).call(this,data) """ @@ -71,7 +71,7 @@ defmodule ElixirScript.Translator.Case.Test do case data do number when number in [1,2,3,4] -> value = 13 - _ -> + _ -> true end end @@ -82,7 +82,7 @@ defmodule ElixirScript.Translator.Case.Test do return value; },function(number) { return Elixir.ElixirScript.Bootstrap.Functions.__load(Elixir).contains(number,Object.freeze([1, 2, 3, 4])); - }),Bootstrap.Core.Patterns.clause([Bootstrap.Core.Patterns.wildcard()],function() { + }),Bootstrap.Core.Patterns.clause([Bootstrap.Core.Patterns.variable()],function(__ignored__) { return true; })).call(this,data) """ @@ -107,7 +107,7 @@ defmodule ElixirScript.Translator.Case.Test do return value; },function(number) { return Elixir.ElixirScript.Bootstrap.Functions.__load(Elixir).contains(number,Object.freeze([1, 2, 3, 4])) || Elixir.ElixirScript.Bootstrap.Functions.__load(Elixir).contains(number,Object.freeze([4, 3, 2, 1])); - }),Bootstrap.Core.Patterns.clause([Bootstrap.Core.Patterns.wildcard()],function() { + }),Bootstrap.Core.Patterns.clause([Bootstrap.Core.Patterns.variable()],function(__ignored__) { return true; })).call(this,data) """ diff --git a/test/translator/function_test.exs b/test/translator/function_test.exs index c7d2018f..57088138 100644 --- a/test/translator/function_test.exs +++ b/test/translator/function_test.exs @@ -60,7 +60,7 @@ defmodule ElixirScript.Translator.Function.Test do return 2; },function(x) { return x === null || x === false; - }),Bootstrap.Core.Patterns.clause([Bootstrap.Core.Patterns.wildcard()],function() { + }),Bootstrap.Core.Patterns.clause([Bootstrap.Core.Patterns.variable()],function(__ignored__) { return 1; })).call(this,1 == 1); })); @@ -88,14 +88,14 @@ defmodule ElixirScript.Translator.Function.Test do return 2; }, function(x) { return x === null || x === false; - }), Bootstrap.Core.Patterns.clause([Bootstrap.Core.Patterns.wildcard()], function() { + }), Bootstrap.Core.Patterns.clause([Bootstrap.Core.Patterns.variable()], function(__ignored__) { return Bootstrap.Core.Patterns.defmatch(Bootstrap.Core.Patterns.clause([Bootstrap.Core.Patterns.variable()], function(x) { let [a] = Bootstrap.Core.Patterns.match(Bootstrap.Core.Patterns.variable(), 1); return a; }, function(x) { return x === null || x === false; - }), Bootstrap.Core.Patterns.clause([Bootstrap.Core.Patterns.wildcard()], function() { + }), Bootstrap.Core.Patterns.clause([Bootstrap.Core.Patterns.variable()], function(__ignored__) { return 4; })).call(this, 2 == 2); })).call(this, 1 == 1); @@ -749,7 +749,7 @@ defmodule ElixirScript.Translator.Function.Test do function(x) { return x === null || x === false; }), - Bootstrap.Core.Patterns.clause([Bootstrap.Core.Patterns.wildcard()], function() { + Bootstrap.Core.Patterns.clause([Bootstrap.Core.Patterns.variable()], function(__ignored__) { return null; })).call(this, true); }, diff --git a/test/translator/list_test.exs b/test/translator/list_test.exs index c4af1fc4..39384bfe 100644 --- a/test/translator/list_test.exs +++ b/test/translator/list_test.exs @@ -60,7 +60,7 @@ defmodule ElixirScript.Translator.List.Test do end js_code = """ - Bootstrap.Core.Patterns.defmatch(Bootstrap.Core.Patterns.clause([Bootstrap.Core.Patterns.wildcard()],function(){ + Bootstrap.Core.Patterns.defmatch(Bootstrap.Core.Patterns.clause([Bootstrap.Core.Patterns.variable()],function(__ignored__){ return Object.freeze([x]).concat(list); })) """ diff --git a/test/translator/match_test.exs b/test/translator/match_test.exs index 520dada0..88b13a03 100644 --- a/test/translator/match_test.exs +++ b/test/translator/match_test.exs @@ -29,10 +29,10 @@ defmodule ElixirScript.Translator.Match.Test do ex_ast = quote do: {a, _, c} = {1, 2, 3} js_code = """ - let [a, undefined, c] = Bootstrap.Core.Patterns.match(Bootstrap.Core.Patterns.type(Bootstrap.Core.Tuple, { - values: [Bootstrap.Core.Patterns.variable(), Bootstrap.Core.Patterns.wildcard(), Bootstrap.Core.Patterns.variable()] + let [a, __ignored__, c] = Bootstrap.Core.Patterns.match(Bootstrap.Core.Patterns.type(Bootstrap.Core.Tuple, { + values: [Bootstrap.Core.Patterns.variable(), Bootstrap.Core.Patterns.variable(), Bootstrap.Core.Patterns.variable()] }), new Bootstrap.Core.Tuple(1, 2, 3)); - let _ref = new Bootstrap.Core.Tuple(a, undefined, c); + let _ref = new Bootstrap.Core.Tuple(a, __ignored__, c); """ assert_translation(ex_ast, js_code) @@ -43,10 +43,10 @@ defmodule ElixirScript.Translator.Match.Test do {^a, _, c} = {1, 2, 3} end js_code = """ - let [, undefined, c] = Bootstrap.Core.Patterns.match(Bootstrap.Core.Patterns.type(Bootstrap.Core.Tuple, { - values: [Bootstrap.Core.Patterns.bound(a), Bootstrap.Core.Patterns.wildcard(), Bootstrap.Core.Patterns.variable()] + let [, __ignored__, c] = Bootstrap.Core.Patterns.match(Bootstrap.Core.Patterns.type(Bootstrap.Core.Tuple, { + values: [Bootstrap.Core.Patterns.bound(a), Bootstrap.Core.Patterns.variable(), Bootstrap.Core.Patterns.variable()] }), new Bootstrap.Core.Tuple(1, 2, 3)); - let _ref = new Bootstrap.Core.Tuple(undefined, undefined, c); + let _ref = new Bootstrap.Core.Tuple(undefined, __ignored__, c); """ assert_translation(ex_ast, js_code) diff --git a/test/translator/pattern_matching_test.exs b/test/translator/pattern_matching_test.exs index b32b8ac3..1bebeb22 100644 --- a/test/translator/pattern_matching_test.exs +++ b/test/translator/pattern_matching_test.exs @@ -29,7 +29,7 @@ defmodule ElixirScript.Translator.PatternMatching.Test do test "match wildcard", %{scope: scope} do params = [{:_, [], Test}] result = PatternMatching.build_match(params, scope) - expected_result = {[PatternMatching.wildcard], [JS.identifier(:undefined)]} + expected_result = {[PatternMatching.parameter()], [JS.identifier(:__ignored__)]} assert result == expected_result end diff --git a/test/translator/try_test.exs b/test/translator/try_test.exs index eaff9c47..645e73ec 100644 --- a/test/translator/try_test.exs +++ b/test/translator/try_test.exs @@ -185,7 +185,7 @@ defmodule ElixirScript.Translator.Try.Test do return Symbol.for('small'); }, function(y) { return y < 1 && y > -1; - }), Bootstrap.Core.Patterns.clause([Bootstrap.Core.Patterns.wildcard()], function() { + }), Bootstrap.Core.Patterns.clause([Bootstrap.Core.Patterns.variable()], function(__ignored__) { return Symbol.for('large'); })), null) """ From bab9a91af0f13635c88efc208345674db2b82aaa Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Thu, 23 Mar 2017 22:37:11 -0500 Subject: [PATCH 052/418] Add more test. Fix variable scoping bug --- lib/elixir_script/translator.ex | 9 ++++++++- .../translator/kernel/special_forms/fn.ex | 5 ++--- lib/elixir_script/translator/lexical_scope.ex | 2 +- priv/std_lib/enum.ex | 13 +++++++++---- test/app/spec/enum.spec.js | 14 ++++++++++++++ test/translator/bug_test.exs | 14 ++++++++++++++ 6 files changed, 48 insertions(+), 9 deletions(-) diff --git a/lib/elixir_script/translator.ex b/lib/elixir_script/translator.ex index 10657ef3..1e808d69 100644 --- a/lib/elixir_script/translator.ex +++ b/lib/elixir_script/translator.ex @@ -645,13 +645,20 @@ defmodule ElixirScript.Translator do is_from_js_module(name, params, env) -> do_translate({{:., [], [{:__aliases__, [], [:JS]}, name]}, [], params }, env) ElixirScript.Translator.LexicalScope.has_var?(env, name) -> + name = case env.vars[name] do + 0 -> + name + num -> + String.to_atom("#{name}#{num}") + end + { Identifier.make_identifier(name), env } has_function?(env.module, {name, 0}, env) -> Call.make_function_call(name, [], env) ElixirScript.Translator.LexicalScope.find_module(env, {name, 0}) -> imported_module_name = ElixirScript.Translator.LexicalScope.find_module(env, {name, 0}) Call.make_module_function_call(imported_module_name, name, params, env) - true -> + true -> { Identifier.make_identifier(name), env } end end diff --git a/lib/elixir_script/translator/kernel/special_forms/fn.ex b/lib/elixir_script/translator/kernel/special_forms/fn.ex index 4a8b9736..80a6de81 100644 --- a/lib/elixir_script/translator/kernel/special_forms/fn.ex +++ b/lib/elixir_script/translator/kernel/special_forms/fn.ex @@ -173,9 +173,8 @@ defmodule ElixirScript.Translator.Function do Enum.map_reduce(list, env, fn(x, env) -> Translator.translate(x, env) end) - _ -> - - Enum.map_reduce(List.wrap(body), env, fn(x, env) -> + _ -> + Enum.map_reduce(List.wrap(body), env, fn(x, env) -> Translator.translate(x, env) end) end diff --git a/lib/elixir_script/translator/lexical_scope.ex b/lib/elixir_script/translator/lexical_scope.ex index 0e444c05..36032da5 100644 --- a/lib/elixir_script/translator/lexical_scope.ex +++ b/lib/elixir_script/translator/lexical_scope.ex @@ -124,7 +124,7 @@ defmodule ElixirScript.Translator.LexicalScope do end def function_scope(env, { _, _ } = func) do - %{ env | function: func, caller: env, vars: [] } + %{ env | function: func, caller: env} end def function_scope(env, nil) do diff --git a/priv/std_lib/enum.ex b/priv/std_lib/enum.ex index 28bb4848..1d6c7d87 100644 --- a/priv/std_lib/enum.ex +++ b/priv/std_lib/enum.ex @@ -9,8 +9,6 @@ defmodule ElixirScript.Enum do end end) - IO.inspect acc - acc end @@ -131,9 +129,16 @@ defmodule ElixirScript.Enum do count == 0 end - def fetch(enumerable, index) do + def fetch(enumerable, something_unique) do + something_unique = if something_unique < 0 do + {_, count} = Enumerable.count(enumerable) + count + something_unique + else + something_unique + end + result = Enumerable.reduce(enumerable, {:cont, 0}, fn(item, acc) -> - if index == acc do + if something_unique == acc do {:halt, {:ok, item}} else {:cont, acc + 1} diff --git a/test/app/spec/enum.spec.js b/test/app/spec/enum.spec.js index 57d9f212..3a265bfa 100644 --- a/test/app/spec/enum.spec.js +++ b/test/app/spec/enum.spec.js @@ -1,5 +1,6 @@ const expect = require('chai').expect; const Elixir = require('../build/Elixir.App'); +const Tuple = require('../../../src/javascript/lib/core').default.Tuple; const Enum = Elixir.load(Elixir.ElixirScript.Enum); @@ -109,4 +110,17 @@ describe('Enum', () => { expect(Enum.empty__qmark__([])).to.eql(true); expect(Enum.empty__qmark__([1, 2, 3])).to.eql(false); }); + + it('fetch/2', () => { + expect(Enum.fetch([66], 0)).to.eql(new Tuple(Symbol.for('ok'), 66)); + expect(Enum.fetch([66], -1)).to.eql(new Tuple(Symbol.for('ok'), 66)); + expect(Enum.fetch([66], 1)).to.eql(Symbol.for('error')); + expect(Enum.fetch([66], -2)).to.eql(Symbol.for('error')); + }); + + it('fetch!/2', () => { + expect(Enum.fetch__emark__([2, 4, 6], 0)).to.eql(2); + expect(Enum.fetch__emark__([2, 4, 6], 2)).to.eql(6); + expect(Enum.fetch__emark__([2, 4, 6], -2)).to.eql(4); + }); }); diff --git a/test/translator/bug_test.exs b/test/translator/bug_test.exs index 6e3820a5..7cae994f 100644 --- a/test/translator/bug_test.exs +++ b/test/translator/bug_test.exs @@ -159,4 +159,18 @@ defmodule ElixirScript.Translator.Bug.Test do assert_translation(ex_ast, js_code) end + + test "variable" do + ex_ast = quote do + Enum.fetch([2, 4, 6], 0) + end + + js_code = """ + Object.assign(document.getElementById('main'), Object.freeze({ + innerHTML: html + })) + """ + + assert_translation(ex_ast, js_code) + end end From a23042962c4e86a71e9f1c2b52753f2f8e024677 Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Thu, 23 Mar 2017 22:40:58 -0500 Subject: [PATCH 053/418] Fix test --- test/translator/bug_test.exs | 15 --------------- test/translator/function_test.exs | 2 +- 2 files changed, 1 insertion(+), 16 deletions(-) diff --git a/test/translator/bug_test.exs b/test/translator/bug_test.exs index 7cae994f..2980d8a8 100644 --- a/test/translator/bug_test.exs +++ b/test/translator/bug_test.exs @@ -158,19 +158,4 @@ defmodule ElixirScript.Translator.Bug.Test do assert_translation(ex_ast, js_code) end - - - test "variable" do - ex_ast = quote do - Enum.fetch([2, 4, 6], 0) - end - - js_code = """ - Object.assign(document.getElementById('main'), Object.freeze({ - innerHTML: html - })) - """ - - assert_translation(ex_ast, js_code) - end end diff --git a/test/translator/function_test.exs b/test/translator/function_test.exs index 57088138..5b48c6d0 100644 --- a/test/translator/function_test.exs +++ b/test/translator/function_test.exs @@ -95,7 +95,7 @@ defmodule ElixirScript.Translator.Function.Test do return a; }, function(x) { return x === null || x === false; - }), Bootstrap.Core.Patterns.clause([Bootstrap.Core.Patterns.variable()], function(__ignored__) { + }), Bootstrap.Core.Patterns.clause([Bootstrap.Core.Patterns.variable()], function(__ignored__1) { return 4; })).call(this, 2 == 2); })).call(this, 1 == 1); From c2efe53123ddf3c0603cea634ce108b27d2dfc1d Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Thu, 23 Mar 2017 22:42:07 -0500 Subject: [PATCH 054/418] Renamed something_unique to index --- priv/std_lib/enum.ex | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/priv/std_lib/enum.ex b/priv/std_lib/enum.ex index 1d6c7d87..fded4e3f 100644 --- a/priv/std_lib/enum.ex +++ b/priv/std_lib/enum.ex @@ -129,16 +129,16 @@ defmodule ElixirScript.Enum do count == 0 end - def fetch(enumerable, something_unique) do - something_unique = if something_unique < 0 do + def fetch(enumerable, index) do + index = if index < 0 do {_, count} = Enumerable.count(enumerable) - count + something_unique + count + index else - something_unique + index end result = Enumerable.reduce(enumerable, {:cont, 0}, fn(item, acc) -> - if something_unique == acc do + if index == acc do {:halt, {:ok, item}} else {:cont, acc + 1} From 97188b75cc93cff209ec5530f0bf64f6a2083c73 Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Sun, 26 Mar 2017 16:28:52 -0500 Subject: [PATCH 055/418] Allow for global JS modules and classes to have implementations for protocols --- lib/elixir_script/translator/kernel/defimpl.ex | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/lib/elixir_script/translator/kernel/defimpl.ex b/lib/elixir_script/translator/kernel/defimpl.ex index 92860e18..8c170abd 100644 --- a/lib/elixir_script/translator/kernel/defimpl.ex +++ b/lib/elixir_script/translator/kernel/defimpl.ex @@ -113,6 +113,11 @@ defmodule ElixirScript.Translator.Defimpl do JS.identifier(:Object) end + defp map_to_js({:__aliases__, context, [:JS | rest]}, env) do + ElixirScript.Translator.JS.translate_js_module({:__aliases__, context, rest}, env) + |> elem(0) + end + defp map_to_js({:__aliases__, _, [:Any]}, _) do JS.identifier(:null) end From f75c33a60f01e0bc101180e66518d11e9c07e746 Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Sun, 26 Mar 2017 21:32:28 -0500 Subject: [PATCH 056/418] Add remove_unused option --- CHANGELOG.md | 5 ++++ lib/elixir_script.ex | 2 ++ lib/elixir_script/cli.ex | 6 +++-- lib/elixir_script/passes/remove_unused.ex | 31 +++++++++++++++++++++++ mix.exs | 2 +- 5 files changed, 43 insertions(+), 3 deletions(-) create mode 100644 lib/elixir_script/passes/remove_unused.ex diff --git a/CHANGELOG.md b/CHANGELOG.md index 1e2307f5..91b0d510 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,11 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/) and this project adheres to [Semantic Versioning](http://semver.org/). +## [0.28.0-dev] + +### Added +- `remove-unused` option that will remove all unused modules from output + ## [0.27.0] - 2017-03-17 ### Added diff --git a/lib/elixir_script.ex b/lib/elixir_script.ex index bde9904f..298b80c9 100644 --- a/lib/elixir_script.ex +++ b/lib/elixir_script.ex @@ -86,6 +86,7 @@ defmodule ElixirScript do |> ElixirScript.Passes.FindFunctions.execute(opts) |> ElixirScript.Passes.JavaScriptAST.execute(opts) |> ElixirScript.Passes.ConsolidateProtocols.execute(opts) + |> ElixirScript.Passes.RemoveUnused.execute(opts) |> ElixirScript.Passes.CreateJSModules.execute(opts) |> ElixirScript.Passes.JavaScriptCode.execute(opts) |> ElixirScript.Passes.HandleOutput.execute(opts) @@ -187,6 +188,7 @@ defmodule ElixirScript do |> Map.put(:app, :app) |> Map.put(:format, :es) |> Map.put(:js_modules, []) + |> Map.put(:remove_unused, false) options = Map.merge(default_options, opts) Map.put(options, :module_formatter, get_module_formatter(options[:format])) diff --git a/lib/elixir_script/cli.ex b/lib/elixir_script/cli.ex index e4bbb67e..e1e573eb 100644 --- a/lib/elixir_script/cli.ex +++ b/lib/elixir_script/cli.ex @@ -6,7 +6,7 @@ defmodule ElixirScript.CLI do @switches [ output: :string, elixir: :boolean, help: :boolean, full_build: :boolean, version: :boolean, - watch: :boolean, format: :string, js_module: [:string, :keep] + watch: :boolean, format: :string, js_module: [:string, :keep], remove_unused: :boolean ] @aliases [ @@ -50,6 +50,7 @@ defmodule ElixirScript.CLI do -o --output [path] places output at the given path. Can be a directory or filename. -e --elixir read input as elixir code string + --remove-unused Removes unused modules from output --full-build informs the compiler to do a full build instead of an incremental one -v --version the current version number -h --help this message @@ -84,7 +85,8 @@ defmodule ElixirScript.CLI do full_build: Keyword.get(options, :full_build, false), output: Keyword.get(options, :output, :stdout), format: String.to_atom(Keyword.get(options, :format, "es")), - js_modules: js_modules + js_modules: js_modules, + remove_unused: Keyword.get(options, :remove_unused, false) } case options[:elixir] do diff --git a/lib/elixir_script/passes/remove_unused.ex b/lib/elixir_script/passes/remove_unused.ex new file mode 100644 index 00000000..4f6ff8fb --- /dev/null +++ b/lib/elixir_script/passes/remove_unused.ex @@ -0,0 +1,31 @@ +defmodule ElixirScript.Passes.RemoveUnused do + @moduledoc false + alias ElixirScript.Translator.Utils + alias ElixirScript.Translator.State + + def execute(compiler_data, %{remove_unused: false}) do + compiler_data + end + + def execute(compiler_data, opts) do + module_refs = State.list_module_references(compiler_data.state) + + data = Enum.reject(compiler_data.data, fn + {_, %{type: :impl} = module_data} -> + length(module_refs[module_data.implements]) == 0 + {_, %{type: :consolidated} = module_data} -> + length(module_refs[module_data.protocol]) == 0 + {module, module_data} -> + cond do + Enum.member?(module_data.functions, {:start, 2}) -> + false + length(module_refs[module]) > 0 -> + false + true -> + true + end + end) + + %{ compiler_data | data: data } + end +end \ No newline at end of file diff --git a/mix.exs b/mix.exs index 6023aa53..b16da257 100644 --- a/mix.exs +++ b/mix.exs @@ -4,7 +4,7 @@ defmodule ElixirScript.Mixfile do def project do [ app: :elixir_script, - version: "0.27.0", + version: "0.28.0-dev", elixir: "~> 1.0", elixirc_paths: elixirc_paths(), escript: escript_config(), From 0a927fbd77b623bfeaf8ff19f416dca443ea1f6c Mon Sep 17 00:00:00 2001 From: Joel Wietelmann Date: Mon, 27 Mar 2017 17:08:50 -0400 Subject: [PATCH 057/418] Update FAQ.md Grammar nitpick. --- FAQ.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FAQ.md b/FAQ.md index 3c2ad53e..760b7aa7 100644 --- a/FAQ.md +++ b/FAQ.md @@ -82,7 +82,7 @@ The compiler to this point has been focused on translating Kernel.SpecialForms a ### A. Yes, but realize this is not at 1.0 yet. -You **can** use ElixirScript on your front ends and have it work and interoperate with JavaScript modules. The problem is since most of the standard library is incomplete. +You **can** use ElixirScript on your front ends and have it work and interoperate with JavaScript modules. The problem is that most of the standard library is incomplete. ## Q. Can I use pattern matching? From e42e5953a792acfee41057d215429c30f9dbe5ac Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Mon, 27 Mar 2017 21:50:39 -0500 Subject: [PATCH 058/418] Fixed removed_unused settings --- lib/elixir_script/passes/remove_unused.ex | 6 ++-- lib/elixir_script/translator.ex | 34 +++---------------- .../translator/kernel/special_forms/call.ex | 3 ++ lib/elixir_script/translator/lexical_scope.ex | 6 ++++ lib/elixir_script/translator/state.ex | 26 ++++++-------- test/app/src/main.ex | 2 ++ 6 files changed, 29 insertions(+), 48 deletions(-) diff --git a/lib/elixir_script/passes/remove_unused.ex b/lib/elixir_script/passes/remove_unused.ex index 4f6ff8fb..728f511b 100644 --- a/lib/elixir_script/passes/remove_unused.ex +++ b/lib/elixir_script/passes/remove_unused.ex @@ -12,14 +12,14 @@ defmodule ElixirScript.Passes.RemoveUnused do data = Enum.reject(compiler_data.data, fn {_, %{type: :impl} = module_data} -> - length(module_refs[module_data.implements]) == 0 + length(Keyword.get(module_refs, module_data.implements, [])) == 0 {_, %{type: :consolidated} = module_data} -> - length(module_refs[module_data.protocol]) == 0 + length(Keyword.get(module_refs, module_data.protocol, [])) == 0 {module, module_data} -> cond do Enum.member?(module_data.functions, {:start, 2}) -> false - length(module_refs[module]) > 0 -> + length(Keyword.get(module_refs, module, [])) > 0 -> false true -> true diff --git a/lib/elixir_script/translator.ex b/lib/elixir_script/translator.ex index 1e808d69..5187266e 100644 --- a/lib/elixir_script/translator.ex +++ b/lib/elixir_script/translator.ex @@ -185,7 +185,7 @@ defmodule ElixirScript.Translator do end defp do_translate({:&, _, [{:/, _, [{{:., _, [module_name, function_name]}, _, []}, arity]}]}, env) do - module_name = create_module_name2(module_name, env) + module_name = create_module_name(module_name, env) js_ast = case module_name do {mod, :local} -> Capture.make_capture(mod, function_name, arity, env) @@ -278,7 +278,7 @@ defmodule ElixirScript.Translator do expanded_ast = Macro.expand(ast, env.env) if expanded_ast == ast do - module_name = create_module_name2(module_name, env) + module_name = create_module_name(module_name, env) case module_name do {mod, :local} -> Call.make_module_function_call(mod, function_name, env) @@ -300,19 +300,11 @@ defmodule ElixirScript.Translator do end end - defp do_translate({{:., context1, [{:__aliases__, context2, [:Elixir, :Enum]}, function_name]}, context3, params }, env) do - translate({{:., context1, [{:__aliases__, context2, [:Enum]}, function_name]}, context3, params }, env) - end - - defp do_translate({{:., context1, [{:__aliases__, context2, [:Enum]}, function_name]}, context3, params }, env) do - translate({{:., context1, [{:__aliases__, context2, [:Bootstrap, :Enum]}, function_name]}, context3, params }, env) - end - defp do_translate({{:., _, [{:__aliases__, _, _} = module_name, function_name]}, _, params } = ast, env) do expanded_ast = Macro.expand(ast, env.env) if expanded_ast == ast do - module_name = create_module_name2(module_name, env) + module_name = create_module_name(module_name, env) case module_name do {mod, :local} -> Call.make_module_function_call(mod, function_name, params, env) @@ -345,7 +337,7 @@ defmodule ElixirScript.Translator do end defp do_translate({:__aliases__, _, aliases} = ast, env) do - module_name = create_module_name2(ast, env) + module_name = create_module_name(ast, env) case module_name do {mod, :local} -> Call.make_module_name(mod, env) @@ -640,7 +632,7 @@ defmodule ElixirScript.Translator do end end - defp do_translate({ name, _, params }, env) when is_atom(params) do + defp do_translate({ name, _context, params }, env) when is_atom(params) do cond do is_from_js_module(name, params, env) -> do_translate({{:., [], [{:__aliases__, [], [:JS]}, name]}, [], params }, env) @@ -683,22 +675,6 @@ defmodule ElixirScript.Translator do end def create_module_name(module_name, env) do - case module_name do - {:__aliases__, _, _} -> - candiate_module_name = ElixirScript.Translator.State.get_module_name(env.state, - Utils.quoted_to_name(module_name)) - - if ElixirScript.Translator.LexicalScope.get_module_name(env, candiate_module_name) in ElixirScript.Translator.State.list_module_names(env.state) do - ElixirScript.Translator.LexicalScope.get_module_name(env, candiate_module_name) - else - module_name - end - _ -> - module_name - end - end - - def create_module_name2(module_name, env) do module_name = Utils.quoted_to_name(module_name) candiate_module_name = ElixirScript.Translator.State.get_module_name(env.state, module_name) diff --git a/lib/elixir_script/translator/kernel/special_forms/call.ex b/lib/elixir_script/translator/kernel/special_forms/call.ex index ca3d04eb..9990624d 100644 --- a/lib/elixir_script/translator/kernel/special_forms/call.ex +++ b/lib/elixir_script/translator/kernel/special_forms/call.ex @@ -34,6 +34,8 @@ defmodule ElixirScript.Translator.Call do end def make_module_function_call(module_name, function_name, params, env) do + ElixirScript.Translator.State.add_module_reference(env.state, env.module, module_name) + members = ["Elixir"] ++ Module.split(module_name) ++ ["__load"] ast = JS.call_expression( @@ -51,6 +53,7 @@ defmodule ElixirScript.Translator.Call do end def make_module_function_call(module_name, function_name, env) do + ElixirScript.Translator.State.add_module_reference(env.state, env.module, module_name) make_module_function_call(module_name, function_name, [], env) end diff --git a/lib/elixir_script/translator/lexical_scope.ex b/lib/elixir_script/translator/lexical_scope.ex index 36032da5..f202e549 100644 --- a/lib/elixir_script/translator/lexical_scope.ex +++ b/lib/elixir_script/translator/lexical_scope.ex @@ -228,6 +228,7 @@ defmodule ElixirScript.Translator.LexicalScope do def add_import(env, module_name) do check_for_module_existence(env, module_name) + ElixirScript.Translator.State.add_module_reference(env.state, env.module, module_name) env = if ElixirScript.Translator.State.is_module_loaded?(env.state, module_name) do add_import_macro(env, module_name, []) @@ -247,6 +248,7 @@ defmodule ElixirScript.Translator.LexicalScope do def add_import(env, module_name, [only: :functions]) do module = get_module(env, module_name) + ElixirScript.Translator.State.add_module_reference(env.state, env.module, module_name) %{ env | functions: List.keydelete(env.functions, module_name, 0) ++ [{ module.name, module.functions }], requires: Enum.uniq(env.requires ++ [module.name]) @@ -263,6 +265,7 @@ defmodule ElixirScript.Translator.LexicalScope do def add_import(env, module_name, [only: only]) do check_for_module_existence(env, module_name) + ElixirScript.Translator.State.add_module_reference(env.state, env.module, module_name) env = if ElixirScript.Translator.State.is_module_loaded?(env.state, module_name) do list = module_name.__info__(:macros) @@ -288,6 +291,7 @@ defmodule ElixirScript.Translator.LexicalScope do def add_import(env, module_name, [except: except]) do check_for_module_existence(env, module_name) + ElixirScript.Translator.State.add_module_reference(env.state, env.module, module_name) env = if ElixirScript.Translator.State.is_module_loaded?(env.state, module_name) do list = module_name.__info__(:macros) @@ -312,6 +316,7 @@ defmodule ElixirScript.Translator.LexicalScope do def add_require(env, module_name) do check_for_module_existence(env, module_name) + ElixirScript.Translator.State.add_module_reference(env.state, env.module, module_name) env = if ElixirScript.Translator.State.is_module_loaded?(env.state, module_name) do add_require_macro(env, module_name, []) @@ -329,6 +334,7 @@ defmodule ElixirScript.Translator.LexicalScope do def add_require(env, module_name, alias_name) do check_for_module_existence(env, module_name) + ElixirScript.Translator.State.add_module_reference(env.state, env.module, module_name) env = if ElixirScript.Translator.State.is_module_loaded?(env.state, module_name) do add_require_macro(env, module_name, [as: alias_name]) diff --git a/lib/elixir_script/translator/state.ex b/lib/elixir_script/translator/state.ex index 9f02731f..bb318401 100644 --- a/lib/elixir_script/translator/state.ex +++ b/lib/elixir_script/translator/state.ex @@ -11,7 +11,13 @@ defmodule ElixirScript.Translator.State do def start_link(compiler_opts, loaded_modules) do Agent.start_link(fn -> - %{ compiler_opts: compiler_opts, modules: Keyword.new, std_lib_map: build_standard_lib_map(), loaded_modules: [JS | loaded_modules] } + %{ + compiler_opts: compiler_opts, + modules: Keyword.new, + std_lib_map: build_standard_lib_map(), + loaded_modules: [JS | loaded_modules], + module_references: Keyword.new() + } end) end @@ -120,27 +126,15 @@ defmodule ElixirScript.Translator.State do nil -> state module -> - module = Map.update(module, :refs, [module_name], fn(x) -> Enum.uniq(x ++ [module_name]) end) - modules = Keyword.put(state.modules, module.name, module) - %{ state | modules: modules } + module_references = Keyword.update(state.module_references, module.name, [module_name], fn(x) -> Enum.uniq(x ++ [module_name]) end) + %{ state | module_references: module_references } end end) end - def get_module_references(pid, module_name) do - case get_module(pid, module_name) do - nil -> - [] - module -> - Map.get(module, :refs, []) - end - end - def list_module_references(pid) do Agent.get(pid, fn(state) -> - Enum.map(state.modules, fn {name, module} -> - {name, Map.get(module, :refs, [])} - end) + state.module_references end) end diff --git a/test/app/src/main.ex b/test/app/src/main.ex index 5ddefc6a..61d6451b 100644 --- a/test/app/src/main.ex +++ b/test/app/src/main.ex @@ -1,5 +1,7 @@ defmodule Main do def start(:normal, callback) do + elem({1, 2}, 0) + Enum.map([], fn(x) -> x end) callback.("started") end From ccfc037635a5de2017a35fea7be6d0ce7e193b03 Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Wed, 29 Mar 2017 19:53:53 -0500 Subject: [PATCH 059/418] minify bootstrap javascript --- package.json | 2 +- rollup.config.js | 2 + src/javascript/lib/core/protocol.js | 10 +- yarn.lock | 282 +++++++++++++++++++--------- 4 files changed, 201 insertions(+), 95 deletions(-) diff --git a/package.json b/package.json index bf002ba8..267ad790 100644 --- a/package.json +++ b/package.json @@ -44,7 +44,7 @@ "rollup": "^0.41.4", "rollup-plugin-babel": "^2.7.1", "rollup-plugin-node-resolve": "^2.0.0", - "rollup-plugin-uglify": "^1.0.1", + "rollup-plugin-babili": "^2.0.0", "sinon": "^1.17.7", "sinon-chai": "^2.8.0" } diff --git a/rollup.config.js b/rollup.config.js index 1f30fafa..a318efdf 100644 --- a/rollup.config.js +++ b/rollup.config.js @@ -1,5 +1,6 @@ import nodeResolve from 'rollup-plugin-node-resolve'; import babel from 'rollup-plugin-babel'; +import babili from 'rollup-plugin-babili'; export default { entry: 'src/javascript/elixir.js', @@ -9,6 +10,7 @@ export default { babel({ babelrc: false, }), + babili({}), ], targets: [{ dest: 'priv/build/iife/Elixir.Bootstrap.js', format: 'iife' }], }; diff --git a/src/javascript/lib/core/protocol.js b/src/javascript/lib/core/protocol.js index 936fc59e..52c25426 100644 --- a/src/javascript/lib/core/protocol.js +++ b/src/javascript/lib/core/protocol.js @@ -6,12 +6,8 @@ class Protocol { this.registry = new Map(); this.fallback = null; - for (const funName in spec) { - this[funName] = createFun(funName).bind(this); - } - function createFun(funName) { - return function (...args) { + return function(...args) { const thing = args[0]; let fun = null; @@ -41,6 +37,10 @@ class Protocol { throw new Error(`No implementation found for ${thing}`); }; } + + for (const funName in spec) { + this[funName] = createFun(funName).bind(this); + } } implementation(type, implementation) { diff --git a/yarn.lock b/yarn.lock index dd23136f..a4a74440 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,6 +2,10 @@ # yarn lockfile v1 +"@comandeer/babel-plugin-banner@^1.0.0": + version "1.0.0" + resolved "https://registry.yarnpkg.com/@comandeer/babel-plugin-banner/-/babel-plugin-banner-1.0.0.tgz#40bcce0bbee084b5b02545a33635d053c248356f" + acorn-jsx@^3.0.0: version "3.0.1" resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-3.0.1.tgz#afdf9488fb1ecefc8348f6fb22f464e32a58b36b" @@ -31,14 +35,6 @@ ajv@^4.7.0: co "^4.6.0" json-stable-stringify "^1.0.1" -align-text@^0.1.1, align-text@^0.1.3: - version "0.1.4" - resolved "https://registry.yarnpkg.com/align-text/-/align-text-0.1.4.tgz#0cd90a561093f35d0a99256c22b7069433fad117" - dependencies: - kind-of "^3.0.2" - longest "^1.0.1" - repeat-string "^1.5.2" - amdefine@>=0.0.4: version "1.0.1" resolved "https://registry.yarnpkg.com/amdefine/-/amdefine-1.0.1.tgz#4a5282ac164729e93619bcfd3ad151f817ce91f5" @@ -101,10 +97,6 @@ assertion-error@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/assertion-error/-/assertion-error-1.0.2.tgz#13ca515d86206da0bac66e834dd397d87581094c" -async@~0.2.6: - version "0.2.10" - resolved "https://registry.yarnpkg.com/async/-/async-0.2.10.tgz#b6bbe0b0674b9d719708ca38de8c237cb526c3d1" - atob@~1.1.0: version "1.1.3" resolved "https://registry.yarnpkg.com/atob/-/atob-1.1.3.tgz#95f13629b12c3a51a5d215abdce2aa9f32f80773" @@ -117,7 +109,7 @@ babel-code-frame@^6.16.0, babel-code-frame@^6.22.0: esutils "^2.0.2" js-tokens "^3.0.0" -babel-core@6, babel-core@^6.0.2, babel-core@^6.23.0, babel-core@^6.7.7: +babel-core@6, babel-core@^6.0.2, babel-core@^6.21.0, babel-core@^6.23.0, babel-core@^6.7.7: version "6.23.1" resolved "https://registry.yarnpkg.com/babel-core/-/babel-core-6.23.1.tgz#c143cb621bb2f621710c220c5d579d15b8a442df" dependencies: @@ -197,6 +189,10 @@ babel-helper-define-map@^6.23.0: babel-types "^6.23.0" lodash "^4.2.0" +babel-helper-evaluate-path@^0.0.3: + version "0.0.3" + resolved "https://registry.yarnpkg.com/babel-helper-evaluate-path/-/babel-helper-evaluate-path-0.0.3.tgz#1d103ac9d4a59e5d431842212f151785f7ac547b" + babel-helper-explode-assignable-expression@^6.22.0: version "6.22.0" resolved "https://registry.yarnpkg.com/babel-helper-explode-assignable-expression/-/babel-helper-explode-assignable-expression-6.22.0.tgz#c97bf76eed3e0bae4048121f2b9dae1a4e7d0478" @@ -214,6 +210,10 @@ babel-helper-explode-class@^6.22.0: babel-traverse "^6.22.0" babel-types "^6.22.0" +babel-helper-flip-expressions@^0.0.2: + version "0.0.2" + resolved "https://registry.yarnpkg.com/babel-helper-flip-expressions/-/babel-helper-flip-expressions-0.0.2.tgz#7bab2cf61162bc92703e9b298ef512bcf77d6787" + babel-helper-function-name@^6.22.0, babel-helper-function-name@^6.23.0: version "6.23.0" resolved "https://registry.yarnpkg.com/babel-helper-function-name/-/babel-helper-function-name-6.23.0.tgz#25742d67175c8903dbe4b6cb9d9e1fcb8dcf23a6" @@ -238,6 +238,18 @@ babel-helper-hoist-variables@^6.22.0: babel-runtime "^6.22.0" babel-types "^6.22.0" +babel-helper-is-nodes-equiv@^0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/babel-helper-is-nodes-equiv/-/babel-helper-is-nodes-equiv-0.0.1.tgz#34e9b300b1479ddd98ec77ea0bbe9342dfe39684" + +babel-helper-is-void-0@^0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/babel-helper-is-void-0/-/babel-helper-is-void-0-0.0.1.tgz#ed74553b883e68226ae45f989a99b02c190f105a" + +babel-helper-mark-eval-scopes@^0.0.3: + version "0.0.3" + resolved "https://registry.yarnpkg.com/babel-helper-mark-eval-scopes/-/babel-helper-mark-eval-scopes-0.0.3.tgz#902f75aeb537336edc35eb9f52b6f09db7785328" + babel-helper-optimise-call-expression@^6.23.0: version "6.23.0" resolved "https://registry.yarnpkg.com/babel-helper-optimise-call-expression/-/babel-helper-optimise-call-expression-6.23.0.tgz#f3ee7eed355b4282138b33d02b78369e470622f5" @@ -263,6 +275,10 @@ babel-helper-remap-async-to-generator@^6.22.0: babel-traverse "^6.22.0" babel-types "^6.22.0" +babel-helper-remove-or-void@^0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/babel-helper-remove-or-void/-/babel-helper-remove-or-void-0.0.1.tgz#f602790e465acf2dfbe84fb3dd210c43a2dd7262" + babel-helper-replace-supers@^6.22.0, babel-helper-replace-supers@^6.23.0: version "6.23.0" resolved "https://registry.yarnpkg.com/babel-helper-replace-supers/-/babel-helper-replace-supers-6.23.0.tgz#eeaf8ad9b58ec4337ca94223bacdca1f8d9b4bfd" @@ -274,6 +290,10 @@ babel-helper-replace-supers@^6.22.0, babel-helper-replace-supers@^6.23.0: babel-traverse "^6.23.0" babel-types "^6.23.0" +babel-helper-to-multiple-sequence-expressions@^0.0.4: + version "0.0.4" + resolved "https://registry.yarnpkg.com/babel-helper-to-multiple-sequence-expressions/-/babel-helper-to-multiple-sequence-expressions-0.0.4.tgz#d94414b386b6286fbaad77f073dea9b34324b01c" + babel-helpers@^6.23.0: version "6.23.0" resolved "https://registry.yarnpkg.com/babel-helpers/-/babel-helpers-6.23.0.tgz#4f8f2e092d0b6a8808a4bde79c27f1e2ecf0d992" @@ -299,6 +319,71 @@ babel-plugin-external-helpers@^6.4.0: dependencies: babel-runtime "^6.22.0" +babel-plugin-minify-builtins@^0.0.2: + version "0.0.2" + resolved "https://registry.yarnpkg.com/babel-plugin-minify-builtins/-/babel-plugin-minify-builtins-0.0.2.tgz#f3be6121763c0c518d5ef82067cef4b615c9498c" + dependencies: + babel-helper-evaluate-path "^0.0.3" + +babel-plugin-minify-constant-folding@^0.0.4: + version "0.0.4" + resolved "https://registry.yarnpkg.com/babel-plugin-minify-constant-folding/-/babel-plugin-minify-constant-folding-0.0.4.tgz#b6e231026a6035e88ceadd206128d7db2b5c15e6" + dependencies: + babel-helper-evaluate-path "^0.0.3" + jsesc "^2.4.0" + +babel-plugin-minify-dead-code-elimination@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/babel-plugin-minify-dead-code-elimination/-/babel-plugin-minify-dead-code-elimination-0.1.4.tgz#18b6ecfab77c29caca061d8210fa3495001e4fa1" + dependencies: + babel-helper-mark-eval-scopes "^0.0.3" + babel-helper-remove-or-void "^0.0.1" + lodash.some "^4.6.0" + +babel-plugin-minify-flip-comparisons@^0.0.2: + version "0.0.2" + resolved "https://registry.yarnpkg.com/babel-plugin-minify-flip-comparisons/-/babel-plugin-minify-flip-comparisons-0.0.2.tgz#7d0953aa5876ede6118966bda9edecc63bf346ab" + dependencies: + babel-helper-is-void-0 "^0.0.1" + +babel-plugin-minify-guarded-expressions@^0.0.4: + version "0.0.4" + resolved "https://registry.yarnpkg.com/babel-plugin-minify-guarded-expressions/-/babel-plugin-minify-guarded-expressions-0.0.4.tgz#957104a760e6a7ffd967005a7a11621bb42fd11c" + dependencies: + babel-helper-flip-expressions "^0.0.2" + +babel-plugin-minify-infinity@^0.0.3: + version "0.0.3" + resolved "https://registry.yarnpkg.com/babel-plugin-minify-infinity/-/babel-plugin-minify-infinity-0.0.3.tgz#4cc99b61d12b434ce80ad675103335c589cba9a1" + +babel-plugin-minify-mangle-names@^0.0.8: + version "0.0.8" + resolved "https://registry.yarnpkg.com/babel-plugin-minify-mangle-names/-/babel-plugin-minify-mangle-names-0.0.8.tgz#1e2fea856dd742d5697aa26b427e41258a8c5b79" + dependencies: + babel-helper-mark-eval-scopes "^0.0.3" + +babel-plugin-minify-numeric-literals@^0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/babel-plugin-minify-numeric-literals/-/babel-plugin-minify-numeric-literals-0.0.1.tgz#9597e6c31154d7daf3744d0bd417c144b275bd53" + +babel-plugin-minify-replace@^0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/babel-plugin-minify-replace/-/babel-plugin-minify-replace-0.0.1.tgz#5d5aea7cb9899245248d1ee9ce7a2fe556a8facc" + +babel-plugin-minify-simplify@^0.0.8: + version "0.0.8" + resolved "https://registry.yarnpkg.com/babel-plugin-minify-simplify/-/babel-plugin-minify-simplify-0.0.8.tgz#597b23327bba4373fed1c51461a689bce9ff4979" + dependencies: + babel-helper-flip-expressions "^0.0.2" + babel-helper-is-nodes-equiv "^0.0.1" + babel-helper-to-multiple-sequence-expressions "^0.0.4" + +babel-plugin-minify-type-constructors@^0.0.4: + version "0.0.4" + resolved "https://registry.yarnpkg.com/babel-plugin-minify-type-constructors/-/babel-plugin-minify-type-constructors-0.0.4.tgz#52d8b623775107523227719ade2d0b7458758b5f" + dependencies: + babel-helper-is-void-0 "^0.0.1" + babel-plugin-syntax-async-functions@^6.8.0: version "6.13.0" resolved "https://registry.yarnpkg.com/babel-plugin-syntax-async-functions/-/babel-plugin-syntax-async-functions-6.13.0.tgz#cad9cad1191b5ad634bf30ae0872391e0647be95" @@ -602,6 +687,24 @@ babel-plugin-transform-function-bind@^6.22.0: babel-plugin-syntax-function-bind "^6.8.0" babel-runtime "^6.22.0" +babel-plugin-transform-inline-consecutive-adds@^0.0.2: + version "0.0.2" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-inline-consecutive-adds/-/babel-plugin-transform-inline-consecutive-adds-0.0.2.tgz#a58fcecfc09c08fbf9373a5a3e70746c03d01fc1" + +babel-plugin-transform-member-expression-literals@^6.8.1: + version "6.8.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-member-expression-literals/-/babel-plugin-transform-member-expression-literals-6.8.1.tgz#60b78cb2b814ac71dd6104ef51c496c62e877337" + +babel-plugin-transform-merge-sibling-variables@^6.8.2: + version "6.8.2" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-merge-sibling-variables/-/babel-plugin-transform-merge-sibling-variables-6.8.2.tgz#498acd07481ab340c1bad8b726c2fad1b8f644e5" + +babel-plugin-transform-minify-booleans@^6.8.0: + version "6.8.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-minify-booleans/-/babel-plugin-transform-minify-booleans-6.8.0.tgz#b1a48864a727847696b84eae36fa4d085a54b42b" + dependencies: + babel-runtime "^6.0.0" + babel-plugin-transform-object-rest-spread@^6.22.0: version "6.23.0" resolved "https://registry.yarnpkg.com/babel-plugin-transform-object-rest-spread/-/babel-plugin-transform-object-rest-spread-6.23.0.tgz#875d6bc9be761c58a2ae3feee5dc4895d8c7f921" @@ -609,6 +712,10 @@ babel-plugin-transform-object-rest-spread@^6.22.0: babel-plugin-syntax-object-rest-spread "^6.8.0" babel-runtime "^6.22.0" +babel-plugin-transform-property-literals@^6.8.1: + version "6.8.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-property-literals/-/babel-plugin-transform-property-literals-6.8.1.tgz#05ed01f6024820b18f1d0495c80fe287176bccd9" + babel-plugin-transform-react-display-name@^6.23.0: version "6.23.0" resolved "https://registry.yarnpkg.com/babel-plugin-transform-react-display-name/-/babel-plugin-transform-react-display-name-6.23.0.tgz#4398910c358441dc4cef18787264d0412ed36b37" @@ -643,6 +750,26 @@ babel-plugin-transform-regenerator@^6.22.0: dependencies: regenerator-transform "0.9.8" +babel-plugin-transform-regexp-constructors@^0.0.6: + version "0.0.6" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-regexp-constructors/-/babel-plugin-transform-regexp-constructors-0.0.6.tgz#0d92607f0d26268296980cb7c1dea5f2dd3e1e20" + +babel-plugin-transform-remove-console@^6.8.1: + version "6.8.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-remove-console/-/babel-plugin-transform-remove-console-6.8.1.tgz#38f6a6ca1581e76b75fc2c6fdcf909deadee7d6a" + +babel-plugin-transform-remove-debugger@^6.8.1: + version "6.8.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-remove-debugger/-/babel-plugin-transform-remove-debugger-6.8.1.tgz#aabd0be107f8299094defe8e1ba8ccf4b114d07f" + +babel-plugin-transform-remove-undefined@^0.0.5: + version "0.0.5" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-remove-undefined/-/babel-plugin-transform-remove-undefined-0.0.5.tgz#12ef11805e06e861dd2eb0c7cc041d2184b8f410" + +babel-plugin-transform-simplify-comparison-operators@^6.8.1: + version "6.8.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-simplify-comparison-operators/-/babel-plugin-transform-simplify-comparison-operators-6.8.1.tgz#a307088e0d1c728081777fba568f4107396ab25c" + babel-plugin-transform-strict-mode@^6.22.0: version "6.22.0" resolved "https://registry.yarnpkg.com/babel-plugin-transform-strict-mode/-/babel-plugin-transform-strict-mode-6.22.0.tgz#e008df01340fdc87e959da65991b7e05970c8c7c" @@ -650,6 +777,40 @@ babel-plugin-transform-strict-mode@^6.22.0: babel-runtime "^6.22.0" babel-types "^6.22.0" +babel-plugin-transform-undefined-to-void@^6.8.0: + version "6.8.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-undefined-to-void/-/babel-plugin-transform-undefined-to-void-6.8.0.tgz#bc5b6b4908d3b1262170e67cb3963903ddce167e" + dependencies: + babel-runtime "^6.0.0" + +babel-preset-babili@^0.0.12: + version "0.0.12" + resolved "https://registry.yarnpkg.com/babel-preset-babili/-/babel-preset-babili-0.0.12.tgz#74d79205d54feae6470bc84231da0b9ac9fc7de9" + dependencies: + babel-plugin-minify-builtins "^0.0.2" + babel-plugin-minify-constant-folding "^0.0.4" + babel-plugin-minify-dead-code-elimination "^0.1.4" + babel-plugin-minify-flip-comparisons "^0.0.2" + babel-plugin-minify-guarded-expressions "^0.0.4" + babel-plugin-minify-infinity "^0.0.3" + babel-plugin-minify-mangle-names "^0.0.8" + babel-plugin-minify-numeric-literals "^0.0.1" + babel-plugin-minify-replace "^0.0.1" + babel-plugin-minify-simplify "^0.0.8" + babel-plugin-minify-type-constructors "^0.0.4" + babel-plugin-transform-inline-consecutive-adds "^0.0.2" + babel-plugin-transform-member-expression-literals "^6.8.1" + babel-plugin-transform-merge-sibling-variables "^6.8.2" + babel-plugin-transform-minify-booleans "^6.8.0" + babel-plugin-transform-property-literals "^6.8.1" + babel-plugin-transform-regexp-constructors "^0.0.6" + babel-plugin-transform-remove-console "^6.8.1" + babel-plugin-transform-remove-debugger "^6.8.1" + babel-plugin-transform-remove-undefined "^0.0.5" + babel-plugin-transform-simplify-comparison-operators "^6.8.1" + babel-plugin-transform-undefined-to-void "^6.8.0" + lodash.isplainobject "^4.0.6" + babel-preset-es2015-rollup@^1.1.1: version "1.2.0" resolved "https://registry.yarnpkg.com/babel-preset-es2015-rollup/-/babel-preset-es2015-rollup-1.2.0.tgz#feedf80346e01fa22d4de15e72cde1cefc59bf67" @@ -751,7 +912,7 @@ babel-register@^6.23.0: mkdirp "^0.5.1" source-map-support "^0.4.2" -babel-runtime@^6.18.0, babel-runtime@^6.22.0: +babel-runtime@^6.0.0, babel-runtime@^6.18.0, babel-runtime@^6.22.0: version "6.23.0" resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-6.23.0.tgz#0a9489f144de70efb3ce4300accdb329e2fc543b" dependencies: @@ -846,17 +1007,6 @@ callsites@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/callsites/-/callsites-0.2.0.tgz#afab96262910a7f33c19a5775825c69f34e350ca" -camelcase@^1.0.2: - version "1.2.1" - resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-1.2.1.tgz#9bb5304d2e0b56698b2c758b08a3eaa9daa58a39" - -center-align@^0.1.1: - version "0.1.3" - resolved "https://registry.yarnpkg.com/center-align/-/center-align-0.1.3.tgz#aa0d32629b6ee972200411cbd4461c907bc2b7ad" - dependencies: - align-text "^0.1.3" - lazy-cache "^1.0.3" - chai@^3.5.0: version "3.5.0" resolved "https://registry.yarnpkg.com/chai/-/chai-3.5.0.tgz#4d02637b067fe958bdbfdd3a40ec56fef7373247" @@ -889,14 +1039,6 @@ cli-width@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-2.1.0.tgz#b234ca209b29ef66fc518d9b98d5847b00edf00a" -cliui@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/cliui/-/cliui-2.1.0.tgz#4b475760ff80264c762c3a1719032e91c7fea0d1" - dependencies: - center-align "^0.1.1" - right-align "^0.1.1" - wordwrap "0.0.2" - clone-stats@^0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/clone-stats/-/clone-stats-0.0.1.tgz#b88f94a82cf38b8791d58046ea4029ad88ca99d1" @@ -992,10 +1134,6 @@ debug@2.X, debug@^2.1.1, debug@^2.2.0: dependencies: ms "0.7.2" -decamelize@^1.0.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" - deep-eql@^0.1.3: version "0.1.3" resolved "https://registry.yarnpkg.com/deep-eql/-/deep-eql-0.1.3.tgz#ef558acab8de25206cd713906d74e56930eb69f2" @@ -1875,6 +2013,10 @@ jsesc@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-1.3.0.tgz#46c3fec8c1892b12b0833db9bc7622176dbab34b" +jsesc@^2.4.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.4.0.tgz#8568d223ff69c0b5e081b4f8edf5a23d978c9867" + jsesc@~0.5.0: version "0.5.0" resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-0.5.0.tgz#e7dee66e35d6fc16f710fe91d5cf69f70f08911d" @@ -1903,10 +2045,6 @@ kind-of@^3.0.2: dependencies: is-buffer "^1.0.2" -lazy-cache@^1.0.3: - version "1.0.4" - resolved "https://registry.yarnpkg.com/lazy-cache/-/lazy-cache-1.0.4.tgz#a1d78fc3a50474cb80845d3b3b6e1da49a446e8e" - lazy-debug-legacy@0.0.X: version "0.0.1" resolved "https://registry.yarnpkg.com/lazy-debug-legacy/-/lazy-debug-legacy-0.0.1.tgz#537716c0776e4cf79e3ed1b621f7658c2911b1b1" @@ -1994,7 +2132,7 @@ lodash.isempty@^4.2.1: version "4.4.0" resolved "https://registry.yarnpkg.com/lodash.isempty/-/lodash.isempty-4.4.0.tgz#6f86cbedd8be4ec987be9aaf33c9684db1b31e7e" -lodash.isplainobject@^4.0.4: +lodash.isplainobject@^4.0.4, lodash.isplainobject@^4.0.6: version "4.0.6" resolved "https://registry.yarnpkg.com/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz#7c526a52d89b45c45cc690b88163be0497f550cb" @@ -2022,6 +2160,10 @@ lodash.restparam@^3.0.0: version "3.6.1" resolved "https://registry.yarnpkg.com/lodash.restparam/-/lodash.restparam-3.6.1.tgz#936a4e309ef330a7645ed4145986c85ae5b20805" +lodash.some@^4.6.0: + version "4.6.0" + resolved "https://registry.yarnpkg.com/lodash.some/-/lodash.some-4.6.0.tgz#1bb9f314ef6b8baded13b549169b2a945eb68e4d" + lodash.template@^3.0.0: version "3.6.2" resolved "https://registry.yarnpkg.com/lodash.template/-/lodash.template-3.6.2.tgz#f8cdecc6169a255be9098ae8b0c53d378931d14f" @@ -2055,10 +2197,6 @@ lolex@1.3.2: version "1.3.2" resolved "https://registry.yarnpkg.com/lolex/-/lolex-1.3.2.tgz#7c3da62ffcb30f0f5a80a2566ca24e45d8a01f31" -longest@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/longest/-/longest-1.0.1.tgz#30a0b2da38f73770e8294a0d22e6625ed77d0097" - loose-envify@^1.0.0: version "1.3.1" resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.3.1.tgz#d1a8ad33fa9ce0e713d65fdd0ac8b748d478c848" @@ -2512,12 +2650,6 @@ restore-cursor@^1.0.1: exit-hook "^1.0.0" onetime "^1.0.0" -right-align@^0.1.1: - version "0.1.3" - resolved "https://registry.yarnpkg.com/right-align/-/right-align-0.1.3.tgz#61339b722fe6a3515689210d24e14c96148613ef" - dependencies: - align-text "^0.1.1" - rimraf@^2.2.8: version "2.6.1" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.1.tgz#c2338ec643df7a1b7fe5c54fa86f57428a55f33d" @@ -2533,6 +2665,14 @@ rollup-plugin-babel@^2.7.1: object-assign "^4.1.0" rollup-pluginutils "^1.5.0" +rollup-plugin-babili@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/rollup-plugin-babili/-/rollup-plugin-babili-2.0.0.tgz#3695cb851c661af5f2834836c22ca0822ff9647b" + dependencies: + "@comandeer/babel-plugin-banner" "^1.0.0" + babel-core "^6.21.0" + babel-preset-babili "^0.0.12" + rollup-plugin-node-resolve@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/rollup-plugin-node-resolve/-/rollup-plugin-node-resolve-2.0.0.tgz#07e0ae94ac002a3ea36e8f33ca121d9f836b1309" @@ -2541,12 +2681,6 @@ rollup-plugin-node-resolve@^2.0.0: builtin-modules "^1.1.0" resolve "^1.1.6" -rollup-plugin-uglify@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/rollup-plugin-uglify/-/rollup-plugin-uglify-1.0.1.tgz#11d0b0c8bcd2d07e6908f74fd16b0152390b922a" - dependencies: - uglify-js "^2.6.1" - rollup-pluginutils@^1.5.0: version "1.5.2" resolved "https://registry.yarnpkg.com/rollup-pluginutils/-/rollup-pluginutils-1.5.2.tgz#1e156e778f94b7255bfa1b3d0178be8f5c552408" @@ -2634,7 +2768,7 @@ source-map-url@~0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.3.0.tgz#7ecaf13b57bcd09da8a40c5d269db33799d4aaf9" -source-map@0.X, source-map@^0.5.0, source-map@^0.5.1, source-map@^0.5.3, source-map@~0.5.1: +source-map@0.X, source-map@^0.5.0, source-map@^0.5.1, source-map@^0.5.3: version "0.5.6" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.6.tgz#75ce38f52bf0733c5a7f0c118d81334a2bb5f412" @@ -2787,19 +2921,6 @@ typedarray@^0.0.6: version "0.0.6" resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" -uglify-js@^2.6.1: - version "2.7.5" - resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-2.7.5.tgz#4612c0c7baaee2ba7c487de4904ae122079f2ca8" - dependencies: - async "~0.2.6" - source-map "~0.5.1" - uglify-to-browserify "~1.0.0" - yargs "~3.10.0" - -uglify-to-browserify@~1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz#6e0924d6bda6b5afe349e39a6d632850a0f882b7" - unc-path-regex@^0.1.0: version "0.1.2" resolved "https://registry.yarnpkg.com/unc-path-regex/-/unc-path-regex-0.1.2.tgz#e73dd3d7b0d7c5ed86fbac6b0ae7d8c6a69d50fa" @@ -2886,14 +3007,6 @@ which@^1.2.12: dependencies: isexe "^1.1.1" -window-size@0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/window-size/-/window-size-0.1.0.tgz#5438cd2ea93b202efa3a19fe8887aee7c94f9c9d" - -wordwrap@0.0.2: - version "0.0.2" - resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-0.0.2.tgz#b79669bb42ecb409f83d583cad52ca17eaa1643f" - wordwrap@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb" @@ -2911,12 +3024,3 @@ write@^0.2.1: "xtend@>=4.0.0 <4.1.0-0", xtend@^4.0.0, xtend@~4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.1.tgz#a5c6d532be656e23db820efb943a1f04998d63af" - -yargs@~3.10.0: - version "3.10.0" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-3.10.0.tgz#f7ee7bd857dd7c1d2d38c0e74efbd681d1431fd1" - dependencies: - camelcase "^1.0.2" - cliui "^2.1.0" - decamelize "^1.0.0" - window-size "0.1.0" From 0abc16d2a425870e8ce694bbe4aaab8324565d96 Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Sat, 1 Apr 2017 09:23:27 -0500 Subject: [PATCH 060/418] Fix tests --- test/translator/bug_test.exs | 2 +- test/translator/capture_test.exs | 2 +- test/translator/function_test.exs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/test/translator/bug_test.exs b/test/translator/bug_test.exs index 2980d8a8..f4474eb1 100644 --- a/test/translator/bug_test.exs +++ b/test/translator/bug_test.exs @@ -47,7 +47,7 @@ defmodule ElixirScript.Translator.Bug.Test do end js_code = """ - Bootstrap.Enum.fetch__emark__(data, i) + Elixir.ElixirScript.Enum.__load(Elixir).fetch__emark__(data, i) """ assert_translation(ex_ast, js_code) diff --git a/test/translator/capture_test.exs b/test/translator/capture_test.exs index ea61fc93..892321ac 100644 --- a/test/translator/capture_test.exs +++ b/test/translator/capture_test.exs @@ -103,7 +103,7 @@ defmodule ElixirScript.Translator.Capture.Test do end js_code = """ - Bootstrap.Enum.map(Object.freeze([]),Bootstrap.Core.Patterns.defmatch(Bootstrap.Core.Patterns.clause([Bootstrap.Core.Patterns.variable()],function(__1) { + Elixir.ElixirScript.Enum.__load(Elixir).map(Object.freeze([]),Bootstrap.Core.Patterns.defmatch(Bootstrap.Core.Patterns.clause([Bootstrap.Core.Patterns.variable()],function(__1) { return process(__1); }))) """ diff --git a/test/translator/function_test.exs b/test/translator/function_test.exs index 5b48c6d0..0f883e30 100644 --- a/test/translator/function_test.exs +++ b/test/translator/function_test.exs @@ -176,7 +176,7 @@ defmodule ElixirScript.Translator.Function.Test do end js_code = """ - Bootstrap.Enum.map(list,Bootstrap.Core.Patterns.defmatch(Bootstrap.Core.Patterns.clause([Bootstrap.Core.Patterns.variable()],function(x) { + Elixir.ElixirScript.Enum.__load(Elixir).map(list,Bootstrap.Core.Patterns.defmatch(Bootstrap.Core.Patterns.clause([Bootstrap.Core.Patterns.variable()],function(x) { return x * 2; }))) """ From 908e97ac60002e93cc1ae5171a70aa620afb1559 Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Sat, 1 Apr 2017 15:23:54 -0500 Subject: [PATCH 061/418] Update tailored dependency --- package.json | 2 +- yarn.lock | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/package.json b/package.json index 267ad790..76c1c998 100644 --- a/package.json +++ b/package.json @@ -23,7 +23,7 @@ "license": "MIT", "dependencies": { "erlang-types": "^1.0.0", - "tailored": "2.3.2" + "tailored": "2.4.1" }, "devDependencies": { "babel": "^6.5.2", diff --git a/yarn.lock b/yarn.lock index a4a74440..c1f5510d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2849,9 +2849,9 @@ table@^3.7.8: slice-ansi "0.0.4" string-width "^2.0.0" -tailored@2.3.2: - version "2.3.2" - resolved "https://registry.yarnpkg.com/tailored/-/tailored-2.3.2.tgz#4081db326b339dd31048c142d52cda3f95c6a135" +tailored@2.4.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/tailored/-/tailored-2.4.1.tgz#5fa0988704af192171dfe1299060ec97611225b4" dependencies: erlang-types "^1.0.0" From 605ed18b98ae85f7c24a2d6b84d020b1c0b8219c Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Sat, 1 Apr 2017 15:31:01 -0500 Subject: [PATCH 062/418] Update deps --- .credo.exs | 2 +- mix.exs | 5 ++--- mix.lock | 2 +- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/.credo.exs b/.credo.exs index ea83b9c6..5c1f8ef1 100644 --- a/.credo.exs +++ b/.credo.exs @@ -78,7 +78,7 @@ {Credo.Check.Readability.ModuleAttributeNames}, {Credo.Check.Readability.ModuleDoc}, {Credo.Check.Readability.ModuleNames}, - {Credo.Check.Readability.NoParenthesesWhenZeroArity}, + {Credo.Check.Readability.ParenthesesOnZeroArityDefs}, {Credo.Check.Readability.ParenthesesInCondition}, {Credo.Check.Readability.PredicateFunctionNames}, {Credo.Check.Readability.PreferImplicitTry}, diff --git a/mix.exs b/mix.exs index b16da257..c31d1f54 100644 --- a/mix.exs +++ b/mix.exs @@ -14,7 +14,6 @@ defmodule ElixirScript.Mixfile do source_url: "https://github.com/elixirscript/elixirscript", aliases: aliases(), test_coverage: [tool: ExCoveralls], - preferred_cli_env: [coveralls: :test], docs: [ extras: ["GettingStarted.md", "FAQ.md"] ] @@ -32,8 +31,8 @@ defmodule ElixirScript.Mixfile do {:estree, "~> 2.5"}, {:fs, "~> 2.12"}, {:ex_doc, "~> 0.14", only: :dev}, - {:excoveralls, "~> 0.5", only: :test}, - {:credo, "~> 0.4", only: [:dev, :test]} + {:excoveralls, "~> 0.6", only: :test}, + {:credo, "~> 0.7", only: [:dev, :test]} ] end diff --git a/mix.lock b/mix.lock index 2020bc3f..0e03c5b6 100644 --- a/mix.lock +++ b/mix.lock @@ -1,6 +1,6 @@ %{"bunt": {:hex, :bunt, "0.2.0", "951c6e801e8b1d2cbe58ebbd3e616a869061ddadcc4863d0a2182541acae9a38", [:mix], []}, "certifi": {:hex, :certifi, "0.7.0", "861a57f3808f7eb0c2d1802afeaae0fa5de813b0df0979153cbafcd853ababaf", [:rebar3], []}, - "credo": {:hex, :credo, "0.6.1", "a941e2591bd2bd2055dc92b810c174650b40b8290459c89a835af9d59ac4a5f8", [:mix], [{:bunt, "~> 0.2.0", [hex: :bunt, optional: false]}]}, + "credo": {:hex, :credo, "0.7.2", "850463f126c09227994967fdcf8b8ad7684ab220f7727c00bcafc0ac37bd3660", [:mix], [{:bunt, "~> 0.2.0", [hex: :bunt, optional: false]}]}, "earmark": {:hex, :earmark, "1.1.1", "433136b7f2e99cde88b745b3a0cfc3fbc81fe58b918a09b40fce7f00db4d8187", [:mix], []}, "estree": {:hex, :estree, "2.5.1", "c93a8fa8a29886e6a6f6c489ba6dc949b998d2985b189967e41e69a92b58e846", [:mix], []}, "ex_doc": {:hex, :ex_doc, "0.14.5", "c0433c8117e948404d93ca69411dd575ec6be39b47802e81ca8d91017a0cf83c", [:mix], [{:earmark, "~> 1.0", [hex: :earmark, optional: false]}]}, From c6ab0a9e8a5cbc43eb68ee9102928714c627ec05 Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Sun, 2 Apr 2017 05:00:43 -0500 Subject: [PATCH 063/418] Cleaning up javascript environment --- .babelrc | 4 +- .flowconfig | 12 - .travis.yml | 2 +- gulpfile.js | 11 - package.json | 21 +- test/app/spec/setup.spec.js | 6 +- yarn.lock | 1579 ++++++----------------------------- 7 files changed, 249 insertions(+), 1386 deletions(-) delete mode 100644 .flowconfig delete mode 100644 gulpfile.js diff --git a/.babelrc b/.babelrc index 9a615718..6a9be799 100644 --- a/.babelrc +++ b/.babelrc @@ -1,3 +1,5 @@ { - "plugins": ["transform-es2015-modules-commonjs"] + "presets": [ + "env" + ] } \ No newline at end of file diff --git a/.flowconfig b/.flowconfig deleted file mode 100644 index 7f76ba60..00000000 --- a/.flowconfig +++ /dev/null @@ -1,12 +0,0 @@ -[ignore] -.*/dist/.* -.*/build/.* -.*/dist_build/.* -.*/node_modules/.* - -[include] -./priv/javascript - -[libs] - -[options] diff --git a/.travis.yml b/.travis.yml index c6facb26..a1fb4260 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,7 +5,7 @@ elixir: otp_release: - 19.0 env: - - TRAVIS_NODE_VERSION="6" + - TRAVIS_NODE_VERSION="7" install: - rm -rf ~/.nvm && git clone https://github.com/creationix/nvm.git ~/.nvm && (cd ~/.nvm && git checkout `git describe --abbrev=0 --tags`) && source ~/.nvm/nvm.sh && nvm install $TRAVIS_NODE_VERSION - npm install -g yarn diff --git a/gulpfile.js b/gulpfile.js deleted file mode 100644 index ac7ed7db..00000000 --- a/gulpfile.js +++ /dev/null @@ -1,11 +0,0 @@ -const gulp = require('gulp'); -const babel = require('gulp-babel'); -const sourcemaps = require('gulp-sourcemaps'); - -const path = './src/javascript'; - -gulp.task('build', () => gulp.src([`${path}/**/*.js`, `!${path}/dist_build/**/*.js`, `!${path}/tests/**/*.js`]) - .pipe(sourcemaps.init()) - .pipe(babel({ presets: ['react', 'stage-0'], babelrc: false })) - .pipe(sourcemaps.write()) - .pipe(gulp.dest('./src/elixirscript'))); diff --git a/package.json b/package.json index 76c1c998..5be1f75c 100644 --- a/package.json +++ b/package.json @@ -13,7 +13,7 @@ "clean": "rm -rf priv/build", "test": "mocha src/javascript/tests --recursive --compilers js:babel-core/register", "build:test-app": "mix elixirscript test/app/src/ -f common -o test/app/build/", - "test-app": "yarn run build:test-app && NODE_ENV=test mocha --recursive 'test/app/spec/**/*.spec.js' --compilers js:babel-core/register" + "test-app": "yarn run build:test-app && NODE_ENV=test mocha --recursive 'test/app/spec/**/*.spec.js' --compilers js:babel-register" }, "repository": { "type": "git", @@ -26,25 +26,18 @@ "tailored": "2.4.1" }, "devDependencies": { - "babel": "^6.5.2", - "babel-core": "^6.7.7", - "babel-plugin-transform-class-properties": "^6.9.1", - "babel-preset-es2015": "^6.6.0", - "babel-preset-es2015-rollup": "^1.1.1", - "babel-preset-react": "^6.5.0", - "babel-preset-stage-0": "^6.5.0", + "babel-core": "^6.24.0", + "babel-register": "^6.24.0", + "babel-preset-env": "^1.3.2", "chai": "^3.5.0", "eslint": "^3.15.0", "eslint-config-airbnb-base": "^11.1.0", "eslint-plugin-import": "^2.2.0", - "gulp": "^3.9.1", - "gulp-babel": "^6.1.2", - "gulp-sourcemaps": "^2.0.0-alpha", - "mocha": "^2.4.5", - "rollup": "^0.41.4", + "mocha": "^3.2.0", + "rollup": "^0.41.6", "rollup-plugin-babel": "^2.7.1", - "rollup-plugin-node-resolve": "^2.0.0", "rollup-plugin-babili": "^2.0.0", + "rollup-plugin-node-resolve": "^2.0.0", "sinon": "^1.17.7", "sinon-chai": "^2.8.0" } diff --git a/test/app/spec/setup.spec.js b/test/app/spec/setup.spec.js index b1c0f404..3e9f4714 100644 --- a/test/app/spec/setup.spec.js +++ b/test/app/spec/setup.spec.js @@ -2,14 +2,14 @@ const sinon = require('sinon'); const chai = require('chai'); const sinonChai = require('sinon-chai'); -before(function () { +before(function() { chai.use(sinonChai); }); -beforeEach(function () { +beforeEach(function() { this.sandbox = sinon.sandbox.create(); }); -afterEach(function () { +afterEach(function() { this.sandbox.restore(); }); diff --git a/yarn.lock b/yarn.lock index c1f5510d..c7b7c84c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -12,33 +12,25 @@ acorn-jsx@^3.0.0: dependencies: acorn "^3.0.4" -acorn@4.0.4: - version "4.0.4" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-4.0.4.tgz#17a8d6a7a6c4ef538b814ec9abac2779293bf30a" - -acorn@4.X: - version "4.0.11" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-4.0.11.tgz#edcda3bd937e7556410d42ed5860f67399c794c0" - acorn@^3.0.4: version "3.3.0" resolved "https://registry.yarnpkg.com/acorn/-/acorn-3.3.0.tgz#45e37fb39e8da3f25baee3ff5369e2bb5f22017a" +acorn@^5.0.1: + version "5.0.3" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.0.3.tgz#c460df08491463f028ccb82eab3730bf01087b3d" + ajv-keywords@^1.0.0: version "1.5.1" resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-1.5.1.tgz#314dd0a4b3368fad3dfcdc54ede6171b886daf3c" ajv@^4.7.0: - version "4.11.3" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-4.11.3.tgz#ce30bdb90d1254f762c75af915fb3a63e7183d22" + version "4.11.5" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-4.11.5.tgz#b6ee74657b993a01dce44b7944d56f485828d5bd" dependencies: co "^4.6.0" json-stable-stringify "^1.0.1" -amdefine@>=0.0.4: - version "1.0.1" - resolved "https://registry.yarnpkg.com/amdefine/-/amdefine-1.0.1.tgz#4a5282ac164729e93619bcfd3ad151f817ce91f5" - ansi-escapes@^1.1.0: version "1.4.0" resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-1.4.0.tgz#d3a8a83b319aa67793662b13e761c7911422306e" @@ -51,44 +43,22 @@ ansi-styles@^2.2.1: version "2.2.1" resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe" -archy@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/archy/-/archy-1.0.0.tgz#f9c8c13757cc1dd7bc379ac77b2c62a5c2868c40" - argparse@^1.0.7: version "1.0.9" resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.9.tgz#73d83bc263f86e97f8cc4f6bae1b0e90a7d22c86" dependencies: sprintf-js "~1.0.2" -arr-diff@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-2.0.0.tgz#8f3b827f955a8bd669697e4a4256ac3ceae356cf" - dependencies: - arr-flatten "^1.0.1" - -arr-flatten@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/arr-flatten/-/arr-flatten-1.0.1.tgz#e5ffe54d45e19f32f216e91eb99c8ce892bb604b" - -array-differ@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/array-differ/-/array-differ-1.0.0.tgz#eff52e3758249d33be402b8bb8e564bb2b5d4031" - array-union@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/array-union/-/array-union-1.0.2.tgz#9a34410e4f4e3da23dea375be5be70f24778ec39" dependencies: array-uniq "^1.0.1" -array-uniq@^1.0.1, array-uniq@^1.0.2: +array-uniq@^1.0.1: version "1.0.3" resolved "https://registry.yarnpkg.com/array-uniq/-/array-uniq-1.0.3.tgz#af6ac877a25cc7f74e058894753858dfdb24fdb6" -array-unique@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.2.1.tgz#a1d97ccafcbc2625cc70fadceb36a50c58b01a53" - arrify@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d" @@ -97,10 +67,6 @@ assertion-error@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/assertion-error/-/assertion-error-1.0.2.tgz#13ca515d86206da0bac66e834dd397d87581094c" -atob@~1.1.0: - version "1.1.3" - resolved "https://registry.yarnpkg.com/atob/-/atob-1.1.3.tgz#95f13629b12c3a51a5d215abdce2aa9f32f80773" - babel-code-frame@^6.16.0, babel-code-frame@^6.22.0: version "6.22.0" resolved "https://registry.yarnpkg.com/babel-code-frame/-/babel-code-frame-6.22.0.tgz#027620bee567a88c32561574e7fd0801d33118e4" @@ -109,15 +75,15 @@ babel-code-frame@^6.16.0, babel-code-frame@^6.22.0: esutils "^2.0.2" js-tokens "^3.0.0" -babel-core@6, babel-core@^6.0.2, babel-core@^6.21.0, babel-core@^6.23.0, babel-core@^6.7.7: - version "6.23.1" - resolved "https://registry.yarnpkg.com/babel-core/-/babel-core-6.23.1.tgz#c143cb621bb2f621710c220c5d579d15b8a442df" +babel-core@6, babel-core@^6.21.0, babel-core@^6.24.0: + version "6.24.0" + resolved "https://registry.yarnpkg.com/babel-core/-/babel-core-6.24.0.tgz#8f36a0a77f5c155aed6f920b844d23ba56742a02" dependencies: babel-code-frame "^6.22.0" - babel-generator "^6.23.0" + babel-generator "^6.24.0" babel-helpers "^6.23.0" babel-messages "^6.23.0" - babel-register "^6.23.0" + babel-register "^6.24.0" babel-runtime "^6.22.0" babel-template "^6.23.0" babel-traverse "^6.23.1" @@ -133,9 +99,9 @@ babel-core@6, babel-core@^6.0.2, babel-core@^6.21.0, babel-core@^6.23.0, babel-c slash "^1.0.0" source-map "^0.5.0" -babel-generator@^6.23.0: - version "6.23.0" - resolved "https://registry.yarnpkg.com/babel-generator/-/babel-generator-6.23.0.tgz#6b8edab956ef3116f79d8c84c5a3c05f32a74bc5" +babel-generator@^6.24.0: + version "6.24.0" + resolved "https://registry.yarnpkg.com/babel-generator/-/babel-generator-6.24.0.tgz#eba270a8cc4ce6e09a61be43465d7c62c1f87c56" dependencies: babel-messages "^6.23.0" babel-runtime "^6.22.0" @@ -146,14 +112,6 @@ babel-generator@^6.23.0: source-map "^0.5.0" trim-right "^1.0.1" -babel-helper-bindify-decorators@^6.22.0: - version "6.22.0" - resolved "https://registry.yarnpkg.com/babel-helper-bindify-decorators/-/babel-helper-bindify-decorators-6.22.0.tgz#d7f5bc261275941ac62acfc4e20dacfb8a3fe952" - dependencies: - babel-runtime "^6.22.0" - babel-traverse "^6.22.0" - babel-types "^6.22.0" - babel-helper-builder-binary-assignment-operator-visitor@^6.22.0: version "6.22.0" resolved "https://registry.yarnpkg.com/babel-helper-builder-binary-assignment-operator-visitor/-/babel-helper-builder-binary-assignment-operator-visitor-6.22.0.tgz#29df56be144d81bdeac08262bfa41d2c5e91cdcd" @@ -162,15 +120,6 @@ babel-helper-builder-binary-assignment-operator-visitor@^6.22.0: babel-runtime "^6.22.0" babel-types "^6.22.0" -babel-helper-builder-react-jsx@^6.23.0: - version "6.23.0" - resolved "https://registry.yarnpkg.com/babel-helper-builder-react-jsx/-/babel-helper-builder-react-jsx-6.23.0.tgz#d53fc8c996e0bc56d0de0fc4cc55a7138395ea4b" - dependencies: - babel-runtime "^6.22.0" - babel-types "^6.23.0" - esutils "^2.0.0" - lodash "^4.2.0" - babel-helper-call-delegate@^6.22.0: version "6.22.0" resolved "https://registry.yarnpkg.com/babel-helper-call-delegate/-/babel-helper-call-delegate-6.22.0.tgz#119921b56120f17e9dae3f74b4f5cc7bcc1b37ef" @@ -201,15 +150,6 @@ babel-helper-explode-assignable-expression@^6.22.0: babel-traverse "^6.22.0" babel-types "^6.22.0" -babel-helper-explode-class@^6.22.0: - version "6.22.0" - resolved "https://registry.yarnpkg.com/babel-helper-explode-class/-/babel-helper-explode-class-6.22.0.tgz#646304924aa6388a516843ba7f1855ef8dfeb69b" - dependencies: - babel-helper-bindify-decorators "^6.22.0" - babel-runtime "^6.22.0" - babel-traverse "^6.22.0" - babel-types "^6.22.0" - babel-helper-flip-expressions@^0.0.2: version "0.0.2" resolved "https://registry.yarnpkg.com/babel-helper-flip-expressions/-/babel-helper-flip-expressions-0.0.2.tgz#7bab2cf61162bc92703e9b298ef512bcf77d6787" @@ -313,12 +253,6 @@ babel-plugin-check-es2015-constants@^6.22.0: dependencies: babel-runtime "^6.22.0" -babel-plugin-external-helpers@^6.4.0: - version "6.22.0" - resolved "https://registry.yarnpkg.com/babel-plugin-external-helpers/-/babel-plugin-external-helpers-6.22.0.tgz#2285f48b02bd5dede85175caf8c62e86adccefa1" - dependencies: - babel-runtime "^6.22.0" - babel-plugin-minify-builtins@^0.0.2: version "0.0.2" resolved "https://registry.yarnpkg.com/babel-plugin-minify-builtins/-/babel-plugin-minify-builtins-0.0.2.tgz#f3be6121763c0c518d5ef82067cef4b615c9498c" @@ -388,66 +322,14 @@ babel-plugin-syntax-async-functions@^6.8.0: version "6.13.0" resolved "https://registry.yarnpkg.com/babel-plugin-syntax-async-functions/-/babel-plugin-syntax-async-functions-6.13.0.tgz#cad9cad1191b5ad634bf30ae0872391e0647be95" -babel-plugin-syntax-async-generators@^6.5.0: - version "6.13.0" - resolved "https://registry.yarnpkg.com/babel-plugin-syntax-async-generators/-/babel-plugin-syntax-async-generators-6.13.0.tgz#6bc963ebb16eccbae6b92b596eb7f35c342a8b9a" - -babel-plugin-syntax-class-constructor-call@^6.18.0: - version "6.18.0" - resolved "https://registry.yarnpkg.com/babel-plugin-syntax-class-constructor-call/-/babel-plugin-syntax-class-constructor-call-6.18.0.tgz#9cb9d39fe43c8600bec8146456ddcbd4e1a76416" - -babel-plugin-syntax-class-properties@^6.8.0: - version "6.13.0" - resolved "https://registry.yarnpkg.com/babel-plugin-syntax-class-properties/-/babel-plugin-syntax-class-properties-6.13.0.tgz#d7eb23b79a317f8543962c505b827c7d6cac27de" - -babel-plugin-syntax-decorators@^6.13.0: - version "6.13.0" - resolved "https://registry.yarnpkg.com/babel-plugin-syntax-decorators/-/babel-plugin-syntax-decorators-6.13.0.tgz#312563b4dbde3cc806cee3e416cceeaddd11ac0b" - -babel-plugin-syntax-do-expressions@^6.8.0: - version "6.13.0" - resolved "https://registry.yarnpkg.com/babel-plugin-syntax-do-expressions/-/babel-plugin-syntax-do-expressions-6.13.0.tgz#5747756139aa26d390d09410b03744ba07e4796d" - -babel-plugin-syntax-dynamic-import@^6.18.0: - version "6.18.0" - resolved "https://registry.yarnpkg.com/babel-plugin-syntax-dynamic-import/-/babel-plugin-syntax-dynamic-import-6.18.0.tgz#8d6a26229c83745a9982a441051572caa179b1da" - babel-plugin-syntax-exponentiation-operator@^6.8.0: version "6.13.0" resolved "https://registry.yarnpkg.com/babel-plugin-syntax-exponentiation-operator/-/babel-plugin-syntax-exponentiation-operator-6.13.0.tgz#9ee7e8337290da95288201a6a57f4170317830de" -babel-plugin-syntax-export-extensions@^6.8.0: - version "6.13.0" - resolved "https://registry.yarnpkg.com/babel-plugin-syntax-export-extensions/-/babel-plugin-syntax-export-extensions-6.13.0.tgz#70a1484f0f9089a4e84ad44bac353c95b9b12721" - -babel-plugin-syntax-flow@^6.18.0: - version "6.18.0" - resolved "https://registry.yarnpkg.com/babel-plugin-syntax-flow/-/babel-plugin-syntax-flow-6.18.0.tgz#4c3ab20a2af26aa20cd25995c398c4eb70310c8d" - -babel-plugin-syntax-function-bind@^6.8.0: - version "6.13.0" - resolved "https://registry.yarnpkg.com/babel-plugin-syntax-function-bind/-/babel-plugin-syntax-function-bind-6.13.0.tgz#48c495f177bdf31a981e732f55adc0bdd2601f46" - -babel-plugin-syntax-jsx@^6.3.13, babel-plugin-syntax-jsx@^6.8.0: - version "6.18.0" - resolved "https://registry.yarnpkg.com/babel-plugin-syntax-jsx/-/babel-plugin-syntax-jsx-6.18.0.tgz#0af32a9a6e13ca7a3fd5069e62d7b0f58d0d8946" - -babel-plugin-syntax-object-rest-spread@^6.8.0: - version "6.13.0" - resolved "https://registry.yarnpkg.com/babel-plugin-syntax-object-rest-spread/-/babel-plugin-syntax-object-rest-spread-6.13.0.tgz#fd6536f2bce13836ffa3a5458c4903a597bb3bf5" - babel-plugin-syntax-trailing-function-commas@^6.22.0: version "6.22.0" resolved "https://registry.yarnpkg.com/babel-plugin-syntax-trailing-function-commas/-/babel-plugin-syntax-trailing-function-commas-6.22.0.tgz#ba0360937f8d06e40180a43fe0d5616fff532cf3" -babel-plugin-transform-async-generator-functions@^6.22.0: - version "6.22.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-async-generator-functions/-/babel-plugin-transform-async-generator-functions-6.22.0.tgz#a720a98153a7596f204099cd5409f4b3c05bab46" - dependencies: - babel-helper-remap-async-to-generator "^6.22.0" - babel-plugin-syntax-async-generators "^6.5.0" - babel-runtime "^6.22.0" - babel-plugin-transform-async-to-generator@^6.22.0: version "6.22.0" resolved "https://registry.yarnpkg.com/babel-plugin-transform-async-to-generator/-/babel-plugin-transform-async-to-generator-6.22.0.tgz#194b6938ec195ad36efc4c33a971acf00d8cd35e" @@ -456,40 +338,6 @@ babel-plugin-transform-async-to-generator@^6.22.0: babel-plugin-syntax-async-functions "^6.8.0" babel-runtime "^6.22.0" -babel-plugin-transform-class-constructor-call@^6.22.0: - version "6.22.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-class-constructor-call/-/babel-plugin-transform-class-constructor-call-6.22.0.tgz#11a4d2216abb5b0eef298b493748f4f2f4869120" - dependencies: - babel-plugin-syntax-class-constructor-call "^6.18.0" - babel-runtime "^6.22.0" - babel-template "^6.22.0" - -babel-plugin-transform-class-properties@^6.22.0, babel-plugin-transform-class-properties@^6.9.1: - version "6.23.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-class-properties/-/babel-plugin-transform-class-properties-6.23.0.tgz#187b747ee404399013563c993db038f34754ac3b" - dependencies: - babel-helper-function-name "^6.23.0" - babel-plugin-syntax-class-properties "^6.8.0" - babel-runtime "^6.22.0" - babel-template "^6.23.0" - -babel-plugin-transform-decorators@^6.22.0: - version "6.22.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-decorators/-/babel-plugin-transform-decorators-6.22.0.tgz#c03635b27a23b23b7224f49232c237a73988d27c" - dependencies: - babel-helper-explode-class "^6.22.0" - babel-plugin-syntax-decorators "^6.13.0" - babel-runtime "^6.22.0" - babel-template "^6.22.0" - babel-types "^6.22.0" - -babel-plugin-transform-do-expressions@^6.22.0: - version "6.22.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-do-expressions/-/babel-plugin-transform-do-expressions-6.22.0.tgz#28ccaf92812d949c2cd1281f690c8fdc468ae9bb" - dependencies: - babel-plugin-syntax-do-expressions "^6.8.0" - babel-runtime "^6.22.0" - babel-plugin-transform-es2015-arrow-functions@^6.22.0: version "6.22.0" resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-arrow-functions/-/babel-plugin-transform-es2015-arrow-functions-6.22.0.tgz#452692cb711d5f79dc7f85e440ce41b9f244d221" @@ -502,7 +350,7 @@ babel-plugin-transform-es2015-block-scoped-functions@^6.22.0: dependencies: babel-runtime "^6.22.0" -babel-plugin-transform-es2015-block-scoping@^6.22.0: +babel-plugin-transform-es2015-block-scoping@^6.23.0: version "6.23.0" resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-block-scoping/-/babel-plugin-transform-es2015-block-scoping-6.23.0.tgz#e48895cf0b375be148cd7c8879b422707a053b51" dependencies: @@ -512,7 +360,7 @@ babel-plugin-transform-es2015-block-scoping@^6.22.0: babel-types "^6.23.0" lodash "^4.2.0" -babel-plugin-transform-es2015-classes@^6.22.0, babel-plugin-transform-es2015-classes@^6.9.0: +babel-plugin-transform-es2015-classes@^6.23.0, babel-plugin-transform-es2015-classes@^6.9.0: version "6.23.0" resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-classes/-/babel-plugin-transform-es2015-classes-6.23.0.tgz#49b53f326202a2fd1b3bbaa5e2edd8a4f78643c1" dependencies: @@ -533,7 +381,7 @@ babel-plugin-transform-es2015-computed-properties@^6.22.0: babel-runtime "^6.22.0" babel-template "^6.22.0" -babel-plugin-transform-es2015-destructuring@^6.22.0: +babel-plugin-transform-es2015-destructuring@^6.23.0: version "6.23.0" resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-destructuring/-/babel-plugin-transform-es2015-destructuring-6.23.0.tgz#997bb1f1ab967f682d2b0876fe358d60e765c56d" dependencies: @@ -546,7 +394,7 @@ babel-plugin-transform-es2015-duplicate-keys@^6.22.0: babel-runtime "^6.22.0" babel-types "^6.22.0" -babel-plugin-transform-es2015-for-of@^6.22.0: +babel-plugin-transform-es2015-for-of@^6.23.0: version "6.23.0" resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-for-of/-/babel-plugin-transform-es2015-for-of-6.23.0.tgz#f47c95b2b613df1d3ecc2fdb7573623c75248691" dependencies: @@ -566,24 +414,24 @@ babel-plugin-transform-es2015-literals@^6.22.0: dependencies: babel-runtime "^6.22.0" -babel-plugin-transform-es2015-modules-amd@^6.22.0: - version "6.22.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-amd/-/babel-plugin-transform-es2015-modules-amd-6.22.0.tgz#bf69cd34889a41c33d90dfb740e0091ccff52f21" +babel-plugin-transform-es2015-modules-amd@^6.22.0, babel-plugin-transform-es2015-modules-amd@^6.24.0: + version "6.24.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-amd/-/babel-plugin-transform-es2015-modules-amd-6.24.0.tgz#a1911fb9b7ec7e05a43a63c5995007557bcf6a2e" dependencies: - babel-plugin-transform-es2015-modules-commonjs "^6.22.0" + babel-plugin-transform-es2015-modules-commonjs "^6.24.0" babel-runtime "^6.22.0" babel-template "^6.22.0" -babel-plugin-transform-es2015-modules-commonjs@^6.22.0: - version "6.23.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-commonjs/-/babel-plugin-transform-es2015-modules-commonjs-6.23.0.tgz#cba7aa6379fb7ec99250e6d46de2973aaffa7b92" +babel-plugin-transform-es2015-modules-commonjs@^6.23.0, babel-plugin-transform-es2015-modules-commonjs@^6.24.0: + version "6.24.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-commonjs/-/babel-plugin-transform-es2015-modules-commonjs-6.24.0.tgz#e921aefb72c2cc26cb03d107626156413222134f" dependencies: babel-plugin-transform-strict-mode "^6.22.0" babel-runtime "^6.22.0" babel-template "^6.23.0" babel-types "^6.23.0" -babel-plugin-transform-es2015-modules-systemjs@^6.22.0: +babel-plugin-transform-es2015-modules-systemjs@^6.23.0: version "6.23.0" resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-systemjs/-/babel-plugin-transform-es2015-modules-systemjs-6.23.0.tgz#ae3469227ffac39b0310d90fec73bfdc4f6317b0" dependencies: @@ -591,11 +439,11 @@ babel-plugin-transform-es2015-modules-systemjs@^6.22.0: babel-runtime "^6.22.0" babel-template "^6.23.0" -babel-plugin-transform-es2015-modules-umd@^6.22.0: - version "6.23.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-umd/-/babel-plugin-transform-es2015-modules-umd-6.23.0.tgz#8d284ae2e19ed8fe21d2b1b26d6e7e0fcd94f0f1" +babel-plugin-transform-es2015-modules-umd@^6.23.0: + version "6.24.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-umd/-/babel-plugin-transform-es2015-modules-umd-6.24.0.tgz#fd5fa63521cae8d273927c3958afd7c067733450" dependencies: - babel-plugin-transform-es2015-modules-amd "^6.22.0" + babel-plugin-transform-es2015-modules-amd "^6.24.0" babel-runtime "^6.22.0" babel-template "^6.23.0" @@ -606,7 +454,7 @@ babel-plugin-transform-es2015-object-super@^6.22.0: babel-helper-replace-supers "^6.22.0" babel-runtime "^6.22.0" -babel-plugin-transform-es2015-parameters@^6.22.0: +babel-plugin-transform-es2015-parameters@^6.23.0: version "6.23.0" resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-parameters/-/babel-plugin-transform-es2015-parameters-6.23.0.tgz#3a2aabb70c8af945d5ce386f1a4250625a83ae3b" dependencies: @@ -644,7 +492,7 @@ babel-plugin-transform-es2015-template-literals@^6.22.0: dependencies: babel-runtime "^6.22.0" -babel-plugin-transform-es2015-typeof-symbol@^6.22.0: +babel-plugin-transform-es2015-typeof-symbol@^6.23.0: version "6.23.0" resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-typeof-symbol/-/babel-plugin-transform-es2015-typeof-symbol-6.23.0.tgz#dec09f1cddff94b52ac73d505c84df59dcceb372" dependencies: @@ -666,27 +514,6 @@ babel-plugin-transform-exponentiation-operator@^6.22.0: babel-plugin-syntax-exponentiation-operator "^6.8.0" babel-runtime "^6.22.0" -babel-plugin-transform-export-extensions@^6.22.0: - version "6.22.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-export-extensions/-/babel-plugin-transform-export-extensions-6.22.0.tgz#53738b47e75e8218589eea946cbbd39109bbe653" - dependencies: - babel-plugin-syntax-export-extensions "^6.8.0" - babel-runtime "^6.22.0" - -babel-plugin-transform-flow-strip-types@^6.22.0: - version "6.22.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-flow-strip-types/-/babel-plugin-transform-flow-strip-types-6.22.0.tgz#84cb672935d43714fdc32bce84568d87441cf7cf" - dependencies: - babel-plugin-syntax-flow "^6.18.0" - babel-runtime "^6.22.0" - -babel-plugin-transform-function-bind@^6.22.0: - version "6.22.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-function-bind/-/babel-plugin-transform-function-bind-6.22.0.tgz#c6fb8e96ac296a310b8cf8ea401462407ddf6a97" - dependencies: - babel-plugin-syntax-function-bind "^6.8.0" - babel-runtime "^6.22.0" - babel-plugin-transform-inline-consecutive-adds@^0.0.2: version "0.0.2" resolved "https://registry.yarnpkg.com/babel-plugin-transform-inline-consecutive-adds/-/babel-plugin-transform-inline-consecutive-adds-0.0.2.tgz#a58fcecfc09c08fbf9373a5a3e70746c03d01fc1" @@ -705,45 +532,10 @@ babel-plugin-transform-minify-booleans@^6.8.0: dependencies: babel-runtime "^6.0.0" -babel-plugin-transform-object-rest-spread@^6.22.0: - version "6.23.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-object-rest-spread/-/babel-plugin-transform-object-rest-spread-6.23.0.tgz#875d6bc9be761c58a2ae3feee5dc4895d8c7f921" - dependencies: - babel-plugin-syntax-object-rest-spread "^6.8.0" - babel-runtime "^6.22.0" - babel-plugin-transform-property-literals@^6.8.1: version "6.8.1" resolved "https://registry.yarnpkg.com/babel-plugin-transform-property-literals/-/babel-plugin-transform-property-literals-6.8.1.tgz#05ed01f6024820b18f1d0495c80fe287176bccd9" -babel-plugin-transform-react-display-name@^6.23.0: - version "6.23.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-react-display-name/-/babel-plugin-transform-react-display-name-6.23.0.tgz#4398910c358441dc4cef18787264d0412ed36b37" - dependencies: - babel-runtime "^6.22.0" - -babel-plugin-transform-react-jsx-self@^6.22.0: - version "6.22.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-react-jsx-self/-/babel-plugin-transform-react-jsx-self-6.22.0.tgz#df6d80a9da2612a121e6ddd7558bcbecf06e636e" - dependencies: - babel-plugin-syntax-jsx "^6.8.0" - babel-runtime "^6.22.0" - -babel-plugin-transform-react-jsx-source@^6.22.0: - version "6.22.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-react-jsx-source/-/babel-plugin-transform-react-jsx-source-6.22.0.tgz#66ac12153f5cd2d17b3c19268f4bf0197f44ecd6" - dependencies: - babel-plugin-syntax-jsx "^6.8.0" - babel-runtime "^6.22.0" - -babel-plugin-transform-react-jsx@^6.23.0: - version "6.23.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-react-jsx/-/babel-plugin-transform-react-jsx-6.23.0.tgz#23e892f7f2e759678eb5e4446a8f8e94e81b3470" - dependencies: - babel-helper-builder-react-jsx "^6.23.0" - babel-plugin-syntax-jsx "^6.8.0" - babel-runtime "^6.22.0" - babel-plugin-transform-regenerator@^6.22.0: version "6.22.0" resolved "https://registry.yarnpkg.com/babel-plugin-transform-regenerator/-/babel-plugin-transform-regenerator-6.22.0.tgz#65740593a319c44522157538d690b84094617ea6" @@ -811,100 +603,45 @@ babel-preset-babili@^0.0.12: babel-plugin-transform-undefined-to-void "^6.8.0" lodash.isplainobject "^4.0.6" -babel-preset-es2015-rollup@^1.1.1: - version "1.2.0" - resolved "https://registry.yarnpkg.com/babel-preset-es2015-rollup/-/babel-preset-es2015-rollup-1.2.0.tgz#feedf80346e01fa22d4de15e72cde1cefc59bf67" - dependencies: - babel-plugin-external-helpers "^6.4.0" - babel-preset-es2015 "^6.3.13" - modify-babel-preset "^2.1.1" - -babel-preset-es2015@^6.3.13, babel-preset-es2015@^6.6.0: - version "6.22.0" - resolved "https://registry.yarnpkg.com/babel-preset-es2015/-/babel-preset-es2015-6.22.0.tgz#af5a98ecb35eb8af764ad8a5a05eb36dc4386835" +babel-preset-env@^1.3.2: + version "1.3.2" + resolved "https://registry.yarnpkg.com/babel-preset-env/-/babel-preset-env-1.3.2.tgz#08eabd2bf810c3678069f7e052323419f1448749" dependencies: babel-plugin-check-es2015-constants "^6.22.0" + babel-plugin-syntax-trailing-function-commas "^6.22.0" + babel-plugin-transform-async-to-generator "^6.22.0" babel-plugin-transform-es2015-arrow-functions "^6.22.0" babel-plugin-transform-es2015-block-scoped-functions "^6.22.0" - babel-plugin-transform-es2015-block-scoping "^6.22.0" - babel-plugin-transform-es2015-classes "^6.22.0" + babel-plugin-transform-es2015-block-scoping "^6.23.0" + babel-plugin-transform-es2015-classes "^6.23.0" babel-plugin-transform-es2015-computed-properties "^6.22.0" - babel-plugin-transform-es2015-destructuring "^6.22.0" + babel-plugin-transform-es2015-destructuring "^6.23.0" babel-plugin-transform-es2015-duplicate-keys "^6.22.0" - babel-plugin-transform-es2015-for-of "^6.22.0" + babel-plugin-transform-es2015-for-of "^6.23.0" babel-plugin-transform-es2015-function-name "^6.22.0" babel-plugin-transform-es2015-literals "^6.22.0" babel-plugin-transform-es2015-modules-amd "^6.22.0" - babel-plugin-transform-es2015-modules-commonjs "^6.22.0" - babel-plugin-transform-es2015-modules-systemjs "^6.22.0" - babel-plugin-transform-es2015-modules-umd "^6.22.0" + babel-plugin-transform-es2015-modules-commonjs "^6.23.0" + babel-plugin-transform-es2015-modules-systemjs "^6.23.0" + babel-plugin-transform-es2015-modules-umd "^6.23.0" babel-plugin-transform-es2015-object-super "^6.22.0" - babel-plugin-transform-es2015-parameters "^6.22.0" + babel-plugin-transform-es2015-parameters "^6.23.0" babel-plugin-transform-es2015-shorthand-properties "^6.22.0" babel-plugin-transform-es2015-spread "^6.22.0" babel-plugin-transform-es2015-sticky-regex "^6.22.0" babel-plugin-transform-es2015-template-literals "^6.22.0" - babel-plugin-transform-es2015-typeof-symbol "^6.22.0" + babel-plugin-transform-es2015-typeof-symbol "^6.23.0" babel-plugin-transform-es2015-unicode-regex "^6.22.0" - babel-plugin-transform-regenerator "^6.22.0" - -babel-preset-flow@^6.23.0: - version "6.23.0" - resolved "https://registry.yarnpkg.com/babel-preset-flow/-/babel-preset-flow-6.23.0.tgz#e71218887085ae9a24b5be4169affb599816c49d" - dependencies: - babel-plugin-transform-flow-strip-types "^6.22.0" - -babel-preset-react@^6.5.0: - version "6.23.0" - resolved "https://registry.yarnpkg.com/babel-preset-react/-/babel-preset-react-6.23.0.tgz#eb7cee4de98a3f94502c28565332da9819455195" - dependencies: - babel-plugin-syntax-jsx "^6.3.13" - babel-plugin-transform-react-display-name "^6.23.0" - babel-plugin-transform-react-jsx "^6.23.0" - babel-plugin-transform-react-jsx-self "^6.22.0" - babel-plugin-transform-react-jsx-source "^6.22.0" - babel-preset-flow "^6.23.0" - -babel-preset-stage-0@^6.5.0: - version "6.22.0" - resolved "https://registry.yarnpkg.com/babel-preset-stage-0/-/babel-preset-stage-0-6.22.0.tgz#707eeb5b415da769eff9c42f4547f644f9296ef9" - dependencies: - babel-plugin-transform-do-expressions "^6.22.0" - babel-plugin-transform-function-bind "^6.22.0" - babel-preset-stage-1 "^6.22.0" - -babel-preset-stage-1@^6.22.0: - version "6.22.0" - resolved "https://registry.yarnpkg.com/babel-preset-stage-1/-/babel-preset-stage-1-6.22.0.tgz#7da05bffea6ad5a10aef93e320cfc6dd465dbc1a" - dependencies: - babel-plugin-transform-class-constructor-call "^6.22.0" - babel-plugin-transform-export-extensions "^6.22.0" - babel-preset-stage-2 "^6.22.0" - -babel-preset-stage-2@^6.22.0: - version "6.22.0" - resolved "https://registry.yarnpkg.com/babel-preset-stage-2/-/babel-preset-stage-2-6.22.0.tgz#ccd565f19c245cade394b21216df704a73b27c07" - dependencies: - babel-plugin-syntax-dynamic-import "^6.18.0" - babel-plugin-transform-class-properties "^6.22.0" - babel-plugin-transform-decorators "^6.22.0" - babel-preset-stage-3 "^6.22.0" - -babel-preset-stage-3@^6.22.0: - version "6.22.0" - resolved "https://registry.yarnpkg.com/babel-preset-stage-3/-/babel-preset-stage-3-6.22.0.tgz#a4e92bbace7456fafdf651d7a7657ee0bbca9c2e" - dependencies: - babel-plugin-syntax-trailing-function-commas "^6.22.0" - babel-plugin-transform-async-generator-functions "^6.22.0" - babel-plugin-transform-async-to-generator "^6.22.0" babel-plugin-transform-exponentiation-operator "^6.22.0" - babel-plugin-transform-object-rest-spread "^6.22.0" + babel-plugin-transform-regenerator "^6.22.0" + browserslist "^1.4.0" + invariant "^2.2.2" -babel-register@^6.23.0: - version "6.23.0" - resolved "https://registry.yarnpkg.com/babel-register/-/babel-register-6.23.0.tgz#c9aa3d4cca94b51da34826c4a0f9e08145d74ff3" +babel-register@^6.24.0: + version "6.24.0" + resolved "https://registry.yarnpkg.com/babel-register/-/babel-register-6.24.0.tgz#5e89f8463ba9970356d02eb07dabe3308b080cfd" dependencies: - babel-core "^6.23.0" + babel-core "^6.24.0" babel-runtime "^6.22.0" core-js "^2.4.0" home-or-tmp "^2.0.0" @@ -952,10 +689,6 @@ babel-types@^6.19.0, babel-types@^6.22.0, babel-types@^6.23.0: lodash "^4.2.0" to-fast-properties "^1.0.1" -babel@^6.5.2: - version "6.23.0" - resolved "https://registry.yarnpkg.com/babel/-/babel-6.23.0.tgz#d0d1e7d803e974765beea3232d4e153c0efb90f4" - babylon@^6.11.0, babylon@^6.15.0: version "6.16.1" resolved "https://registry.yarnpkg.com/babylon/-/babylon-6.16.1.tgz#30c5a22f481978a9e7f8cdfdf496b11d94b404d3" @@ -964,10 +697,6 @@ balanced-match@^0.4.1: version "0.4.2" resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-0.4.2.tgz#cb3f3e3c732dc0f01ee70b403f302e61d7709838" -beeper@^1.0.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/beeper/-/beeper-1.1.1.tgz#e6d5ea8c5dad001304a70b22638447f69cb2f809" - brace-expansion@^1.0.0: version "1.1.6" resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.6.tgz#7197d7eaa9b87e648390ea61fc66c84427420df9" @@ -975,20 +704,23 @@ brace-expansion@^1.0.0: balanced-match "^0.4.1" concat-map "0.0.1" -braces@^1.8.2: - version "1.8.5" - resolved "https://registry.yarnpkg.com/braces/-/braces-1.8.5.tgz#ba77962e12dff969d6b76711e914b737857bf6a7" - dependencies: - expand-range "^1.8.1" - preserve "^0.2.0" - repeat-element "^1.1.2" - browser-resolve@^1.11.0: version "1.11.2" resolved "https://registry.yarnpkg.com/browser-resolve/-/browser-resolve-1.11.2.tgz#8ff09b0a2c421718a1051c260b32e48f442938ce" dependencies: resolve "1.1.7" +browser-stdout@1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/browser-stdout/-/browser-stdout-1.3.0.tgz#f351d32969d32fa5d7a5567154263d928ae3bd1f" + +browserslist@^1.4.0: + version "1.7.7" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-1.7.7.tgz#0bd76704258be829b2398bb50e4b62d1a166b0b9" + dependencies: + caniuse-db "^1.0.30000639" + electron-to-chromium "^1.2.7" + buffer-shims@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/buffer-shims/-/buffer-shims-1.0.0.tgz#9978ce317388c649ad8793028c3477ef044a8b51" @@ -1007,6 +739,10 @@ callsites@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/callsites/-/callsites-0.2.0.tgz#afab96262910a7f33c19a5775825c69f34e350ca" +caniuse-db@^1.0.30000639: + version "1.0.30000646" + resolved "https://registry.yarnpkg.com/caniuse-db/-/caniuse-db-1.0.30000646.tgz#c724b90d61df24286e015fc528d062073c00def4" + chai@^3.5.0: version "3.5.0" resolved "https://registry.yarnpkg.com/chai/-/chai-3.5.0.tgz#4d02637b067fe958bdbfdd3a40ec56fef7373247" @@ -1039,18 +775,6 @@ cli-width@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-2.1.0.tgz#b234ca209b29ef66fc518d9b98d5847b00edf00a" -clone-stats@^0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/clone-stats/-/clone-stats-0.0.1.tgz#b88f94a82cf38b8791d58046ea4029ad88ca99d1" - -clone@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/clone/-/clone-0.2.0.tgz#c6126a90ad4f72dbf5acdb243cc37724fe93fc1f" - -clone@^1.0.0, clone@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/clone/-/clone-1.0.2.tgz#260b7a99ebb1edfe247538175f783243cb19d149" - co@^4.6.0: version "4.6.0" resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184" @@ -1059,19 +783,17 @@ code-point-at@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" -commander@0.6.1: - version "0.6.1" - resolved "https://registry.yarnpkg.com/commander/-/commander-0.6.1.tgz#fa68a14f6a945d54dbbe50d8cdb3320e9e3b1a06" - -commander@2.3.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/commander/-/commander-2.3.0.tgz#fd430e889832ec353b9acd1de217c11cb3eef873" +commander@2.9.0: + version "2.9.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.9.0.tgz#9c99094176e12240cb22d6c5146098400fe0f7d4" + dependencies: + graceful-readlink ">= 1.0.0" concat-map@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" -concat-stream@^1.4.6: +concat-stream@^1.5.2: version "1.6.0" resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.0.tgz#0aac662fd52be78964d5532f694784e70110acf7" dependencies: @@ -1083,9 +805,9 @@ contains-path@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/contains-path/-/contains-path-0.1.0.tgz#fe8cf184ff6670b6baef01a9d4861a5cbec4120a" -convert-source-map@1.X, convert-source-map@^1.1.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.4.0.tgz#e3dad195bf61bfe13a7a3c73e9876ec14a0268f3" +convert-source-map@^1.1.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.5.0.tgz#9acd70851c6d5dfdd93d9282e5edf94a03ff46b5" core-js@^2.4.0: version "2.4.1" @@ -1095,32 +817,11 @@ core-util-is@~1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" -css@2.X: - version "2.2.1" - resolved "https://registry.yarnpkg.com/css/-/css-2.2.1.tgz#73a4c81de85db664d4ee674f7d47085e3b2d55dc" - dependencies: - inherits "^2.0.1" - source-map "^0.1.38" - source-map-resolve "^0.3.0" - urix "^0.1.0" - -d@^0.1.1, d@~0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/d/-/d-0.1.1.tgz#da184c535d18d8ee7ba2aa229b914009fae11309" - dependencies: - es5-ext "~0.10.2" - -dateformat@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/dateformat/-/dateformat-2.0.0.tgz#2743e3abb5c3fc2462e527dca445e04e9f4dee17" - -debug-fabulous@0.0.X: - version "0.0.4" - resolved "https://registry.yarnpkg.com/debug-fabulous/-/debug-fabulous-0.0.4.tgz#fa071c5d87484685424807421ca4b16b0b1a0763" +d@1: + version "1.0.0" + resolved "https://registry.yarnpkg.com/d/-/d-1.0.0.tgz#754bb5bfe55451da69a58b94d45f4c5b0462d58f" dependencies: - debug "2.X" - lazy-debug-legacy "0.0.X" - object-assign "4.1.0" + es5-ext "^0.10.9" debug@2.2.0: version "2.2.0" @@ -1128,9 +829,9 @@ debug@2.2.0: dependencies: ms "0.7.1" -debug@2.X, debug@^2.1.1, debug@^2.2.0: - version "2.6.1" - resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.1.tgz#79855090ba2c4e3115cc7d8769491d58f0491351" +debug@^2.1.1, debug@^2.2.0: + version "2.6.3" + resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.3.tgz#0f7eb8c30965ec08c72accfa0130c8b79984141d" dependencies: ms "0.7.2" @@ -1144,12 +845,6 @@ deep-is@~0.1.3: version "0.1.3" resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34" -defaults@^1.0.0: - version "1.0.3" - resolved "https://registry.yarnpkg.com/defaults/-/defaults-1.0.3.tgz#c656051e9817d9ff08ed881477f3fe4019f3ef7d" - dependencies: - clone "^1.0.2" - del@^2.0.2: version "2.2.2" resolved "https://registry.yarnpkg.com/del/-/del-2.2.2.tgz#c12c981d067846c84bcaf862cff930d907ffd1a8" @@ -1162,110 +857,91 @@ del@^2.0.2: pinkie-promise "^2.0.0" rimraf "^2.2.8" -deprecated@^0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/deprecated/-/deprecated-0.0.1.tgz#f9c9af5464afa1e7a971458a8bdef2aa94d5bb19" - -detect-file@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/detect-file/-/detect-file-0.1.0.tgz#4935dedfd9488648e006b0129566e9386711ea63" - dependencies: - fs-exists-sync "^0.1.0" - detect-indent@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-4.0.0.tgz#f76d064352cdf43a1cb6ce619c4ee3a9475de208" dependencies: repeating "^2.0.0" -detect-newline@2.X: - version "2.1.0" - resolved "https://registry.yarnpkg.com/detect-newline/-/detect-newline-2.1.0.tgz#f41f1c10be4b00e87b5f13da680759f2c5bfd3e2" - diff@1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/diff/-/diff-1.4.0.tgz#7f28d2eb9ee7b15a97efd89ce63dcfdaa3ccbabf" -doctrine@1.5.0, doctrine@^1.2.2: +doctrine@1.5.0: version "1.5.0" resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-1.5.0.tgz#379dce730f6166f76cefa4e6707a159b02c5a6fa" dependencies: esutils "^2.0.2" isarray "^1.0.0" -duplexer2@0.0.2: - version "0.0.2" - resolved "https://registry.yarnpkg.com/duplexer2/-/duplexer2-0.0.2.tgz#c614dcf67e2fb14995a91711e5a617e8a60a31db" +doctrine@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-2.0.0.tgz#c73d8d2909d22291e1a007a395804da8b665fe63" dependencies: - readable-stream "~1.1.9" + esutils "^2.0.2" + isarray "^1.0.0" -end-of-stream@~0.1.5: - version "0.1.5" - resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-0.1.5.tgz#8e177206c3c80837d85632e8b9359dfe8b2f6eaf" - dependencies: - once "~1.3.0" +electron-to-chromium@^1.2.7: + version "1.3.2" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.2.tgz#b8ce5c93b308db0e92f6d0435c46ddec8f6363ab" erlang-types@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/erlang-types/-/erlang-types-1.0.0.tgz#e555bd091667498a01d340d18203231dc96d962f" -es5-ext@^0.10.7, es5-ext@^0.10.8, es5-ext@~0.10.11, es5-ext@~0.10.2, es5-ext@~0.10.7: - version "0.10.12" - resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.12.tgz#aa84641d4db76b62abba5e45fd805ecbab140047" +es5-ext@^0.10.14, es5-ext@^0.10.9, es5-ext@~0.10.14: + version "0.10.15" + resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.15.tgz#c330a5934c1ee21284a7c081a86e5fd937c91ea6" dependencies: es6-iterator "2" es6-symbol "~3.1" -es6-iterator@2: - version "2.0.0" - resolved "https://registry.yarnpkg.com/es6-iterator/-/es6-iterator-2.0.0.tgz#bd968567d61635e33c0b80727613c9cb4b096bac" +es6-iterator@2, es6-iterator@^2.0.1, es6-iterator@~2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/es6-iterator/-/es6-iterator-2.0.1.tgz#8e319c9f0453bf575d374940a655920e59ca5512" dependencies: - d "^0.1.1" - es5-ext "^0.10.7" - es6-symbol "3" + d "1" + es5-ext "^0.10.14" + es6-symbol "^3.1" es6-map@^0.1.3: - version "0.1.4" - resolved "https://registry.yarnpkg.com/es6-map/-/es6-map-0.1.4.tgz#a34b147be224773a4d7da8072794cefa3632b897" + version "0.1.5" + resolved "https://registry.yarnpkg.com/es6-map/-/es6-map-0.1.5.tgz#9136e0503dcc06a301690f0bb14ff4e364e949f0" dependencies: - d "~0.1.1" - es5-ext "~0.10.11" - es6-iterator "2" - es6-set "~0.1.3" - es6-symbol "~3.1.0" - event-emitter "~0.3.4" + d "1" + es5-ext "~0.10.14" + es6-iterator "~2.0.1" + es6-set "~0.1.5" + es6-symbol "~3.1.1" + event-emitter "~0.3.5" -es6-set@~0.1.3: - version "0.1.4" - resolved "https://registry.yarnpkg.com/es6-set/-/es6-set-0.1.4.tgz#9516b6761c2964b92ff479456233a247dc707ce8" +es6-set@~0.1.5: + version "0.1.5" + resolved "https://registry.yarnpkg.com/es6-set/-/es6-set-0.1.5.tgz#d2b3ec5d4d800ced818db538d28974db0a73ccb1" dependencies: - d "~0.1.1" - es5-ext "~0.10.11" - es6-iterator "2" - es6-symbol "3" - event-emitter "~0.3.4" + d "1" + es5-ext "~0.10.14" + es6-iterator "~2.0.1" + es6-symbol "3.1.1" + event-emitter "~0.3.5" -es6-symbol@3, es6-symbol@~3.1, es6-symbol@~3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/es6-symbol/-/es6-symbol-3.1.0.tgz#94481c655e7a7cad82eba832d97d5433496d7ffa" +es6-symbol@3.1.1, es6-symbol@^3.1, es6-symbol@^3.1.1, es6-symbol@~3.1, es6-symbol@~3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/es6-symbol/-/es6-symbol-3.1.1.tgz#bf00ef4fdab6ba1b46ecb7b629b4c7ed5715cc77" dependencies: - d "~0.1.1" - es5-ext "~0.10.11" + d "1" + es5-ext "~0.10.14" es6-weak-map@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/es6-weak-map/-/es6-weak-map-2.0.1.tgz#0d2bbd8827eb5fb4ba8f97fbfea50d43db21ea81" + version "2.0.2" + resolved "https://registry.yarnpkg.com/es6-weak-map/-/es6-weak-map-2.0.2.tgz#5e3ab32251ffd1538a1f8e5ffa1357772f92d96f" dependencies: - d "^0.1.1" - es5-ext "^0.10.8" - es6-iterator "2" - es6-symbol "3" - -escape-string-regexp@1.0.2, escape-string-regexp@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.2.tgz#4dbc2fe674e71949caf3fb2695ce7f2dc1d9a8d1" + d "1" + es5-ext "^0.10.14" + es6-iterator "^2.0.1" + es6-symbol "^3.1.1" -escape-string-regexp@^1.0.5: +escape-string-regexp@1.0.5, escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" @@ -1279,8 +955,8 @@ escope@^3.6.0: estraverse "^4.1.1" eslint-config-airbnb-base@^11.1.0: - version "11.1.0" - resolved "https://registry.yarnpkg.com/eslint-config-airbnb-base/-/eslint-config-airbnb-base-11.1.0.tgz#dc9b3ec70b8c74dcbe6d6257c9da3992c39ca2ca" + version "11.1.2" + resolved "https://registry.yarnpkg.com/eslint-config-airbnb-base/-/eslint-config-airbnb-base-11.1.2.tgz#259209a7678bf693e31cbe8f953f206b6aa7ccc3" eslint-import-resolver-node@^0.2.0: version "0.2.3" @@ -1313,16 +989,17 @@ eslint-plugin-import@^2.2.0: pkg-up "^1.0.0" eslint@^3.15.0: - version "3.16.1" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-3.16.1.tgz#9bc31fc7341692cf772e80607508f67d711c5609" + version "3.19.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-3.19.0.tgz#c8fc6201c7f40dd08941b87c085767386a679acc" dependencies: babel-code-frame "^6.16.0" chalk "^1.1.3" - concat-stream "^1.4.6" + concat-stream "^1.5.2" debug "^2.1.1" - doctrine "^1.2.2" + doctrine "^2.0.0" escope "^3.6.0" espree "^3.4.0" + esquery "^1.0.0" estraverse "^4.2.0" esutils "^2.0.2" file-entry-cache "^2.0.0" @@ -1352,16 +1029,22 @@ eslint@^3.15.0: user-home "^2.0.0" espree@^3.4.0: - version "3.4.0" - resolved "https://registry.yarnpkg.com/espree/-/espree-3.4.0.tgz#41656fa5628e042878025ef467e78f125cb86e1d" + version "3.4.1" + resolved "https://registry.yarnpkg.com/espree/-/espree-3.4.1.tgz#28a83ab4aaed71ed8fe0f5efe61b76a05c13c4d2" dependencies: - acorn "4.0.4" + acorn "^5.0.1" acorn-jsx "^3.0.0" esprima@^3.1.1: version "3.1.3" resolved "https://registry.yarnpkg.com/esprima/-/esprima-3.1.3.tgz#fdca51cee6133895e3c88d535ce49dbff62a4633" +esquery@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.0.0.tgz#cfba8b57d7fba93f17298a8a006a04cda13d80fa" + dependencies: + estraverse "^4.0.0" + esrecurse@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.1.0.tgz#4713b6536adf7f2ac4f327d559e7756bff648220" @@ -1369,7 +1052,7 @@ esrecurse@^4.1.0: estraverse "~4.1.0" object-assign "^4.0.1" -estraverse@^4.1.1, estraverse@^4.2.0: +estraverse@^4.0.0, estraverse@^4.1.1, estraverse@^4.2.0: version "4.2.0" resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.2.0.tgz#0dee3fed31fcd469618ce7342099fc1afa0bdb13" @@ -1381,56 +1064,21 @@ estree-walker@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-0.2.1.tgz#bdafe8095383d8414d5dc2ecf4c9173b6db9412e" -esutils@^2.0.0, esutils@^2.0.2: +esutils@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.2.tgz#0abf4f1caa5bcb1f7a9d8acc6dea4faaa04bac9b" -event-emitter@~0.3.4: - version "0.3.4" - resolved "https://registry.yarnpkg.com/event-emitter/-/event-emitter-0.3.4.tgz#8d63ddfb4cfe1fae3b32ca265c4c720222080bb5" +event-emitter@~0.3.5: + version "0.3.5" + resolved "https://registry.yarnpkg.com/event-emitter/-/event-emitter-0.3.5.tgz#df8c69eef1647923c7157b9ce83840610b02cc39" dependencies: - d "~0.1.1" - es5-ext "~0.10.7" + d "1" + es5-ext "~0.10.14" exit-hook@^1.0.0: version "1.1.1" resolved "https://registry.yarnpkg.com/exit-hook/-/exit-hook-1.1.1.tgz#f05ca233b48c05d54fff07765df8507e95c02ff8" -expand-brackets@^0.1.4: - version "0.1.5" - resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-0.1.5.tgz#df07284e342a807cd733ac5af72411e581d1177b" - dependencies: - is-posix-bracket "^0.1.0" - -expand-range@^1.8.1: - version "1.8.2" - resolved "https://registry.yarnpkg.com/expand-range/-/expand-range-1.8.2.tgz#a299effd335fe2721ebae8e257ec79644fc85337" - dependencies: - fill-range "^2.1.0" - -expand-tilde@^1.2.1, expand-tilde@^1.2.2: - version "1.2.2" - resolved "https://registry.yarnpkg.com/expand-tilde/-/expand-tilde-1.2.2.tgz#0b81eba897e5a3d31d1c3d102f8f01441e559449" - dependencies: - os-homedir "^1.0.1" - -extend@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.0.tgz#5a474353b9f3353ddd8176dfd37b91c83a46f1d4" - -extglob@^0.3.1: - version "0.3.2" - resolved "https://registry.yarnpkg.com/extglob/-/extglob-0.3.2.tgz#2e18ff3d2f49ab2765cec9023f011daa8d8349a1" - dependencies: - is-extglob "^1.0.0" - -fancy-log@^1.1.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/fancy-log/-/fancy-log-1.3.0.tgz#45be17d02bb9917d60ccffd4995c999e6c8c9948" - dependencies: - chalk "^1.1.1" - time-stamp "^1.0.0" - fast-levenshtein@~2.0.4: version "2.0.6" resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" @@ -1449,24 +1097,6 @@ file-entry-cache@^2.0.0: flat-cache "^1.2.1" object-assign "^4.0.1" -filename-regex@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/filename-regex/-/filename-regex-2.0.0.tgz#996e3e80479b98b9897f15a8a58b3d084e926775" - -fill-range@^2.1.0: - version "2.2.3" - resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-2.2.3.tgz#50b77dfd7e469bc7492470963699fe7a8485a723" - dependencies: - is-number "^2.1.0" - isobject "^2.0.0" - randomatic "^1.1.3" - repeat-element "^1.1.2" - repeat-string "^1.5.2" - -find-index@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/find-index/-/find-index-0.1.1.tgz#675d358b2ca3892d795a1ab47232f8b6e2e0dde4" - find-up@^1.0.0: version "1.1.2" resolved "https://registry.yarnpkg.com/find-up/-/find-up-1.1.2.tgz#6b2e9822b1a2ce0a60ab64d610eccad53cb24d0f" @@ -1474,35 +1104,6 @@ find-up@^1.0.0: path-exists "^2.0.0" pinkie-promise "^2.0.0" -findup-sync@^0.4.2: - version "0.4.3" - resolved "https://registry.yarnpkg.com/findup-sync/-/findup-sync-0.4.3.tgz#40043929e7bc60adf0b7f4827c4c6e75a0deca12" - dependencies: - detect-file "^0.1.0" - is-glob "^2.0.1" - micromatch "^2.3.7" - resolve-dir "^0.1.0" - -fined@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/fined/-/fined-1.0.2.tgz#5b28424b760d7598960b7ef8480dff8ad3660e97" - dependencies: - expand-tilde "^1.2.1" - lodash.assignwith "^4.0.7" - lodash.isempty "^4.2.1" - lodash.isplainobject "^4.0.4" - lodash.isstring "^4.0.1" - lodash.pick "^4.2.1" - parse-filepath "^1.0.1" - -first-chunk-stream@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/first-chunk-stream/-/first-chunk-stream-1.0.0.tgz#59bfb50cd905f60d7c394cd3d9acaab4e6ad934e" - -flagged-respawn@^0.3.2: - version "0.3.2" - resolved "https://registry.yarnpkg.com/flagged-respawn/-/flagged-respawn-0.3.2.tgz#ff191eddcd7088a675b2610fffc976be9b8074b5" - flat-cache@^1.2.1: version "1.2.2" resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-1.2.2.tgz#fa86714e72c21db88601761ecf2f555d1abc6b96" @@ -1512,26 +1113,12 @@ flat-cache@^1.2.1: graceful-fs "^4.1.2" write "^0.2.1" -for-in@^0.1.5: - version "0.1.6" - resolved "https://registry.yarnpkg.com/for-in/-/for-in-0.1.6.tgz#c9f96e89bfad18a545af5ec3ed352a1d9e5b4dc8" - -for-own@^0.1.4: - version "0.1.4" - resolved "https://registry.yarnpkg.com/for-own/-/for-own-0.1.4.tgz#0149b41a39088c7515f51ebe1c1386d45f935072" - dependencies: - for-in "^0.1.5" - formatio@1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/formatio/-/formatio-1.1.1.tgz#5ed3ccd636551097383465d996199100e86161e9" dependencies: samsam "~1.1" -fs-exists-sync@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/fs-exists-sync/-/fs-exists-sync-0.1.0.tgz#982d6893af918e72d08dec9e8673ff2b5a8d6add" - fs.realpath@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" @@ -1540,12 +1127,6 @@ function-bind@^1.0.2: version "1.1.0" resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.0.tgz#16176714c801798e4e8f2cf7f7529467bb4a5771" -gaze@^0.5.1: - version "0.5.2" - resolved "https://registry.yarnpkg.com/gaze/-/gaze-0.5.2.tgz#40b709537d24d1d45767db5a908689dfe69ac44f" - dependencies: - globule "~0.1.0" - generate-function@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/generate-function/-/generate-function-2.0.0.tgz#6858fe7c0969b7d4e9093337647ac79f60dfbe74" @@ -1556,57 +1137,16 @@ generate-object-property@^1.1.0: dependencies: is-property "^1.0.0" -glob-base@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/glob-base/-/glob-base-0.3.0.tgz#dbb164f6221b1c0b1ccf82aea328b497df0ea3c4" - dependencies: - glob-parent "^2.0.0" - is-glob "^2.0.0" - -glob-parent@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-2.0.0.tgz#81383d72db054fcccf5336daa902f182f6edbb28" - dependencies: - is-glob "^2.0.0" - -glob-stream@^3.1.5: - version "3.1.18" - resolved "https://registry.yarnpkg.com/glob-stream/-/glob-stream-3.1.18.tgz#9170a5f12b790306fdfe598f313f8f7954fd143b" - dependencies: - glob "^4.3.1" - glob2base "^0.0.12" - minimatch "^2.0.1" - ordered-read-streams "^0.1.0" - through2 "^0.6.1" - unique-stream "^1.0.0" - -glob-watcher@^0.0.6: - version "0.0.6" - resolved "https://registry.yarnpkg.com/glob-watcher/-/glob-watcher-0.0.6.tgz#b95b4a8df74b39c83298b0c05c978b4d9a3b710b" - dependencies: - gaze "^0.5.1" - -glob2base@^0.0.12: - version "0.0.12" - resolved "https://registry.yarnpkg.com/glob2base/-/glob2base-0.0.12.tgz#9d419b3e28f12e83a362164a277055922c9c0d56" - dependencies: - find-index "^0.1.1" - -glob@3.2.11: - version "3.2.11" - resolved "https://registry.yarnpkg.com/glob/-/glob-3.2.11.tgz#4a973f635b9190f715d10987d5c00fd2815ebe3d" - dependencies: - inherits "2" - minimatch "0.3" - -glob@^4.3.1: - version "4.5.3" - resolved "https://registry.yarnpkg.com/glob/-/glob-4.5.3.tgz#c6cb73d3226c1efef04de3c56d012f03377ee15f" +glob@7.0.5: + version "7.0.5" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.0.5.tgz#b4202a69099bbb4d292a7c1b95b6682b67ebdc95" dependencies: + fs.realpath "^1.0.0" inflight "^1.0.4" inherits "2" - minimatch "^2.0.1" + minimatch "^3.0.2" once "^1.3.0" + path-is-absolute "^1.0.0" glob@^7.0.0, glob@^7.0.3, glob@^7.0.5: version "7.1.1" @@ -1619,33 +1159,9 @@ glob@^7.0.0, glob@^7.0.3, glob@^7.0.5: once "^1.3.0" path-is-absolute "^1.0.0" -glob@~3.1.21: - version "3.1.21" - resolved "https://registry.yarnpkg.com/glob/-/glob-3.1.21.tgz#d29e0a055dea5138f4d07ed40e8982e83c2066cd" - dependencies: - graceful-fs "~1.2.0" - inherits "1" - minimatch "~0.2.11" - -global-modules@^0.2.3: - version "0.2.3" - resolved "https://registry.yarnpkg.com/global-modules/-/global-modules-0.2.3.tgz#ea5a3bed42c6d6ce995a4f8a1269b5dae223828d" - dependencies: - global-prefix "^0.1.4" - is-windows "^0.2.0" - -global-prefix@^0.1.4: - version "0.1.5" - resolved "https://registry.yarnpkg.com/global-prefix/-/global-prefix-0.1.5.tgz#8d3bc6b8da3ca8112a160d8d496ff0462bfef78f" - dependencies: - homedir-polyfill "^1.0.0" - ini "^1.3.4" - is-windows "^0.2.0" - which "^1.2.12" - globals@^9.0.0, globals@^9.14.0: - version "9.16.0" - resolved "https://registry.yarnpkg.com/globals/-/globals-9.16.0.tgz#63e903658171ec2d9f51b1d31de5e2b8dc01fb80" + version "9.17.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-9.17.0.tgz#0c0ca696d9b9bb694d2e5470bd37777caad50286" globby@^5.0.0: version "5.0.0" @@ -1658,122 +1174,27 @@ globby@^5.0.0: pify "^2.0.0" pinkie-promise "^2.0.0" -globule@~0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/globule/-/globule-0.1.0.tgz#d9c8edde1da79d125a151b79533b978676346ae5" - dependencies: - glob "~3.1.21" - lodash "~1.0.1" - minimatch "~0.2.11" - -glogg@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/glogg/-/glogg-1.0.0.tgz#7fe0f199f57ac906cf512feead8f90ee4a284fc5" - dependencies: - sparkles "^1.0.0" - -graceful-fs@4.X, graceful-fs@^4.1.2: +graceful-fs@^4.1.2: version "4.1.11" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.11.tgz#0e8bdfe4d1ddb8854d64e04ea7c00e2a026e5658" -graceful-fs@^3.0.0: - version "3.0.11" - resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-3.0.11.tgz#7613c778a1afea62f25c630a086d7f3acbbdd818" - dependencies: - natives "^1.1.0" - -graceful-fs@~1.2.0: - version "1.2.3" - resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-1.2.3.tgz#15a4806a57547cb2d2dbf27f42e89a8c3451b364" +"graceful-readlink@>= 1.0.0": + version "1.0.1" + resolved "https://registry.yarnpkg.com/graceful-readlink/-/graceful-readlink-1.0.1.tgz#4cafad76bc62f02fa039b2f94e9a3dd3a391a725" growl@1.9.2: version "1.9.2" resolved "https://registry.yarnpkg.com/growl/-/growl-1.9.2.tgz#0ea7743715db8d8de2c5ede1775e1b45ac85c02f" -gulp-babel@^6.1.2: - version "6.1.2" - resolved "https://registry.yarnpkg.com/gulp-babel/-/gulp-babel-6.1.2.tgz#7c0176e4ba3f244c60588a0c4b320a45d1adefce" - dependencies: - babel-core "^6.0.2" - gulp-util "^3.0.0" - object-assign "^4.0.1" - replace-ext "0.0.1" - through2 "^2.0.0" - vinyl-sourcemaps-apply "^0.2.0" - -gulp-sourcemaps@^2.0.0-alpha: - version "2.4.1" - resolved "https://registry.yarnpkg.com/gulp-sourcemaps/-/gulp-sourcemaps-2.4.1.tgz#8f65dc5c0d07b2fd5c88bc60ec7f13e56716bf74" - dependencies: - acorn "4.X" - convert-source-map "1.X" - css "2.X" - debug-fabulous "0.0.X" - detect-newline "2.X" - graceful-fs "4.X" - source-map "0.X" - strip-bom "3.X" - through2 "2.X" - vinyl "1.X" - -gulp-util@^3.0.0: - version "3.0.8" - resolved "https://registry.yarnpkg.com/gulp-util/-/gulp-util-3.0.8.tgz#0054e1e744502e27c04c187c3ecc505dd54bbb4f" - dependencies: - array-differ "^1.0.0" - array-uniq "^1.0.2" - beeper "^1.0.0" - chalk "^1.0.0" - dateformat "^2.0.0" - fancy-log "^1.1.0" - gulplog "^1.0.0" - has-gulplog "^0.1.0" - lodash._reescape "^3.0.0" - lodash._reevaluate "^3.0.0" - lodash._reinterpolate "^3.0.0" - lodash.template "^3.0.0" - minimist "^1.1.0" - multipipe "^0.1.2" - object-assign "^3.0.0" - replace-ext "0.0.1" - through2 "^2.0.0" - vinyl "^0.5.0" - -gulp@^3.9.1: - version "3.9.1" - resolved "https://registry.yarnpkg.com/gulp/-/gulp-3.9.1.tgz#571ce45928dd40af6514fc4011866016c13845b4" - dependencies: - archy "^1.0.0" - chalk "^1.0.0" - deprecated "^0.0.1" - gulp-util "^3.0.0" - interpret "^1.0.0" - liftoff "^2.1.0" - minimist "^1.1.0" - orchestrator "^0.3.0" - pretty-hrtime "^1.0.0" - semver "^4.1.0" - tildify "^1.0.0" - v8flags "^2.0.2" - vinyl-fs "^0.3.0" - -gulplog@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/gulplog/-/gulplog-1.0.0.tgz#e28c4d45d05ecbbed818363ce8f9c5926229ffe5" - dependencies: - glogg "^1.0.0" - has-ansi@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91" dependencies: ansi-regex "^2.0.0" -has-gulplog@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/has-gulplog/-/has-gulplog-0.1.0.tgz#6414c82913697da51590397dafb12f22967811ce" - dependencies: - sparkles "^1.0.0" +has-flag@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-1.0.0.tgz#9d9e793165ce017a00f00418c43f942a7b1d11fa" has@^1.0.1: version "1.0.1" @@ -1788,15 +1209,9 @@ home-or-tmp@^2.0.0: os-homedir "^1.0.0" os-tmpdir "^1.0.1" -homedir-polyfill@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/homedir-polyfill/-/homedir-polyfill-1.0.1.tgz#4c2bbc8a758998feebf5ed68580f76d46768b4bc" - dependencies: - parse-passwd "^1.0.0" - ignore@^3.2.0: - version "3.2.4" - resolved "https://registry.yarnpkg.com/ignore/-/ignore-3.2.4.tgz#4055e03596729a8fabe45a43c100ad5ed815c4e8" + version "3.2.6" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-3.2.6.tgz#26e8da0644be0bb4cb39516f6c79f0e0f4ffe48c" imurmurhash@^0.1.4: version "0.1.4" @@ -1809,11 +1224,7 @@ inflight@^1.0.4: once "^1.3.0" wrappy "1" -inherits@1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/inherits/-/inherits-1.0.2.tgz#ca4309dadee6b54cc0b8d247e8d7c7a0975bdc9b" - -inherits@2, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.1: +inherits@2, inherits@^2.0.3, inherits@~2.0.1: version "2.0.3" resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" @@ -1821,10 +1232,6 @@ inherits@2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.1.tgz#b17d08d326b4423e568eff719f91b0b1cbdf69f1" -ini@^1.3.4: - version "1.3.4" - resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.4.tgz#0537cb79daf59b59a1a517dff706c86ec039162e" - inquirer@^0.12.0: version "0.12.0" resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-0.12.0.tgz#1ef2bfd63504df0bc75785fff8c2c41df12f077e" @@ -1844,44 +1251,15 @@ inquirer@^0.12.0: through "^2.3.6" interpret@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.0.1.tgz#d579fb7f693b858004947af39fa0db49f795602c" + version "1.0.2" + resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.0.2.tgz#f4f623f0bb7122f15f5717c8e254b8161b5c5b2d" -invariant@^2.2.0: +invariant@^2.2.0, invariant@^2.2.2: version "2.2.2" resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.2.tgz#9e1f56ac0acdb6bf303306f338be3b204ae60360" dependencies: loose-envify "^1.0.0" -is-absolute@^0.2.3: - version "0.2.6" - resolved "https://registry.yarnpkg.com/is-absolute/-/is-absolute-0.2.6.tgz#20de69f3db942ef2d87b9c2da36f172235b1b5eb" - dependencies: - is-relative "^0.2.1" - is-windows "^0.2.0" - -is-buffer@^1.0.2: - version "1.1.4" - resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.4.tgz#cfc86ccd5dc5a52fa80489111c6920c457e2d98b" - -is-dotfile@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/is-dotfile/-/is-dotfile-1.0.2.tgz#2c132383f39199f8edc268ca01b9b007d205cc4d" - -is-equal-shallow@^0.1.3: - version "0.1.3" - resolved "https://registry.yarnpkg.com/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz#2238098fc221de0bcfa5d9eac4c45d638aa1c534" - dependencies: - is-primitive "^2.0.0" - -is-extendable@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89" - -is-extglob@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-1.0.0.tgz#ac468177c4943405a092fc8f29760c6ffc6206c0" - is-finite@^1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/is-finite/-/is-finite-1.0.2.tgz#cc6677695602be550ef11e8b4aa6305342b6d0aa" @@ -1898,12 +1276,6 @@ is-fullwidth-code-point@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" -is-glob@^2.0.0, is-glob@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-2.0.1.tgz#d096f926a3ded5600f3fdfd91198cb0888c2d863" - dependencies: - is-extglob "^1.0.0" - is-my-json-valid@^2.10.0: version "2.16.0" resolved "https://registry.yarnpkg.com/is-my-json-valid/-/is-my-json-valid-2.16.0.tgz#f079dd9bfdae65ee2038aae8acbc86ab109e3693" @@ -1913,12 +1285,6 @@ is-my-json-valid@^2.10.0: jsonpointer "^4.0.0" xtend "^4.0.0" -is-number@^2.0.2, is-number@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/is-number/-/is-number-2.1.0.tgz#01fcbbb393463a548f2f466cce16dece49db908f" - dependencies: - kind-of "^3.0.2" - is-path-cwd@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-path-cwd/-/is-path-cwd-1.0.0.tgz#d225ec23132e89edd38fda767472e62e65f1106d" @@ -1935,76 +1301,27 @@ is-path-inside@^1.0.0: dependencies: path-is-inside "^1.0.1" -is-posix-bracket@^0.1.0: - version "0.1.1" - resolved "https://registry.yarnpkg.com/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz#3334dc79774368e92f016e6fbc0a88f5cd6e6bc4" - -is-primitive@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/is-primitive/-/is-primitive-2.0.0.tgz#207bab91638499c07b2adf240a41a87210034575" - is-property@^1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/is-property/-/is-property-1.0.2.tgz#57fe1c4e48474edd65b09911f26b1cd4095dda84" -is-relative@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/is-relative/-/is-relative-0.2.1.tgz#d27f4c7d516d175fb610db84bbeef23c3bc97aa5" - dependencies: - is-unc-path "^0.1.1" - is-resolvable@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-resolvable/-/is-resolvable-1.0.0.tgz#8df57c61ea2e3c501408d100fb013cf8d6e0cc62" dependencies: tryit "^1.0.1" -is-unc-path@^0.1.1: - version "0.1.2" - resolved "https://registry.yarnpkg.com/is-unc-path/-/is-unc-path-0.1.2.tgz#6ab053a72573c10250ff416a3814c35178af39b9" - dependencies: - unc-path-regex "^0.1.0" - -is-utf8@^0.2.0: - version "0.2.1" - resolved "https://registry.yarnpkg.com/is-utf8/-/is-utf8-0.2.1.tgz#4b0da1442104d1b336340e80797e865cf39f7d72" - -is-windows@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-0.2.0.tgz#de1aa6d63ea29dd248737b69f1ff8b8002d2108c" - -isarray@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf" - -isarray@1.0.0, isarray@^1.0.0, isarray@~1.0.0: +isarray@^1.0.0, isarray@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" -isexe@^1.1.1: - version "1.1.2" - resolved "https://registry.yarnpkg.com/isexe/-/isexe-1.1.2.tgz#36f3e22e60750920f5e7241a476a8c6a42275ad0" - -isobject@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/isobject/-/isobject-2.1.0.tgz#f065561096a3f1da2ef46272f815c840d87e0c89" - dependencies: - isarray "1.0.0" - -jade@0.26.3: - version "0.26.3" - resolved "https://registry.yarnpkg.com/jade/-/jade-0.26.3.tgz#8f10d7977d8d79f2f6ff862a81b0513ccb25686c" - dependencies: - commander "0.6.1" - mkdirp "0.3.0" - js-tokens@^3.0.0: version "3.0.1" resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.1.tgz#08e9f132484a2c45a30907e9dc4d5567b7f114d7" js-yaml@^3.5.1: - version "3.8.1" - resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.8.1.tgz#782ba50200be7b9e5a8537001b7804db3ad02628" + version "3.8.2" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.8.2.tgz#02d3e2c0f6beab20248d412c352203827d786721" dependencies: argparse "^1.0.7" esprima "^3.1.1" @@ -2027,6 +1344,10 @@ json-stable-stringify@^1.0.0, json-stable-stringify@^1.0.1: dependencies: jsonify "~0.0.0" +json3@3.3.2: + version "3.3.2" + resolved "https://registry.yarnpkg.com/json3/-/json3-3.3.2.tgz#3c0434743df93e2f5c42aee7b19bcb483575f4e1" + json5@^0.5.0: version "0.5.1" resolved "https://registry.yarnpkg.com/json5/-/json5-0.5.1.tgz#1eade7acc012034ad84e2396767ead9fa5495821" @@ -2039,16 +1360,6 @@ jsonpointer@^4.0.0: version "4.0.1" resolved "https://registry.yarnpkg.com/jsonpointer/-/jsonpointer-4.0.1.tgz#4fd92cb34e0e9db3c89c8622ecf51f9b978c6cb9" -kind-of@^3.0.2: - version "3.1.0" - resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.1.0.tgz#475d698a5e49ff5e53d14e3e732429dc8bf4cf47" - dependencies: - is-buffer "^1.0.2" - -lazy-debug-legacy@0.0.X: - version "0.0.1" - resolved "https://registry.yarnpkg.com/lazy-debug-legacy/-/lazy-debug-legacy-0.0.1.tgz#537716c0776e4cf79e3ed1b621f7658c2911b1b1" - levn@^0.3.0, levn@~0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee" @@ -2056,31 +1367,20 @@ levn@^0.3.0, levn@~0.3.0: prelude-ls "~1.1.2" type-check "~0.3.2" -liftoff@^2.1.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/liftoff/-/liftoff-2.3.0.tgz#a98f2ff67183d8ba7cfaca10548bd7ff0550b385" - dependencies: - extend "^3.0.0" - findup-sync "^0.4.2" - fined "^1.0.1" - flagged-respawn "^0.3.2" - lodash.isplainobject "^4.0.4" - lodash.isstring "^4.0.1" - lodash.mapvalues "^4.4.0" - rechoir "^0.6.2" - resolve "^1.1.7" +lodash._baseassign@^3.0.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/lodash._baseassign/-/lodash._baseassign-3.2.0.tgz#8c38a099500f215ad09e59f1722fd0c52bfe0a4e" + dependencies: + lodash._basecopy "^3.0.0" + lodash.keys "^3.0.0" lodash._basecopy@^3.0.0: version "3.0.1" resolved "https://registry.yarnpkg.com/lodash._basecopy/-/lodash._basecopy-3.0.1.tgz#8da0e6a876cf344c0ad8a54882111dd3c5c7ca36" -lodash._basetostring@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/lodash._basetostring/-/lodash._basetostring-3.0.1.tgz#d1861d877f824a52f669832dcaf3ee15566a07d5" - -lodash._basevalues@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/lodash._basevalues/-/lodash._basevalues-3.0.0.tgz#5b775762802bde3d3297503e26300820fdf661b7" +lodash._basecreate@^3.0.0: + version "3.0.3" + resolved "https://registry.yarnpkg.com/lodash._basecreate/-/lodash._basecreate-3.0.3.tgz#1bc661614daa7fc311b7d03bf16806a0213cf821" lodash._getnative@^3.0.0: version "3.9.1" @@ -2090,35 +1390,17 @@ lodash._isiterateecall@^3.0.0: version "3.0.9" resolved "https://registry.yarnpkg.com/lodash._isiterateecall/-/lodash._isiterateecall-3.0.9.tgz#5203ad7ba425fae842460e696db9cf3e6aac057c" -lodash._reescape@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/lodash._reescape/-/lodash._reescape-3.0.0.tgz#2b1d6f5dfe07c8a355753e5f27fac7f1cde1616a" - -lodash._reevaluate@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/lodash._reevaluate/-/lodash._reevaluate-3.0.0.tgz#58bc74c40664953ae0b124d806996daca431e2ed" - -lodash._reinterpolate@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz#0ccf2d89166af03b3663c796538b75ac6e114d9d" - -lodash._root@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/lodash._root/-/lodash._root-3.0.1.tgz#fba1c4524c19ee9a5f8136b4609f017cf4ded692" - -lodash.assignwith@^4.0.7: - version "4.2.0" - resolved "https://registry.yarnpkg.com/lodash.assignwith/-/lodash.assignwith-4.2.0.tgz#127a97f02adc41751a954d24b0de17e100e038eb" - lodash.cond@^4.3.0: version "4.5.2" resolved "https://registry.yarnpkg.com/lodash.cond/-/lodash.cond-4.5.2.tgz#f471a1da486be60f6ab955d17115523dd1d255d5" -lodash.escape@^3.0.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/lodash.escape/-/lodash.escape-3.2.0.tgz#995ee0dc18c1b48cc92effae71a10aab5b487698" +lodash.create@3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/lodash.create/-/lodash.create-3.1.1.tgz#d7f2849f0dbda7e04682bb8cd72ab022461debe7" dependencies: - lodash._root "^3.0.0" + lodash._baseassign "^3.0.0" + lodash._basecreate "^3.0.0" + lodash._isiterateecall "^3.0.0" lodash.isarguments@^3.0.0: version "3.1.0" @@ -2128,18 +1410,10 @@ lodash.isarray@^3.0.0: version "3.0.4" resolved "https://registry.yarnpkg.com/lodash.isarray/-/lodash.isarray-3.0.4.tgz#79e4eb88c36a8122af86f844aa9bcd851b5fbb55" -lodash.isempty@^4.2.1: - version "4.4.0" - resolved "https://registry.yarnpkg.com/lodash.isempty/-/lodash.isempty-4.4.0.tgz#6f86cbedd8be4ec987be9aaf33c9684db1b31e7e" - -lodash.isplainobject@^4.0.4, lodash.isplainobject@^4.0.6: +lodash.isplainobject@^4.0.6: version "4.0.6" resolved "https://registry.yarnpkg.com/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz#7c526a52d89b45c45cc690b88163be0497f550cb" -lodash.isstring@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/lodash.isstring/-/lodash.isstring-4.0.1.tgz#d527dfb5456eca7cc9bb95d5daeaf88ba54a5451" - lodash.keys@^3.0.0: version "3.1.2" resolved "https://registry.yarnpkg.com/lodash.keys/-/lodash.keys-3.1.2.tgz#4dbc0472b156be50a0b286855d1bd0b0c656098a" @@ -2148,51 +1422,14 @@ lodash.keys@^3.0.0: lodash.isarguments "^3.0.0" lodash.isarray "^3.0.0" -lodash.mapvalues@^4.4.0: - version "4.6.0" - resolved "https://registry.yarnpkg.com/lodash.mapvalues/-/lodash.mapvalues-4.6.0.tgz#1bafa5005de9dd6f4f26668c30ca37230cc9689c" - -lodash.pick@^4.2.1: - version "4.4.0" - resolved "https://registry.yarnpkg.com/lodash.pick/-/lodash.pick-4.4.0.tgz#52f05610fff9ded422611441ed1fc123a03001b3" - -lodash.restparam@^3.0.0: - version "3.6.1" - resolved "https://registry.yarnpkg.com/lodash.restparam/-/lodash.restparam-3.6.1.tgz#936a4e309ef330a7645ed4145986c85ae5b20805" - lodash.some@^4.6.0: version "4.6.0" resolved "https://registry.yarnpkg.com/lodash.some/-/lodash.some-4.6.0.tgz#1bb9f314ef6b8baded13b549169b2a945eb68e4d" -lodash.template@^3.0.0: - version "3.6.2" - resolved "https://registry.yarnpkg.com/lodash.template/-/lodash.template-3.6.2.tgz#f8cdecc6169a255be9098ae8b0c53d378931d14f" - dependencies: - lodash._basecopy "^3.0.0" - lodash._basetostring "^3.0.0" - lodash._basevalues "^3.0.0" - lodash._isiterateecall "^3.0.0" - lodash._reinterpolate "^3.0.0" - lodash.escape "^3.0.0" - lodash.keys "^3.0.0" - lodash.restparam "^3.0.0" - lodash.templatesettings "^3.0.0" - -lodash.templatesettings@^3.0.0: - version "3.1.1" - resolved "https://registry.yarnpkg.com/lodash.templatesettings/-/lodash.templatesettings-3.1.1.tgz#fb307844753b66b9f1afa54e262c745307dba8e5" - dependencies: - lodash._reinterpolate "^3.0.0" - lodash.escape "^3.0.0" - lodash@^4.0.0, lodash@^4.2.0, lodash@^4.3.0: version "4.17.4" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.4.tgz#78203a4d1c328ae1d86dca6460e369b57f4055ae" -lodash@~1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/lodash/-/lodash-1.0.2.tgz#8f57560c83b59fc270bd3d561b690043430e2551" - lolex@1.3.2: version "1.3.2" resolved "https://registry.yarnpkg.com/lolex/-/lolex-1.3.2.tgz#7c3da62ffcb30f0f5a80a2566ca24e45d8a01f31" @@ -2203,96 +1440,37 @@ loose-envify@^1.0.0: dependencies: js-tokens "^3.0.0" -lru-cache@2: - version "2.7.3" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-2.7.3.tgz#6d4524e8b955f95d4f5b58851ce21dd72fb4e952" - -map-cache@^0.2.0: - version "0.2.2" - resolved "https://registry.yarnpkg.com/map-cache/-/map-cache-0.2.2.tgz#c32abd0bd6525d9b051645bb4f26ac5dc98a0dbf" - -micromatch@^2.3.7: - version "2.3.11" - resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-2.3.11.tgz#86677c97d1720b363431d04d0d15293bd38c1565" - dependencies: - arr-diff "^2.0.0" - array-unique "^0.2.1" - braces "^1.8.2" - expand-brackets "^0.1.4" - extglob "^0.3.1" - filename-regex "^2.0.0" - is-extglob "^1.0.0" - is-glob "^2.0.1" - kind-of "^3.0.2" - normalize-path "^2.0.1" - object.omit "^2.0.0" - parse-glob "^3.0.4" - regex-cache "^0.4.2" - -minimatch@0.3: - version "0.3.0" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-0.3.0.tgz#275d8edaac4f1bb3326472089e7949c8394699dd" - dependencies: - lru-cache "2" - sigmund "~1.0.0" - -minimatch@^2.0.1: - version "2.0.10" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-2.0.10.tgz#8d087c39c6b38c001b97fca7ce6d0e1e80afbac7" - dependencies: - brace-expansion "^1.0.0" - minimatch@^3.0.2, minimatch@^3.0.3: version "3.0.3" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.3.tgz#2a4e4090b96b2db06a9d7df01055a62a77c9b774" dependencies: brace-expansion "^1.0.0" -minimatch@~0.2.11: - version "0.2.14" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-0.2.14.tgz#c74e780574f63c6f9a090e90efbe6ef53a6a756a" - dependencies: - lru-cache "2" - sigmund "~1.0.0" - minimist@0.0.8: version "0.0.8" resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" -minimist@^1.1.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284" - -mkdirp@0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.3.0.tgz#1bbf5ab1ba827af23575143490426455f481fe1e" - mkdirp@0.5.1, mkdirp@^0.5.0, mkdirp@^0.5.1: version "0.5.1" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" dependencies: minimist "0.0.8" -mocha@^2.4.5: - version "2.5.3" - resolved "https://registry.yarnpkg.com/mocha/-/mocha-2.5.3.tgz#161be5bdeb496771eb9b35745050b622b5aefc58" +mocha@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/mocha/-/mocha-3.2.0.tgz#7dc4f45e5088075171a68896814e6ae9eb7a85e3" dependencies: - commander "2.3.0" + browser-stdout "1.3.0" + commander "2.9.0" debug "2.2.0" diff "1.4.0" - escape-string-regexp "1.0.2" - glob "3.2.11" + escape-string-regexp "1.0.5" + glob "7.0.5" growl "1.9.2" - jade "0.26.3" + json3 "3.3.2" + lodash.create "3.1.1" mkdirp "0.5.1" - supports-color "1.2.0" - to-iso-string "0.0.2" - -modify-babel-preset@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/modify-babel-preset/-/modify-babel-preset-2.1.1.tgz#2d3190162ee62fb67aaa3325c242f026322ebbac" - dependencies: - require-relative "^0.8.7" + supports-color "3.1.2" ms@0.7.1: version "0.7.1" @@ -2302,63 +1480,28 @@ ms@0.7.2: version "0.7.2" resolved "https://registry.yarnpkg.com/ms/-/ms-0.7.2.tgz#ae25cf2512b3885a1d95d7f037868d8431124765" -multipipe@^0.1.2: - version "0.1.2" - resolved "https://registry.yarnpkg.com/multipipe/-/multipipe-0.1.2.tgz#2a8f2ddf70eed564dff2d57f1e1a137d9f05078b" - dependencies: - duplexer2 "0.0.2" - mute-stream@0.0.5: version "0.0.5" resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.5.tgz#8fbfabb0a98a253d3184331f9e8deb7372fac6c0" -natives@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/natives/-/natives-1.1.0.tgz#e9ff841418a6b2ec7a495e939984f78f163e6e31" - natural-compare@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" -normalize-path@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-2.0.1.tgz#47886ac1662760d4261b7d979d241709d3ce3f7a" - number-is-nan@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" -object-assign@4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.0.tgz#7a3b3d0e98063d43f4c03f2e8ae6cd51a86883a0" - -object-assign@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-3.0.0.tgz#9bedd5ca0897949bca47e7ff408062d549f587f2" - object-assign@^4.0.1, object-assign@^4.1.0: version "4.1.1" resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" -object.omit@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/object.omit/-/object.omit-2.0.1.tgz#1a9c744829f39dbb858c76ca3579ae2a54ebd1fa" - dependencies: - for-own "^0.1.4" - is-extendable "^0.1.1" - once@^1.3.0: version "1.4.0" resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" dependencies: wrappy "1" -once@~1.3.0: - version "1.3.3" - resolved "https://registry.yarnpkg.com/once/-/once-1.3.3.tgz#b2e261557ce4c314ec8304f3fa82663e4297ca20" - dependencies: - wrappy "1" - onetime@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/onetime/-/onetime-1.1.0.tgz#a1f7838f8314c516f05ecefcbc4ccfe04b4ed789" @@ -2374,19 +1517,7 @@ optionator@^0.8.2: type-check "~0.3.2" wordwrap "~1.0.0" -orchestrator@^0.3.0: - version "0.3.8" - resolved "https://registry.yarnpkg.com/orchestrator/-/orchestrator-0.3.8.tgz#14e7e9e2764f7315fbac184e506c7aa6df94ad7e" - dependencies: - end-of-stream "~0.1.5" - sequencify "~0.0.7" - stream-consume "~0.1.0" - -ordered-read-streams@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/ordered-read-streams/-/ordered-read-streams-0.1.0.tgz#fd565a9af8eb4473ba69b6ed8a34352cb552f126" - -os-homedir@^1.0.0, os-homedir@^1.0.1: +os-homedir@^1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3" @@ -2394,27 +1525,6 @@ os-tmpdir@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" -parse-filepath@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/parse-filepath/-/parse-filepath-1.0.1.tgz#159d6155d43904d16c10ef698911da1e91969b73" - dependencies: - is-absolute "^0.2.3" - map-cache "^0.2.0" - path-root "^0.1.1" - -parse-glob@^3.0.4: - version "3.0.4" - resolved "https://registry.yarnpkg.com/parse-glob/-/parse-glob-3.0.4.tgz#b2c376cfb11f35513badd173ef0bb6e3a388391c" - dependencies: - glob-base "^0.3.0" - is-dotfile "^1.0.0" - is-extglob "^1.0.0" - is-glob "^2.0.0" - -parse-passwd@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/parse-passwd/-/parse-passwd-1.0.0.tgz#6d5b934a456993b23d37f40a382d6f1666a8e5c6" - path-exists@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-2.1.0.tgz#0feb6c64f0fc518d9a754dd5efb62c7022761f4b" @@ -2433,16 +1543,6 @@ path-parse@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.5.tgz#3c1adf871ea9cd6c9431b6ea2bd74a0ff055c4c1" -path-root-regex@^0.1.0: - version "0.1.2" - resolved "https://registry.yarnpkg.com/path-root-regex/-/path-root-regex-0.1.2.tgz#bfccdc8df5b12dc52c8b43ec38d18d72c04ba96d" - -path-root@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/path-root/-/path-root-0.1.1.tgz#9a4a6814cac1c0cd73360a95f32083c8ea4745b7" - dependencies: - path-root-regex "^0.1.0" - pify@^2.0.0: version "2.3.0" resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" @@ -2477,14 +1577,6 @@ prelude-ls@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" -preserve@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/preserve/-/preserve-0.2.0.tgz#815ed1f6ebc65926f865b310c0713bcb3315ce4b" - -pretty-hrtime@^1.0.0: - version "1.0.3" - resolved "https://registry.yarnpkg.com/pretty-hrtime/-/pretty-hrtime-1.0.3.tgz#b7e3ea42435a4c9b2759d99e0f201eb195802ee1" - private@^0.1.6: version "0.1.7" resolved "https://registry.yarnpkg.com/private/-/private-0.1.7.tgz#68ce5e8a1ef0a23bb570cc28537b5332aba63ef1" @@ -2497,25 +1589,9 @@ progress@^1.1.8: version "1.1.8" resolved "https://registry.yarnpkg.com/progress/-/progress-1.1.8.tgz#e260c78f6161cdd9b0e56cc3e0a85de17c7a57be" -randomatic@^1.1.3: - version "1.1.6" - resolved "https://registry.yarnpkg.com/randomatic/-/randomatic-1.1.6.tgz#110dcabff397e9dcff7c0789ccc0a49adf1ec5bb" - dependencies: - is-number "^2.0.2" - kind-of "^3.0.2" - -"readable-stream@>=1.0.33-1 <1.1.0-0": - version "1.0.34" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.0.34.tgz#125820e34bc842d2f2aaafafe4c2916ee32c157c" - dependencies: - core-util-is "~1.0.0" - inherits "~2.0.1" - isarray "0.0.1" - string_decoder "~0.10.x" - -readable-stream@^2.1.5, readable-stream@^2.2.2: - version "2.2.3" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.2.3.tgz#9cf49463985df016c8ae8813097a9293a9b33729" +readable-stream@^2.2.2: + version "2.2.6" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.2.6.tgz#8b43aed76e71483938d12a8d46c6cf1a00b1f816" dependencies: buffer-shims "^1.0.0" core-util-is "~1.0.0" @@ -2525,15 +1601,6 @@ readable-stream@^2.1.5, readable-stream@^2.2.2: string_decoder "~0.10.x" util-deprecate "~1.0.1" -readable-stream@~1.1.9: - version "1.1.14" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.1.14.tgz#7cf4c54ef648e3813084c636dd2079e166c081d9" - dependencies: - core-util-is "~1.0.0" - inherits "~2.0.1" - isarray "0.0.1" - string_decoder "~0.10.x" - readline2@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/readline2/-/readline2-1.0.1.tgz#41059608ffc154757b715d9989d199ffbf372e35" @@ -2564,13 +1631,6 @@ regenerator-transform@0.9.8: babel-types "^6.19.0" private "^0.1.6" -regex-cache@^0.4.2: - version "0.4.3" - resolved "https://registry.yarnpkg.com/regex-cache/-/regex-cache-0.4.3.tgz#9b1a6c35d4d0dfcef5711ae651e8e9d3d7114145" - dependencies: - is-equal-shallow "^0.1.3" - is-primitive "^2.0.0" - regexpu-core@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-2.0.0.tgz#49d038837b8dcf8bfa5b9a42139938e6ea2ae240" @@ -2589,28 +1649,12 @@ regjsparser@^0.1.4: dependencies: jsesc "~0.5.0" -repeat-element@^1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.2.tgz#ef089a178d1483baae4d93eb98b4f9e4e11d990a" - -repeat-string@^1.5.2: - version "1.6.1" - resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" - repeating@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/repeating/-/repeating-2.0.1.tgz#5214c53a926d3552707527fbab415dbc08d06dda" dependencies: is-finite "^1.0.0" -replace-ext@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/replace-ext/-/replace-ext-0.0.1.tgz#29bbd92078a739f0bcce2b4ee41e837953522924" - -require-relative@^0.8.7: - version "0.8.7" - resolved "https://registry.yarnpkg.com/require-relative/-/require-relative-0.8.7.tgz#7999539fc9e047a37928fa196f8e1563dabd36de" - require-uncached@^1.0.2: version "1.0.3" resolved "https://registry.yarnpkg.com/require-uncached/-/require-uncached-1.0.3.tgz#4e0d56d6c9662fd31e43011c4b95aa49955421d3" @@ -2618,28 +1662,17 @@ require-uncached@^1.0.2: caller-path "^0.1.0" resolve-from "^1.0.0" -resolve-dir@^0.1.0: - version "0.1.1" - resolved "https://registry.yarnpkg.com/resolve-dir/-/resolve-dir-0.1.1.tgz#b219259a5602fac5c5c496ad894a6e8cc430261e" - dependencies: - expand-tilde "^1.2.2" - global-modules "^0.2.3" - resolve-from@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-1.0.1.tgz#26cbfe935d1aeeeabb29bc3fe5aeb01e93d44226" -resolve-url@~0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a" - resolve@1.1.7: version "1.1.7" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.1.7.tgz#203114d82ad2c5ed9e8e0411b3932875e889e97b" -resolve@^1.1.6, resolve@^1.1.7: - version "1.3.1" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.3.1.tgz#5d0a1632609b6b00a22284293db1d5d973676314" +resolve@^1.1.6: + version "1.3.2" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.3.2.tgz#1f0442c9e0cbb8136e87b9305f932f46c7f28235" dependencies: path-parse "^1.0.5" @@ -2674,8 +1707,8 @@ rollup-plugin-babili@^2.0.0: babel-preset-babili "^0.0.12" rollup-plugin-node-resolve@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/rollup-plugin-node-resolve/-/rollup-plugin-node-resolve-2.0.0.tgz#07e0ae94ac002a3ea36e8f33ca121d9f836b1309" + version "2.1.1" + resolved "https://registry.yarnpkg.com/rollup-plugin-node-resolve/-/rollup-plugin-node-resolve-2.1.1.tgz#cbb783b0d15b02794d58915350b2f0d902b8ddc8" dependencies: browser-resolve "^1.11.0" builtin-modules "^1.1.0" @@ -2688,9 +1721,9 @@ rollup-pluginutils@^1.5.0: estree-walker "^0.2.1" minimatch "^3.0.2" -rollup@^0.41.4: - version "0.41.4" - resolved "https://registry.yarnpkg.com/rollup/-/rollup-0.41.4.tgz#a970580176329f9ead86854d7fd4c46de752aef8" +rollup@^0.41.6: + version "0.41.6" + resolved "https://registry.yarnpkg.com/rollup/-/rollup-0.41.6.tgz#e0d05497877a398c104d816d2733a718a7a94e2a" dependencies: source-map-support "^0.4.0" @@ -2708,29 +1741,17 @@ samsam@1.1.2, samsam@~1.1: version "1.1.2" resolved "https://registry.yarnpkg.com/samsam/-/samsam-1.1.2.tgz#bec11fdc83a9fda063401210e40176c3024d1567" -semver@^4.1.0: - version "4.3.6" - resolved "https://registry.yarnpkg.com/semver/-/semver-4.3.6.tgz#300bc6e0e86374f7ba61068b5b1ecd57fc6532da" - -sequencify@~0.0.7: - version "0.0.7" - resolved "https://registry.yarnpkg.com/sequencify/-/sequencify-0.0.7.tgz#90cff19d02e07027fd767f5ead3e7b95d1e7380c" - shelljs@^0.7.5: - version "0.7.6" - resolved "https://registry.yarnpkg.com/shelljs/-/shelljs-0.7.6.tgz#379cccfb56b91c8601e4793356eb5382924de9ad" + version "0.7.7" + resolved "https://registry.yarnpkg.com/shelljs/-/shelljs-0.7.7.tgz#b2f5c77ef97148f4b4f6e22682e10bba8667cff1" dependencies: glob "^7.0.0" interpret "^1.0.0" rechoir "^0.6.2" -sigmund@~1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/sigmund/-/sigmund-1.0.1.tgz#3ff21f198cad2175f9f3b781853fd94d0d19b590" - sinon-chai@^2.8.0: - version "2.8.0" - resolved "https://registry.yarnpkg.com/sinon-chai/-/sinon-chai-2.8.0.tgz#432a9bbfd51a6fc00798f4d2526a829c060687ac" + version "2.9.0" + resolved "https://registry.yarnpkg.com/sinon-chai/-/sinon-chai-2.9.0.tgz#34d820042bc9661a14527130d401eb462c49bb84" sinon@^1.17.7: version "1.17.7" @@ -2749,47 +1770,20 @@ slice-ansi@0.0.4: version "0.0.4" resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-0.0.4.tgz#edbf8903f66f7ce2f8eafd6ceed65e264c831b35" -source-map-resolve@^0.3.0: - version "0.3.1" - resolved "https://registry.yarnpkg.com/source-map-resolve/-/source-map-resolve-0.3.1.tgz#610f6122a445b8dd51535a2a71b783dfc1248761" - dependencies: - atob "~1.1.0" - resolve-url "~0.2.1" - source-map-url "~0.3.0" - urix "~0.1.0" - source-map-support@^0.4.0, source-map-support@^0.4.2: - version "0.4.11" - resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.4.11.tgz#647f939978b38535909530885303daf23279f322" + version "0.4.14" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.4.14.tgz#9d4463772598b86271b4f523f6c1f4e02a7d6aef" dependencies: - source-map "^0.5.3" - -source-map-url@~0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.3.0.tgz#7ecaf13b57bcd09da8a40c5d269db33799d4aaf9" + source-map "^0.5.6" -source-map@0.X, source-map@^0.5.0, source-map@^0.5.1, source-map@^0.5.3: +source-map@^0.5.0, source-map@^0.5.6: version "0.5.6" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.6.tgz#75ce38f52bf0733c5a7f0c118d81334a2bb5f412" -source-map@^0.1.38: - version "0.1.43" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.1.43.tgz#c24bc146ca517c1471f5dacbe2571b2b7f9e3346" - dependencies: - amdefine ">=0.0.4" - -sparkles@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/sparkles/-/sparkles-1.0.0.tgz#1acbbfb592436d10bbe8f785b7cc6f82815012c3" - sprintf-js@~1.0.2: version "1.0.3" resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" -stream-consume@~0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/stream-consume/-/stream-consume-0.1.0.tgz#a41ead1a6d6081ceb79f65b061901b6d8f3d1d0f" - string-width@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3" @@ -2815,24 +1809,19 @@ strip-ansi@^3.0.0: dependencies: ansi-regex "^2.0.0" -strip-bom@3.X, strip-bom@^3.0.0: +strip-bom@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3" -strip-bom@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-1.0.0.tgz#85b8862f3844b5a6d5ec8467a93598173a36f794" - dependencies: - first-chunk-stream "^1.0.0" - is-utf8 "^0.2.0" - strip-json-comments@~2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" -supports-color@1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-1.2.0.tgz#ff1ed1e61169d06b3cf2d588e188b18d8847e17e" +supports-color@3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-3.1.2.tgz#72a262894d9d408b956ca05ff37b2ed8a6e2a2d5" + dependencies: + has-flag "^1.0.0" supports-color@^2.0.0: version "2.0.0" @@ -2859,42 +1848,14 @@ text-table@~0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" -through2@2.X, through2@^2.0.0: - version "2.0.3" - resolved "https://registry.yarnpkg.com/through2/-/through2-2.0.3.tgz#0004569b37c7c74ba39c43f3ced78d1ad94140be" - dependencies: - readable-stream "^2.1.5" - xtend "~4.0.1" - -through2@^0.6.1: - version "0.6.5" - resolved "https://registry.yarnpkg.com/through2/-/through2-0.6.5.tgz#41ab9c67b29d57209071410e1d7a7a968cd3ad48" - dependencies: - readable-stream ">=1.0.33-1 <1.1.0-0" - xtend ">=4.0.0 <4.1.0-0" - through@^2.3.6: version "2.3.8" resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" -tildify@^1.0.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/tildify/-/tildify-1.2.0.tgz#dcec03f55dca9b7aa3e5b04f21817eb56e63588a" - dependencies: - os-homedir "^1.0.0" - -time-stamp@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/time-stamp/-/time-stamp-1.0.1.tgz#9f4bd23559c9365966f3302dbba2b07c6b99b151" - to-fast-properties@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-1.0.2.tgz#f3f5c0c3ba7299a7ef99427e44633257ade43320" -to-iso-string@0.0.2: - version "0.0.2" - resolved "https://registry.yarnpkg.com/to-iso-string/-/to-iso-string-0.0.2.tgz#4dc19e664dfccbe25bd8db508b00c6da158255d1" - trim-right@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/trim-right/-/trim-right-1.0.1.tgz#cb2e1203067e0c8de1f614094b9fe45704ea6003" @@ -2921,22 +1882,6 @@ typedarray@^0.0.6: version "0.0.6" resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" -unc-path-regex@^0.1.0: - version "0.1.2" - resolved "https://registry.yarnpkg.com/unc-path-regex/-/unc-path-regex-0.1.2.tgz#e73dd3d7b0d7c5ed86fbac6b0ae7d8c6a69d50fa" - -unique-stream@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/unique-stream/-/unique-stream-1.0.0.tgz#d59a4a75427447d9aa6c91e70263f8d26a4b104b" - -urix@^0.1.0, urix@~0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/urix/-/urix-0.1.0.tgz#da937f7a62e21fec1fd18d49b35c2935067a6c72" - -user-home@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/user-home/-/user-home-1.1.1.tgz#2b5be23a32b63a7c9deb8d0f28d485724a3df190" - user-home@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/user-home/-/user-home-2.0.0.tgz#9c70bfd8169bc1dcbf48604e0f04b8b49cde9e9f" @@ -2953,60 +1898,6 @@ util-deprecate@~1.0.1: dependencies: inherits "2.0.1" -v8flags@^2.0.2: - version "2.0.11" - resolved "https://registry.yarnpkg.com/v8flags/-/v8flags-2.0.11.tgz#bca8f30f0d6d60612cc2c00641e6962d42ae6881" - dependencies: - user-home "^1.1.1" - -vinyl-fs@^0.3.0: - version "0.3.14" - resolved "https://registry.yarnpkg.com/vinyl-fs/-/vinyl-fs-0.3.14.tgz#9a6851ce1cac1c1cea5fe86c0931d620c2cfa9e6" - dependencies: - defaults "^1.0.0" - glob-stream "^3.1.5" - glob-watcher "^0.0.6" - graceful-fs "^3.0.0" - mkdirp "^0.5.0" - strip-bom "^1.0.0" - through2 "^0.6.1" - vinyl "^0.4.0" - -vinyl-sourcemaps-apply@^0.2.0: - version "0.2.1" - resolved "https://registry.yarnpkg.com/vinyl-sourcemaps-apply/-/vinyl-sourcemaps-apply-0.2.1.tgz#ab6549d61d172c2b1b87be5c508d239c8ef87705" - dependencies: - source-map "^0.5.1" - -vinyl@1.X: - version "1.2.0" - resolved "https://registry.yarnpkg.com/vinyl/-/vinyl-1.2.0.tgz#5c88036cf565e5df05558bfc911f8656df218884" - dependencies: - clone "^1.0.0" - clone-stats "^0.0.1" - replace-ext "0.0.1" - -vinyl@^0.4.0: - version "0.4.6" - resolved "https://registry.yarnpkg.com/vinyl/-/vinyl-0.4.6.tgz#2f356c87a550a255461f36bbeb2a5ba8bf784847" - dependencies: - clone "^0.2.0" - clone-stats "^0.0.1" - -vinyl@^0.5.0: - version "0.5.3" - resolved "https://registry.yarnpkg.com/vinyl/-/vinyl-0.5.3.tgz#b0455b38fc5e0cf30d4325132e461970c2091cde" - dependencies: - clone "^1.0.0" - clone-stats "^0.0.1" - replace-ext "0.0.1" - -which@^1.2.12: - version "1.2.12" - resolved "https://registry.yarnpkg.com/which/-/which-1.2.12.tgz#de67b5e450269f194909ef23ece4ebe416fa1192" - dependencies: - isexe "^1.1.1" - wordwrap@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb" @@ -3021,6 +1912,6 @@ write@^0.2.1: dependencies: mkdirp "^0.5.1" -"xtend@>=4.0.0 <4.1.0-0", xtend@^4.0.0, xtend@~4.0.1: +xtend@^4.0.0: version "4.0.1" resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.1.tgz#a5c6d532be656e23db820efb943a1f04998d63af" From dcb7f40d6a3457916cb36c71684e874b70be29b5 Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Mon, 3 Apr 2017 22:58:36 -0500 Subject: [PATCH 064/418] Update tailored dep --- package.json | 2 +- yarn.lock | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/package.json b/package.json index 5be1f75c..9f20f631 100644 --- a/package.json +++ b/package.json @@ -23,7 +23,7 @@ "license": "MIT", "dependencies": { "erlang-types": "^1.0.0", - "tailored": "2.4.1" + "tailored": "2.4.4" }, "devDependencies": { "babel-core": "^6.24.0", diff --git a/yarn.lock b/yarn.lock index c7b7c84c..ea295d82 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1838,9 +1838,9 @@ table@^3.7.8: slice-ansi "0.0.4" string-width "^2.0.0" -tailored@2.4.1: - version "2.4.1" - resolved "https://registry.yarnpkg.com/tailored/-/tailored-2.4.1.tgz#5fa0988704af192171dfe1299060ec97611225b4" +tailored@2.4.4: + version "2.4.4" + resolved "https://registry.yarnpkg.com/tailored/-/tailored-2.4.4.tgz#686642640d9d360cd8d26b8f313cc1203cb520a7" dependencies: erlang-types "^1.0.0" From e29a068fdbad1b0747067b244b74137c55c11b49 Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Tue, 4 Apr 2017 09:17:18 -0500 Subject: [PATCH 065/418] Update tailored to fix matching on tuples --- package.json | 2 +- src/javascript/lib/core/special_forms.js | 11 ++++++----- src/javascript/tests/with.spec.js | 7 +++---- yarn.lock | 6 +++--- 4 files changed, 13 insertions(+), 13 deletions(-) diff --git a/package.json b/package.json index 9f20f631..c9ecbf18 100644 --- a/package.json +++ b/package.json @@ -23,7 +23,7 @@ "license": "MIT", "dependencies": { "erlang-types": "^1.0.0", - "tailored": "2.4.4" + "tailored": "2.4.5" }, "devDependencies": { "babel-core": "^6.24.0", diff --git a/src/javascript/lib/core/special_forms.js b/src/javascript/lib/core/special_forms.js index faac7e94..e308ddf7 100644 --- a/src/javascript/lib/core/special_forms.js +++ b/src/javascript/lib/core/special_forms.js @@ -27,10 +27,10 @@ function _for(expression, generators, collectable_protocol, into = []) { for (const value of generatedValues) { if (expression.guard.apply(this, value)) { - result = fun(result, new Core.Tuple( - Symbol.for('cont'), - expression.fn.apply(this, value), - )); + result = fun( + result, + new Core.Tuple(Symbol.for('cont'), expression.fn.apply(this, value)), + ); } } @@ -39,7 +39,7 @@ function _for(expression, generators, collectable_protocol, into = []) { function run_list_generators(generator, generators) { if (generators.length == 0) { - return generator.map((x) => { + return generator.map(x => { if (Array.isArray(x)) { return x; } @@ -140,6 +140,7 @@ function _with(...args) { } return result; } + argsToPass = argsToPass.concat(patternResult); } diff --git a/src/javascript/tests/with.spec.js b/src/javascript/tests/with.spec.js index 9d5a6609..e1a30150 100644 --- a/src/javascript/tests/with.spec.js +++ b/src/javascript/tests/with.spec.js @@ -118,10 +118,9 @@ describe('with', () => { ), ); - expect(value).to.eql(new Tuple( - Symbol.for('error'), - Symbol.for('wrong_data'), - )); + expect(value).to.eql( + new Tuple(Symbol.for('error'), Symbol.for('wrong_data')), + ); }); it('with else that don`t match', () => { diff --git a/yarn.lock b/yarn.lock index ea295d82..ed077766 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1838,9 +1838,9 @@ table@^3.7.8: slice-ansi "0.0.4" string-width "^2.0.0" -tailored@2.4.4: - version "2.4.4" - resolved "https://registry.yarnpkg.com/tailored/-/tailored-2.4.4.tgz#686642640d9d360cd8d26b8f313cc1203cb520a7" +tailored@2.4.5: + version "2.4.5" + resolved "https://registry.yarnpkg.com/tailored/-/tailored-2.4.5.tgz#c100530d8c2978a0b75228159a46bfe636fa70d6" dependencies: erlang-types "^1.0.0" From f1e3d000ebf4059dbaae455ddb45442a48939310 Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Tue, 4 Apr 2017 09:31:08 -0500 Subject: [PATCH 066/418] Fix tuple pattern creation --- .../translator/pattern_matching.ex | 14 ++--- test/translator/case_test.exs | 40 +++++-------- test/translator/for_test.exs | 44 ++++---------- test/translator/function_test.exs | 22 ++++--- test/translator/match_test.exs | 21 +++---- test/translator/pattern_matching_test.exs | 16 ++--- test/translator/with_test.exs | 58 ++++++++----------- 7 files changed, 81 insertions(+), 134 deletions(-) diff --git a/lib/elixir_script/translator/pattern_matching.ex b/lib/elixir_script/translator/pattern_matching.ex index e90c59e5..6a9be928 100644 --- a/lib/elixir_script/translator/pattern_matching.ex +++ b/lib/elixir_script/translator/pattern_matching.ex @@ -244,14 +244,12 @@ defmodule ElixirScript.Translator.PatternMatching do |> Enum.map(&build_match([&1], env)) |> reduce_patterns - pattern = JS.object_expression([ - JS.property( - JS.identifier("values"), - JS.array_expression(patterns) - ) - ]) - - { [type(Primitive.tuple_class, pattern)], params } + tuple_pattern = JS.new_expression( + Primitive.tuple_class(), + patterns + ) + + { [tuple_pattern], params } end defp do_build_match({:\\, _, [{name, _, _}, default]}, env) do diff --git a/test/translator/case_test.exs b/test/translator/case_test.exs index 08bb8fbb..4a38b333 100644 --- a/test/translator/case_test.exs +++ b/test/translator/case_test.exs @@ -155,13 +155,11 @@ defmodule ElixirScript.Translator.Case.Test do end js_code = """ - Bootstrap.Core.Patterns.defmatch(Bootstrap.Core.Patterns.clause([Bootstrap.Core.Patterns.type(Bootstrap.Core.Tuple, { - values: [Bootstrap.Core.Patterns.variable(), Bootstrap.Core.Patterns.variable()] - })], function(one, two) { - return console.info(one); - }), Bootstrap.Core.Patterns.clause([Symbol.for('error')], function() { - return null; - })).call(this, data) +Bootstrap.Core.Patterns.defmatch(Bootstrap.Core.Patterns.clause([new Bootstrap.Core.Tuple(Bootstrap.Core.Patterns.variable(), Bootstrap.Core.Patterns.variable())], function(one, two) { + return console.info(one); + }), Bootstrap.Core.Patterns.clause([Symbol.for('error')], function() { + return null; + })).call(this, data); """ assert_translation(ex_ast, js_code) @@ -181,15 +179,11 @@ defmodule ElixirScript.Translator.Case.Test do end js_code = """ - Bootstrap.Core.Patterns.defmatch(Bootstrap.Core.Patterns.clause([Bootstrap.Core.Patterns.type(Bootstrap.Core.Tuple, { - values: [Bootstrap.Core.Patterns.type(Bootstrap.Core.Tuple, { - values: [Bootstrap.Core.Patterns.variable(), Bootstrap.Core.Patterns.variable()] - }), Bootstrap.Core.Patterns.variable()] - })], function(one, two, three) { - return console.info(one); - }), Bootstrap.Core.Patterns.clause([Symbol.for('error')], function() { - return null; - })).call(this, data) +Bootstrap.Core.Patterns.defmatch(Bootstrap.Core.Patterns.clause([new Bootstrap.Core.Tuple(new Bootstrap.Core.Tuple(Bootstrap.Core.Patterns.variable(), Bootstrap.Core.Patterns.variable()), Bootstrap.Core.Patterns.variable())], function(one, two, three) { + return console.info(one); + }), Bootstrap.Core.Patterns.clause([Symbol.for('error')], function() { + return null; + })).call(this, data) """ assert_translation(ex_ast, js_code) @@ -205,15 +199,11 @@ defmodule ElixirScript.Translator.Case.Test do end js_code = """ - Bootstrap.Core.Patterns.defmatch(Bootstrap.Core.Patterns.clause([Bootstrap.Core.Patterns.type(Bootstrap.Core.Tuple, { - values: [Bootstrap.Core.Patterns.variable(), Bootstrap.Core.Patterns.type(Bootstrap.Core.Tuple, { - values: [Bootstrap.Core.Patterns.variable(), Bootstrap.Core.Patterns.variable()] - })] - })], function(one, two, three) { - return console.info(one); - }), Bootstrap.Core.Patterns.clause([Symbol.for('error')], function() { - return null; - })).call(this, data) +Bootstrap.Core.Patterns.defmatch(Bootstrap.Core.Patterns.clause([new Bootstrap.Core.Tuple(Bootstrap.Core.Patterns.variable(), new Bootstrap.Core.Tuple(Bootstrap.Core.Patterns.variable(), Bootstrap.Core.Patterns.variable()))], function(one, two, three) { + return console.info(one); + }), Bootstrap.Core.Patterns.clause([Symbol.for('error')], function() { + return null; + })).call(this, data) """ assert_translation(ex_ast, js_code) diff --git a/test/translator/for_test.exs b/test/translator/for_test.exs index 6826d704..60fda4e7 100644 --- a/test/translator/for_test.exs +++ b/test/translator/for_test.exs @@ -8,25 +8,11 @@ defmodule ElixirScript.Translator.For.Test do end js_code = """ - Bootstrap.Core.SpecialForms._for( - Bootstrap.Core.Patterns.clause( - [Bootstrap.Core.Patterns.variable()], - function(n) { - return n * 2; - }, - function() { - return true; - } - ), - [ - Bootstrap.Core.Patterns.list_generator( - Bootstrap.Core.Patterns.variable(), - Object.freeze([1, 2, 3, 4]) - ) - ], - Elixir.ElixirScript.Collectable.__load(Elixir), - Object.freeze([]) - ) + Bootstrap.Core.SpecialForms._for(Bootstrap.Core.Patterns.clause([Bootstrap.Core.Patterns.variable()], function(n) { + return n * 2; + }, function() { + return true; + }), [Bootstrap.Core.Patterns.list_generator(Bootstrap.Core.Patterns.variable(), Object.freeze([1, 2, 3, 4]))], Elixir.ElixirScript.Collectable.__load(Elixir), Object.freeze([])) """ assert_translation(ex_ast, js_code) @@ -173,21 +159,11 @@ defmodule ElixirScript.Translator.For.Test do end js_code = """ - Bootstrap.Core.SpecialForms._for( - Bootstrap.Core.Patterns.clause([Bootstrap.Core.Patterns.type(Bootstrap.Core.Tuple, { - values: [Symbol.for('user'), Bootstrap.Core.Patterns.variable()] - })], function(name) { - return Elixir.ElixirScript.String.__load(Elixir).upcase(name); - }, function() { - return true; - }), - [ - Bootstrap.Core.Patterns.list_generator(Bootstrap.Core.Patterns.type(Bootstrap.Core.Tuple, { - values: [Symbol.for('user'), Bootstrap.Core.Patterns.variable()] - }), Object.freeze([new Bootstrap.Core.Tuple(Symbol.for('user'), 'john'), new Bootstrap.Core.Tuple(Symbol.for('admin'), 'john'), new Bootstrap.Core.Tuple(Symbol.for('user'), 'meg')])) - ], - Elixir.ElixirScript.Collectable.__load(Elixir), - Object.freeze([])) + Bootstrap.Core.SpecialForms._for(Bootstrap.Core.Patterns.clause([new Bootstrap.Core.Tuple(Symbol.for('user'), Bootstrap.Core.Patterns.variable())], function(name) { + return Elixir.ElixirScript.String.__load(Elixir).upcase(name); + }, function() { + return true; + }), [Bootstrap.Core.Patterns.list_generator(new Bootstrap.Core.Tuple(Symbol.for('user'), Bootstrap.Core.Patterns.variable()), Object.freeze([new Bootstrap.Core.Tuple(Symbol.for('user'), 'john'), new Bootstrap.Core.Tuple(Symbol.for('admin'), 'john'), new Bootstrap.Core.Tuple(Symbol.for('user'), 'meg')]))], Elixir.ElixirScript.Collectable.__load(Elixir), Object.freeze([])) """ assert_translation(ex_ast, js_code) diff --git a/test/translator/function_test.exs b/test/translator/function_test.exs index 0f883e30..2f6e6764 100644 --- a/test/translator/function_test.exs +++ b/test/translator/function_test.exs @@ -111,13 +111,13 @@ defmodule ElixirScript.Translator.Function.Test do end js_code = """ - const test1 = Bootstrap.Core.Patterns.defmatch(Bootstrap.Core.Patterns.clause([Bootstrap.Core.Patterns.variable(), Bootstrap.Core.Patterns.variable()], function(alpha, beta) { - let [a, b] = Bootstrap.Core.Patterns.match(Bootstrap.Core.Patterns.type(Bootstrap.Core.Tuple, { - values: [Bootstrap.Core.Patterns.variable(), Bootstrap.Core.Patterns.variable()] - }), new Bootstrap.Core.Tuple(1, 2)); - let _ref = new Bootstrap.Core.Tuple(a, b); - return _ref; - })); + const test1 = Bootstrap.Core.Patterns.defmatch(Bootstrap.Core.Patterns.clause([Bootstrap.Core.Patterns.variable(), Bootstrap.Core.Patterns.variable()], function(alpha, beta) { + let [a, b] = Bootstrap.Core.Patterns.match(new Bootstrap.Core.Tuple(Bootstrap.Core.Patterns.variable(), Bootstrap.Core.Patterns.variable()), new Bootstrap.Core.Tuple(1, 2)); + + let _ref = new Bootstrap.Core.Tuple(a, b); + + return _ref; + })); """ assert_translation(ex_ast, js_code) @@ -429,11 +429,9 @@ defmodule ElixirScript.Translator.Function.Test do js_code = """ - const something = Bootstrap.Core.Patterns.defmatch(Bootstrap.Core.Patterns.clause([Bootstrap.Core.Patterns.type(Bootstrap.Core.Tuple, { - values: [Bootstrap.Core.Patterns.variable(), Bootstrap.Core.Patterns.variable()] - })], function(apple, fruits) { - return null; - })); + const something = Bootstrap.Core.Patterns.defmatch(Bootstrap.Core.Patterns.clause([new Bootstrap.Core.Tuple(Bootstrap.Core.Patterns.variable(), Bootstrap.Core.Patterns.variable())], function(apple, fruits) { + return null; + })); """ assert_translation(ex_ast, js_code) diff --git a/test/translator/match_test.exs b/test/translator/match_test.exs index 88b13a03..639738f6 100644 --- a/test/translator/match_test.exs +++ b/test/translator/match_test.exs @@ -19,20 +19,20 @@ defmodule ElixirScript.Translator.Match.Test do {a, b} = {1, 2} end js_code = """ - let [a, b] = Bootstrap.Core.Patterns.match(Bootstrap.Core.Patterns.type(Bootstrap.Core.Tuple, { - values: [Bootstrap.Core.Patterns.variable(), Bootstrap.Core.Patterns.variable()] - }), new Bootstrap.Core.Tuple(1, 2)); - let _ref = new Bootstrap.Core.Tuple(a, b); + let [a, b] = Bootstrap.Core.Patterns.match( + new Bootstrap.Core.Tuple( + Bootstrap.Core.Patterns.variable(), + Bootstrap.Core.Patterns.variable() + ), + new Bootstrap.Core.Tuple(1, 2) + ); """ assert_translation(ex_ast, js_code) ex_ast = quote do: {a, _, c} = {1, 2, 3} js_code = """ - let [a, __ignored__, c] = Bootstrap.Core.Patterns.match(Bootstrap.Core.Patterns.type(Bootstrap.Core.Tuple, { - values: [Bootstrap.Core.Patterns.variable(), Bootstrap.Core.Patterns.variable(), Bootstrap.Core.Patterns.variable()] - }), new Bootstrap.Core.Tuple(1, 2, 3)); - let _ref = new Bootstrap.Core.Tuple(a, __ignored__, c); + let [a, __ignored__, c] = Bootstrap.Core.Patterns.match(new Bootstrap.Core.Tuple(Bootstrap.Core.Patterns.variable(), Bootstrap.Core.Patterns.variable(), Bootstrap.Core.Patterns.variable()), new Bootstrap.Core.Tuple(1, 2, 3)); """ assert_translation(ex_ast, js_code) @@ -43,10 +43,7 @@ defmodule ElixirScript.Translator.Match.Test do {^a, _, c} = {1, 2, 3} end js_code = """ - let [, __ignored__, c] = Bootstrap.Core.Patterns.match(Bootstrap.Core.Patterns.type(Bootstrap.Core.Tuple, { - values: [Bootstrap.Core.Patterns.bound(a), Bootstrap.Core.Patterns.variable(), Bootstrap.Core.Patterns.variable()] - }), new Bootstrap.Core.Tuple(1, 2, 3)); - let _ref = new Bootstrap.Core.Tuple(undefined, __ignored__, c); + let [, __ignored__, c] = Bootstrap.Core.Patterns.match(new Bootstrap.Core.Tuple(Bootstrap.Core.Patterns.bound(a), Bootstrap.Core.Patterns.variable(), Bootstrap.Core.Patterns.variable()), new Bootstrap.Core.Tuple(1, 2, 3)); """ assert_translation(ex_ast, js_code) diff --git a/test/translator/pattern_matching_test.exs b/test/translator/pattern_matching_test.exs index 1bebeb22..757c438d 100644 --- a/test/translator/pattern_matching_test.exs +++ b/test/translator/pattern_matching_test.exs @@ -193,10 +193,10 @@ defmodule ElixirScript.Translator.PatternMatching.Test do params = [{:{}, [], [1, {:b, [], Elixir}, 3]}] result = PatternMatching.build_match(params, scope ) expected_result = { - [PatternMatching.type(Primitive.tuple_class, JS.object_expression([JS.property( - JS.identifier("values"), - JS.array_expression([JS.literal(1), PatternMatching.parameter, JS.literal(3)]) - ) ] )) ], + [JS.new_expression( + Primitive.tuple_class(), + [JS.literal(1), PatternMatching.parameter, JS.literal(3)] + )], [JS.identifier("b")] } @@ -205,10 +205,10 @@ defmodule ElixirScript.Translator.PatternMatching.Test do params = [{1, {:b, [], Elixir}}] result = PatternMatching.build_match(params, scope ) expected_result = { - [PatternMatching.type(Primitive.tuple_class, JS.object_expression([JS.property( - JS.identifier("values"), - JS.array_expression([JS.literal(1), PatternMatching.parameter]) - ) ] )) ], + [JS.new_expression( + Primitive.tuple_class(), + [JS.literal(1), PatternMatching.parameter] + )], [JS.identifier("b")] } diff --git a/test/translator/with_test.exs b/test/translator/with_test.exs index 74133f03..58c44375 100644 --- a/test/translator/with_test.exs +++ b/test/translator/with_test.exs @@ -11,16 +11,12 @@ defmodule ElixirScript.Translator.With.Test do end js_code = """ - Bootstrap.Core.SpecialForms._with([Bootstrap.Core.Patterns.type(Bootstrap.Core.Tuple,{ - values: [Symbol.for('ok'), Bootstrap.Core.Patterns.variable()] - }), function() { - return Elixir.ElixirScript.Map.__load(Elixir).fetch(opts,Symbol.for('width')); - }],[Bootstrap.Core.Patterns.type(Bootstrap.Core.Tuple,{ - values: [Symbol.for('ok'), Bootstrap.Core.Patterns.variable()] - }), function(width) { - return Elixir.ElixirScript.Map.__load(Elixir).fetch(opts,Symbol.for('height')); - }],function(width,height) { - return new Bootstrap.Core.Tuple(Symbol.for('ok'),width * height); + Bootstrap.Core.SpecialForms._with([new Bootstrap.Core.Tuple(Symbol.for('ok'), Bootstrap.Core.Patterns.variable()), function() { + return Elixir.ElixirScript.Map.__load(Elixir).fetch(opts, Symbol.for('width')); + }], [new Bootstrap.Core.Tuple(Symbol.for('ok'), Bootstrap.Core.Patterns.variable()), function(width) { + return Elixir.ElixirScript.Map.__load(Elixir).fetch(opts, Symbol.for('height')); + }], function(width, height) { + return new Bootstrap.Core.Tuple(Symbol.for('ok'), width * height); }) """ @@ -37,18 +33,14 @@ defmodule ElixirScript.Translator.With.Test do end js_code = """ - Bootstrap.Core.SpecialForms._with([Bootstrap.Core.Patterns.type(Bootstrap.Core.Tuple,{ - values: [Symbol.for('ok'), Bootstrap.Core.Patterns.variable()] - }), function() { - return Elixir.ElixirScript.Map.__load(Elixir).fetch(opts,Symbol.for('width')); - }],[Bootstrap.Core.Patterns.variable(), function(width) { - return width * 2; - }],[Bootstrap.Core.Patterns.type(Bootstrap.Core.Tuple,{ - values: [Symbol.for('ok'), Bootstrap.Core.Patterns.variable()] - }), function(width,double_width) { - return Elixir.ElixirScript.Map.__load(Elixir).fetch(opts,Symbol.for('height')); - }],function(width,double_width,height) { - return new Bootstrap.Core.Tuple(Symbol.for('ok'),double_width * height); + Bootstrap.Core.SpecialForms._with([new Bootstrap.Core.Tuple(Symbol.for('ok'), Bootstrap.Core.Patterns.variable()), function() { + return Elixir.ElixirScript.Map.__load(Elixir).fetch(opts, Symbol.for('width')); + }], [Bootstrap.Core.Patterns.variable(), function(width) { + return width * 2; + }], [new Bootstrap.Core.Tuple(Symbol.for('ok'), Bootstrap.Core.Patterns.variable()), function(width, double_width) { + return Elixir.ElixirScript.Map.__load(Elixir).fetch(opts, Symbol.for('height')); + }], function(width, double_width, height) { + return new Bootstrap.Core.Tuple(Symbol.for('ok'), double_width * height); }) """ @@ -67,19 +59,15 @@ defmodule ElixirScript.Translator.With.Test do end js_code = """ - Bootstrap.Core.SpecialForms._with([Bootstrap.Core.Patterns.type(Bootstrap.Core.Tuple,{ - values: [Symbol.for('ok'), Bootstrap.Core.Patterns.variable()] - }), function() { - return Elixir.ElixirScript.Map.__load(Elixir).fetch(opts,Symbol.for('width')); - }],[Bootstrap.Core.Patterns.type(Bootstrap.Core.Tuple,{ - values: [Symbol.for('ok'), Bootstrap.Core.Patterns.variable()] - }), function(width) { - return Elixir.ElixirScript.Map.__load(Elixir).fetch(opts,Symbol.for('height')); - }],function(width,height) { - return new Bootstrap.Core.Tuple(Symbol.for('ok'),width * height); - },Bootstrap.Core.Patterns.defmatch(Bootstrap.Core.Patterns.clause([Symbol.for('error')],function() { - return new Bootstrap.Core.Tuple(Symbol.for('error'),Symbol.for('wrong_data')); - }))) + Bootstrap.Core.SpecialForms._with([new Bootstrap.Core.Tuple(Symbol.for('ok'), Bootstrap.Core.Patterns.variable()), function() { + return Elixir.ElixirScript.Map.__load(Elixir).fetch(opts, Symbol.for('width')); + }], [new Bootstrap.Core.Tuple(Symbol.for('ok'), Bootstrap.Core.Patterns.variable()), function(width) { + return Elixir.ElixirScript.Map.__load(Elixir).fetch(opts, Symbol.for('height')); + }], function(width, height) { + return new Bootstrap.Core.Tuple(Symbol.for('ok'), width * height); + }, Bootstrap.Core.Patterns.defmatch(Bootstrap.Core.Patterns.clause([Symbol.for('error')], function() { + return new Bootstrap.Core.Tuple(Symbol.for('error'), Symbol.for('wrong_data')); + }))) """ assert_translation(ex_ast, js_code) From f020aca99a99fd9d4bc7f2f953dcd5fbd0d62d3a Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Tue, 4 Apr 2017 18:52:57 -0500 Subject: [PATCH 067/418] Update struct pattern matching to use object matching instead of type --- .../translator/kernel/special_forms/struct.ex | 4 ++ .../translator/pattern_matching.ex | 10 +-- test/translator/function_test.exs | 44 +++++++----- test/translator/pattern_matching_test.exs | 32 ++++++--- test/translator/try_test.exs | 72 +++++++++++-------- 5 files changed, 99 insertions(+), 63 deletions(-) diff --git a/lib/elixir_script/translator/kernel/special_forms/struct.ex b/lib/elixir_script/translator/kernel/special_forms/struct.ex index 84c5becb..c8af4383 100644 --- a/lib/elixir_script/translator/kernel/special_forms/struct.ex +++ b/lib/elixir_script/translator/kernel/special_forms/struct.ex @@ -6,6 +6,10 @@ defmodule ElixirScript.Translator.Struct do alias ElixirScript.Translator.Map alias ElixirScript.Translator.Identifier + def get_struct_module_name(module_name, env) do + ElixirScript.Translator.State.get_module_name(env.state, Utils.quoted_to_name(module_name)) + end + def get_struct_class(module_name, env) do candiate_module_name = ElixirScript.Translator.State.get_module_name(env.state, Utils.quoted_to_name(module_name)) diff --git a/lib/elixir_script/translator/pattern_matching.ex b/lib/elixir_script/translator/pattern_matching.ex index 6a9be928..d03892b5 100644 --- a/lib/elixir_script/translator/pattern_matching.ex +++ b/lib/elixir_script/translator/pattern_matching.ex @@ -8,6 +8,7 @@ defmodule ElixirScript.Translator.PatternMatching do alias ElixirScript.Translator.Map alias ElixirScript.Translator.Struct alias ElixirScript.Translator.Bitstring + alias ElixirScript.Translator.Utils @patterns JS.member_expression( JS.member_expression( @@ -208,11 +209,12 @@ defmodule ElixirScript.Translator.PatternMatching do { JS.object_expression(List.wrap(props)), params } end - defp do_build_match({:%, _, [{:__aliases__, _, _} = name, {:%{}, meta, props}]}, env) do - struct_name = Struct.get_struct_class(name, env) - {pattern, params} = do_build_match({:%{}, meta, props}, env) + defp do_build_match({:%, _, [{:__aliases__, _, name}, {:%{}, meta, props}]}, env) do + module_name = ElixirScript.Translator.State.get_module_name(env.state, Utils.quoted_to_name(name)) + name = Utils.name_to_js_file_name(module_name) + {pattern, params} = do_build_match({:%{}, meta, [__struct__: String.to_atom(name)] ++ props}, env) - { [type(struct_name, pattern)], params } + { pattern, params } end defp do_build_match({:=, _, [{name, _, _}, right]}, env) when not name in [:%, :{}, :__aliases__, :^, :%{}] do diff --git a/test/translator/function_test.exs b/test/translator/function_test.exs index 2f6e6764..eb9e145e 100644 --- a/test/translator/function_test.exs +++ b/test/translator/function_test.exs @@ -449,9 +449,11 @@ defmodule ElixirScript.Translator.Function.Test do js_code = """ - const something = Bootstrap.Core.Patterns.defmatch(Bootstrap.Core.Patterns.clause([Bootstrap.Core.Patterns.type(Elixir.AStruct.__load(Elixir).Elixir$AStruct, {})], function() { - return null; - })); + const something = Bootstrap.Core.Patterns.defmatch(Bootstrap.Core.Patterns.clause([{ + [Symbol.for('__struct__')]: Symbol.for('Elixir.AStruct') + }], function() { + return null; + })); """ assert_translation(ex_ast, js_code) @@ -469,9 +471,11 @@ defmodule ElixirScript.Translator.Function.Test do end js_code = """ - const something = Bootstrap.Core.Patterns.defmatch(Bootstrap.Core.Patterns.clause([Bootstrap.Core.Patterns.capture(Bootstrap.Core.Patterns.type(Elixir.AStruct.__load(Elixir).Elixir$AStruct, {}))], function(a) { - return null; - })); + const something = Bootstrap.Core.Patterns.defmatch(Bootstrap.Core.Patterns.clause([Bootstrap.Core.Patterns.capture({ + [Symbol.for('__struct__')]: Symbol.for('Elixir.AStruct') + })], function(a) { + return null; + })); """ assert_translation(ex_ast, js_code) end @@ -505,11 +509,13 @@ defmodule ElixirScript.Translator.Function.Test do js_code = """ - const something = Bootstrap.Core.Patterns.defmatch(Bootstrap.Core.Patterns.clause([Bootstrap.Core.Patterns.type(Elixir.AStruct.__load(Elixir).Elixir$AStruct, { - [Symbol.for('key')]: Bootstrap.Core.Patterns.variable(), [Symbol.for('key1')]: 2 - })], function(value) { - return null; - })); + const something = Bootstrap.Core.Patterns.defmatch(Bootstrap.Core.Patterns.clause([{ + [Symbol.for('__struct__')]: Symbol.for('Elixir.AStruct'), + [Symbol.for('key')]: Bootstrap.Core.Patterns.variable(), + [Symbol.for('key1')]: 2 + }], function(value) { + return null; + })); """ assert_translation(ex_ast, js_code) @@ -525,13 +531,15 @@ defmodule ElixirScript.Translator.Function.Test do js_code = """ - const something = Bootstrap.Core.Patterns.defmatch(Bootstrap.Core.Patterns.clause([Bootstrap.Core.Patterns.type(Elixir.AStruct.__load(Elixir).Elixir$AStruct, { - [Symbol.for('key')]: Bootstrap.Core.Patterns.variable(), [Symbol.for('key1')]: 2 - })], function(value) { - return null; - }, function(value) { - return Elixir.ElixirScript.Kernel.__load(Elixir).is_number(value); - })); + const something = Bootstrap.Core.Patterns.defmatch(Bootstrap.Core.Patterns.clause([{ + [Symbol.for('__struct__')]: Symbol.for('Elixir.AStruct'), + [Symbol.for('key')]: Bootstrap.Core.Patterns.variable(), + [Symbol.for('key1')]: 2 + }], function(value) { + return null; + }, function(value) { + return Elixir.ElixirScript.Kernel.__load(Elixir).is_number(value); + })); """ assert_translation(ex_ast, js_code) diff --git a/test/translator/pattern_matching_test.exs b/test/translator/pattern_matching_test.exs index 757c438d..75598bc6 100644 --- a/test/translator/pattern_matching_test.exs +++ b/test/translator/pattern_matching_test.exs @@ -112,7 +112,11 @@ defmodule ElixirScript.Translator.PatternMatching.Test do params = [{:%, [], [{:__aliases__, [alias: false], [:Hello]}, {:%{}, [], []}]}] result = PatternMatching.build_match(params, scope ) expected_result = { - [PatternMatching.type(JS.identifier("Hello"), JS.object_expression([]))], + [JS.object_expression([ + JS.property(Primitive.make_atom(:__struct__), + Primitive.make_atom(Hello), + :init, false, false, true), + ])], [] } @@ -123,10 +127,12 @@ defmodule ElixirScript.Translator.PatternMatching.Test do params = [{:%, [], [{:__aliases__, [alias: false], [:Hello]}, {:%{}, [], [key: 1]}]}] result = PatternMatching.build_match(params, scope ) expected_result = { - [PatternMatching.type(JS.identifier("Hello"), JS.object_expression([ - Map.make_property(Translator.translate!(:key, scope ), Translator.translate!(1, scope )) - ])) - ], + [JS.object_expression([ + JS.property(Primitive.make_atom(:__struct__), + Primitive.make_atom(Hello), + :init, false, false, true), + Map.make_property(Translator.translate!(:key, scope ), Translator.translate!(1, scope)) + ])], [] } @@ -137,10 +143,12 @@ defmodule ElixirScript.Translator.PatternMatching.Test do params = [{:%, [], [{:__aliases__, [alias: false], [:Hello]}, {:%{}, [], [key: {:key, [], Elixir}]}]}] result = PatternMatching.build_match(params, scope ) expected_result = { - [PatternMatching.type(JS.identifier("Hello"), JS.object_expression([ - Map.make_property(Translator.translate!(:key, scope ), PatternMatching.parameter) - ])) - ], + [JS.object_expression([ + JS.property(Primitive.make_atom(:__struct__), + Primitive.make_atom(Hello), + :init, false, false, true), + Map.make_property(Translator.translate!(:key, scope ), PatternMatching.parameter()) + ])], [JS.identifier("key")] } @@ -171,7 +179,11 @@ defmodule ElixirScript.Translator.PatternMatching.Test do params = [{:=, [], [{:%, [], [{:__aliases__, [alias: false], [:AStruct]}, {:%{}, [], []}]}, {:a, [], ElixirScript.Translator.Function.Test}]}] result = PatternMatching.build_match(params, scope ) expected_result = { - [PatternMatching.capture(PatternMatching.type(JS.identifier("AStruct"), JS.object_expression([])))], + [PatternMatching.capture(JS.object_expression([ + JS.property(Primitive.make_atom(:__struct__), + Primitive.make_atom(AStruct), + :init, false, false, true), + ]))], [JS.identifier("a")] } diff --git a/test/translator/try_test.exs b/test/translator/try_test.exs index 645e73ec..868a03b2 100644 --- a/test/translator/try_test.exs +++ b/test/translator/try_test.exs @@ -13,11 +13,13 @@ defmodule ElixirScript.Translator.Try.Test do end js_code = """ - Bootstrap.Core.SpecialForms._try(function() { - return 1; - }, Bootstrap.Core.Patterns.defmatch(Bootstrap.Core.Patterns.clause([Bootstrap.Core.Patterns.type(ArgumentError, {})], function() { - return Elixir.ElixirScript.IO.__load(Elixir).puts('Invalid argument given'); - })), null, null, null) + Bootstrap.Core.SpecialForms._try(function() { + return 1; + }, Bootstrap.Core.Patterns.defmatch(Bootstrap.Core.Patterns.clause([{ + [Symbol.for('__struct__')]: Symbol.for('Elixir.ArgumentError') + }], function() { + return Elixir.ElixirScript.IO.__load(Elixir).puts('Invalid argument given'); + })), null, null, null) """ assert_translation(ex_ast, js_code) @@ -35,11 +37,13 @@ defmodule ElixirScript.Translator.Try.Test do end js_code = """ - Bootstrap.Core.SpecialForms._try(function() { - return 1; - }, Bootstrap.Core.Patterns.defmatch(Bootstrap.Core.Patterns.clause([Bootstrap.Core.Patterns.type(ArgumentError, {})], function() { - return Elixir.ElixirScript.IO.__load(Elixir).puts('Invalid argument given'); - })), null, null, null) + Bootstrap.Core.SpecialForms._try(function() { + return 1; + }, Bootstrap.Core.Patterns.defmatch(Bootstrap.Core.Patterns.clause([{ + [Symbol.for('__struct__')]: Symbol.for('Elixir.ArgumentError') + }], function() { + return Elixir.ElixirScript.IO.__load(Elixir).puts('Invalid argument given'); + })), null, null, null) """ assert_translation(ex_ast, js_code) @@ -106,13 +110,15 @@ defmodule ElixirScript.Translator.Try.Test do end js_code = """ - Bootstrap.Core.SpecialForms._try(function() { - return 1; - }, Bootstrap.Core.Patterns.defmatch(Bootstrap.Core.Patterns.clause([Bootstrap.Core.Patterns.type(ArgumentError, {})], function() { - return Elixir.ElixirScript.IO.__load(Elixir).puts('ArgumentError'); - }), Bootstrap.Core.Patterns.clause([Bootstrap.Core.Patterns.variable()], function(x) { - return Elixir.ElixirScript.IO.__load(Elixir).puts('x'); - })), null, null, null) + Bootstrap.Core.SpecialForms._try(function() { + return 1; + }, Bootstrap.Core.Patterns.defmatch(Bootstrap.Core.Patterns.clause([{ + [Symbol.for('__struct__')]: Symbol.for('Elixir.ArgumentError') + }], function() { + return Elixir.ElixirScript.IO.__load(Elixir).puts('ArgumentError'); + }), Bootstrap.Core.Patterns.clause([Bootstrap.Core.Patterns.variable()], function(x) { + return Elixir.ElixirScript.IO.__load(Elixir).puts('x'); + })), null, null, null) """ assert_translation(ex_ast, js_code) @@ -132,13 +138,15 @@ defmodule ElixirScript.Translator.Try.Test do end js_code = """ - Bootstrap.Core.SpecialForms._try(function() { - return 1; - }, Bootstrap.Core.Patterns.defmatch(Bootstrap.Core.Patterns.clause([Bootstrap.Core.Patterns.type(ArgumentError, {})], function() { - return Elixir.ElixirScript.IO.__load(Elixir).puts('Invalid argument given'); - })), null, null, function() { - return Elixir.ElixirScript.IO.__load(Elixir).puts('This is printed regardless if it failed or succeed'); - }) + Bootstrap.Core.SpecialForms._try(function() { + return 1; + }, Bootstrap.Core.Patterns.defmatch(Bootstrap.Core.Patterns.clause([{ + [Symbol.for('__struct__')]: Symbol.for('Elixir.ArgumentError') + }], function() { + return Elixir.ElixirScript.IO.__load(Elixir).puts('Invalid argument given'); + })), null, null, function() { + return Elixir.ElixirScript.IO.__load(Elixir).puts('This is printed regardless if it failed or succeed'); + }) """ assert_translation(ex_ast, js_code) @@ -207,13 +215,15 @@ defmodule ElixirScript.Translator.Try.Test do end js_code = """ - Bootstrap.Core.SpecialForms._try(function() { - return 1; - }, Bootstrap.Core.Patterns.defmatch(Bootstrap.Core.Patterns.clause([Bootstrap.Core.Patterns.type(ArgumentError, {})], function() { - return Elixir.ElixirScript.IO.__load(Elixir).puts('Invalid argument given'); - })), Bootstrap.Core.Patterns.defmatch(Bootstrap.Core.Patterns.clause([Symbol.for('throw'), Symbol.for('Error')], function() { - return Elixir.ElixirScript.IO.__load(Elixir).puts('caught error'); - })), null, null) + Bootstrap.Core.SpecialForms._try(function() { + return 1; + }, Bootstrap.Core.Patterns.defmatch(Bootstrap.Core.Patterns.clause([{ + [Symbol.for('__struct__')]: Symbol.for('Elixir.ArgumentError') + }], function() { + return Elixir.ElixirScript.IO.__load(Elixir).puts('Invalid argument given'); + })), Bootstrap.Core.Patterns.defmatch(Bootstrap.Core.Patterns.clause([Symbol.for('throw'), Symbol.for('Error')], function() { + return Elixir.ElixirScript.IO.__load(Elixir).puts('caught error'); + })), null, null) """ assert_translation(ex_ast, js_code) From 9e67c1a0f8af83fe3f4d6d623586e5b4f2a3a9db Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Wed, 5 Apr 2017 07:08:09 -0500 Subject: [PATCH 068/418] Update incorrect function calls found by compiler --- lib/elixir_script/translator.ex | 2 +- lib/elixir_script/translator/kernel/special_forms/call.ex | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/elixir_script/translator.ex b/lib/elixir_script/translator.ex index 5187266e..ae8e0f49 100644 --- a/lib/elixir_script/translator.ex +++ b/lib/elixir_script/translator.ex @@ -646,7 +646,7 @@ defmodule ElixirScript.Translator do { Identifier.make_identifier(name), env } has_function?(env.module, {name, 0}, env) -> - Call.make_function_call(name, [], env) + Call.make_local_function_call(name, [], env) ElixirScript.Translator.LexicalScope.find_module(env, {name, 0}) -> imported_module_name = ElixirScript.Translator.LexicalScope.find_module(env, {name, 0}) Call.make_module_function_call(imported_module_name, name, params, env) diff --git a/lib/elixir_script/translator/kernel/special_forms/call.ex b/lib/elixir_script/translator/kernel/special_forms/call.ex index 9990624d..2356c5a6 100644 --- a/lib/elixir_script/translator/kernel/special_forms/call.ex +++ b/lib/elixir_script/translator/kernel/special_forms/call.ex @@ -105,7 +105,7 @@ defmodule ElixirScript.Translator.Call do JS.identifier("call_property") ), [ - Translator.translate!(module_name), + Translator.translate!(module_name, env), Translator.translate!(to_string(function_name), env) ] ) From db2f827957a25292410752b03075cd3d8e7a0db1 Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Wed, 5 Apr 2017 22:55:32 -0500 Subject: [PATCH 069/418] Update struct implementation to not use classes --- lib/elixir_script/translator.ex | 16 ++- .../translator/kernel/defmodule.ex | 20 +-- .../translator/kernel/special_forms/map.ex | 18 ++- .../translator/kernel/special_forms/struct.ex | 107 +++++++++++++++ priv/std_lib/map.ex | 3 +- test/prelude/kernel_test.exs | 2 +- test/translator/defmodule_test.exs | 43 +++++- test/translator/map_test.exs | 4 +- test/translator/struct_test.exs | 122 ++++++++++++------ test/translator/try_test.exs | 2 +- 10 files changed, 272 insertions(+), 65 deletions(-) diff --git a/lib/elixir_script/translator.ex b/lib/elixir_script/translator.ex index ae8e0f49..0001e8e9 100644 --- a/lib/elixir_script/translator.ex +++ b/lib/elixir_script/translator.ex @@ -219,7 +219,13 @@ defmodule ElixirScript.Translator do end defp do_translate({:%, _, [alias_info, data]}, env) do - { Struct.new_struct(alias_info, data, env), env } + module = case create_module_name(alias_info, env) do + {module, _} -> + module + module -> + module + end + Call.make_module_function_call(module, :__struct__, [data], env) end defp do_translate({:%{}, _, [{:|, _, [map, data]}]}, env) do @@ -541,12 +547,12 @@ defmodule ElixirScript.Translator do Def.process_delegate(name, params, options, env) end - defp do_translate({:defstruct, _, attributes}, env) do - { Struct.make_defstruct(attributes, env), env } + defp do_translate({:defstruct, _, [attributes]}, env) do + { Struct.make_struct(attributes, env), env } end - defp do_translate({:defexception, _, attributes}, env) do - { Struct.make_defexception(attributes, env), env } + defp do_translate({:defexception, _, [attributes]}, env) do + { Struct.make_struct(attributes ++ [__exception__: true], env), env } end defp do_translate({:defmodule, _, [{:__aliases__, _, module_name_list}, [do: body]]}, env) do diff --git a/lib/elixir_script/translator/kernel/defmodule.ex b/lib/elixir_script/translator/kernel/defmodule.ex index 285eab4b..dd2c76ba 100644 --- a/lib/elixir_script/translator/kernel/defmodule.ex +++ b/lib/elixir_script/translator/kernel/defmodule.ex @@ -51,7 +51,11 @@ defmodule ElixirScript.Translator.Defmodule do { exported_functions, private_functions } = process_functions(functions, env) - {structs, body} = extract_structs_from_body(body, env) + struct_prop = if has_struct?(body) do + [JS.property(Identifier.make_identifier("__struct__"), Identifier.make_identifier("__struct__"), :init, true)] + else + [] + end body = Enum.map(body, fn(x) -> case x do @@ -65,7 +69,7 @@ defmodule ElixirScript.Translator.Defmodule do body = Group.inflate_groups(body) exported_object = JS.object_expression( - make_defstruct_property(module, structs) ++ + struct_prop ++ Enum.map(exported_functions, fn({key, _value}) -> JS.property(Identifier.make_identifier(key), Identifier.make_identifier(key), :init, true) end) @@ -74,7 +78,7 @@ defmodule ElixirScript.Translator.Defmodule do exported_functions = Enum.map(exported_functions, fn({_key, value}) -> value end) private_functions = Enum.map(private_functions, fn({_key, value}) -> value end) - body = structs ++ private_functions ++ exported_functions ++ body + body = private_functions ++ exported_functions ++ body {body, exported_object} end @@ -161,17 +165,17 @@ defmodule ElixirScript.Translator.Defmodule do end) end - def extract_structs_from_body(body, env) do - module_js_name = Utils.name_to_js_name(env.module) - - Enum.partition(body, fn(x) -> + def has_struct?(body) do + val = Enum.find(body, fn(x) -> case x do - %ESTree.VariableDeclaration{declarations: [%ESTree.VariableDeclarator{id: %ESTree.Identifier{name: ^module_js_name} } ] } -> + %ESTree.VariableDeclaration{declarations: [%ESTree.VariableDeclarator{id: %ESTree.Identifier{name: "__struct__"} } ] } -> true _ -> false end end) + + val != nil end defp make_defstruct_property(_, []) do diff --git a/lib/elixir_script/translator/kernel/special_forms/map.ex b/lib/elixir_script/translator/kernel/special_forms/map.ex index 02f17691..77e4382b 100644 --- a/lib/elixir_script/translator/kernel/special_forms/map.ex +++ b/lib/elixir_script/translator/kernel/special_forms/map.ex @@ -67,10 +67,22 @@ defmodule ElixirScript.Translator.Map do js_ast = JS.call_expression( JS.member_expression( - Primitive.special_forms(), - JS.identifier("map_update") + JS.identifier("Object"), + JS.identifier("freeze") ), - [map, data] + [ + JS.call_expression( + JS.member_expression( + JS.identifier("Object"), + JS.identifier("assign") + ), + [ + JS.object_expression([]), + map, + data + ] + ) + ] ) { js_ast, env } diff --git a/lib/elixir_script/translator/kernel/special_forms/struct.ex b/lib/elixir_script/translator/kernel/special_forms/struct.ex index c8af4383..ad3c50d7 100644 --- a/lib/elixir_script/translator/kernel/special_forms/struct.ex +++ b/lib/elixir_script/translator/kernel/special_forms/struct.ex @@ -139,4 +139,111 @@ defmodule ElixirScript.Translator.Struct do JS.variable_declaration([ref_declarator], :const) end + def make_struct(attributes, env) do + struct_name = Map.make_property(Translator.translate!(:__struct__, env), Translator.translate!({:__MODULE__, [], []}, env)) + + defaults = Enum.map(attributes, fn + ({x, y}) -> + Map.make_property( + Translator.translate!(x, env), + Translator.translate!(y, env) + ) + (x) -> + Map.make_property( + Translator.translate!(x, env), + Translator.translate!(nil, env) + ) + end) + + keys = Enum.map(attributes, fn + ({x, _}) -> + Translator.translate!(x, env) + (x) -> + Translator.translate!(x, env) + end) + + keys = JS.array_expression(keys) + defaults = JS.object_expression([struct_name] ++ defaults) + + allowed_keys = JS.variable_declaration([JS.variable_declarator( + JS.identifier("allowed_keys"), + keys + )], :const) + + value_keys = JS.variable_declaration([JS.variable_declarator( + JS.identifier("value_keys"), + JS.call_expression( + JS.member_expression( + JS.identifier("Object"), + JS.identifier("keys") + ), + [JS.identifier("values")] + ) + )], :const) + + every_call = JS.call_expression( + JS.member_expression( + JS.identifier("value_keys"), + JS.identifier("every") + ), + [ + JS.function_expression([JS.identifier("key")], [], JS.block_statement([ + JS.return_statement( + JS.call_expression( + JS.member_expression( + JS.identifier("allowed_keys"), + JS.identifier("includes") + ), + [JS.identifier("key")] + ) + ) + ])) + ] + ) + + every_call_result = JS.variable_declaration([JS.variable_declarator( + JS.identifier("every_call_result"), + every_call + )], :const) + + bottom = JS.if_statement( + JS.identifier("every_call_result"), + JS.block_statement([ + JS.return_statement( + JS.call_expression( + JS.member_expression( + JS.identifier("Object"), + JS.identifier("assign") + ), + [JS.object_expression([]), defaults, JS.identifier("values")] + ) + ) + ]), + JS.block_statement([ + JS.throw_statement( + JS.literal("Unallowed key found") + ) + ]) + ) + + func = JS.function_expression([ + %ESTree.AssignmentPattern{ + left: JS.identifier("values"), + right: JS.object_expression([]) + } + ], + [], + JS.block_statement([ + allowed_keys, + value_keys, + every_call_result, + bottom + ])) + + JS.variable_declaration([JS.variable_declarator( + JS.identifier("__struct__"), + func + )], :const) + end + end diff --git a/priv/std_lib/map.ex b/priv/std_lib/map.ex index 2fca8243..b8e48707 100644 --- a/priv/std_lib/map.ex +++ b/priv/std_lib/map.ex @@ -70,7 +70,8 @@ defmodule ElixirScript.Map do end def merge(map1, map2) do - Bootstrap.Core.SpecialForms.map_update(map1, map2) + JS.Object.assign(%{}, map1, map2) + |> JS.Object.freeze() end def split(map, keys) do diff --git a/test/prelude/kernel_test.exs b/test/prelude/kernel_test.exs index c080a158..e134c61e 100644 --- a/test/prelude/kernel_test.exs +++ b/test/prelude/kernel_test.exs @@ -9,7 +9,7 @@ defmodule ElixirScript.Lib.Elixir.Kernel.Test do js_code = """ - Elixir.ElixirScript.Range.__load(Elixir).Elixir$ElixirScript$Range.create(Object.freeze({ + Elixir.ElixirScript.Range.__load(Elixir).__struct__(Object.freeze({ [Symbol.for('first')]: 1, [Symbol.for('last')]: 4 })) diff --git a/test/translator/defmodule_test.exs b/test/translator/defmodule_test.exs index acc965e7..6d7c8b45 100644 --- a/test/translator/defmodule_test.exs +++ b/test/translator/defmodule_test.exs @@ -68,9 +68,24 @@ defmodule ElixirScript.Translator.Defmodule.Test do end js_code = """ - const Elixir$Animals$Elephant = Bootstrap.Core.Functions.defstruct({ - [Symbol.for('__struct__')]: Symbol.for('Elixir.Animals.Elephant'), [Symbol.for('trunk')]: true - }); + const __struct__ = function(values = {}) { + const allowed_keys = [Symbol.for('trunk')] + + const value_keys = Object.keys(values) + + const every_call_result = value_keys.every(function(key) { + return allowed_keys.includes(key); + }) + + if (every_call_result) { + return Object.assign({}, { + [Symbol.for('__struct__')]: Symbol.for('Elixir.Animals.Elephant'), + [Symbol.for('trunk')]: true + }, values); + } else { + throw 'Unallowed key found'; + } + }; """ assert_translation(ex_ast, js_code) @@ -101,10 +116,24 @@ defmodule ElixirScript.Translator.Defmodule.Test do end js_code = """ - const Elixir$Animals$Elephant$Bear = Bootstrap.Core.Functions.defstruct({ - [Symbol.for('__struct__')]: Symbol.for('Elixir.Animals.Elephant.Bear'), - [Symbol.for('trunk')]: true - }); + const __struct__ = function(values = {}) { + const allowed_keys = [Symbol.for('trunk')] + + const value_keys = Object.keys(values) + + const every_call_result = value_keys.every(function(key) { + return allowed_keys.includes(key); + }) + + if (every_call_result) { + return Object.assign({}, { + [Symbol.for('__struct__')]: Symbol.for('Elixir.Animals.Elephant.Bear'), + [Symbol.for('trunk')]: true + }, values); + } else { + throw 'Unallowed key found'; + } + }; """ assert_translation(ex_ast, js_code) diff --git a/test/translator/map_test.exs b/test/translator/map_test.exs index 75a237d5..8c49fcb6 100644 --- a/test/translator/map_test.exs +++ b/test/translator/map_test.exs @@ -49,9 +49,9 @@ defmodule ElixirScript.Translator.Map.Test do end js_code = """ - Bootstrap.Core.SpecialForms.map_update(map,Object.freeze({ + Object.freeze(Object.assign({}, map, Object.freeze({ [Symbol.for('value')]: 1 - })) + }))) """ assert_translation(ex_ast, js_code) diff --git a/test/translator/struct_test.exs b/test/translator/struct_test.exs index dcc07631..e02a9d60 100644 --- a/test/translator/struct_test.exs +++ b/test/translator/struct_test.exs @@ -10,11 +10,25 @@ defmodule ElixirScript.Translator.Struct.Test do end js_code = """ - const Elixir$User = Bootstrap.Core.Functions.defstruct({ - [Symbol.for('__struct__')]: Symbol.for('Elixir.User'), - [Symbol.for('name')]: 'john', - [Symbol.for('age')]: 27 - }); + const __struct__ = function(values = {}) { + const allowed_keys = [Symbol.for('name'), Symbol.for('age')] + + const value_keys = Object.keys(values) + + const every_call_result = value_keys.every(function(key) { + return allowed_keys.includes(key); + }) + + if (every_call_result) { + return Object.assign({}, { + [Symbol.for('__struct__')]: Symbol.for('Elixir.User'), + [Symbol.for('name')]: 'john', + [Symbol.for('age')]: 27 + }, values); + } else { + throw 'Unallowed key found'; + } + }; """ assert_translation(ex_ast, js_code) @@ -29,11 +43,25 @@ defmodule ElixirScript.Translator.Struct.Test do end js_code = """ - const Elixir$User = Bootstrap.Core.Functions.defstruct({ - [Symbol.for('__struct__')]: Symbol.for('Elixir.User'), - [Symbol.for('name')]: null, - [Symbol.for('age')]: null - }); + const __struct__ = function(values = {}) { + const allowed_keys = [Symbol.for('name'), Symbol.for('age')] + + const value_keys = Object.keys(values) + + const every_call_result = value_keys.every(function(key) { + return allowed_keys.includes(key); + }) + + if (every_call_result) { + return Object.assign({}, { + [Symbol.for('__struct__')]: Symbol.for('Elixir.User'), + [Symbol.for('name')]: null, + [Symbol.for('age')]: null + }, values); + } else { + throw 'Unallowed key found'; + } + }; """ assert_translation(ex_ast, js_code) @@ -50,11 +78,7 @@ defmodule ElixirScript.Translator.Struct.Test do end js_code = """ - const Elixir$User = Bootstrap.Core.Functions.defstruct({ - [Symbol.for('__struct__')]: Symbol.for('Elixir.User'), - [Symbol.for('name')]: null, - [Symbol.for('age')]: null - }); + Elixir.User.__load(Elixir).__struct__(Object.freeze({}) """ assert_translation(ex_ast, js_code) @@ -68,12 +92,7 @@ defmodule ElixirScript.Translator.Struct.Test do end js_code = """ - const Elixir$User = Bootstrap.Core.Functions.defstruct({ - [Symbol.for('__struct__')]: Symbol.for('Elixir.User'), - [Symbol.for('name')]: null, - [Symbol.for('age')]: null - }); - + Elixir.User.__load(Elixir).__struct__(Object.freeze({[Symbol.for('name')]: 'John'}) """ assert_translation(ex_ast, js_code) @@ -86,9 +105,9 @@ defmodule ElixirScript.Translator.Struct.Test do end js_code = """ - let [user] = Bootstrap.Core.Patterns.match(Bootstrap.Core.Patterns.variable(),Bootstrap.Core.SpecialForms.map_update(map,Object.freeze({ - [Symbol.for('key')]: 1 - }))); + let [user] = Bootstrap.Core.Patterns.match(Bootstrap.Core.Patterns.variable(), Object.freeze(Object.assign({}, map, Object.freeze({ + [Symbol.for('key')]: 1 + })))); """ assert_translation(ex_ast, js_code) @@ -100,9 +119,10 @@ defmodule ElixirScript.Translator.Struct.Test do end js_code = """ - let [user] = Bootstrap.Core.Patterns.match(Bootstrap.Core.Patterns.variable(),Bootstrap.Core.SpecialForms.map_update(map,Object.freeze({ - [Symbol.for('key')]: 1, [Symbol.for('key1')]: 11 - }))); + let [user] = Bootstrap.Core.Patterns.match(Bootstrap.Core.Patterns.variable(), Object.freeze(Object.assign({}, map, Object.freeze({ + [Symbol.for('key')]: 1, + [Symbol.for('key1')]: 11 + })))); """ assert_translation(ex_ast, js_code) @@ -116,11 +136,25 @@ defmodule ElixirScript.Translator.Struct.Test do end js_code = """ - const Elixir$MyAppError = Bootstrap.Core.Functions.defexception({ - [Symbol.for('__struct__')]: Symbol.for('Elixir.MyAppError'), - [Symbol.for('__exception__')]: true, - [Symbol.for('message')]: 'This is a message' - }); + const __struct__ = function(values = {}) { + const allowed_keys = [Symbol.for('message'), Symbol.for('__exception__')] + + const value_keys = Object.keys(values) + + const every_call_result = value_keys.every(function(key) { + return allowed_keys.includes(key); + }) + + if (every_call_result) { + return Object.assign({}, { + [Symbol.for('__struct__')]: Symbol.for('Elixir.MyAppError'), + [Symbol.for('message')]: 'This is a message', + [Symbol.for('__exception__')]: true + }, values); + } else { + throw 'Unallowed key found'; + } + }; """ assert_translation(ex_ast, js_code) @@ -132,11 +166,25 @@ defmodule ElixirScript.Translator.Struct.Test do end js_code = """ - const Elixir$MyAppError = Bootstrap.Core.Functions.defexception({ - [Symbol.for('__struct__')]: Symbol.for('Elixir.MyAppError'), - [Symbol.for('__exception__')]: true, - [Symbol.for('message')]: null - }); + const __struct__ = function(values = {}) { + const allowed_keys = [Symbol.for('message'), Symbol.for('__exception__')] + + const value_keys = Object.keys(values) + + const every_call_result = value_keys.every(function(key) { + return allowed_keys.includes(key); + }) + + if (every_call_result) { + return Object.assign({}, { + [Symbol.for('__struct__')]: Symbol.for('Elixir.MyAppError'), + [Symbol.for('message')]: null, + [Symbol.for('__exception__')]: true + }, values); + } else { + throw 'Unallowed key found'; + } + }; """ assert_translation(ex_ast, js_code) diff --git a/test/translator/try_test.exs b/test/translator/try_test.exs index 868a03b2..951f5d65 100644 --- a/test/translator/try_test.exs +++ b/test/translator/try_test.exs @@ -66,7 +66,7 @@ defmodule ElixirScript.Translator.Try.Test do },Bootstrap.Core.Patterns.defmatch(Bootstrap.Core.Patterns.clause([Bootstrap.Core.Patterns.variable()],function(x) { return Elixir.ElixirScript.IO.__load(Elixir).puts('Invalid argument given'); },function(x) { - return Elixir.ElixirScript.Bootstrap.Functions.__load(Elixir).contains(x,Object.freeze([ArgumentError.create(Object.freeze({}))])); + return Elixir.ElixirScript.Bootstrap.Functions.__load(Elixir).contains(x, Object.freeze([Elixir.ArgumentError.__load(Elixir).__struct__(Object.freeze({}))])); })),null,null,null) """ From 76bb6f85bc88abef617e814dd63753a0d0f91643 Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Wed, 5 Apr 2017 22:57:00 -0500 Subject: [PATCH 070/418] Remove js implementations of structs and map update --- src/javascript/lib/core/functions.js | 38 ------------------------ src/javascript/lib/core/special_forms.js | 6 ---- 2 files changed, 44 deletions(-) diff --git a/src/javascript/lib/core/functions.js b/src/javascript/lib/core/functions.js index 52a34def..f6d0e2df 100644 --- a/src/javascript/lib/core/functions.js +++ b/src/javascript/lib/core/functions.js @@ -64,42 +64,6 @@ function get_global() { throw new Error('No global state found'); } -function defstruct(defaults) { - return class { - constructor(update = {}) { - const the_values = Object.assign(defaults, update); - Object.assign(this, the_values); - } - - static create(updates = {}) { - const x = new this(updates); - return Object.freeze(x); - } - }; -} - -function defexception(defaults) { - return class extends Error { - constructor(update = {}) { - const message = update.message || ''; - super(message); - - const the_values = Object.assign(defaults, update); - Object.assign(this, the_values); - - this.name = this.constructor.name; - this.message = message; - this[Symbol.for('__exception__')] = true; - Error.captureStackTrace(this, this.constructor.name); - } - - static create(updates = {}) { - const x = new this(updates); - return Object.freeze(x); - } - }; -} - function defprotocol(spec) { return new Protocol(spec); } @@ -134,8 +98,6 @@ function build_namespace(ns, ns_string) { export default { call_property, get_global, - defstruct, - defexception, defprotocol, defimpl, build_namespace, diff --git a/src/javascript/lib/core/special_forms.js b/src/javascript/lib/core/special_forms.js index e308ddf7..a449bbe8 100644 --- a/src/javascript/lib/core/special_forms.js +++ b/src/javascript/lib/core/special_forms.js @@ -14,12 +14,6 @@ function cond(clauses) { throw new Error(); } -function map_update(map, values) { - return Object.freeze( - Object.assign(Object.create(map.constructor.prototype), map, values), - ); -} - function _for(expression, generators, collectable_protocol, into = []) { let [result, fun] = collectable_protocol.into(into); From b806f991fb8bb8a4d256f7b3e991750025f938fb Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Wed, 5 Apr 2017 22:57:23 -0500 Subject: [PATCH 071/418] Remove map_update export --- src/javascript/lib/core/special_forms.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/javascript/lib/core/special_forms.js b/src/javascript/lib/core/special_forms.js index a449bbe8..7be8c643 100644 --- a/src/javascript/lib/core/special_forms.js +++ b/src/javascript/lib/core/special_forms.js @@ -144,7 +144,6 @@ function _with(...args) { export default { _case, cond, - map_update, _for, _try, _with, From e1026bc31fa1a937784c58bcfa2fc1a0393b3716 Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Thu, 6 Apr 2017 21:48:32 -0500 Subject: [PATCH 072/418] Fix struct tests. Add js tests to test struct creation --- lib/elixir_script/translator.ex | 36 ++++- .../translator/kernel/defimpl.ex | 12 +- .../translator/kernel/special_forms/struct.ex | 133 ------------------ .../translator/kernel/special_forms/try.ex | 17 ++- lib/elixir_script/translator/state.ex | 1 + priv/std_lib/exceptions.ex | 3 + src/javascript/lib/core/protocol.js | 6 + test/app/spec/exception.spec.js | 51 +++++++ test/app/spec/struct.spec.js | 24 ++++ test/app/src/user.ex | 7 + test/translator/kernel_test.exs | 4 +- test/translator/struct_test.exs | 2 +- test/translator/try_test.exs | 12 +- 13 files changed, 148 insertions(+), 160 deletions(-) create mode 100644 priv/std_lib/exceptions.ex create mode 100644 test/app/spec/exception.spec.js create mode 100644 test/app/spec/struct.spec.js create mode 100644 test/app/src/user.ex diff --git a/lib/elixir_script/translator.ex b/lib/elixir_script/translator.ex index 0001e8e9..bcc20064 100644 --- a/lib/elixir_script/translator.ex +++ b/lib/elixir_script/translator.ex @@ -353,7 +353,15 @@ defmodule ElixirScript.Translator do end defp do_translate({:__MODULE__, _, _ }, env) do - translate(env.module, env) + module_name = create_module_name(env.module, env) + mod = case module_name do + {mod, _} -> + mod + mod -> + mod + end + + translate(mod, env) end defp do_translate({:__block__, _, expressions }, env) do @@ -584,17 +592,31 @@ defmodule ElixirScript.Translator do end defp do_translate({:raise, _, [alias_info, attributes]}, env) when is_list(attributes) do - js_ast = JS.throw_statement( - Struct.new_struct(alias_info, {:%{}, [], attributes }, env) - ) + module = case create_module_name(alias_info, env) do + {module, _} -> + module + module -> + module + end + + {call, _} = Call.make_module_function_call(module, :__struct__, [{:%{}, [], attributes }], env) + + js_ast = JS.throw_statement(call) { js_ast, env } end defp do_translate({:raise, _, [alias_info, message]}, env) do - js_ast = JS.throw_statement( - Struct.new_struct(alias_info, {:%{}, [], [message: message] }, env) - ) + module = case create_module_name(alias_info, env) do + {module, _} -> + module + module -> + module + end + + {call, _} = Call.make_module_function_call(module, :__struct__, [{:%{}, [], [message: message] }], env) + + js_ast = JS.throw_statement(call) { js_ast, env } end diff --git a/lib/elixir_script/translator/kernel/defimpl.ex b/lib/elixir_script/translator/kernel/defimpl.ex index 8c170abd..4f038974 100644 --- a/lib/elixir_script/translator/kernel/defimpl.ex +++ b/lib/elixir_script/translator/kernel/defimpl.ex @@ -124,10 +124,14 @@ defmodule ElixirScript.Translator.Defimpl do defp map_to_js({:__aliases__, _, _} = module, env) do - ElixirScript.Translator.Struct.get_struct_class( - module, - env - ) + module = case ElixirScript.Translator.create_module_name(module, env) do + {module, _} -> + module + module -> + module + end + + ElixirScript.Translator.translate!(module) end end diff --git a/lib/elixir_script/translator/kernel/special_forms/struct.ex b/lib/elixir_script/translator/kernel/special_forms/struct.ex index ad3c50d7..6d9f522f 100644 --- a/lib/elixir_script/translator/kernel/special_forms/struct.ex +++ b/lib/elixir_script/translator/kernel/special_forms/struct.ex @@ -6,139 +6,6 @@ defmodule ElixirScript.Translator.Struct do alias ElixirScript.Translator.Map alias ElixirScript.Translator.Identifier - def get_struct_module_name(module_name, env) do - ElixirScript.Translator.State.get_module_name(env.state, Utils.quoted_to_name(module_name)) - end - - def get_struct_class(module_name, env) do - candiate_module_name = ElixirScript.Translator.State.get_module_name(env.state, Utils.quoted_to_name(module_name)) - - if ElixirScript.Translator.LexicalScope.get_module_name(env, candiate_module_name) in ElixirScript.Translator.State.list_module_names(env.state) do - name = ElixirScript.Translator.LexicalScope.get_module_name(env, candiate_module_name) - ident = JS.identifier(Utils.name_to_js_name(name)) - ElixirScript.Translator.State.add_module_reference(env.state, env.module, name) - - members = ["Elixir"] ++ Module.split(name) ++ ["__load"] - - JS.member_expression( - JS.call_expression( - Identifier.make_namespace_members(members), - [JS.identifier("Elixir")] - ), - ident - ) - - else - Identifier.make_identifier(module_name) - end - end - - def new_struct(module_name, data, env) do - JS.call_expression( - JS.member_expression( - get_struct_class(module_name, env), - JS.identifier(:create) - ), - [Translator.translate!(data, env)] - ) - end - - def make_defstruct(attributes, env) when length(attributes) == 1 do - attributes = Enum.flat_map(attributes, fn(x) -> x end) - - defaults = Enum.map(attributes, fn - ({x, y}) -> - Map.make_property( - Translator.translate!(x, env), - Translator.translate!(y, env) - ) - (attribute) -> - Map.make_property( - Translator.translate!(attribute, env), - Translator.translate!(nil, env) - ) - end) - |> JS.object_expression - - do_make_defstruct(:defstruct, defaults, env) - end - - def make_defstruct(attributes, env) do - defaults = Enum.map(attributes, fn(x) -> - Map.make_property( - Translator.translate!(x, env), - Translator.translate!(nil, env) - ) - end) - |> JS.object_expression - - do_make_defstruct(:defstruct, defaults, env) - end - - def make_defexception(attributes, env) when length(attributes) == 1 do - exception_key_value = Map.make_property(Translator.translate!(:__exception__, env), Translator.translate!(true, env)) - - attributes = Enum.flat_map(attributes, fn(x) -> x end) - - defaults = [exception_key_value] ++ Enum.map(attributes, fn - ({x, y}) -> - Map.make_property( - Translator.translate!(x, env), - Translator.translate!(y, env) - ) - (x) -> - Map.make_property( - Translator.translate!(x, env), - Translator.translate!(nil, env) - ) - end) - |> JS.object_expression - - do_make_defstruct(:defexception, defaults, env) - end - - def make_defexceptions(attributes, env) do - exception_key_value = Map.make_property(Translator.translate!(:__exception__, env), Translator.translate!(true, env)) - - defaults = [exception_key_value] ++ Enum.map(attributes, fn - (x) -> - Map.make_property( - Translator.translate!(x, env), - Translator.translate!(nil, env) - ) - end) - |> JS.object_expression - - do_make_defstruct(:defexception, defaults, env) - end - - defp do_make_defstruct(name, defaults, env) do - struct_name = Map.make_property(Translator.translate!(:__struct__, env), Translator.translate!({:__MODULE__, [], []}, env)) - - defaults = %{ defaults | properties: [struct_name] ++ defaults.properties } - - ref = JS.identifier(Utils.name_to_js_name(env.module)) - - ref_declarator = JS.variable_declarator( - ref, - JS.call_expression( - JS.member_expression( - JS.member_expression( - JS.identifier("Bootstrap"), - JS.member_expression( - JS.identifier("Core"), - JS.identifier("Functions") - ) - ), - JS.identifier(name) - ), - [defaults] - ) - ) - - JS.variable_declaration([ref_declarator], :const) - end - def make_struct(attributes, env) do struct_name = Map.make_property(Translator.translate!(:__struct__, env), Translator.translate!({:__MODULE__, [], []}, env)) diff --git a/lib/elixir_script/translator/kernel/special_forms/try.ex b/lib/elixir_script/translator/kernel/special_forms/try.ex index c281b6a6..94276f23 100644 --- a/lib/elixir_script/translator/kernel/special_forms/try.ex +++ b/lib/elixir_script/translator/kernel/special_forms/try.ex @@ -62,10 +62,10 @@ defmodule ElixirScript.Translator.Try do { func, _ } = Enum.map(rescue_block, fn(x) -> case x do {:->, _, [[{value, _, module}], block]} when not is_list(module) -> - {:->, [], [[{value, [], convert_to_struct(module)}], block]} + {:->, [], [[{value, [], convert_to_struct(module, env)}], block]} {:->, _, [[{:in, meta, [value, error_names]}], block]} -> error_names = Enum.map(error_names, fn(x) -> - convert_to_struct(x) + convert_to_struct(x, env) end) guards = {:in, meta, [value, error_names]} @@ -73,7 +73,7 @@ defmodule ElixirScript.Translator.Try do {:->, [], [ [{:when, [], [value | [guards]]}], block ]} {:->, _, [error_names, block]} -> Enum.map(error_names, fn(x) -> - {:->, [], [[convert_to_struct(x)], block]} + {:->, [], [[convert_to_struct(x, env)], block]} end) end end) @@ -97,13 +97,16 @@ defmodule ElixirScript.Translator.Try do JS.function_expression([], [], translated_body) end - defp convert_to_struct([module]) do - convert_to_struct(module) + defp convert_to_struct([module], env) do + convert_to_struct(module, env) end - defp convert_to_struct(module) do + defp convert_to_struct(module, env) do case module do - {:__aliases__, _, _} = alias_ast-> + {:__aliases__, _, _} = alias_ast -> + alias_ast = ElixirScript.Translator.State.get_module_name(env.state, alias_ast) + |> ElixirScript.Translator.Utils.name_to_quoted + {:%, [], [alias_ast, {:%{}, [], []}]} ast -> ast diff --git a/lib/elixir_script/translator/state.ex b/lib/elixir_script/translator/state.ex index bb318401..fbbc936b 100644 --- a/lib/elixir_script/translator/state.ex +++ b/lib/elixir_script/translator/state.ex @@ -47,6 +47,7 @@ defmodule ElixirScript.Translator.State do |> Map.put(Process, ElixirScript.Process) |> Map.put(Regex, ElixirScript.Regex) |> Map.put(IO, ElixirScript.IO) + |> Map.put(ArgumentError, ElixirScript.ArgumentError) end def set_module_data(pid, module_data) do diff --git a/priv/std_lib/exceptions.ex b/priv/std_lib/exceptions.ex new file mode 100644 index 00000000..cb2ce0c5 --- /dev/null +++ b/priv/std_lib/exceptions.ex @@ -0,0 +1,3 @@ +defmodule ElixirScript.ArgumentError do + defexception message: "argument error" +end \ No newline at end of file diff --git a/src/javascript/lib/core/protocol.js b/src/javascript/lib/core/protocol.js index 52c25426..94f7feb2 100644 --- a/src/javascript/lib/core/protocol.js +++ b/src/javascript/lib/core/protocol.js @@ -23,6 +23,10 @@ class Protocol { typeof thing === 'string' && this.hasImplementation(Core.BitString) ) { fun = this.registry.get(Core.BitString)[funName]; + } else if ( + thing[Symbol.for('__struct__')] && this.hasImplementation(thing) + ) { + fun = this.registry.get(thing[Symbol.for('__struct__')])[funName]; } else if (this.hasImplementation(thing)) { fun = this.registry.get(thing.constructor)[funName]; } else if (this.fallback) { @@ -56,6 +60,8 @@ class Protocol { thing === Core.Integer || thing === Core.Float || thing === Core.BitString ) { return this.registry.has(thing); + } else if (thing[Symbol.for('__struct__')]) { + return this.registry.has(Symbol.for('__struct__')); } return this.registry.has(thing.constructor); diff --git a/test/app/spec/exception.spec.js b/test/app/spec/exception.spec.js new file mode 100644 index 00000000..8efaf8d7 --- /dev/null +++ b/test/app/spec/exception.spec.js @@ -0,0 +1,51 @@ +const expect = require('chai').expect; +const Elixir = require('../build/Elixir.App'); + +describe('Exception', () => { + it('Create Exception', () => { + const ArgumentError = Elixir.load(Elixir.ElixirScript.ArgumentError); + + let struct = ArgumentError.__struct__(); + + expect(Object.getOwnPropertySymbols(struct)).to.eql([ + Symbol.for('__struct__'), + Symbol.for('message'), + Symbol.for('__exception__'), + ]); + + expect(struct[Symbol.for('__struct__')]).to.eql( + Symbol.for('Elixir.ElixirScript.ArgumentError'), + ); + expect(struct[Symbol.for('__exception__')]).to.eql(true); + expect(struct[Symbol.for('message')]).to.eql('argument error'); + + struct = ArgumentError.__struct__({ + [Symbol.for('message')]: 'new argument error', + }); + + expect(struct[Symbol.for('message')]).to.eql('new argument error'); + }); + + it('raise exception', () => { + const User = Elixir.load(Elixir.User); + const ArgumentError = Elixir.load(Elixir.ElixirScript.ArgumentError); + + expect(User.throw_something()).to.throw(ArgumentError.__struct__()); + + let struct = User.__struct__(); + + expect(Object.getOwnPropertySymbols(struct)).to.eql([ + Symbol.for('__struct__'), + Symbol.for('first'), + Symbol.for('last'), + ]); + + expect(struct[Symbol.for('__struct__')]).to.eql(Symbol.for('Elixir.User')); + expect(struct[Symbol.for('first')]).to.eql(null); + expect(struct[Symbol.for('last')]).to.eql(null); + + struct = User.__struct__({ [Symbol.for('first')]: 'John' }); + + expect(struct[Symbol.for('first')]).to.eql('John'); + }); +}); diff --git a/test/app/spec/struct.spec.js b/test/app/spec/struct.spec.js new file mode 100644 index 00000000..768d3afd --- /dev/null +++ b/test/app/spec/struct.spec.js @@ -0,0 +1,24 @@ +const expect = require('chai').expect; +const Elixir = require('../build/Elixir.App'); + +describe('Struct', () => { + it('Create Struct', () => { + const User = Elixir.load(Elixir.User); + + let struct = User.__struct__(); + + expect(Object.getOwnPropertySymbols(struct)).to.eql([ + Symbol.for('__struct__'), + Symbol.for('first'), + Symbol.for('last'), + ]); + + expect(struct[Symbol.for('__struct__')]).to.eql(Symbol.for('Elixir.User')); + expect(struct[Symbol.for('first')]).to.eql(null); + expect(struct[Symbol.for('last')]).to.eql(null); + + struct = User.__struct__({ [Symbol.for('first')]: 'John' }); + + expect(struct[Symbol.for('first')]).to.eql('John'); + }); +}); diff --git a/test/app/src/user.ex b/test/app/src/user.ex new file mode 100644 index 00000000..bcdaf9ed --- /dev/null +++ b/test/app/src/user.ex @@ -0,0 +1,7 @@ +defmodule User do + defstruct [:first, :last] + + def throw_something() do + raise ArgumentError + end +end \ No newline at end of file diff --git a/test/translator/kernel_test.exs b/test/translator/kernel_test.exs index 7c645f73..2438c7f3 100644 --- a/test/translator/kernel_test.exs +++ b/test/translator/kernel_test.exs @@ -11,7 +11,7 @@ defmodule ElixirScript.Translator.Kernel.Test do end js_code = """ - throw ArgumentError.create(Object.freeze({ + throw Elixir.ElixirScript.ArgumentError.__load(Elixir).__struct__(Object.freeze({ [Symbol.for('message')]: 'cannot convert list to string. The list must contain only integers, strings or nested such lists; got: ' + Elixir.ElixirScript.String.Chars.__load(Elixir).to_string(inspect(list)) })); """ @@ -27,7 +27,7 @@ defmodule ElixirScript.Translator.Kernel.Test do end js_code = """ - throw ArgumentError.create(Object.freeze({ + throw Elixir.ElixirScript.ArgumentError.__load(Elixir).__struct__(Object.freeze({ [Symbol.for('message')]: 'cannot convert list to string. The list must contain only integers, strings or nested such lists; got' })); """ diff --git a/test/translator/struct_test.exs b/test/translator/struct_test.exs index e02a9d60..b562a050 100644 --- a/test/translator/struct_test.exs +++ b/test/translator/struct_test.exs @@ -204,7 +204,7 @@ defmodule ElixirScript.Translator.Struct.Test do end js_code = """ - throw Elixir.MyAppError.__load(Elixir).Elixir$MyAppError.create(Object.freeze({ + throw Elixir.MyAppError.__load(Elixir).__struct__(Object.freeze({ [Symbol.for('message')]: 'did not get what was expected' })); """ diff --git a/test/translator/try_test.exs b/test/translator/try_test.exs index 951f5d65..f8728b61 100644 --- a/test/translator/try_test.exs +++ b/test/translator/try_test.exs @@ -16,7 +16,7 @@ defmodule ElixirScript.Translator.Try.Test do Bootstrap.Core.SpecialForms._try(function() { return 1; }, Bootstrap.Core.Patterns.defmatch(Bootstrap.Core.Patterns.clause([{ - [Symbol.for('__struct__')]: Symbol.for('Elixir.ArgumentError') + [Symbol.for('__struct__')]: Symbol.for('Elixir.ElixirScript.ArgumentError') }], function() { return Elixir.ElixirScript.IO.__load(Elixir).puts('Invalid argument given'); })), null, null, null) @@ -40,7 +40,7 @@ defmodule ElixirScript.Translator.Try.Test do Bootstrap.Core.SpecialForms._try(function() { return 1; }, Bootstrap.Core.Patterns.defmatch(Bootstrap.Core.Patterns.clause([{ - [Symbol.for('__struct__')]: Symbol.for('Elixir.ArgumentError') + [Symbol.for('__struct__')]: Symbol.for('Elixir.ElixirScript.ArgumentError') }], function() { return Elixir.ElixirScript.IO.__load(Elixir).puts('Invalid argument given'); })), null, null, null) @@ -66,7 +66,7 @@ defmodule ElixirScript.Translator.Try.Test do },Bootstrap.Core.Patterns.defmatch(Bootstrap.Core.Patterns.clause([Bootstrap.Core.Patterns.variable()],function(x) { return Elixir.ElixirScript.IO.__load(Elixir).puts('Invalid argument given'); },function(x) { - return Elixir.ElixirScript.Bootstrap.Functions.__load(Elixir).contains(x, Object.freeze([Elixir.ArgumentError.__load(Elixir).__struct__(Object.freeze({}))])); + return Elixir.ElixirScript.Bootstrap.Functions.__load(Elixir).contains(x, Object.freeze([Elixir.ElixirScript.ArgumentError.__load(Elixir).__struct__(Object.freeze({}))])); })),null,null,null) """ @@ -113,7 +113,7 @@ defmodule ElixirScript.Translator.Try.Test do Bootstrap.Core.SpecialForms._try(function() { return 1; }, Bootstrap.Core.Patterns.defmatch(Bootstrap.Core.Patterns.clause([{ - [Symbol.for('__struct__')]: Symbol.for('Elixir.ArgumentError') + [Symbol.for('__struct__')]: Symbol.for('Elixir.ElixirScript.ArgumentError') }], function() { return Elixir.ElixirScript.IO.__load(Elixir).puts('ArgumentError'); }), Bootstrap.Core.Patterns.clause([Bootstrap.Core.Patterns.variable()], function(x) { @@ -141,7 +141,7 @@ defmodule ElixirScript.Translator.Try.Test do Bootstrap.Core.SpecialForms._try(function() { return 1; }, Bootstrap.Core.Patterns.defmatch(Bootstrap.Core.Patterns.clause([{ - [Symbol.for('__struct__')]: Symbol.for('Elixir.ArgumentError') + [Symbol.for('__struct__')]: Symbol.for('Elixir.ElixirScript.ArgumentError') }], function() { return Elixir.ElixirScript.IO.__load(Elixir).puts('Invalid argument given'); })), null, null, function() { @@ -218,7 +218,7 @@ defmodule ElixirScript.Translator.Try.Test do Bootstrap.Core.SpecialForms._try(function() { return 1; }, Bootstrap.Core.Patterns.defmatch(Bootstrap.Core.Patterns.clause([{ - [Symbol.for('__struct__')]: Symbol.for('Elixir.ArgumentError') + [Symbol.for('__struct__')]: Symbol.for('Elixir.ElixirScript.ArgumentError') }], function() { return Elixir.ElixirScript.IO.__load(Elixir).puts('Invalid argument given'); })), Bootstrap.Core.Patterns.defmatch(Bootstrap.Core.Patterns.clause([Symbol.for('throw'), Symbol.for('Error')], function() { From 6a285df260164152ec648b489e9e83d7d4d6738b Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Fri, 7 Apr 2017 01:03:23 -0500 Subject: [PATCH 073/418] Fix new implementation of structs with protocol implementations --- lib/elixir_script/translator.ex | 15 +++++++++++++ .../translator/kernel/defimpl.ex | 2 +- src/javascript/lib/core/protocol.js | 2 +- test/app/spec/exception.spec.js | 22 +++++-------------- test/app/spec/struct.spec.js | 12 ++++++++++ test/app/src/user.ex | 10 +++++++++ 6 files changed, 44 insertions(+), 19 deletions(-) diff --git a/lib/elixir_script/translator.ex b/lib/elixir_script/translator.ex index bcc20064..ca71c476 100644 --- a/lib/elixir_script/translator.ex +++ b/lib/elixir_script/translator.ex @@ -621,6 +621,21 @@ defmodule ElixirScript.Translator do { js_ast, env } end + defp do_translate({:raise, _, [{:__aliases__, _, _} = alias_info]}, env) do + module = case create_module_name(alias_info, env) do + {module, _} -> + module + module -> + module + end + + {call, _} = Call.make_module_function_call(module, :__struct__, [], env) + + js_ast = JS.throw_statement(call) + + { js_ast, env } + end + defp do_translate({:raise, _, [message]}, env) do js_ast = JS.throw_statement( JS.object_expression( diff --git a/lib/elixir_script/translator/kernel/defimpl.ex b/lib/elixir_script/translator/kernel/defimpl.ex index 4f038974..0e1dde5d 100644 --- a/lib/elixir_script/translator/kernel/defimpl.ex +++ b/lib/elixir_script/translator/kernel/defimpl.ex @@ -131,7 +131,7 @@ defmodule ElixirScript.Translator.Defimpl do module end - ElixirScript.Translator.translate!(module) + ElixirScript.Translator.translate!(module, env) end end diff --git a/src/javascript/lib/core/protocol.js b/src/javascript/lib/core/protocol.js index 94f7feb2..02fb4f08 100644 --- a/src/javascript/lib/core/protocol.js +++ b/src/javascript/lib/core/protocol.js @@ -61,7 +61,7 @@ class Protocol { ) { return this.registry.has(thing); } else if (thing[Symbol.for('__struct__')]) { - return this.registry.has(Symbol.for('__struct__')); + return this.registry.has(thing[Symbol.for('__struct__')]); } return this.registry.has(thing.constructor); diff --git a/test/app/spec/exception.spec.js b/test/app/spec/exception.spec.js index 8efaf8d7..7e3f19db 100644 --- a/test/app/spec/exception.spec.js +++ b/test/app/spec/exception.spec.js @@ -30,22 +30,10 @@ describe('Exception', () => { const User = Elixir.load(Elixir.User); const ArgumentError = Elixir.load(Elixir.ElixirScript.ArgumentError); - expect(User.throw_something()).to.throw(ArgumentError.__struct__()); - - let struct = User.__struct__(); - - expect(Object.getOwnPropertySymbols(struct)).to.eql([ - Symbol.for('__struct__'), - Symbol.for('first'), - Symbol.for('last'), - ]); - - expect(struct[Symbol.for('__struct__')]).to.eql(Symbol.for('Elixir.User')); - expect(struct[Symbol.for('first')]).to.eql(null); - expect(struct[Symbol.for('last')]).to.eql(null); - - struct = User.__struct__({ [Symbol.for('first')]: 'John' }); - - expect(struct[Symbol.for('first')]).to.eql('John'); + try { + User.throw_something(); + } catch (e) { + expect(e[Symbol.for('message')]).to.eql('argument error'); + } }); }); diff --git a/test/app/spec/struct.spec.js b/test/app/spec/struct.spec.js index 768d3afd..765ea491 100644 --- a/test/app/spec/struct.spec.js +++ b/test/app/spec/struct.spec.js @@ -21,4 +21,16 @@ describe('Struct', () => { expect(struct[Symbol.for('first')]).to.eql('John'); }); + + it('Protocol', () => { + const User = Elixir.load(Elixir.User); + const StringChars = Elixir.load(Elixir.ElixirScript.String.Chars); + + const struct = User.__struct__({ + [Symbol.for('first')]: 'John', + [Symbol.for('last')]: 'Doe', + }); + + expect(StringChars.to_string(struct)).to.eql('JohnDoe'); + }); }); diff --git a/test/app/src/user.ex b/test/app/src/user.ex index bcdaf9ed..2781433d 100644 --- a/test/app/src/user.ex +++ b/test/app/src/user.ex @@ -4,4 +4,14 @@ defmodule User do def throw_something() do raise ArgumentError end +end + +defimpl String.Chars, for: User do + def to_string(nil) do + "" + end + + def to_string(user) do + user.first <> user.last + end end \ No newline at end of file From 1842c66f0f573b802f8b7cb2d0aeb1847517adb4 Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Sat, 8 Apr 2017 10:01:13 -0500 Subject: [PATCH 074/418] Remove tests for map_update --- src/javascript/tests/special_forms.spec.js | 33 ---------------------- 1 file changed, 33 deletions(-) delete mode 100644 src/javascript/tests/special_forms.spec.js diff --git a/src/javascript/tests/special_forms.spec.js b/src/javascript/tests/special_forms.spec.js deleted file mode 100644 index cc540546..00000000 --- a/src/javascript/tests/special_forms.spec.js +++ /dev/null @@ -1,33 +0,0 @@ -import Core from "../lib/core"; -const SpecialForms = Core.SpecialForms; - -import chai from 'chai'; -var expect = chai.expect; - -describe('SpecialForms', function(){ - - describe('map_update', function(){ - it('creates new object', function(){ - const foo = Object.freeze({foo: "bar", fizz: "buzz"}); - const bar = SpecialForms.map_update(foo, {baz: "bar", fizz: "fizzbuzz"}); - - expect(foo instanceof Object).to.equal(bar instanceof Object); - expect(foo.foo).to.equal(bar.foo); - expect(bar.fizz).to.equal("fizzbuzz"); - expect(foo === bar).to.equal(false); - }); - - it('creates new class', function(){ - function MyClass(foo){ - this.foo = foo; - } - - const foo = new MyClass("bar"); - const bar = SpecialForms.map_update(foo, {baz: "bar", fizz: "fizzbuzz"}); - - expect(foo instanceof MyClass).to.equal(bar instanceof MyClass); - expect(foo.foo).to.equal(bar.foo); - expect(bar.fizz).to.equal("fizzbuzz"); - }); - }); -}); From 0e899a57189d28ef7c40a7b41b66014f26052c96 Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Sat, 8 Apr 2017 10:16:38 -0500 Subject: [PATCH 075/418] Make standard lib map by iterating over elixir modules --- lib/elixir_script/translator/state.ex | 36 ++++++++------------------- 1 file changed, 10 insertions(+), 26 deletions(-) diff --git a/lib/elixir_script/translator/state.ex b/lib/elixir_script/translator/state.ex index fbbc936b..b5fff798 100644 --- a/lib/elixir_script/translator/state.ex +++ b/lib/elixir_script/translator/state.ex @@ -22,32 +22,16 @@ defmodule ElixirScript.Translator.State do end defp build_standard_lib_map() do - Map.new - |> Map.put(Kernel, ElixirScript.Kernel) - |> Map.put(Tuple, ElixirScript.Tuple) - |> Map.put(Atom, ElixirScript.Atom) - |> Map.put(Collectable, ElixirScript.Collectable) - |> Map.put(String.Chars, ElixirScript.String.Chars) - |> Map.put(Enumerable, ElixirScript.Enumerable) - |> Map.put(Enum, ElixirScript.Enum) - |> Map.put(Enum.OutOfBoundsError, ElixirScript.Enum.OutOfBoundsError) - |> Map.put(Integer, ElixirScript.Integer) - |> Map.put(Macro.Env, ElixirScript.Macro.Env) - |> Map.put(View, ElixirScript.View) - |> Map.put(Agent, ElixirScript.Agent) - |> Map.put(Range, ElixirScript.Range) - |> Map.put(String, ElixirScript.String) - |> Map.put(Base, ElixirScript.Base) - |> Map.put(Module, ElixirScript.Module) - |> Map.put(Map, ElixirScript.Map) - |> Map.put(Keyword, ElixirScript.Keyword) - |> Map.put(Bitwise, ElixirScript.Bitwise) - |> Map.put(MapSet, ElixirScript.MapSet) - |> Map.put(List, ElixirScript.List) - |> Map.put(Process, ElixirScript.Process) - |> Map.put(Regex, ElixirScript.Regex) - |> Map.put(IO, ElixirScript.IO) - |> Map.put(ArgumentError, ElixirScript.ArgumentError) + Application.spec(:elixir, :modules) + |> Enum.reduce(Map.new, fn(x, acc) -> + try do + elixirscript_module = (["ElixirScript"] ++ Module.split(x)) |> Module.concat() + Map.put(acc, x, elixirscript_module) + rescue + FunctionClauseError -> + acc + end + end) end def set_module_data(pid, module_data) do From e03a42e8b2940ea2b23e9d5fcf4bbd8e8e92d762 Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Sun, 9 Apr 2017 09:41:58 -0500 Subject: [PATCH 076/418] Add file of supported Elixir modules and functions --- Supported.md | 2004 ++++++++++++++++++++++++++++ lib/elixir_script/gen/supported.ex | 70 + lib/elixir_script/translator.ex | 5 - mix.exs | 9 +- priv/std_lib/exceptions.ex | 4 + priv/std_lib/kernel.ex | 4 + 6 files changed, 2090 insertions(+), 6 deletions(-) create mode 100644 Supported.md create mode 100644 lib/elixir_script/gen/supported.ex diff --git a/Supported.md b/Supported.md new file mode 100644 index 00000000..42a37640 --- /dev/null +++ b/Supported.md @@ -0,0 +1,2004 @@ +# Supported Elixir Modules +## BadStructError +- [ ] __struct__/0 +- [ ] __struct__/1 +- [ ] exception/1 +- [ ] message/1 +## Collectable.List +- [X] __impl__/1 +- [X] into/1 +## Inspect.Float +- [ ] __impl__/1 +- [ ] inspect/2 +## String.Chars.Version.Requirement +- [ ] __impl__/1 +- [ ] to_string/1 +## Inspect.NaiveDateTime +- [ ] __impl__/1 +- [ ] inspect/2 +## Inspect.MapSet +- [ ] __impl__/1 +- [ ] inspect/2 +## Inspect +- [ ] __protocol__/1 +- [ ] impl_for/1 +- [ ] impl_for!/1 +- [ ] inspect/2 +## Inspect.Range +- [ ] __impl__/1 +- [ ] inspect/2 +## ArgumentError +- [X] __struct__/0 +- [X] __struct__/1 +- [X] exception/1 +- [X] message/1 +## Base +- [ ] decode16/1 +- [ ] decode16/2 +- [ ] decode16!/1 +- [ ] decode16!/2 +- [ ] decode32/1 +- [ ] decode32/2 +- [ ] decode32!/1 +- [ ] decode32!/2 +- [X] decode64/1 +- [ ] decode64/2 +- [X] decode64!/1 +- [ ] decode64!/2 +- [ ] encode16/1 +- [ ] encode16/2 +- [ ] encode32/1 +- [ ] encode32/2 +- [X] encode64/1 +- [ ] encode64/2 +- [ ] hex_decode32/1 +- [ ] hex_decode32/2 +- [ ] hex_decode32!/1 +- [ ] hex_decode32!/2 +- [ ] hex_encode32/1 +- [ ] hex_encode32/2 +- [ ] url_decode64/1 +- [ ] url_decode64/2 +- [ ] url_decode64!/1 +- [ ] url_decode64!/2 +- [ ] url_encode64/1 +- [ ] url_encode64/2 +## Macro.Env +- [X] __struct__/0 +- [X] __struct__/1 +- [ ] in_guard?/1 +- [ ] in_match?/1 +- [ ] location/1 +- [ ] stacktrace/1 +## Collectable.Map +- [X] __impl__/1 +- [X] into/1 +## Inspect.Regex +- [ ] __impl__/1 +- [ ] inspect/2 +## Behaviour +- [ ] __using__/1 +- [ ] defcallback/1 +- [ ] defmacrocallback/1 +## Collectable +- [X] __protocol__/1 +- [X] impl_for/1 +- [X] impl_for!/1 +- [X] into/1 +## String.Chars.Time +- [ ] __impl__/1 +- [ ] to_string/1 +## String.Chars.Atom +- [X] __impl__/1 +- [X] to_string/1 +## String.Chars +- [X] __protocol__/1 +- [X] impl_for/1 +- [X] impl_for!/1 +- [X] to_string/1 +## Integer +- [ ] digits/1 +- [ ] digits/2 +- [ ] floor_div/2 +- [ ] mod/2 +- [X] parse/1 +- [X] parse/2 +- [X] to_char_list/1 +- [ ] to_charlist/1 +- [ ] to_charlist/2 +- [ ] to_string/1 +- [ ] to_string/2 +- [ ] undigits/1 +- [ ] undigits/2 +- [X] is_even/1 +- [X] is_odd/1 +## String.Chars.NaiveDateTime +- [ ] __impl__/1 +- [ ] to_string/1 +## Inspect.Any +- [ ] __impl__/1 +- [ ] inspect/2 +## BadMapError +- [ ] __struct__/0 +- [ ] __struct__/1 +- [ ] exception/1 +- [ ] message/1 +## BadArityError +- [ ] __struct__/0 +- [ ] __struct__/1 +- [ ] exception/1 +- [ ] message/1 +## Kernel +- [X] !=/2 +- [X] !==/2 +- [X] */2 +- [X] +/1 +- [X] +/2 +- [X] ++/2 +- [X] -/1 +- [X] -/2 +- [X] --/2 +- [X] //2 +- [X] /2 +- [X] >=/2 +- [X] abs/1 +- [X] apply/2 +- [X] apply/3 +- [X] binary_part/3 +- [ ] bit_size/1 +- [ ] byte_size/1 +- [X] div/2 +- [X] elem/2 +- [ ] exit/1 +- [ ] function_exported?/3 +- [ ] get_and_update_in/3 +- [ ] get_in/2 +- [X] hd/1 +- [ ] inspect/1 +- [ ] inspect/2 +- [X] is_atom/1 +- [X] is_binary/1 +- [X] is_bitstring/1 +- [X] is_boolean/1 +- [X] is_float/1 +- [X] is_function/1 +- [X] is_function/2 +- [X] is_integer/1 +- [X] is_list/1 +- [X] is_map/1 +- [X] is_number/1 +- [X] is_pid/1 +- [X] is_port/1 +- [X] is_reference/1 +- [X] is_tuple/1 +- [X] length/1 +- [ ] macro_exported?/3 +- [ ] make_ref/0 +- [X] map_size/1 +- [X] max/2 +- [X] min/2 +- [ ] node/0 +- [ ] node/1 +- [ ] not/1 +- [ ] pop_in/2 +- [ ] put_elem/3 +- [ ] put_in/3 +- [X] rem/2 +- [X] round/1 +- [ ] self/0 +- [ ] send/2 +- [ ] spawn/1 +- [ ] spawn/3 +- [ ] spawn_link/1 +- [ ] spawn_link/3 +- [ ] spawn_monitor/1 +- [ ] spawn_monitor/3 +- [ ] struct/1 +- [ ] struct/2 +- [ ] struct!/1 +- [ ] struct!/2 +- [X] throw/1 +- [X] tl/1 +- [X] trunc/1 +- [X] tuple_size/1 +- [ ] update_in/3 +- [X] !/1 +- [X] &&/2 +- [X] ../2 +- [X] <>/2 +- [X] @/1 +- [ ] alias!/1 +- [X] and/2 +- [ ] binding/0 +- [ ] binding/1 +- [X] def/1 +- [X] def/2 +- [X] defdelegate/2 +- [X] defexception/1 +- [X] defimpl/2 +- [X] defimpl/3 +- [X] defmacro/1 +- [X] defmacro/2 +- [ ] defmacrop/1 +- [ ] defmacrop/2 +- [X] defmodule/2 +- [X] defoverridable/1 +- [X] defp/1 +- [X] defp/2 +- [X] defprotocol/2 +- [X] defstruct/1 +- [ ] destructure/2 +- [ ] get_and_update_in/2 +- [X] if/2 +- [X] in/2 +- [X] is_nil/1 +- [X] match?/2 +- [X] or/2 +- [ ] pop_in/1 +- [ ] put_in/2 +- [ ] raise/1 +- [ ] raise/2 +- [ ] reraise/2 +- [ ] reraise/3 +- [ ] sigil_C/2 +- [ ] sigil_D/2 +- [ ] sigil_N/2 +- [ ] sigil_R/2 +- [ ] sigil_S/2 +- [ ] sigil_T/2 +- [ ] sigil_W/2 +- [ ] sigil_c/2 +- [X] sigil_r/2 +- [ ] sigil_s/2 +- [ ] sigil_w/2 +- [ ] to_char_list/1 +- [ ] to_charlist/1 +- [X] to_string/1 +- [X] unless/2 +- [ ] update_in/2 +- [X] use/1 +- [X] use/2 +- [ ] var!/1 +- [ ] var!/2 +- [X] |>/2 +- [X] ||/2 +## Kernel.ParallelCompiler +- [ ] files/1 +- [ ] files/2 +- [ ] files_to_path/2 +- [ ] files_to_path/3 +## File.Stream +- [ ] __build__/3 +- [ ] __struct__/0 +- [ ] __struct__/1 +## Inspect.List +- [ ] __impl__/1 +- [ ] inspect/2 +- [ ] keyword/2 +- [ ] keyword?/1 +- [ ] printable?/1 +## Path.Wildcard +- [ ] list_dir/1 +- [ ] read_link_info/1 +## SyntaxError +- [ ] __struct__/0 +- [ ] __struct__/1 +- [ ] exception/1 +- [ ] message/1 +## List.Chars.List +- [ ] __impl__/1 +- [ ] to_charlist/1 +## CaseClauseError +- [ ] __struct__/0 +- [ ] __struct__/1 +- [ ] exception/1 +- [ ] message/1 +## Path +- [ ] absname/1 +- [ ] absname/2 +- [ ] basename/1 +- [ ] basename/2 +- [ ] dirname/1 +- [ ] expand/1 +- [ ] expand/2 +- [ ] extname/1 +- [ ] join/1 +- [ ] join/2 +- [ ] relative/1 +- [ ] relative_to/2 +- [ ] relative_to_cwd/1 +- [ ] rootname/1 +- [ ] rootname/2 +- [ ] split/1 +- [ ] type/1 +- [ ] wildcard/1 +- [ ] wildcard/2 +## UnicodeConversionError +- [ ] __struct__/0 +- [ ] __struct__/1 +- [ ] exception/1 +- [ ] message/1 +## String.Chars.BitString +- [X] __impl__/1 +- [X] to_string/1 +## DateTime +- [ ] __struct__/0 +- [ ] __struct__/1 +- [ ] compare/2 +- [ ] from_iso8601/1 +- [ ] from_naive/2 +- [ ] from_naive!/2 +- [ ] from_unix/1 +- [ ] from_unix/2 +- [ ] from_unix!/1 +- [ ] from_unix!/2 +- [ ] to_date/1 +- [ ] to_iso8601/1 +- [ ] to_naive/1 +- [ ] to_string/1 +- [ ] to_time/1 +- [ ] to_unix/1 +- [ ] to_unix/2 +- [ ] utc_now/0 +## String.Chars.Float +- [X] __impl__/1 +- [X] to_string/1 +## Collectable.File.Stream +- [ ] __impl__/1 +- [ ] into/1 +## String.Chars.URI +- [ ] __impl__/1 +- [ ] to_string/1 +## CompileError +- [ ] __struct__/0 +- [ ] __struct__/1 +- [ ] exception/1 +- [ ] message/1 +## File +- [ ] cd/1 +- [ ] cd!/1 +- [ ] cd!/2 +- [ ] chgrp/2 +- [ ] chgrp!/2 +- [ ] chmod/2 +- [ ] chmod!/2 +- [ ] chown/2 +- [ ] chown!/2 +- [ ] close/1 +- [ ] copy/2 +- [ ] copy/3 +- [ ] copy!/2 +- [ ] copy!/3 +- [ ] cp/2 +- [ ] cp/3 +- [ ] cp!/2 +- [ ] cp!/3 +- [ ] cp_r/2 +- [ ] cp_r/3 +- [ ] cp_r!/2 +- [ ] cp_r!/3 +- [ ] cwd/0 +- [ ] cwd!/0 +- [ ] dir?/1 +- [ ] exists?/1 +- [ ] ln_s/2 +- [ ] ls/0 +- [ ] ls/1 +- [ ] ls!/0 +- [ ] ls!/1 +- [ ] lstat/1 +- [ ] lstat/2 +- [ ] lstat!/1 +- [ ] lstat!/2 +- [ ] mkdir/1 +- [ ] mkdir!/1 +- [ ] mkdir_p/1 +- [ ] mkdir_p!/1 +- [ ] open/1 +- [ ] open/2 +- [ ] open/3 +- [ ] open!/1 +- [ ] open!/2 +- [ ] open!/3 +- [ ] read/1 +- [ ] read!/1 +- [ ] regular?/1 +- [ ] rename/2 +- [ ] rm/1 +- [ ] rm!/1 +- [ ] rm_rf/1 +- [ ] rm_rf!/1 +- [ ] rmdir/1 +- [ ] rmdir!/1 +- [ ] stat/1 +- [ ] stat/2 +- [ ] stat!/1 +- [ ] stat!/2 +- [ ] stream!/1 +- [ ] stream!/2 +- [ ] stream!/3 +- [ ] touch/1 +- [ ] touch/2 +- [ ] touch!/1 +- [ ] touch!/2 +- [ ] write/2 +- [ ] write/3 +- [ ] write!/2 +- [ ] write!/3 +- [ ] write_stat/2 +- [ ] write_stat/3 +- [ ] write_stat!/2 +- [ ] write_stat!/3 +## Dict +- [ ] delete/2 +- [ ] drop/2 +- [ ] empty/1 +- [ ] equal?/2 +- [ ] fetch/2 +- [ ] fetch!/2 +- [ ] get/2 +- [ ] get/3 +- [ ] get_and_update/3 +- [ ] get_lazy/3 +- [ ] has_key?/2 +- [ ] keys/1 +- [ ] merge/2 +- [ ] merge/3 +- [ ] pop/2 +- [ ] pop/3 +- [ ] pop_lazy/3 +- [ ] put/3 +- [ ] put_new/3 +- [ ] put_new_lazy/3 +- [ ] size/1 +- [ ] split/2 +- [ ] take/2 +- [ ] to_list/1 +- [ ] update/4 +- [ ] update!/3 +- [ ] values/1 +- [ ] __using__/1 +## Version.Requirement +- [ ] __struct__/0 +- [ ] __struct__/1 +## String +- [X] at/2 +- [X] capitalize/1 +- [ ] chunk/2 +- [X] codepoints/1 +- [X] contains?/2 +- [X] downcase/1 +- [X] duplicate/2 +- [X] ends_with?/2 +- [ ] equivalent?/2 +- [X] first/1 +- [X] graphemes/1 +- [ ] jaro_distance/2 +- [X] last/1 +- [X] length/1 +- [ ] ljust/2 +- [ ] ljust/3 +- [ ] lstrip/1 +- [ ] lstrip/2 +- [X] match?/2 +- [ ] myers_difference/2 +- [X] next_codepoint/1 +- [X] next_grapheme/1 +- [ ] next_grapheme_size/1 +- [ ] normalize/2 +- [ ] pad_leading/2 +- [ ] pad_leading/3 +- [ ] pad_trailing/2 +- [ ] pad_trailing/3 +- [ ] printable?/1 +- [ ] replace/3 +- [ ] replace/4 +- [ ] replace_leading/3 +- [ ] replace_prefix/3 +- [ ] replace_suffix/3 +- [ ] replace_trailing/3 +- [X] reverse/1 +- [ ] rjust/2 +- [ ] rjust/3 +- [ ] rstrip/1 +- [ ] rstrip/2 +- [ ] slice/2 +- [ ] slice/3 +- [X] split/1 +- [X] split/2 +- [X] split/3 +- [ ] split_at/2 +- [ ] splitter/2 +- [ ] splitter/3 +- [X] starts_with?/2 +- [ ] strip/1 +- [ ] strip/2 +- [X] to_atom/1 +- [X] to_char_list/1 +- [ ] to_charlist/1 +- [X] to_existing_atom/1 +- [X] to_float/1 +- [X] to_integer/1 +- [X] to_integer/2 +- [ ] trim/1 +- [ ] trim/2 +- [ ] trim_leading/1 +- [ ] trim_leading/2 +- [ ] trim_trailing/1 +- [ ] trim_trailing/2 +- [X] upcase/1 +- [ ] valid?/1 +- [X] valid_character?/1 +## Record.Extractor +- [ ] extract/2 +- [ ] extract_all/1 +## Collectable.HashSet +- [ ] __impl__/1 +- [ ] into/1 +## String.Unicode +- [ ] codepoints/1 +- [ ] graphemes/1 +- [ ] length/1 +- [ ] next_codepoint/1 +- [ ] next_grapheme_size/1 +- [ ] split_at/2 +- [ ] version/0 +## ErlangError +- [ ] __struct__/0 +- [ ] __struct__/1 +- [ ] exception/1 +- [ ] message/1 +- [ ] normalize/2 +## File.Stat +- [ ] __struct__/0 +- [ ] __struct__/1 +- [ ] from_record/1 +- [ ] to_record/1 +## Inspect.Version +- [ ] __impl__/1 +- [ ] inspect/2 +## RuntimeError +- [X] __struct__/0 +- [X] __struct__/1 +- [X] exception/1 +- [X] message/1 +## Range +- [X] __struct__/0 +- [X] __struct__/1 +- [X] new/2 +- [X] range?/1 +## Exception +- [ ] exception?/1 +- [ ] format/2 +- [ ] format/3 +- [ ] format_banner/2 +- [ ] format_banner/3 +- [ ] format_exit/1 +- [ ] format_fa/2 +- [ ] format_file_line/2 +- [ ] format_file_line/3 +- [ ] format_mfa/3 +- [ ] format_stacktrace/0 +- [ ] format_stacktrace/1 +- [ ] format_stacktrace_entry/1 +- [ ] message/1 +- [ ] normalize/2 +- [ ] normalize/3 +## Inspect.Function +- [ ] __impl__/1 +- [ ] inspect/2 +## Enumerable.GenEvent.Stream +- [ ] __impl__/1 +- [ ] count/1 +- [ ] member?/2 +- [ ] reduce/3 +## Enum.OutOfBoundsError +- [X] __struct__/0 +- [X] __struct__/1 +- [X] exception/1 +- [X] message/1 +## Enumerable.Range +- [ ] __impl__/1 +- [ ] count/1 +- [ ] member?/2 +- [ ] reduce/3 +## Date +- [ ] __struct__/0 +- [ ] __struct__/1 +- [ ] compare/2 +- [ ] day_of_week/1 +- [ ] days_in_month/1 +- [ ] from_erl/1 +- [ ] from_erl!/1 +- [ ] from_iso8601/1 +- [ ] from_iso8601!/1 +- [ ] leap_year?/1 +- [ ] new/3 +- [ ] to_erl/1 +- [ ] to_iso8601/1 +- [ ] to_string/1 +- [ ] utc_today/0 +## Inspect.Time +- [ ] __impl__/1 +- [ ] inspect/2 +## String.Casing +- [ ] downcase/1 +- [ ] titlecase_once/1 +- [ ] upcase/1 +## Regex.CompileError +- [ ] __struct__/0 +- [ ] __struct__/1 +- [ ] exception/1 +- [ ] message/1 +## Supervisor.Spec +- [ ] supervise/2 +- [ ] supervisor/2 +- [ ] supervisor/3 +- [ ] worker/2 +- [ ] worker/3 +## Collectable.MapSet +- [ ] __impl__/1 +- [ ] into/1 +## StringIO +- [ ] close/1 +- [ ] code_change/3 +- [ ] contents/1 +- [ ] flush/1 +- [ ] handle_call/3 +- [ ] handle_cast/2 +- [ ] handle_info/2 +- [ ] init/1 +- [ ] open/1 +- [ ] open/2 +- [ ] terminate/2 +## Inspect.Port +- [ ] __impl__/1 +- [ ] inspect/2 +## GenEvent.Stream +- [ ] __struct__/0 +- [ ] __struct__/1 +- [ ] code_change/3 +- [ ] handle_call/2 +- [ ] handle_event/2 +- [ ] handle_info/2 +- [ ] init/1 +- [ ] terminate/2 +## Protocol.UndefinedError +- [ ] __struct__/0 +- [ ] __struct__/1 +- [ ] exception/1 +- [ ] message/1 +## BadFunctionError +- [ ] __struct__/0 +- [ ] __struct__/1 +- [ ] exception/1 +- [ ] message/1 +## Time +- [ ] __struct__/0 +- [ ] __struct__/1 +- [ ] compare/2 +- [ ] from_erl/1 +- [ ] from_erl/2 +- [ ] from_erl!/1 +- [ ] from_erl!/2 +- [ ] from_iso8601/1 +- [ ] from_iso8601!/1 +- [ ] new/3 +- [ ] new/4 +- [ ] to_erl/1 +- [ ] to_iso8601/1 +- [ ] to_string/1 +- [ ] utc_now/0 +## List.Chars.BitString +- [ ] __impl__/1 +- [ ] to_charlist/1 +## Registry +- [ ] dispatch/3 +- [ ] keys/2 +- [ ] lookup/2 +- [ ] match/3 +- [ ] meta/2 +- [ ] put_meta/3 +- [ ] register/3 +- [ ] register_name/2 +- [ ] send/2 +- [ ] start_link/2 +- [ ] start_link/3 +- [ ] unregister/2 +- [ ] unregister_name/1 +- [ ] update_value/3 +- [ ] whereis_name/1 +## List.Chars.Float +- [ ] __impl__/1 +- [ ] to_charlist/1 +## Code.LoadError +- [ ] __struct__/0 +- [ ] __struct__/1 +- [ ] exception/1 +- [ ] message/1 +## ArithmeticError +- [ ] __struct__/0 +- [ ] __struct__/1 +- [ ] exception/1 +- [ ] message/1 +## String.Chars.List +- [X] __impl__/1 +- [X] to_string/1 +## Inspect.BitString +- [ ] __impl__/1 +- [ ] escape/2 +- [ ] escape_char/1 +- [ ] inspect/2 +## Inspect.HashSet +- [ ] __impl__/1 +- [ ] inspect/2 +## String.Chars.DateTime +- [ ] __impl__/1 +- [ ] to_string/1 +## Inspect.Map +- [ ] __impl__/1 +- [ ] inspect/2 +- [ ] inspect/3 +## HashDict +- [ ] __struct__/0 +- [ ] __struct__/1 +- [ ] delete/2 +- [ ] dict_delete/2 +- [ ] drop/2 +- [ ] equal?/2 +- [ ] fetch/2 +- [ ] fetch!/2 +- [ ] get/2 +- [ ] get/3 +- [ ] get_and_update/3 +- [ ] get_lazy/3 +- [ ] has_key?/2 +- [ ] keys/1 +- [ ] merge/2 +- [ ] merge/3 +- [ ] new/0 +- [ ] pop/2 +- [ ] pop/3 +- [ ] pop_lazy/3 +- [ ] put/3 +- [ ] put_new/3 +- [ ] put_new_lazy/3 +- [ ] reduce/3 +- [ ] size/1 +- [ ] split/2 +- [ ] take/2 +- [ ] to_list/1 +- [ ] update/4 +- [ ] update!/3 +- [ ] values/1 +## NaiveDateTime +- [ ] __struct__/0 +- [ ] __struct__/1 +- [ ] add/2 +- [ ] add/3 +- [ ] compare/2 +- [ ] diff/2 +- [ ] diff/3 +- [ ] from_erl/1 +- [ ] from_erl/2 +- [ ] from_erl!/1 +- [ ] from_erl!/2 +- [ ] from_iso8601/1 +- [ ] from_iso8601!/1 +- [ ] new/2 +- [ ] new/6 +- [ ] new/7 +- [ ] to_date/1 +- [ ] to_erl/1 +- [ ] to_iso8601/1 +- [ ] to_string/1 +- [ ] to_time/1 +- [ ] utc_now/0 +## IO.ANSI +- [ ] black/0 +- [ ] black_background/0 +- [ ] blink_off/0 +- [ ] blink_rapid/0 +- [ ] blink_slow/0 +- [ ] blue/0 +- [ ] blue_background/0 +- [ ] bright/0 +- [ ] clear/0 +- [ ] clear_line/0 +- [ ] color/1 +- [ ] color/3 +- [ ] color_background/1 +- [ ] color_background/3 +- [ ] conceal/0 +- [ ] crossed_out/0 +- [ ] cyan/0 +- [ ] cyan_background/0 +- [ ] default_background/0 +- [ ] default_color/0 +- [ ] enabled?/0 +- [ ] encircled/0 +- [ ] faint/0 +- [ ] font_1/0 +- [ ] font_2/0 +- [ ] font_3/0 +- [ ] font_4/0 +- [ ] font_5/0 +- [ ] font_6/0 +- [ ] font_7/0 +- [ ] font_8/0 +- [ ] font_9/0 +- [ ] format/1 +- [ ] format/2 +- [ ] format_fragment/1 +- [ ] format_fragment/2 +- [ ] framed/0 +- [ ] green/0 +- [ ] green_background/0 +- [ ] home/0 +- [ ] inverse/0 +- [ ] inverse_off/0 +- [ ] italic/0 +- [ ] light_black/0 +- [ ] light_black_background/0 +- [ ] light_blue/0 +- [ ] light_blue_background/0 +- [ ] light_cyan/0 +- [ ] light_cyan_background/0 +- [ ] light_green/0 +- [ ] light_green_background/0 +- [ ] light_magenta/0 +- [ ] light_magenta_background/0 +- [ ] light_red/0 +- [ ] light_red_background/0 +- [ ] light_white/0 +- [ ] light_white_background/0 +- [ ] light_yellow/0 +- [ ] light_yellow_background/0 +- [ ] magenta/0 +- [ ] magenta_background/0 +- [ ] no_underline/0 +- [ ] normal/0 +- [ ] not_framed_encircled/0 +- [ ] not_italic/0 +- [ ] not_overlined/0 +- [ ] overlined/0 +- [ ] primary_font/0 +- [ ] red/0 +- [ ] red_background/0 +- [ ] reset/0 +- [ ] reverse/0 +- [ ] reverse_off/0 +- [ ] underline/0 +- [ ] white/0 +- [ ] white_background/0 +- [ ] yellow/0 +- [ ] yellow_background/0 +## Module +- [ ] add_doc/5 +- [ ] add_doc/6 +- [ ] compile_doc/6 +- [ ] concat/1 +- [ ] concat/2 +- [ ] create/3 +- [ ] defines?/2 +- [ ] defines?/3 +- [ ] definitions_in/1 +- [ ] definitions_in/2 +- [ ] delete_attribute/2 +- [ ] eval_quoted/2 +- [ ] eval_quoted/3 +- [ ] eval_quoted/4 +- [ ] get_attribute/2 +- [ ] get_attribute/3 +- [ ] make_overridable/2 +- [ ] open?/1 +- [ ] overridable?/2 +- [ ] put_attribute/3 +- [ ] put_attribute/5 +- [ ] register_attribute/3 +- [ ] safe_concat/1 +- [ ] safe_concat/2 +- [ ] split/1 +- [ ] store_typespec/3 +## IO +- [ ] binread/1 +- [ ] binread/2 +- [ ] binstream/2 +- [ ] binwrite/1 +- [ ] binwrite/2 +- [ ] chardata_to_string/1 +- [ ] each_binstream/2 +- [ ] each_stream/2 +- [ ] getn/1 +- [ ] getn/2 +- [ ] getn/3 +- [ ] gets/1 +- [ ] gets/2 +- [X] inspect/1 +- [X] inspect/2 +- [ ] inspect/3 +- [ ] iodata_length/1 +- [ ] iodata_to_binary/1 +- [X] puts/1 +- [X] puts/2 +- [ ] read/1 +- [ ] read/2 +- [ ] stream/2 +- [X] warn/1 +- [ ] warn/2 +- [ ] write/1 +- [ ] write/2 +## MatchError +- [ ] __struct__/0 +- [ ] __struct__/1 +- [ ] exception/1 +- [ ] message/1 +## Enumerable.HashSet +- [ ] __impl__/1 +- [ ] count/1 +- [ ] member?/2 +- [ ] reduce/3 +## Enumerable.HashDict +- [ ] __impl__/1 +- [ ] count/1 +- [ ] member?/2 +- [ ] reduce/3 +## Agent +- [ ] cast/2 +- [ ] cast/4 +- [X] get/2 +- [ ] get/3 +- [ ] get/4 +- [ ] get/5 +- [X] get_and_update/2 +- [ ] get_and_update/3 +- [ ] get_and_update/4 +- [ ] get_and_update/5 +- [X] start/1 +- [X] start/2 +- [ ] start/3 +- [ ] start/4 +- [X] start_link/1 +- [X] start_link/2 +- [ ] start_link/3 +- [ ] start_link/4 +- [X] stop/1 +- [ ] stop/2 +- [ ] stop/3 +- [X] update/2 +- [ ] update/3 +- [ ] update/4 +- [ ] update/5 +## String.Chars.Version +- [ ] __impl__/1 +- [ ] to_string/1 +## System +- [ ] argv/0 +- [ ] argv/1 +- [ ] at_exit/1 +- [ ] build_info/0 +- [ ] cmd/2 +- [ ] cmd/3 +- [ ] compiled_endianness/0 +- [ ] convert_time_unit/3 +- [ ] cwd/0 +- [ ] cwd!/0 +- [ ] delete_env/1 +- [ ] endianness/0 +- [ ] find_executable/1 +- [ ] get_env/0 +- [ ] get_env/1 +- [ ] get_pid/0 +- [ ] halt/0 +- [ ] halt/1 +- [ ] monotonic_time/0 +- [ ] monotonic_time/1 +- [ ] os_time/0 +- [ ] os_time/1 +- [ ] otp_release/0 +- [ ] put_env/1 +- [ ] put_env/2 +- [ ] schedulers/0 +- [ ] schedulers_online/0 +- [ ] stacktrace/0 +- [ ] system_time/0 +- [ ] system_time/1 +- [ ] time_offset/0 +- [ ] time_offset/1 +- [ ] tmp_dir/0 +- [ ] tmp_dir!/0 +- [ ] unique_integer/0 +- [ ] unique_integer/1 +- [ ] user_home/0 +- [ ] user_home!/0 +- [ ] version/0 +## Inspect.Tuple +- [ ] __impl__/1 +- [ ] inspect/2 +## Collectable.BitString +- [X] __impl__/1 +- [X] into/1 +## Enumerable.Map +- [X] __impl__/1 +- [X] count/1 +- [X] member?/2 +- [X] reduce/3 +## Enum.EmptyError +- [ ] __struct__/0 +- [ ] __struct__/1 +- [ ] exception/1 +- [ ] message/1 +## GenEvent +- [ ] ack_notify/2 +- [ ] add_handler/3 +- [ ] add_mon_handler/3 +- [ ] call/3 +- [ ] call/4 +- [ ] format_status/2 +- [ ] init_hib/4 +- [ ] init_it/6 +- [ ] notify/2 +- [ ] remove_handler/3 +- [ ] start/0 +- [ ] start/1 +- [ ] start_link/0 +- [ ] start_link/1 +- [ ] stop/1 +- [ ] stop/2 +- [ ] stop/3 +- [ ] stream/1 +- [ ] stream/2 +- [ ] swap_handler/5 +- [ ] swap_mon_handler/5 +- [ ] sync_notify/2 +- [ ] system_code_change/4 +- [ ] system_continue/3 +- [ ] system_get_state/1 +- [ ] system_replace_state/2 +- [ ] system_terminate/4 +- [ ] which_handlers/1 +- [ ] __using__/1 +## Inspect.Error +- [ ] __struct__/0 +- [ ] __struct__/1 +- [ ] exception/1 +- [ ] message/1 +## Enumerable.List +- [X] __impl__/1 +- [X] count/1 +- [X] member?/2 +- [X] reduce/3 +## OptionParser.ParseError +- [ ] __struct__/0 +- [ ] __struct__/1 +- [ ] exception/1 +- [ ] message/1 +## Map +- [X] delete/2 +- [X] drop/2 +- [X] equal?/2 +- [X] fetch/2 +- [X] fetch!/2 +- [X] from_struct/1 +- [X] get/2 +- [X] get/3 +- [X] get_and_update/3 +- [ ] get_and_update!/3 +- [X] get_lazy/3 +- [X] has_key?/2 +- [X] keys/1 +- [X] merge/2 +- [ ] merge/3 +- [X] new/0 +- [ ] new/1 +- [ ] new/2 +- [X] pop/2 +- [X] pop/3 +- [X] pop_lazy/3 +- [X] put/3 +- [X] put_new/3 +- [X] put_new_lazy/3 +- [X] size/1 +- [X] split/2 +- [X] take/2 +- [X] to_list/1 +- [X] update/4 +- [X] update!/3 +- [X] values/1 +## OptionParser +- [ ] get_option_key/1 +- [ ] next/1 +- [ ] next/2 +- [ ] parse/1 +- [ ] parse/2 +- [ ] parse!/1 +- [ ] parse!/2 +- [ ] parse_head/1 +- [ ] parse_head/2 +- [ ] parse_head!/1 +- [ ] parse_head!/2 +- [ ] split/1 +- [ ] to_argv/1 +- [ ] to_argv/2 +## Kernel.ErrorHandler +- [ ] ensure_compiled/2 +- [ ] ensure_loaded/1 +- [ ] undefined_function/3 +- [ ] undefined_lambda/3 +## List.Chars.Integer +- [ ] __impl__/1 +- [ ] to_charlist/1 +## HashSet +- [ ] __struct__/0 +- [ ] __struct__/1 +- [ ] delete/2 +- [ ] difference/2 +- [ ] disjoint?/2 +- [ ] equal?/2 +- [ ] intersection/2 +- [ ] member?/2 +- [ ] new/0 +- [ ] put/2 +- [ ] reduce/3 +- [ ] size/1 +- [ ] subset?/2 +- [ ] to_list/1 +- [ ] union/2 +## Inspect.Date +- [ ] __impl__/1 +- [ ] inspect/2 +## Code +- [ ] append_path/1 +- [ ] available_compiler_options/0 +- [ ] compile_quoted/1 +- [ ] compile_quoted/2 +- [ ] compile_string/1 +- [ ] compile_string/2 +- [ ] compiler_options/0 +- [ ] compiler_options/1 +- [ ] delete_path/1 +- [ ] ensure_compiled/1 +- [ ] ensure_compiled?/1 +- [ ] ensure_loaded/1 +- [ ] ensure_loaded?/1 +- [ ] eval_file/1 +- [ ] eval_file/2 +- [ ] eval_quoted/1 +- [ ] eval_quoted/2 +- [ ] eval_quoted/3 +- [ ] eval_string/1 +- [ ] eval_string/2 +- [ ] eval_string/3 +- [ ] get_docs/2 +- [ ] load_file/1 +- [ ] load_file/2 +- [ ] loaded_files/0 +- [ ] prepend_path/1 +- [ ] require_file/1 +- [ ] require_file/2 +- [ ] string_to_quoted/1 +- [ ] string_to_quoted/2 +- [ ] string_to_quoted!/1 +- [ ] string_to_quoted!/2 +- [ ] unload_files/1 +## Kernel.SpecialForms +- [X] %/2 +- [X] %{}/1 +- [X] &/1 +- [X] ./2 +- [X] ::/2 +- [X] <<>>/1 +- [X] =/2 +- [X] ^/1 +- [X] __CALLER__/0 +- [X] __DIR__/0 +- [X] __ENV__/0 +- [X] __MODULE__/0 +- [X] __aliases__/1 +- [X] __block__/1 +- [X] alias/2 +- [X] case/2 +- [X] cond/1 +- [X] fn/1 +- [X] for/1 +- [X] import/2 +- [X] quote/2 +- [ ] receive/1 +- [X] require/2 +- [X] super/1 +- [X] try/1 +- [X] unquote/1 +- [X] unquote_splicing/1 +- [X] with/1 +- [X] {}/1 +## Tuple +- [X] append/2 +- [X] delete_at/2 +- [X] duplicate/2 +- [X] insert_at/3 +- [X] to_list/1 +## SystemLimitError +- [ ] __struct__/0 +- [ ] __struct__/1 +- [ ] exception/1 +- [ ] message/1 +## Bitwise +- [X] &&&/2 +- [X] <<>>/2 +- [X] ^^^/2 +- [ ] __using__/1 +- [X] band/2 +- [X] bnot/1 +- [X] bor/2 +- [X] bsl/2 +- [X] bsr/2 +- [X] bxor/2 +- [X] |||/2 +- [X] ~~~/1 +## String.Chars.Integer +- [X] __impl__/1 +- [X] to_string/1 +## Inspect.Reference +- [ ] __impl__/1 +- [ ] inspect/2 +## IO.StreamError +- [ ] __struct__/0 +- [ ] __struct__/1 +- [ ] exception/1 +- [ ] message/1 +## Process +- [ ] alive?/1 +- [ ] cancel_timer/1 +- [ ] delete/1 +- [ ] demonitor/1 +- [ ] demonitor/2 +- [ ] exit/2 +- [ ] flag/2 +- [ ] flag/3 +- [ ] get/0 +- [ ] get/1 +- [ ] get/2 +- [ ] get_keys/0 +- [ ] get_keys/1 +- [ ] group_leader/0 +- [ ] group_leader/2 +- [ ] hibernate/3 +- [ ] info/1 +- [ ] info/2 +- [ ] link/1 +- [ ] list/0 +- [ ] monitor/1 +- [ ] put/2 +- [ ] read_timer/1 +- [ ] register/2 +- [ ] registered/0 +- [ ] send/3 +- [ ] send_after/3 +- [ ] send_after/4 +- [ ] sleep/1 +- [ ] spawn/2 +- [ ] spawn/4 +- [ ] unlink/1 +- [ ] unregister/1 +- [ ] whereis/1 +## Protocol +- [ ] __builtin__/0 +- [ ] __derive__/3 +- [ ] __ensure_defimpl__/3 +- [ ] __functions_spec__/1 +- [ ] __impl__/2 +- [ ] __protocol__/2 +- [ ] __spec__?/3 +- [ ] assert_impl!/2 +- [ ] assert_protocol!/1 +- [ ] consolidate/2 +- [ ] consolidated?/1 +- [ ] extract_impls/2 +- [ ] extract_protocols/1 +- [ ] def/1 +- [ ] derive/2 +- [ ] derive/3 +## UndefinedFunctionError +- [ ] __struct__/0 +- [ ] __struct__/1 +- [ ] exception/1 +- [ ] message/1 +## Version.InvalidVersionError +- [ ] __struct__/0 +- [ ] __struct__/1 +- [ ] exception/1 +- [ ] message/1 +## Task +- [ ] __struct__/0 +- [ ] __struct__/1 +- [ ] async/1 +- [ ] async/3 +- [ ] async_stream/2 +- [ ] async_stream/3 +- [ ] async_stream/4 +- [ ] async_stream/5 +- [ ] await/1 +- [ ] await/2 +- [ ] find/2 +- [ ] shutdown/1 +- [ ] shutdown/2 +- [ ] start/1 +- [ ] start/3 +- [ ] start_link/1 +- [ ] start_link/3 +- [ ] yield/1 +- [ ] yield/2 +- [ ] yield_many/1 +- [ ] yield_many/2 +## Float +- [ ] ceil/1 +- [ ] ceil/2 +- [ ] floor/1 +- [ ] floor/2 +- [ ] parse/1 +- [ ] ratio/1 +- [ ] round/1 +- [ ] round/2 +- [ ] to_char_list/1 +- [ ] to_char_list/2 +- [ ] to_charlist/1 +- [ ] to_string/1 +- [ ] to_string/2 +## Supervisor +- [ ] count_children/1 +- [ ] delete_child/2 +- [ ] restart_child/2 +- [ ] start_child/2 +- [ ] start_link/2 +- [ ] start_link/3 +- [ ] stop/1 +- [ ] stop/2 +- [ ] stop/3 +- [ ] terminate_child/2 +- [ ] which_children/1 +- [ ] __using__/1 +## Enumerable +- [X] __protocol__/1 +- [X] count/1 +- [X] impl_for/1 +- [X] impl_for!/1 +- [X] member?/2 +- [X] reduce/3 +## Enum +- [X] all?/1 +- [X] all?/2 +- [X] any?/1 +- [X] any?/2 +- [X] at/2 +- [X] at/3 +- [ ] chunk/2 +- [ ] chunk/3 +- [ ] chunk/4 +- [ ] chunk_by/2 +- [X] concat/1 +- [X] concat/2 +- [X] count/1 +- [X] count/2 +- [ ] dedup/1 +- [ ] dedup_by/2 +- [X] drop/2 +- [X] drop_every/2 +- [X] drop_while/2 +- [X] each/2 +- [X] empty?/1 +- [X] fetch/2 +- [X] fetch!/2 +- [X] filter/2 +- [X] filter_map/3 +- [X] find/2 +- [X] find/3 +- [ ] find_index/2 +- [ ] find_value/2 +- [ ] find_value/3 +- [ ] flat_map/2 +- [ ] flat_map_reduce/3 +- [ ] group_by/2 +- [ ] group_by/3 +- [ ] intersperse/2 +- [X] into/2 +- [X] into/3 +- [ ] join/1 +- [ ] join/2 +- [X] map/2 +- [ ] map_every/3 +- [ ] map_join/2 +- [ ] map_join/3 +- [X] map_reduce/3 +- [ ] max/1 +- [ ] max/2 +- [ ] max_by/2 +- [ ] max_by/3 +- [X] member?/2 +- [ ] min/1 +- [ ] min/2 +- [ ] min_by/2 +- [ ] min_by/3 +- [ ] min_max/1 +- [ ] min_max/2 +- [ ] min_max_by/2 +- [ ] min_max_by/3 +- [ ] partition/2 +- [ ] random/1 +- [X] reduce/2 +- [X] reduce/3 +- [ ] reduce_while/3 +- [ ] reject/2 +- [X] reverse/1 +- [X] reverse/2 +- [ ] reverse_slice/3 +- [ ] scan/2 +- [ ] scan/3 +- [ ] shuffle/1 +- [ ] slice/2 +- [ ] slice/3 +- [ ] sort/1 +- [ ] sort/2 +- [ ] sort_by/2 +- [ ] sort_by/3 +- [ ] split/2 +- [ ] split_while/2 +- [ ] split_with/2 +- [ ] sum/1 +- [X] take/2 +- [X] take_every/2 +- [ ] take_random/2 +- [X] take_while/2 +- [X] to_list/1 +- [ ] uniq/1 +- [ ] uniq/2 +- [ ] uniq_by/2 +- [ ] unzip/1 +- [ ] with_index/1 +- [ ] with_index/2 +- [ ] zip/1 +- [ ] zip/2 +## Keyword +- [ ] delete/2 +- [ ] delete/3 +- [ ] delete_first/2 +- [ ] drop/2 +- [ ] equal?/2 +- [ ] fetch/2 +- [ ] fetch!/2 +- [X] get/2 +- [X] get/3 +- [ ] get_and_update/3 +- [ ] get_and_update!/3 +- [ ] get_lazy/3 +- [ ] get_values/2 +- [X] has_key?/2 +- [ ] keys/1 +- [ ] keyword?/1 +- [ ] merge/2 +- [ ] merge/3 +- [X] new/0 +- [ ] new/1 +- [ ] new/2 +- [ ] pop/2 +- [ ] pop/3 +- [ ] pop_first/2 +- [ ] pop_first/3 +- [ ] pop_lazy/3 +- [ ] put/3 +- [ ] put_new/3 +- [ ] put_new_lazy/3 +- [ ] size/1 +- [ ] split/2 +- [ ] take/2 +- [ ] to_list/1 +- [ ] update/4 +- [ ] update!/3 +- [ ] values/1 +## Collectable.HashDict +- [ ] __impl__/1 +- [ ] into/1 +## Enumerable.File.Stream +- [ ] __impl__/1 +- [ ] count/1 +- [ ] member?/2 +- [ ] reduce/3 +## Access +- [ ] all/0 +- [ ] at/1 +- [ ] elem/1 +- [ ] fetch/2 +- [ ] get/2 +- [ ] get/3 +- [ ] get_and_update/3 +- [ ] key/1 +- [ ] key/2 +- [ ] key!/1 +- [ ] pop/2 +## IO.Stream +- [ ] __build__/3 +- [ ] __struct__/0 +- [ ] __struct__/1 +## Enumerable.Stream +- [ ] __impl__/1 +- [ ] count/1 +- [ ] member?/2 +- [ ] reduce/3 +## Stream +- [ ] __struct__/0 +- [ ] __struct__/1 +- [ ] chunk/2 +- [ ] chunk/3 +- [ ] chunk/4 +- [ ] chunk_by/2 +- [ ] concat/1 +- [ ] concat/2 +- [ ] cycle/1 +- [ ] dedup/1 +- [ ] dedup_by/2 +- [ ] drop/2 +- [ ] drop_every/2 +- [ ] drop_while/2 +- [ ] each/2 +- [ ] filter/2 +- [ ] filter_map/3 +- [ ] flat_map/2 +- [ ] interval/1 +- [ ] into/2 +- [ ] into/3 +- [ ] iterate/2 +- [ ] map/2 +- [ ] map_every/3 +- [ ] reject/2 +- [ ] repeatedly/1 +- [ ] resource/3 +- [ ] run/1 +- [ ] scan/2 +- [ ] scan/3 +- [ ] take/2 +- [ ] take_every/2 +- [ ] take_while/2 +- [ ] timer/1 +- [ ] transform/3 +- [ ] transform/4 +- [ ] unfold/2 +- [ ] uniq/1 +- [ ] uniq/2 +- [ ] uniq_by/2 +- [ ] with_index/1 +- [ ] with_index/2 +- [ ] zip/1 +- [ ] zip/2 +## Task.Supervisor +- [ ] async/2 +- [ ] async/4 +- [ ] async_nolink/2 +- [ ] async_nolink/4 +- [ ] async_stream/3 +- [ ] async_stream/4 +- [ ] async_stream/5 +- [ ] async_stream/6 +- [ ] async_stream_nolink/3 +- [ ] async_stream_nolink/4 +- [ ] async_stream_nolink/5 +- [ ] async_stream_nolink/6 +- [ ] children/1 +- [ ] start_child/2 +- [ ] start_child/4 +- [ ] start_link/0 +- [ ] start_link/1 +- [ ] terminate_child/2 +## Inspect.Version.Requirement +- [ ] __impl__/1 +- [ ] inspect/2 +## TryClauseError +- [ ] __struct__/0 +- [ ] __struct__/1 +- [ ] exception/1 +- [ ] message/1 +## Version +- [ ] __struct__/0 +- [ ] __struct__/1 +- [ ] compare/2 +- [ ] compile_requirement/1 +- [ ] match?/2 +- [ ] match?/3 +- [ ] parse/1 +- [ ] parse!/1 +- [ ] parse_requirement/1 +## Record +- [ ] __access__/4 +- [ ] __access__/5 +- [ ] __fields__/2 +- [ ] __keyword__/3 +- [ ] extract/2 +- [ ] extract_all/1 +- [ ] defrecord/2 +- [ ] defrecord/3 +- [ ] defrecordp/2 +- [ ] defrecordp/3 +- [ ] is_record/1 +- [ ] is_record/2 +## CondClauseError +- [ ] __struct__/0 +- [ ] __struct__/1 +- [ ] exception/1 +- [ ] message/1 +## Inspect.Integer +- [ ] __impl__/1 +- [ ] inspect/2 +## List +- [X] delete/2 +- [X] delete_at/2 +- [X] duplicate/2 +- [X] first/1 +- [X] flatten/1 +- [X] flatten/2 +- [X] foldl/3 +- [X] foldr/3 +- [X] insert_at/3 +- [X] keydelete/3 +- [X] keyfind/3 +- [X] keyfind/4 +- [X] keymember?/3 +- [X] keyreplace/4 +- [ ] keysort/2 +- [ ] keystore/4 +- [ ] keytake/3 +- [X] last/1 +- [ ] myers_difference/2 +- [ ] pop_at/2 +- [ ] pop_at/3 +- [X] replace_at/3 +- [ ] to_atom/1 +- [ ] to_existing_atom/1 +- [ ] to_float/1 +- [ ] to_integer/1 +- [ ] to_integer/2 +- [ ] to_string/1 +- [X] to_tuple/1 +- [X] update_at/3 +- [X] wrap/1 +- [X] zip/1 +## Regex +- [ ] __struct__/0 +- [ ] __struct__/1 +- [X] compile/1 +- [X] compile/2 +- [X] compile!/1 +- [X] compile!/2 +- [ ] escape/1 +- [X] match?/2 +- [ ] named_captures/2 +- [ ] named_captures/3 +- [ ] names/1 +- [X] opts/1 +- [ ] re_pattern/1 +- [X] regex?/1 +- [X] replace/3 +- [X] replace/4 +- [X] run/2 +- [X] run/3 +- [X] scan/2 +- [X] scan/3 +- [X] source/1 +- [ ] split/2 +- [ ] split/3 +- [ ] unescape_map/1 +## Collectable.IO.Stream +- [ ] __impl__/1 +- [ ] into/1 +## File.Error +- [ ] __struct__/0 +- [ ] __struct__/1 +- [ ] exception/1 +- [ ] message/1 +## Inspect.Algebra +- [ ] break/0 +- [ ] break/1 +- [ ] color/3 +- [ ] concat/1 +- [ ] concat/2 +- [ ] empty/0 +- [ ] fold_doc/2 +- [ ] format/2 +- [ ] glue/2 +- [ ] glue/3 +- [ ] group/1 +- [ ] line/2 +- [ ] nest/2 +- [ ] space/2 +- [ ] surround/3 +- [ ] surround_many/5 +- [ ] surround_many/6 +- [ ] to_doc/2 +## Node +- [ ] alive?/0 +- [ ] connect/1 +- [ ] disconnect/1 +- [ ] get_cookie/0 +- [ ] list/0 +- [ ] list/1 +- [ ] monitor/2 +- [ ] monitor/3 +- [ ] ping/1 +- [ ] self/0 +- [ ] set_cookie/1 +- [ ] set_cookie/2 +- [ ] spawn/2 +- [ ] spawn/3 +- [ ] spawn/4 +- [ ] spawn/5 +- [ ] spawn_link/2 +- [ ] spawn_link/4 +- [ ] start/1 +- [ ] start/2 +- [ ] start/3 +- [ ] stop/0 +## File.CopyError +- [ ] __struct__/0 +- [ ] __struct__/1 +- [ ] exception/1 +- [ ] message/1 +## Port +- [ ] close/1 +- [ ] command/2 +- [ ] command/3 +- [ ] connect/2 +- [ ] info/1 +- [ ] info/2 +- [ ] list/0 +- [ ] open/2 +## Enumerable.MapSet +- [ ] __impl__/1 +- [ ] count/1 +- [ ] member?/2 +- [ ] reduce/3 +## Inspect.Stream +- [ ] __impl__/1 +- [ ] inspect/2 +## Kernel.ParallelRequire +- [ ] files/1 +- [ ] files/2 +## FunctionClauseError +- [ ] __struct__/0 +- [ ] __struct__/1 +- [ ] exception/1 +- [ ] message/1 +## Enumerable.Function +- [ ] __impl__/1 +- [ ] count/1 +- [ ] member?/2 +- [ ] reduce/3 +## GenServer +- [ ] abcast/2 +- [ ] abcast/3 +- [ ] call/2 +- [ ] call/3 +- [ ] cast/2 +- [ ] multi_call/2 +- [ ] multi_call/3 +- [ ] multi_call/4 +- [ ] reply/2 +- [ ] start/2 +- [ ] start/3 +- [ ] start_link/2 +- [ ] start_link/3 +- [ ] stop/1 +- [ ] stop/2 +- [ ] stop/3 +- [ ] whereis/1 +- [ ] __using__/1 +## List.Chars +- [ ] __protocol__/1 +- [ ] impl_for/1 +- [ ] impl_for!/1 +- [ ] to_char_list/1 +- [ ] to_charlist/1 +## Inspect.Atom +- [ ] __impl__/1 +- [ ] inspect/1 +- [ ] inspect/2 +## Inspect.HashDict +- [ ] __impl__/1 +- [ ] inspect/2 +## Enumerable.IO.Stream +- [ ] __impl__/1 +- [ ] count/1 +- [ ] member?/2 +- [ ] reduce/3 +## Kernel.Typespec +- [ ] beam_callbacks/1 +- [ ] beam_specs/1 +- [ ] beam_typedocs/1 +- [ ] beam_types/1 +- [ ] define_spec/3 +- [ ] define_type/3 +- [ ] define_type/4 +- [ ] defines_callback?/3 +- [ ] defines_spec?/3 +- [ ] defines_type?/3 +- [ ] defspec/3 +- [ ] deftype/3 +- [ ] spec_to_ast/2 +- [ ] spec_to_signature/1 +- [ ] translate_spec/3 +- [ ] translate_type/3 +- [ ] type_to_ast/1 +- [ ] type_to_signature/1 +- [ ] defcallback/1 +- [ ] defmacrocallback/1 +- [ ] defopaque/1 +- [ ] defoptional_callbacks/1 +- [ ] defspec/1 +- [ ] deftype/1 +- [ ] deftypep/1 +## KeyError +- [ ] __struct__/0 +- [ ] __struct__/1 +- [ ] exception/1 +- [ ] message/1 +## MapSet +- [X] __struct__/0 +- [X] __struct__/1 +- [X] delete/2 +- [X] difference/2 +- [X] disjoint?/2 +- [X] equal?/2 +- [X] intersection/2 +- [X] member?/2 +- [X] new/0 +- [ ] new/1 +- [ ] new/2 +- [X] put/2 +- [X] size/1 +- [X] subset?/2 +- [X] to_list/1 +- [X] union/2 +## Macro +- [ ] camelize/1 +- [ ] decompose_call/1 +- [ ] escape/1 +- [ ] escape/2 +- [ ] expand/2 +- [ ] expand_once/2 +- [ ] pipe/3 +- [ ] pipe_warning/1 +- [ ] postwalk/2 +- [ ] postwalk/3 +- [ ] prewalk/2 +- [ ] prewalk/3 +- [ ] to_string/1 +- [ ] to_string/2 +- [ ] traverse/4 +- [ ] underscore/1 +- [ ] unescape_string/1 +- [ ] unescape_string/2 +- [ ] unescape_tokens/1 +- [ ] unescape_tokens/2 +- [ ] unpipe/1 +- [ ] update_meta/2 +- [ ] validate/1 +- [ ] var/2 +- [ ] binary_ops/0 +- [ ] unary_ops/0 +## URI +- [ ] __struct__/0 +- [ ] __struct__/1 +- [ ] char_reserved?/1 +- [ ] char_unescaped?/1 +- [ ] char_unreserved?/1 +- [ ] decode/1 +- [ ] decode_query/1 +- [ ] decode_query/2 +- [ ] decode_www_form/1 +- [ ] default_port/1 +- [ ] default_port/2 +- [ ] encode/1 +- [ ] encode/2 +- [ ] encode_query/1 +- [ ] encode_www_form/1 +- [ ] merge/2 +- [ ] parse/1 +- [ ] path_to_segments/1 +- [ ] query_decoder/1 +- [ ] to_string/1 +## Inspect.Opts +- [ ] __struct__/0 +- [ ] __struct__/1 +## Atom +- [X] to_char_list/1 +- [ ] to_charlist/1 +- [X] to_string/1 +## TokenMissingError +- [ ] __struct__/0 +- [ ] __struct__/1 +- [ ] exception/1 +- [ ] message/1 +## BadBooleanError +- [ ] __struct__/0 +- [ ] __struct__/1 +- [ ] exception/1 +- [ ] message/1 +## String.Chars.Date +- [ ] __impl__/1 +- [ ] to_string/1 +## Set +- [ ] delete/2 +- [ ] difference/2 +- [ ] disjoint?/2 +- [ ] empty/1 +- [ ] equal?/2 +- [ ] intersection/2 +- [ ] member?/2 +- [ ] put/2 +- [ ] size/1 +- [ ] subset?/2 +- [ ] to_list/1 +- [ ] union/2 +## WithClauseError +- [ ] __struct__/0 +- [ ] __struct__/1 +- [ ] exception/1 +- [ ] message/1 +## List.Chars.Atom +- [ ] __impl__/1 +- [ ] to_charlist/1 +## Version.InvalidRequirementError +- [ ] __struct__/0 +- [ ] __struct__/1 +- [ ] exception/1 +- [ ] message/1 +## Application +- [ ] app_dir/1 +- [ ] app_dir/2 +- [ ] delete_env/2 +- [ ] delete_env/3 +- [ ] ensure_all_started/1 +- [ ] ensure_all_started/2 +- [ ] ensure_started/1 +- [ ] ensure_started/2 +- [ ] fetch_env/2 +- [ ] fetch_env!/2 +- [ ] format_error/1 +- [ ] get_all_env/1 +- [ ] get_application/1 +- [ ] get_env/2 +- [ ] get_env/3 +- [ ] load/1 +- [ ] loaded_applications/0 +- [ ] put_env/3 +- [ ] put_env/4 +- [ ] spec/1 +- [ ] spec/2 +- [ ] start/1 +- [ ] start/2 +- [ ] started_applications/0 +- [ ] started_applications/1 +- [ ] stop/1 +- [ ] unload/1 +- [ ] __using__/1 +## Inspect.PID +- [ ] __impl__/1 +- [ ] inspect/2 +## Calendar.ISO +- [ ] date/3 +- [ ] date_to_iso8601/3 +- [ ] date_to_string/3 +- [ ] datetime_to_iso8601/11 +- [ ] datetime_to_string/11 +- [ ] day_of_week/3 +- [ ] days_in_month/2 +- [ ] from_unix/2 +- [ ] leap_year?/1 +- [ ] naive_datetime_to_iso8601/7 +- [ ] naive_datetime_to_string/7 +- [ ] parse_microsecond/1 +- [ ] parse_offset/1 +- [ ] time_to_iso8601/4 +- [ ] time_to_string/4 diff --git a/lib/elixir_script/gen/supported.ex b/lib/elixir_script/gen/supported.ex new file mode 100644 index 00000000..422c3670 --- /dev/null +++ b/lib/elixir_script/gen/supported.ex @@ -0,0 +1,70 @@ +defmodule ElixirScript.Gen.Supported do + @moduledoc false + @private_modules [ + Kernel.Utils, + String.Normalizer, + Version.Parser, + IO.ANSI.Sequence, + Version.Parser.DSL, + String.Break, + IO.ANSI.Docs, + Kernel.LexicalTracker, + Task.Supervised, + Supervisor.Default, + Registry.Partition, + Module.LocalsTracker, + Kernel.CLI, + Registry.Supervisor, + Stream.Reducers, + Agent.Server, + ] + + def generate() do + File.open!("Supported.md", [:write], &write_to_file/1) + end + + def write_to_file(file) do + IO.puts(file, "# Supported Elixir Modules") + module_map = get_module_map() + + Enum.each(module_map, fn({elixir_module, elixir_script_module}) -> + IO.puts(file, "## #{inspect elixir_module}") + exports = elixir_module.__info__(:functions) ++ elixir_module.__info__(:macros) + elixir_script_exports = if Code.ensure_loaded?(elixir_script_module) do + elixir_script_module.__info__(:functions) ++ elixir_script_module.__info__(:macros) + else + [] + end + + Enum.each(exports, fn({func, arity}) -> + if Enum.member?(elixir_script_exports, {func, arity}) do + IO.puts(file, "- [X] #{func}/#{arity}") + else + IO.puts(file, "- [ ] #{func}/#{arity}") + end + end) + end) + end + + defp get_module_map() do + Application.spec(:elixir, :modules) + |> Enum.filter(&is_public(&1)) + |> Enum.reduce(Map.new, fn(x, acc) -> + try do + elixirscript_module = (["ElixirScript"] ++ Module.split(x)) |> Module.concat() + Map.put(acc, x, elixirscript_module) + rescue + FunctionClauseError -> + acc + end + end) + end + + defp is_public(m) when m in @private_modules do + false + end + + defp is_public(_) do + true + end +end \ No newline at end of file diff --git a/lib/elixir_script/translator.ex b/lib/elixir_script/translator.ex index ca71c476..d8c11001 100644 --- a/lib/elixir_script/translator.ex +++ b/lib/elixir_script/translator.ex @@ -167,11 +167,6 @@ defmodule ElixirScript.Translator do Expression.make_binary_expression(:%, left, right, env) end - defp do_translate({:throw, _, [params]}, env) do - { result, env } = translate(params, env) - { JS.throw_statement(result), env } - end - defp do_translate({:<>, context, [left, right]}, env) do translate({:+, context, [left, right]}, env) end diff --git a/mix.exs b/mix.exs index c31d1f54..869e92d8 100644 --- a/mix.exs +++ b/mix.exs @@ -62,7 +62,8 @@ defmodule ElixirScript.Mixfile do defp aliases do [dist: &dist/1, - install: &install/1] + install: &install/1, + supported: &supported/1] end def dist(_) do @@ -105,4 +106,10 @@ defmodule ElixirScript.Mixfile do IO.puts("installed at /usr/local/elixirscript") end + def supported(_) do + Mix.Task.run "app.start" + + ElixirScript.Gen.Supported.generate() + end + end diff --git a/priv/std_lib/exceptions.ex b/priv/std_lib/exceptions.ex index cb2ce0c5..4f723003 100644 --- a/priv/std_lib/exceptions.ex +++ b/priv/std_lib/exceptions.ex @@ -1,3 +1,7 @@ defmodule ElixirScript.ArgumentError do defexception message: "argument error" +end + +defmodule ElixirScript.RuntimeError do + defexception message: "runtime error" end \ No newline at end of file diff --git a/priv/std_lib/kernel.ex b/priv/std_lib/kernel.ex index 1bc4dbe4..83978563 100644 --- a/priv/std_lib/kernel.ex +++ b/priv/std_lib/kernel.ex @@ -202,4 +202,8 @@ defmodule ElixirScript.Kernel do %ElixirScript.Range{ first: unquote(first), last: unquote(last) } end end + + def throw(term) do + JS.throw(term) + end end From c2a86ec1b53e8ac32b8b0f5b3d67f994b7682c07 Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Sun, 9 Apr 2017 09:44:54 -0500 Subject: [PATCH 077/418] Update supported.md with description --- Supported.md | 3 +++ lib/elixir_script/gen/supported.ex | 1 + 2 files changed, 4 insertions(+) diff --git a/Supported.md b/Supported.md index 42a37640..6b339f91 100644 --- a/Supported.md +++ b/Supported.md @@ -1,4 +1,7 @@ # Supported Elixir Modules + +List all public modules in the Elixir Standard Libary. If a function or macro is supported in ElixirScript, it is checked + ## BadStructError - [ ] __struct__/0 - [ ] __struct__/1 diff --git a/lib/elixir_script/gen/supported.ex b/lib/elixir_script/gen/supported.ex index 422c3670..0f3adfaa 100644 --- a/lib/elixir_script/gen/supported.ex +++ b/lib/elixir_script/gen/supported.ex @@ -25,6 +25,7 @@ defmodule ElixirScript.Gen.Supported do def write_to_file(file) do IO.puts(file, "# Supported Elixir Modules") + IO.puts(file, "List all public modules in the Elixir Standard Libary. If a function or macro is supported in ElixirScript, it is checked") module_map = get_module_map() Enum.each(module_map, fn({elixir_module, elixir_script_module}) -> From 5914b3cb7b26411b0150dc031a73ddebce20e03b Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Sun, 9 Apr 2017 09:59:36 -0500 Subject: [PATCH 078/418] Check of raise --- Supported.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Supported.md b/Supported.md index 6b339f91..4f331299 100644 --- a/Supported.md +++ b/Supported.md @@ -244,8 +244,8 @@ List all public modules in the Elixir Standard Libary. If a function or macro is - [X] or/2 - [ ] pop_in/1 - [ ] put_in/2 -- [ ] raise/1 -- [ ] raise/2 +- [X] raise/1 +- [X] raise/2 - [ ] reraise/2 - [ ] reraise/3 - [ ] sigil_C/2 From fe5dce7d805ea87edf8462ac7346ae04bb094493 Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Sun, 9 Apr 2017 11:14:26 -0500 Subject: [PATCH 079/418] Update docs --- CONTRIBUTING.md | 17 ++++--- FAQ.md | 72 +----------------------------- lib/elixir_script/gen/supported.ex | 2 +- mix.exs | 2 +- 4 files changed, 11 insertions(+), 82 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 511aa424..b9884e8a 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -64,27 +64,26 @@ found in Elixir in ElixirScript. ElixirScript is broken up into the following parts: * The compiler, written in Elixir -* The standard library modules, mostly written in Elixir +* The standard library modules, written in Elixir * The javascript core The ElixirScript compiler is in the `lib` folder of the project. Here is where Elixir code is converted into JavaScript. -The standard library modules are in the `lib/std_lib` folder. +The standard library modules are in the `priv/std_lib` folder. The JavaScript code is in the `src/javascript`. -This is where features such as pattern matching and the standard library are implemented. +This is where features such as pattern matching and the special forms are implemented. The ElixirScript tests can be run using `mix test` -The JavaScript tests can be run using `npm test` +The JavaScript tests can be run using `yarn test` Please make sure all tests pass after making changes. Also make sure to include tests for the changes you made. -Contributing to the JavaScript code may be the easiest and most rewarding changes. -Don't see a feature, module or function from Elixir in ElixirScript yet? You can implement it -in the JavaScript code. +Contributing to the standard library may be the easiest and most rewarding changes. +Don't see a module, function or macro from Elixir in ElixirScript yet? You can help by implementing it. ## Pull requests @@ -119,7 +118,7 @@ in order to craft an excellent pull request: # Navigate to the newly cloned directory cd elixirscript # Assign the original repo to a remote called "upstream" - git remote add upstream https://github.com/bryanjos/elixirscript + git remote add upstream https://github.com/elixirscript/elixirscript ``` 2. If you cloned a while ago, get the latest changes from upstream: @@ -150,7 +149,7 @@ in order to craft an excellent pull request: ```sh mix test - npm test + yarn test ``` This is needed to ensure your changes can diff --git a/FAQ.md b/FAQ.md index 760b7aa7..92ba2f7e 100644 --- a/FAQ.md +++ b/FAQ.md @@ -6,77 +6,7 @@ # Q. How much is implemented? -### A. Most of Kernel.SpecialForms as well as some modules in the Standard Library - -The compiler to this point has been focused on translating Kernel.SpecialForms and Kernel. Below is a list of what is complete, incomplete, as well as missing - -#### Kernel.SpecialForms - -* Complete - * `__DIR__` - * `__MODULE__` - * `^var` - * `&expr` - * `for` - * `%{}` - * `{args}` - * `<>` - * `fn [clauses] end` - * `cond(clauses)` - * `__block__` - * `__aliases__` - * `unquote` - * `unquote_splicing` - * `%` - * `left.right` - * `quote` - * `import` - * `case` - * `left = right` - * `require` - * `left :: right` - * `alias` - * `__CALLER__` - * `__ENV__` - * `super(args)` - -* Missing - * `receive` - -* Caveats - * `quote` - ignores `context` options - * `left = right` does not support full unification yet. - ```elixir - a = 1 # works as expected - - 1 = a # may not work currently, but in some cases it will - ``` - - -#### Completed Modules - - * Tuple - * List - * Atom - * Range - * Map - * MapSet - -#### Incomplete Modules - - * Kernel - * Enum - * Agent - * Integer - * Keyword - * Base - * String - * Bitwise - * Set - -#### Missing Modules - * Everything else - +### A. Check out the [Supported Modules, Functions, and Macros](Supported.md) ## Q. Can I use it today? diff --git a/lib/elixir_script/gen/supported.ex b/lib/elixir_script/gen/supported.ex index 0f3adfaa..17ec8263 100644 --- a/lib/elixir_script/gen/supported.ex +++ b/lib/elixir_script/gen/supported.ex @@ -29,7 +29,7 @@ defmodule ElixirScript.Gen.Supported do module_map = get_module_map() Enum.each(module_map, fn({elixir_module, elixir_script_module}) -> - IO.puts(file, "## #{inspect elixir_module}") + IO.puts(file, "## #{inspect elixir_module}") exports = elixir_module.__info__(:functions) ++ elixir_module.__info__(:macros) elixir_script_exports = if Code.ensure_loaded?(elixir_script_module) do elixir_script_module.__info__(:functions) ++ elixir_script_module.__info__(:macros) diff --git a/mix.exs b/mix.exs index 869e92d8..8b257ebb 100644 --- a/mix.exs +++ b/mix.exs @@ -15,7 +15,7 @@ defmodule ElixirScript.Mixfile do aliases: aliases(), test_coverage: [tool: ExCoveralls], docs: [ - extras: ["GettingStarted.md", "FAQ.md"] + extras: ["GettingStarted.md", "FAQ.md", "Supported.md"] ] ] end From e1a6b21d3e59ae8039cfc388e17f04d53a6612c3 Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Sun, 9 Apr 2017 19:48:07 -0500 Subject: [PATCH 080/418] Getting global js state once on start --- CHANGELOG.md | 1 + lib/elixir_script/translator/kernel/js.ex | 15 ++++++--------- priv/std_lib/js.ex | 2 +- src/javascript/lib/core.js | 21 +++++++++++++++++++-- src/javascript/lib/core/functions.js | 13 ------------- test/translator/js_test.exs | 16 ++++++++-------- 6 files changed, 35 insertions(+), 33 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 91b0d510..710e2cbd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ### Added - `remove-unused` option that will remove all unused modules from output +- reimplemented structs to avoid creating JavaScript classes ## [0.27.0] - 2017-03-17 diff --git a/lib/elixir_script/translator/kernel/js.ex b/lib/elixir_script/translator/kernel/js.ex index 43c1c0d1..ea0c52e6 100644 --- a/lib/elixir_script/translator/kernel/js.ex +++ b/lib/elixir_script/translator/kernel/js.ex @@ -23,12 +23,9 @@ defmodule ElixirScript.Translator.JS do Builder.member_expression( Builder.member_expression( Builder.identifier("Bootstrap"), - Builder.member_expression( - Builder.identifier("Core"), - Builder.identifier("Functions") - ) + Builder.identifier("Core") ), - Builder.identifier("get_global") + Builder.identifier("global") ) end @@ -191,7 +188,7 @@ defmodule ElixirScript.Translator.JS do Builder.call_expression( call_property(), [ - Builder.call_expression(global(), []), + global(), Translator.translate!(to_string(function), env) ] ) @@ -200,7 +197,7 @@ defmodule ElixirScript.Translator.JS do defp do_translate({function, _, params}, env) do Builder.call_expression( Builder.member_expression( - Builder.call_expression(global(), []), + global(), Builder.identifier(function) ), Enum.map(params, &Translator.translate!(&1, env)) @@ -214,7 +211,7 @@ defmodule ElixirScript.Translator.JS do call_property(), [ Builder.member_expression( - Builder.call_expression(global(), []), + global(), members ), Translator.translate!(to_string(function), env) @@ -228,7 +225,7 @@ defmodule ElixirScript.Translator.JS do Builder.call_expression( Builder.member_expression( Builder.member_expression( - Builder.call_expression(global(), []), + global(), members ), Builder.identifier(function) diff --git a/priv/std_lib/js.ex b/priv/std_lib/js.ex index d9383a9a..3e3db5ac 100644 --- a/priv/std_lib/js.ex +++ b/priv/std_lib/js.ex @@ -52,7 +52,7 @@ defmodule JS do In node this would be the global object. """ def global() do - Bootstrap.Core.Functions.get_global() + Bootstrap.Core.global() end @doc """ diff --git a/src/javascript/lib/core.js b/src/javascript/lib/core.js index 8b488fb8..366a6a6a 100644 --- a/src/javascript/lib/core.js +++ b/src/javascript/lib/core.js @@ -5,8 +5,24 @@ import SpecialForms from './core/special_forms'; class Integer {} class Float {} -Functions.get_global().__elixirscript_store__ = new Map(); -Functions.get_global().__elixirscript_names__ = new Map(); + +function get_global() { + if (typeof self !== 'undefined') { + return self; + } else if (typeof window !== 'undefined') { + return window; + } else if (typeof global !== 'undefined') { + return global; + } + + console.warn('No global state found'); + return null; +} + +const globalState = get_global(); + +globalState.__elixirscript_store__ = new Map(); +globalState.__elixirscript_names__ = new Map(); export default { Tuple: ErlangTypes.Tuple, @@ -17,4 +33,5 @@ export default { Float, Functions, SpecialForms, + global: globalState, }; diff --git a/src/javascript/lib/core/functions.js b/src/javascript/lib/core/functions.js index f6d0e2df..d0d21099 100644 --- a/src/javascript/lib/core/functions.js +++ b/src/javascript/lib/core/functions.js @@ -52,18 +52,6 @@ function call_property(item, property) { return item[prop]; } -function get_global() { - if (typeof self !== 'undefined') { - return self; - } else if (typeof window !== 'undefined') { - return window; - } else if (typeof global !== 'undefined') { - return global; - } - - throw new Error('No global state found'); -} - function defprotocol(spec) { return new Protocol(spec); } @@ -97,7 +85,6 @@ function build_namespace(ns, ns_string) { export default { call_property, - get_global, defprotocol, defimpl, build_namespace, diff --git a/test/translator/js_test.exs b/test/translator/js_test.exs index 2118dba8..7dde65f2 100644 --- a/test/translator/js_test.exs +++ b/test/translator/js_test.exs @@ -5,48 +5,48 @@ defmodule ElixirScript.Translator.JS.Test do test "translate global function calls" do ex_ast = quote do: JS.alert("hi") - js_code = "Bootstrap.Core.Functions.get_global().alert('hi')" + js_code = "Bootstrap.Core.global.alert('hi')" assert_translation(ex_ast, js_code) ex_ast = quote do: JS.back() - js_code = "Bootstrap.Core.Functions.call_property(Bootstrap.Core.Functions.get_global(), 'back')" + js_code = "Bootstrap.Core.Functions.call_property(Bootstrap.Core.global, 'back')" assert_translation(ex_ast, js_code) end test "translate global properties" do ex_ast = quote do: JS.length - js_code = "Bootstrap.Core.Functions.call_property(Bootstrap.Core.Functions.get_global(), 'length')" + js_code = "Bootstrap.Core.Functions.call_property(Bootstrap.Core.global, 'length')" assert_translation(ex_ast, js_code) end test "translate global module" do ex_ast = quote do: JS.String.toString() - js_code = "Bootstrap.Core.Functions.call_property(Bootstrap.Core.Functions.get_global().String, 'toString')" + js_code = "Bootstrap.Core.Functions.call_property(Bootstrap.Core.global.String, 'toString')" assert_translation(ex_ast, js_code) ex_ast = quote do: JS.String.raw("hi") - js_code = "Bootstrap.Core.Functions.get_global().String.raw('hi')" + js_code = "Bootstrap.Core.global.String.raw('hi')" assert_translation(ex_ast, js_code) ex_ast = quote do: JS.Something.Other.raw("hi") - js_code = "Bootstrap.Core.Functions.get_global().Something.Other.raw('hi')" + js_code = "Bootstrap.Core.global.Something.Other.raw('hi')" assert_translation(ex_ast, js_code) end test "translate global lowercase" do ex_ast = quote do: JS.console.log("hi") - js_code = "Bootstrap.Core.Functions.call_property(Bootstrap.Core.Functions.get_global(), 'console').log('hi')" + js_code = "Bootstrap.Core.Functions.call_property(Bootstrap.Core.global, 'console').log('hi')" assert_translation(ex_ast, js_code) ex_ast = quote do: JS.window.length - js_code = "Bootstrap.Core.Functions.call_property(Bootstrap.Core.Functions.call_property(Bootstrap.Core.Functions.get_global(), 'window'), 'length')" + js_code = "Bootstrap.Core.Functions.call_property(Bootstrap.Core.Functions.call_property(Bootstrap.Core.global, 'window'), 'length')" assert_translation(ex_ast, js_code) end From 455113ea5d45bdd92d11640c085ef09cb86113af Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Sun, 9 Apr 2017 20:05:34 -0500 Subject: [PATCH 081/418] Update supported generator to order modules --- Supported.md | 3963 ++++++++++++++-------------- lib/elixir_script/gen/supported.ex | 114 +- 2 files changed, 2085 insertions(+), 1992 deletions(-) diff --git a/Supported.md b/Supported.md index 4f331299..69be84e1 100644 --- a/Supported.md +++ b/Supported.md @@ -1,2007 +1,2006 @@ # Supported Elixir Modules - List all public modules in the Elixir Standard Libary. If a function or macro is supported in ElixirScript, it is checked - -## BadStructError -- [ ] __struct__/0 -- [ ] __struct__/1 -- [ ] exception/1 -- [ ] message/1 -## Collectable.List -- [X] __impl__/1 -- [X] into/1 -## Inspect.Float -- [ ] __impl__/1 -- [ ] inspect/2 -## String.Chars.Version.Requirement -- [ ] __impl__/1 -- [ ] to_string/1 -## Inspect.NaiveDateTime -- [ ] __impl__/1 -- [ ] inspect/2 -## Inspect.MapSet -- [ ] __impl__/1 -- [ ] inspect/2 -## Inspect -- [ ] __protocol__/1 -- [ ] impl_for/1 -- [ ] impl_for!/1 -- [ ] inspect/2 -## Inspect.Range -- [ ] __impl__/1 -- [ ] inspect/2 +## Access +- [ ] `all/0` +- [ ] `at/1` +- [ ] `elem/1` +- [ ] `fetch/2` +- [ ] `get/2` +- [ ] `get/3` +- [ ] `get_and_update/3` +- [ ] `key/1` +- [ ] `key/2` +- [ ] `key!/1` +- [ ] `pop/2` +## Agent +- [ ] `cast/2` +- [ ] `cast/4` +- [X] `get/2` +- [ ] `get/3` +- [ ] `get/4` +- [ ] `get/5` +- [X] `get_and_update/2` +- [ ] `get_and_update/3` +- [ ] `get_and_update/4` +- [ ] `get_and_update/5` +- [X] `start/1` +- [X] `start/2` +- [ ] `start/3` +- [ ] `start/4` +- [X] `start_link/1` +- [X] `start_link/2` +- [ ] `start_link/3` +- [ ] `start_link/4` +- [X] `stop/1` +- [ ] `stop/2` +- [ ] `stop/3` +- [X] `update/2` +- [ ] `update/3` +- [ ] `update/4` +- [ ] `update/5` +## Application +- [ ] `app_dir/1` +- [ ] `app_dir/2` +- [ ] `delete_env/2` +- [ ] `delete_env/3` +- [ ] `ensure_all_started/1` +- [ ] `ensure_all_started/2` +- [ ] `ensure_started/1` +- [ ] `ensure_started/2` +- [ ] `fetch_env/2` +- [ ] `fetch_env!/2` +- [ ] `format_error/1` +- [ ] `get_all_env/1` +- [ ] `get_application/1` +- [ ] `get_env/2` +- [ ] `get_env/3` +- [ ] `load/1` +- [ ] `loaded_applications/0` +- [ ] `put_env/3` +- [ ] `put_env/4` +- [ ] `spec/1` +- [ ] `spec/2` +- [ ] `start/1` +- [ ] `start/2` +- [ ] `started_applications/0` +- [ ] `started_applications/1` +- [ ] `stop/1` +- [ ] `unload/1` +- [ ] `__using__/1` ## ArgumentError -- [X] __struct__/0 -- [X] __struct__/1 -- [X] exception/1 -- [X] message/1 +- [X] `__struct__/0` +- [X] `__struct__/1` +- [X] `exception/1` +- [X] `message/1` +## ArithmeticError +- [ ] `__struct__/0` +- [ ] `__struct__/1` +- [ ] `exception/1` +- [ ] `message/1` +## Atom +- [X] `to_char_list/1` +- [ ] `to_charlist/1` +- [X] `to_string/1` +## BadArityError +- [ ] `__struct__/0` +- [ ] `__struct__/1` +- [ ] `exception/1` +- [ ] `message/1` +## BadBooleanError +- [ ] `__struct__/0` +- [ ] `__struct__/1` +- [ ] `exception/1` +- [ ] `message/1` +## BadFunctionError +- [ ] `__struct__/0` +- [ ] `__struct__/1` +- [ ] `exception/1` +- [ ] `message/1` +## BadMapError +- [ ] `__struct__/0` +- [ ] `__struct__/1` +- [ ] `exception/1` +- [ ] `message/1` +## BadStructError +- [ ] `__struct__/0` +- [ ] `__struct__/1` +- [ ] `exception/1` +- [ ] `message/1` ## Base -- [ ] decode16/1 -- [ ] decode16/2 -- [ ] decode16!/1 -- [ ] decode16!/2 -- [ ] decode32/1 -- [ ] decode32/2 -- [ ] decode32!/1 -- [ ] decode32!/2 -- [X] decode64/1 -- [ ] decode64/2 -- [X] decode64!/1 -- [ ] decode64!/2 -- [ ] encode16/1 -- [ ] encode16/2 -- [ ] encode32/1 -- [ ] encode32/2 -- [X] encode64/1 -- [ ] encode64/2 -- [ ] hex_decode32/1 -- [ ] hex_decode32/2 -- [ ] hex_decode32!/1 -- [ ] hex_decode32!/2 -- [ ] hex_encode32/1 -- [ ] hex_encode32/2 -- [ ] url_decode64/1 -- [ ] url_decode64/2 -- [ ] url_decode64!/1 -- [ ] url_decode64!/2 -- [ ] url_encode64/1 -- [ ] url_encode64/2 -## Macro.Env -- [X] __struct__/0 -- [X] __struct__/1 -- [ ] in_guard?/1 -- [ ] in_match?/1 -- [ ] location/1 -- [ ] stacktrace/1 -## Collectable.Map -- [X] __impl__/1 -- [X] into/1 -## Inspect.Regex -- [ ] __impl__/1 -- [ ] inspect/2 +- [ ] `decode16/1` +- [ ] `decode16/2` +- [ ] `decode16!/1` +- [ ] `decode16!/2` +- [ ] `decode32/1` +- [ ] `decode32/2` +- [ ] `decode32!/1` +- [ ] `decode32!/2` +- [X] `decode64/1` +- [ ] `decode64/2` +- [X] `decode64!/1` +- [ ] `decode64!/2` +- [ ] `encode16/1` +- [ ] `encode16/2` +- [ ] `encode32/1` +- [ ] `encode32/2` +- [X] `encode64/1` +- [ ] `encode64/2` +- [ ] `hex_decode32/1` +- [ ] `hex_decode32/2` +- [ ] `hex_decode32!/1` +- [ ] `hex_decode32!/2` +- [ ] `hex_encode32/1` +- [ ] `hex_encode32/2` +- [ ] `url_decode64/1` +- [ ] `url_decode64/2` +- [ ] `url_decode64!/1` +- [ ] `url_decode64!/2` +- [ ] `url_encode64/1` +- [ ] `url_encode64/2` ## Behaviour -- [ ] __using__/1 -- [ ] defcallback/1 -- [ ] defmacrocallback/1 -## Collectable -- [X] __protocol__/1 -- [X] impl_for/1 -- [X] impl_for!/1 -- [X] into/1 -## String.Chars.Time -- [ ] __impl__/1 -- [ ] to_string/1 -## String.Chars.Atom -- [X] __impl__/1 -- [X] to_string/1 -## String.Chars -- [X] __protocol__/1 -- [X] impl_for/1 -- [X] impl_for!/1 -- [X] to_string/1 -## Integer -- [ ] digits/1 -- [ ] digits/2 -- [ ] floor_div/2 -- [ ] mod/2 -- [X] parse/1 -- [X] parse/2 -- [X] to_char_list/1 -- [ ] to_charlist/1 -- [ ] to_charlist/2 -- [ ] to_string/1 -- [ ] to_string/2 -- [ ] undigits/1 -- [ ] undigits/2 -- [X] is_even/1 -- [X] is_odd/1 -## String.Chars.NaiveDateTime -- [ ] __impl__/1 -- [ ] to_string/1 -## Inspect.Any -- [ ] __impl__/1 -- [ ] inspect/2 -## BadMapError -- [ ] __struct__/0 -- [ ] __struct__/1 -- [ ] exception/1 -- [ ] message/1 -## BadArityError -- [ ] __struct__/0 -- [ ] __struct__/1 -- [ ] exception/1 -- [ ] message/1 -## Kernel -- [X] !=/2 -- [X] !==/2 -- [X] */2 -- [X] +/1 -- [X] +/2 -- [X] ++/2 -- [X] -/1 -- [X] -/2 -- [X] --/2 -- [X] //2 -- [X] /2 -- [X] >=/2 -- [X] abs/1 -- [X] apply/2 -- [X] apply/3 -- [X] binary_part/3 -- [ ] bit_size/1 -- [ ] byte_size/1 -- [X] div/2 -- [X] elem/2 -- [ ] exit/1 -- [ ] function_exported?/3 -- [ ] get_and_update_in/3 -- [ ] get_in/2 -- [X] hd/1 -- [ ] inspect/1 -- [ ] inspect/2 -- [X] is_atom/1 -- [X] is_binary/1 -- [X] is_bitstring/1 -- [X] is_boolean/1 -- [X] is_float/1 -- [X] is_function/1 -- [X] is_function/2 -- [X] is_integer/1 -- [X] is_list/1 -- [X] is_map/1 -- [X] is_number/1 -- [X] is_pid/1 -- [X] is_port/1 -- [X] is_reference/1 -- [X] is_tuple/1 -- [X] length/1 -- [ ] macro_exported?/3 -- [ ] make_ref/0 -- [X] map_size/1 -- [X] max/2 -- [X] min/2 -- [ ] node/0 -- [ ] node/1 -- [ ] not/1 -- [ ] pop_in/2 -- [ ] put_elem/3 -- [ ] put_in/3 -- [X] rem/2 -- [X] round/1 -- [ ] self/0 -- [ ] send/2 -- [ ] spawn/1 -- [ ] spawn/3 -- [ ] spawn_link/1 -- [ ] spawn_link/3 -- [ ] spawn_monitor/1 -- [ ] spawn_monitor/3 -- [ ] struct/1 -- [ ] struct/2 -- [ ] struct!/1 -- [ ] struct!/2 -- [X] throw/1 -- [X] tl/1 -- [X] trunc/1 -- [X] tuple_size/1 -- [ ] update_in/3 -- [X] !/1 -- [X] &&/2 -- [X] ../2 -- [X] <>/2 -- [X] @/1 -- [ ] alias!/1 -- [X] and/2 -- [ ] binding/0 -- [ ] binding/1 -- [X] def/1 -- [X] def/2 -- [X] defdelegate/2 -- [X] defexception/1 -- [X] defimpl/2 -- [X] defimpl/3 -- [X] defmacro/1 -- [X] defmacro/2 -- [ ] defmacrop/1 -- [ ] defmacrop/2 -- [X] defmodule/2 -- [X] defoverridable/1 -- [X] defp/1 -- [X] defp/2 -- [X] defprotocol/2 -- [X] defstruct/1 -- [ ] destructure/2 -- [ ] get_and_update_in/2 -- [X] if/2 -- [X] in/2 -- [X] is_nil/1 -- [X] match?/2 -- [X] or/2 -- [ ] pop_in/1 -- [ ] put_in/2 -- [X] raise/1 -- [X] raise/2 -- [ ] reraise/2 -- [ ] reraise/3 -- [ ] sigil_C/2 -- [ ] sigil_D/2 -- [ ] sigil_N/2 -- [ ] sigil_R/2 -- [ ] sigil_S/2 -- [ ] sigil_T/2 -- [ ] sigil_W/2 -- [ ] sigil_c/2 -- [X] sigil_r/2 -- [ ] sigil_s/2 -- [ ] sigil_w/2 -- [ ] to_char_list/1 -- [ ] to_charlist/1 -- [X] to_string/1 -- [X] unless/2 -- [ ] update_in/2 -- [X] use/1 -- [X] use/2 -- [ ] var!/1 -- [ ] var!/2 -- [X] |>/2 -- [X] ||/2 -## Kernel.ParallelCompiler -- [ ] files/1 -- [ ] files/2 -- [ ] files_to_path/2 -- [ ] files_to_path/3 -## File.Stream -- [ ] __build__/3 -- [ ] __struct__/0 -- [ ] __struct__/1 -## Inspect.List -- [ ] __impl__/1 -- [ ] inspect/2 -- [ ] keyword/2 -- [ ] keyword?/1 -- [ ] printable?/1 -## Path.Wildcard -- [ ] list_dir/1 -- [ ] read_link_info/1 -## SyntaxError -- [ ] __struct__/0 -- [ ] __struct__/1 -- [ ] exception/1 -- [ ] message/1 -## List.Chars.List -- [ ] __impl__/1 -- [ ] to_charlist/1 +- [ ] `__using__/1` +- [ ] `defcallback/1` +- [ ] `defmacrocallback/1` +## Bitwise +- [X] `&&&/2` +- [X] `<<>>/2` +- [X] `^^^/2` +- [ ] `__using__/1` +- [X] `band/2` +- [X] `bnot/1` +- [X] `bor/2` +- [X] `bsl/2` +- [X] `bsr/2` +- [X] `bxor/2` +- [X] `|||/2` +- [X] `~~~/1` +## Calendar +## Calendar.ISO +- [ ] `date/3` +- [ ] `date_to_iso8601/3` +- [ ] `date_to_string/3` +- [ ] `datetime_to_iso8601/11` +- [ ] `datetime_to_string/11` +- [ ] `day_of_week/3` +- [ ] `days_in_month/2` +- [ ] `from_unix/2` +- [ ] `leap_year?/1` +- [ ] `naive_datetime_to_iso8601/7` +- [ ] `naive_datetime_to_string/7` +- [ ] `parse_microsecond/1` +- [ ] `parse_offset/1` +- [ ] `time_to_iso8601/4` +- [ ] `time_to_string/4` ## CaseClauseError -- [ ] __struct__/0 -- [ ] __struct__/1 -- [ ] exception/1 -- [ ] message/1 -## Path -- [ ] absname/1 -- [ ] absname/2 -- [ ] basename/1 -- [ ] basename/2 -- [ ] dirname/1 -- [ ] expand/1 -- [ ] expand/2 -- [ ] extname/1 -- [ ] join/1 -- [ ] join/2 -- [ ] relative/1 -- [ ] relative_to/2 -- [ ] relative_to_cwd/1 -- [ ] rootname/1 -- [ ] rootname/2 -- [ ] split/1 -- [ ] type/1 -- [ ] wildcard/1 -- [ ] wildcard/2 -## UnicodeConversionError -- [ ] __struct__/0 -- [ ] __struct__/1 -- [ ] exception/1 -- [ ] message/1 -## String.Chars.BitString -- [X] __impl__/1 -- [X] to_string/1 -## DateTime -- [ ] __struct__/0 -- [ ] __struct__/1 -- [ ] compare/2 -- [ ] from_iso8601/1 -- [ ] from_naive/2 -- [ ] from_naive!/2 -- [ ] from_unix/1 -- [ ] from_unix/2 -- [ ] from_unix!/1 -- [ ] from_unix!/2 -- [ ] to_date/1 -- [ ] to_iso8601/1 -- [ ] to_naive/1 -- [ ] to_string/1 -- [ ] to_time/1 -- [ ] to_unix/1 -- [ ] to_unix/2 -- [ ] utc_now/0 -## String.Chars.Float -- [X] __impl__/1 -- [X] to_string/1 +- [ ] `__struct__/0` +- [ ] `__struct__/1` +- [ ] `exception/1` +- [ ] `message/1` +## Code +- [ ] `append_path/1` +- [ ] `available_compiler_options/0` +- [ ] `compile_quoted/1` +- [ ] `compile_quoted/2` +- [ ] `compile_string/1` +- [ ] `compile_string/2` +- [ ] `compiler_options/0` +- [ ] `compiler_options/1` +- [ ] `delete_path/1` +- [ ] `ensure_compiled/1` +- [ ] `ensure_compiled?/1` +- [ ] `ensure_loaded/1` +- [ ] `ensure_loaded?/1` +- [ ] `eval_file/1` +- [ ] `eval_file/2` +- [ ] `eval_quoted/1` +- [ ] `eval_quoted/2` +- [ ] `eval_quoted/3` +- [ ] `eval_string/1` +- [ ] `eval_string/2` +- [ ] `eval_string/3` +- [ ] `get_docs/2` +- [ ] `load_file/1` +- [ ] `load_file/2` +- [ ] `loaded_files/0` +- [ ] `prepend_path/1` +- [ ] `require_file/1` +- [ ] `require_file/2` +- [ ] `string_to_quoted/1` +- [ ] `string_to_quoted/2` +- [ ] `string_to_quoted!/1` +- [ ] `string_to_quoted!/2` +- [ ] `unload_files/1` +## Code.LoadError +- [ ] `__struct__/0` +- [ ] `__struct__/1` +- [ ] `exception/1` +- [ ] `message/1` +## Collectable +- [X] `__protocol__/1` +- [X] `impl_for/1` +- [X] `impl_for!/1` +- [X] `into/1` +## Collectable.BitString +- [X] `__impl__/1` +- [X] `into/1` ## Collectable.File.Stream -- [ ] __impl__/1 -- [ ] into/1 -## String.Chars.URI -- [ ] __impl__/1 -- [ ] to_string/1 +- [ ] `__impl__/1` +- [ ] `into/1` +## Collectable.HashDict +- [ ] `__impl__/1` +- [ ] `into/1` +## Collectable.HashSet +- [ ] `__impl__/1` +- [ ] `into/1` +## Collectable.IO.Stream +- [ ] `__impl__/1` +- [ ] `into/1` +## Collectable.List +- [X] `__impl__/1` +- [X] `into/1` +## Collectable.Map +- [X] `__impl__/1` +- [X] `into/1` +## Collectable.MapSet +- [ ] `__impl__/1` +- [ ] `into/1` ## CompileError -- [ ] __struct__/0 -- [ ] __struct__/1 -- [ ] exception/1 -- [ ] message/1 -## File -- [ ] cd/1 -- [ ] cd!/1 -- [ ] cd!/2 -- [ ] chgrp/2 -- [ ] chgrp!/2 -- [ ] chmod/2 -- [ ] chmod!/2 -- [ ] chown/2 -- [ ] chown!/2 -- [ ] close/1 -- [ ] copy/2 -- [ ] copy/3 -- [ ] copy!/2 -- [ ] copy!/3 -- [ ] cp/2 -- [ ] cp/3 -- [ ] cp!/2 -- [ ] cp!/3 -- [ ] cp_r/2 -- [ ] cp_r/3 -- [ ] cp_r!/2 -- [ ] cp_r!/3 -- [ ] cwd/0 -- [ ] cwd!/0 -- [ ] dir?/1 -- [ ] exists?/1 -- [ ] ln_s/2 -- [ ] ls/0 -- [ ] ls/1 -- [ ] ls!/0 -- [ ] ls!/1 -- [ ] lstat/1 -- [ ] lstat/2 -- [ ] lstat!/1 -- [ ] lstat!/2 -- [ ] mkdir/1 -- [ ] mkdir!/1 -- [ ] mkdir_p/1 -- [ ] mkdir_p!/1 -- [ ] open/1 -- [ ] open/2 -- [ ] open/3 -- [ ] open!/1 -- [ ] open!/2 -- [ ] open!/3 -- [ ] read/1 -- [ ] read!/1 -- [ ] regular?/1 -- [ ] rename/2 -- [ ] rm/1 -- [ ] rm!/1 -- [ ] rm_rf/1 -- [ ] rm_rf!/1 -- [ ] rmdir/1 -- [ ] rmdir!/1 -- [ ] stat/1 -- [ ] stat/2 -- [ ] stat!/1 -- [ ] stat!/2 -- [ ] stream!/1 -- [ ] stream!/2 -- [ ] stream!/3 -- [ ] touch/1 -- [ ] touch/2 -- [ ] touch!/1 -- [ ] touch!/2 -- [ ] write/2 -- [ ] write/3 -- [ ] write!/2 -- [ ] write!/3 -- [ ] write_stat/2 -- [ ] write_stat/3 -- [ ] write_stat!/2 -- [ ] write_stat!/3 +- [ ] `__struct__/0` +- [ ] `__struct__/1` +- [ ] `exception/1` +- [ ] `message/1` +## CondClauseError +- [ ] `__struct__/0` +- [ ] `__struct__/1` +- [ ] `exception/1` +- [ ] `message/1` +## Date +- [ ] `__struct__/0` +- [ ] `__struct__/1` +- [ ] `compare/2` +- [ ] `day_of_week/1` +- [ ] `days_in_month/1` +- [ ] `from_erl/1` +- [ ] `from_erl!/1` +- [ ] `from_iso8601/1` +- [ ] `from_iso8601!/1` +- [ ] `leap_year?/1` +- [ ] `new/3` +- [ ] `to_erl/1` +- [ ] `to_iso8601/1` +- [ ] `to_string/1` +- [ ] `utc_today/0` +## DateTime +- [ ] `__struct__/0` +- [ ] `__struct__/1` +- [ ] `compare/2` +- [ ] `from_iso8601/1` +- [ ] `from_naive/2` +- [ ] `from_naive!/2` +- [ ] `from_unix/1` +- [ ] `from_unix/2` +- [ ] `from_unix!/1` +- [ ] `from_unix!/2` +- [ ] `to_date/1` +- [ ] `to_iso8601/1` +- [ ] `to_naive/1` +- [ ] `to_string/1` +- [ ] `to_time/1` +- [ ] `to_unix/1` +- [ ] `to_unix/2` +- [ ] `utc_now/0` ## Dict -- [ ] delete/2 -- [ ] drop/2 -- [ ] empty/1 -- [ ] equal?/2 -- [ ] fetch/2 -- [ ] fetch!/2 -- [ ] get/2 -- [ ] get/3 -- [ ] get_and_update/3 -- [ ] get_lazy/3 -- [ ] has_key?/2 -- [ ] keys/1 -- [ ] merge/2 -- [ ] merge/3 -- [ ] pop/2 -- [ ] pop/3 -- [ ] pop_lazy/3 -- [ ] put/3 -- [ ] put_new/3 -- [ ] put_new_lazy/3 -- [ ] size/1 -- [ ] split/2 -- [ ] take/2 -- [ ] to_list/1 -- [ ] update/4 -- [ ] update!/3 -- [ ] values/1 -- [ ] __using__/1 -## Version.Requirement -- [ ] __struct__/0 -- [ ] __struct__/1 -## String -- [X] at/2 -- [X] capitalize/1 -- [ ] chunk/2 -- [X] codepoints/1 -- [X] contains?/2 -- [X] downcase/1 -- [X] duplicate/2 -- [X] ends_with?/2 -- [ ] equivalent?/2 -- [X] first/1 -- [X] graphemes/1 -- [ ] jaro_distance/2 -- [X] last/1 -- [X] length/1 -- [ ] ljust/2 -- [ ] ljust/3 -- [ ] lstrip/1 -- [ ] lstrip/2 -- [X] match?/2 -- [ ] myers_difference/2 -- [X] next_codepoint/1 -- [X] next_grapheme/1 -- [ ] next_grapheme_size/1 -- [ ] normalize/2 -- [ ] pad_leading/2 -- [ ] pad_leading/3 -- [ ] pad_trailing/2 -- [ ] pad_trailing/3 -- [ ] printable?/1 -- [ ] replace/3 -- [ ] replace/4 -- [ ] replace_leading/3 -- [ ] replace_prefix/3 -- [ ] replace_suffix/3 -- [ ] replace_trailing/3 -- [X] reverse/1 -- [ ] rjust/2 -- [ ] rjust/3 -- [ ] rstrip/1 -- [ ] rstrip/2 -- [ ] slice/2 -- [ ] slice/3 -- [X] split/1 -- [X] split/2 -- [X] split/3 -- [ ] split_at/2 -- [ ] splitter/2 -- [ ] splitter/3 -- [X] starts_with?/2 -- [ ] strip/1 -- [ ] strip/2 -- [X] to_atom/1 -- [X] to_char_list/1 -- [ ] to_charlist/1 -- [X] to_existing_atom/1 -- [X] to_float/1 -- [X] to_integer/1 -- [X] to_integer/2 -- [ ] trim/1 -- [ ] trim/2 -- [ ] trim_leading/1 -- [ ] trim_leading/2 -- [ ] trim_trailing/1 -- [ ] trim_trailing/2 -- [X] upcase/1 -- [ ] valid?/1 -- [X] valid_character?/1 -## Record.Extractor -- [ ] extract/2 -- [ ] extract_all/1 -## Collectable.HashSet -- [ ] __impl__/1 -- [ ] into/1 -## String.Unicode -- [ ] codepoints/1 -- [ ] graphemes/1 -- [ ] length/1 -- [ ] next_codepoint/1 -- [ ] next_grapheme_size/1 -- [ ] split_at/2 -- [ ] version/0 -## ErlangError -- [ ] __struct__/0 -- [ ] __struct__/1 -- [ ] exception/1 -- [ ] message/1 -- [ ] normalize/2 -## File.Stat -- [ ] __struct__/0 -- [ ] __struct__/1 -- [ ] from_record/1 -- [ ] to_record/1 -## Inspect.Version -- [ ] __impl__/1 -- [ ] inspect/2 -## RuntimeError -- [X] __struct__/0 -- [X] __struct__/1 -- [X] exception/1 -- [X] message/1 -## Range -- [X] __struct__/0 -- [X] __struct__/1 -- [X] new/2 -- [X] range?/1 -## Exception -- [ ] exception?/1 -- [ ] format/2 -- [ ] format/3 -- [ ] format_banner/2 -- [ ] format_banner/3 -- [ ] format_exit/1 -- [ ] format_fa/2 -- [ ] format_file_line/2 -- [ ] format_file_line/3 -- [ ] format_mfa/3 -- [ ] format_stacktrace/0 -- [ ] format_stacktrace/1 -- [ ] format_stacktrace_entry/1 -- [ ] message/1 -- [ ] normalize/2 -- [ ] normalize/3 -## Inspect.Function -- [ ] __impl__/1 -- [ ] inspect/2 -## Enumerable.GenEvent.Stream -- [ ] __impl__/1 -- [ ] count/1 -- [ ] member?/2 -- [ ] reduce/3 +- [ ] `delete/2` +- [ ] `drop/2` +- [ ] `empty/1` +- [ ] `equal?/2` +- [ ] `fetch/2` +- [ ] `fetch!/2` +- [ ] `get/2` +- [ ] `get/3` +- [ ] `get_and_update/3` +- [ ] `get_lazy/3` +- [ ] `has_key?/2` +- [ ] `keys/1` +- [ ] `merge/2` +- [ ] `merge/3` +- [ ] `pop/2` +- [ ] `pop/3` +- [ ] `pop_lazy/3` +- [ ] `put/3` +- [ ] `put_new/3` +- [ ] `put_new_lazy/3` +- [ ] `size/1` +- [ ] `split/2` +- [ ] `take/2` +- [ ] `to_list/1` +- [ ] `update/4` +- [ ] `update!/3` +- [ ] `values/1` +- [ ] `__using__/1` +## Enum +- [X] `all?/1` +- [X] `all?/2` +- [X] `any?/1` +- [X] `any?/2` +- [X] `at/2` +- [X] `at/3` +- [ ] `chunk/2` +- [ ] `chunk/3` +- [ ] `chunk/4` +- [ ] `chunk_by/2` +- [X] `concat/1` +- [X] `concat/2` +- [X] `count/1` +- [X] `count/2` +- [ ] `dedup/1` +- [ ] `dedup_by/2` +- [X] `drop/2` +- [X] `drop_every/2` +- [X] `drop_while/2` +- [X] `each/2` +- [X] `empty?/1` +- [X] `fetch/2` +- [X] `fetch!/2` +- [X] `filter/2` +- [X] `filter_map/3` +- [X] `find/2` +- [X] `find/3` +- [ ] `find_index/2` +- [ ] `find_value/2` +- [ ] `find_value/3` +- [ ] `flat_map/2` +- [ ] `flat_map_reduce/3` +- [ ] `group_by/2` +- [ ] `group_by/3` +- [ ] `intersperse/2` +- [X] `into/2` +- [X] `into/3` +- [ ] `join/1` +- [ ] `join/2` +- [X] `map/2` +- [ ] `map_every/3` +- [ ] `map_join/2` +- [ ] `map_join/3` +- [X] `map_reduce/3` +- [ ] `max/1` +- [ ] `max/2` +- [ ] `max_by/2` +- [ ] `max_by/3` +- [X] `member?/2` +- [ ] `min/1` +- [ ] `min/2` +- [ ] `min_by/2` +- [ ] `min_by/3` +- [ ] `min_max/1` +- [ ] `min_max/2` +- [ ] `min_max_by/2` +- [ ] `min_max_by/3` +- [ ] `partition/2` +- [ ] `random/1` +- [X] `reduce/2` +- [X] `reduce/3` +- [ ] `reduce_while/3` +- [ ] `reject/2` +- [X] `reverse/1` +- [X] `reverse/2` +- [ ] `reverse_slice/3` +- [ ] `scan/2` +- [ ] `scan/3` +- [ ] `shuffle/1` +- [ ] `slice/2` +- [ ] `slice/3` +- [ ] `sort/1` +- [ ] `sort/2` +- [ ] `sort_by/2` +- [ ] `sort_by/3` +- [ ] `split/2` +- [ ] `split_while/2` +- [ ] `split_with/2` +- [ ] `sum/1` +- [X] `take/2` +- [X] `take_every/2` +- [ ] `take_random/2` +- [X] `take_while/2` +- [X] `to_list/1` +- [ ] `uniq/1` +- [ ] `uniq/2` +- [ ] `uniq_by/2` +- [ ] `unzip/1` +- [ ] `with_index/1` +- [ ] `with_index/2` +- [ ] `zip/1` +- [ ] `zip/2` +## Enum.EmptyError +- [ ] `__struct__/0` +- [ ] `__struct__/1` +- [ ] `exception/1` +- [ ] `message/1` ## Enum.OutOfBoundsError -- [X] __struct__/0 -- [X] __struct__/1 -- [X] exception/1 -- [X] message/1 +- [X] `__struct__/0` +- [X] `__struct__/1` +- [X] `exception/1` +- [X] `message/1` +## Enumerable +- [X] `__protocol__/1` +- [X] `count/1` +- [X] `impl_for/1` +- [X] `impl_for!/1` +- [X] `member?/2` +- [X] `reduce/3` +## Enumerable.File.Stream +- [ ] `__impl__/1` +- [ ] `count/1` +- [ ] `member?/2` +- [ ] `reduce/3` +## Enumerable.Function +- [ ] `__impl__/1` +- [ ] `count/1` +- [ ] `member?/2` +- [ ] `reduce/3` +## Enumerable.GenEvent.Stream +- [ ] `__impl__/1` +- [ ] `count/1` +- [ ] `member?/2` +- [ ] `reduce/3` +## Enumerable.HashDict +- [ ] `__impl__/1` +- [ ] `count/1` +- [ ] `member?/2` +- [ ] `reduce/3` +## Enumerable.HashSet +- [ ] `__impl__/1` +- [ ] `count/1` +- [ ] `member?/2` +- [ ] `reduce/3` +## Enumerable.IO.Stream +- [ ] `__impl__/1` +- [ ] `count/1` +- [ ] `member?/2` +- [ ] `reduce/3` +## Enumerable.List +- [X] `__impl__/1` +- [X] `count/1` +- [X] `member?/2` +- [X] `reduce/3` +## Enumerable.Map +- [X] `__impl__/1` +- [X] `count/1` +- [X] `member?/2` +- [X] `reduce/3` +## Enumerable.MapSet +- [ ] `__impl__/1` +- [ ] `count/1` +- [ ] `member?/2` +- [ ] `reduce/3` ## Enumerable.Range -- [ ] __impl__/1 -- [ ] count/1 -- [ ] member?/2 -- [ ] reduce/3 -## Date -- [ ] __struct__/0 -- [ ] __struct__/1 -- [ ] compare/2 -- [ ] day_of_week/1 -- [ ] days_in_month/1 -- [ ] from_erl/1 -- [ ] from_erl!/1 -- [ ] from_iso8601/1 -- [ ] from_iso8601!/1 -- [ ] leap_year?/1 -- [ ] new/3 -- [ ] to_erl/1 -- [ ] to_iso8601/1 -- [ ] to_string/1 -- [ ] utc_today/0 -## Inspect.Time -- [ ] __impl__/1 -- [ ] inspect/2 -## String.Casing -- [ ] downcase/1 -- [ ] titlecase_once/1 -- [ ] upcase/1 -## Regex.CompileError -- [ ] __struct__/0 -- [ ] __struct__/1 -- [ ] exception/1 -- [ ] message/1 -## Supervisor.Spec -- [ ] supervise/2 -- [ ] supervisor/2 -- [ ] supervisor/3 -- [ ] worker/2 -- [ ] worker/3 -## Collectable.MapSet -- [ ] __impl__/1 -- [ ] into/1 -## StringIO -- [ ] close/1 -- [ ] code_change/3 -- [ ] contents/1 -- [ ] flush/1 -- [ ] handle_call/3 -- [ ] handle_cast/2 -- [ ] handle_info/2 -- [ ] init/1 -- [ ] open/1 -- [ ] open/2 -- [ ] terminate/2 -## Inspect.Port -- [ ] __impl__/1 -- [ ] inspect/2 +- [ ] `__impl__/1` +- [ ] `count/1` +- [ ] `member?/2` +- [ ] `reduce/3` +## Enumerable.Stream +- [ ] `__impl__/1` +- [ ] `count/1` +- [ ] `member?/2` +- [ ] `reduce/3` +## ErlangError +- [ ] `__struct__/0` +- [ ] `__struct__/1` +- [ ] `exception/1` +- [ ] `message/1` +- [ ] `normalize/2` +## Exception +- [ ] `exception?/1` +- [ ] `format/2` +- [ ] `format/3` +- [ ] `format_banner/2` +- [ ] `format_banner/3` +- [ ] `format_exit/1` +- [ ] `format_fa/2` +- [ ] `format_file_line/2` +- [ ] `format_file_line/3` +- [ ] `format_mfa/3` +- [ ] `format_stacktrace/0` +- [ ] `format_stacktrace/1` +- [ ] `format_stacktrace_entry/1` +- [ ] `message/1` +- [ ] `normalize/2` +- [ ] `normalize/3` +## File +- [ ] `cd/1` +- [ ] `cd!/1` +- [ ] `cd!/2` +- [ ] `chgrp/2` +- [ ] `chgrp!/2` +- [ ] `chmod/2` +- [ ] `chmod!/2` +- [ ] `chown/2` +- [ ] `chown!/2` +- [ ] `close/1` +- [ ] `copy/2` +- [ ] `copy/3` +- [ ] `copy!/2` +- [ ] `copy!/3` +- [ ] `cp/2` +- [ ] `cp/3` +- [ ] `cp!/2` +- [ ] `cp!/3` +- [ ] `cp_r/2` +- [ ] `cp_r/3` +- [ ] `cp_r!/2` +- [ ] `cp_r!/3` +- [ ] `cwd/0` +- [ ] `cwd!/0` +- [ ] `dir?/1` +- [ ] `exists?/1` +- [ ] `ln_s/2` +- [ ] `ls/0` +- [ ] `ls/1` +- [ ] `ls!/0` +- [ ] `ls!/1` +- [ ] `lstat/1` +- [ ] `lstat/2` +- [ ] `lstat!/1` +- [ ] `lstat!/2` +- [ ] `mkdir/1` +- [ ] `mkdir!/1` +- [ ] `mkdir_p/1` +- [ ] `mkdir_p!/1` +- [ ] `open/1` +- [ ] `open/2` +- [ ] `open/3` +- [ ] `open!/1` +- [ ] `open!/2` +- [ ] `open!/3` +- [ ] `read/1` +- [ ] `read!/1` +- [ ] `regular?/1` +- [ ] `rename/2` +- [ ] `rm/1` +- [ ] `rm!/1` +- [ ] `rm_rf/1` +- [ ] `rm_rf!/1` +- [ ] `rmdir/1` +- [ ] `rmdir!/1` +- [ ] `stat/1` +- [ ] `stat/2` +- [ ] `stat!/1` +- [ ] `stat!/2` +- [ ] `stream!/1` +- [ ] `stream!/2` +- [ ] `stream!/3` +- [ ] `touch/1` +- [ ] `touch/2` +- [ ] `touch!/1` +- [ ] `touch!/2` +- [ ] `write/2` +- [ ] `write/3` +- [ ] `write!/2` +- [ ] `write!/3` +- [ ] `write_stat/2` +- [ ] `write_stat/3` +- [ ] `write_stat!/2` +- [ ] `write_stat!/3` +## File.CopyError +- [ ] `__struct__/0` +- [ ] `__struct__/1` +- [ ] `exception/1` +- [ ] `message/1` +## File.Error +- [ ] `__struct__/0` +- [ ] `__struct__/1` +- [ ] `exception/1` +- [ ] `message/1` +## File.Stat +- [ ] `__struct__/0` +- [ ] `__struct__/1` +- [ ] `from_record/1` +- [ ] `to_record/1` +## File.Stream +- [ ] `__build__/3` +- [ ] `__struct__/0` +- [ ] `__struct__/1` +## Float +- [ ] `ceil/1` +- [ ] `ceil/2` +- [ ] `floor/1` +- [ ] `floor/2` +- [ ] `parse/1` +- [ ] `ratio/1` +- [ ] `round/1` +- [ ] `round/2` +- [ ] `to_char_list/1` +- [ ] `to_char_list/2` +- [ ] `to_charlist/1` +- [ ] `to_string/1` +- [ ] `to_string/2` +## FunctionClauseError +- [ ] `__struct__/0` +- [ ] `__struct__/1` +- [ ] `exception/1` +- [ ] `message/1` +## GenEvent +- [ ] `ack_notify/2` +- [ ] `add_handler/3` +- [ ] `add_mon_handler/3` +- [ ] `call/3` +- [ ] `call/4` +- [ ] `format_status/2` +- [ ] `init_hib/4` +- [ ] `init_it/6` +- [ ] `notify/2` +- [ ] `remove_handler/3` +- [ ] `start/0` +- [ ] `start/1` +- [ ] `start_link/0` +- [ ] `start_link/1` +- [ ] `stop/1` +- [ ] `stop/2` +- [ ] `stop/3` +- [ ] `stream/1` +- [ ] `stream/2` +- [ ] `swap_handler/5` +- [ ] `swap_mon_handler/5` +- [ ] `sync_notify/2` +- [ ] `system_code_change/4` +- [ ] `system_continue/3` +- [ ] `system_get_state/1` +- [ ] `system_replace_state/2` +- [ ] `system_terminate/4` +- [ ] `which_handlers/1` +- [ ] `__using__/1` ## GenEvent.Stream -- [ ] __struct__/0 -- [ ] __struct__/1 -- [ ] code_change/3 -- [ ] handle_call/2 -- [ ] handle_event/2 -- [ ] handle_info/2 -- [ ] init/1 -- [ ] terminate/2 -## Protocol.UndefinedError -- [ ] __struct__/0 -- [ ] __struct__/1 -- [ ] exception/1 -- [ ] message/1 -## BadFunctionError -- [ ] __struct__/0 -- [ ] __struct__/1 -- [ ] exception/1 -- [ ] message/1 -## Time -- [ ] __struct__/0 -- [ ] __struct__/1 -- [ ] compare/2 -- [ ] from_erl/1 -- [ ] from_erl/2 -- [ ] from_erl!/1 -- [ ] from_erl!/2 -- [ ] from_iso8601/1 -- [ ] from_iso8601!/1 -- [ ] new/3 -- [ ] new/4 -- [ ] to_erl/1 -- [ ] to_iso8601/1 -- [ ] to_string/1 -- [ ] utc_now/0 -## List.Chars.BitString -- [ ] __impl__/1 -- [ ] to_charlist/1 -## Registry -- [ ] dispatch/3 -- [ ] keys/2 -- [ ] lookup/2 -- [ ] match/3 -- [ ] meta/2 -- [ ] put_meta/3 -- [ ] register/3 -- [ ] register_name/2 -- [ ] send/2 -- [ ] start_link/2 -- [ ] start_link/3 -- [ ] unregister/2 -- [ ] unregister_name/1 -- [ ] update_value/3 -- [ ] whereis_name/1 -## List.Chars.Float -- [ ] __impl__/1 -- [ ] to_charlist/1 -## Code.LoadError -- [ ] __struct__/0 -- [ ] __struct__/1 -- [ ] exception/1 -- [ ] message/1 -## ArithmeticError -- [ ] __struct__/0 -- [ ] __struct__/1 -- [ ] exception/1 -- [ ] message/1 -## String.Chars.List -- [X] __impl__/1 -- [X] to_string/1 +- [ ] `__struct__/0` +- [ ] `__struct__/1` +- [ ] `code_change/3` +- [ ] `handle_call/2` +- [ ] `handle_event/2` +- [ ] `handle_info/2` +- [ ] `init/1` +- [ ] `terminate/2` +## GenServer +- [ ] `abcast/2` +- [ ] `abcast/3` +- [ ] `call/2` +- [ ] `call/3` +- [ ] `cast/2` +- [ ] `multi_call/2` +- [ ] `multi_call/3` +- [ ] `multi_call/4` +- [ ] `reply/2` +- [ ] `start/2` +- [ ] `start/3` +- [ ] `start_link/2` +- [ ] `start_link/3` +- [ ] `stop/1` +- [ ] `stop/2` +- [ ] `stop/3` +- [ ] `whereis/1` +- [ ] `__using__/1` +## HashDict +- [ ] `__struct__/0` +- [ ] `__struct__/1` +- [ ] `delete/2` +- [ ] `dict_delete/2` +- [ ] `drop/2` +- [ ] `equal?/2` +- [ ] `fetch/2` +- [ ] `fetch!/2` +- [ ] `get/2` +- [ ] `get/3` +- [ ] `get_and_update/3` +- [ ] `get_lazy/3` +- [ ] `has_key?/2` +- [ ] `keys/1` +- [ ] `merge/2` +- [ ] `merge/3` +- [ ] `new/0` +- [ ] `pop/2` +- [ ] `pop/3` +- [ ] `pop_lazy/3` +- [ ] `put/3` +- [ ] `put_new/3` +- [ ] `put_new_lazy/3` +- [ ] `reduce/3` +- [ ] `size/1` +- [ ] `split/2` +- [ ] `take/2` +- [ ] `to_list/1` +- [ ] `update/4` +- [ ] `update!/3` +- [ ] `values/1` +## HashSet +- [ ] `__struct__/0` +- [ ] `__struct__/1` +- [ ] `delete/2` +- [ ] `difference/2` +- [ ] `disjoint?/2` +- [ ] `equal?/2` +- [ ] `intersection/2` +- [ ] `member?/2` +- [ ] `new/0` +- [ ] `put/2` +- [ ] `reduce/3` +- [ ] `size/1` +- [ ] `subset?/2` +- [ ] `to_list/1` +- [ ] `union/2` +## IO +- [ ] `binread/1` +- [ ] `binread/2` +- [ ] `binstream/2` +- [ ] `binwrite/1` +- [ ] `binwrite/2` +- [ ] `chardata_to_string/1` +- [ ] `each_binstream/2` +- [ ] `each_stream/2` +- [ ] `getn/1` +- [ ] `getn/2` +- [ ] `getn/3` +- [ ] `gets/1` +- [ ] `gets/2` +- [X] `inspect/1` +- [X] `inspect/2` +- [ ] `inspect/3` +- [ ] `iodata_length/1` +- [ ] `iodata_to_binary/1` +- [X] `puts/1` +- [X] `puts/2` +- [ ] `read/1` +- [ ] `read/2` +- [ ] `stream/2` +- [X] `warn/1` +- [ ] `warn/2` +- [ ] `write/1` +- [ ] `write/2` +## IO.ANSI +- [ ] `black/0` +- [ ] `black_background/0` +- [ ] `blink_off/0` +- [ ] `blink_rapid/0` +- [ ] `blink_slow/0` +- [ ] `blue/0` +- [ ] `blue_background/0` +- [ ] `bright/0` +- [ ] `clear/0` +- [ ] `clear_line/0` +- [ ] `color/1` +- [ ] `color/3` +- [ ] `color_background/1` +- [ ] `color_background/3` +- [ ] `conceal/0` +- [ ] `crossed_out/0` +- [ ] `cyan/0` +- [ ] `cyan_background/0` +- [ ] `default_background/0` +- [ ] `default_color/0` +- [ ] `enabled?/0` +- [ ] `encircled/0` +- [ ] `faint/0` +- [ ] `font_1/0` +- [ ] `font_2/0` +- [ ] `font_3/0` +- [ ] `font_4/0` +- [ ] `font_5/0` +- [ ] `font_6/0` +- [ ] `font_7/0` +- [ ] `font_8/0` +- [ ] `font_9/0` +- [ ] `format/1` +- [ ] `format/2` +- [ ] `format_fragment/1` +- [ ] `format_fragment/2` +- [ ] `framed/0` +- [ ] `green/0` +- [ ] `green_background/0` +- [ ] `home/0` +- [ ] `inverse/0` +- [ ] `inverse_off/0` +- [ ] `italic/0` +- [ ] `light_black/0` +- [ ] `light_black_background/0` +- [ ] `light_blue/0` +- [ ] `light_blue_background/0` +- [ ] `light_cyan/0` +- [ ] `light_cyan_background/0` +- [ ] `light_green/0` +- [ ] `light_green_background/0` +- [ ] `light_magenta/0` +- [ ] `light_magenta_background/0` +- [ ] `light_red/0` +- [ ] `light_red_background/0` +- [ ] `light_white/0` +- [ ] `light_white_background/0` +- [ ] `light_yellow/0` +- [ ] `light_yellow_background/0` +- [ ] `magenta/0` +- [ ] `magenta_background/0` +- [ ] `no_underline/0` +- [ ] `normal/0` +- [ ] `not_framed_encircled/0` +- [ ] `not_italic/0` +- [ ] `not_overlined/0` +- [ ] `overlined/0` +- [ ] `primary_font/0` +- [ ] `red/0` +- [ ] `red_background/0` +- [ ] `reset/0` +- [ ] `reverse/0` +- [ ] `reverse_off/0` +- [ ] `underline/0` +- [ ] `white/0` +- [ ] `white_background/0` +- [ ] `yellow/0` +- [ ] `yellow_background/0` +## IO.Stream +- [ ] `__build__/3` +- [ ] `__struct__/0` +- [ ] `__struct__/1` +## IO.StreamError +- [ ] `__struct__/0` +- [ ] `__struct__/1` +- [ ] `exception/1` +- [ ] `message/1` +## Inspect +- [ ] `__protocol__/1` +- [ ] `impl_for/1` +- [ ] `impl_for!/1` +- [ ] `inspect/2` +## Inspect.Algebra +- [ ] `break/0` +- [ ] `break/1` +- [ ] `color/3` +- [ ] `concat/1` +- [ ] `concat/2` +- [ ] `empty/0` +- [ ] `fold_doc/2` +- [ ] `format/2` +- [ ] `glue/2` +- [ ] `glue/3` +- [ ] `group/1` +- [ ] `line/2` +- [ ] `nest/2` +- [ ] `space/2` +- [ ] `surround/3` +- [ ] `surround_many/5` +- [ ] `surround_many/6` +- [ ] `to_doc/2` +## Inspect.Any +- [ ] `__impl__/1` +- [ ] `inspect/2` +## Inspect.Atom +- [ ] `__impl__/1` +- [ ] `inspect/1` +- [ ] `inspect/2` ## Inspect.BitString -- [ ] __impl__/1 -- [ ] escape/2 -- [ ] escape_char/1 -- [ ] inspect/2 +- [ ] `__impl__/1` +- [ ] `escape/2` +- [ ] `escape_char/1` +- [ ] `inspect/2` +## Inspect.Date +- [ ] `__impl__/1` +- [ ] `inspect/2` +## Inspect.Error +- [ ] `__struct__/0` +- [ ] `__struct__/1` +- [ ] `exception/1` +- [ ] `message/1` +## Inspect.Float +- [ ] `__impl__/1` +- [ ] `inspect/2` +## Inspect.Function +- [ ] `__impl__/1` +- [ ] `inspect/2` +## Inspect.HashDict +- [ ] `__impl__/1` +- [ ] `inspect/2` ## Inspect.HashSet -- [ ] __impl__/1 -- [ ] inspect/2 -## String.Chars.DateTime -- [ ] __impl__/1 -- [ ] to_string/1 +- [ ] `__impl__/1` +- [ ] `inspect/2` +## Inspect.Integer +- [ ] `__impl__/1` +- [ ] `inspect/2` +## Inspect.List +- [ ] `__impl__/1` +- [ ] `inspect/2` +- [ ] `keyword/2` +- [ ] `keyword?/1` +- [ ] `printable?/1` ## Inspect.Map -- [ ] __impl__/1 -- [ ] inspect/2 -- [ ] inspect/3 -## HashDict -- [ ] __struct__/0 -- [ ] __struct__/1 -- [ ] delete/2 -- [ ] dict_delete/2 -- [ ] drop/2 -- [ ] equal?/2 -- [ ] fetch/2 -- [ ] fetch!/2 -- [ ] get/2 -- [ ] get/3 -- [ ] get_and_update/3 -- [ ] get_lazy/3 -- [ ] has_key?/2 -- [ ] keys/1 -- [ ] merge/2 -- [ ] merge/3 -- [ ] new/0 -- [ ] pop/2 -- [ ] pop/3 -- [ ] pop_lazy/3 -- [ ] put/3 -- [ ] put_new/3 -- [ ] put_new_lazy/3 -- [ ] reduce/3 -- [ ] size/1 -- [ ] split/2 -- [ ] take/2 -- [ ] to_list/1 -- [ ] update/4 -- [ ] update!/3 -- [ ] values/1 -## NaiveDateTime -- [ ] __struct__/0 -- [ ] __struct__/1 -- [ ] add/2 -- [ ] add/3 -- [ ] compare/2 -- [ ] diff/2 -- [ ] diff/3 -- [ ] from_erl/1 -- [ ] from_erl/2 -- [ ] from_erl!/1 -- [ ] from_erl!/2 -- [ ] from_iso8601/1 -- [ ] from_iso8601!/1 -- [ ] new/2 -- [ ] new/6 -- [ ] new/7 -- [ ] to_date/1 -- [ ] to_erl/1 -- [ ] to_iso8601/1 -- [ ] to_string/1 -- [ ] to_time/1 -- [ ] utc_now/0 -## IO.ANSI -- [ ] black/0 -- [ ] black_background/0 -- [ ] blink_off/0 -- [ ] blink_rapid/0 -- [ ] blink_slow/0 -- [ ] blue/0 -- [ ] blue_background/0 -- [ ] bright/0 -- [ ] clear/0 -- [ ] clear_line/0 -- [ ] color/1 -- [ ] color/3 -- [ ] color_background/1 -- [ ] color_background/3 -- [ ] conceal/0 -- [ ] crossed_out/0 -- [ ] cyan/0 -- [ ] cyan_background/0 -- [ ] default_background/0 -- [ ] default_color/0 -- [ ] enabled?/0 -- [ ] encircled/0 -- [ ] faint/0 -- [ ] font_1/0 -- [ ] font_2/0 -- [ ] font_3/0 -- [ ] font_4/0 -- [ ] font_5/0 -- [ ] font_6/0 -- [ ] font_7/0 -- [ ] font_8/0 -- [ ] font_9/0 -- [ ] format/1 -- [ ] format/2 -- [ ] format_fragment/1 -- [ ] format_fragment/2 -- [ ] framed/0 -- [ ] green/0 -- [ ] green_background/0 -- [ ] home/0 -- [ ] inverse/0 -- [ ] inverse_off/0 -- [ ] italic/0 -- [ ] light_black/0 -- [ ] light_black_background/0 -- [ ] light_blue/0 -- [ ] light_blue_background/0 -- [ ] light_cyan/0 -- [ ] light_cyan_background/0 -- [ ] light_green/0 -- [ ] light_green_background/0 -- [ ] light_magenta/0 -- [ ] light_magenta_background/0 -- [ ] light_red/0 -- [ ] light_red_background/0 -- [ ] light_white/0 -- [ ] light_white_background/0 -- [ ] light_yellow/0 -- [ ] light_yellow_background/0 -- [ ] magenta/0 -- [ ] magenta_background/0 -- [ ] no_underline/0 -- [ ] normal/0 -- [ ] not_framed_encircled/0 -- [ ] not_italic/0 -- [ ] not_overlined/0 -- [ ] overlined/0 -- [ ] primary_font/0 -- [ ] red/0 -- [ ] red_background/0 -- [ ] reset/0 -- [ ] reverse/0 -- [ ] reverse_off/0 -- [ ] underline/0 -- [ ] white/0 -- [ ] white_background/0 -- [ ] yellow/0 -- [ ] yellow_background/0 -## Module -- [ ] add_doc/5 -- [ ] add_doc/6 -- [ ] compile_doc/6 -- [ ] concat/1 -- [ ] concat/2 -- [ ] create/3 -- [ ] defines?/2 -- [ ] defines?/3 -- [ ] definitions_in/1 -- [ ] definitions_in/2 -- [ ] delete_attribute/2 -- [ ] eval_quoted/2 -- [ ] eval_quoted/3 -- [ ] eval_quoted/4 -- [ ] get_attribute/2 -- [ ] get_attribute/3 -- [ ] make_overridable/2 -- [ ] open?/1 -- [ ] overridable?/2 -- [ ] put_attribute/3 -- [ ] put_attribute/5 -- [ ] register_attribute/3 -- [ ] safe_concat/1 -- [ ] safe_concat/2 -- [ ] split/1 -- [ ] store_typespec/3 -## IO -- [ ] binread/1 -- [ ] binread/2 -- [ ] binstream/2 -- [ ] binwrite/1 -- [ ] binwrite/2 -- [ ] chardata_to_string/1 -- [ ] each_binstream/2 -- [ ] each_stream/2 -- [ ] getn/1 -- [ ] getn/2 -- [ ] getn/3 -- [ ] gets/1 -- [ ] gets/2 -- [X] inspect/1 -- [X] inspect/2 -- [ ] inspect/3 -- [ ] iodata_length/1 -- [ ] iodata_to_binary/1 -- [X] puts/1 -- [X] puts/2 -- [ ] read/1 -- [ ] read/2 -- [ ] stream/2 -- [X] warn/1 -- [ ] warn/2 -- [ ] write/1 -- [ ] write/2 -## MatchError -- [ ] __struct__/0 -- [ ] __struct__/1 -- [ ] exception/1 -- [ ] message/1 -## Enumerable.HashSet -- [ ] __impl__/1 -- [ ] count/1 -- [ ] member?/2 -- [ ] reduce/3 -## Enumerable.HashDict -- [ ] __impl__/1 -- [ ] count/1 -- [ ] member?/2 -- [ ] reduce/3 -## Agent -- [ ] cast/2 -- [ ] cast/4 -- [X] get/2 -- [ ] get/3 -- [ ] get/4 -- [ ] get/5 -- [X] get_and_update/2 -- [ ] get_and_update/3 -- [ ] get_and_update/4 -- [ ] get_and_update/5 -- [X] start/1 -- [X] start/2 -- [ ] start/3 -- [ ] start/4 -- [X] start_link/1 -- [X] start_link/2 -- [ ] start_link/3 -- [ ] start_link/4 -- [X] stop/1 -- [ ] stop/2 -- [ ] stop/3 -- [X] update/2 -- [ ] update/3 -- [ ] update/4 -- [ ] update/5 -## String.Chars.Version -- [ ] __impl__/1 -- [ ] to_string/1 -## System -- [ ] argv/0 -- [ ] argv/1 -- [ ] at_exit/1 -- [ ] build_info/0 -- [ ] cmd/2 -- [ ] cmd/3 -- [ ] compiled_endianness/0 -- [ ] convert_time_unit/3 -- [ ] cwd/0 -- [ ] cwd!/0 -- [ ] delete_env/1 -- [ ] endianness/0 -- [ ] find_executable/1 -- [ ] get_env/0 -- [ ] get_env/1 -- [ ] get_pid/0 -- [ ] halt/0 -- [ ] halt/1 -- [ ] monotonic_time/0 -- [ ] monotonic_time/1 -- [ ] os_time/0 -- [ ] os_time/1 -- [ ] otp_release/0 -- [ ] put_env/1 -- [ ] put_env/2 -- [ ] schedulers/0 -- [ ] schedulers_online/0 -- [ ] stacktrace/0 -- [ ] system_time/0 -- [ ] system_time/1 -- [ ] time_offset/0 -- [ ] time_offset/1 -- [ ] tmp_dir/0 -- [ ] tmp_dir!/0 -- [ ] unique_integer/0 -- [ ] unique_integer/1 -- [ ] user_home/0 -- [ ] user_home!/0 -- [ ] version/0 +- [ ] `__impl__/1` +- [ ] `inspect/2` +- [ ] `inspect/3` +## Inspect.MapSet +- [ ] `__impl__/1` +- [ ] `inspect/2` +## Inspect.NaiveDateTime +- [ ] `__impl__/1` +- [ ] `inspect/2` +## Inspect.Opts +- [ ] `__struct__/0` +- [ ] `__struct__/1` +## Inspect.PID +- [ ] `__impl__/1` +- [ ] `inspect/2` +## Inspect.Port +- [ ] `__impl__/1` +- [ ] `inspect/2` +## Inspect.Range +- [ ] `__impl__/1` +- [ ] `inspect/2` +## Inspect.Reference +- [ ] `__impl__/1` +- [ ] `inspect/2` +## Inspect.Regex +- [ ] `__impl__/1` +- [ ] `inspect/2` +## Inspect.Stream +- [ ] `__impl__/1` +- [ ] `inspect/2` +## Inspect.Time +- [ ] `__impl__/1` +- [ ] `inspect/2` ## Inspect.Tuple -- [ ] __impl__/1 -- [ ] inspect/2 -## Collectable.BitString -- [X] __impl__/1 -- [X] into/1 -## Enumerable.Map -- [X] __impl__/1 -- [X] count/1 -- [X] member?/2 -- [X] reduce/3 -## Enum.EmptyError -- [ ] __struct__/0 -- [ ] __struct__/1 -- [ ] exception/1 -- [ ] message/1 -## GenEvent -- [ ] ack_notify/2 -- [ ] add_handler/3 -- [ ] add_mon_handler/3 -- [ ] call/3 -- [ ] call/4 -- [ ] format_status/2 -- [ ] init_hib/4 -- [ ] init_it/6 -- [ ] notify/2 -- [ ] remove_handler/3 -- [ ] start/0 -- [ ] start/1 -- [ ] start_link/0 -- [ ] start_link/1 -- [ ] stop/1 -- [ ] stop/2 -- [ ] stop/3 -- [ ] stream/1 -- [ ] stream/2 -- [ ] swap_handler/5 -- [ ] swap_mon_handler/5 -- [ ] sync_notify/2 -- [ ] system_code_change/4 -- [ ] system_continue/3 -- [ ] system_get_state/1 -- [ ] system_replace_state/2 -- [ ] system_terminate/4 -- [ ] which_handlers/1 -- [ ] __using__/1 -## Inspect.Error -- [ ] __struct__/0 -- [ ] __struct__/1 -- [ ] exception/1 -- [ ] message/1 -## Enumerable.List -- [X] __impl__/1 -- [X] count/1 -- [X] member?/2 -- [X] reduce/3 -## OptionParser.ParseError -- [ ] __struct__/0 -- [ ] __struct__/1 -- [ ] exception/1 -- [ ] message/1 -## Map -- [X] delete/2 -- [X] drop/2 -- [X] equal?/2 -- [X] fetch/2 -- [X] fetch!/2 -- [X] from_struct/1 -- [X] get/2 -- [X] get/3 -- [X] get_and_update/3 -- [ ] get_and_update!/3 -- [X] get_lazy/3 -- [X] has_key?/2 -- [X] keys/1 -- [X] merge/2 -- [ ] merge/3 -- [X] new/0 -- [ ] new/1 -- [ ] new/2 -- [X] pop/2 -- [X] pop/3 -- [X] pop_lazy/3 -- [X] put/3 -- [X] put_new/3 -- [X] put_new_lazy/3 -- [X] size/1 -- [X] split/2 -- [X] take/2 -- [X] to_list/1 -- [X] update/4 -- [X] update!/3 -- [X] values/1 -## OptionParser -- [ ] get_option_key/1 -- [ ] next/1 -- [ ] next/2 -- [ ] parse/1 -- [ ] parse/2 -- [ ] parse!/1 -- [ ] parse!/2 -- [ ] parse_head/1 -- [ ] parse_head/2 -- [ ] parse_head!/1 -- [ ] parse_head!/2 -- [ ] split/1 -- [ ] to_argv/1 -- [ ] to_argv/2 +- [ ] `__impl__/1` +- [ ] `inspect/2` +## Inspect.Version +- [ ] `__impl__/1` +- [ ] `inspect/2` +## Inspect.Version.Requirement +- [ ] `__impl__/1` +- [ ] `inspect/2` +## Integer +- [ ] `digits/1` +- [ ] `digits/2` +- [ ] `floor_div/2` +- [ ] `mod/2` +- [X] `parse/1` +- [X] `parse/2` +- [X] `to_char_list/1` +- [ ] `to_charlist/1` +- [ ] `to_charlist/2` +- [ ] `to_string/1` +- [ ] `to_string/2` +- [ ] `undigits/1` +- [ ] `undigits/2` +- [X] `is_even/1` +- [X] `is_odd/1` +## Kernel +- [X] `!=/2` +- [X] `!==/2` +- [X] `*/2` +- [X] `+/1` +- [X] `+/2` +- [X] `++/2` +- [X] `-/1` +- [X] `-/2` +- [X] `--/2` +- [X] `//2` +- [X] `/2` +- [X] `>=/2` +- [X] `abs/1` +- [X] `apply/2` +- [X] `apply/3` +- [X] `binary_part/3` +- [ ] `bit_size/1` +- [ ] `byte_size/1` +- [X] `div/2` +- [X] `elem/2` +- [ ] `exit/1` +- [ ] `function_exported?/3` +- [ ] `get_and_update_in/3` +- [ ] `get_in/2` +- [X] `hd/1` +- [ ] `inspect/1` +- [ ] `inspect/2` +- [X] `is_atom/1` +- [X] `is_binary/1` +- [X] `is_bitstring/1` +- [X] `is_boolean/1` +- [X] `is_float/1` +- [X] `is_function/1` +- [X] `is_function/2` +- [X] `is_integer/1` +- [X] `is_list/1` +- [X] `is_map/1` +- [X] `is_number/1` +- [X] `is_pid/1` +- [X] `is_port/1` +- [X] `is_reference/1` +- [X] `is_tuple/1` +- [X] `length/1` +- [ ] `macro_exported?/3` +- [ ] `make_ref/0` +- [X] `map_size/1` +- [X] `max/2` +- [X] `min/2` +- [ ] `node/0` +- [ ] `node/1` +- [ ] `not/1` +- [ ] `pop_in/2` +- [ ] `put_elem/3` +- [ ] `put_in/3` +- [X] `rem/2` +- [X] `round/1` +- [ ] `self/0` +- [ ] `send/2` +- [ ] `spawn/1` +- [ ] `spawn/3` +- [ ] `spawn_link/1` +- [ ] `spawn_link/3` +- [ ] `spawn_monitor/1` +- [ ] `spawn_monitor/3` +- [ ] `struct/1` +- [ ] `struct/2` +- [ ] `struct!/1` +- [ ] `struct!/2` +- [X] `throw/1` +- [X] `tl/1` +- [X] `trunc/1` +- [X] `tuple_size/1` +- [ ] `update_in/3` +- [X] `!/1` +- [X] `&&/2` +- [X] `../2` +- [X] `<>/2` +- [X] `@/1` +- [ ] `alias!/1` +- [X] `and/2` +- [ ] `binding/0` +- [ ] `binding/1` +- [X] `def/1` +- [X] `def/2` +- [X] `defdelegate/2` +- [X] `defexception/1` +- [X] `defimpl/2` +- [X] `defimpl/3` +- [X] `defmacro/1` +- [X] `defmacro/2` +- [X] `defmacrop/1` +- [X] `defmacrop/2` +- [X] `defmodule/2` +- [X] `defoverridable/1` +- [X] `defp/1` +- [X] `defp/2` +- [X] `defprotocol/2` +- [X] `defstruct/1` +- [ ] `destructure/2` +- [ ] `get_and_update_in/2` +- [X] `if/2` +- [X] `in/2` +- [X] `is_nil/1` +- [X] `match?/2` +- [X] `or/2` +- [ ] `pop_in/1` +- [ ] `put_in/2` +- [X] `raise/1` +- [X] `raise/2` +- [ ] `reraise/2` +- [ ] `reraise/3` +- [ ] `sigil_C/2` +- [ ] `sigil_D/2` +- [ ] `sigil_N/2` +- [ ] `sigil_R/2` +- [ ] `sigil_S/2` +- [ ] `sigil_T/2` +- [ ] `sigil_W/2` +- [ ] `sigil_c/2` +- [X] `sigil_r/2` +- [ ] `sigil_s/2` +- [ ] `sigil_w/2` +- [ ] `to_char_list/1` +- [ ] `to_charlist/1` +- [X] `to_string/1` +- [X] `unless/2` +- [ ] `update_in/2` +- [X] `use/1` +- [X] `use/2` +- [ ] `var!/1` +- [ ] `var!/2` +- [X] `|>/2` +- [X] `||/2` ## Kernel.ErrorHandler -- [ ] ensure_compiled/2 -- [ ] ensure_loaded/1 -- [ ] undefined_function/3 -- [ ] undefined_lambda/3 -## List.Chars.Integer -- [ ] __impl__/1 -- [ ] to_charlist/1 -## HashSet -- [ ] __struct__/0 -- [ ] __struct__/1 -- [ ] delete/2 -- [ ] difference/2 -- [ ] disjoint?/2 -- [ ] equal?/2 -- [ ] intersection/2 -- [ ] member?/2 -- [ ] new/0 -- [ ] put/2 -- [ ] reduce/3 -- [ ] size/1 -- [ ] subset?/2 -- [ ] to_list/1 -- [ ] union/2 -## Inspect.Date -- [ ] __impl__/1 -- [ ] inspect/2 -## Code -- [ ] append_path/1 -- [ ] available_compiler_options/0 -- [ ] compile_quoted/1 -- [ ] compile_quoted/2 -- [ ] compile_string/1 -- [ ] compile_string/2 -- [ ] compiler_options/0 -- [ ] compiler_options/1 -- [ ] delete_path/1 -- [ ] ensure_compiled/1 -- [ ] ensure_compiled?/1 -- [ ] ensure_loaded/1 -- [ ] ensure_loaded?/1 -- [ ] eval_file/1 -- [ ] eval_file/2 -- [ ] eval_quoted/1 -- [ ] eval_quoted/2 -- [ ] eval_quoted/3 -- [ ] eval_string/1 -- [ ] eval_string/2 -- [ ] eval_string/3 -- [ ] get_docs/2 -- [ ] load_file/1 -- [ ] load_file/2 -- [ ] loaded_files/0 -- [ ] prepend_path/1 -- [ ] require_file/1 -- [ ] require_file/2 -- [ ] string_to_quoted/1 -- [ ] string_to_quoted/2 -- [ ] string_to_quoted!/1 -- [ ] string_to_quoted!/2 -- [ ] unload_files/1 +- [ ] `ensure_compiled/2` +- [ ] `ensure_loaded/1` +- [ ] `undefined_function/3` +- [ ] `undefined_lambda/3` +## Kernel.ParallelCompiler +- [ ] `files/1` +- [ ] `files/2` +- [ ] `files_to_path/2` +- [ ] `files_to_path/3` +## Kernel.ParallelRequire +- [ ] `files/1` +- [ ] `files/2` ## Kernel.SpecialForms -- [X] %/2 -- [X] %{}/1 -- [X] &/1 -- [X] ./2 -- [X] ::/2 -- [X] <<>>/1 -- [X] =/2 -- [X] ^/1 -- [X] __CALLER__/0 -- [X] __DIR__/0 -- [X] __ENV__/0 -- [X] __MODULE__/0 -- [X] __aliases__/1 -- [X] __block__/1 -- [X] alias/2 -- [X] case/2 -- [X] cond/1 -- [X] fn/1 -- [X] for/1 -- [X] import/2 -- [X] quote/2 -- [ ] receive/1 -- [X] require/2 -- [X] super/1 -- [X] try/1 -- [X] unquote/1 -- [X] unquote_splicing/1 -- [X] with/1 -- [X] {}/1 -## Tuple -- [X] append/2 -- [X] delete_at/2 -- [X] duplicate/2 -- [X] insert_at/3 -- [X] to_list/1 -## SystemLimitError -- [ ] __struct__/0 -- [ ] __struct__/1 -- [ ] exception/1 -- [ ] message/1 -## Bitwise -- [X] &&&/2 -- [X] <<>>/2 -- [X] ^^^/2 -- [ ] __using__/1 -- [X] band/2 -- [X] bnot/1 -- [X] bor/2 -- [X] bsl/2 -- [X] bsr/2 -- [X] bxor/2 -- [X] |||/2 -- [X] ~~~/1 -## String.Chars.Integer -- [X] __impl__/1 -- [X] to_string/1 -## Inspect.Reference -- [ ] __impl__/1 -- [ ] inspect/2 -## IO.StreamError -- [ ] __struct__/0 -- [ ] __struct__/1 -- [ ] exception/1 -- [ ] message/1 +- [X] `%/2` +- [X] `%{}/1` +- [X] `&/1` +- [X] `./2` +- [X] `::/2` +- [X] `<<>>/1` +- [X] `=/2` +- [X] `^/1` +- [X] `__CALLER__/0` +- [X] `__DIR__/0` +- [X] `__ENV__/0` +- [X] `__MODULE__/0` +- [X] `__aliases__/1` +- [X] `__block__/1` +- [X] `alias/2` +- [X] `case/2` +- [X] `cond/1` +- [X] `fn/1` +- [X] `for/1` +- [X] `import/2` +- [X] `quote/2` +- [ ] `receive/1` +- [X] `require/2` +- [X] `super/1` +- [X] `try/1` +- [X] `unquote/1` +- [X] `unquote_splicing/1` +- [X] `with/1` +- [X] `{}/1` +## Kernel.Typespec +- [ ] `beam_callbacks/1` +- [ ] `beam_specs/1` +- [ ] `beam_typedocs/1` +- [ ] `beam_types/1` +- [ ] `define_spec/3` +- [ ] `define_type/3` +- [ ] `define_type/4` +- [ ] `defines_callback?/3` +- [ ] `defines_spec?/3` +- [ ] `defines_type?/3` +- [ ] `defspec/3` +- [ ] `deftype/3` +- [ ] `spec_to_ast/2` +- [ ] `spec_to_signature/1` +- [ ] `translate_spec/3` +- [ ] `translate_type/3` +- [ ] `type_to_ast/1` +- [ ] `type_to_signature/1` +- [ ] `defcallback/1` +- [ ] `defmacrocallback/1` +- [ ] `defopaque/1` +- [ ] `defoptional_callbacks/1` +- [ ] `defspec/1` +- [ ] `deftype/1` +- [ ] `deftypep/1` +## KeyError +- [ ] `__struct__/0` +- [ ] `__struct__/1` +- [ ] `exception/1` +- [ ] `message/1` +## Keyword +- [ ] `delete/2` +- [ ] `delete/3` +- [ ] `delete_first/2` +- [ ] `drop/2` +- [ ] `equal?/2` +- [ ] `fetch/2` +- [ ] `fetch!/2` +- [X] `get/2` +- [X] `get/3` +- [ ] `get_and_update/3` +- [ ] `get_and_update!/3` +- [ ] `get_lazy/3` +- [ ] `get_values/2` +- [X] `has_key?/2` +- [ ] `keys/1` +- [ ] `keyword?/1` +- [ ] `merge/2` +- [ ] `merge/3` +- [X] `new/0` +- [ ] `new/1` +- [ ] `new/2` +- [ ] `pop/2` +- [ ] `pop/3` +- [ ] `pop_first/2` +- [ ] `pop_first/3` +- [ ] `pop_lazy/3` +- [ ] `put/3` +- [ ] `put_new/3` +- [ ] `put_new_lazy/3` +- [ ] `size/1` +- [ ] `split/2` +- [ ] `take/2` +- [ ] `to_list/1` +- [ ] `update/4` +- [ ] `update!/3` +- [ ] `values/1` +## List +- [X] `delete/2` +- [X] `delete_at/2` +- [X] `duplicate/2` +- [X] `first/1` +- [X] `flatten/1` +- [X] `flatten/2` +- [X] `foldl/3` +- [X] `foldr/3` +- [X] `insert_at/3` +- [X] `keydelete/3` +- [X] `keyfind/3` +- [X] `keyfind/4` +- [X] `keymember?/3` +- [X] `keyreplace/4` +- [ ] `keysort/2` +- [ ] `keystore/4` +- [ ] `keytake/3` +- [X] `last/1` +- [ ] `myers_difference/2` +- [ ] `pop_at/2` +- [ ] `pop_at/3` +- [X] `replace_at/3` +- [ ] `to_atom/1` +- [ ] `to_existing_atom/1` +- [ ] `to_float/1` +- [ ] `to_integer/1` +- [ ] `to_integer/2` +- [ ] `to_string/1` +- [X] `to_tuple/1` +- [X] `update_at/3` +- [X] `wrap/1` +- [X] `zip/1` +## List.Chars +- [ ] `__protocol__/1` +- [ ] `impl_for/1` +- [ ] `impl_for!/1` +- [ ] `to_char_list/1` +- [ ] `to_charlist/1` +## List.Chars.Atom +- [ ] `__impl__/1` +- [ ] `to_charlist/1` +## List.Chars.BitString +- [ ] `__impl__/1` +- [ ] `to_charlist/1` +## List.Chars.Float +- [ ] `__impl__/1` +- [ ] `to_charlist/1` +## List.Chars.Integer +- [ ] `__impl__/1` +- [ ] `to_charlist/1` +## List.Chars.List +- [ ] `__impl__/1` +- [ ] `to_charlist/1` +## Macro +- [ ] `camelize/1` +- [ ] `decompose_call/1` +- [ ] `escape/1` +- [ ] `escape/2` +- [ ] `expand/2` +- [ ] `expand_once/2` +- [ ] `pipe/3` +- [ ] `pipe_warning/1` +- [ ] `postwalk/2` +- [ ] `postwalk/3` +- [ ] `prewalk/2` +- [ ] `prewalk/3` +- [ ] `to_string/1` +- [ ] `to_string/2` +- [ ] `traverse/4` +- [ ] `underscore/1` +- [ ] `unescape_string/1` +- [ ] `unescape_string/2` +- [ ] `unescape_tokens/1` +- [ ] `unescape_tokens/2` +- [ ] `unpipe/1` +- [ ] `update_meta/2` +- [ ] `validate/1` +- [ ] `var/2` +- [ ] `binary_ops/0` +- [ ] `unary_ops/0` +## Macro.Env +- [X] `__struct__/0` +- [X] `__struct__/1` +- [ ] `in_guard?/1` +- [ ] `in_match?/1` +- [ ] `location/1` +- [ ] `stacktrace/1` +## Map +- [X] `delete/2` +- [X] `drop/2` +- [X] `equal?/2` +- [X] `fetch/2` +- [X] `fetch!/2` +- [X] `from_struct/1` +- [X] `get/2` +- [X] `get/3` +- [X] `get_and_update/3` +- [ ] `get_and_update!/3` +- [X] `get_lazy/3` +- [X] `has_key?/2` +- [X] `keys/1` +- [X] `merge/2` +- [ ] `merge/3` +- [X] `new/0` +- [ ] `new/1` +- [ ] `new/2` +- [X] `pop/2` +- [X] `pop/3` +- [X] `pop_lazy/3` +- [X] `put/3` +- [X] `put_new/3` +- [X] `put_new_lazy/3` +- [X] `size/1` +- [X] `split/2` +- [X] `take/2` +- [X] `to_list/1` +- [X] `update/4` +- [X] `update!/3` +- [X] `values/1` +## MapSet +- [X] `__struct__/0` +- [X] `__struct__/1` +- [X] `delete/2` +- [X] `difference/2` +- [X] `disjoint?/2` +- [X] `equal?/2` +- [X] `intersection/2` +- [X] `member?/2` +- [X] `new/0` +- [ ] `new/1` +- [ ] `new/2` +- [X] `put/2` +- [X] `size/1` +- [X] `subset?/2` +- [X] `to_list/1` +- [X] `union/2` +## MatchError +- [ ] `__struct__/0` +- [ ] `__struct__/1` +- [ ] `exception/1` +- [ ] `message/1` +## Module +- [ ] `add_doc/5` +- [ ] `add_doc/6` +- [ ] `compile_doc/6` +- [ ] `concat/1` +- [ ] `concat/2` +- [ ] `create/3` +- [ ] `defines?/2` +- [ ] `defines?/3` +- [ ] `definitions_in/1` +- [ ] `definitions_in/2` +- [ ] `delete_attribute/2` +- [ ] `eval_quoted/2` +- [ ] `eval_quoted/3` +- [ ] `eval_quoted/4` +- [ ] `get_attribute/2` +- [ ] `get_attribute/3` +- [ ] `make_overridable/2` +- [ ] `open?/1` +- [ ] `overridable?/2` +- [ ] `put_attribute/3` +- [ ] `put_attribute/5` +- [ ] `register_attribute/3` +- [ ] `safe_concat/1` +- [ ] `safe_concat/2` +- [ ] `split/1` +- [ ] `store_typespec/3` +## NaiveDateTime +- [ ] `__struct__/0` +- [ ] `__struct__/1` +- [ ] `add/2` +- [ ] `add/3` +- [ ] `compare/2` +- [ ] `diff/2` +- [ ] `diff/3` +- [ ] `from_erl/1` +- [ ] `from_erl/2` +- [ ] `from_erl!/1` +- [ ] `from_erl!/2` +- [ ] `from_iso8601/1` +- [ ] `from_iso8601!/1` +- [ ] `new/2` +- [ ] `new/6` +- [ ] `new/7` +- [ ] `to_date/1` +- [ ] `to_erl/1` +- [ ] `to_iso8601/1` +- [ ] `to_string/1` +- [ ] `to_time/1` +- [ ] `utc_now/0` +## Node +- [ ] `alive?/0` +- [ ] `connect/1` +- [ ] `disconnect/1` +- [ ] `get_cookie/0` +- [ ] `list/0` +- [ ] `list/1` +- [ ] `monitor/2` +- [ ] `monitor/3` +- [ ] `ping/1` +- [ ] `self/0` +- [ ] `set_cookie/1` +- [ ] `set_cookie/2` +- [ ] `spawn/2` +- [ ] `spawn/3` +- [ ] `spawn/4` +- [ ] `spawn/5` +- [ ] `spawn_link/2` +- [ ] `spawn_link/4` +- [ ] `start/1` +- [ ] `start/2` +- [ ] `start/3` +- [ ] `stop/0` +## OptionParser +- [ ] `get_option_key/1` +- [ ] `next/1` +- [ ] `next/2` +- [ ] `parse/1` +- [ ] `parse/2` +- [ ] `parse!/1` +- [ ] `parse!/2` +- [ ] `parse_head/1` +- [ ] `parse_head/2` +- [ ] `parse_head!/1` +- [ ] `parse_head!/2` +- [ ] `split/1` +- [ ] `to_argv/1` +- [ ] `to_argv/2` +## OptionParser.ParseError +- [ ] `__struct__/0` +- [ ] `__struct__/1` +- [ ] `exception/1` +- [ ] `message/1` +## Path +- [ ] `absname/1` +- [ ] `absname/2` +- [ ] `basename/1` +- [ ] `basename/2` +- [ ] `dirname/1` +- [ ] `expand/1` +- [ ] `expand/2` +- [ ] `extname/1` +- [ ] `join/1` +- [ ] `join/2` +- [ ] `relative/1` +- [ ] `relative_to/2` +- [ ] `relative_to_cwd/1` +- [ ] `rootname/1` +- [ ] `rootname/2` +- [ ] `split/1` +- [ ] `type/1` +- [ ] `wildcard/1` +- [ ] `wildcard/2` +## Path.Wildcard +- [ ] `list_dir/1` +- [ ] `read_link_info/1` +## Port +- [ ] `close/1` +- [ ] `command/2` +- [ ] `command/3` +- [ ] `connect/2` +- [ ] `info/1` +- [ ] `info/2` +- [ ] `list/0` +- [ ] `open/2` ## Process -- [ ] alive?/1 -- [ ] cancel_timer/1 -- [ ] delete/1 -- [ ] demonitor/1 -- [ ] demonitor/2 -- [ ] exit/2 -- [ ] flag/2 -- [ ] flag/3 -- [ ] get/0 -- [ ] get/1 -- [ ] get/2 -- [ ] get_keys/0 -- [ ] get_keys/1 -- [ ] group_leader/0 -- [ ] group_leader/2 -- [ ] hibernate/3 -- [ ] info/1 -- [ ] info/2 -- [ ] link/1 -- [ ] list/0 -- [ ] monitor/1 -- [ ] put/2 -- [ ] read_timer/1 -- [ ] register/2 -- [ ] registered/0 -- [ ] send/3 -- [ ] send_after/3 -- [ ] send_after/4 -- [ ] sleep/1 -- [ ] spawn/2 -- [ ] spawn/4 -- [ ] unlink/1 -- [ ] unregister/1 -- [ ] whereis/1 +- [ ] `alive?/1` +- [ ] `cancel_timer/1` +- [ ] `delete/1` +- [ ] `demonitor/1` +- [ ] `demonitor/2` +- [ ] `exit/2` +- [ ] `flag/2` +- [ ] `flag/3` +- [ ] `get/0` +- [ ] `get/1` +- [ ] `get/2` +- [ ] `get_keys/0` +- [ ] `get_keys/1` +- [ ] `group_leader/0` +- [ ] `group_leader/2` +- [ ] `hibernate/3` +- [ ] `info/1` +- [ ] `info/2` +- [ ] `link/1` +- [ ] `list/0` +- [ ] `monitor/1` +- [ ] `put/2` +- [ ] `read_timer/1` +- [ ] `register/2` +- [ ] `registered/0` +- [ ] `send/3` +- [ ] `send_after/3` +- [ ] `send_after/4` +- [ ] `sleep/1` +- [ ] `spawn/2` +- [ ] `spawn/4` +- [ ] `unlink/1` +- [ ] `unregister/1` +- [ ] `whereis/1` ## Protocol -- [ ] __builtin__/0 -- [ ] __derive__/3 -- [ ] __ensure_defimpl__/3 -- [ ] __functions_spec__/1 -- [ ] __impl__/2 -- [ ] __protocol__/2 -- [ ] __spec__?/3 -- [ ] assert_impl!/2 -- [ ] assert_protocol!/1 -- [ ] consolidate/2 -- [ ] consolidated?/1 -- [ ] extract_impls/2 -- [ ] extract_protocols/1 -- [ ] def/1 -- [ ] derive/2 -- [ ] derive/3 -## UndefinedFunctionError -- [ ] __struct__/0 -- [ ] __struct__/1 -- [ ] exception/1 -- [ ] message/1 -## Version.InvalidVersionError -- [ ] __struct__/0 -- [ ] __struct__/1 -- [ ] exception/1 -- [ ] message/1 -## Task -- [ ] __struct__/0 -- [ ] __struct__/1 -- [ ] async/1 -- [ ] async/3 -- [ ] async_stream/2 -- [ ] async_stream/3 -- [ ] async_stream/4 -- [ ] async_stream/5 -- [ ] await/1 -- [ ] await/2 -- [ ] find/2 -- [ ] shutdown/1 -- [ ] shutdown/2 -- [ ] start/1 -- [ ] start/3 -- [ ] start_link/1 -- [ ] start_link/3 -- [ ] yield/1 -- [ ] yield/2 -- [ ] yield_many/1 -- [ ] yield_many/2 -## Float -- [ ] ceil/1 -- [ ] ceil/2 -- [ ] floor/1 -- [ ] floor/2 -- [ ] parse/1 -- [ ] ratio/1 -- [ ] round/1 -- [ ] round/2 -- [ ] to_char_list/1 -- [ ] to_char_list/2 -- [ ] to_charlist/1 -- [ ] to_string/1 -- [ ] to_string/2 -## Supervisor -- [ ] count_children/1 -- [ ] delete_child/2 -- [ ] restart_child/2 -- [ ] start_child/2 -- [ ] start_link/2 -- [ ] start_link/3 -- [ ] stop/1 -- [ ] stop/2 -- [ ] stop/3 -- [ ] terminate_child/2 -- [ ] which_children/1 -- [ ] __using__/1 -## Enumerable -- [X] __protocol__/1 -- [X] count/1 -- [X] impl_for/1 -- [X] impl_for!/1 -- [X] member?/2 -- [X] reduce/3 -## Enum -- [X] all?/1 -- [X] all?/2 -- [X] any?/1 -- [X] any?/2 -- [X] at/2 -- [X] at/3 -- [ ] chunk/2 -- [ ] chunk/3 -- [ ] chunk/4 -- [ ] chunk_by/2 -- [X] concat/1 -- [X] concat/2 -- [X] count/1 -- [X] count/2 -- [ ] dedup/1 -- [ ] dedup_by/2 -- [X] drop/2 -- [X] drop_every/2 -- [X] drop_while/2 -- [X] each/2 -- [X] empty?/1 -- [X] fetch/2 -- [X] fetch!/2 -- [X] filter/2 -- [X] filter_map/3 -- [X] find/2 -- [X] find/3 -- [ ] find_index/2 -- [ ] find_value/2 -- [ ] find_value/3 -- [ ] flat_map/2 -- [ ] flat_map_reduce/3 -- [ ] group_by/2 -- [ ] group_by/3 -- [ ] intersperse/2 -- [X] into/2 -- [X] into/3 -- [ ] join/1 -- [ ] join/2 -- [X] map/2 -- [ ] map_every/3 -- [ ] map_join/2 -- [ ] map_join/3 -- [X] map_reduce/3 -- [ ] max/1 -- [ ] max/2 -- [ ] max_by/2 -- [ ] max_by/3 -- [X] member?/2 -- [ ] min/1 -- [ ] min/2 -- [ ] min_by/2 -- [ ] min_by/3 -- [ ] min_max/1 -- [ ] min_max/2 -- [ ] min_max_by/2 -- [ ] min_max_by/3 -- [ ] partition/2 -- [ ] random/1 -- [X] reduce/2 -- [X] reduce/3 -- [ ] reduce_while/3 -- [ ] reject/2 -- [X] reverse/1 -- [X] reverse/2 -- [ ] reverse_slice/3 -- [ ] scan/2 -- [ ] scan/3 -- [ ] shuffle/1 -- [ ] slice/2 -- [ ] slice/3 -- [ ] sort/1 -- [ ] sort/2 -- [ ] sort_by/2 -- [ ] sort_by/3 -- [ ] split/2 -- [ ] split_while/2 -- [ ] split_with/2 -- [ ] sum/1 -- [X] take/2 -- [X] take_every/2 -- [ ] take_random/2 -- [X] take_while/2 -- [X] to_list/1 -- [ ] uniq/1 -- [ ] uniq/2 -- [ ] uniq_by/2 -- [ ] unzip/1 -- [ ] with_index/1 -- [ ] with_index/2 -- [ ] zip/1 -- [ ] zip/2 -## Keyword -- [ ] delete/2 -- [ ] delete/3 -- [ ] delete_first/2 -- [ ] drop/2 -- [ ] equal?/2 -- [ ] fetch/2 -- [ ] fetch!/2 -- [X] get/2 -- [X] get/3 -- [ ] get_and_update/3 -- [ ] get_and_update!/3 -- [ ] get_lazy/3 -- [ ] get_values/2 -- [X] has_key?/2 -- [ ] keys/1 -- [ ] keyword?/1 -- [ ] merge/2 -- [ ] merge/3 -- [X] new/0 -- [ ] new/1 -- [ ] new/2 -- [ ] pop/2 -- [ ] pop/3 -- [ ] pop_first/2 -- [ ] pop_first/3 -- [ ] pop_lazy/3 -- [ ] put/3 -- [ ] put_new/3 -- [ ] put_new_lazy/3 -- [ ] size/1 -- [ ] split/2 -- [ ] take/2 -- [ ] to_list/1 -- [ ] update/4 -- [ ] update!/3 -- [ ] values/1 -## Collectable.HashDict -- [ ] __impl__/1 -- [ ] into/1 -## Enumerable.File.Stream -- [ ] __impl__/1 -- [ ] count/1 -- [ ] member?/2 -- [ ] reduce/3 -## Access -- [ ] all/0 -- [ ] at/1 -- [ ] elem/1 -- [ ] fetch/2 -- [ ] get/2 -- [ ] get/3 -- [ ] get_and_update/3 -- [ ] key/1 -- [ ] key/2 -- [ ] key!/1 -- [ ] pop/2 -## IO.Stream -- [ ] __build__/3 -- [ ] __struct__/0 -- [ ] __struct__/1 -## Enumerable.Stream -- [ ] __impl__/1 -- [ ] count/1 -- [ ] member?/2 -- [ ] reduce/3 +- [ ] `__builtin__/0` +- [ ] `__derive__/3` +- [ ] `__ensure_defimpl__/3` +- [ ] `__functions_spec__/1` +- [ ] `__impl__/2` +- [ ] `__protocol__/2` +- [ ] `__spec__?/3` +- [ ] `assert_impl!/2` +- [ ] `assert_protocol!/1` +- [ ] `consolidate/2` +- [ ] `consolidated?/1` +- [ ] `extract_impls/2` +- [ ] `extract_protocols/1` +- [ ] `def/1` +- [ ] `derive/2` +- [ ] `derive/3` +## Protocol.UndefinedError +- [ ] `__struct__/0` +- [ ] `__struct__/1` +- [ ] `exception/1` +- [ ] `message/1` +## Range +- [X] `__struct__/0` +- [X] `__struct__/1` +- [X] `new/2` +- [X] `range?/1` +## Record +- [ ] `__access__/4` +- [ ] `__access__/5` +- [ ] `__fields__/2` +- [ ] `__keyword__/3` +- [ ] `extract/2` +- [ ] `extract_all/1` +- [ ] `defrecord/2` +- [ ] `defrecord/3` +- [ ] `defrecordp/2` +- [ ] `defrecordp/3` +- [ ] `is_record/1` +- [ ] `is_record/2` +## Record.Extractor +- [ ] `extract/2` +- [ ] `extract_all/1` +## Regex +- [ ] `__struct__/0` +- [ ] `__struct__/1` +- [X] `compile/1` +- [X] `compile/2` +- [X] `compile!/1` +- [X] `compile!/2` +- [ ] `escape/1` +- [X] `match?/2` +- [ ] `named_captures/2` +- [ ] `named_captures/3` +- [ ] `names/1` +- [X] `opts/1` +- [ ] `re_pattern/1` +- [X] `regex?/1` +- [X] `replace/3` +- [X] `replace/4` +- [X] `run/2` +- [X] `run/3` +- [X] `scan/2` +- [X] `scan/3` +- [X] `source/1` +- [ ] `split/2` +- [ ] `split/3` +- [ ] `unescape_map/1` +## Regex.CompileError +- [ ] `__struct__/0` +- [ ] `__struct__/1` +- [ ] `exception/1` +- [ ] `message/1` +## Registry +- [ ] `dispatch/3` +- [ ] `keys/2` +- [ ] `lookup/2` +- [ ] `match/3` +- [ ] `meta/2` +- [ ] `put_meta/3` +- [ ] `register/3` +- [ ] `register_name/2` +- [ ] `send/2` +- [ ] `start_link/2` +- [ ] `start_link/3` +- [ ] `unregister/2` +- [ ] `unregister_name/1` +- [ ] `update_value/3` +- [ ] `whereis_name/1` +## RuntimeError +- [X] `__struct__/0` +- [X] `__struct__/1` +- [X] `exception/1` +- [X] `message/1` +## Set +- [ ] `delete/2` +- [ ] `difference/2` +- [ ] `disjoint?/2` +- [ ] `empty/1` +- [ ] `equal?/2` +- [ ] `intersection/2` +- [ ] `member?/2` +- [ ] `put/2` +- [ ] `size/1` +- [ ] `subset?/2` +- [ ] `to_list/1` +- [ ] `union/2` ## Stream -- [ ] __struct__/0 -- [ ] __struct__/1 -- [ ] chunk/2 -- [ ] chunk/3 -- [ ] chunk/4 -- [ ] chunk_by/2 -- [ ] concat/1 -- [ ] concat/2 -- [ ] cycle/1 -- [ ] dedup/1 -- [ ] dedup_by/2 -- [ ] drop/2 -- [ ] drop_every/2 -- [ ] drop_while/2 -- [ ] each/2 -- [ ] filter/2 -- [ ] filter_map/3 -- [ ] flat_map/2 -- [ ] interval/1 -- [ ] into/2 -- [ ] into/3 -- [ ] iterate/2 -- [ ] map/2 -- [ ] map_every/3 -- [ ] reject/2 -- [ ] repeatedly/1 -- [ ] resource/3 -- [ ] run/1 -- [ ] scan/2 -- [ ] scan/3 -- [ ] take/2 -- [ ] take_every/2 -- [ ] take_while/2 -- [ ] timer/1 -- [ ] transform/3 -- [ ] transform/4 -- [ ] unfold/2 -- [ ] uniq/1 -- [ ] uniq/2 -- [ ] uniq_by/2 -- [ ] with_index/1 -- [ ] with_index/2 -- [ ] zip/1 -- [ ] zip/2 +- [ ] `__struct__/0` +- [ ] `__struct__/1` +- [ ] `chunk/2` +- [ ] `chunk/3` +- [ ] `chunk/4` +- [ ] `chunk_by/2` +- [ ] `concat/1` +- [ ] `concat/2` +- [ ] `cycle/1` +- [ ] `dedup/1` +- [ ] `dedup_by/2` +- [ ] `drop/2` +- [ ] `drop_every/2` +- [ ] `drop_while/2` +- [ ] `each/2` +- [ ] `filter/2` +- [ ] `filter_map/3` +- [ ] `flat_map/2` +- [ ] `interval/1` +- [ ] `into/2` +- [ ] `into/3` +- [ ] `iterate/2` +- [ ] `map/2` +- [ ] `map_every/3` +- [ ] `reject/2` +- [ ] `repeatedly/1` +- [ ] `resource/3` +- [ ] `run/1` +- [ ] `scan/2` +- [ ] `scan/3` +- [ ] `take/2` +- [ ] `take_every/2` +- [ ] `take_while/2` +- [ ] `timer/1` +- [ ] `transform/3` +- [ ] `transform/4` +- [ ] `unfold/2` +- [ ] `uniq/1` +- [ ] `uniq/2` +- [ ] `uniq_by/2` +- [ ] `with_index/1` +- [ ] `with_index/2` +- [ ] `zip/1` +- [ ] `zip/2` +## String +- [X] `at/2` +- [X] `capitalize/1` +- [ ] `chunk/2` +- [X] `codepoints/1` +- [X] `contains?/2` +- [X] `downcase/1` +- [X] `duplicate/2` +- [X] `ends_with?/2` +- [ ] `equivalent?/2` +- [X] `first/1` +- [X] `graphemes/1` +- [ ] `jaro_distance/2` +- [X] `last/1` +- [X] `length/1` +- [ ] `ljust/2` +- [ ] `ljust/3` +- [ ] `lstrip/1` +- [ ] `lstrip/2` +- [X] `match?/2` +- [ ] `myers_difference/2` +- [X] `next_codepoint/1` +- [X] `next_grapheme/1` +- [ ] `next_grapheme_size/1` +- [ ] `normalize/2` +- [ ] `pad_leading/2` +- [ ] `pad_leading/3` +- [ ] `pad_trailing/2` +- [ ] `pad_trailing/3` +- [ ] `printable?/1` +- [ ] `replace/3` +- [ ] `replace/4` +- [ ] `replace_leading/3` +- [ ] `replace_prefix/3` +- [ ] `replace_suffix/3` +- [ ] `replace_trailing/3` +- [X] `reverse/1` +- [ ] `rjust/2` +- [ ] `rjust/3` +- [ ] `rstrip/1` +- [ ] `rstrip/2` +- [ ] `slice/2` +- [ ] `slice/3` +- [X] `split/1` +- [X] `split/2` +- [X] `split/3` +- [ ] `split_at/2` +- [ ] `splitter/2` +- [ ] `splitter/3` +- [X] `starts_with?/2` +- [ ] `strip/1` +- [ ] `strip/2` +- [X] `to_atom/1` +- [X] `to_char_list/1` +- [ ] `to_charlist/1` +- [X] `to_existing_atom/1` +- [X] `to_float/1` +- [X] `to_integer/1` +- [X] `to_integer/2` +- [ ] `trim/1` +- [ ] `trim/2` +- [ ] `trim_leading/1` +- [ ] `trim_leading/2` +- [ ] `trim_trailing/1` +- [ ] `trim_trailing/2` +- [X] `upcase/1` +- [ ] `valid?/1` +- [X] `valid_character?/1` +## String.Casing +- [ ] `downcase/1` +- [ ] `titlecase_once/1` +- [ ] `upcase/1` +## String.Chars +- [X] `__protocol__/1` +- [X] `impl_for/1` +- [X] `impl_for!/1` +- [X] `to_string/1` +## String.Chars.Atom +- [X] `__impl__/1` +- [X] `to_string/1` +## String.Chars.BitString +- [X] `__impl__/1` +- [X] `to_string/1` +## String.Chars.Date +- [ ] `__impl__/1` +- [ ] `to_string/1` +## String.Chars.DateTime +- [ ] `__impl__/1` +- [ ] `to_string/1` +## String.Chars.Float +- [X] `__impl__/1` +- [X] `to_string/1` +## String.Chars.Integer +- [X] `__impl__/1` +- [X] `to_string/1` +## String.Chars.List +- [X] `__impl__/1` +- [X] `to_string/1` +## String.Chars.NaiveDateTime +- [ ] `__impl__/1` +- [ ] `to_string/1` +## String.Chars.Time +- [ ] `__impl__/1` +- [ ] `to_string/1` +## String.Chars.URI +- [ ] `__impl__/1` +- [ ] `to_string/1` +## String.Chars.Version +- [ ] `__impl__/1` +- [ ] `to_string/1` +## String.Chars.Version.Requirement +- [ ] `__impl__/1` +- [ ] `to_string/1` +## String.Unicode +- [ ] `codepoints/1` +- [ ] `graphemes/1` +- [ ] `length/1` +- [ ] `next_codepoint/1` +- [ ] `next_grapheme_size/1` +- [ ] `split_at/2` +- [ ] `version/0` +## StringIO +- [ ] `close/1` +- [ ] `code_change/3` +- [ ] `contents/1` +- [ ] `flush/1` +- [ ] `handle_call/3` +- [ ] `handle_cast/2` +- [ ] `handle_info/2` +- [ ] `init/1` +- [ ] `open/1` +- [ ] `open/2` +- [ ] `terminate/2` +## Supervisor +- [ ] `count_children/1` +- [ ] `delete_child/2` +- [ ] `restart_child/2` +- [ ] `start_child/2` +- [ ] `start_link/2` +- [ ] `start_link/3` +- [ ] `stop/1` +- [ ] `stop/2` +- [ ] `stop/3` +- [ ] `terminate_child/2` +- [ ] `which_children/1` +- [ ] `__using__/1` +## Supervisor.Spec +- [ ] `supervise/2` +- [ ] `supervisor/2` +- [ ] `supervisor/3` +- [ ] `worker/2` +- [ ] `worker/3` +## SyntaxError +- [ ] `__struct__/0` +- [ ] `__struct__/1` +- [ ] `exception/1` +- [ ] `message/1` +## System +- [ ] `argv/0` +- [ ] `argv/1` +- [ ] `at_exit/1` +- [ ] `build_info/0` +- [ ] `cmd/2` +- [ ] `cmd/3` +- [ ] `compiled_endianness/0` +- [ ] `convert_time_unit/3` +- [ ] `cwd/0` +- [ ] `cwd!/0` +- [ ] `delete_env/1` +- [ ] `endianness/0` +- [ ] `find_executable/1` +- [ ] `get_env/0` +- [ ] `get_env/1` +- [ ] `get_pid/0` +- [ ] `halt/0` +- [ ] `halt/1` +- [ ] `monotonic_time/0` +- [ ] `monotonic_time/1` +- [ ] `os_time/0` +- [ ] `os_time/1` +- [ ] `otp_release/0` +- [ ] `put_env/1` +- [ ] `put_env/2` +- [ ] `schedulers/0` +- [ ] `schedulers_online/0` +- [ ] `stacktrace/0` +- [ ] `system_time/0` +- [ ] `system_time/1` +- [ ] `time_offset/0` +- [ ] `time_offset/1` +- [ ] `tmp_dir/0` +- [ ] `tmp_dir!/0` +- [ ] `unique_integer/0` +- [ ] `unique_integer/1` +- [ ] `user_home/0` +- [ ] `user_home!/0` +- [ ] `version/0` +## SystemLimitError +- [ ] `__struct__/0` +- [ ] `__struct__/1` +- [ ] `exception/1` +- [ ] `message/1` +## Task +- [ ] `__struct__/0` +- [ ] `__struct__/1` +- [ ] `async/1` +- [ ] `async/3` +- [ ] `async_stream/2` +- [ ] `async_stream/3` +- [ ] `async_stream/4` +- [ ] `async_stream/5` +- [ ] `await/1` +- [ ] `await/2` +- [ ] `find/2` +- [ ] `shutdown/1` +- [ ] `shutdown/2` +- [ ] `start/1` +- [ ] `start/3` +- [ ] `start_link/1` +- [ ] `start_link/3` +- [ ] `yield/1` +- [ ] `yield/2` +- [ ] `yield_many/1` +- [ ] `yield_many/2` ## Task.Supervisor -- [ ] async/2 -- [ ] async/4 -- [ ] async_nolink/2 -- [ ] async_nolink/4 -- [ ] async_stream/3 -- [ ] async_stream/4 -- [ ] async_stream/5 -- [ ] async_stream/6 -- [ ] async_stream_nolink/3 -- [ ] async_stream_nolink/4 -- [ ] async_stream_nolink/5 -- [ ] async_stream_nolink/6 -- [ ] children/1 -- [ ] start_child/2 -- [ ] start_child/4 -- [ ] start_link/0 -- [ ] start_link/1 -- [ ] terminate_child/2 -## Inspect.Version.Requirement -- [ ] __impl__/1 -- [ ] inspect/2 +- [ ] `async/2` +- [ ] `async/4` +- [ ] `async_nolink/2` +- [ ] `async_nolink/4` +- [ ] `async_stream/3` +- [ ] `async_stream/4` +- [ ] `async_stream/5` +- [ ] `async_stream/6` +- [ ] `async_stream_nolink/3` +- [ ] `async_stream_nolink/4` +- [ ] `async_stream_nolink/5` +- [ ] `async_stream_nolink/6` +- [ ] `children/1` +- [ ] `start_child/2` +- [ ] `start_child/4` +- [ ] `start_link/0` +- [ ] `start_link/1` +- [ ] `terminate_child/2` +## Time +- [ ] `__struct__/0` +- [ ] `__struct__/1` +- [ ] `compare/2` +- [ ] `from_erl/1` +- [ ] `from_erl/2` +- [ ] `from_erl!/1` +- [ ] `from_erl!/2` +- [ ] `from_iso8601/1` +- [ ] `from_iso8601!/1` +- [ ] `new/3` +- [ ] `new/4` +- [ ] `to_erl/1` +- [ ] `to_iso8601/1` +- [ ] `to_string/1` +- [ ] `utc_now/0` +## TokenMissingError +- [ ] `__struct__/0` +- [ ] `__struct__/1` +- [ ] `exception/1` +- [ ] `message/1` ## TryClauseError -- [ ] __struct__/0 -- [ ] __struct__/1 -- [ ] exception/1 -- [ ] message/1 -## Version -- [ ] __struct__/0 -- [ ] __struct__/1 -- [ ] compare/2 -- [ ] compile_requirement/1 -- [ ] match?/2 -- [ ] match?/3 -- [ ] parse/1 -- [ ] parse!/1 -- [ ] parse_requirement/1 -## Record -- [ ] __access__/4 -- [ ] __access__/5 -- [ ] __fields__/2 -- [ ] __keyword__/3 -- [ ] extract/2 -- [ ] extract_all/1 -- [ ] defrecord/2 -- [ ] defrecord/3 -- [ ] defrecordp/2 -- [ ] defrecordp/3 -- [ ] is_record/1 -- [ ] is_record/2 -## CondClauseError -- [ ] __struct__/0 -- [ ] __struct__/1 -- [ ] exception/1 -- [ ] message/1 -## Inspect.Integer -- [ ] __impl__/1 -- [ ] inspect/2 -## List -- [X] delete/2 -- [X] delete_at/2 -- [X] duplicate/2 -- [X] first/1 -- [X] flatten/1 -- [X] flatten/2 -- [X] foldl/3 -- [X] foldr/3 -- [X] insert_at/3 -- [X] keydelete/3 -- [X] keyfind/3 -- [X] keyfind/4 -- [X] keymember?/3 -- [X] keyreplace/4 -- [ ] keysort/2 -- [ ] keystore/4 -- [ ] keytake/3 -- [X] last/1 -- [ ] myers_difference/2 -- [ ] pop_at/2 -- [ ] pop_at/3 -- [X] replace_at/3 -- [ ] to_atom/1 -- [ ] to_existing_atom/1 -- [ ] to_float/1 -- [ ] to_integer/1 -- [ ] to_integer/2 -- [ ] to_string/1 -- [X] to_tuple/1 -- [X] update_at/3 -- [X] wrap/1 -- [X] zip/1 -## Regex -- [ ] __struct__/0 -- [ ] __struct__/1 -- [X] compile/1 -- [X] compile/2 -- [X] compile!/1 -- [X] compile!/2 -- [ ] escape/1 -- [X] match?/2 -- [ ] named_captures/2 -- [ ] named_captures/3 -- [ ] names/1 -- [X] opts/1 -- [ ] re_pattern/1 -- [X] regex?/1 -- [X] replace/3 -- [X] replace/4 -- [X] run/2 -- [X] run/3 -- [X] scan/2 -- [X] scan/3 -- [X] source/1 -- [ ] split/2 -- [ ] split/3 -- [ ] unescape_map/1 -## Collectable.IO.Stream -- [ ] __impl__/1 -- [ ] into/1 -## File.Error -- [ ] __struct__/0 -- [ ] __struct__/1 -- [ ] exception/1 -- [ ] message/1 -## Inspect.Algebra -- [ ] break/0 -- [ ] break/1 -- [ ] color/3 -- [ ] concat/1 -- [ ] concat/2 -- [ ] empty/0 -- [ ] fold_doc/2 -- [ ] format/2 -- [ ] glue/2 -- [ ] glue/3 -- [ ] group/1 -- [ ] line/2 -- [ ] nest/2 -- [ ] space/2 -- [ ] surround/3 -- [ ] surround_many/5 -- [ ] surround_many/6 -- [ ] to_doc/2 -## Node -- [ ] alive?/0 -- [ ] connect/1 -- [ ] disconnect/1 -- [ ] get_cookie/0 -- [ ] list/0 -- [ ] list/1 -- [ ] monitor/2 -- [ ] monitor/3 -- [ ] ping/1 -- [ ] self/0 -- [ ] set_cookie/1 -- [ ] set_cookie/2 -- [ ] spawn/2 -- [ ] spawn/3 -- [ ] spawn/4 -- [ ] spawn/5 -- [ ] spawn_link/2 -- [ ] spawn_link/4 -- [ ] start/1 -- [ ] start/2 -- [ ] start/3 -- [ ] stop/0 -## File.CopyError -- [ ] __struct__/0 -- [ ] __struct__/1 -- [ ] exception/1 -- [ ] message/1 -## Port -- [ ] close/1 -- [ ] command/2 -- [ ] command/3 -- [ ] connect/2 -- [ ] info/1 -- [ ] info/2 -- [ ] list/0 -- [ ] open/2 -## Enumerable.MapSet -- [ ] __impl__/1 -- [ ] count/1 -- [ ] member?/2 -- [ ] reduce/3 -## Inspect.Stream -- [ ] __impl__/1 -- [ ] inspect/2 -## Kernel.ParallelRequire -- [ ] files/1 -- [ ] files/2 -## FunctionClauseError -- [ ] __struct__/0 -- [ ] __struct__/1 -- [ ] exception/1 -- [ ] message/1 -## Enumerable.Function -- [ ] __impl__/1 -- [ ] count/1 -- [ ] member?/2 -- [ ] reduce/3 -## GenServer -- [ ] abcast/2 -- [ ] abcast/3 -- [ ] call/2 -- [ ] call/3 -- [ ] cast/2 -- [ ] multi_call/2 -- [ ] multi_call/3 -- [ ] multi_call/4 -- [ ] reply/2 -- [ ] start/2 -- [ ] start/3 -- [ ] start_link/2 -- [ ] start_link/3 -- [ ] stop/1 -- [ ] stop/2 -- [ ] stop/3 -- [ ] whereis/1 -- [ ] __using__/1 -## List.Chars -- [ ] __protocol__/1 -- [ ] impl_for/1 -- [ ] impl_for!/1 -- [ ] to_char_list/1 -- [ ] to_charlist/1 -## Inspect.Atom -- [ ] __impl__/1 -- [ ] inspect/1 -- [ ] inspect/2 -## Inspect.HashDict -- [ ] __impl__/1 -- [ ] inspect/2 -## Enumerable.IO.Stream -- [ ] __impl__/1 -- [ ] count/1 -- [ ] member?/2 -- [ ] reduce/3 -## Kernel.Typespec -- [ ] beam_callbacks/1 -- [ ] beam_specs/1 -- [ ] beam_typedocs/1 -- [ ] beam_types/1 -- [ ] define_spec/3 -- [ ] define_type/3 -- [ ] define_type/4 -- [ ] defines_callback?/3 -- [ ] defines_spec?/3 -- [ ] defines_type?/3 -- [ ] defspec/3 -- [ ] deftype/3 -- [ ] spec_to_ast/2 -- [ ] spec_to_signature/1 -- [ ] translate_spec/3 -- [ ] translate_type/3 -- [ ] type_to_ast/1 -- [ ] type_to_signature/1 -- [ ] defcallback/1 -- [ ] defmacrocallback/1 -- [ ] defopaque/1 -- [ ] defoptional_callbacks/1 -- [ ] defspec/1 -- [ ] deftype/1 -- [ ] deftypep/1 -## KeyError -- [ ] __struct__/0 -- [ ] __struct__/1 -- [ ] exception/1 -- [ ] message/1 -## MapSet -- [X] __struct__/0 -- [X] __struct__/1 -- [X] delete/2 -- [X] difference/2 -- [X] disjoint?/2 -- [X] equal?/2 -- [X] intersection/2 -- [X] member?/2 -- [X] new/0 -- [ ] new/1 -- [ ] new/2 -- [X] put/2 -- [X] size/1 -- [X] subset?/2 -- [X] to_list/1 -- [X] union/2 -## Macro -- [ ] camelize/1 -- [ ] decompose_call/1 -- [ ] escape/1 -- [ ] escape/2 -- [ ] expand/2 -- [ ] expand_once/2 -- [ ] pipe/3 -- [ ] pipe_warning/1 -- [ ] postwalk/2 -- [ ] postwalk/3 -- [ ] prewalk/2 -- [ ] prewalk/3 -- [ ] to_string/1 -- [ ] to_string/2 -- [ ] traverse/4 -- [ ] underscore/1 -- [ ] unescape_string/1 -- [ ] unescape_string/2 -- [ ] unescape_tokens/1 -- [ ] unescape_tokens/2 -- [ ] unpipe/1 -- [ ] update_meta/2 -- [ ] validate/1 -- [ ] var/2 -- [ ] binary_ops/0 -- [ ] unary_ops/0 +- [ ] `__struct__/0` +- [ ] `__struct__/1` +- [ ] `exception/1` +- [ ] `message/1` +## Tuple +- [X] `append/2` +- [X] `delete_at/2` +- [X] `duplicate/2` +- [X] `insert_at/3` +- [X] `to_list/1` ## URI -- [ ] __struct__/0 -- [ ] __struct__/1 -- [ ] char_reserved?/1 -- [ ] char_unescaped?/1 -- [ ] char_unreserved?/1 -- [ ] decode/1 -- [ ] decode_query/1 -- [ ] decode_query/2 -- [ ] decode_www_form/1 -- [ ] default_port/1 -- [ ] default_port/2 -- [ ] encode/1 -- [ ] encode/2 -- [ ] encode_query/1 -- [ ] encode_www_form/1 -- [ ] merge/2 -- [ ] parse/1 -- [ ] path_to_segments/1 -- [ ] query_decoder/1 -- [ ] to_string/1 -## Inspect.Opts -- [ ] __struct__/0 -- [ ] __struct__/1 -## Atom -- [X] to_char_list/1 -- [ ] to_charlist/1 -- [X] to_string/1 -## TokenMissingError -- [ ] __struct__/0 -- [ ] __struct__/1 -- [ ] exception/1 -- [ ] message/1 -## BadBooleanError -- [ ] __struct__/0 -- [ ] __struct__/1 -- [ ] exception/1 -- [ ] message/1 -## String.Chars.Date -- [ ] __impl__/1 -- [ ] to_string/1 -## Set -- [ ] delete/2 -- [ ] difference/2 -- [ ] disjoint?/2 -- [ ] empty/1 -- [ ] equal?/2 -- [ ] intersection/2 -- [ ] member?/2 -- [ ] put/2 -- [ ] size/1 -- [ ] subset?/2 -- [ ] to_list/1 -- [ ] union/2 -## WithClauseError -- [ ] __struct__/0 -- [ ] __struct__/1 -- [ ] exception/1 -- [ ] message/1 -## List.Chars.Atom -- [ ] __impl__/1 -- [ ] to_charlist/1 +- [ ] `__struct__/0` +- [ ] `__struct__/1` +- [ ] `char_reserved?/1` +- [ ] `char_unescaped?/1` +- [ ] `char_unreserved?/1` +- [ ] `decode/1` +- [ ] `decode_query/1` +- [ ] `decode_query/2` +- [ ] `decode_www_form/1` +- [ ] `default_port/1` +- [ ] `default_port/2` +- [ ] `encode/1` +- [ ] `encode/2` +- [ ] `encode_query/1` +- [ ] `encode_www_form/1` +- [ ] `merge/2` +- [ ] `parse/1` +- [ ] `path_to_segments/1` +- [ ] `query_decoder/1` +- [ ] `to_string/1` +## UndefinedFunctionError +- [ ] `__struct__/0` +- [ ] `__struct__/1` +- [ ] `exception/1` +- [ ] `message/1` +## UnicodeConversionError +- [ ] `__struct__/0` +- [ ] `__struct__/1` +- [ ] `exception/1` +- [ ] `message/1` +## Version +- [ ] `__struct__/0` +- [ ] `__struct__/1` +- [ ] `compare/2` +- [ ] `compile_requirement/1` +- [ ] `match?/2` +- [ ] `match?/3` +- [ ] `parse/1` +- [ ] `parse!/1` +- [ ] `parse_requirement/1` ## Version.InvalidRequirementError -- [ ] __struct__/0 -- [ ] __struct__/1 -- [ ] exception/1 -- [ ] message/1 -## Application -- [ ] app_dir/1 -- [ ] app_dir/2 -- [ ] delete_env/2 -- [ ] delete_env/3 -- [ ] ensure_all_started/1 -- [ ] ensure_all_started/2 -- [ ] ensure_started/1 -- [ ] ensure_started/2 -- [ ] fetch_env/2 -- [ ] fetch_env!/2 -- [ ] format_error/1 -- [ ] get_all_env/1 -- [ ] get_application/1 -- [ ] get_env/2 -- [ ] get_env/3 -- [ ] load/1 -- [ ] loaded_applications/0 -- [ ] put_env/3 -- [ ] put_env/4 -- [ ] spec/1 -- [ ] spec/2 -- [ ] start/1 -- [ ] start/2 -- [ ] started_applications/0 -- [ ] started_applications/1 -- [ ] stop/1 -- [ ] unload/1 -- [ ] __using__/1 -## Inspect.PID -- [ ] __impl__/1 -- [ ] inspect/2 -## Calendar.ISO -- [ ] date/3 -- [ ] date_to_iso8601/3 -- [ ] date_to_string/3 -- [ ] datetime_to_iso8601/11 -- [ ] datetime_to_string/11 -- [ ] day_of_week/3 -- [ ] days_in_month/2 -- [ ] from_unix/2 -- [ ] leap_year?/1 -- [ ] naive_datetime_to_iso8601/7 -- [ ] naive_datetime_to_string/7 -- [ ] parse_microsecond/1 -- [ ] parse_offset/1 -- [ ] time_to_iso8601/4 -- [ ] time_to_string/4 +- [ ] `__struct__/0` +- [ ] `__struct__/1` +- [ ] `exception/1` +- [ ] `message/1` +## Version.InvalidVersionError +- [ ] `__struct__/0` +- [ ] `__struct__/1` +- [ ] `exception/1` +- [ ] `message/1` +## Version.Requirement +- [ ] `__struct__/0` +- [ ] `__struct__/1` +## WithClauseError +- [ ] `__struct__/0` +- [ ] `__struct__/1` +- [ ] `exception/1` +- [ ] `message/1` diff --git a/lib/elixir_script/gen/supported.ex b/lib/elixir_script/gen/supported.ex index 17ec8263..904ac938 100644 --- a/lib/elixir_script/gen/supported.ex +++ b/lib/elixir_script/gen/supported.ex @@ -26,34 +26,39 @@ defmodule ElixirScript.Gen.Supported do def write_to_file(file) do IO.puts(file, "# Supported Elixir Modules") IO.puts(file, "List all public modules in the Elixir Standard Libary. If a function or macro is supported in ElixirScript, it is checked") - module_map = get_module_map() + module_map = get_module_list() Enum.each(module_map, fn({elixir_module, elixir_script_module}) -> IO.puts(file, "## #{inspect elixir_module}") exports = elixir_module.__info__(:functions) ++ elixir_module.__info__(:macros) - elixir_script_exports = if Code.ensure_loaded?(elixir_script_module) do - elixir_script_module.__info__(:functions) ++ elixir_script_module.__info__(:macros) - else - [] + + elixir_script_exports = cond do + elixir_script_module == ElixirScript.Kernel.SpecialForms -> + extra(elixir_script_module) + Code.ensure_loaded?(elixir_script_module) -> + elixir_script_module.__info__(:functions) ++ elixir_script_module.__info__(:macros) ++ extra(elixir_script_module) + true -> + [] end Enum.each(exports, fn({func, arity}) -> if Enum.member?(elixir_script_exports, {func, arity}) do - IO.puts(file, "- [X] #{func}/#{arity}") + IO.puts(file, "- [X] `#{func}/#{arity}`") else - IO.puts(file, "- [ ] #{func}/#{arity}") + IO.puts(file, "- [ ] `#{func}/#{arity}`") end end) end) end - defp get_module_map() do + defp get_module_list() do Application.spec(:elixir, :modules) |> Enum.filter(&is_public(&1)) - |> Enum.reduce(Map.new, fn(x, acc) -> + |> Enum.sort(fn(x, y) -> to_string(x) >= to_string(y) end) + |> Enum.reduce(Keyword.new, fn(x, acc) -> try do elixirscript_module = (["ElixirScript"] ++ Module.split(x)) |> Module.concat() - Map.put(acc, x, elixirscript_module) + Keyword.put(acc, x, elixirscript_module) rescue FunctionClauseError -> acc @@ -68,4 +73,93 @@ defmodule ElixirScript.Gen.Supported do defp is_public(_) do true end + + defp extra(ElixirScript.Kernel.SpecialForms) do + [ + %: 2, + %{}: 1, + &: 1, + ".": 2, + "::": 2, + <<>>: 1, + =: 2, + ^: 1, + __CALLER__: 0, + __DIR__: 0, + __ENV__: 0, + __MODULE__: 0, + __aliases__: 1, + __block__: 1, + alias: 2, + case: 2, + cond: 1, + fn: 1, + for: 1, + import: 2, + quote: 2, + require: 2, + super: 1, + try: 1, + unquote: 1, + unquote_splicing: 1, + with: 1, + {}: 1, + ] + end + + defp extra(ElixirScript.Kernel) do + [ + !=: 2, + !==: 2, + *: 2, + +: 1, + +: 2, + ++: 2, + -: 1, + -: 2, + --: 2, + /: 2, + <: 2, + <=: 2, + ==: 2, + ===: 2, + =~: 2, + >: 2, + >=: 2, + div: 2, + rem: 2, + !: 1, + &&: 2, + <>: 2, + @: 1, + and: 2, + def: 1, + def: 2, + defdelegate: 2, + defexception: 1, + defimpl: 2, + defimpl: 3, + defmacro: 1, + defmacro: 2, + defmacrop: 1, + defmacrop: 2, + defmodule: 2, + defoverridable: 1, + defp: 1, + defp: 2, + defprotocol: 2, + defstruct: 1, + raise: 1, + raise: 2, + or: 2, + use: 1, + use: 2, + ||: 2, + ] + end + + + defp extra(_) do + [] + end end \ No newline at end of file From 2b38d06a639c30416750213f71b22c6a8097ba92 Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Tue, 11 Apr 2017 22:04:00 -0500 Subject: [PATCH 082/418] Add __info__ to each module --- lib/elixir_script/translator.ex | 9 +++-- .../translator/kernel/defmodule.ex | 38 ++++++++++++++++++- test/translator/defmodule_test.exs | 20 +++++++--- 3 files changed, 56 insertions(+), 11 deletions(-) diff --git a/lib/elixir_script/translator.ex b/lib/elixir_script/translator.ex index d8c11001..d71914a9 100644 --- a/lib/elixir_script/translator.ex +++ b/lib/elixir_script/translator.ex @@ -523,15 +523,18 @@ defmodule ElixirScript.Translator do end defp do_translate({function, _, [{:when, _, [{name, _, _params} | _guards] }, _] } = ast, env) when function in @generator_types do - Def.process_function(name, [ast], %{ env | context: :generator}) + {js_ast, _} = Def.process_function(name, [ast], %{ env | context: :generator}) + {js_ast, env} end defp do_translate({function, _, [{name, _, params}, _]} = ast, env) when function in @generator_types and is_atom(params) do - Def.process_function(name, [ast], %{ env | context: :generator}) + {js_ast, _} = Def.process_function(name, [ast], %{ env | context: :generator}) + {js_ast, env} end defp do_translate({function, _, [{name, _, _params}, _]} = ast, env) when function in @generator_types do - Def.process_function(name, [ast], %{ env | context: :generator}) + {js_ast, _} = Def.process_function(name, [ast], %{ env | context: :generator}) + {js_ast, env} end defp do_translate({function, _, [{:when, _, [{name, _, _params} | _guards] }, _] } = ast, env) when function in @function_types do diff --git a/lib/elixir_script/translator/kernel/defmodule.ex b/lib/elixir_script/translator/kernel/defmodule.ex index dd2c76ba..eb77bc00 100644 --- a/lib/elixir_script/translator/kernel/defmodule.ex +++ b/lib/elixir_script/translator/kernel/defmodule.ex @@ -57,6 +57,8 @@ defmodule ElixirScript.Translator.Defmodule do [] end + info_prop = [JS.property(Identifier.make_identifier("__info__"), Identifier.make_identifier("__info__"), :init, true)] + body = Enum.map(body, fn(x) -> case x do %ESTree.CallExpression{} -> @@ -69,7 +71,7 @@ defmodule ElixirScript.Translator.Defmodule do body = Group.inflate_groups(body) exported_object = JS.object_expression( - struct_prop ++ + info_prop ++ struct_prop ++ Enum.map(exported_functions, fn({key, _value}) -> JS.property(Identifier.make_identifier(key), Identifier.make_identifier(key), :init, true) end) @@ -78,7 +80,7 @@ defmodule ElixirScript.Translator.Defmodule do exported_functions = Enum.map(exported_functions, fn({_key, value}) -> value end) private_functions = Enum.map(private_functions, fn({_key, value}) -> value end) - body = private_functions ++ exported_functions ++ body + body = private_functions ++ exported_functions ++ [make_info_function(env)] ++ body {body, exported_object} end @@ -230,4 +232,36 @@ defmodule ElixirScript.Translator.Defmodule do JS.variable_declaration([declarator], :const) end + def make_info_function(env) do + functions = Keyword.get(env.functions, env.module, []) + macros = Keyword.get(env.macros, env.module, []) + + info_case = quote do + case kind do + :functions -> + unquote(functions) + :macros -> + unquote(macros) + :module -> + unquote(env.module) + end + end + + translated_case = ElixirScript.Translator.translate!(info_case, env) + + declarator = JS.variable_declarator( + Identifier.make_identifier("__info__"), + JS.function_expression( + [JS.identifier("kind")], + [], + JS.block_statement([ + JS.return_statement(translated_case) + ]) + ) + ) + + JS.variable_declaration([declarator], :const) + + end + end diff --git a/test/translator/defmodule_test.exs b/test/translator/defmodule_test.exs index 6d7c8b45..8719b2a9 100644 --- a/test/translator/defmodule_test.exs +++ b/test/translator/defmodule_test.exs @@ -9,7 +9,9 @@ defmodule ElixirScript.Translator.Defmodule.Test do end js_code = """ - const __exports = {}; + const __exports = { + __info__ + }; """ assert_translation(ex_ast, js_code) @@ -31,19 +33,25 @@ defmodule ElixirScript.Translator.Defmodule.Test do end js_code = """ - const something = Bootstrap.Core.Patterns.defmatchgen(Bootstrap.Core.Patterns.clause([], function*() { + const something = Bootstrap.Core.Patterns.defmatch(Bootstrap.Core.Patterns.clause([], function() { return ul; })); + const __info__ = function(kind) { + return Bootstrap.Core.Patterns.defmatch(Bootstrap.Core.Patterns.clause([Symbol.for('functions')], function() { + return Object.freeze([new Bootstrap.Core.Tuple(Symbol.for('something'), 0)]); + }), Bootstrap.Core.Patterns.clause([Symbol.for('macros')], function() { + return Object.freeze([]); + }), Bootstrap.Core.Patterns.clause([Symbol.for('module')], function() { + return Symbol.for('Elixir.Elephant'); + })).call(this, kind); + }; + const ul = '#todo-list'; const something_else = Bootstrap.Core.Patterns.defmatchgen(Bootstrap.Core.Patterns.clause([], function*() { return null; })); - - const __exports = { - something - }; """ assert_translation(ex_ast, js_code) From 11f2f9f8a350fd3964221fd874a2ecdbb414924f Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Sun, 16 Apr 2017 19:18:14 -0500 Subject: [PATCH 083/418] Update estree dep --- mix.exs | 4 ++-- mix.lock | 20 ++++++++++---------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/mix.exs b/mix.exs index 8b257ebb..2a84943b 100644 --- a/mix.exs +++ b/mix.exs @@ -28,9 +28,9 @@ defmodule ElixirScript.Mixfile do defp deps do [ - {:estree, "~> 2.5"}, + {:estree, "~> 2.6"}, {:fs, "~> 2.12"}, - {:ex_doc, "~> 0.14", only: :dev}, + {:ex_doc, "~> 0.15", only: :dev}, {:excoveralls, "~> 0.6", only: :test}, {:credo, "~> 0.7", only: [:dev, :test]} ] diff --git a/mix.lock b/mix.lock index 0e03c5b6..b6b6b0d2 100644 --- a/mix.lock +++ b/mix.lock @@ -1,15 +1,15 @@ %{"bunt": {:hex, :bunt, "0.2.0", "951c6e801e8b1d2cbe58ebbd3e616a869061ddadcc4863d0a2182541acae9a38", [:mix], []}, - "certifi": {:hex, :certifi, "0.7.0", "861a57f3808f7eb0c2d1802afeaae0fa5de813b0df0979153cbafcd853ababaf", [:rebar3], []}, - "credo": {:hex, :credo, "0.7.2", "850463f126c09227994967fdcf8b8ad7684ab220f7727c00bcafc0ac37bd3660", [:mix], [{:bunt, "~> 0.2.0", [hex: :bunt, optional: false]}]}, - "earmark": {:hex, :earmark, "1.1.1", "433136b7f2e99cde88b745b3a0cfc3fbc81fe58b918a09b40fce7f00db4d8187", [:mix], []}, - "estree": {:hex, :estree, "2.5.1", "c93a8fa8a29886e6a6f6c489ba6dc949b998d2985b189967e41e69a92b58e846", [:mix], []}, - "ex_doc": {:hex, :ex_doc, "0.14.5", "c0433c8117e948404d93ca69411dd575ec6be39b47802e81ca8d91017a0cf83c", [:mix], [{:earmark, "~> 1.0", [hex: :earmark, optional: false]}]}, - "excoveralls": {:hex, :excoveralls, "0.6.2", "0e993d096f1fbb6e70a3daced5c89aac066bda6bce57829622aa2d1e2b338cfb", [:mix], [{:exjsx, "~> 3.0", [hex: :exjsx, optional: false]}, {:hackney, ">= 0.12.0", [hex: :hackney, optional: false]}]}, - "exjsx": {:hex, :exjsx, "3.2.1", "1bc5bf1e4fd249104178f0885030bcd75a4526f4d2a1e976f4b428d347614f0f", [:mix], [{:jsx, "~> 2.8.0", [hex: :jsx, optional: false]}]}, + "certifi": {:hex, :certifi, "1.0.0", "1c787a85b1855ba354f0b8920392c19aa1d06b0ee1362f9141279620a5be2039", [:rebar3], []}, + "credo": {:hex, :credo, "0.7.3", "9827ab04002186af1aec014a811839a06f72aaae6cd5eed3919b248c8767dbf3", [:mix], [{:bunt, "~> 0.2.0", [hex: :bunt, optional: false]}]}, + "earmark": {:hex, :earmark, "1.2.0", "bf1ce17aea43ab62f6943b97bd6e3dc032ce45d4f787504e3adf738e54b42f3a", [:mix], []}, + "estree": {:hex, :estree, "2.6.0", "86a301b0c355fa55c19e7ef9dceb1b1e983c6df526a2b7846818a38c258fc3fb", [:mix], []}, + "ex_doc": {:hex, :ex_doc, "0.15.1", "d5f9d588fd802152516fccfdb96d6073753f77314fcfee892b15b6724ca0d596", [:mix], [{:earmark, "~> 1.1", [hex: :earmark, optional: false]}]}, + "excoveralls": {:hex, :excoveralls, "0.6.3", "894bf9254890a4aac1d1165da08145a72700ff42d8cb6ce8195a584cb2a4b374", [:mix], [{:exjsx, "~> 3.0", [hex: :exjsx, optional: false]}, {:hackney, ">= 0.12.0", [hex: :hackney, optional: false]}]}, + "exjsx": {:hex, :exjsx, "3.2.1", "1bc5bf1e4fd249104178f0885030bcd75a4526f4d2a1e976f4b428d347614f0f", [], [{:jsx, "~> 2.8.0", [hex: :jsx, optional: false]}]}, "fs": {:hex, :fs, "2.12.0", "ad631efacc9a5683c8eaa1b274e24fa64a1b8eb30747e9595b93bec7e492e25e", [:rebar3], []}, - "hackney": {:hex, :hackney, "1.6.5", "8c025ee397ac94a184b0743c73b33b96465e85f90a02e210e86df6cbafaa5065", [:rebar3], [{:certifi, "0.7.0", [hex: :certifi, optional: false]}, {:idna, "1.2.0", [hex: :idna, optional: false]}, {:metrics, "1.0.1", [hex: :metrics, optional: false]}, {:mimerl, "1.0.2", [hex: :mimerl, optional: false]}, {:ssl_verify_fun, "1.1.1", [hex: :ssl_verify_fun, optional: false]}]}, - "idna": {:hex, :idna, "1.2.0", "ac62ee99da068f43c50dc69acf700e03a62a348360126260e87f2b54eced86b2", [:rebar3], []}, + "hackney": {:hex, :hackney, "1.7.1", "e238c52c5df3c3b16ce613d3a51c7220a784d734879b1e231c9babd433ac1cb4", [:rebar3], [{:certifi, "1.0.0", [hex: :certifi, optional: false]}, {:idna, "4.0.0", [hex: :idna, optional: false]}, {:metrics, "1.0.1", [hex: :metrics, optional: false]}, {:mimerl, "1.0.2", [hex: :mimerl, optional: false]}, {:ssl_verify_fun, "1.1.1", [hex: :ssl_verify_fun, optional: false]}]}, + "idna": {:hex, :idna, "4.0.0", "10aaa9f79d0b12cf0def53038547855b91144f1bfcc0ec73494f38bb7b9c4961", [:rebar3], []}, "jsx": {:hex, :jsx, "2.8.2", "7acc7d785b5abe8a6e9adbde926a24e481f29956dd8b4df49e3e4e7bcc92a018", [:mix, :rebar3], []}, - "metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [:rebar3], []}, + "metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [], []}, "mimerl": {:hex, :mimerl, "1.0.2", "993f9b0e084083405ed8252b99460c4f0563e41729ab42d9074fd5e52439be88", [], []}, "ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.1", "28a4d65b7f59893bc2c7de786dec1e1555bd742d336043fe644ae956c3497fbe", [:make, :rebar], []}} From 547862e23fad79abbfac56b23a5752016f61de45 Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Sun, 16 Apr 2017 19:19:40 -0500 Subject: [PATCH 084/418] Add js module to atom table --- lib/elixir_script/passes/create_js_modules.ex | 40 ++++++++++++++++++- priv/std_lib/range.ex | 4 +- src/javascript/lib/core/functions.js | 4 +- 3 files changed, 43 insertions(+), 5 deletions(-) diff --git a/lib/elixir_script/passes/create_js_modules.ex b/lib/elixir_script/passes/create_js_modules.ex index dbadb4fe..d9e5bb53 100644 --- a/lib/elixir_script/passes/create_js_modules.ex +++ b/lib/elixir_script/passes/create_js_modules.ex @@ -65,10 +65,15 @@ defmodule ElixirScript.Passes.CreateJSModules do elixir = JS.variable_declaration([declarator], :const) + table_additions = Enum.map(opts.js_modules, fn + {module, path} -> add_import_to_table(module) + {module, path, _} -> add_import_to_table(module) + end) + ast = opts.module_formatter.build( [], opts.js_modules, - [elixir, start, load] ++ body, + [elixir, create_atom_table(), start, load] ++ table_additions ++ body, JS.identifier("Elixir") ) @@ -128,4 +133,37 @@ defmodule ElixirScript.Passes.CreateJSModules do ) ) end + + defp create_atom_table() do + JS.assignment_expression( + :=, + JS.member_expression( + JS.identifier("Elixir"), + JS.identifier("__table__") + ), + JS.object_expression([]) + ) + end + + defp add_import_to_table(module_name) do + ref = ElixirScript.Translator.Identifier.make_namespace_members(module_name) + JS.assignment_expression( + :=, + JS.member_expression( + JS.member_expression( + JS.identifier("Elixir"), + JS.identifier("__table__") + ), + JS.call_expression( + JS.member_expression( + JS.identifier("Symbol"), + JS.identifier("for") + ), + [JS.literal(ref.name)] + ), + true + ), + ref + ) + end end diff --git a/priv/std_lib/range.ex b/priv/std_lib/range.ex index 9ae8bffe..7f53b13e 100644 --- a/priv/std_lib/range.ex +++ b/priv/std_lib/range.ex @@ -3,10 +3,10 @@ defmodule ElixirScript.Range do defstruct first: nil, last: nil def new(first, last) do - %ElixirScript.Range{first: first, last: last} + %Range{first: first, last: last} end - def range?(%ElixirScript.Range{}), do: true + def range?(%Range{}), do: true def range?(_), do: false end diff --git a/src/javascript/lib/core/functions.js b/src/javascript/lib/core/functions.js index d0d21099..9df6ba34 100644 --- a/src/javascript/lib/core/functions.js +++ b/src/javascript/lib/core/functions.js @@ -77,8 +77,8 @@ function build_namespace(ns, ns_string) { parent = parent[part]; } - root.__table = ns.__table || {}; - root.__table[Symbol.for(ns_string)] = parent; + root.__table__ = ns.__table__ || {}; + root.__table__[Symbol.for(ns_string)] = parent; return parent; } From e5c433ef94db29cf4ef1020d086bac9eb59255b5 Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Wed, 26 Apr 2017 05:19:27 -0500 Subject: [PATCH 085/418] Add JavaScript Interoperability documentation --- GettingStarted.md | 27 +---------- JavascriptInterop.md | 113 +++++++++++++++++++++++++++++++++++++++++++ mix.exs | 2 +- 3 files changed, 115 insertions(+), 27 deletions(-) create mode 100644 JavascriptInterop.md diff --git a/GettingStarted.md b/GettingStarted.md index 36c5f1f5..95fe5f4a 100644 --- a/GettingStarted.md +++ b/GettingStarted.md @@ -128,32 +128,7 @@ Elixirscript supports public macros. Private macros are currently unsupported. ### JavaScript Interop -Elixirscript has a couple of ways of interacting with JavaScript. - -#### Globally scoped functions - -Use the erlang module syntax, to call JavaScript functions in the global scope. - - # Calling alert - :window.alert("hi") - - # console - :console.log("hello") - - # document - :document.getElementById("main") - -#### Globally scoped modules - -You can call globally scoped modules you would an Elixir module - - Date.now() - -Only works if module begins with a captial letter - -#### The JS module - -The JS module has many other functions and macros. For more information, check out the docs. +Check out the [JavaScript Interoperability](JavaScriptInterop.html) documentation #### Frontend Project Boilerplate diff --git a/JavascriptInterop.md b/JavascriptInterop.md new file mode 100644 index 00000000..13095e2f --- /dev/null +++ b/JavascriptInterop.md @@ -0,0 +1,113 @@ +# JavaScript Interoperability + +## ElixirScript Calling JavaScript + +### JS module + +The `JS` module has functions and macros that help with interacting with JavaScript. +These mostly correspond to JavaScript keywords that may be useful. + +```elixir +# Calling the JavaScript Debugger +JS.debugger() + +# Getting the type of a value +JS.typeof(my_value) + +# Creating a new JavaScript Map +map = JS.new(JS.Map, []) +``` + +### Accessing Global Objects, Functions, and Properties + +In order to interact with JavaScript things in the global scope, append "JS" to them. The global scope corresponds to whatever the global object is in the JavaScript environment you are in. For example, in a browser this would be `window` or `self`: + +```elixir +# Calling alert +JS.alert("hello") + +# Calling a method on Object +JS.Object.keys(my_object) + +# Creating a new JavaScript Date +JS.new(JS.Date, []) + +# Getting the outer width +JS.outerWidth +``` + +### JavaScript modules + +ElixirScript can use JavaScript modules from the supported modules systems. +In order to do so, you must tell ElixirScript about them upfront. + +If using ElixirScript in a mix project, you can do so inside of the ElixirScript configuration keyword list + +```elixir + def project do + [ + app: :my_project, + elixir_script: [ + format: :es, + js_modules: [ + {React, "react"}, + {ReactDOM, "react-dom"} + ] + ] + ] + end +``` + +Or if using the CLI, you can do so by passing each module via the `js-module` flag + +``` +elixirscript "app/elixirscript" -o dist --js-module React:react --js-module ReactDOM:react-dom +``` + +Interacting with these modules works the same as interacting with an ElixirScript module + +```elixir +React.createElement(...) +``` + +## JavaScript Calling ElixirScript + + In order to start an ElixirScript application, you must first import it using whichever JavaScript module system you are using and then call `Elixir.start` + + ```Elixir + # Our ElixirScript module + + defmodule Main do + def start(:normal, args) do + JS.console.log(args) + end + end + + ``` + + ```javascript + //ES module example + import Elixir from './Elixir.App' + Elixir.start(Elixir.Main, [1, 2, 3]) + ``` + + In the above example, we have an ElixirScript module, `Main` with a `start/2` function. This function is the entry point into your ElixirScript application. when we call `Elixir.start`, we give it this module's name (All modules when compiled begin with `Elixir.`) and a list of the initial args. + + + If you want to use an ElixirScript module inside of your JavaScript code, you can do so using `Elixir.load`. + + ```Elixir + # Our ElixirScript module + + defmodule MyModule do + def hi() do + JS.alert("hello") + end + end + ``` + + + ```javascript + const MyModule = Elixir.load(Elixir.MyModule); + MyModule.hi() + ``` \ No newline at end of file diff --git a/mix.exs b/mix.exs index 2a84943b..a9b380f3 100644 --- a/mix.exs +++ b/mix.exs @@ -15,7 +15,7 @@ defmodule ElixirScript.Mixfile do aliases: aliases(), test_coverage: [tool: ExCoveralls], docs: [ - extras: ["GettingStarted.md", "FAQ.md", "Supported.md"] + extras: ["GettingStarted.md", "FAQ.md", "Supported.md", "JavaScriptInterop.md"] ] ] end From e483e17571571174d9b035eeda14e491ae4a3289 Mon Sep 17 00:00:00 2001 From: Connor Rigby Date: Fri, 5 May 2017 15:01:12 -0700 Subject: [PATCH 086/418] Fix typo in GettingStarted.md --- GettingStarted.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/GettingStarted.md b/GettingStarted.md index 95fe5f4a..10059635 100644 --- a/GettingStarted.md +++ b/GettingStarted.md @@ -75,7 +75,7 @@ Adding Elixirscript to your mix project gives you the ability to add it to your Add dependency to your deps in mix.exs: - ```elixir +```elixir {:elixir_script, "~> 0.26"} ``` @@ -100,6 +100,7 @@ Add dependency to your deps in mix.exs: compilers: [:elixir_script] ++ Mix.compilers ] end +``` Available options are: From 1f7434c4c13fd0e29ad2b53d0a941fbe5c8b867d Mon Sep 17 00:00:00 2001 From: Connor Rigby Date: Fri, 5 May 2017 15:02:05 -0700 Subject: [PATCH 087/418] Update GettingStarted.md --- GettingStarted.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/GettingStarted.md b/GettingStarted.md index 10059635..cab117a3 100644 --- a/GettingStarted.md +++ b/GettingStarted.md @@ -75,12 +75,13 @@ Adding Elixirscript to your mix project gives you the ability to add it to your Add dependency to your deps in mix.exs: -```elixir +``` elixir {:elixir_script, "~> 0.26"} - ``` +``` Elixirscript uses default input, output and module formats if options are not given. If you wish to change any or all options, add an `elixir_script` key to your project configuration. - + +``` elixir def project do [ app: :my_app, From 7e215c77f1c894073b4a0098211247e114f74000 Mon Sep 17 00:00:00 2001 From: Connor Rigby Date: Fri, 5 May 2017 15:02:50 -0700 Subject: [PATCH 088/418] Update GettingStarted.md --- GettingStarted.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/GettingStarted.md b/GettingStarted.md index cab117a3..6870c716 100644 --- a/GettingStarted.md +++ b/GettingStarted.md @@ -76,10 +76,10 @@ Adding Elixirscript to your mix project gives you the ability to add it to your Add dependency to your deps in mix.exs: ``` elixir - {:elixir_script, "~> 0.26"} +{:elixir_script, "~> 0.26"} ``` - Elixirscript uses default input, output and module formats if options are not given. If you wish to change any or all options, add an `elixir_script` key to your project configuration. +Elixirscript uses default input, output and module formats if options are not given. If you wish to change any or all options, add an `elixir_script` key to your project configuration. ``` elixir def project do From abca9e267cadc83bf418c38c6cb426520e7728ba Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Thu, 11 May 2017 05:47:41 -0500 Subject: [PATCH 089/418] add .tool-versions file --- .tool-versions | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 .tool-versions diff --git a/.tool-versions b/.tool-versions new file mode 100644 index 00000000..88fcc8d5 --- /dev/null +++ b/.tool-versions @@ -0,0 +1,3 @@ +elixir 1.4.2 +erlang 19.3 +nodejs 7.10.0 \ No newline at end of file From fe909acccebfffecfb2c4688993724ce4aca668a Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Thu, 11 May 2017 20:22:22 -0500 Subject: [PATCH 090/418] Update .tool-versions --- .tool-versions | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.tool-versions b/.tool-versions index 88fcc8d5..822dfebc 100644 --- a/.tool-versions +++ b/.tool-versions @@ -1,3 +1,3 @@ -elixir 1.4.2 -erlang 19.3 +elixir 1.5.0-dev +erlang ref-OTP-20.0-rc1 nodejs 7.10.0 \ No newline at end of file From 8fa0fce8f0d3a7fdc09fd21cb3fb3d2ce19b0a78 Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Fri, 19 May 2017 10:42:02 -0400 Subject: [PATCH 091/418] Got compilation working with new version of elixir --- lib/elixir_script/experimental/backend.ex | 33 + lib/elixir_script/experimental/clause.ex | 115 +++ .../experimental/examples/example.ex | 11 + .../experimental/examples/size.ex | 22 + lib/elixir_script/experimental/form.ex | 187 ++++ .../experimental/forms/bitstring.ex | 147 +++ lib/elixir_script/experimental/forms/call.ex | 45 + lib/elixir_script/experimental/forms/for.ex | 128 +++ lib/elixir_script/experimental/forms/map.ex | 61 ++ lib/elixir_script/experimental/forms/match.ex | 95 ++ .../experimental/forms/pattern.ex | 142 +++ .../experimental/forms/struct.ex | 20 + lib/elixir_script/experimental/forms/try.ex | 98 ++ lib/elixir_script/experimental/function.ex | 48 + .../experimental/functions/erlang.ex | 909 ++++++++++++++++++ .../experimental/functions/lists.ex | 114 +++ .../experimental/functions/maps.ex | 38 + lib/elixir_script/experimental/module.ex | 88 ++ .../experimental/module_state.ex | 21 + lib/elixir_script/next/beam.ex | 19 + lib/elixir_script/next/compiler.ex | 82 ++ lib/elixir_script/next/state.ex | 42 + lib/elixir_script/passes/create_js_modules.ex | 2 +- .../kernel/special_forms/identifier.ex | 7 +- test/beam_test.exs | 8 + 25 files changed, 2480 insertions(+), 2 deletions(-) create mode 100644 lib/elixir_script/experimental/backend.ex create mode 100644 lib/elixir_script/experimental/clause.ex create mode 100644 lib/elixir_script/experimental/examples/example.ex create mode 100644 lib/elixir_script/experimental/examples/size.ex create mode 100644 lib/elixir_script/experimental/form.ex create mode 100644 lib/elixir_script/experimental/forms/bitstring.ex create mode 100644 lib/elixir_script/experimental/forms/call.ex create mode 100644 lib/elixir_script/experimental/forms/for.ex create mode 100644 lib/elixir_script/experimental/forms/map.ex create mode 100644 lib/elixir_script/experimental/forms/match.ex create mode 100644 lib/elixir_script/experimental/forms/pattern.ex create mode 100644 lib/elixir_script/experimental/forms/struct.ex create mode 100644 lib/elixir_script/experimental/forms/try.ex create mode 100644 lib/elixir_script/experimental/function.ex create mode 100644 lib/elixir_script/experimental/functions/erlang.ex create mode 100644 lib/elixir_script/experimental/functions/lists.ex create mode 100644 lib/elixir_script/experimental/functions/maps.ex create mode 100644 lib/elixir_script/experimental/module.ex create mode 100644 lib/elixir_script/experimental/module_state.ex create mode 100644 lib/elixir_script/next/beam.ex create mode 100644 lib/elixir_script/next/compiler.ex create mode 100644 lib/elixir_script/next/state.ex create mode 100644 test/beam_test.exs diff --git a/lib/elixir_script/experimental/backend.ex b/lib/elixir_script/experimental/backend.ex new file mode 100644 index 00000000..a5d3d4e0 --- /dev/null +++ b/lib/elixir_script/experimental/backend.ex @@ -0,0 +1,33 @@ +defmodule ElixirScript.Experimental.Backend do + alias ElixirScript.Experimental.Module + alias ESTree.Tools.Generator + alias ElixirScript.Experimental.ModuleState + + def compile(line, file, module, attrs, defs, unreachable, opts) do + # Print all arguments + #IO.inspect binding() + + # Compile module to JavaScript AST + js_ast = Module.compile(line, file, module, attrs, defs, unreachable, opts) + + # Generate JavaScript code string + js_code = Generator.generate(js_ast) + + #IO.puts js_code + + write_js(module, js_code) + # Invoke the default backend - it returns the compiled beam binary + :elixir_erl.compile(line, file, module, attrs, defs, unreachable, opts) + end + + defp write_js(module, js_code) do + output_dir = Path.join([Mix.Project.build_path(), "_javascript"]) + + if !File.exists?(output_dir) do + File.mkdir_p!(output_dir) + end + + output_path = Path.join([output_dir, "#{module}.js"]) + File.write!(output_path, js_code) + end +end diff --git a/lib/elixir_script/experimental/clause.ex b/lib/elixir_script/experimental/clause.ex new file mode 100644 index 00000000..29327f77 --- /dev/null +++ b/lib/elixir_script/experimental/clause.ex @@ -0,0 +1,115 @@ +defmodule ElixirScript.Experimental.Clause do + alias ESTree.Tools.Builder, as: J + alias ElixirScript.Experimental.Form + alias ElixirScript.Experimental.Forms.Pattern + + @moduledoc """ + Handles translation of all of the clause ASTs + """ + + @patterns J.member_expression( + J.member_expression( + J.identifier("Bootstrap"), + J.identifier("Core") + ), + J.identifier("Patterns") + ) + + def compile({ _, args, guards, body}, state) do + {patterns, params} = Pattern.compile(args, state) + guard = compile_guard(params, guards, state) + + body = case body do + nil -> + J.identifier("null") + {:__block__, _, block_body} -> + Enum.map(block_body, &Form.compile(&1, state)) + |> List.flatten + _ -> + Form.compile(body, state) + end + + body = return_last_statement(body) + + J.call_expression( + J.member_expression( + @patterns, + J.identifier("clause") + ), + [ + J.array_expression(patterns), + J.function_expression( + params, + [], + J.block_statement(body) + ), + guard + ] + ) + end + + def compile({:->, _, [[{:when, _, params}], body ]}, state) do + guards = List.last(params) + params = params |> Enum.reverse |> tl |> Enum.reverse + + compile({[], params, guards, body}, state) + end + + def compile({:->, _, [params, body]}, state) do + compile({[], params, [], body}, state) + end + + def return_last_statement(body) do + body + |> List.wrap + |> Enum.reverse + |> do_return_last_statement + |> Enum.reverse + end + + defp do_return_last_statement([%ESTree.ThrowStatement{} = ast]) do + [ast] + end + + defp do_return_last_statement([head]) do + [J.return_statement(head)] + end + + defp do_return_last_statement([%ESTree.ThrowStatement{} = head | tail]) do + [head] ++ tail + end + + defp do_return_last_statement([head | tail]) do + [J.return_statement(head)] ++ tail + end + + defp compile_guard(params, guards, state) do + + guards = guards + |> List.wrap + |> Enum.reverse + |> process_guards + |> Form.compile(state) + + J.function_expression( + params, + [], + J.block_statement([ + J.return_statement(guards) + ]) + ) + + end + + defp process_guards([]) do + true + end + + defp process_guards([guard]) do + guard + end + + defp process_guards([head | tail]) do + {{:., [], [:erlang, :orelse]}, [], [process_guards(tail), head]} + end +end diff --git a/lib/elixir_script/experimental/examples/example.ex b/lib/elixir_script/experimental/examples/example.ex new file mode 100644 index 00000000..c6914c21 --- /dev/null +++ b/lib/elixir_script/experimental/examples/example.ex @@ -0,0 +1,11 @@ +defmodule Example do + @compile {:undocumented_elixir_backend_option, ElixirScript.Experimental.Backend} + + defstruct [:name] + + def new() do + JS.Map.new() + Hello.hi() + end + +end diff --git a/lib/elixir_script/experimental/examples/size.ex b/lib/elixir_script/experimental/examples/size.ex new file mode 100644 index 00000000..e16baa30 --- /dev/null +++ b/lib/elixir_script/experimental/examples/size.ex @@ -0,0 +1,22 @@ +defprotocol Example.Size do + @compile {:undocumented_elixir_backend_option, ElixirScript.Experimental.Backend} + def size(data) +end + +defimpl Example.Size, for: BitString do + @compile {:undocumented_elixir_backend_option, ElixirScript.Experimental.Backend} + + def size(string), do: byte_size(string) +end + +defimpl Example.Size, for: Map do + @compile {:undocumented_elixir_backend_option, ElixirScript.Experimental.Backend} + + def size(map), do: map_size(map) +end + +defimpl Example.Size, for: Tuple do + @compile {:undocumented_elixir_backend_option, ElixirScript.Experimental.Backend} + + def size(tuple), do: tuple_size(tuple) +end \ No newline at end of file diff --git a/lib/elixir_script/experimental/form.ex b/lib/elixir_script/experimental/form.ex new file mode 100644 index 00000000..6c9a7c06 --- /dev/null +++ b/lib/elixir_script/experimental/form.ex @@ -0,0 +1,187 @@ +defmodule ElixirScript.Experimental.Form do + alias ESTree.Tools.Builder, as: J + alias ElixirScript.Experimental.Forms.{Map, Bitstring, Match, Call, Try, For, Struct} + alias ElixirScript.Experimental.Functions.{Erlang, Lists, Maps} + alias ElixirScript.Translator.Identifier + alias ElixirScript.Experimental.Clause + + @moduledoc """ + Handles translation of all forms that are not functions or clauses + """ + + def compile(nil, _) do + J.identifier("null") + end + + def compile(form, _) when is_boolean(form) when is_integer(form) when is_float(form) when is_binary(form) do + J.literal(form) + end + + def compile(form, state) when is_list(form) do + J.array_expression( + Enum.map(form, &compile(&1, state)) + ) + end + + def compile(form, state) when is_atom(form) do + if ElixirScript.Experimental.Module.is_elixir_module(form) do + members = ["Elixir"] ++ Module.split(form) + J.identifier(Enum.join(members, "_")) + else + J.call_expression( + J.member_expression( + J.identifier("Symbol"), + J.identifier("for") + ), + [J.literal(form)] + ) + end + end + + def compile({a, b}, state) do + compile({:{}, [], [a, b]}, state) + end + + def compile({:{}, _, elements}, state) do + J.call_expression( + J.member_expression( + J.member_expression( + J.identifier("Bootstrap"), + J.identifier("Core") + ), + J.identifier("Tuple") + ), + Enum.map(elements, &compile(&1, state)) + ) + end + + def compile({:%{}, _, _} = map, state) do + Map.compile(map, state) + end + + def compile({:<<>>, _, _} = bitstring, state) do + Bitstring.compile(bitstring, state) + end + + def compile({:=, _, [left, right]} = match, state) do + Match.compile(match, state) + end + + def compile({:%, _, [_, _]} = ast, state) do + Struct.compile(ast, state) + end + + def compile({:for, _, _} = ast, state) do + For.compile(ast, state) + end + + def compile({:case, _, [condition, [do: clauses]]}, state) do + func = J.call_expression( + J.member_expression( + ElixirScript.Experimental.Function.patterns_ast(), + J.identifier("defmatch") + ), + Enum.map(clauses, &Clause.compile(&1, state)) + ) + + J.call_expression( + J.member_expression( func, J.identifier("call")), + [J.identifier(:this), compile(condition, state)] + ) + end + + def compile({:cond, _, [[do: clauses]]}, state) do + processed_clauses = Enum.map(clauses, fn({:->, _, [clause, clause_body]}) -> + translated_body = Enum.map(List.wrap(clause_body), &compile(&1, state)) + |> Clause.return_last_statement + translated_body = J.function_expression([], [], J.block_statement(translated_body)) + + translated_clause = compile(hd(clause), state) + + + J.array_expression([translated_clause, translated_body]) + end) + + + cond_function = J.member_expression( + J.member_expression( + J.identifier("Bootstrap"), + J.member_expression( + J.identifier("Core"), + J.identifier("SpecialForms") + ) + ), + J.identifier("cond") + ) + + J.call_expression( + cond_function, + processed_clauses + ) + end + + def compile({:receive, context, _}, state) do + line = Keyword.get(context, :line, 1) + raise ElixirScriptCompileError, message: "Line: #{line} receive not supported" + end + + def compile({:try, _, [blocks]}, state) do + Try.compile(blocks, state) + end + + def compile({:fn, _, clauses}, state) do + J.call_expression( + J.member_expression( + ElixirScript.Experimental.Function.patterns_ast(), + J.identifier("defmatch") + ), + Enum.map(clauses, &Clause.compile(&1, state)) + ) + end + + def compile({{:., _, [:erlang, _]}, _, _} = ast, state) do + Erlang.rewrite(ast, state) + end + + def compile({{:., _, [:lists, _]}, _, _} = ast, state) do + Lists.rewrite(ast, state) + end + + def compile({{:., _, [:maps, _]}, _, _} = ast, state) do + Maps.rewrite(ast, state) + end + + def compile({{:., _, [_, _]}, _, _} = ast, state) do + Call.compile(ast, state) + end + + def compile({:super, context, params}, state) do + {function_name, _} = Keyword.fetch!(context, :function) + IO.inspect {"HERE!!!!", function_name} + + J.call_expression( + ElixirScript.Translator.Identifier.make_function_name(function_name, length(params)), + Enum.map(params, &compile(&1, state)) + ) + end + + def compile({function_name, _, params}, state) when is_list(params) do + case function_name do + a when is_atom(a) -> + J.call_expression( + ElixirScript.Translator.Identifier.make_function_name(function_name, length(params)), + Enum.map(params, &compile(&1, state)) + ) + _ -> + J.call_expression( + compile(function_name, state), + Enum.map(params, &compile(&1, state)) + ) + end + end + + def compile({var, _, _}, state) do + ElixirScript.Translator.Identifier.make_identifier(var) + end + +end diff --git a/lib/elixir_script/experimental/forms/bitstring.ex b/lib/elixir_script/experimental/forms/bitstring.ex new file mode 100644 index 00000000..ed978e5a --- /dev/null +++ b/lib/elixir_script/experimental/forms/bitstring.ex @@ -0,0 +1,147 @@ +defmodule ElixirScript.Experimental.Forms.Bitstring do + @moduledoc false + alias ESTree.Tools.Builder, as: JS + alias ElixirScript.Experimental.Form + + + def compile({:<<>>, _, elements}, state) do + js_ast = JS.new_expression( + JS.member_expression( + JS.member_expression( + JS.identifier("Bootstrap"), + JS.identifier("Core") + ), + JS.identifier("BitString") + ), + Enum.map(elements, &compile_element(&1, state)) + ) + + js_ast + end + + def compile_element(element, state) when is_number(element) do + do_compile_element({:integer, Form.compile(element, state)}) + end + + def compile_element(element, state) when is_binary(element) do + do_compile_element({:binary, Form.compile(element, state)}) + end + + def compile_element({:<<>>, [], elements}, state) do + {ast, _} = compile(elements, state) + ast + end + + def compile_element({:::, _, [element, {type, _, _}]}, state) when type in [:integer, :float, :bitstring, :bits, :binary, :bytes, :utf8, :utf16, :utf32, :signed, :unsigned] do + do_compile_element({type, translate_element(element, state)}) + end + + def compile_element({:::, _, [element, {type, _, params}]}, state) when type in [:size, :unit] do + do_compile_element({type, translate_element(element, state), Enum.map(params, &translate_element(&1, state))}) + end + + def compile_element({:::, _, [element, {:*, _, [size, unit]}]}, state) do + size_ast = do_compile_element({:size, translate_element(element, state), [translate_element(size, state)]}) + do_compile_element({:unit, size_ast, [translate_element(unit, state)]}) + end + + def compile_element({:::, _, [element, {:-, _, types}]}, state) do + handle_type_adjectives({:-, [], types}, translate_element(element, state), state) + end + + def compile_element({:::, _, [element, size]}, state) do + do_compile_element({:size, translate_element(element, state), [translate_element(size, state)]}) + end + + def compile_element(element, state) do + do_compile_element({:binary, translate_element(element, state)}) + end + + def translate_element(ElixirScript.Translator.PatternMatching, _) do + JS.object_expression([JS.property( + JS.literal("value"), + ElixirScript.Translator.PatternMatching.parameter() + ) + ]) + end + + def translate_element(element, state) do + Form.compile(element, state) + end + + defp handle_type_adjectives({:-, _, types}, ast, state) do + Enum.reduce(types, ast, fn(type, current_ast) -> + case type do + {:-, _, sub_types} -> + handle_type_adjectives({:-, [], sub_types}, current_ast, state) + {:*, _, [size, unit]} -> + size_ast = do_compile_element({:size, current_ast, [Form.compile(size, state)]}) + do_compile_element({:unit, size_ast, [Form.compile(unit, state)]}) + {the_type, _, params} when is_list(params) -> + do_compile_element({the_type, current_ast, Enum.map(params, &Form.compile(&1, state))}) + {the_type, _, _} -> + do_compile_element({the_type, current_ast}) + end + end) + end + + defp bitstring_class() do + JS.member_expression( + JS.member_expression( + JS.identifier("Bootstrap"), + JS.identifier("Core") + ), + JS.identifier("BitString") + ) + end + + defp do_compile_element({type, ast}) do + JS.call_expression( + JS.member_expression( + bitstring_class, + JS.identifier(type) + ), + [ + ast + ] + ) + end + + defp do_compile_element({type, ast, params}) when is_list(params) do + JS.call_expression( + JS.member_expression( + bitstring_class, + JS.identifier(type) + ), + [ + ast + ] ++ params + ) + end + + def make_interpolated_string(elements, state) do + translated_elements = Enum.map(elements, fn(x)-> + case x do + elem when is_binary(elem) -> + Form.compile(elem, state) + {:::, _, data} -> + Form.compile(hd(data), state) + end + end) + + { do_make_interpolated_string(tl(translated_elements), hd(translated_elements)) } + end + + defp do_make_interpolated_string([], ast, _) do + ast + end + + defp do_make_interpolated_string(elements, ast) do + JS.binary_expression( + :+, + ast, + do_make_interpolated_string(tl(elements), hd(elements)) + ) + end + +end diff --git a/lib/elixir_script/experimental/forms/call.ex b/lib/elixir_script/experimental/forms/call.ex new file mode 100644 index 00000000..efd578c3 --- /dev/null +++ b/lib/elixir_script/experimental/forms/call.ex @@ -0,0 +1,45 @@ +defmodule ElixirScript.Experimental.Forms.Call do + alias ESTree.Tools.Builder, as: J + alias ElixirScript.Experimental.Form + alias ElixirScript.Translator.Identifier + alias ElixirScript.State, as: ModuleState + + def compile({{:., _, [module, function]}, _, params}, state) do + function_name = cond do + ElixirScript.Experimental.Module.is_js_module(module, state) -> + ElixirScript.Translator.Identifier.make_extern_function_name(function) + ElixirScript.Experimental.Module.is_elixir_module(module) -> + if ModuleState.get_module(state.pid, module) == nil do + ElixirScript.Experimental.Module.compile(module, state.pid) + end + ElixirScript.Translator.Identifier.make_function_name(function, length(params)) + true -> + ElixirScript.Translator.Identifier.make_function_name(function, length(params)) + end + + J.call_expression( + J.member_expression( + process_module_name(module, state), + function_name + ), + Enum.map(params, &Form.compile(&1, state)) + ) + end + + defp process_module_name(module, state) when is_atom(module) do + cond do + ElixirScript.Experimental.Module.is_js_module(module, state) -> + members = tl(Module.split(module)) + Identifier.make_namespace_members(members) + ElixirScript.Experimental.Module.is_elixir_module(module) -> + members = ["Elixir"] ++ Module.split(module) + J.identifier(Enum.join(members, "_")) + true -> + ElixirScript.Translator.Identifier.make_identifier(module) + end + end + + defp process_module_name(module, state) do + Form.compile(module, state) + end +end diff --git a/lib/elixir_script/experimental/forms/for.ex b/lib/elixir_script/experimental/forms/for.ex new file mode 100644 index 00000000..b98604e6 --- /dev/null +++ b/lib/elixir_script/experimental/forms/for.ex @@ -0,0 +1,128 @@ +defmodule ElixirScript.Experimental.Forms.For do + alias ESTree.Tools.Builder, as: JS + alias ElixirScript.Experimental.Form + alias ElixirScript.Experimental.Clause + alias ElixirScript.Experimental.Forms.{Pattern} + + def compile({:for, _, generators}, state) do + args = handle_args(generators, state) + + generators = JS.array_expression(args.generators) + + into = args.into || JS.array_expression([]) + filter = args.filter || JS.function_expression([], [], JS.block_statement([JS.return_statement(JS.identifier("true"))])) + fun = args.fun + + + expression = JS.call_expression( + JS.member_expression( + JS.member_expression( + JS.member_expression( + JS.identifier("Bootstrap"), + JS.identifier("Core") + ), + JS.identifier("Patterns") + ), + JS.identifier("clause") + ), + [JS.array_expression(args.patterns), fun, filter] + ) + + collectable = JS.member_expression( + JS.identifier("Elixir"), + JS.identifier("Collectable") + ) + + JS.call_expression( + JS.member_expression( + JS.member_expression( + JS.identifier("Bootstrap"), + JS.member_expression( + JS.identifier("Core"), + JS.identifier("SpecialForms") + ) + ), + JS.identifier("_for") + ), + [expression, generators, collectable, into] + ) + end + + defp handle_args(generators, module_state) do + Enum.reduce(generators, %{generators: [], args: [], filter: nil, fun: nil, into: nil, patterns: []}, fn + + ({:<<>>, _, body}, state) -> + {bs_parts, collection} = Enum.map_reduce(body, nil, fn + {:::, _, _} = ast, state -> + {ast, state} + {:<-, _, [var, collection]}, _ -> + {var, collection} + end) + + {patterns, params} = Pattern.compile([{:<<>>, [], bs_parts}], module_state) + + gen = JS.call_expression( + JS.member_expression( + JS.member_expression( + JS.member_expression( + JS.identifier("Bootstrap"), + JS.identifier("Core") + ), + JS.identifier("Patterns") + ), + JS.identifier("bitstring_generator") + ), + [hd(patterns), Form.compile(collection, module_state)] + ) + + %{state | generators: state.generators ++ [gen], args: state.args ++ params, patterns: state.patterns ++ patterns} + + ({:<-, _, [identifier, enum]}, state) -> + {patterns, params} = Pattern.compile([identifier], module_state) + + gen = JS.call_expression( + JS.member_expression( + JS.member_expression( + JS.member_expression( + JS.identifier("Bootstrap"), + JS.identifier("Core") + ), + JS.identifier("Patterns") + ), + JS.identifier("list_generator") + ), + [hd(patterns), Form.compile(enum, module_state)] + ) + + %{state | generators: state.generators ++ [gen], args: state.args ++ params, patterns: state.patterns ++ patterns} + ([into: expression], state) -> + %{state | into: Form.compile(expression, module_state)} + + ([into: expression, do: expression2], state) -> + fun = create_function_expression(expression2, state, module_state) + + %{state | into: Form.compile(expression, module_state), fun: fun} + + ([do: expression], state) -> + fun = create_function_expression(expression, state, module_state) + + %{state | fun: fun} + (filter, state) -> + fun = create_function_expression(filter, state, module_state) + + %{state | filter: fun} + end) + end + + + defp create_function_expression(ast, state, module_state) do + ast = Enum.map(List.wrap(ast), &Form.compile(&1, module_state)) + |> Clause.return_last_statement + + JS.function_expression( + state.args, + [], + JS.block_statement(ast) + ) + end +end diff --git a/lib/elixir_script/experimental/forms/map.ex b/lib/elixir_script/experimental/forms/map.ex new file mode 100644 index 00000000..bac66534 --- /dev/null +++ b/lib/elixir_script/experimental/forms/map.ex @@ -0,0 +1,61 @@ +defmodule ElixirScript.Experimental.Forms.Map do + alias ESTree.Tools.Builder, as: J + alias ElixirScript.Experimental.Form + + def compile({:%{}, _, [{:|, _, [map, new_values]}]}, state) do + map = Form.compile(map, state) + data = Form.compile({:%{}, [], new_values}, state) + + J.call_expression( + J.member_expression( + J.member_expression( + J.identifier("Bootstrap"), + J.member_expression( + J.identifier("Core"), + J.identifier("SpecialForms") + ) + ), + J.identifier("map_update") + ), + [map, data] + ) + end + + def compile({:%{}, _, properties}, state) do + properties + |> Enum.map(fn + ({x, y}) -> + case x do + {_, _, nil } -> + J.property(Form.compile(x, state), Form.compile(y, state), :init, false, false, true) + _ -> + make_property(Form.compile(x, state), Form.compile(y, state)) + end + end) + |> J.object_expression + end + + def make_property(%ESTree.Identifier{} = key, value) do + J.property(key, value) + end + + def make_property(%ESTree.Literal{value: k}, value) when is_binary(k) do + key = case String.contains?(k, "-") do + true -> + J.literal(k) + false -> + ElixirScript.Translator.Identifier.make_identifier(k) + end + + J.property(key, value) + end + + def make_property(key, value) do + J.property(key, value, :init, false, false, true) + end + + def make_shorthand_property(%ESTree.Identifier{} = key) do + J.property(key, key, :init, true) + end + +end diff --git a/lib/elixir_script/experimental/forms/match.ex b/lib/elixir_script/experimental/forms/match.ex new file mode 100644 index 00000000..9d0275c7 --- /dev/null +++ b/lib/elixir_script/experimental/forms/match.ex @@ -0,0 +1,95 @@ +defmodule ElixirScript.Experimental.Forms.Match do + alias ESTree.Tools.Builder, as: J + alias ElixirScript.Experimental.Form + alias ElixirScript.Experimental.Forms.{Pattern} + + def compile({:=, _, [left, right]}, state) do + right_ast = Form.compile(right, state) + + { patterns, params } = Pattern.compile([left], state) + + declarator = J.variable_declarator( + J.array_pattern(params), + J.call_expression( + J.member_expression( + J.member_expression( + J.member_expression( + J.identifier("Bootstrap"), + J.identifier("Core") + ), + J.identifier("Patterns") + ), + J.identifier("match") + ), + [hd(patterns), right_ast] + ) + ) + + array_pattern = J.variable_declaration([declarator], :let) + + js_ast = case left do + list when is_list(list) -> + make_list_ref(array_pattern, params, state) + { _, _ } -> + make_tuple_ref(array_pattern, params) + {:{}, _, _ } -> + make_tuple_ref(array_pattern, params) + _ -> + array_pattern + end + + js_ast + end + + + defp make_list_ref(array_pattern, params, state) do + {ref, params} = make_params(params) + + ref_declarator = J.variable_declarator( + ref, + J.array_expression( + Enum.map(params, &Form.compile(&1, state)) + ) + ) + + make_variable_declaration_and_group(ref_declarator, array_pattern) + end + + defp make_tuple_ref(array_pattern, params) do + {ref, params} = make_params(params) + + ref_declarator = J.variable_declarator( + ref, + J.new_expression( + J.member_expression( + J.identifier("Bootstrap"), + J.member_expression( + J.identifier("Core"), + J.identifier("Tuple") + ) + ), + params + ) + ) + + make_variable_declaration_and_group(ref_declarator, array_pattern) + end + + + defp make_params(params) do + ref = J.identifier("_ref") + + params = Enum.map(params, fn + (nil) -> J.identifier(:undefined) + (x) -> x + end) + + { ref, params } + end + + defp make_variable_declaration_and_group(ref_declarator, array_pattern) do + ref_declaration = J.variable_declaration([ref_declarator], :let) + [array_pattern, ref_declaration] + end + +end \ No newline at end of file diff --git a/lib/elixir_script/experimental/forms/pattern.ex b/lib/elixir_script/experimental/forms/pattern.ex new file mode 100644 index 00000000..c745b020 --- /dev/null +++ b/lib/elixir_script/experimental/forms/pattern.ex @@ -0,0 +1,142 @@ +defmodule ElixirScript.Experimental.Forms.Pattern do + alias ElixirScript.Translator.PatternMatching, as: PM + alias ESTree.Tools.Builder, as: J + alias ElixirScript.Experimental.Form + alias ElixirScript.Experimental.Forms.{Bitstring, Map} + + @moduledoc """ + Handles all pattern matching translations + """ + + def compile(patterns, state) do + patterns + |> Enum.reduce({[], []}, fn + x, { patterns, params } -> + {pattern, param} = process_pattern(x, state) + { patterns ++ List.wrap(pattern), params ++ List.wrap(param) } + end) + end + + defp process_pattern(term, state) when is_number(term) or is_binary(term) or is_boolean(term) or is_atom(term) or is_nil(term) do + { [Form.compile(term, state)], [] } + end + + defp process_pattern({:^, _, [value]}, state) do + { [PM.bound(Form.compile(value, state))], [nil] } + end + + defp process_pattern({:_, _, _}, _) do + { [PM.wildcard()], [J.identifier(:_)] } + end + + defp process_pattern({a, b}, state) do + process_pattern({:{}, [], [a, b] }, state) + end + + defp process_pattern({:{}, _, elements }, state) do + { patterns, params } = elements + |> Enum.map(&compile([&1], state)) + |> reduce_patterns(state) + + pattern = J.object_expression([ + J.property( + J.identifier("values"), + J.array_expression(patterns) + ) + ]) + + tuple = J.member_expression( + J.member_expression( + J.identifier("Bootstrap"), + J.identifier("Core") + ), + J.identifier("Tuple") + ) + + { [PM.type(tuple, pattern)], params } + end + + defp process_pattern(list, state) when is_list(list) do + { patterns, params } = list + |> Enum.map(&compile([&1], state)) + |> reduce_patterns(state) + + {[J.array_expression(patterns)], params} + end + + defp process_pattern({:%{}, _, props}, state) do + properties = Enum.map(props, fn({key, value}) -> + {pattern, params} = process_pattern(value, state) + property = case key do + {:^, _, [the_key]} -> + J.property(Form.compile(the_key, state), hd(List.wrap(pattern)), :init, false, false, true) + _ -> + Map.make_property(Form.compile(key, state), hd(List.wrap(pattern))) + end + + { property, params } + end) + + {props, params} = Enum.reduce(properties, {[], []}, fn({prop, param}, {props, params}) -> + { props ++ [prop], params ++ param } + end) + + { J.object_expression(List.wrap(props)), params } + end + + defp process_pattern({:<<>>, _, elements}, state) do + params = Enum.reduce(elements, [], fn + ({:::, _, [{ variable, _, params }, _]}, state) when is_nil(params) + when is_list(params) and length(params) == 0 -> + state ++ [ElixirScript.Translator.Identifier.make_identifier(variable)] + _, state -> + state + end) + + elements = Enum.map(elements, fn + ({:::, context, [{ _, _, params }, options]}) when is_atom(params) -> + Bitstring.compile_element({:::, context, [ElixirScript.Translator.PatternMatching, options]}, state) + x -> + Bitstring.compile_element(x, state) + end) + + { [PM.bitstring_match(elements)], params } + end + + defp process_pattern([{:|, _, [head, tail]}], state) do + { head_patterns, head_params } = process_pattern(head, state) + { tail_patterns, tail_params } = process_pattern(tail, state) + params = head_params ++ tail_params + + { [PM.head_tail(hd(head_patterns), hd(tail_patterns))], params } + end + + defp process_pattern({:<>, _, [prefix, value]}, state) do + { [PM.starts_with(prefix)], [Form.compile(value, state)] } + end + + defp process_pattern({:=, _, [{name, _, _}, right]}, state) do + unify(name, right, state) + end + + defp process_pattern({:=, _, [left, {name, _, _}]}, state) do + unify(name, left, state) + end + + defp process_pattern({var, _, _}, _) do + { [PM.parameter()], [ElixirScript.Translator.Identifier.make_identifier(var)] } + end + + defp reduce_patterns(patterns, _) do + patterns + |> Enum.reduce({ [], [] }, fn({ pattern, new_param }, { patterns, new_params }) -> + { patterns ++ List.wrap(pattern), new_params ++ List.wrap(new_param) } + end) + end + + defp unify(target, source, state) do + { patterns, params } = compile([source], state) + { [PM.capture(hd(patterns))], params ++ [ElixirScript.Translator.Identifier.make_identifier(target)] } + end + +end diff --git a/lib/elixir_script/experimental/forms/struct.ex b/lib/elixir_script/experimental/forms/struct.ex new file mode 100644 index 00000000..7aebfa78 --- /dev/null +++ b/lib/elixir_script/experimental/forms/struct.ex @@ -0,0 +1,20 @@ +defmodule ElixirScript.Experimental.Forms.Struct do + alias ESTree.Tools.Builder, as: J + alias ElixirScript.Experimental.Form + alias ElixirScript.Translator.Identifier + + def compile({:%, _, [module, params]}, state) do + J.call_expression( + J.member_expression( + process_module_name(module), + J.identifier("__struct__1") + ), + [Form.compile(params, state)] + ) + end + + defp process_module_name(module) do + members = ["Elixir"] ++ Module.split(module) + Identifier.make_namespace_members(members) + end +end diff --git a/lib/elixir_script/experimental/forms/try.ex b/lib/elixir_script/experimental/forms/try.ex new file mode 100644 index 00000000..effe3fbd --- /dev/null +++ b/lib/elixir_script/experimental/forms/try.ex @@ -0,0 +1,98 @@ +defmodule ElixirScript.Experimental.Forms.Try do + @moduledoc false + alias ESTree.Tools.Builder, as: JS + alias ElixirScript.Experimental.Clause + alias ElixirScript.Experimental.Form + + def compile(blocks, state) do + try_block = Keyword.get(blocks, :do) + rescue_block = Keyword.get(blocks, :rescue, nil) + catch_block = Keyword.get(blocks, :catch, nil) + after_block = Keyword.get(blocks, :after, nil) + else_block = Keyword.get(blocks, :else, nil) + + translated_body = prepare_function_body(try_block, state) + + translated_body = JS.block_statement(translated_body) + try_block = JS.function_expression([], [], translated_body) + + rescue_block = if rescue_block do + process_rescue_block(rescue_block, state) + else + JS.identifier(:null) + end + + catch_block = if catch_block do + Form.compile({:fn, [], catch_block}, state) + else + JS.identifier(:null) + end + + after_block = if after_block do + process_after_block(after_block, state) + else + JS.identifier(:null) + end + + else_block = if else_block do + Form.compile({:fn, [], else_block}, state) + else + JS.identifier(:null) + end + + js_ast = JS.call_expression( + JS.member_expression( + JS.member_expression( + JS.identifier("Bootstrap"), + JS.member_expression( + JS.identifier("Core"), + JS.identifier("SpecialForms") + ) + ), + JS.identifier("_try") + ), + [ + try_block, + rescue_block, + catch_block, + else_block, + after_block + ] + ) + + js_ast + end + + defp process_rescue_block(rescue_block, state) do + processed_clauses = Enum.map(rescue_block, fn + {:->, _, [ [{:in, _, [param, names]} = pattern], body]} -> + Clause.compile({[], [param], [{{:., [], [Enum, :member?]}, [], [param, names]}], body}, state) + {:->, _, [ [param], body]} -> + Clause.compile({[], [param], [], body}, state) + end) + + + JS.call_expression( + JS.member_expression( + ElixirScript.Experimental.Function.patterns_ast(), + JS.identifier("defmatch") + ), + processed_clauses + ) + + end + + defp process_after_block(after_block, state) do + translated_body = prepare_function_body(after_block, state) + translated_body = JS.block_statement(translated_body) + + JS.function_expression([], [], translated_body) + end + + defp prepare_function_body(body, state) do + body + |> List.wrap + |> Enum.map(&Form.compile(&1, state)) + |> Clause.return_last_statement + end +end diff --git a/lib/elixir_script/experimental/function.ex b/lib/elixir_script/experimental/function.ex new file mode 100644 index 00000000..1ac7a330 --- /dev/null +++ b/lib/elixir_script/experimental/function.ex @@ -0,0 +1,48 @@ +defmodule ElixirScript.Experimental.Function do + alias ESTree.Tools.Builder, as: J + alias ElixirScript.Experimental.Clause + + @moduledoc """ + Translates the given Elixir function AST into the + equivalent JavaScript AST. Function names are + + """ + + def patterns_ast() do + J.member_expression( + J.member_expression( + J.identifier("Bootstrap"), + J.identifier("Core") + ), + J.identifier("Patterns") + ) + end + + def compile({{name, arity}, type, _, clauses}, state) do + clauses = Enum.map(clauses, fn(clause) -> + + # Walk the AST and add the function to the context. + # This information is used when translating "super" + Macro.prewalk(clause, fn + {subject, context, params} -> + {subject, Keyword.put(context, :function, {name, arity}), params } + ast -> + ast + end) + end) + + + declarator = J.variable_declarator( + ElixirScript.Translator.Identifier.make_function_name(name, arity), + J.call_expression( + J.member_expression( + patterns_ast(), + J.identifier("defmatch") + ), + Enum.map(clauses, &Clause.compile(&1, state)) + ) + ) + + J.variable_declaration([declarator], :const) + end +end diff --git a/lib/elixir_script/experimental/functions/erlang.ex b/lib/elixir_script/experimental/functions/erlang.ex new file mode 100644 index 00000000..cbe63f26 --- /dev/null +++ b/lib/elixir_script/experimental/functions/erlang.ex @@ -0,0 +1,909 @@ +defmodule ElixirScript.Experimental.Functions.Erlang do + @moduledoc false + alias ESTree.Tools.Builder, as: J + alias ElixirScript.Experimental.Form + + def rewrite({{:., _, [:erlang, :abs]}, _, [number]}, state) do + J.call_expression( + J.member_expression( + J.identifier("Math"), + J.identifier("abs") + ), + [Form.compile(number, state)] + ) + end + + def rewrite({{:., _, [:erlang, :apply]}, _, [fun, args]}, state) do + J.call_expression( + J.member_expression( + Form.compile(fun, state), + J.identifier("apply") + ), + [Form.compile(fun, state), J.array_expression(Enum.map(args, &Form.compile(&1, state)))] + ) + end + + def rewrite({{:., _, [:erlang, :apply]}, _, [module, fun, args]}, state) do + mod = J.member_expression( + Form.compile(module, state), + Form.compile(fun, state) + ) + + J.call_expression( + J.member_expression( + mod, + J.identifier("apply") + ), + [mod, J.array_expression(Enum.map(args, &Form.compile(&1, state)))] + ) + end + + def rewrite({{:., _, [:erlang, :binary_part]}, _, [binary, start, length]}, state) do + J.call_expression( + J.member_expression( + Form.compile(binary, state), + J.identifier("substring") + ), + [Form.compile(start, state), Form.compile(length, state)] + ) + end + + def rewrite({{:., _, [:erlang, :bit_size]}, _, [bitstring]}, state) do + J.call_expression( + J.member_expression( + Form.compile(bitstring, state), + J.identifier("bit_size") + ), + [] + ) + end + + def rewrite({{:., _, [:erlang, :byte_size]}, _, [bitstring]}, state) do + J.call_expression( + J.member_expression( + Form.compile(bitstring, state), + J.identifier("byte_size") + ), + [] + ) + end + + def rewrite({{:., _, [:erlang, :div]}, _, [left, right]}, state) do + J.binary_expression( + :/, + Form.compile(left, state), + Form.compile(right, state) + ) + end + + def rewrite({{:., _, [:erlang, :exit]}, _, [reason]}, _) do + J.literal(0) + end + + def rewrite({{:., _, [:erlang, :hd]}, _, [list]}, state) do + J.member_expression( + Form.compile(list, state), + J.literal(0), + true + ) + end + + def rewrite({{:., _, [:erlang, :is_atom]}, _, [term]}, state) do + J.binary_expression( + :typeof, + Form.compile(term, state), + J.literal("symbol") + ) + end + + def rewrite({{:., _, [:erlang, :is_binary]}, _, [term]}, state) do + J.binary_expression( + :typeof, + Form.compile(term, state), + J.literal("string") + ) + end + + def rewrite({{:., _, [:erlang, :is_bitstring]}, _, [term]}, state) do + J.binary_expression( + :||, + J.binary_expression( + :typeof, + Form.compile(term, state), + J.literal("string") + ), + J.binary_expression( + :instanceof, + Form.compile(term, state), + J.member_expression( + J.member_expression( + J.identifier("Bootstrap"), + J.identifier("Core") + ), + J.identifier("BitString") + ) + ) + ) + end + + def rewrite({{:., _, [:erlang, :is_boolean]}, _, [term]}, state) do + J.binary_expression( + :||, + J.binary_expression( + :typeof, + Form.compile(term, state), + J.literal("boolean") + ), + J.binary_expression( + :instanceof, + Form.compile(term, state), + J.identifier("Boolean") + ) + ) + end + + def rewrite({{:., _, [:erlang, :is_float]}, _, [term]}, state) do + J.binary_expression( + :||, + J.binary_expression( + :typeof, + Form.compile(term, state), + J.literal("number") + ), + J.binary_expression( + :&&, + J.binary_expression( + :instanceof, + Form.compile(term, state), + J.identifier("Number") + ), + J.unary_expression( + :!, + true, + J.call_expression( + J.member_expression( + J.identifier("Number"), + J.identifier("isInteger") + ), + [Form.compile(term, state)] + ) + ) + ) + ) + end + + def rewrite({{:., _, [:erlang, :is_function]}, _, [term]}, state) do + J.binary_expression( + :||, + J.binary_expression( + :typeof, + Form.compile(term, state), + J.literal("function") + ), + J.binary_expression( + :instanceof, + Form.compile(term, state), + J.identifier("Function") + ) + ) + end + + def rewrite({{:., _, [:erlang, :is_function]}, _, [term, _]}, state) do + J.binary_expression( + :||, + J.binary_expression( + :typeof, + Form.compile(term, state), + J.literal("function") + ), + J.binary_expression( + :instanceof, + Form.compile(term, state), + J.identifier("Function") + ) + ) + end + + def rewrite({{:., _, [:erlang, :is_integer]}, _, [term]}, state) do + J.call_expression( + J.member_expression( + J.identifier("Number"), + J.identifier("isInteger") + ), + [Form.compile(term, state)] + ) + end + + def rewrite({{:., _, [:erlang, :is_list]}, _, [term]}, state) do + J.call_expression( + J.member_expression( + J.identifier("Array"), + J.identifier("isArray") + ), + [Form.compile(term, state)] + ) + end + + def rewrite({{:., _, [:erlang, :is_number]}, _, [term]}, state) do + J.binary_expression( + :||, + J.binary_expression( + :typeof, + Form.compile(term, state), + J.literal("number") + ), + J.binary_expression( + :instanceof, + Form.compile(term, state), + J.identifier("Number") + ) + ) + end + + def rewrite({{:., _, [:erlang, :is_pid]}, _, [term]}, state) do + J.binary_expression( + :instanceof, + Form.compile(term, state), + J.member_expression( + J.member_expression( + J.identifier("Bootstrap"), + J.identifier("Core") + ), + J.identifier("PID") + ) + ) + end + + def rewrite({{:., _, [:erlang, :is_port]}, _, [_term]}, state) do + J.literal(false) + end + + def rewrite({{:., _, [:erlang, :is_reference]}, _, [_term]}, state) do + J.literal(false) + end + + def rewrite({{:., _, [:erlang, :is_tuple]}, _, [term]}, state) do + J.binary_expression( + :instanceof, + Form.compile(term, state), + J.member_expression( + J.member_expression( + J.identifier("Bootstrap"), + J.identifier("Core") + ), + J.identifier("Tuple") + ) + ) + end + + def rewrite({{:., _, [:erlang, :is_map]}, _, [term]}, state) do + J.binary_expression( + :||, + J.binary_expression( + :typeof, + Form.compile(term, state), + J.literal("object") + ), + J.binary_expression( + :instanceof, + Form.compile(term, state), + J.identifier("Object") + ) + ) + end + + def rewrite({{:., _, [:erlang, :length]}, _, [list]}, state) do + J.member_expression( + Form.compile(list, state), + J.identifier("length") + ) + end + + def rewrite({{:., _, [:erlang, :make_ref]}, _, []}, state) do + J.literal(false) + end + + def rewrite({{:., _, [:erlang, :map_size]}, _, [map]}, state) do + J.member_expression( + J.call_expression( + J.member_expression( + J.identifier("Object"), + J.identifier("keys") + ), + [Form.compile(map, state)] + ), + J.identifier("length") + ) + end + + def rewrite({{:., _, [:erlang, :max]}, _, [first, second]}, state) do + J.call_expression( + J.member_expression( + J.identifier("Math"), + J.identifier("max") + ), + [Form.compile(first, state), Form.compile(second, state)] + ) + end + + def rewrite({{:., _, [:erlang, :min]}, _, [first, second]}, state) do + J.call_expression( + J.member_expression( + J.identifier("Math"), + J.identifier("min") + ), + [Form.compile(first, state), Form.compile(second, state)] + ) + end + + def rewrite({{:., _, [:erlang, :node]}, _, []}, state) do + J.identifier("nonode@nohost") + end + + def rewrite({{:., _, [:erlang, :node]}, _, [_]}, state) do + J.identifier("nonode@nohost") + end + + def rewrite({{:., _, [:erlang, :rem]}, _, [first, second]}, state) do + J.binary_expression( + :%, + Form.compile(first, state), + Form.compile(second, state) + ) + end + + def rewrite({{:., _, [:erlang, :round]}, _, [number]}, state) do + J.call_expression( + J.member_expression( + J.identifier("Math"), + J.identifier("round") + ), + [Form.compile(number, state)] + ) + end + + def rewrite({{:., _, [:erlang, :send]}, _, [dest, msg]}, state) do + raise ":erlang.send not supported" + end + + def rewrite({{:., _, [:erlang, :self]}, _, []}, state) do + raise ":erlang.self not supported" + end + + def rewrite({{:., _, [:erlang, :spawn]}, _, [_fun]}, state) do + raise ":erlang.spawn not supported" + end + + def rewrite({{:., _, [:erlang, :spawn]}, _, [_module, _fun, _args]}, state) do + raise ":erlang.spawn not supported" + end + + def rewrite({{:., _, [:erlang, :spawn_link]}, _, [_fun]}, state) do + raise ":erlang.spawn_link not supported" + end + + def rewrite({{:., _, [:erlang, :spawn_link]}, _, [_module, _fun, _args]}, state) do + raise ":erlang.spawn_link not supported" + end + + def rewrite({{:., _, [:erlang, :spawn_monitor]}, _, [_fun]}, state) do + raise ":erlang.spawn_monitor not supported" + end + + def rewrite({{:., _, [:erlang, :spawn_monitor]}, _, [_module, _fun, _args]}, state) do + raise ":erlang.spawn_monitor not supported" + end + + def rewrite({{:., _, [:erlang, :throw]}, _, [term]}, state) do + J.throw_statement( + Form.compile(term, state) + ) + end + + def rewrite({{:., _, [:erlang, :tl]}, _, [list]}, state) do + J.call_expression( + J.member_expression( + Form.compile(list, state), + J.identifier("splice") + ), + [J.literal(1)] + ) + end + + def rewrite({{:., _, [:erlang, :trunc]}, _, [number]}, state) do + J.call_expression( + J.member_expression( + J.identifier("Math"), + J.identifier("floor") + ), + [Form.compile(number, state)] + ) + end + + def rewrite({{:., _, [:erlang, :tuple_size]}, _, [tuple]}, state) do + J.member_expression( + Form.compile(tuple, state), + J.identifier("length") + ) + end + + def rewrite({{:., _, [:erlang, operator]}, _, [left, right]}, state) when operator in [:+, :-, :*, :/, :<, :>, :>=, :==] do + J.binary_expression( + operator, + Form.compile(left, state), + Form.compile(right, state) + ) + end + + def rewrite({{:., _, [:erlang, operator]}, _, [value]}, state) when operator in [:+, :-] do + J.unary_expression( + operator, + true, + Form.compile(value, state) + ) + end + + def rewrite({{:., _, [:erlang, :++]}, _, [left, right]}, state) do + J.call_expression( + J.member_expression( + Form.compile(left, state), + J.identifier("concat") + ), + [Form.compile(right, state)] + ) + end + + def rewrite({{:., _, [:erlang, :--]}, _, [list, element]}, state) do + J.call_expression( + J.member_expression( + Form.compile(list, state), + J.identifier("slice") + ), + [ + J.binary_expression( + :+, + J.call_expression( + J.member_expression( + Form.compile(list, state), + J.identifier("indexOf") + ), + [Form.compile(element, state)] + ), + J.literal(1) + ) + ] + ) + end + + def rewrite({{:., _, [:erlang, :not]}, _, [value]}, state) do + J.unary_expression( + :!, + true, + Form.compile(value, state) + ) + end + + def rewrite({{:., _, [:erlang, :"=<"]}, _, [left, right]}, state) do + J.binary_expression( + :<=, + Form.compile(left, state), + Form.compile(right, state) + ) + end + + def rewrite({{:., _, [:erlang, :"/="]}, _, [left, right]}, state) do + J.binary_expression( + :!=, + Form.compile(left, state), + Form.compile(right, state) + ) + end + + def rewrite({{:., _, [:erlang, :"=:="]}, _, [left, right]}, state) do + J.binary_expression( + :===, + Form.compile(left, state), + Form.compile(right, state) + ) + end + + def rewrite({{:., _, [:erlang, :"=/="]}, _, [left, right]}, state) do + J.binary_expression( + :!==, + Form.compile(left, state), + Form.compile(right, state) + ) + end + + def rewrite({{:., _, [:erlang, :element]}, _, [index, tuple]}, state) do + J.call_expression( + J.member_expression( + Form.compile(tuple, state), + J.identifier("get") + ), + [ + J.binary_expression( + :-, + Form.compile(index, state), + J.literal(1) + ) + ] + ) + end + + def rewrite({{:., _, [:erlang, :setelement]}, _, [index, tuple, value]}, state) do + J.call_expression( + J.member_expression( + Form.compile(tuple, state), + J.identifier("put_elem") + ), + [ + J.binary_expression( + :-, + Form.compile(index, state), + J.literal(1) + ), + Form.compile(value, state) + ] + ) + + quote do: unquote(tuple).put_elem(unquote(index) - 1, unquote(value)) + end + + def rewrite({{:., _, [:erlang, :orelse]}, _, [left, right]}, state) do + J.binary_expression( + :||, + Form.compile(left, state), + Form.compile(right, state) + ) + end + + def rewrite({{:., _, [:erlang, :or]}, _, [left, right]}, state) do + J.binary_expression( + :||, + Form.compile(left, state), + Form.compile(right, state) + ) + end + + def rewrite({{:., _, [:erlang, :andalso]}, _, [left, right]}, state) do + J.binary_expression( + :&&, + Form.compile(left, state), + Form.compile(right, state) + ) + end + + def rewrite({{:., _, [:erlang, :error]}, _, [error]}, state) do + J.throw_statement( + Form.compile(error, state) + ) + end + + def rewrite({{:., _, [:erlang, :raise]}, _, [_class, reason, _stacktrace]}, state) do + J.throw_statement( + Form.compile(reason, state) + ) + end + + def rewrite({{:., _, [:erlang, :atom_to_binary]}, _, [atom, _]}, state) do + J.call_expression( + J.member_expression( + J.identifier("Symbol"), + J.identifier("keyFor") + ), + [Form.compile(atom, state)] + ) + end + + def rewrite({{:., _, [:erlang, :atom_to_list]}, _, [atom]}, state) do + J.call_expression( + J.member_expression( + J.call_expression( + J.member_expression( + J.identifier("Symbol"), + J.identifier("keyFor") + ), + [Form.compile(atom, state)] + ), + J.identifier("split") + ), + [J.literal("")] + ) + end + + def rewrite({{:., _, [:erlang, :bnot]}, _, [expr]}, state) do + J.unary_expression( + :"~", + true, + Form.compile(expr, state) + ) + end + + def rewrite({{:., _, [:erlang, :band]}, _, [left, right]}, state) do + J.binary_expression( + :&, + Form.compile(left, state), + Form.compile(right, state) + ) + end + + def rewrite({{:., _, [:erlang, :bor]}, _, [left, right]}, state) do + J.binary_expression( + :|, + Form.compile(left, state), + Form.compile(right, state) + ) + end + + def rewrite({{:., _, [:erlang, :bxor]}, _, [left, right]}, state) do + J.binary_expression( + :^, + Form.compile(left, state), + Form.compile(right, state) + ) + end + + def rewrite({{:., _, [:erlang, :bsl]}, _, [left, right]}, state) do + J.binary_expression( + :"<<", + Form.compile(left, state), + Form.compile(right, state) + ) + end + + def rewrite({{:., _, [:erlang, :bsr]}, _, [left, right]}, state) do + J.binary_expression( + :">>", + Form.compile(left, state), + Form.compile(right, state) + ) + end + + def rewrite({{:., _, [:erlang, :function_exported]}, _, [_, _, _]}, state) do + J.literal(true) + end + + def rewrite({{:., _, [:erlang, :make_tuple]}, _, [size, data]}, state) do + J.new_expression( + J.member_expression( + J.member_expression( + J.identifier("Bootstrap"), + J.identifier("Core") + ), + J.identifier("Tuple") + ), + [] + ) + end + + def rewrite({{:., _, [:erlang, :insert_element]}, _, [index, tuple, term]}, state) do + J.call_expression( + J.member_expression( + Form.compile(tuple, state), + J.identifier("put_elem") + ), + [ + J.binary_expression( + :-, + Form.compile(index, state), + J.literal(1) + ), + Form.compile(term, state) + ] + ) + end + + def rewrite({{:., _, [:erlang, :tuple_to_list]}, _, [tuple]}, state) do + J.member_expression( + Form.compile(tuple, state), + J.identifier("values") + ) + end + + def rewrite({{:., _, [:erlang, :append_element]}, _, [tuple, value]}, state) do + J.call_expression( + J.member_expression( + Form.compile(tuple, state), + J.identifier("put_elem") + ), + [ + J.member_expression( + Form.compile(tuple, state), + J.identifier("length") + ), + Form.compile(value, state) + ] + ) + end + + def rewrite({{:., _, [:erlang, :delete_element]}, _, [index, tuple]}, state) do + J.call_expression( + J.member_expression( + Form.compile(tuple, state), + J.identifier("remove_elem") + ), + [Form.compile(index, state)] + ) + end + + def rewrite({{:., _, [:erlang, :binary_to_atom]}, _, [binary, _]}, state) do + J.call_expression( + J.member_expression( + J.identifier("Symbol"), + J.identifier("for") + ), + [Form.compile(binary, state)] + ) + end + + def rewrite({{:., _, [:erlang, :binary_to_existing_atom]}, _, [binary, _]}, state) do + J.call_expression( + J.member_expression( + J.identifier("Symbol"), + J.identifier("for") + ), + [Form.compile(binary, state)] + ) + end + + def rewrite({{:., _, [:erlang, :list_to_atom]}, _, [char_list]}, state) do + J.call_expression( + J.member_expression( + J.identifier("Symbol"), + J.identifier("for") + ), + [Form.compile(char_list, state)] + ) + end + + def rewrite({{:., _, [:erlang, :list_to_existing_atom]}, _, [char_list]}, state) do + J.call_expression( + J.member_expression( + J.identifier("Symbol"), + J.identifier("for") + ), + [Form.compile(char_list, state)] + ) + end + + def rewrite({{:., _, [:erlang, :list_to_tuple]}, _, [list]}, state) do + J.new_expression( + J.member_expression( + J.member_expression( + J.identifier("Bootstrap"), + J.identifier("Core") + ), + J.identifier("Tuple") + ), + [ + J.rest_element( + Form.compile(list, state) + ) + ] + ) + end + + def rewrite({{:., _, [:erlang, :list_to_float]}, _, [list]}, state) do + J.call_expression( + J.identifier("parseFloat"), + [Form.compile(list, state)] + ) + end + + def rewrite({{:., _, [:erlang, :list_to_integer]}, _, [list]}, state) do + J.call_expression( + J.identifier("parseInt"), + [Form.compile(list, state)] + ) + end + + def rewrite({{:., _, [:erlang, :list_to_integer]}, _, [list, base]}, state) do + J.call_expression( + J.identifier("parseInt"), + [Form.compile(list, state), Form.compile(base, state)] + ) + end + + def rewrite({{:., _, [:erlang, :integer_to_binary]}, _, [integer]}, state) do + J.call_expression( + J.member_expression( + Form.compile(integer, state), + J.identifier("toString") + ), + [] + ) + end + + def rewrite({{:., _, [:erlang, :integer_to_binary]}, _, [integer, base]}, state) do + J.call_expression( + J.member_expression( + Form.compile(integer, state), + J.identifier("toString") + ), + [Form.compile(base, state)] + ) + end + + def rewrite({{:., _, [:erlang, :integer_to_list]}, _, [integer]}, state) do + J.call_expression( + J.member_expression( + Form.compile(integer, state), + J.identifier("toString") + ), + [] + ) + end + + def rewrite({{:., _, [:erlang, :integer_to_list]}, _, [integer, base]}, state) do + J.call_expression( + J.member_expression( + Form.compile(integer, state), + J.identifier("toString") + ), + [Form.compile(base, state)] + ) + end + + def rewrite({{:., _, [:erlang, :float_to_binary]}, _, [float]}, state) do + J.call_expression( + J.member_expression( + Form.compile(float, state), + J.identifier("toString") + ), + [] + ) + end + + def rewrite({{:., _, [:erlang, :float_to_binary]}, _, [float, base]}, state) do + J.call_expression( + J.member_expression( + Form.compile(float, state), + J.identifier("toString") + ), + [Form.compile(base, state)] + ) + end + + def rewrite({{:., _, [:erlang, :float_to_list]}, _, [float]}, state) do + J.call_expression( + J.member_expression( + Form.compile(float, state), + J.identifier("toString") + ), + [] + ) + end + + def rewrite({{:., _, [:erlang, :float_to_list]}, _, [float, base]}, state) do + J.call_expression( + J.member_expression( + Form.compile(float, state), + J.identifier("toString") + ), + [Form.compile(base, state)] + ) + end + + def rewrite({{:., _, [:erlang, :binary_to_float]}, _, [binary]}, state) do + J.call_expression( + J.identifier("parseFloat"), + [Form.compile(binary, state)] + ) + end + + def rewrite({{:., _, [:erlang, :binary_to_integer]}, _, [binary]}, state) do + J.call_expression( + J.identifier("parseInt"), + [Form.compile(binary, state)] + ) + end + + def rewrite({{:., _, [:erlang, :binary_to_integer]}, _, [binary, base]}, state) do + J.call_expression( + J.identifier("parseInt"), + [Form.compile(binary, state), Form.compile(base, state)] + ) + end + +end diff --git a/lib/elixir_script/experimental/functions/lists.ex b/lib/elixir_script/experimental/functions/lists.ex new file mode 100644 index 00000000..e28a0128 --- /dev/null +++ b/lib/elixir_script/experimental/functions/lists.ex @@ -0,0 +1,114 @@ +defmodule ElixirScript.Experimental.Functions.Lists do + @moduledoc false + alias ESTree.Tools.Builder, as: J + alias ElixirScript.Experimental.Form + + def rewrite({{:., _, [:lists, :map]}, _, [fun, list]}, state) do + J.call_expression( + J.member_expression( + Form.compile(list, state), + J.identifier("map") + ), + [Form.compile(fun, state)] + ) + end + + def rewrite({{:., _, [:lists, :member]}, _, [elem, list]}, state) do + J.binary_expression( + :>, + J.call_expression( + J.member_expression( + Form.compile(list, state), + J.identifier("indexOf") + ), + [Form.compile(elem, state)] + ), + J.unary_expression( + :-, + true, + J.literal(1) + ) + ) + end + + def rewrite({{:., _, [:lists, :reverse]}, _, [list]}, state) do + J.call_expression( + J.member_expression( + J.call_expression( + J.member_expression( + Form.compile(list, state), + J.identifier("concat") + ), + [J.array_expression([])] + ), + J.identifier("reverse") + ), + [] + ) + end + + def rewrite({{:., _, [:lists, :reverse]}, _, [list, tail]}, state) do + J.call_expression( + J.member_expression( + J.call_expression( + J.member_expression( + J.call_expression( + J.member_expression( + Form.compile(list, state), + J.identifier("concat") + ), + [J.array_expression([])] + ), + J.identifier("reverse") + ), + [] + ), + J.identifier("concat") + ), + [Form.compile(tail, state)] + ) + end + + def rewrite({{:., _, [:lists, :sort]}, _, [list]}, state) do + J.call_expression( + J.member_expression( + J.call_expression( + J.member_expression( + Form.compile(list, state), + J.identifier("concat") + ), + [J.array_expression([])] + ), + J.identifier("sort") + ), + [] + ) + end + + def rewrite({{:., _, [:lists, :filter]}, _, [pred, list]}, state) do + J.call_expression( + J.member_expression( + Form.compile(list, state), + J.identifier("filter") + ), + [Form.compile(pred, state)] + ) + end + + def rewrite({{:., _, [:lists, :delete]}, _, [elem, list]}, state) do + J.call_expression( + J.member_expression( + J.member_expression( + J.member_expression( + J.identifier("Bootstrap"), + J.identifier("Core") + ), + J.identifier("Functions") + ), + J.identifier("remove_from_list") + ), + [Form.compile(list, state), Form.compile(elem, state)] + ) + end + +end diff --git a/lib/elixir_script/experimental/functions/maps.ex b/lib/elixir_script/experimental/functions/maps.ex new file mode 100644 index 00000000..8e4d1377 --- /dev/null +++ b/lib/elixir_script/experimental/functions/maps.ex @@ -0,0 +1,38 @@ +defmodule ElixirScript.Experimental.Functions.Maps do + @moduledoc false + alias ESTree.Tools.Builder, as: J + alias ElixirScript.Experimental.Form + + def rewrite({{:., _, [:maps, :update]}, _, [key, value, map]}, state) do + J.call_expression( + J.member_expression( + J.member_expression( + J.member_expression( + J.identifier("Bootstrap"), + J.identifier("Core") + ), + J.identifier("Functions") + ), + J.identifier("update_map") + ), + [Form.compile(map, state), Form.compile(key, state), Form.compile(value, state)] + ) + end + + def rewrite({{:., _, [:maps, :find]}, _, [key, map]}, state) do + J.call_expression( + J.member_expression( + J.member_expression( + J.member_expression( + J.identifier("Bootstrap"), + J.identifier("Core") + ), + J.identifier("Functions") + ), + J.identifier("update_map") + ), + [Form.compile(key, state), Form.compile(map, state)] + ) + end + +end diff --git a/lib/elixir_script/experimental/module.ex b/lib/elixir_script/experimental/module.ex new file mode 100644 index 00000000..25d384eb --- /dev/null +++ b/lib/elixir_script/experimental/module.ex @@ -0,0 +1,88 @@ +defmodule ElixirScript.Experimental.Module do + alias ESTree.Tools.Builder, as: J + alias ElixirScript.Experimental.Function + alias ElixirScript.Translator.Identifier + alias ElixirScript.State, as: ModuleState + + @moduledoc """ + Upper level module that handles compilation + """ + + def compile(module, pid) do + info = case ElixirScript.Beam.debug_info(module) do + {:ok, info} -> + info + {:error, error} -> + raise "An error occurred while compiling #{inspect module}: #{error}" + end + + %{ + attributes: _attrs, + compile_opts: _compile_opts, + definitions: defs, + file: _file, + line: _line, + module: ^module, + unreachable: unreachable + } = info + + state = %{ + pid: pid + } + + reachable_defs = Enum.filter(defs, fn + { name, _, _, _} -> not(name in unreachable) + { _, type, _, _} when type in [:defmacro, :defmacrop] -> false + _ -> true + end) + + module_info = %{module: module, defs: defs} + ModuleState.put_module(pid, module, module_info) + + compiled_functions = reachable_defs + |> Enum.map(&Function.compile(&1, state)) + + exports = make_exports(reachable_defs) + + js_ast = ElixirScript.ModuleSystems.Namespace.build( + module, + compiled_functions, + exports, + nil + ) + + ModuleState.put_module(pid, module, Map.put(module_info, :js_ast, hd(js_ast))) + end + + defp make_exports(reachable_defs) do + exports = Enum.reduce(reachable_defs, [], fn + {{name, arity}, :def, _, _}, list -> + function_name = ElixirScript.Translator.Identifier.make_function_name(name, arity) + list ++ [J.property(function_name, function_name, :init, true)] + _, list -> + list + end) + + J.object_expression(exports) + end + + def is_elixir_module(module) when is_atom(module) do + first_char = String.first(to_string(module)) + Regex.match?(~r/[A-Z]/, first_char) + end + + def is_elixir_module(_) do + false + end + + def is_js_module(module, state) do + cond do + module in ModuleState.get_javascript_modules(state.pid) -> + true + is_elixir_module(module) and hd(Module.split(module)) == "JS" -> + true + true -> + false + end + end +end diff --git a/lib/elixir_script/experimental/module_state.ex b/lib/elixir_script/experimental/module_state.ex new file mode 100644 index 00000000..dbd21825 --- /dev/null +++ b/lib/elixir_script/experimental/module_state.ex @@ -0,0 +1,21 @@ +defmodule ElixirScript.Experimental.ModuleState do + def start_link(module) do + Agent.start_link(fn -> %{ module: module, refs: [] } end) + end + + def stop(pid) do + Agent.stop(pid) + end + + def put_module_ref(pid, module) do + Agent.update(pid, fn(x) -> + %{x | refs: Enum.uniq([module | x.refs]) } + end) + end + + def get_module_refs(pid) do + Agent.get(pid, fn(x) -> + x.refs + end) + end +end \ No newline at end of file diff --git a/lib/elixir_script/next/beam.ex b/lib/elixir_script/next/beam.ex new file mode 100644 index 00000000..975ec593 --- /dev/null +++ b/lib/elixir_script/next/beam.ex @@ -0,0 +1,19 @@ +defmodule ElixirScript.Beam do + + @spec debug_info(atom) :: {:ok | :error, map | binary} + def debug_info(module) when is_atom(module) do + with {_, beam, _} <- :code.get_object_code(module), + {:ok, {^module, [debug_info: {:debug_info_v1, backend, data}]}} <- :beam_lib.chunks(beam, [:debug_info]) do + backend.debug_info(:elixir_v1, module, data, []) + else + :error -> + {:error, "Unknown module"} + {:error,:beam_lib,{:unknown_chunk,"non_existing.beam",:debug_info}} -> + {:error, "Unsupported version of Erlang"} + {:error,:beam_lib,{:file_error,"non_existing.beam",:enoent}} -> + {:error, "Debug info not available"} + end + + end + +end \ No newline at end of file diff --git a/lib/elixir_script/next/compiler.ex b/lib/elixir_script/next/compiler.ex new file mode 100644 index 00000000..44c99b45 --- /dev/null +++ b/lib/elixir_script/next/compiler.ex @@ -0,0 +1,82 @@ +defmodule ElixirScript.Compiler do + alias ESTree.Tools.{Builder, Generator} + + def compile(entry_modules, opts \\ []) do + opts = build_compiler_options(opts) + {:ok, pid} = ElixirScript.State.start_link(opts) + + modules = List.wrap(entry_modules) + Enum.each(modules, fn(module) -> + case ElixirScript.State.get_module(pid, module) do + nil -> + ElixirScript.Experimental.Module.compile(module, pid) + _ -> + nil + end + end) + + modules = ElixirScript.State.list_modules(pid) + |> Enum.map(fn {_module, info} -> info.js_ast end) + + bundle(modules, opts) + + ElixirScript.State.stop(pid) + end + + defp bundle(modules, opts) do + ElixirScript.Passes.CreateJSModules.compile(modules, opts) + + js_code = modules + |> ElixirScript.Passes.CreateJSModules.compile(opts) + |> List.wrap + |> Builder.program + |> prepare_js_ast + |> Generator.generate + + concat(js_code) + end + + defp concat(code) do + "'use strict';\n" <> ElixirScript.get_bootstrap_js("iife") <> "\n" <> code + end + + defp prepare_js_ast(js_ast) do + case js_ast do + modules when is_list(modules) -> + modules + |> Enum.reduce([], &(&2 ++ &1.body)) + |> Builder.program + %ElixirScript.Translator.Group{body: body} -> + Builder.program(body) + %ElixirScript.Translator.Empty{} -> + Builder.program([]) + _ -> + js_ast + end + end + + defp build_compiler_options(opts) do + default_options = Map.new + |> Map.put(:full_build, false) + |> Map.put(:output, nil) + |> Map.put(:app, :app) + |> Map.put(:format, :es) + |> Map.put(:js_modules, Keyword.get(opts, :js_modules, [])) + |> Map.put(:remove_unused, false) + + options = default_options + Map.put(options, :module_formatter, get_module_formatter(options[:format])) + end + + defp get_module_formatter(:umd) do + ElixirScript.ModuleSystems.UMD + end + + defp get_module_formatter(:common) do + ElixirScript.ModuleSystems.Common + end + + defp get_module_formatter(_) do + ElixirScript.ModuleSystems.ES + end +end \ No newline at end of file diff --git a/lib/elixir_script/next/state.ex b/lib/elixir_script/next/state.ex new file mode 100644 index 00000000..18418929 --- /dev/null +++ b/lib/elixir_script/next/state.ex @@ -0,0 +1,42 @@ +defmodule ElixirScript.State do + def start_link(compiler_opts) do + Agent.start_link(fn -> + %{ + compiler_opts: compiler_opts, + modules: Keyword.new, + refs: [] + } + end) + end + + def stop(pid) do + Agent.stop(pid) + end + + def get_module(pid, module) do + Agent.get(pid, fn(state) -> + Keyword.get(state.modules, module) + end) + end + + def put_module(pid, module, value) do + Agent.update(pid, fn(state) -> + %{ state | modules: Keyword.put(state.modules, module, value) } + end) + end + + def get_javascript_modules(pid) do + Agent.get(pid, fn(state) -> + Keyword.get(state.compiler_opts, :js_modules, []) + |> Enum.map(fn({module_name, _path}) -> + module_name + end) + end) + end + + def list_modules(pid) do + Agent.get(pid, fn(state) -> + state.modules + end) + end +end \ No newline at end of file diff --git a/lib/elixir_script/passes/create_js_modules.ex b/lib/elixir_script/passes/create_js_modules.ex index d9e5bb53..a0cff524 100644 --- a/lib/elixir_script/passes/create_js_modules.ex +++ b/lib/elixir_script/passes/create_js_modules.ex @@ -57,7 +57,7 @@ defmodule ElixirScript.Passes.CreateJSModules do body end - defp compile(body, opts) do + def compile(body, opts) do declarator = JS.variable_declarator( JS.identifier("Elixir"), JS.object_expression([]) diff --git a/lib/elixir_script/translator/kernel/special_forms/identifier.ex b/lib/elixir_script/translator/kernel/special_forms/identifier.ex index 3639432c..2542260c 100644 --- a/lib/elixir_script/translator/kernel/special_forms/identifier.ex +++ b/lib/elixir_script/translator/kernel/special_forms/identifier.ex @@ -80,6 +80,11 @@ defmodule ElixirScript.Translator.Identifier do end |> Enum.reverse |> make_alias - end + end + + def make_function_name(name, arity) when is_atom(name) do + name = filter_name(name) + JS.identifier("#{name}#{arity}") + end end diff --git a/test/beam_test.exs b/test/beam_test.exs new file mode 100644 index 00000000..5d52e87e --- /dev/null +++ b/test/beam_test.exs @@ -0,0 +1,8 @@ +defmodule ElixirScript.Beam.Test do + use ExUnit.Case + + test "can get ast from beam" do + assert {:ok, map} = ElixirScript.Beam.debug_info(Atom) + IO.inspect map + end +end From a3d529fb8e7fad0111ddf59099fa7b93de8e802e Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Sun, 21 May 2017 15:33:56 -0500 Subject: [PATCH 092/418] Compile protocol implementations. --- lib/elixir_script/experimental/clause.ex | 7 ++ .../experimental/examples/example.ex | 7 +- lib/elixir_script/experimental/form.ex | 12 +-- lib/elixir_script/experimental/forms/for.ex | 4 + lib/elixir_script/experimental/forms/match.ex | 11 +-- .../experimental/forms/pattern.ex | 1 - lib/elixir_script/experimental/function.ex | 13 +--- .../experimental/functions/erlang.ex | 75 ++++++++++--------- .../experimental/functions/lists.ex | 64 ++++++++++++++++ .../experimental/functions/maps.ex | 47 ++++++++++++ lib/elixir_script/experimental/module.ex | 29 ++++++- lib/elixir_script/next/beam.ex | 25 ++++++- lib/elixir_script/next/compiler.ex | 9 ++- lib/elixir_script/next/state.ex | 2 +- .../kernel/special_forms/identifier.ex | 4 + test/beam_test.exs | 1 - 16 files changed, 234 insertions(+), 77 deletions(-) diff --git a/lib/elixir_script/experimental/clause.ex b/lib/elixir_script/experimental/clause.ex index 29327f77..ea61a39c 100644 --- a/lib/elixir_script/experimental/clause.ex +++ b/lib/elixir_script/experimental/clause.ex @@ -25,6 +25,9 @@ defmodule ElixirScript.Experimental.Clause do {:__block__, _, block_body} -> Enum.map(block_body, &Form.compile(&1, state)) |> List.flatten + b when is_list(b) -> + Enum.map(b, &Form.compile(&1, state)) + |> List.flatten _ -> Form.compile(body, state) end @@ -83,6 +86,10 @@ defmodule ElixirScript.Experimental.Clause do [J.return_statement(head)] ++ tail end + defp do_return_last_statement([]) do + [J.return_statement(J.identifier("null"))] + end + defp compile_guard(params, guards, state) do guards = guards diff --git a/lib/elixir_script/experimental/examples/example.ex b/lib/elixir_script/experimental/examples/example.ex index c6914c21..2761f632 100644 --- a/lib/elixir_script/experimental/examples/example.ex +++ b/lib/elixir_script/experimental/examples/example.ex @@ -1,11 +1,6 @@ defmodule Example do - @compile {:undocumented_elixir_backend_option, ElixirScript.Experimental.Backend} - - defstruct [:name] - def new() do - JS.Map.new() - Hello.hi() + Base.encode16("foobar") end end diff --git a/lib/elixir_script/experimental/form.ex b/lib/elixir_script/experimental/form.ex index 6c9a7c06..9778d4f8 100644 --- a/lib/elixir_script/experimental/form.ex +++ b/lib/elixir_script/experimental/form.ex @@ -1,6 +1,6 @@ defmodule ElixirScript.Experimental.Form do alias ESTree.Tools.Builder, as: J - alias ElixirScript.Experimental.Forms.{Map, Bitstring, Match, Call, Try, For, Struct} + alias ElixirScript.Experimental.Forms.{Bitstring, Match, Call, Try, For, Struct} alias ElixirScript.Experimental.Functions.{Erlang, Lists, Maps} alias ElixirScript.Translator.Identifier alias ElixirScript.Experimental.Clause @@ -25,7 +25,7 @@ defmodule ElixirScript.Experimental.Form do def compile(form, state) when is_atom(form) do if ElixirScript.Experimental.Module.is_elixir_module(form) do - members = ["Elixir"] ++ Module.split(form) + members = if form == Elixir, do: ["Elixir"], else: ["Elixir"] ++ Module.split(form) J.identifier(Enum.join(members, "_")) else J.call_expression( @@ -56,7 +56,7 @@ defmodule ElixirScript.Experimental.Form do end def compile({:%{}, _, _} = map, state) do - Map.compile(map, state) + ElixirScript.Experimental.Forms.Map.compile(map, state) end def compile({:<<>>, _, _} = bitstring, state) do @@ -122,7 +122,8 @@ defmodule ElixirScript.Experimental.Form do def compile({:receive, context, _}, state) do line = Keyword.get(context, :line, 1) - raise ElixirScriptCompileError, message: "Line: #{line} receive not supported" + #raise ElixirScriptCompileError, message: "Line: #{line} receive not supported" + J.call_expression(J.identifier(:receive), []) end def compile({:try, _, [blocks]}, state) do @@ -156,8 +157,7 @@ defmodule ElixirScript.Experimental.Form do end def compile({:super, context, params}, state) do - {function_name, _} = Keyword.fetch!(context, :function) - IO.inspect {"HERE!!!!", function_name} + {function_name, _} = Map.get(state, :function) J.call_expression( ElixirScript.Translator.Identifier.make_function_name(function_name, length(params)), diff --git a/lib/elixir_script/experimental/forms/for.ex b/lib/elixir_script/experimental/forms/for.ex index b98604e6..1313aedd 100644 --- a/lib/elixir_script/experimental/forms/for.ex +++ b/lib/elixir_script/experimental/forms/for.ex @@ -48,6 +48,10 @@ defmodule ElixirScript.Experimental.Forms.For do ) end + defp handle_args(nil, module_state) do + %{generators: [], args: [], filter: nil, fun: nil, into: nil, patterns: []} + end + defp handle_args(generators, module_state) do Enum.reduce(generators, %{generators: [], args: [], filter: nil, fun: nil, into: nil, patterns: []}, fn diff --git a/lib/elixir_script/experimental/forms/match.ex b/lib/elixir_script/experimental/forms/match.ex index 9d0275c7..3e40b2f4 100644 --- a/lib/elixir_script/experimental/forms/match.ex +++ b/lib/elixir_script/experimental/forms/match.ex @@ -45,13 +45,7 @@ defmodule ElixirScript.Experimental.Forms.Match do defp make_list_ref(array_pattern, params, state) do {ref, params} = make_params(params) - ref_declarator = J.variable_declarator( - ref, - J.array_expression( - Enum.map(params, &Form.compile(&1, state)) - ) - ) - + ref_declarator = J.variable_declarator(ref, J.array_expression(params)) make_variable_declaration_and_group(ref_declarator, array_pattern) end @@ -89,7 +83,8 @@ defmodule ElixirScript.Experimental.Forms.Match do defp make_variable_declaration_and_group(ref_declarator, array_pattern) do ref_declaration = J.variable_declaration([ref_declarator], :let) - [array_pattern, ref_declaration] + #[array_pattern, ref_declaration] + array_pattern end end \ No newline at end of file diff --git a/lib/elixir_script/experimental/forms/pattern.ex b/lib/elixir_script/experimental/forms/pattern.ex index c745b020..1b6edf22 100644 --- a/lib/elixir_script/experimental/forms/pattern.ex +++ b/lib/elixir_script/experimental/forms/pattern.ex @@ -138,5 +138,4 @@ defmodule ElixirScript.Experimental.Forms.Pattern do { patterns, params } = compile([source], state) { [PM.capture(hd(patterns))], params ++ [ElixirScript.Translator.Identifier.make_identifier(target)] } end - end diff --git a/lib/elixir_script/experimental/function.ex b/lib/elixir_script/experimental/function.ex index 1ac7a330..b16f18f6 100644 --- a/lib/elixir_script/experimental/function.ex +++ b/lib/elixir_script/experimental/function.ex @@ -19,18 +19,7 @@ defmodule ElixirScript.Experimental.Function do end def compile({{name, arity}, type, _, clauses}, state) do - clauses = Enum.map(clauses, fn(clause) -> - - # Walk the AST and add the function to the context. - # This information is used when translating "super" - Macro.prewalk(clause, fn - {subject, context, params} -> - {subject, Keyword.put(context, :function, {name, arity}), params } - ast -> - ast - end) - end) - + state = Map.put(state, :function, {name, arity}) declarator = J.variable_declarator( ElixirScript.Translator.Identifier.make_function_name(name, arity), diff --git a/lib/elixir_script/experimental/functions/erlang.ex b/lib/elixir_script/experimental/functions/erlang.ex index cbe63f26..0d813a40 100644 --- a/lib/elixir_script/experimental/functions/erlang.ex +++ b/lib/elixir_script/experimental/functions/erlang.ex @@ -19,7 +19,7 @@ defmodule ElixirScript.Experimental.Functions.Erlang do Form.compile(fun, state), J.identifier("apply") ), - [Form.compile(fun, state), J.array_expression(Enum.map(args, &Form.compile(&1, state)))] + [Form.compile(fun, state), J.array_expression(Enum.map(List.wrap(args), &Form.compile(&1, state)))] ) end @@ -34,7 +34,7 @@ defmodule ElixirScript.Experimental.Functions.Erlang do mod, J.identifier("apply") ), - [mod, J.array_expression(Enum.map(args, &Form.compile(&1, state)))] + [mod, J.array_expression(Enum.map(List.wrap(args), &Form.compile(&1, state)))] ) end @@ -362,37 +362,37 @@ defmodule ElixirScript.Experimental.Functions.Erlang do ) end - def rewrite({{:., _, [:erlang, :send]}, _, [dest, msg]}, state) do - raise ":erlang.send not supported" - end - - def rewrite({{:., _, [:erlang, :self]}, _, []}, state) do - raise ":erlang.self not supported" - end - - def rewrite({{:., _, [:erlang, :spawn]}, _, [_fun]}, state) do - raise ":erlang.spawn not supported" - end - - def rewrite({{:., _, [:erlang, :spawn]}, _, [_module, _fun, _args]}, state) do - raise ":erlang.spawn not supported" - end - - def rewrite({{:., _, [:erlang, :spawn_link]}, _, [_fun]}, state) do - raise ":erlang.spawn_link not supported" - end - - def rewrite({{:., _, [:erlang, :spawn_link]}, _, [_module, _fun, _args]}, state) do - raise ":erlang.spawn_link not supported" - end - - def rewrite({{:., _, [:erlang, :spawn_monitor]}, _, [_fun]}, state) do - raise ":erlang.spawn_monitor not supported" - end - - def rewrite({{:., _, [:erlang, :spawn_monitor]}, _, [_module, _fun, _args]}, state) do - raise ":erlang.spawn_monitor not supported" - end +# def rewrite({{:., _, [:erlang, :send]}, _, [dest, msg]}, state) do +# raise ":erlang.send not supported" +# end +# +# def rewrite({{:., _, [:erlang, :self]}, _, []}, state) do +# raise ":erlang.self not supported" +# end +# +# def rewrite({{:., _, [:erlang, :spawn]}, _, [_fun]}, state) do +# raise ":erlang.spawn not supported" +# end +# +# def rewrite({{:., _, [:erlang, :spawn]}, _, [_module, _fun, _args]}, state) do +# raise ":erlang.spawn not supported" +# end +# +# def rewrite({{:., _, [:erlang, :spawn_link]}, _, [_fun]}, state) do +# raise ":erlang.spawn_link not supported" +# end +# +# def rewrite({{:., _, [:erlang, :spawn_link]}, _, [_module, _fun, _args]}, state) do +# raise ":erlang.spawn_link not supported" +# end +# +# def rewrite({{:., _, [:erlang, :spawn_monitor]}, _, [_fun]}, state) do +# raise ":erlang.spawn_monitor not supported" +# end +# +# def rewrite({{:., _, [:erlang, :spawn_monitor]}, _, [_module, _fun, _args]}, state) do +# raise ":erlang.spawn_monitor not supported" +# end def rewrite({{:., _, [:erlang, :throw]}, _, [term]}, state) do J.throw_statement( @@ -546,8 +546,6 @@ defmodule ElixirScript.Experimental.Functions.Erlang do Form.compile(value, state) ] ) - - quote do: unquote(tuple).put_elem(unquote(index) - 1, unquote(value)) end def rewrite({{:., _, [:erlang, :orelse]}, _, [left, right]}, state) do @@ -906,4 +904,11 @@ defmodule ElixirScript.Experimental.Functions.Erlang do ) end + def rewrite({{:., _, [:erlang, _]}, _, _}, state) do + J.call_expression( + J.identifier("toString"), + [] + ) + end + end diff --git a/lib/elixir_script/experimental/functions/lists.ex b/lib/elixir_script/experimental/functions/lists.ex index e28a0128..1c1c2a39 100644 --- a/lib/elixir_script/experimental/functions/lists.ex +++ b/lib/elixir_script/experimental/functions/lists.ex @@ -111,4 +111,68 @@ defmodule ElixirScript.Experimental.Functions.Lists do ) end + def rewrite({{:., _, [:lists, _]}, _, [elem, list]}, state) do + J.call_expression( + J.member_expression( + J.member_expression( + J.member_expression( + J.identifier("Bootstrap"), + J.identifier("Core") + ), + J.identifier("Functions") + ), + J.identifier("remove_from_list") + ), + [Form.compile(list, state), Form.compile(elem, state)] + ) + end + + def rewrite({{:., _, [:lists, _]}, _, [elem, list, _, _]}, state) do + J.call_expression( + J.member_expression( + J.member_expression( + J.member_expression( + J.identifier("Bootstrap"), + J.identifier("Core") + ), + J.identifier("Functions") + ), + J.identifier("remove_from_list") + ), + [Form.compile(list, state), Form.compile(elem, state)] + ) + end + + def rewrite({{:., _, [:lists, _]}, _, [elem, list, _]}, state) do + J.call_expression( + J.member_expression( + J.member_expression( + J.member_expression( + J.identifier("Bootstrap"), + J.identifier("Core") + ), + J.identifier("Functions") + ), + J.identifier("remove_from_list") + ), + [Form.compile(list, state), Form.compile(elem, state)] + ) + end + + def rewrite({{:., _, [:lists, _]}, _, [list]}, state) do + J.call_expression( + J.member_expression( + J.call_expression( + J.member_expression( + Form.compile(list, state), + J.identifier("concat") + ), + [J.array_expression([])] + ), + J.identifier("reverse") + ), + [] + ) + end + end diff --git a/lib/elixir_script/experimental/functions/maps.ex b/lib/elixir_script/experimental/functions/maps.ex index 8e4d1377..4e528d8a 100644 --- a/lib/elixir_script/experimental/functions/maps.ex +++ b/lib/elixir_script/experimental/functions/maps.ex @@ -35,4 +35,51 @@ defmodule ElixirScript.Experimental.Functions.Maps do ) end + def rewrite({{:., _, [:maps, :put]}, _, [key, map, _]}, state) do + J.call_expression( + J.member_expression( + J.member_expression( + J.member_expression( + J.identifier("Bootstrap"), + J.identifier("Core") + ), + J.identifier("Functions") + ), + J.identifier("update_map") + ), + [Form.compile(key, state), Form.compile(map, state)] + ) + end + + def rewrite({{:., _, [:maps, :is_key]}, _, [key, map]}, state) do + J.call_expression( + J.member_expression( + J.member_expression( + J.member_expression( + J.identifier("Bootstrap"), + J.identifier("Core") + ), + J.identifier("Functions") + ), + J.identifier("update_map") + ), + [Form.compile(key, state), Form.compile(map, state)] + ) + end + + def rewrite({{:., _, [:maps, _]}, _, _}, state) do + J.call_expression( + J.member_expression( + J.member_expression( + J.member_expression( + J.identifier("Bootstrap"), + J.identifier("Core") + ), + J.identifier("Functions") + ), + J.identifier("update_map") + ), + [] + ) + end end diff --git a/lib/elixir_script/experimental/module.ex b/lib/elixir_script/experimental/module.ex index 25d384eb..8aba34b3 100644 --- a/lib/elixir_script/experimental/module.ex +++ b/lib/elixir_script/experimental/module.ex @@ -9,13 +9,18 @@ defmodule ElixirScript.Experimental.Module do """ def compile(module, pid) do + IO.inspect "Compiling #{inspect module}" info = case ElixirScript.Beam.debug_info(module) do {:ok, info} -> - info + compile_module(module, info, pid) + {:ok, module, implementations} -> + compile_protocol(module, implementations, pid) {:error, error} -> raise "An error occurred while compiling #{inspect module}: #{error}" end + end + defp compile_module(module, info, pid) do %{ attributes: _attrs, compile_opts: _compile_opts, @@ -51,7 +56,13 @@ defmodule ElixirScript.Experimental.Module do nil ) - ModuleState.put_module(pid, module, Map.put(module_info, :js_ast, hd(js_ast))) + ModuleState.put_module(pid, module, Map.put(module_info, :js_ast, hd(js_ast))) + end + + defp compile_protocol(module, implementations, pid) do + ModuleState.put_module(pid, module, %{}) + + Enum.each(implementations, fn({impl, info}) -> compile_module(impl, info, pid) end) end defp make_exports(reachable_defs) do @@ -66,9 +77,19 @@ defmodule ElixirScript.Experimental.Module do J.object_expression(exports) end + def is_elixir_module(Elixir) do + true + end + def is_elixir_module(module) when is_atom(module) do - first_char = String.first(to_string(module)) - Regex.match?(~r/[A-Z]/, first_char) + str_module = Atom.to_string(module) + + case str_module do + "Elixir." <> _ -> + true + _ -> + false + end end def is_elixir_module(_) do diff --git a/lib/elixir_script/next/beam.ex b/lib/elixir_script/next/beam.ex index 975ec593..8272eeeb 100644 --- a/lib/elixir_script/next/beam.ex +++ b/lib/elixir_script/next/beam.ex @@ -3,8 +3,14 @@ defmodule ElixirScript.Beam do @spec debug_info(atom) :: {:ok | :error, map | binary} def debug_info(module) when is_atom(module) do with {_, beam, _} <- :code.get_object_code(module), - {:ok, {^module, [debug_info: {:debug_info_v1, backend, data}]}} <- :beam_lib.chunks(beam, [:debug_info]) do - backend.debug_info(:elixir_v1, module, data, []) + {:ok, {^module, [debug_info: {:debug_info_v1, backend, data}]}} <- :beam_lib.chunks(beam, [:debug_info]), + {:ok, {^module, attribute_info}} = :beam_lib.chunks(beam, [:attributes]) do + + if Keyword.get(attribute_info[:attributes], :protocol) do + get_protocol_implementations(module) + else + backend.debug_info(:elixir_v1, module, data, []) + end else :error -> {:error, "Unknown module"} @@ -13,7 +19,22 @@ defmodule ElixirScript.Beam do {:error,:beam_lib,{:file_error,"non_existing.beam",:enoent}} -> {:error, "Debug info not available"} end + end + + defp get_protocol_implementations(module) do + implementations = module + |> Protocol.extract_impls(:code.get_path()) + |> Enum.map(fn(x) -> Module.concat([module, x]) end) + |> Enum.map(fn(x) -> + case debug_info(x) do + {:ok, info} -> + {x, info} + _ -> + raise "Unable to compile protocol implementation #{inspect x}" + end + end) + {:ok, module, implementations} end end \ No newline at end of file diff --git a/lib/elixir_script/next/compiler.ex b/lib/elixir_script/next/compiler.ex index 44c99b45..586988bb 100644 --- a/lib/elixir_script/next/compiler.ex +++ b/lib/elixir_script/next/compiler.ex @@ -16,7 +16,14 @@ defmodule ElixirScript.Compiler do end) modules = ElixirScript.State.list_modules(pid) - |> Enum.map(fn {_module, info} -> info.js_ast end) + |> Enum.filter_map( + fn {_, info} -> Map.has_key?(info, :js_ast) end, + fn {_module, info} -> + info.js_ast + end + ) + + Enum.map() bundle(modules, opts) diff --git a/lib/elixir_script/next/state.ex b/lib/elixir_script/next/state.ex index 18418929..bd0f4735 100644 --- a/lib/elixir_script/next/state.ex +++ b/lib/elixir_script/next/state.ex @@ -27,7 +27,7 @@ defmodule ElixirScript.State do def get_javascript_modules(pid) do Agent.get(pid, fn(state) -> - Keyword.get(state.compiler_opts, :js_modules, []) + Map.get(state.compiler_opts, :js_modules, []) |> Enum.map(fn({module_name, _path}) -> module_name end) diff --git a/lib/elixir_script/translator/kernel/special_forms/identifier.ex b/lib/elixir_script/translator/kernel/special_forms/identifier.ex index 2542260c..d44bb6b7 100644 --- a/lib/elixir_script/translator/kernel/special_forms/identifier.ex +++ b/lib/elixir_script/translator/kernel/special_forms/identifier.ex @@ -51,6 +51,10 @@ defmodule ElixirScript.Translator.Identifier do |> JS.identifier end + defp filter_name(name) when is_tuple(name) do + name + end + defp filter_name(reserved_word) when reserved_word in @js_reserved_words do "__#{Atom.to_string(reserved_word)}__" end diff --git a/test/beam_test.exs b/test/beam_test.exs index 5d52e87e..bfcbb798 100644 --- a/test/beam_test.exs +++ b/test/beam_test.exs @@ -3,6 +3,5 @@ defmodule ElixirScript.Beam.Test do test "can get ast from beam" do assert {:ok, map} = ElixirScript.Beam.debug_info(Atom) - IO.inspect map end end From 82ca2c640aa26198ed906a72726455e65436c7fa Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Mon, 22 May 2017 22:13:32 -0500 Subject: [PATCH 093/418] Add pass to find used modules and functions --- lib/elixir_script/experimental/forms/for.ex | 10 +- lib/elixir_script/next/compiler.ex | 11 +- lib/elixir_script/next/find_used.ex | 248 ++++++++++++++++++++ 3 files changed, 259 insertions(+), 10 deletions(-) create mode 100644 lib/elixir_script/next/find_used.ex diff --git a/lib/elixir_script/experimental/forms/for.ex b/lib/elixir_script/experimental/forms/for.ex index 1313aedd..bf623836 100644 --- a/lib/elixir_script/experimental/forms/for.ex +++ b/lib/elixir_script/experimental/forms/for.ex @@ -57,11 +57,11 @@ defmodule ElixirScript.Experimental.Forms.For do ({:<<>>, _, body}, state) -> {bs_parts, collection} = Enum.map_reduce(body, nil, fn - {:::, _, _} = ast, state -> - {ast, state} - {:<-, _, [var, collection]}, _ -> - {var, collection} - end) + {:::, _, _} = ast, state -> + {ast, state} + {:<-, _, [var, collection]}, _ -> + {var, collection} + end) {patterns, params} = Pattern.compile([{:<<>>, [], bs_parts}], module_state) diff --git a/lib/elixir_script/next/compiler.ex b/lib/elixir_script/next/compiler.ex index 586988bb..4895604b 100644 --- a/lib/elixir_script/next/compiler.ex +++ b/lib/elixir_script/next/compiler.ex @@ -5,8 +5,10 @@ defmodule ElixirScript.Compiler do opts = build_compiler_options(opts) {:ok, pid} = ElixirScript.State.start_link(opts) - modules = List.wrap(entry_modules) - Enum.each(modules, fn(module) -> + entry_modules + |> List.wrap + |> ElixirScript.FindUsed.find_used(pid) + |> Enum.each(fn(module) -> case ElixirScript.State.get_module(pid, module) do nil -> ElixirScript.Experimental.Module.compile(module, pid) @@ -15,7 +17,8 @@ defmodule ElixirScript.Compiler do end end) - modules = ElixirScript.State.list_modules(pid) + modules = pid + |> ElixirScript.State.list_modules |> Enum.filter_map( fn {_, info} -> Map.has_key?(info, :js_ast) end, fn {_module, info} -> @@ -23,8 +26,6 @@ defmodule ElixirScript.Compiler do end ) - Enum.map() - bundle(modules, opts) ElixirScript.State.stop(pid) diff --git a/lib/elixir_script/next/find_used.ex b/lib/elixir_script/next/find_used.ex new file mode 100644 index 00000000..a534f5aa --- /dev/null +++ b/lib/elixir_script/next/find_used.ex @@ -0,0 +1,248 @@ +defmodule ElixirScript.FindUsed do + alias ElixirScript.State, as: ModuleState + + def find_used(modules, pid) do + Enum.each(List.wrap(modules), fn(module) -> + if ElixirScript.State.get_module(pid, module) == nil do + execute(module, pid) + end + end) + end + + defp execute(module, pid) do + case ElixirScript.Beam.debug_info(module) do + {:ok, info} -> + walk_module(module, info, pid) + {:ok, module, implementations} -> + walk_protocol(module, implementations, pid) + {:error, error} -> + raise "An error occurred while compiling #{inspect module}: #{error}" + end + end + + defp walk_module(module, info, pid) do + %{ + attributes: _attrs, + walk_opts: _walk_opts, + definitions: defs, + file: _file, + line: _line, + module: ^module, + unreachable: unreachable + } = info + + module_info = %{module: module, info: info} + ModuleState.put_module(pid, module, module_info) + + reachable_defs = Enum.filter(defs, fn + { _, type, _, _} when type in [:defmacro, :defmacrop] -> false + { name, _, _, _} -> not(name in unreachable) + _ -> true + end) + + state = %{ + pid: pid + } + + Enum.each(reachable_defs, &walk(&1, state)) + + end + + defp walk_protocol(module, implementations, pid) do + ModuleState.put_module(pid, module, %{}) + Enum.each(implementations, fn({impl, info}) -> walk_module(impl, info, pid) end) + end + + defp walk({{_name, _arity}, _type, _, clauses}, state) do + Enum.each(clauses, &walk(&1, state)) + end + + defp walk({ _, _args, _guards, body}, state) do + case body do + nil -> + nil + {:__block__, _, block_body} -> + Enum.map(block_body, &walk(&1, state)) + b when is_list(b) -> + Enum.map(b, &walk(&1, state)) + _ -> + walk(body, state) + end + end + + defp walk({:->, _, [[{:when, _, params}], body ]}, state) do + guards = List.last(params) + params = params |> Enum.reverse |> tl |> Enum.reverse + + walk({[], params, guards, body}, state) + end + + defp walk({:->, _, [params, body]}, state) do + walk({[], params, [], body}, state) + end + + defp walk(nil, _) do + nil + end + + defp walk(form, _) when is_boolean(form) when is_integer(form) when is_float(form) when is_binary(form) do + nil + end + + defp walk(form, state) when is_list(form) do + Enum.each(form, &walk(&1, state)) + end + + defp walk(form, state) when is_atom(form) do + if ElixirScript.Experimental.Module.is_elixir_module(form) do + if ModuleState.get_module(state.pid, form) == nil do + execute(form, state.pid) + end + end + end + + defp walk({a, b}, state) do + walk({:{}, [], [a, b]}, state) + end + + defp walk({:{}, _, elements}, state) do + Enum.each(elements, &walk(&1, state)) + end + + defp walk({:%{}, _, properties}, state) do + Enum.each(properties, fn (val) -> walk(val, state) end) + end + + defp walk({:<<>>, _, elements}, state) do + Enum.each(elements, fn (val) -> walk(val, state) end) + end + + defp walk({:=, _, [left, right]}, state) do + walk(left, state) + walk(right, state) + end + + defp walk({:%, _, [module, params]}, state) do + if ElixirScript.Experimental.Module.is_elixir_module(module) do + if ModuleState.get_module(state.pid, module) == nil do + execute(module, state.pid) + end + end + Enum.each(params, &walk(&1, state)) + end + + defp walk({:for, _, generators}, state) do + Enum.each(generators, fn + {:<<>>, _, body} -> + walk(body, state) + + {:<-, _, [identifier, enum]} -> + walk(identifier, state) + walk(enum, state) + + [into: expression] -> + walk(expression, state) + + [into: expression, do: expression2] -> + walk(expression, state) + walk(expression2, state) + + [do: expression] -> + walk(expression, state) + + filter -> + walk(filter, state) + end) + end + + defp walk({:case, _, [condition, [do: clauses]]}, state) do + Enum.each(clauses, &walk(&1, state)) + walk(condition, state) + end + + defp walk({:cond, _, [[do: clauses]]}, state) do + Enum.each(clauses, fn({:->, _, [clause, clause_body]}) -> + Enum.each(List.wrap(clause_body), &walk(&1, state)) + walk(hd(clause), state) + end) + end + + defp walk({:receive, _context, _}, _state) do + nil + end + + defp walk({:try, _, [blocks]}, state) do + try_block = Keyword.get(blocks, :do) + rescue_block = Keyword.get(blocks, :rescue, nil) + catch_block = Keyword.get(blocks, :catch, nil) + after_block = Keyword.get(blocks, :after, nil) + else_block = Keyword.get(blocks, :else, nil) + + Enum.each(List.wrap(try_block), &walk(&1, state)) + + if rescue_block do + Enum.each(rescue_block, fn + {:->, _, [ [{:in, _, [param, names]}], body]} -> + walk({[], [param], [{{:., [], [Enum, :member?]}, [], [param, names]}], body}, state) + {:->, _, [ [param], body]} -> + walk({[], [param], [], body}, state) + end) + end + + if catch_block do + walk({:fn, [], catch_block}, state) + end + + if after_block do + Enum.each(List.wrap(after_block), &walk(&1, state)) + end + + if else_block do + walk({:fn, [], else_block}, state) + end + end + + defp walk({:fn, _, clauses}, state) do + Enum.each(clauses, &walk(&1, state)) + end + + defp walk({{:., _, [:erlang, _]}, _, _}, _state) do + nil + end + + defp walk({{:., _, [:lists, _]}, _, _}, _state) do + nil + end + + defp walk({{:., _, [:maps, _]}, _, _}, _state) do + nil + end + + defp walk({{:., _, [module, _]}, _, params}, state) do + cond do + ElixirScript.Experimental.Module.is_js_module(module, state) -> + nil + ElixirScript.Experimental.Module.is_elixir_module(module) -> + if ModuleState.get_module(state.pid, module) == nil do + execute(module, state.pid) + end + true -> + nil + end + + Enum.each(params, &walk(&1, state)) + end + + defp walk({:super, _, params}, state) do + Enum.each(params, &walk(&1, state)) + end + + defp walk({_, _, params}, state) when is_list(params) do + Enum.each(params, &walk(&1, state)) + end + + defp walk({_, _, _}, _state) do + nil + end + +end \ No newline at end of file From db214817c0cf17b5b5f987a177986e9bb801ccda Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Mon, 22 May 2017 23:06:01 -0500 Subject: [PATCH 094/418] Fix used crawling --- lib/elixir_script/experimental/backend.ex | 33 --------------- .../experimental/examples/example.ex | 6 ++- lib/elixir_script/experimental/forms/call.ex | 6 --- lib/elixir_script/experimental/module.ex | 33 +++------------ lib/elixir_script/next/compiler.ex | 21 +++++----- lib/elixir_script/next/find_used.ex | 41 +++++++++---------- lib/elixir_script/next/state.ex | 15 +++++++ .../kernel/special_forms/identifier.ex | 4 ++ 8 files changed, 61 insertions(+), 98 deletions(-) delete mode 100644 lib/elixir_script/experimental/backend.ex diff --git a/lib/elixir_script/experimental/backend.ex b/lib/elixir_script/experimental/backend.ex deleted file mode 100644 index a5d3d4e0..00000000 --- a/lib/elixir_script/experimental/backend.ex +++ /dev/null @@ -1,33 +0,0 @@ -defmodule ElixirScript.Experimental.Backend do - alias ElixirScript.Experimental.Module - alias ESTree.Tools.Generator - alias ElixirScript.Experimental.ModuleState - - def compile(line, file, module, attrs, defs, unreachable, opts) do - # Print all arguments - #IO.inspect binding() - - # Compile module to JavaScript AST - js_ast = Module.compile(line, file, module, attrs, defs, unreachable, opts) - - # Generate JavaScript code string - js_code = Generator.generate(js_ast) - - #IO.puts js_code - - write_js(module, js_code) - # Invoke the default backend - it returns the compiled beam binary - :elixir_erl.compile(line, file, module, attrs, defs, unreachable, opts) - end - - defp write_js(module, js_code) do - output_dir = Path.join([Mix.Project.build_path(), "_javascript"]) - - if !File.exists?(output_dir) do - File.mkdir_p!(output_dir) - end - - output_path = Path.join([output_dir, "#{module}.js"]) - File.write!(output_path, js_code) - end -end diff --git a/lib/elixir_script/experimental/examples/example.ex b/lib/elixir_script/experimental/examples/example.ex index 2761f632..677bf0f8 100644 --- a/lib/elixir_script/experimental/examples/example.ex +++ b/lib/elixir_script/experimental/examples/example.ex @@ -1,6 +1,10 @@ defmodule Example do def new() do - Base.encode16("foobar") + newnew() + end + + def newnew() do + Atom.to_string("hello") end end diff --git a/lib/elixir_script/experimental/forms/call.ex b/lib/elixir_script/experimental/forms/call.ex index efd578c3..062abc05 100644 --- a/lib/elixir_script/experimental/forms/call.ex +++ b/lib/elixir_script/experimental/forms/call.ex @@ -2,17 +2,11 @@ defmodule ElixirScript.Experimental.Forms.Call do alias ESTree.Tools.Builder, as: J alias ElixirScript.Experimental.Form alias ElixirScript.Translator.Identifier - alias ElixirScript.State, as: ModuleState def compile({{:., _, [module, function]}, _, params}, state) do function_name = cond do ElixirScript.Experimental.Module.is_js_module(module, state) -> ElixirScript.Translator.Identifier.make_extern_function_name(function) - ElixirScript.Experimental.Module.is_elixir_module(module) -> - if ModuleState.get_module(state.pid, module) == nil do - ElixirScript.Experimental.Module.compile(module, state.pid) - end - ElixirScript.Translator.Identifier.make_function_name(function, length(params)) true -> ElixirScript.Translator.Identifier.make_function_name(function, length(params)) end diff --git a/lib/elixir_script/experimental/module.ex b/lib/elixir_script/experimental/module.ex index 8aba34b3..3d30a09d 100644 --- a/lib/elixir_script/experimental/module.ex +++ b/lib/elixir_script/experimental/module.ex @@ -8,19 +8,7 @@ defmodule ElixirScript.Experimental.Module do Upper level module that handles compilation """ - def compile(module, pid) do - IO.inspect "Compiling #{inspect module}" - info = case ElixirScript.Beam.debug_info(module) do - {:ok, info} -> - compile_module(module, info, pid) - {:ok, module, implementations} -> - compile_protocol(module, implementations, pid) - {:error, error} -> - raise "An error occurred while compiling #{inspect module}: #{error}" - end - end - - defp compile_module(module, info, pid) do + def compile(module, info, pid) do %{ attributes: _attrs, compile_opts: _compile_opts, @@ -28,7 +16,8 @@ defmodule ElixirScript.Experimental.Module do file: _file, line: _line, module: ^module, - unreachable: unreachable + unreachable: _unreachable, + used: used } = info state = %{ @@ -36,14 +25,10 @@ defmodule ElixirScript.Experimental.Module do } reachable_defs = Enum.filter(defs, fn - { name, _, _, _} -> not(name in unreachable) - { _, type, _, _} when type in [:defmacro, :defmacrop] -> false - _ -> true + { name, _, _, _} -> name in used + _ -> false end) - module_info = %{module: module, defs: defs} - ModuleState.put_module(pid, module, module_info) - compiled_functions = reachable_defs |> Enum.map(&Function.compile(&1, state)) @@ -56,13 +41,7 @@ defmodule ElixirScript.Experimental.Module do nil ) - ModuleState.put_module(pid, module, Map.put(module_info, :js_ast, hd(js_ast))) - end - - defp compile_protocol(module, implementations, pid) do - ModuleState.put_module(pid, module, %{}) - - Enum.each(implementations, fn({impl, info}) -> compile_module(impl, info, pid) end) + ModuleState.put_module(pid, module, Map.put(info, :js_ast, hd(js_ast))) end defp make_exports(reachable_defs) do diff --git a/lib/elixir_script/next/compiler.ex b/lib/elixir_script/next/compiler.ex index 4895604b..f826bfc6 100644 --- a/lib/elixir_script/next/compiler.ex +++ b/lib/elixir_script/next/compiler.ex @@ -5,21 +5,21 @@ defmodule ElixirScript.Compiler do opts = build_compiler_options(opts) {:ok, pid} = ElixirScript.State.start_link(opts) + IO.puts "Finding used modules and functions" entry_modules |> List.wrap |> ElixirScript.FindUsed.find_used(pid) - |> Enum.each(fn(module) -> - case ElixirScript.State.get_module(pid, module) do - nil -> - ElixirScript.Experimental.Module.compile(module, pid) - _ -> - nil - end + + modules = ElixirScript.State.list_modules(pid) + + IO.puts "Compiling" + Enum.each(modules, fn({module, info}) -> + ElixirScript.Experimental.Module.compile(module, info, pid) end) - modules = pid - |> ElixirScript.State.list_modules - |> Enum.filter_map( + modules = ElixirScript.State.list_modules(pid) + + modules = Enum.filter_map(modules, fn {_, info} -> Map.has_key?(info, :js_ast) end, fn {_module, info} -> info.js_ast @@ -42,6 +42,7 @@ defmodule ElixirScript.Compiler do |> Generator.generate concat(js_code) + |> IO.puts end defp concat(code) do diff --git a/lib/elixir_script/next/find_used.ex b/lib/elixir_script/next/find_used.ex index a534f5aa..4a44c71f 100644 --- a/lib/elixir_script/next/find_used.ex +++ b/lib/elixir_script/next/find_used.ex @@ -10,6 +10,7 @@ defmodule ElixirScript.FindUsed do end defp execute(module, pid) do + IO.inspect module case ElixirScript.Beam.debug_info(module) do {:ok, info} -> walk_module(module, info, pid) @@ -23,7 +24,7 @@ defmodule ElixirScript.FindUsed do defp walk_module(module, info, pid) do %{ attributes: _attrs, - walk_opts: _walk_opts, + compile_opts: _compile_opts, definitions: defs, file: _file, line: _line, @@ -31,8 +32,7 @@ defmodule ElixirScript.FindUsed do unreachable: unreachable } = info - module_info = %{module: module, info: info} - ModuleState.put_module(pid, module, module_info) + ModuleState.put_module(pid, module, info) reachable_defs = Enum.filter(defs, fn { _, type, _, _} when type in [:defmacro, :defmacrop] -> false @@ -41,7 +41,8 @@ defmodule ElixirScript.FindUsed do end) state = %{ - pid: pid + pid: pid, + module: module } Enum.each(reachable_defs, &walk(&1, state)) @@ -81,25 +82,17 @@ defmodule ElixirScript.FindUsed do walk({[], params, [], body}, state) end - defp walk(nil, _) do - nil - end - - defp walk(form, _) when is_boolean(form) when is_integer(form) when is_float(form) when is_binary(form) do - nil - end - defp walk(form, state) when is_list(form) do Enum.each(form, &walk(&1, state)) end - defp walk(form, state) when is_atom(form) do - if ElixirScript.Experimental.Module.is_elixir_module(form) do - if ModuleState.get_module(state.pid, form) == nil do - execute(form, state.pid) - end - end - end + #defp walk(form, state) when is_atom(form) do + #if ElixirScript.Experimental.Module.is_elixir_module(form) do + # if ModuleState.get_module(state.pid, form) == nil do + # execute(form, state.pid) + # end + #end + #end defp walk({a, b}, state) do walk({:{}, [], [a, b]}, state) @@ -218,7 +211,7 @@ defmodule ElixirScript.FindUsed do nil end - defp walk({{:., _, [module, _]}, _, params}, state) do + defp walk({{:., _, [module, function]}, _, params}, state) do cond do ElixirScript.Experimental.Module.is_js_module(module, state) -> nil @@ -226,6 +219,7 @@ defmodule ElixirScript.FindUsed do if ModuleState.get_module(state.pid, module) == nil do execute(module, state.pid) end + ModuleState.add_used(state.pid, module, {function, length(params)}) true -> nil end @@ -237,11 +231,16 @@ defmodule ElixirScript.FindUsed do Enum.each(params, &walk(&1, state)) end + defp walk({function, _, params}, state) when is_atom(function) and is_list(params) do + ModuleState.add_used(state.pid, state.module, {function, length(params)}) + Enum.each(params, &walk(&1, state)) + end + defp walk({_, _, params}, state) when is_list(params) do Enum.each(params, &walk(&1, state)) end - defp walk({_, _, _}, _state) do + defp walk(_, _) do nil end diff --git a/lib/elixir_script/next/state.ex b/lib/elixir_script/next/state.ex index bd0f4735..ccc837bf 100644 --- a/lib/elixir_script/next/state.ex +++ b/lib/elixir_script/next/state.ex @@ -21,10 +21,25 @@ defmodule ElixirScript.State do def put_module(pid, module, value) do Agent.update(pid, fn(state) -> + value = Map.put(value, :used, []) %{ state | modules: Keyword.put(state.modules, module, value) } end) end + def add_used(pid, module, {_function, _arity} = func) do + Agent.update(pid, fn(state) -> + module_info = Keyword.get(state.modules, module) + + used = Map.get(module_info, :used, []) + used = used ++ [func] + + module_info = Map.put(module_info, :used, used) + modules = Keyword.put(state.modules, module, module_info) + + %{ state | modules: modules } + end) + end + def get_javascript_modules(pid) do Agent.get(pid, fn(state) -> Map.get(state.compiler_opts, :js_modules, []) diff --git a/lib/elixir_script/translator/kernel/special_forms/identifier.ex b/lib/elixir_script/translator/kernel/special_forms/identifier.ex index d44bb6b7..99586343 100644 --- a/lib/elixir_script/translator/kernel/special_forms/identifier.ex +++ b/lib/elixir_script/translator/kernel/special_forms/identifier.ex @@ -91,4 +91,8 @@ defmodule ElixirScript.Translator.Identifier do JS.identifier("#{name}#{arity}") end + def make_extern_function_name(name) do + JS.identifier("#{name}") + end + end From dc5d1ba165f8189155ddc9fb68e6e4b8042517d0 Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Fri, 26 May 2017 20:40:18 -0500 Subject: [PATCH 095/418] Refactor file paths and add documentation --- .tool-versions | 2 +- .../experimental/examples/size.ex | 22 ------- lib/elixir_script/next/beam.ex | 7 ++ lib/elixir_script/next/compiler.ex | 60 ++--------------- .../next/{ => passes}/find_used.ex | 24 ++++--- lib/elixir_script/next/passes/translate.ex | 64 +++++++++++++++++++ .../passes/translate}/clause.ex | 6 +- .../passes/translate}/examples/example.ex | 0 .../next/passes/translate/examples/size.ex | 22 +++++++ .../passes/translate}/form.ex | 16 ++--- .../passes/translate}/forms/bitstring.ex | 4 +- .../passes/translate}/forms/call.ex | 10 +-- .../passes/translate}/forms/for.ex | 8 +-- .../passes/translate}/forms/map.ex | 4 +- .../passes/translate}/forms/match.ex | 6 +- .../passes/translate}/forms/pattern.ex | 6 +- .../passes/translate}/forms/struct.ex | 4 +- .../passes/translate}/forms/try.ex | 8 +-- .../passes/translate}/function.ex | 4 +- .../passes/translate}/functions/erlang.ex | 4 +- .../passes/translate}/functions/lists.ex | 4 +- .../passes/translate}/functions/maps.ex | 4 +- .../passes/translate}/module.ex | 19 +++--- .../passes/translate}/module_state.ex | 2 +- lib/elixir_script/next/state.ex | 10 +++ mix.lock | 30 ++++----- 26 files changed, 197 insertions(+), 153 deletions(-) delete mode 100644 lib/elixir_script/experimental/examples/size.ex rename lib/elixir_script/next/{ => passes}/find_used.ex (89%) create mode 100644 lib/elixir_script/next/passes/translate.ex rename lib/elixir_script/{experimental => next/passes/translate}/clause.ex (94%) rename lib/elixir_script/{experimental => next/passes/translate}/examples/example.ex (100%) create mode 100644 lib/elixir_script/next/passes/translate/examples/size.ex rename lib/elixir_script/{experimental => next/passes/translate}/form.ex (90%) rename lib/elixir_script/{experimental => next/passes/translate}/forms/bitstring.ex (97%) rename lib/elixir_script/{experimental => next/passes/translate}/forms/call.ex (77%) rename lib/elixir_script/{experimental => next/passes/translate}/forms/for.ex (95%) rename lib/elixir_script/{experimental => next/passes/translate}/forms/map.ex (94%) rename lib/elixir_script/{experimental => next/passes/translate}/forms/match.ex (93%) rename lib/elixir_script/{experimental => next/passes/translate}/forms/pattern.ex (96%) rename lib/elixir_script/{experimental => next/passes/translate}/forms/struct.ex (83%) rename lib/elixir_script/{experimental => next/passes/translate}/forms/try.ex (92%) rename lib/elixir_script/{experimental => next/passes/translate}/function.ex (90%) rename lib/elixir_script/{experimental => next/passes/translate}/functions/erlang.ex (99%) rename lib/elixir_script/{experimental => next/passes/translate}/functions/lists.ex (97%) rename lib/elixir_script/{experimental => next/passes/translate}/functions/maps.ex (95%) rename lib/elixir_script/{experimental => next/passes/translate}/module.ex (82%) rename lib/elixir_script/{experimental => next/passes/translate}/module_state.ex (87%) diff --git a/.tool-versions b/.tool-versions index 822dfebc..09178de1 100644 --- a/.tool-versions +++ b/.tool-versions @@ -1,3 +1,3 @@ -elixir 1.5.0-dev erlang ref-OTP-20.0-rc1 +elixir ref-9825280 nodejs 7.10.0 \ No newline at end of file diff --git a/lib/elixir_script/experimental/examples/size.ex b/lib/elixir_script/experimental/examples/size.ex deleted file mode 100644 index e16baa30..00000000 --- a/lib/elixir_script/experimental/examples/size.ex +++ /dev/null @@ -1,22 +0,0 @@ -defprotocol Example.Size do - @compile {:undocumented_elixir_backend_option, ElixirScript.Experimental.Backend} - def size(data) -end - -defimpl Example.Size, for: BitString do - @compile {:undocumented_elixir_backend_option, ElixirScript.Experimental.Backend} - - def size(string), do: byte_size(string) -end - -defimpl Example.Size, for: Map do - @compile {:undocumented_elixir_backend_option, ElixirScript.Experimental.Backend} - - def size(map), do: map_size(map) -end - -defimpl Example.Size, for: Tuple do - @compile {:undocumented_elixir_backend_option, ElixirScript.Experimental.Backend} - - def size(tuple), do: tuple_size(tuple) -end \ No newline at end of file diff --git a/lib/elixir_script/next/beam.ex b/lib/elixir_script/next/beam.ex index 8272eeeb..c6183758 100644 --- a/lib/elixir_script/next/beam.ex +++ b/lib/elixir_script/next/beam.ex @@ -1,5 +1,12 @@ defmodule ElixirScript.Beam do + @moduledoc false + @doc """ + Takes a module and finds the expanded AST + from the debug info inside the beam file. + For protocols, this will return a list of + all the protocol implementations + """ @spec debug_info(atom) :: {:ok | :error, map | binary} def debug_info(module) when is_atom(module) do with {_, beam, _} <- :code.get_object_code(module), diff --git a/lib/elixir_script/next/compiler.ex b/lib/elixir_script/next/compiler.ex index f826bfc6..864fa645 100644 --- a/lib/elixir_script/next/compiler.ex +++ b/lib/elixir_script/next/compiler.ex @@ -1,6 +1,9 @@ defmodule ElixirScript.Compiler do - alias ESTree.Tools.{Builder, Generator} - + @moduledoc """ + Compiles the given modules to JavaScript. + """ + + @spec compile([atom], []) :: nil def compile(entry_modules, opts \\ []) do opts = build_compiler_options(opts) {:ok, pid} = ElixirScript.State.start_link(opts) @@ -8,70 +11,21 @@ defmodule ElixirScript.Compiler do IO.puts "Finding used modules and functions" entry_modules |> List.wrap - |> ElixirScript.FindUsed.find_used(pid) - - modules = ElixirScript.State.list_modules(pid) + |> ElixirScript.FindUsed.execute(pid) IO.puts "Compiling" - Enum.each(modules, fn({module, info}) -> - ElixirScript.Experimental.Module.compile(module, info, pid) - end) - modules = ElixirScript.State.list_modules(pid) - modules = Enum.filter_map(modules, - fn {_, info} -> Map.has_key?(info, :js_ast) end, - fn {_module, info} -> - info.js_ast - end - ) - - bundle(modules, opts) + ElixirScript.Translate.execute(modules, pid) ElixirScript.State.stop(pid) end - defp bundle(modules, opts) do - ElixirScript.Passes.CreateJSModules.compile(modules, opts) - - js_code = modules - |> ElixirScript.Passes.CreateJSModules.compile(opts) - |> List.wrap - |> Builder.program - |> prepare_js_ast - |> Generator.generate - - concat(js_code) - |> IO.puts - end - - defp concat(code) do - "'use strict';\n" <> ElixirScript.get_bootstrap_js("iife") <> "\n" <> code - end - - defp prepare_js_ast(js_ast) do - case js_ast do - modules when is_list(modules) -> - modules - |> Enum.reduce([], &(&2 ++ &1.body)) - |> Builder.program - %ElixirScript.Translator.Group{body: body} -> - Builder.program(body) - %ElixirScript.Translator.Empty{} -> - Builder.program([]) - _ -> - js_ast - end - end - defp build_compiler_options(opts) do default_options = Map.new - |> Map.put(:full_build, false) |> Map.put(:output, nil) - |> Map.put(:app, :app) |> Map.put(:format, :es) |> Map.put(:js_modules, Keyword.get(opts, :js_modules, [])) - |> Map.put(:remove_unused, false) options = default_options Map.put(options, :module_formatter, get_module_formatter(options[:format])) diff --git a/lib/elixir_script/next/find_used.ex b/lib/elixir_script/next/passes/find_used.ex similarity index 89% rename from lib/elixir_script/next/find_used.ex rename to lib/elixir_script/next/passes/find_used.ex index 4a44c71f..8a19d9e6 100644 --- a/lib/elixir_script/next/find_used.ex +++ b/lib/elixir_script/next/passes/find_used.ex @@ -1,16 +1,22 @@ defmodule ElixirScript.FindUsed do + @moduledoc false alias ElixirScript.State, as: ModuleState - def find_used(modules, pid) do + @doc """ + Takes a list of entry modules and finds modules they use along with + documenting the functions used. The data collected about used functions + is used to filter only the used functions for compilation + """ + @spec execute([atom], pid) :: nil + def execute(modules, pid) do Enum.each(List.wrap(modules), fn(module) -> if ElixirScript.State.get_module(pid, module) == nil do - execute(module, pid) + do_execute(module, pid) end end) end - defp execute(module, pid) do - IO.inspect module + defp do_execute(module, pid) do case ElixirScript.Beam.debug_info(module) do {:ok, info} -> walk_module(module, info, pid) @@ -87,7 +93,7 @@ defmodule ElixirScript.FindUsed do end #defp walk(form, state) when is_atom(form) do - #if ElixirScript.Experimental.Module.is_elixir_module(form) do + #if ElixirScript.Translate.Module.is_elixir_module(form) do # if ModuleState.get_module(state.pid, form) == nil do # execute(form, state.pid) # end @@ -116,9 +122,9 @@ defmodule ElixirScript.FindUsed do end defp walk({:%, _, [module, params]}, state) do - if ElixirScript.Experimental.Module.is_elixir_module(module) do + if ElixirScript.Translate.Module.is_elixir_module(module) do if ModuleState.get_module(state.pid, module) == nil do - execute(module, state.pid) + do_execute(module, state.pid) end end Enum.each(params, &walk(&1, state)) @@ -213,9 +219,9 @@ defmodule ElixirScript.FindUsed do defp walk({{:., _, [module, function]}, _, params}, state) do cond do - ElixirScript.Experimental.Module.is_js_module(module, state) -> + ElixirScript.Translate.Module.is_js_module(module, state) -> nil - ElixirScript.Experimental.Module.is_elixir_module(module) -> + ElixirScript.Translate.Module.is_elixir_module(module) -> if ModuleState.get_module(state.pid, module) == nil do execute(module, state.pid) end diff --git a/lib/elixir_script/next/passes/translate.ex b/lib/elixir_script/next/passes/translate.ex new file mode 100644 index 00000000..5319086a --- /dev/null +++ b/lib/elixir_script/next/passes/translate.ex @@ -0,0 +1,64 @@ +defmodule ElixirScript.Translate do + @moduledoc false + + alias ElixirScript.State, as: ModuleState + alias ESTree.Tools.{Builder, Generator} + + @doc """ + Takes a list of modules and translates their ast into + JavaScript AST. The modules are the ones collected from + the FindUsed pass. + """ + @spec execute([atom], pid) :: nil + def execute(modules, pid) do + Enum.each(modules, fn({module, info}) -> + ElixirScript.Translate.Module.compile(module, info, pid) + end) + + modules = ElixirScript.State.list_modules(pid) + + modules = Enum.filter_map(modules, + fn {_, info} -> Map.has_key?(info, :js_ast) end, + fn {_module, info} -> + info.js_ast + end + ) + + opts = ModuleState.get_compiler_opts(pid) + + bundle(modules, opts) + end + + defp bundle(modules, opts) do + ElixirScript.Passes.CreateJSModules.compile(modules, opts) + + js_code = modules + |> ElixirScript.Passes.CreateJSModules.compile(opts) + |> List.wrap + |> Builder.program + |> prepare_js_ast + |> Generator.generate + + concat(js_code) + |> IO.puts + end + + defp concat(code) do + "'use strict';\n" <> ElixirScript.get_bootstrap_js("iife") <> "\n" <> code + end + + defp prepare_js_ast(js_ast) do + case js_ast do + modules when is_list(modules) -> + modules + |> Enum.reduce([], &(&2 ++ &1.body)) + |> Builder.program + %ElixirScript.Translator.Group{body: body} -> + Builder.program(body) + %ElixirScript.Translator.Empty{} -> + Builder.program([]) + _ -> + js_ast + end + end +end diff --git a/lib/elixir_script/experimental/clause.ex b/lib/elixir_script/next/passes/translate/clause.ex similarity index 94% rename from lib/elixir_script/experimental/clause.ex rename to lib/elixir_script/next/passes/translate/clause.ex index ea61a39c..ca1553ee 100644 --- a/lib/elixir_script/experimental/clause.ex +++ b/lib/elixir_script/next/passes/translate/clause.ex @@ -1,7 +1,7 @@ -defmodule ElixirScript.Experimental.Clause do +defmodule ElixirScript.Translate.Clause do alias ESTree.Tools.Builder, as: J - alias ElixirScript.Experimental.Form - alias ElixirScript.Experimental.Forms.Pattern + alias ElixirScript.Translate.Form + alias ElixirScript.Translate.Forms.Pattern @moduledoc """ Handles translation of all of the clause ASTs diff --git a/lib/elixir_script/experimental/examples/example.ex b/lib/elixir_script/next/passes/translate/examples/example.ex similarity index 100% rename from lib/elixir_script/experimental/examples/example.ex rename to lib/elixir_script/next/passes/translate/examples/example.ex diff --git a/lib/elixir_script/next/passes/translate/examples/size.ex b/lib/elixir_script/next/passes/translate/examples/size.ex new file mode 100644 index 00000000..d2a2619d --- /dev/null +++ b/lib/elixir_script/next/passes/translate/examples/size.ex @@ -0,0 +1,22 @@ +defprotocol Example.Size do + @compile {:undocumented_elixir_backend_option, ElixirScript.Translate.Backend} + def size(data) +end + +defimpl Example.Size, for: BitString do + @compile {:undocumented_elixir_backend_option, ElixirScript.Translate.Backend} + + def size(string), do: byte_size(string) +end + +defimpl Example.Size, for: Map do + @compile {:undocumented_elixir_backend_option, ElixirScript.Translate.Backend} + + def size(map), do: map_size(map) +end + +defimpl Example.Size, for: Tuple do + @compile {:undocumented_elixir_backend_option, ElixirScript.Translate.Backend} + + def size(tuple), do: tuple_size(tuple) +end \ No newline at end of file diff --git a/lib/elixir_script/experimental/form.ex b/lib/elixir_script/next/passes/translate/form.ex similarity index 90% rename from lib/elixir_script/experimental/form.ex rename to lib/elixir_script/next/passes/translate/form.ex index 9778d4f8..e325071f 100644 --- a/lib/elixir_script/experimental/form.ex +++ b/lib/elixir_script/next/passes/translate/form.ex @@ -1,9 +1,9 @@ -defmodule ElixirScript.Experimental.Form do +defmodule ElixirScript.Translate.Form do alias ESTree.Tools.Builder, as: J - alias ElixirScript.Experimental.Forms.{Bitstring, Match, Call, Try, For, Struct} - alias ElixirScript.Experimental.Functions.{Erlang, Lists, Maps} + alias ElixirScript.Translate.Forms.{Bitstring, Match, Call, Try, For, Struct} + alias ElixirScript.Translate.Functions.{Erlang, Lists, Maps} alias ElixirScript.Translator.Identifier - alias ElixirScript.Experimental.Clause + alias ElixirScript.Translate.Clause @moduledoc """ Handles translation of all forms that are not functions or clauses @@ -24,7 +24,7 @@ defmodule ElixirScript.Experimental.Form do end def compile(form, state) when is_atom(form) do - if ElixirScript.Experimental.Module.is_elixir_module(form) do + if ElixirScript.Translate.Module.is_elixir_module(form) do members = if form == Elixir, do: ["Elixir"], else: ["Elixir"] ++ Module.split(form) J.identifier(Enum.join(members, "_")) else @@ -56,7 +56,7 @@ defmodule ElixirScript.Experimental.Form do end def compile({:%{}, _, _} = map, state) do - ElixirScript.Experimental.Forms.Map.compile(map, state) + ElixirScript.Translate.Forms.Map.compile(map, state) end def compile({:<<>>, _, _} = bitstring, state) do @@ -78,7 +78,7 @@ defmodule ElixirScript.Experimental.Form do def compile({:case, _, [condition, [do: clauses]]}, state) do func = J.call_expression( J.member_expression( - ElixirScript.Experimental.Function.patterns_ast(), + ElixirScript.Translate.Function.patterns_ast(), J.identifier("defmatch") ), Enum.map(clauses, &Clause.compile(&1, state)) @@ -133,7 +133,7 @@ defmodule ElixirScript.Experimental.Form do def compile({:fn, _, clauses}, state) do J.call_expression( J.member_expression( - ElixirScript.Experimental.Function.patterns_ast(), + ElixirScript.Translate.Function.patterns_ast(), J.identifier("defmatch") ), Enum.map(clauses, &Clause.compile(&1, state)) diff --git a/lib/elixir_script/experimental/forms/bitstring.ex b/lib/elixir_script/next/passes/translate/forms/bitstring.ex similarity index 97% rename from lib/elixir_script/experimental/forms/bitstring.ex rename to lib/elixir_script/next/passes/translate/forms/bitstring.ex index ed978e5a..e6d23408 100644 --- a/lib/elixir_script/experimental/forms/bitstring.ex +++ b/lib/elixir_script/next/passes/translate/forms/bitstring.ex @@ -1,7 +1,7 @@ -defmodule ElixirScript.Experimental.Forms.Bitstring do +defmodule ElixirScript.Translate.Forms.Bitstring do @moduledoc false alias ESTree.Tools.Builder, as: JS - alias ElixirScript.Experimental.Form + alias ElixirScript.Translate.Form def compile({:<<>>, _, elements}, state) do diff --git a/lib/elixir_script/experimental/forms/call.ex b/lib/elixir_script/next/passes/translate/forms/call.ex similarity index 77% rename from lib/elixir_script/experimental/forms/call.ex rename to lib/elixir_script/next/passes/translate/forms/call.ex index 062abc05..0715538a 100644 --- a/lib/elixir_script/experimental/forms/call.ex +++ b/lib/elixir_script/next/passes/translate/forms/call.ex @@ -1,11 +1,11 @@ -defmodule ElixirScript.Experimental.Forms.Call do +defmodule ElixirScript.Translate.Forms.Call do alias ESTree.Tools.Builder, as: J - alias ElixirScript.Experimental.Form + alias ElixirScript.Translate.Form alias ElixirScript.Translator.Identifier def compile({{:., _, [module, function]}, _, params}, state) do function_name = cond do - ElixirScript.Experimental.Module.is_js_module(module, state) -> + ElixirScript.Translate.Module.is_js_module(module, state) -> ElixirScript.Translator.Identifier.make_extern_function_name(function) true -> ElixirScript.Translator.Identifier.make_function_name(function, length(params)) @@ -22,10 +22,10 @@ defmodule ElixirScript.Experimental.Forms.Call do defp process_module_name(module, state) when is_atom(module) do cond do - ElixirScript.Experimental.Module.is_js_module(module, state) -> + ElixirScript.Translate.Module.is_js_module(module, state) -> members = tl(Module.split(module)) Identifier.make_namespace_members(members) - ElixirScript.Experimental.Module.is_elixir_module(module) -> + ElixirScript.Translate.Module.is_elixir_module(module) -> members = ["Elixir"] ++ Module.split(module) J.identifier(Enum.join(members, "_")) true -> diff --git a/lib/elixir_script/experimental/forms/for.ex b/lib/elixir_script/next/passes/translate/forms/for.ex similarity index 95% rename from lib/elixir_script/experimental/forms/for.ex rename to lib/elixir_script/next/passes/translate/forms/for.ex index bf623836..5c8aeb42 100644 --- a/lib/elixir_script/experimental/forms/for.ex +++ b/lib/elixir_script/next/passes/translate/forms/for.ex @@ -1,8 +1,8 @@ -defmodule ElixirScript.Experimental.Forms.For do +defmodule ElixirScript.Translate.Forms.For do alias ESTree.Tools.Builder, as: JS - alias ElixirScript.Experimental.Form - alias ElixirScript.Experimental.Clause - alias ElixirScript.Experimental.Forms.{Pattern} + alias ElixirScript.Translate.Form + alias ElixirScript.Translate.Clause + alias ElixirScript.Translate.Forms.{Pattern} def compile({:for, _, generators}, state) do args = handle_args(generators, state) diff --git a/lib/elixir_script/experimental/forms/map.ex b/lib/elixir_script/next/passes/translate/forms/map.ex similarity index 94% rename from lib/elixir_script/experimental/forms/map.ex rename to lib/elixir_script/next/passes/translate/forms/map.ex index bac66534..a33624ef 100644 --- a/lib/elixir_script/experimental/forms/map.ex +++ b/lib/elixir_script/next/passes/translate/forms/map.ex @@ -1,6 +1,6 @@ -defmodule ElixirScript.Experimental.Forms.Map do +defmodule ElixirScript.Translate.Forms.Map do alias ESTree.Tools.Builder, as: J - alias ElixirScript.Experimental.Form + alias ElixirScript.Translate.Form def compile({:%{}, _, [{:|, _, [map, new_values]}]}, state) do map = Form.compile(map, state) diff --git a/lib/elixir_script/experimental/forms/match.ex b/lib/elixir_script/next/passes/translate/forms/match.ex similarity index 93% rename from lib/elixir_script/experimental/forms/match.ex rename to lib/elixir_script/next/passes/translate/forms/match.ex index 3e40b2f4..67fabcc2 100644 --- a/lib/elixir_script/experimental/forms/match.ex +++ b/lib/elixir_script/next/passes/translate/forms/match.ex @@ -1,7 +1,7 @@ -defmodule ElixirScript.Experimental.Forms.Match do +defmodule ElixirScript.Translate.Forms.Match do alias ESTree.Tools.Builder, as: J - alias ElixirScript.Experimental.Form - alias ElixirScript.Experimental.Forms.{Pattern} + alias ElixirScript.Translate.Form + alias ElixirScript.Translate.Forms.{Pattern} def compile({:=, _, [left, right]}, state) do right_ast = Form.compile(right, state) diff --git a/lib/elixir_script/experimental/forms/pattern.ex b/lib/elixir_script/next/passes/translate/forms/pattern.ex similarity index 96% rename from lib/elixir_script/experimental/forms/pattern.ex rename to lib/elixir_script/next/passes/translate/forms/pattern.ex index 1b6edf22..5ed3ba6b 100644 --- a/lib/elixir_script/experimental/forms/pattern.ex +++ b/lib/elixir_script/next/passes/translate/forms/pattern.ex @@ -1,8 +1,8 @@ -defmodule ElixirScript.Experimental.Forms.Pattern do +defmodule ElixirScript.Translate.Forms.Pattern do alias ElixirScript.Translator.PatternMatching, as: PM alias ESTree.Tools.Builder, as: J - alias ElixirScript.Experimental.Form - alias ElixirScript.Experimental.Forms.{Bitstring, Map} + alias ElixirScript.Translate.Form + alias ElixirScript.Translate.Forms.{Bitstring, Map} @moduledoc """ Handles all pattern matching translations diff --git a/lib/elixir_script/experimental/forms/struct.ex b/lib/elixir_script/next/passes/translate/forms/struct.ex similarity index 83% rename from lib/elixir_script/experimental/forms/struct.ex rename to lib/elixir_script/next/passes/translate/forms/struct.ex index 7aebfa78..4b4e83fd 100644 --- a/lib/elixir_script/experimental/forms/struct.ex +++ b/lib/elixir_script/next/passes/translate/forms/struct.ex @@ -1,6 +1,6 @@ -defmodule ElixirScript.Experimental.Forms.Struct do +defmodule ElixirScript.Translate.Forms.Struct do alias ESTree.Tools.Builder, as: J - alias ElixirScript.Experimental.Form + alias ElixirScript.Translate.Form alias ElixirScript.Translator.Identifier def compile({:%, _, [module, params]}, state) do diff --git a/lib/elixir_script/experimental/forms/try.ex b/lib/elixir_script/next/passes/translate/forms/try.ex similarity index 92% rename from lib/elixir_script/experimental/forms/try.ex rename to lib/elixir_script/next/passes/translate/forms/try.ex index effe3fbd..940bc7ae 100644 --- a/lib/elixir_script/experimental/forms/try.ex +++ b/lib/elixir_script/next/passes/translate/forms/try.ex @@ -1,8 +1,8 @@ -defmodule ElixirScript.Experimental.Forms.Try do +defmodule ElixirScript.Translate.Forms.Try do @moduledoc false alias ESTree.Tools.Builder, as: JS - alias ElixirScript.Experimental.Clause - alias ElixirScript.Experimental.Form + alias ElixirScript.Translate.Clause + alias ElixirScript.Translate.Form def compile(blocks, state) do try_block = Keyword.get(blocks, :do) @@ -74,7 +74,7 @@ defmodule ElixirScript.Experimental.Forms.Try do JS.call_expression( JS.member_expression( - ElixirScript.Experimental.Function.patterns_ast(), + ElixirScript.Translate.Function.patterns_ast(), JS.identifier("defmatch") ), processed_clauses diff --git a/lib/elixir_script/experimental/function.ex b/lib/elixir_script/next/passes/translate/function.ex similarity index 90% rename from lib/elixir_script/experimental/function.ex rename to lib/elixir_script/next/passes/translate/function.ex index b16f18f6..b3204e65 100644 --- a/lib/elixir_script/experimental/function.ex +++ b/lib/elixir_script/next/passes/translate/function.ex @@ -1,6 +1,6 @@ -defmodule ElixirScript.Experimental.Function do +defmodule ElixirScript.Translate.Function do alias ESTree.Tools.Builder, as: J - alias ElixirScript.Experimental.Clause + alias ElixirScript.Translate.Clause @moduledoc """ Translates the given Elixir function AST into the diff --git a/lib/elixir_script/experimental/functions/erlang.ex b/lib/elixir_script/next/passes/translate/functions/erlang.ex similarity index 99% rename from lib/elixir_script/experimental/functions/erlang.ex rename to lib/elixir_script/next/passes/translate/functions/erlang.ex index 0d813a40..2fe056fc 100644 --- a/lib/elixir_script/experimental/functions/erlang.ex +++ b/lib/elixir_script/next/passes/translate/functions/erlang.ex @@ -1,7 +1,7 @@ -defmodule ElixirScript.Experimental.Functions.Erlang do +defmodule ElixirScript.Translate.Functions.Erlang do @moduledoc false alias ESTree.Tools.Builder, as: J - alias ElixirScript.Experimental.Form + alias ElixirScript.Translate.Form def rewrite({{:., _, [:erlang, :abs]}, _, [number]}, state) do J.call_expression( diff --git a/lib/elixir_script/experimental/functions/lists.ex b/lib/elixir_script/next/passes/translate/functions/lists.ex similarity index 97% rename from lib/elixir_script/experimental/functions/lists.ex rename to lib/elixir_script/next/passes/translate/functions/lists.ex index 1c1c2a39..db2d7d73 100644 --- a/lib/elixir_script/experimental/functions/lists.ex +++ b/lib/elixir_script/next/passes/translate/functions/lists.ex @@ -1,7 +1,7 @@ -defmodule ElixirScript.Experimental.Functions.Lists do +defmodule ElixirScript.Translate.Functions.Lists do @moduledoc false alias ESTree.Tools.Builder, as: J - alias ElixirScript.Experimental.Form + alias ElixirScript.Translate.Form def rewrite({{:., _, [:lists, :map]}, _, [fun, list]}, state) do J.call_expression( diff --git a/lib/elixir_script/experimental/functions/maps.ex b/lib/elixir_script/next/passes/translate/functions/maps.ex similarity index 95% rename from lib/elixir_script/experimental/functions/maps.ex rename to lib/elixir_script/next/passes/translate/functions/maps.ex index 4e528d8a..2db82ecf 100644 --- a/lib/elixir_script/experimental/functions/maps.ex +++ b/lib/elixir_script/next/passes/translate/functions/maps.ex @@ -1,7 +1,7 @@ -defmodule ElixirScript.Experimental.Functions.Maps do +defmodule ElixirScript.Translate.Functions.Maps do @moduledoc false alias ESTree.Tools.Builder, as: J - alias ElixirScript.Experimental.Form + alias ElixirScript.Translate.Form def rewrite({{:., _, [:maps, :update]}, _, [key, value, map]}, state) do J.call_expression( diff --git a/lib/elixir_script/experimental/module.ex b/lib/elixir_script/next/passes/translate/module.ex similarity index 82% rename from lib/elixir_script/experimental/module.ex rename to lib/elixir_script/next/passes/translate/module.ex index 3d30a09d..dd5b142b 100644 --- a/lib/elixir_script/experimental/module.ex +++ b/lib/elixir_script/next/passes/translate/module.ex @@ -1,13 +1,14 @@ -defmodule ElixirScript.Experimental.Module do +defmodule ElixirScript.Translate.Module do + @moduledoc false alias ESTree.Tools.Builder, as: J - alias ElixirScript.Experimental.Function + alias ElixirScript.Translate.Function alias ElixirScript.Translator.Identifier alias ElixirScript.State, as: ModuleState - @moduledoc """ - Upper level module that handles compilation + @doc """ + Translate the given module's ast to + JavaScript AST """ - def compile(module, info, pid) do %{ attributes: _attrs, @@ -24,15 +25,17 @@ defmodule ElixirScript.Experimental.Module do pid: pid } - reachable_defs = Enum.filter(defs, fn + # Filter so that we only have the + # Used functions to compile + used_defs = Enum.filter(defs, fn { name, _, _, _} -> name in used _ -> false end) - compiled_functions = reachable_defs + compiled_functions = used_defs |> Enum.map(&Function.compile(&1, state)) - exports = make_exports(reachable_defs) + exports = make_exports(used_defs) js_ast = ElixirScript.ModuleSystems.Namespace.build( module, diff --git a/lib/elixir_script/experimental/module_state.ex b/lib/elixir_script/next/passes/translate/module_state.ex similarity index 87% rename from lib/elixir_script/experimental/module_state.ex rename to lib/elixir_script/next/passes/translate/module_state.ex index dbd21825..8e2afdd2 100644 --- a/lib/elixir_script/experimental/module_state.ex +++ b/lib/elixir_script/next/passes/translate/module_state.ex @@ -1,4 +1,4 @@ -defmodule ElixirScript.Experimental.ModuleState do +defmodule ElixirScript.Translate.ModuleState do def start_link(module) do Agent.start_link(fn -> %{ module: module, refs: [] } end) end diff --git a/lib/elixir_script/next/state.ex b/lib/elixir_script/next/state.ex index ccc837bf..711d8244 100644 --- a/lib/elixir_script/next/state.ex +++ b/lib/elixir_script/next/state.ex @@ -1,4 +1,8 @@ defmodule ElixirScript.State do + @moduledoc false + + # Holds the state for the ElixirScript compiler + def start_link(compiler_opts) do Agent.start_link(fn -> %{ @@ -13,6 +17,12 @@ defmodule ElixirScript.State do Agent.stop(pid) end + def get_compiler_opts(pid) do + Agent.get(pid, fn(state) -> + state.compiler_opts + end) + end + def get_module(pid, module) do Agent.get(pid, fn(state) -> Keyword.get(state.modules, module) diff --git a/mix.lock b/mix.lock index b6b6b0d2..353e11a0 100644 --- a/mix.lock +++ b/mix.lock @@ -1,15 +1,15 @@ -%{"bunt": {:hex, :bunt, "0.2.0", "951c6e801e8b1d2cbe58ebbd3e616a869061ddadcc4863d0a2182541acae9a38", [:mix], []}, - "certifi": {:hex, :certifi, "1.0.0", "1c787a85b1855ba354f0b8920392c19aa1d06b0ee1362f9141279620a5be2039", [:rebar3], []}, - "credo": {:hex, :credo, "0.7.3", "9827ab04002186af1aec014a811839a06f72aaae6cd5eed3919b248c8767dbf3", [:mix], [{:bunt, "~> 0.2.0", [hex: :bunt, optional: false]}]}, - "earmark": {:hex, :earmark, "1.2.0", "bf1ce17aea43ab62f6943b97bd6e3dc032ce45d4f787504e3adf738e54b42f3a", [:mix], []}, - "estree": {:hex, :estree, "2.6.0", "86a301b0c355fa55c19e7ef9dceb1b1e983c6df526a2b7846818a38c258fc3fb", [:mix], []}, - "ex_doc": {:hex, :ex_doc, "0.15.1", "d5f9d588fd802152516fccfdb96d6073753f77314fcfee892b15b6724ca0d596", [:mix], [{:earmark, "~> 1.1", [hex: :earmark, optional: false]}]}, - "excoveralls": {:hex, :excoveralls, "0.6.3", "894bf9254890a4aac1d1165da08145a72700ff42d8cb6ce8195a584cb2a4b374", [:mix], [{:exjsx, "~> 3.0", [hex: :exjsx, optional: false]}, {:hackney, ">= 0.12.0", [hex: :hackney, optional: false]}]}, - "exjsx": {:hex, :exjsx, "3.2.1", "1bc5bf1e4fd249104178f0885030bcd75a4526f4d2a1e976f4b428d347614f0f", [], [{:jsx, "~> 2.8.0", [hex: :jsx, optional: false]}]}, - "fs": {:hex, :fs, "2.12.0", "ad631efacc9a5683c8eaa1b274e24fa64a1b8eb30747e9595b93bec7e492e25e", [:rebar3], []}, - "hackney": {:hex, :hackney, "1.7.1", "e238c52c5df3c3b16ce613d3a51c7220a784d734879b1e231c9babd433ac1cb4", [:rebar3], [{:certifi, "1.0.0", [hex: :certifi, optional: false]}, {:idna, "4.0.0", [hex: :idna, optional: false]}, {:metrics, "1.0.1", [hex: :metrics, optional: false]}, {:mimerl, "1.0.2", [hex: :mimerl, optional: false]}, {:ssl_verify_fun, "1.1.1", [hex: :ssl_verify_fun, optional: false]}]}, - "idna": {:hex, :idna, "4.0.0", "10aaa9f79d0b12cf0def53038547855b91144f1bfcc0ec73494f38bb7b9c4961", [:rebar3], []}, - "jsx": {:hex, :jsx, "2.8.2", "7acc7d785b5abe8a6e9adbde926a24e481f29956dd8b4df49e3e4e7bcc92a018", [:mix, :rebar3], []}, - "metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [], []}, - "mimerl": {:hex, :mimerl, "1.0.2", "993f9b0e084083405ed8252b99460c4f0563e41729ab42d9074fd5e52439be88", [], []}, - "ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.1", "28a4d65b7f59893bc2c7de786dec1e1555bd742d336043fe644ae956c3497fbe", [:make, :rebar], []}} +%{"bunt": {:hex, :bunt, "0.2.0", "951c6e801e8b1d2cbe58ebbd3e616a869061ddadcc4863d0a2182541acae9a38", [:mix], [], "hexpm"}, + "certifi": {:hex, :certifi, "1.0.0", "1c787a85b1855ba354f0b8920392c19aa1d06b0ee1362f9141279620a5be2039", [:rebar3], [], "hexpm"}, + "credo": {:hex, :credo, "0.7.3", "9827ab04002186af1aec014a811839a06f72aaae6cd5eed3919b248c8767dbf3", [:mix], [{:bunt, "~> 0.2.0", [hex: :bunt, repo: "hexpm", optional: false]}], "hexpm"}, + "earmark": {:hex, :earmark, "1.2.0", "bf1ce17aea43ab62f6943b97bd6e3dc032ce45d4f787504e3adf738e54b42f3a", [:mix], [], "hexpm"}, + "estree": {:hex, :estree, "2.6.0", "86a301b0c355fa55c19e7ef9dceb1b1e983c6df526a2b7846818a38c258fc3fb", [:mix], [], "hexpm"}, + "ex_doc": {:hex, :ex_doc, "0.15.1", "d5f9d588fd802152516fccfdb96d6073753f77314fcfee892b15b6724ca0d596", [:mix], [{:earmark, "~> 1.1", [hex: :earmark, repo: "hexpm", optional: false]}], "hexpm"}, + "excoveralls": {:hex, :excoveralls, "0.6.3", "894bf9254890a4aac1d1165da08145a72700ff42d8cb6ce8195a584cb2a4b374", [:mix], [{:exjsx, "~> 3.0", [hex: :exjsx, repo: "hexpm", optional: false]}, {:hackney, ">= 0.12.0", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm"}, + "exjsx": {:hex, :exjsx, "3.2.1", "1bc5bf1e4fd249104178f0885030bcd75a4526f4d2a1e976f4b428d347614f0f", [:mix], [{:jsx, "~> 2.8.0", [hex: :jsx, repo: "hexpm", optional: false]}], "hexpm"}, + "fs": {:hex, :fs, "2.12.0", "ad631efacc9a5683c8eaa1b274e24fa64a1b8eb30747e9595b93bec7e492e25e", [:rebar3], [], "hexpm"}, + "hackney": {:hex, :hackney, "1.7.1", "e238c52c5df3c3b16ce613d3a51c7220a784d734879b1e231c9babd433ac1cb4", [:rebar3], [{:certifi, "1.0.0", [hex: :certifi, repo: "hexpm", optional: false]}, {:idna, "4.0.0", [hex: :idna, repo: "hexpm", optional: false]}, {:metrics, "1.0.1", [hex: :metrics, repo: "hexpm", optional: false]}, {:mimerl, "1.0.2", [hex: :mimerl, repo: "hexpm", optional: false]}, {:ssl_verify_fun, "1.1.1", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}], "hexpm"}, + "idna": {:hex, :idna, "4.0.0", "10aaa9f79d0b12cf0def53038547855b91144f1bfcc0ec73494f38bb7b9c4961", [:rebar3], [], "hexpm"}, + "jsx": {:hex, :jsx, "2.8.2", "7acc7d785b5abe8a6e9adbde926a24e481f29956dd8b4df49e3e4e7bcc92a018", [:mix, :rebar3], [], "hexpm"}, + "metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [:rebar3], [], "hexpm"}, + "mimerl": {:hex, :mimerl, "1.0.2", "993f9b0e084083405ed8252b99460c4f0563e41729ab42d9074fd5e52439be88", [:rebar3], [], "hexpm"}, + "ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.1", "28a4d65b7f59893bc2c7de786dec1e1555bd742d336043fe644ae956c3497fbe", [:make, :rebar], [], "hexpm"}} From 69e85ab80ce74d620b6c98579ce5b2b5f032d16e Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Fri, 26 May 2017 21:06:37 -0500 Subject: [PATCH 096/418] Remove rewrite of erlang functions. Add erlang compat layer in javascript --- .../next/passes/translate/form.ex | 31 +- .../next/passes/translate/functions/erlang.ex | 914 ------------------ .../next/passes/translate/functions/lists.ex | 178 ---- .../next/passes/translate/functions/maps.ex | 85 -- src/javascript/lib/core.js | 6 + .../lib/core/erlang_compat/erlang.js | 1 + .../lib/core/erlang_compat/lists.js | 1 + src/javascript/lib/core/erlang_compat/maps.js | 1 + 8 files changed, 26 insertions(+), 1191 deletions(-) delete mode 100644 lib/elixir_script/next/passes/translate/functions/erlang.ex delete mode 100644 lib/elixir_script/next/passes/translate/functions/lists.ex delete mode 100644 lib/elixir_script/next/passes/translate/functions/maps.ex create mode 100644 src/javascript/lib/core/erlang_compat/erlang.js create mode 100644 src/javascript/lib/core/erlang_compat/lists.js create mode 100644 src/javascript/lib/core/erlang_compat/maps.js diff --git a/lib/elixir_script/next/passes/translate/form.ex b/lib/elixir_script/next/passes/translate/form.ex index e325071f..5d69280a 100644 --- a/lib/elixir_script/next/passes/translate/form.ex +++ b/lib/elixir_script/next/passes/translate/form.ex @@ -13,7 +13,7 @@ defmodule ElixirScript.Translate.Form do J.identifier("null") end - def compile(form, _) when is_boolean(form) when is_integer(form) when is_float(form) when is_binary(form) do + def compile(form, _) when is_boolean(form) or is_integer(form) or is_float(form) or is_binary(form) do J.literal(form) end @@ -120,10 +120,9 @@ defmodule ElixirScript.Translate.Form do ) end - def compile({:receive, context, _}, state) do + def compile({:receive, context, _}, _state) do line = Keyword.get(context, :line, 1) - #raise ElixirScriptCompileError, message: "Line: #{line} receive not supported" - J.call_expression(J.identifier(:receive), []) + raise ElixirScriptCompileError, message: "Line: #{line} receive not supported" end def compile({:try, _, [blocks]}, state) do @@ -140,16 +139,20 @@ defmodule ElixirScript.Translate.Form do ) end - def compile({{:., _, [:erlang, _]}, _, _} = ast, state) do - Erlang.rewrite(ast, state) - end - - def compile({{:., _, [:lists, _]}, _, _} = ast, state) do - Lists.rewrite(ast, state) - end - - def compile({{:., _, [:maps, _]}, _, _} = ast, state) do - Maps.rewrite(ast, state) + def compile({{:., _, [module, function]}, _, params}, state) when module in [:erlang, :lists, :maps] do + J.call_expression( + J.member_expression( + J.member_expression( + J.member_expression( + J.identifier("Bootstrap"), + J.identifier("Core") + ), + J.identifier(module) + ), + J.identifier(function) + ), + Enum.map(params, &compile(&1, state)) + ) end def compile({{:., _, [_, _]}, _, _} = ast, state) do diff --git a/lib/elixir_script/next/passes/translate/functions/erlang.ex b/lib/elixir_script/next/passes/translate/functions/erlang.ex deleted file mode 100644 index 2fe056fc..00000000 --- a/lib/elixir_script/next/passes/translate/functions/erlang.ex +++ /dev/null @@ -1,914 +0,0 @@ -defmodule ElixirScript.Translate.Functions.Erlang do - @moduledoc false - alias ESTree.Tools.Builder, as: J - alias ElixirScript.Translate.Form - - def rewrite({{:., _, [:erlang, :abs]}, _, [number]}, state) do - J.call_expression( - J.member_expression( - J.identifier("Math"), - J.identifier("abs") - ), - [Form.compile(number, state)] - ) - end - - def rewrite({{:., _, [:erlang, :apply]}, _, [fun, args]}, state) do - J.call_expression( - J.member_expression( - Form.compile(fun, state), - J.identifier("apply") - ), - [Form.compile(fun, state), J.array_expression(Enum.map(List.wrap(args), &Form.compile(&1, state)))] - ) - end - - def rewrite({{:., _, [:erlang, :apply]}, _, [module, fun, args]}, state) do - mod = J.member_expression( - Form.compile(module, state), - Form.compile(fun, state) - ) - - J.call_expression( - J.member_expression( - mod, - J.identifier("apply") - ), - [mod, J.array_expression(Enum.map(List.wrap(args), &Form.compile(&1, state)))] - ) - end - - def rewrite({{:., _, [:erlang, :binary_part]}, _, [binary, start, length]}, state) do - J.call_expression( - J.member_expression( - Form.compile(binary, state), - J.identifier("substring") - ), - [Form.compile(start, state), Form.compile(length, state)] - ) - end - - def rewrite({{:., _, [:erlang, :bit_size]}, _, [bitstring]}, state) do - J.call_expression( - J.member_expression( - Form.compile(bitstring, state), - J.identifier("bit_size") - ), - [] - ) - end - - def rewrite({{:., _, [:erlang, :byte_size]}, _, [bitstring]}, state) do - J.call_expression( - J.member_expression( - Form.compile(bitstring, state), - J.identifier("byte_size") - ), - [] - ) - end - - def rewrite({{:., _, [:erlang, :div]}, _, [left, right]}, state) do - J.binary_expression( - :/, - Form.compile(left, state), - Form.compile(right, state) - ) - end - - def rewrite({{:., _, [:erlang, :exit]}, _, [reason]}, _) do - J.literal(0) - end - - def rewrite({{:., _, [:erlang, :hd]}, _, [list]}, state) do - J.member_expression( - Form.compile(list, state), - J.literal(0), - true - ) - end - - def rewrite({{:., _, [:erlang, :is_atom]}, _, [term]}, state) do - J.binary_expression( - :typeof, - Form.compile(term, state), - J.literal("symbol") - ) - end - - def rewrite({{:., _, [:erlang, :is_binary]}, _, [term]}, state) do - J.binary_expression( - :typeof, - Form.compile(term, state), - J.literal("string") - ) - end - - def rewrite({{:., _, [:erlang, :is_bitstring]}, _, [term]}, state) do - J.binary_expression( - :||, - J.binary_expression( - :typeof, - Form.compile(term, state), - J.literal("string") - ), - J.binary_expression( - :instanceof, - Form.compile(term, state), - J.member_expression( - J.member_expression( - J.identifier("Bootstrap"), - J.identifier("Core") - ), - J.identifier("BitString") - ) - ) - ) - end - - def rewrite({{:., _, [:erlang, :is_boolean]}, _, [term]}, state) do - J.binary_expression( - :||, - J.binary_expression( - :typeof, - Form.compile(term, state), - J.literal("boolean") - ), - J.binary_expression( - :instanceof, - Form.compile(term, state), - J.identifier("Boolean") - ) - ) - end - - def rewrite({{:., _, [:erlang, :is_float]}, _, [term]}, state) do - J.binary_expression( - :||, - J.binary_expression( - :typeof, - Form.compile(term, state), - J.literal("number") - ), - J.binary_expression( - :&&, - J.binary_expression( - :instanceof, - Form.compile(term, state), - J.identifier("Number") - ), - J.unary_expression( - :!, - true, - J.call_expression( - J.member_expression( - J.identifier("Number"), - J.identifier("isInteger") - ), - [Form.compile(term, state)] - ) - ) - ) - ) - end - - def rewrite({{:., _, [:erlang, :is_function]}, _, [term]}, state) do - J.binary_expression( - :||, - J.binary_expression( - :typeof, - Form.compile(term, state), - J.literal("function") - ), - J.binary_expression( - :instanceof, - Form.compile(term, state), - J.identifier("Function") - ) - ) - end - - def rewrite({{:., _, [:erlang, :is_function]}, _, [term, _]}, state) do - J.binary_expression( - :||, - J.binary_expression( - :typeof, - Form.compile(term, state), - J.literal("function") - ), - J.binary_expression( - :instanceof, - Form.compile(term, state), - J.identifier("Function") - ) - ) - end - - def rewrite({{:., _, [:erlang, :is_integer]}, _, [term]}, state) do - J.call_expression( - J.member_expression( - J.identifier("Number"), - J.identifier("isInteger") - ), - [Form.compile(term, state)] - ) - end - - def rewrite({{:., _, [:erlang, :is_list]}, _, [term]}, state) do - J.call_expression( - J.member_expression( - J.identifier("Array"), - J.identifier("isArray") - ), - [Form.compile(term, state)] - ) - end - - def rewrite({{:., _, [:erlang, :is_number]}, _, [term]}, state) do - J.binary_expression( - :||, - J.binary_expression( - :typeof, - Form.compile(term, state), - J.literal("number") - ), - J.binary_expression( - :instanceof, - Form.compile(term, state), - J.identifier("Number") - ) - ) - end - - def rewrite({{:., _, [:erlang, :is_pid]}, _, [term]}, state) do - J.binary_expression( - :instanceof, - Form.compile(term, state), - J.member_expression( - J.member_expression( - J.identifier("Bootstrap"), - J.identifier("Core") - ), - J.identifier("PID") - ) - ) - end - - def rewrite({{:., _, [:erlang, :is_port]}, _, [_term]}, state) do - J.literal(false) - end - - def rewrite({{:., _, [:erlang, :is_reference]}, _, [_term]}, state) do - J.literal(false) - end - - def rewrite({{:., _, [:erlang, :is_tuple]}, _, [term]}, state) do - J.binary_expression( - :instanceof, - Form.compile(term, state), - J.member_expression( - J.member_expression( - J.identifier("Bootstrap"), - J.identifier("Core") - ), - J.identifier("Tuple") - ) - ) - end - - def rewrite({{:., _, [:erlang, :is_map]}, _, [term]}, state) do - J.binary_expression( - :||, - J.binary_expression( - :typeof, - Form.compile(term, state), - J.literal("object") - ), - J.binary_expression( - :instanceof, - Form.compile(term, state), - J.identifier("Object") - ) - ) - end - - def rewrite({{:., _, [:erlang, :length]}, _, [list]}, state) do - J.member_expression( - Form.compile(list, state), - J.identifier("length") - ) - end - - def rewrite({{:., _, [:erlang, :make_ref]}, _, []}, state) do - J.literal(false) - end - - def rewrite({{:., _, [:erlang, :map_size]}, _, [map]}, state) do - J.member_expression( - J.call_expression( - J.member_expression( - J.identifier("Object"), - J.identifier("keys") - ), - [Form.compile(map, state)] - ), - J.identifier("length") - ) - end - - def rewrite({{:., _, [:erlang, :max]}, _, [first, second]}, state) do - J.call_expression( - J.member_expression( - J.identifier("Math"), - J.identifier("max") - ), - [Form.compile(first, state), Form.compile(second, state)] - ) - end - - def rewrite({{:., _, [:erlang, :min]}, _, [first, second]}, state) do - J.call_expression( - J.member_expression( - J.identifier("Math"), - J.identifier("min") - ), - [Form.compile(first, state), Form.compile(second, state)] - ) - end - - def rewrite({{:., _, [:erlang, :node]}, _, []}, state) do - J.identifier("nonode@nohost") - end - - def rewrite({{:., _, [:erlang, :node]}, _, [_]}, state) do - J.identifier("nonode@nohost") - end - - def rewrite({{:., _, [:erlang, :rem]}, _, [first, second]}, state) do - J.binary_expression( - :%, - Form.compile(first, state), - Form.compile(second, state) - ) - end - - def rewrite({{:., _, [:erlang, :round]}, _, [number]}, state) do - J.call_expression( - J.member_expression( - J.identifier("Math"), - J.identifier("round") - ), - [Form.compile(number, state)] - ) - end - -# def rewrite({{:., _, [:erlang, :send]}, _, [dest, msg]}, state) do -# raise ":erlang.send not supported" -# end -# -# def rewrite({{:., _, [:erlang, :self]}, _, []}, state) do -# raise ":erlang.self not supported" -# end -# -# def rewrite({{:., _, [:erlang, :spawn]}, _, [_fun]}, state) do -# raise ":erlang.spawn not supported" -# end -# -# def rewrite({{:., _, [:erlang, :spawn]}, _, [_module, _fun, _args]}, state) do -# raise ":erlang.spawn not supported" -# end -# -# def rewrite({{:., _, [:erlang, :spawn_link]}, _, [_fun]}, state) do -# raise ":erlang.spawn_link not supported" -# end -# -# def rewrite({{:., _, [:erlang, :spawn_link]}, _, [_module, _fun, _args]}, state) do -# raise ":erlang.spawn_link not supported" -# end -# -# def rewrite({{:., _, [:erlang, :spawn_monitor]}, _, [_fun]}, state) do -# raise ":erlang.spawn_monitor not supported" -# end -# -# def rewrite({{:., _, [:erlang, :spawn_monitor]}, _, [_module, _fun, _args]}, state) do -# raise ":erlang.spawn_monitor not supported" -# end - - def rewrite({{:., _, [:erlang, :throw]}, _, [term]}, state) do - J.throw_statement( - Form.compile(term, state) - ) - end - - def rewrite({{:., _, [:erlang, :tl]}, _, [list]}, state) do - J.call_expression( - J.member_expression( - Form.compile(list, state), - J.identifier("splice") - ), - [J.literal(1)] - ) - end - - def rewrite({{:., _, [:erlang, :trunc]}, _, [number]}, state) do - J.call_expression( - J.member_expression( - J.identifier("Math"), - J.identifier("floor") - ), - [Form.compile(number, state)] - ) - end - - def rewrite({{:., _, [:erlang, :tuple_size]}, _, [tuple]}, state) do - J.member_expression( - Form.compile(tuple, state), - J.identifier("length") - ) - end - - def rewrite({{:., _, [:erlang, operator]}, _, [left, right]}, state) when operator in [:+, :-, :*, :/, :<, :>, :>=, :==] do - J.binary_expression( - operator, - Form.compile(left, state), - Form.compile(right, state) - ) - end - - def rewrite({{:., _, [:erlang, operator]}, _, [value]}, state) when operator in [:+, :-] do - J.unary_expression( - operator, - true, - Form.compile(value, state) - ) - end - - def rewrite({{:., _, [:erlang, :++]}, _, [left, right]}, state) do - J.call_expression( - J.member_expression( - Form.compile(left, state), - J.identifier("concat") - ), - [Form.compile(right, state)] - ) - end - - def rewrite({{:., _, [:erlang, :--]}, _, [list, element]}, state) do - J.call_expression( - J.member_expression( - Form.compile(list, state), - J.identifier("slice") - ), - [ - J.binary_expression( - :+, - J.call_expression( - J.member_expression( - Form.compile(list, state), - J.identifier("indexOf") - ), - [Form.compile(element, state)] - ), - J.literal(1) - ) - ] - ) - end - - def rewrite({{:., _, [:erlang, :not]}, _, [value]}, state) do - J.unary_expression( - :!, - true, - Form.compile(value, state) - ) - end - - def rewrite({{:., _, [:erlang, :"=<"]}, _, [left, right]}, state) do - J.binary_expression( - :<=, - Form.compile(left, state), - Form.compile(right, state) - ) - end - - def rewrite({{:., _, [:erlang, :"/="]}, _, [left, right]}, state) do - J.binary_expression( - :!=, - Form.compile(left, state), - Form.compile(right, state) - ) - end - - def rewrite({{:., _, [:erlang, :"=:="]}, _, [left, right]}, state) do - J.binary_expression( - :===, - Form.compile(left, state), - Form.compile(right, state) - ) - end - - def rewrite({{:., _, [:erlang, :"=/="]}, _, [left, right]}, state) do - J.binary_expression( - :!==, - Form.compile(left, state), - Form.compile(right, state) - ) - end - - def rewrite({{:., _, [:erlang, :element]}, _, [index, tuple]}, state) do - J.call_expression( - J.member_expression( - Form.compile(tuple, state), - J.identifier("get") - ), - [ - J.binary_expression( - :-, - Form.compile(index, state), - J.literal(1) - ) - ] - ) - end - - def rewrite({{:., _, [:erlang, :setelement]}, _, [index, tuple, value]}, state) do - J.call_expression( - J.member_expression( - Form.compile(tuple, state), - J.identifier("put_elem") - ), - [ - J.binary_expression( - :-, - Form.compile(index, state), - J.literal(1) - ), - Form.compile(value, state) - ] - ) - end - - def rewrite({{:., _, [:erlang, :orelse]}, _, [left, right]}, state) do - J.binary_expression( - :||, - Form.compile(left, state), - Form.compile(right, state) - ) - end - - def rewrite({{:., _, [:erlang, :or]}, _, [left, right]}, state) do - J.binary_expression( - :||, - Form.compile(left, state), - Form.compile(right, state) - ) - end - - def rewrite({{:., _, [:erlang, :andalso]}, _, [left, right]}, state) do - J.binary_expression( - :&&, - Form.compile(left, state), - Form.compile(right, state) - ) - end - - def rewrite({{:., _, [:erlang, :error]}, _, [error]}, state) do - J.throw_statement( - Form.compile(error, state) - ) - end - - def rewrite({{:., _, [:erlang, :raise]}, _, [_class, reason, _stacktrace]}, state) do - J.throw_statement( - Form.compile(reason, state) - ) - end - - def rewrite({{:., _, [:erlang, :atom_to_binary]}, _, [atom, _]}, state) do - J.call_expression( - J.member_expression( - J.identifier("Symbol"), - J.identifier("keyFor") - ), - [Form.compile(atom, state)] - ) - end - - def rewrite({{:., _, [:erlang, :atom_to_list]}, _, [atom]}, state) do - J.call_expression( - J.member_expression( - J.call_expression( - J.member_expression( - J.identifier("Symbol"), - J.identifier("keyFor") - ), - [Form.compile(atom, state)] - ), - J.identifier("split") - ), - [J.literal("")] - ) - end - - def rewrite({{:., _, [:erlang, :bnot]}, _, [expr]}, state) do - J.unary_expression( - :"~", - true, - Form.compile(expr, state) - ) - end - - def rewrite({{:., _, [:erlang, :band]}, _, [left, right]}, state) do - J.binary_expression( - :&, - Form.compile(left, state), - Form.compile(right, state) - ) - end - - def rewrite({{:., _, [:erlang, :bor]}, _, [left, right]}, state) do - J.binary_expression( - :|, - Form.compile(left, state), - Form.compile(right, state) - ) - end - - def rewrite({{:., _, [:erlang, :bxor]}, _, [left, right]}, state) do - J.binary_expression( - :^, - Form.compile(left, state), - Form.compile(right, state) - ) - end - - def rewrite({{:., _, [:erlang, :bsl]}, _, [left, right]}, state) do - J.binary_expression( - :"<<", - Form.compile(left, state), - Form.compile(right, state) - ) - end - - def rewrite({{:., _, [:erlang, :bsr]}, _, [left, right]}, state) do - J.binary_expression( - :">>", - Form.compile(left, state), - Form.compile(right, state) - ) - end - - def rewrite({{:., _, [:erlang, :function_exported]}, _, [_, _, _]}, state) do - J.literal(true) - end - - def rewrite({{:., _, [:erlang, :make_tuple]}, _, [size, data]}, state) do - J.new_expression( - J.member_expression( - J.member_expression( - J.identifier("Bootstrap"), - J.identifier("Core") - ), - J.identifier("Tuple") - ), - [] - ) - end - - def rewrite({{:., _, [:erlang, :insert_element]}, _, [index, tuple, term]}, state) do - J.call_expression( - J.member_expression( - Form.compile(tuple, state), - J.identifier("put_elem") - ), - [ - J.binary_expression( - :-, - Form.compile(index, state), - J.literal(1) - ), - Form.compile(term, state) - ] - ) - end - - def rewrite({{:., _, [:erlang, :tuple_to_list]}, _, [tuple]}, state) do - J.member_expression( - Form.compile(tuple, state), - J.identifier("values") - ) - end - - def rewrite({{:., _, [:erlang, :append_element]}, _, [tuple, value]}, state) do - J.call_expression( - J.member_expression( - Form.compile(tuple, state), - J.identifier("put_elem") - ), - [ - J.member_expression( - Form.compile(tuple, state), - J.identifier("length") - ), - Form.compile(value, state) - ] - ) - end - - def rewrite({{:., _, [:erlang, :delete_element]}, _, [index, tuple]}, state) do - J.call_expression( - J.member_expression( - Form.compile(tuple, state), - J.identifier("remove_elem") - ), - [Form.compile(index, state)] - ) - end - - def rewrite({{:., _, [:erlang, :binary_to_atom]}, _, [binary, _]}, state) do - J.call_expression( - J.member_expression( - J.identifier("Symbol"), - J.identifier("for") - ), - [Form.compile(binary, state)] - ) - end - - def rewrite({{:., _, [:erlang, :binary_to_existing_atom]}, _, [binary, _]}, state) do - J.call_expression( - J.member_expression( - J.identifier("Symbol"), - J.identifier("for") - ), - [Form.compile(binary, state)] - ) - end - - def rewrite({{:., _, [:erlang, :list_to_atom]}, _, [char_list]}, state) do - J.call_expression( - J.member_expression( - J.identifier("Symbol"), - J.identifier("for") - ), - [Form.compile(char_list, state)] - ) - end - - def rewrite({{:., _, [:erlang, :list_to_existing_atom]}, _, [char_list]}, state) do - J.call_expression( - J.member_expression( - J.identifier("Symbol"), - J.identifier("for") - ), - [Form.compile(char_list, state)] - ) - end - - def rewrite({{:., _, [:erlang, :list_to_tuple]}, _, [list]}, state) do - J.new_expression( - J.member_expression( - J.member_expression( - J.identifier("Bootstrap"), - J.identifier("Core") - ), - J.identifier("Tuple") - ), - [ - J.rest_element( - Form.compile(list, state) - ) - ] - ) - end - - def rewrite({{:., _, [:erlang, :list_to_float]}, _, [list]}, state) do - J.call_expression( - J.identifier("parseFloat"), - [Form.compile(list, state)] - ) - end - - def rewrite({{:., _, [:erlang, :list_to_integer]}, _, [list]}, state) do - J.call_expression( - J.identifier("parseInt"), - [Form.compile(list, state)] - ) - end - - def rewrite({{:., _, [:erlang, :list_to_integer]}, _, [list, base]}, state) do - J.call_expression( - J.identifier("parseInt"), - [Form.compile(list, state), Form.compile(base, state)] - ) - end - - def rewrite({{:., _, [:erlang, :integer_to_binary]}, _, [integer]}, state) do - J.call_expression( - J.member_expression( - Form.compile(integer, state), - J.identifier("toString") - ), - [] - ) - end - - def rewrite({{:., _, [:erlang, :integer_to_binary]}, _, [integer, base]}, state) do - J.call_expression( - J.member_expression( - Form.compile(integer, state), - J.identifier("toString") - ), - [Form.compile(base, state)] - ) - end - - def rewrite({{:., _, [:erlang, :integer_to_list]}, _, [integer]}, state) do - J.call_expression( - J.member_expression( - Form.compile(integer, state), - J.identifier("toString") - ), - [] - ) - end - - def rewrite({{:., _, [:erlang, :integer_to_list]}, _, [integer, base]}, state) do - J.call_expression( - J.member_expression( - Form.compile(integer, state), - J.identifier("toString") - ), - [Form.compile(base, state)] - ) - end - - def rewrite({{:., _, [:erlang, :float_to_binary]}, _, [float]}, state) do - J.call_expression( - J.member_expression( - Form.compile(float, state), - J.identifier("toString") - ), - [] - ) - end - - def rewrite({{:., _, [:erlang, :float_to_binary]}, _, [float, base]}, state) do - J.call_expression( - J.member_expression( - Form.compile(float, state), - J.identifier("toString") - ), - [Form.compile(base, state)] - ) - end - - def rewrite({{:., _, [:erlang, :float_to_list]}, _, [float]}, state) do - J.call_expression( - J.member_expression( - Form.compile(float, state), - J.identifier("toString") - ), - [] - ) - end - - def rewrite({{:., _, [:erlang, :float_to_list]}, _, [float, base]}, state) do - J.call_expression( - J.member_expression( - Form.compile(float, state), - J.identifier("toString") - ), - [Form.compile(base, state)] - ) - end - - def rewrite({{:., _, [:erlang, :binary_to_float]}, _, [binary]}, state) do - J.call_expression( - J.identifier("parseFloat"), - [Form.compile(binary, state)] - ) - end - - def rewrite({{:., _, [:erlang, :binary_to_integer]}, _, [binary]}, state) do - J.call_expression( - J.identifier("parseInt"), - [Form.compile(binary, state)] - ) - end - - def rewrite({{:., _, [:erlang, :binary_to_integer]}, _, [binary, base]}, state) do - J.call_expression( - J.identifier("parseInt"), - [Form.compile(binary, state), Form.compile(base, state)] - ) - end - - def rewrite({{:., _, [:erlang, _]}, _, _}, state) do - J.call_expression( - J.identifier("toString"), - [] - ) - end - -end diff --git a/lib/elixir_script/next/passes/translate/functions/lists.ex b/lib/elixir_script/next/passes/translate/functions/lists.ex deleted file mode 100644 index db2d7d73..00000000 --- a/lib/elixir_script/next/passes/translate/functions/lists.ex +++ /dev/null @@ -1,178 +0,0 @@ -defmodule ElixirScript.Translate.Functions.Lists do - @moduledoc false - alias ESTree.Tools.Builder, as: J - alias ElixirScript.Translate.Form - - def rewrite({{:., _, [:lists, :map]}, _, [fun, list]}, state) do - J.call_expression( - J.member_expression( - Form.compile(list, state), - J.identifier("map") - ), - [Form.compile(fun, state)] - ) - end - - def rewrite({{:., _, [:lists, :member]}, _, [elem, list]}, state) do - J.binary_expression( - :>, - J.call_expression( - J.member_expression( - Form.compile(list, state), - J.identifier("indexOf") - ), - [Form.compile(elem, state)] - ), - J.unary_expression( - :-, - true, - J.literal(1) - ) - ) - end - - def rewrite({{:., _, [:lists, :reverse]}, _, [list]}, state) do - J.call_expression( - J.member_expression( - J.call_expression( - J.member_expression( - Form.compile(list, state), - J.identifier("concat") - ), - [J.array_expression([])] - ), - J.identifier("reverse") - ), - [] - ) - end - - def rewrite({{:., _, [:lists, :reverse]}, _, [list, tail]}, state) do - J.call_expression( - J.member_expression( - J.call_expression( - J.member_expression( - J.call_expression( - J.member_expression( - Form.compile(list, state), - J.identifier("concat") - ), - [J.array_expression([])] - ), - J.identifier("reverse") - ), - [] - ), - J.identifier("concat") - ), - [Form.compile(tail, state)] - ) - end - - def rewrite({{:., _, [:lists, :sort]}, _, [list]}, state) do - J.call_expression( - J.member_expression( - J.call_expression( - J.member_expression( - Form.compile(list, state), - J.identifier("concat") - ), - [J.array_expression([])] - ), - J.identifier("sort") - ), - [] - ) - end - - def rewrite({{:., _, [:lists, :filter]}, _, [pred, list]}, state) do - J.call_expression( - J.member_expression( - Form.compile(list, state), - J.identifier("filter") - ), - [Form.compile(pred, state)] - ) - end - - def rewrite({{:., _, [:lists, :delete]}, _, [elem, list]}, state) do - J.call_expression( - J.member_expression( - J.member_expression( - J.member_expression( - J.identifier("Bootstrap"), - J.identifier("Core") - ), - J.identifier("Functions") - ), - J.identifier("remove_from_list") - ), - [Form.compile(list, state), Form.compile(elem, state)] - ) - end - - def rewrite({{:., _, [:lists, _]}, _, [elem, list]}, state) do - J.call_expression( - J.member_expression( - J.member_expression( - J.member_expression( - J.identifier("Bootstrap"), - J.identifier("Core") - ), - J.identifier("Functions") - ), - J.identifier("remove_from_list") - ), - [Form.compile(list, state), Form.compile(elem, state)] - ) - end - - def rewrite({{:., _, [:lists, _]}, _, [elem, list, _, _]}, state) do - J.call_expression( - J.member_expression( - J.member_expression( - J.member_expression( - J.identifier("Bootstrap"), - J.identifier("Core") - ), - J.identifier("Functions") - ), - J.identifier("remove_from_list") - ), - [Form.compile(list, state), Form.compile(elem, state)] - ) - end - - def rewrite({{:., _, [:lists, _]}, _, [elem, list, _]}, state) do - J.call_expression( - J.member_expression( - J.member_expression( - J.member_expression( - J.identifier("Bootstrap"), - J.identifier("Core") - ), - J.identifier("Functions") - ), - J.identifier("remove_from_list") - ), - [Form.compile(list, state), Form.compile(elem, state)] - ) - end - - def rewrite({{:., _, [:lists, _]}, _, [list]}, state) do - J.call_expression( - J.member_expression( - J.call_expression( - J.member_expression( - Form.compile(list, state), - J.identifier("concat") - ), - [J.array_expression([])] - ), - J.identifier("reverse") - ), - [] - ) - end - -end diff --git a/lib/elixir_script/next/passes/translate/functions/maps.ex b/lib/elixir_script/next/passes/translate/functions/maps.ex deleted file mode 100644 index 2db82ecf..00000000 --- a/lib/elixir_script/next/passes/translate/functions/maps.ex +++ /dev/null @@ -1,85 +0,0 @@ -defmodule ElixirScript.Translate.Functions.Maps do - @moduledoc false - alias ESTree.Tools.Builder, as: J - alias ElixirScript.Translate.Form - - def rewrite({{:., _, [:maps, :update]}, _, [key, value, map]}, state) do - J.call_expression( - J.member_expression( - J.member_expression( - J.member_expression( - J.identifier("Bootstrap"), - J.identifier("Core") - ), - J.identifier("Functions") - ), - J.identifier("update_map") - ), - [Form.compile(map, state), Form.compile(key, state), Form.compile(value, state)] - ) - end - - def rewrite({{:., _, [:maps, :find]}, _, [key, map]}, state) do - J.call_expression( - J.member_expression( - J.member_expression( - J.member_expression( - J.identifier("Bootstrap"), - J.identifier("Core") - ), - J.identifier("Functions") - ), - J.identifier("update_map") - ), - [Form.compile(key, state), Form.compile(map, state)] - ) - end - - def rewrite({{:., _, [:maps, :put]}, _, [key, map, _]}, state) do - J.call_expression( - J.member_expression( - J.member_expression( - J.member_expression( - J.identifier("Bootstrap"), - J.identifier("Core") - ), - J.identifier("Functions") - ), - J.identifier("update_map") - ), - [Form.compile(key, state), Form.compile(map, state)] - ) - end - - def rewrite({{:., _, [:maps, :is_key]}, _, [key, map]}, state) do - J.call_expression( - J.member_expression( - J.member_expression( - J.member_expression( - J.identifier("Bootstrap"), - J.identifier("Core") - ), - J.identifier("Functions") - ), - J.identifier("update_map") - ), - [Form.compile(key, state), Form.compile(map, state)] - ) - end - - def rewrite({{:., _, [:maps, _]}, _, _}, state) do - J.call_expression( - J.member_expression( - J.member_expression( - J.member_expression( - J.identifier("Bootstrap"), - J.identifier("Core") - ), - J.identifier("Functions") - ), - J.identifier("update_map") - ), - [] - ) - end -end diff --git a/src/javascript/lib/core.js b/src/javascript/lib/core.js index 366a6a6a..bacfe6fe 100644 --- a/src/javascript/lib/core.js +++ b/src/javascript/lib/core.js @@ -2,6 +2,9 @@ import Patterns from 'tailored'; import ErlangTypes from 'erlang-types'; import Functions from './core/functions'; import SpecialForms from './core/special_forms'; +import erlang from './core/erlang_compat/erlang'; +import maps from './core/erlang_compat/maps'; +import lists from './core/erlang_compat/lists'; class Integer {} class Float {} @@ -34,4 +37,7 @@ export default { Functions, SpecialForms, global: globalState, + erlang, + maps, + lists, }; diff --git a/src/javascript/lib/core/erlang_compat/erlang.js b/src/javascript/lib/core/erlang_compat/erlang.js new file mode 100644 index 00000000..ff8b4c56 --- /dev/null +++ b/src/javascript/lib/core/erlang_compat/erlang.js @@ -0,0 +1 @@ +export default {}; diff --git a/src/javascript/lib/core/erlang_compat/lists.js b/src/javascript/lib/core/erlang_compat/lists.js new file mode 100644 index 00000000..ff8b4c56 --- /dev/null +++ b/src/javascript/lib/core/erlang_compat/lists.js @@ -0,0 +1 @@ +export default {}; diff --git a/src/javascript/lib/core/erlang_compat/maps.js b/src/javascript/lib/core/erlang_compat/maps.js new file mode 100644 index 00000000..ff8b4c56 --- /dev/null +++ b/src/javascript/lib/core/erlang_compat/maps.js @@ -0,0 +1 @@ +export default {}; From 73f313583a6e19cfa119070da4c4e67d8d100603 Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Sun, 28 May 2017 08:46:53 -0500 Subject: [PATCH 097/418] Remove references to experimental backend --- .tool-versions | 2 +- README.md | 3 +- lib/elixir_script/next/beam.ex | 2 + lib/elixir_script/next/passes/find_used.ex | 37 +++++++++++-------- lib/elixir_script/next/passes/translate.ex | 2 +- .../next/passes/translate/examples/example.ex | 6 +-- .../next/passes/translate/examples/size.ex | 6 --- .../next/passes/translate/module.ex | 10 ++++- .../lib/core/erlang_compat/erlang.js | 2 + .../lib/core/erlang_compat/lists.js | 2 + src/javascript/lib/core/erlang_compat/maps.js | 2 + 11 files changed, 43 insertions(+), 31 deletions(-) diff --git a/.tool-versions b/.tool-versions index 09178de1..d588b60f 100644 --- a/.tool-versions +++ b/.tool-versions @@ -1,3 +1,3 @@ erlang ref-OTP-20.0-rc1 -elixir ref-9825280 +elixir ref-9873e42 nodejs 7.10.0 \ No newline at end of file diff --git a/README.md b/README.md index 41d5886b..300f89b5 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,8 @@ The goal is to convert a subset (or full set) of Elixir code to JavaScript, prov Requirements =========== -* Elixir +* Erlang 20 or greater +* Elixir 1.5 or greater * Node (only for development) Usage diff --git a/lib/elixir_script/next/beam.ex b/lib/elixir_script/next/beam.ex index c6183758..7660eaa0 100644 --- a/lib/elixir_script/next/beam.ex +++ b/lib/elixir_script/next/beam.ex @@ -23,6 +23,8 @@ defmodule ElixirScript.Beam do {:error, "Unknown module"} {:error,:beam_lib,{:unknown_chunk,"non_existing.beam",:debug_info}} -> {:error, "Unsupported version of Erlang"} + {:error,:beam_lib,{:missing_chunk, _ , _}} -> + {:error, "Debug info not available"} {:error,:beam_lib,{:file_error,"non_existing.beam",:enoent}} -> {:error, "Debug info not available"} end diff --git a/lib/elixir_script/next/passes/find_used.ex b/lib/elixir_script/next/passes/find_used.ex index 8a19d9e6..07cde8f0 100644 --- a/lib/elixir_script/next/passes/find_used.ex +++ b/lib/elixir_script/next/passes/find_used.ex @@ -2,6 +2,19 @@ defmodule ElixirScript.FindUsed do @moduledoc false alias ElixirScript.State, as: ModuleState + @erlang_modules [ + :erlang, + :maps, + :lists, + :gen, + :elixir_errors, + :supervisor, + :application, + :code, + :elixir_utils, + :file + ] + @doc """ Takes a list of entry modules and finds modules they use along with documenting the functions used. The data collected about used functions @@ -127,7 +140,8 @@ defmodule ElixirScript.FindUsed do do_execute(module, state.pid) end end - Enum.each(params, &walk(&1, state)) + + walk(params, state) end defp walk({:for, _, generators}, state) do @@ -181,11 +195,11 @@ defmodule ElixirScript.FindUsed do if rescue_block do Enum.each(rescue_block, fn - {:->, _, [ [{:in, _, [param, names]}], body]} -> - walk({[], [param], [{{:., [], [Enum, :member?]}, [], [param, names]}], body}, state) - {:->, _, [ [param], body]} -> - walk({[], [param], [], body}, state) - end) + {:->, _, [ [{:in, _, [param, names]}], body]} -> + walk({[], [param], [{{:., [], [Enum, :member?]}, [], [param, names]}], body}, state) + {:->, _, [ [param], body]} -> + walk({[], [param], [], body}, state) + end) end if catch_block do @@ -205,15 +219,8 @@ defmodule ElixirScript.FindUsed do Enum.each(clauses, &walk(&1, state)) end - defp walk({{:., _, [:erlang, _]}, _, _}, _state) do - nil - end - - defp walk({{:., _, [:lists, _]}, _, _}, _state) do - nil - end - - defp walk({{:., _, [:maps, _]}, _, _}, _state) do + defp walk({{:., _, [module, function]}, _, params}, _state) when module in @erlang_modules do + IO.inspect {module, function, length(params)} nil end diff --git a/lib/elixir_script/next/passes/translate.ex b/lib/elixir_script/next/passes/translate.ex index 5319086a..8d1660d7 100644 --- a/lib/elixir_script/next/passes/translate.ex +++ b/lib/elixir_script/next/passes/translate.ex @@ -40,7 +40,7 @@ defmodule ElixirScript.Translate do |> Generator.generate concat(js_code) - |> IO.puts + #|> IO.puts end defp concat(code) do diff --git a/lib/elixir_script/next/passes/translate/examples/example.ex b/lib/elixir_script/next/passes/translate/examples/example.ex index 677bf0f8..cc1dfdf0 100644 --- a/lib/elixir_script/next/passes/translate/examples/example.ex +++ b/lib/elixir_script/next/passes/translate/examples/example.ex @@ -1,10 +1,6 @@ defmodule Example do def new() do - newnew() - end - - def newnew() do - Atom.to_string("hello") + Base.encode16("hello") end end diff --git a/lib/elixir_script/next/passes/translate/examples/size.ex b/lib/elixir_script/next/passes/translate/examples/size.ex index d2a2619d..10dadd44 100644 --- a/lib/elixir_script/next/passes/translate/examples/size.ex +++ b/lib/elixir_script/next/passes/translate/examples/size.ex @@ -1,22 +1,16 @@ defprotocol Example.Size do - @compile {:undocumented_elixir_backend_option, ElixirScript.Translate.Backend} def size(data) end defimpl Example.Size, for: BitString do - @compile {:undocumented_elixir_backend_option, ElixirScript.Translate.Backend} def size(string), do: byte_size(string) end defimpl Example.Size, for: Map do - @compile {:undocumented_elixir_backend_option, ElixirScript.Translate.Backend} - def size(map), do: map_size(map) end defimpl Example.Size, for: Tuple do - @compile {:undocumented_elixir_backend_option, ElixirScript.Translate.Backend} - def size(tuple), do: tuple_size(tuple) end \ No newline at end of file diff --git a/lib/elixir_script/next/passes/translate/module.ex b/lib/elixir_script/next/passes/translate/module.ex index dd5b142b..04daa366 100644 --- a/lib/elixir_script/next/passes/translate/module.ex +++ b/lib/elixir_script/next/passes/translate/module.ex @@ -17,7 +17,7 @@ defmodule ElixirScript.Translate.Module do file: _file, line: _line, module: ^module, - unreachable: _unreachable, + unreachable: unreachable, used: used } = info @@ -27,7 +27,13 @@ defmodule ElixirScript.Translate.Module do # Filter so that we only have the # Used functions to compile - used_defs = Enum.filter(defs, fn + used_defs = defs + |> Enum.filter(fn + { _, type, _, _} when type in [:defmacro, :defmacrop] -> false + { name, _, _, _} -> not(name in unreachable) + _ -> true + end) + |> Enum.filter(fn { name, _, _, _} -> name in used _ -> false end) diff --git a/src/javascript/lib/core/erlang_compat/erlang.js b/src/javascript/lib/core/erlang_compat/erlang.js index ff8b4c56..d1b75509 100644 --- a/src/javascript/lib/core/erlang_compat/erlang.js +++ b/src/javascript/lib/core/erlang_compat/erlang.js @@ -1 +1,3 @@ +// http://erlang.org/doc/man/erlang.html + export default {}; diff --git a/src/javascript/lib/core/erlang_compat/lists.js b/src/javascript/lib/core/erlang_compat/lists.js index ff8b4c56..245b967c 100644 --- a/src/javascript/lib/core/erlang_compat/lists.js +++ b/src/javascript/lib/core/erlang_compat/lists.js @@ -1 +1,3 @@ +// http://erlang.org/doc/man/lists.html + export default {}; diff --git a/src/javascript/lib/core/erlang_compat/maps.js b/src/javascript/lib/core/erlang_compat/maps.js index ff8b4c56..f7269751 100644 --- a/src/javascript/lib/core/erlang_compat/maps.js +++ b/src/javascript/lib/core/erlang_compat/maps.js @@ -1 +1,3 @@ +// http://erlang.org/doc/man/maps.html + export default {}; From 030fb4d37aa7e55353c1e2c2b91fb3d043f2fbd0 Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Sun, 28 May 2017 11:07:55 -0500 Subject: [PATCH 098/418] Switch to ava for JavaScript testing. Add some implementations and tests for erlang compat. Add new pass to compiler for handling output --- .gitignore | 1 + lib/elixir_script/compile_error.ex | 3 + .../elixir_script_compile_error.ex | 3 - lib/elixir_script/next/beam.ex | 3 +- lib/elixir_script/next/compiler.ex | 15 +- lib/elixir_script/next/passes/output.ex | 74 + lib/elixir_script/next/passes/translate.ex | 46 - .../next/passes/translate/examples/example.ex | 4 +- .../next/passes/translate/form.ex | 4 +- .../next/passes/translate/module.ex | 1 + lib/elixir_script/passes/create_js_modules.ex | 2 +- lib/mix/tasks/compile.elixir_script.ex | 2 +- package.json | 21 +- .../lib/core/erlang_compat/erlang.js | 12 +- .../lib/core/erlang_compat/lists.js | 8 +- src/javascript/lib/core/erlang_compat/maps.js | 34 +- src/javascript/tests/case.spec.js | 51 +- src/javascript/tests/cond.spec.js | 21 +- .../tests/core/erlang_compat/erlang_spec.js | 15 + .../tests/core/erlang_compat/lists_spec.js | 6 + .../tests/core/erlang_compat/maps_spec.js | 22 + src/javascript/tests/core/functions.spec.js | 24 +- src/javascript/tests/for.spec.js | 179 +- src/javascript/tests/try.spec.js | 56 +- src/javascript/tests/with.spec.js | 152 +- test/app/spec/atom.spec.js | 14 - test/app/spec/bootstrap/functions.spec.js | 29 - test/app/spec/enum.spec.js | 126 - test/app/spec/exception.spec.js | 39 - test/app/spec/integer.spec.js | 53 - test/app/spec/main.spec.js | 24 +- test/app/spec/setup.spec.js | 15 - test/app/spec/struct.spec.js | 36 - test/app/spec/tuple.spec.js | 29 - yarn.lock | 2522 +++++++++++++++-- 35 files changed, 2803 insertions(+), 843 deletions(-) create mode 100644 lib/elixir_script/compile_error.ex delete mode 100644 lib/elixir_script/elixir_script_compile_error.ex create mode 100644 lib/elixir_script/next/passes/output.ex create mode 100644 src/javascript/tests/core/erlang_compat/erlang_spec.js create mode 100644 src/javascript/tests/core/erlang_compat/lists_spec.js create mode 100644 src/javascript/tests/core/erlang_compat/maps_spec.js delete mode 100644 test/app/spec/atom.spec.js delete mode 100644 test/app/spec/bootstrap/functions.spec.js delete mode 100644 test/app/spec/enum.spec.js delete mode 100644 test/app/spec/exception.spec.js delete mode 100644 test/app/spec/integer.spec.js delete mode 100644 test/app/spec/setup.spec.js delete mode 100644 test/app/spec/struct.spec.js delete mode 100644 test/app/spec/tuple.spec.js diff --git a/.gitignore b/.gitignore index 6eea78e1..382f0cac 100644 --- a/.gitignore +++ b/.gitignore @@ -19,4 +19,5 @@ src/elixirscript priv/**/*.js stdlib_state.bin *.log +.nyc_output test/app/build diff --git a/lib/elixir_script/compile_error.ex b/lib/elixir_script/compile_error.ex new file mode 100644 index 00000000..fea01237 --- /dev/null +++ b/lib/elixir_script/compile_error.ex @@ -0,0 +1,3 @@ +defmodule ElixirScript.CompileError do + defexception [:message] +end diff --git a/lib/elixir_script/elixir_script_compile_error.ex b/lib/elixir_script/elixir_script_compile_error.ex deleted file mode 100644 index 978d1d84..00000000 --- a/lib/elixir_script/elixir_script_compile_error.ex +++ /dev/null @@ -1,3 +0,0 @@ -defmodule ElixirScriptCompileError do - defexception [:message] -end diff --git a/lib/elixir_script/next/beam.ex b/lib/elixir_script/next/beam.ex index 7660eaa0..d9838c28 100644 --- a/lib/elixir_script/next/beam.ex +++ b/lib/elixir_script/next/beam.ex @@ -9,7 +9,8 @@ defmodule ElixirScript.Beam do """ @spec debug_info(atom) :: {:ok | :error, map | binary} def debug_info(module) when is_atom(module) do - with {_, beam, _} <- :code.get_object_code(module), + #TODO: Get modified date from _beam_path to check for cached version? + with {_, beam, _beam_path} <- :code.get_object_code(module), {:ok, {^module, [debug_info: {:debug_info_v1, backend, data}]}} <- :beam_lib.chunks(beam, [:debug_info]), {:ok, {^module, attribute_info}} = :beam_lib.chunks(beam, [:attributes]) do diff --git a/lib/elixir_script/next/compiler.ex b/lib/elixir_script/next/compiler.ex index 864fa645..0fa7bb21 100644 --- a/lib/elixir_script/next/compiler.ex +++ b/lib/elixir_script/next/compiler.ex @@ -5,7 +5,7 @@ defmodule ElixirScript.Compiler do @spec compile([atom], []) :: nil def compile(entry_modules, opts \\ []) do - opts = build_compiler_options(opts) + opts = build_compiler_options(opts, entry_modules) {:ok, pid} = ElixirScript.State.start_link(opts) IO.puts "Finding used modules and functions" @@ -15,19 +15,24 @@ defmodule ElixirScript.Compiler do IO.puts "Compiling" modules = ElixirScript.State.list_modules(pid) - ElixirScript.Translate.execute(modules, pid) + + IO.puts "Building Output" + modules = ElixirScript.State.list_modules(pid) + ElixirScript.Output.execute(modules, pid) ElixirScript.State.stop(pid) end - defp build_compiler_options(opts) do + defp build_compiler_options(opts, entry_modules) do default_options = Map.new - |> Map.put(:output, nil) - |> Map.put(:format, :es) + |> Map.put(:output, Keyword.get(opts, :output)) + |> Map.put(:format, Keyword.get(opts, :format, :es)) |> Map.put(:js_modules, Keyword.get(opts, :js_modules, [])) + |> Map.put(:entry_modules, entry_modules) options = default_options + IO.inspect options Map.put(options, :module_formatter, get_module_formatter(options[:format])) end diff --git a/lib/elixir_script/next/passes/output.ex b/lib/elixir_script/next/passes/output.ex new file mode 100644 index 00000000..f2cdd164 --- /dev/null +++ b/lib/elixir_script/next/passes/output.ex @@ -0,0 +1,74 @@ +defmodule ElixirScript.Output do + @moduledoc false + + alias ElixirScript.State, as: ModuleState + alias ESTree.Tools.{Builder, Generator} + @generated_name "Elixir.App.js" + + @doc """ + Takes outputs the JavaScript code in the specified output + """ + @spec execute([atom], pid) :: nil + def execute(modules, pid) do + modules = Enum.filter_map(modules, fn {_, info} -> Map.has_key?(info, :js_ast) end, + fn {_module, info} -> + info.js_ast + end + ) + + opts = ModuleState.get_compiler_opts(pid) + + bundle(modules, opts) + |> output(Map.get(opts, :output)) + end + + defp bundle(modules, opts) do + ElixirScript.Passes.CreateJSModules.compile(modules, opts) + + js_code = modules + |> ElixirScript.Passes.CreateJSModules.compile(opts) + |> List.wrap + |> Builder.program + |> prepare_js_ast + |> Generator.generate + + concat(js_code) + end + + defp concat(code) do + "'use strict';\n" <> ElixirScript.get_bootstrap_js("iife") <> "\n" <> code + end + + defp prepare_js_ast(js_ast) do + case js_ast do + modules when is_list(modules) -> + modules + |> Enum.reduce([], &(&2 ++ &1.body)) + |> Builder.program + %ElixirScript.Translator.Group{body: body} -> + Builder.program(body) + %ElixirScript.Translator.Empty{} -> + Builder.program([]) + _ -> + js_ast + end + end + + defp output(code, nil), do: code + defp output(code, :stdout), do: IO.puts(code) + + defp output(code, path) do + file_name = case Path.extname(path) do + ".js" -> + path + _ -> + Path.join([path, @generated_name]) + end + + if !File.exists?(Path.dirname(file_name)) do + File.mkdir_p!(Path.dirname(file_name)) + end + + File.write!(file_name, code) + end +end \ No newline at end of file diff --git a/lib/elixir_script/next/passes/translate.ex b/lib/elixir_script/next/passes/translate.ex index 8d1660d7..b32a05bb 100644 --- a/lib/elixir_script/next/passes/translate.ex +++ b/lib/elixir_script/next/passes/translate.ex @@ -14,51 +14,5 @@ defmodule ElixirScript.Translate do Enum.each(modules, fn({module, info}) -> ElixirScript.Translate.Module.compile(module, info, pid) end) - - modules = ElixirScript.State.list_modules(pid) - - modules = Enum.filter_map(modules, - fn {_, info} -> Map.has_key?(info, :js_ast) end, - fn {_module, info} -> - info.js_ast - end - ) - - opts = ModuleState.get_compiler_opts(pid) - - bundle(modules, opts) - end - - defp bundle(modules, opts) do - ElixirScript.Passes.CreateJSModules.compile(modules, opts) - - js_code = modules - |> ElixirScript.Passes.CreateJSModules.compile(opts) - |> List.wrap - |> Builder.program - |> prepare_js_ast - |> Generator.generate - - concat(js_code) - #|> IO.puts - end - - defp concat(code) do - "'use strict';\n" <> ElixirScript.get_bootstrap_js("iife") <> "\n" <> code - end - - defp prepare_js_ast(js_ast) do - case js_ast do - modules when is_list(modules) -> - modules - |> Enum.reduce([], &(&2 ++ &1.body)) - |> Builder.program - %ElixirScript.Translator.Group{body: body} -> - Builder.program(body) - %ElixirScript.Translator.Empty{} -> - Builder.program([]) - _ -> - js_ast - end end end diff --git a/lib/elixir_script/next/passes/translate/examples/example.ex b/lib/elixir_script/next/passes/translate/examples/example.ex index cc1dfdf0..02f457a1 100644 --- a/lib/elixir_script/next/passes/translate/examples/example.ex +++ b/lib/elixir_script/next/passes/translate/examples/example.ex @@ -1,6 +1,6 @@ defmodule Example do - def new() do - Base.encode16("hello") + def start(_, _) do + Atom.to_string(:gravity) end end diff --git a/lib/elixir_script/next/passes/translate/form.ex b/lib/elixir_script/next/passes/translate/form.ex index 5d69280a..b8f3952b 100644 --- a/lib/elixir_script/next/passes/translate/form.ex +++ b/lib/elixir_script/next/passes/translate/form.ex @@ -122,7 +122,7 @@ defmodule ElixirScript.Translate.Form do def compile({:receive, context, _}, _state) do line = Keyword.get(context, :line, 1) - raise ElixirScriptCompileError, message: "Line: #{line} receive not supported" + raise ElixirScript.CompileError, message: "Line: #{line} receive not supported" end def compile({:try, _, [blocks]}, state) do @@ -149,7 +149,7 @@ defmodule ElixirScript.Translate.Form do ), J.identifier(module) ), - J.identifier(function) + ElixirScript.Translator.Identifier.make_function_name(function, length(params)) ), Enum.map(params, &compile(&1, state)) ) diff --git a/lib/elixir_script/next/passes/translate/module.ex b/lib/elixir_script/next/passes/translate/module.ex index 04daa366..6d3f96bf 100644 --- a/lib/elixir_script/next/passes/translate/module.ex +++ b/lib/elixir_script/next/passes/translate/module.ex @@ -34,6 +34,7 @@ defmodule ElixirScript.Translate.Module do _ -> true end) |> Enum.filter(fn + { {:start, 2}, _, _, _ } -> true { name, _, _, _} -> name in used _ -> false end) diff --git a/lib/elixir_script/passes/create_js_modules.ex b/lib/elixir_script/passes/create_js_modules.ex index a0cff524..2ba89848 100644 --- a/lib/elixir_script/passes/create_js_modules.ex +++ b/lib/elixir_script/passes/create_js_modules.ex @@ -100,7 +100,7 @@ defmodule ElixirScript.Passes.CreateJSModules do ), [JS.identifier("Elixir")] ), - JS.identifier("start") + JS.identifier("start2") ), [ElixirScript.Translator.Primitive.make_atom(:normal), JS.identifier(:args)] ) diff --git a/lib/mix/tasks/compile.elixir_script.ex b/lib/mix/tasks/compile.elixir_script.ex index b02c937d..e448a117 100644 --- a/lib/mix/tasks/compile.elixir_script.ex +++ b/lib/mix/tasks/compile.elixir_script.ex @@ -43,7 +43,7 @@ defmodule Mix.Tasks.Compile.ElixirScript do end defp do_compile(_, nil) do - raise ElixirScriptCompileError, message: "Unable to find mix project app name" + raise ElixirScript.CompileError, message: "Unable to find mix project app name" end defp do_compile(elixirscript_base, app) do diff --git a/package.json b/package.json index c9ecbf18..90b86fb4 100644 --- a/package.json +++ b/package.json @@ -11,9 +11,9 @@ "lint:fix": "eslint src/javascript/lib/**/*.js src/javascript/tests/**/*.js --fix", "build": "rollup -c rollup.config.js", "clean": "rm -rf priv/build", - "test": "mocha src/javascript/tests --recursive --compilers js:babel-core/register", + "test": "nyc ava src/javascript/tests", "build:test-app": "mix elixirscript test/app/src/ -f common -o test/app/build/", - "test-app": "yarn run build:test-app && NODE_ENV=test mocha --recursive 'test/app/spec/**/*.spec.js' --compilers js:babel-register" + "test-app": "yarn run build:test-app && NODE_ENV=test ava 'test/app/spec/**/*.spec.js'" }, "repository": { "type": "git", @@ -26,19 +26,26 @@ "tailored": "2.4.5" }, "devDependencies": { + "ava": "^0.19.1", "babel-core": "^6.24.0", - "babel-register": "^6.24.0", "babel-preset-env": "^1.3.2", - "chai": "^3.5.0", + "babel-register": "^6.24.0", "eslint": "^3.15.0", "eslint-config-airbnb-base": "^11.1.0", "eslint-plugin-import": "^2.2.0", - "mocha": "^3.2.0", + "nyc": "^10.3.2", "rollup": "^0.41.6", "rollup-plugin-babel": "^2.7.1", "rollup-plugin-babili": "^2.0.0", "rollup-plugin-node-resolve": "^2.0.0", - "sinon": "^1.17.7", - "sinon-chai": "^2.8.0" + "sinon": "^1.17.7" + }, + "ava": { + "require": [ + "babel-register" + ], + "babel": { + "babelrc": true + } } } \ No newline at end of file diff --git a/src/javascript/lib/core/erlang_compat/erlang.js b/src/javascript/lib/core/erlang_compat/erlang.js index d1b75509..6de89420 100644 --- a/src/javascript/lib/core/erlang_compat/erlang.js +++ b/src/javascript/lib/core/erlang_compat/erlang.js @@ -1,3 +1,13 @@ // http://erlang.org/doc/man/erlang.html -export default {}; +function atom_to_binary2(atom, encoding = Symbol.for('utf8')) { + if (encoding !== Symbol.for('utf8')) { + throw new Error(`unsupported encoding ${encoding}`); + } + + return Symbol.keyFor(atom); +} + +export default { + atom_to_binary2, +}; diff --git a/src/javascript/lib/core/erlang_compat/lists.js b/src/javascript/lib/core/erlang_compat/lists.js index 245b967c..1d2814df 100644 --- a/src/javascript/lib/core/erlang_compat/lists.js +++ b/src/javascript/lib/core/erlang_compat/lists.js @@ -1,3 +1,9 @@ // http://erlang.org/doc/man/lists.html -export default {}; +function reverse1(list) { + return [...list].reverse(); +} + +export default { + reverse1, +}; diff --git a/src/javascript/lib/core/erlang_compat/maps.js b/src/javascript/lib/core/erlang_compat/maps.js index f7269751..97e42b91 100644 --- a/src/javascript/lib/core/erlang_compat/maps.js +++ b/src/javascript/lib/core/erlang_compat/maps.js @@ -1,3 +1,35 @@ // http://erlang.org/doc/man/maps.html +import ErlangTypes from 'erlang-types'; -export default {}; +const OK = Symbol.for('ok'); +const ERROR = Symbol.for('error'); +const BADMAP = Symbol.for('badmap'); + +function find2(key, map) { + if (map instanceof Object === false) { + return new ErlangTypes.Tuple(BADMAP, map); + } + + const value = map[key]; + + if (typeof value !== 'undefined') { + return new ErlangTypes.Tuple(OK, value); + } + + return ERROR; +} + +function fold3(fun, init, map) { + let acc = init; + + for (const [key, value] of Object.entries(map)) { + acc = fun(key, value, acc); + } + + return acc; +} + +export default { + find2, + fold3, +}; diff --git a/src/javascript/tests/case.spec.js b/src/javascript/tests/case.spec.js index 9dc4e43e..4b143edc 100644 --- a/src/javascript/tests/case.spec.js +++ b/src/javascript/tests/case.spec.js @@ -1,36 +1,33 @@ +import test from 'ava'; import Core from '../lib/core'; -import chai from 'chai'; + const Patterns = Core.Patterns; const SpecialForms = Core.SpecialForms; const Tuple = Core.Tuple; -const expect = chai.expect; - -describe('case', () => { - it('case', () => { - const clauses = [ - Patterns.clause( - [ - new Tuple( - Symbol.for('selector'), - Patterns.variable(), - Patterns.variable(), - ), - ], - (i, value) => { - return value; - }, - i => { - return Kernel.is_integer(i); - }, - ), - Patterns.clause([Patterns.variable()], value => { +test('case', t => { + const clauses = [ + Patterns.clause( + [ + new Tuple( + Symbol.for('selector'), + Patterns.variable(), + Patterns.variable() + ), + ], + (i, value) => { return value; - }), - ]; + }, + i => { + return Kernel.is_integer(i); + } + ), + Patterns.clause([Patterns.variable()], value => { + return value; + }), + ]; - const result = SpecialForms._case('thing', clauses); + const result = SpecialForms._case('thing', clauses); - expect(result).to.equal('thing'); - }); + t.is(result, 'thing'); }); diff --git a/src/javascript/tests/cond.spec.js b/src/javascript/tests/cond.spec.js index 3e16ad18..c5d66aed 100644 --- a/src/javascript/tests/cond.spec.js +++ b/src/javascript/tests/cond.spec.js @@ -1,19 +1,16 @@ -import chai from 'chai'; +import test from 'ava'; import Core from '../lib/core'; const SpecialForms = Core.SpecialForms; -const expect = chai.expect; -describe('cond', () => { - it('cond', () => { - const clauses = [ - [1 + 1 === 1, () => 'This will never match'], - [2 * 2 !== 4, () => 'Nor this'], - [true, () => 'This will'], - ]; +test('cond', t => { + const clauses = [ + [1 + 1 === 1, () => 'This will never match'], + [2 * 2 !== 4, () => 'Nor this'], + [true, () => 'This will'], + ]; - const result = SpecialForms.cond(clauses); + const result = SpecialForms.cond(clauses); - expect(result).to.equal('This will'); - }); + t.is(result, 'This will'); }); diff --git a/src/javascript/tests/core/erlang_compat/erlang_spec.js b/src/javascript/tests/core/erlang_compat/erlang_spec.js new file mode 100644 index 00000000..299f56f5 --- /dev/null +++ b/src/javascript/tests/core/erlang_compat/erlang_spec.js @@ -0,0 +1,15 @@ +import test from 'ava'; +import Core from '../../../lib/core'; + +test('atom_to_binary2', t => { + t.is(Core.erlang.atom_to_binary2(Symbol.for('error')), 'error'); + t.is( + Core.erlang.atom_to_binary2(Symbol.for('error'), Symbol.for('utf8')), + 'error' + ); + + t.throws( + () => Core.erlang.atom_to_binary2(Symbol.for('error'), Symbol.for('utf16')), + Error + ); +}); diff --git a/src/javascript/tests/core/erlang_compat/lists_spec.js b/src/javascript/tests/core/erlang_compat/lists_spec.js new file mode 100644 index 00000000..e86e6d46 --- /dev/null +++ b/src/javascript/tests/core/erlang_compat/lists_spec.js @@ -0,0 +1,6 @@ +import test from 'ava'; +import Core from '../../../lib/core'; + +test('reverse1', t => { + t.deepEqual(Core.lists.reverse1([1, 2, 3]), [3, 2, 1]); +}); diff --git a/src/javascript/tests/core/erlang_compat/maps_spec.js b/src/javascript/tests/core/erlang_compat/maps_spec.js new file mode 100644 index 00000000..41d78acd --- /dev/null +++ b/src/javascript/tests/core/erlang_compat/maps_spec.js @@ -0,0 +1,22 @@ +import test from 'ava'; +import Core from '../../../lib/core'; + +test('find2', t => { + let myMap = {}; + let result = Core.maps.find2('t', myMap); + t.is(result, Symbol.for('error')); + + myMap = 'Hello'; + result = Core.maps.find2('t', myMap); + t.deepEqual(result.values, [Symbol.for('badmap'), myMap]); + + myMap = { t: 'b' }; + result = Core.maps.find2('t', myMap); + t.deepEqual(result.values, [Symbol.for('ok'), 'b']); +}); + +test('fold3', t => { + let myMap = { a: 1, b: 2 }; + let result = Core.maps.fold3((k, v, acc) => acc + v, 0, myMap); + t.is(result, 3); +}); diff --git a/src/javascript/tests/core/functions.spec.js b/src/javascript/tests/core/functions.spec.js index 698d8c3c..f9076d44 100644 --- a/src/javascript/tests/core/functions.spec.js +++ b/src/javascript/tests/core/functions.spec.js @@ -1,18 +1,14 @@ +import test from 'ava'; import Core from '../../lib/core'; const Functions = Core.Functions; -import chai from 'chai'; -const expect = chai.expect; - -describe('Functions', () => { - it('call_property', () => { - expect(Functions.call_property(1, 'toString')).to.equal('1'); - expect(Functions.call_property([], 'toString')).to.equal(''); - expect(Functions.call_property([], 'length')).to.equal(0); - expect(Functions.call_property('', 'toString')).to.equal(''); - expect(Functions.call_property('', 'length')).to.equal(0); - expect(Functions.call_property(Symbol('test'), 'toString')).to.equal('Symbol(test)'); - expect(Functions.call_property({ completed: false }, 'completed')).to.equal(false); - expect(Functions.call_property({ id: 0 }, 'id')).to.equal(0); - }); +test('call_property', t => { + t.is(Functions.call_property(1, 'toString'), '1'); + t.is(Functions.call_property([], 'toString'), ''); + t.is(Functions.call_property([], 'length'), 0); + t.is(Functions.call_property('', 'toString'), ''); + t.is(Functions.call_property('', 'length'), 0); + t.is(Functions.call_property(Symbol('test'), 'toString'), 'Symbol(test)'); + t.is(Functions.call_property({ completed: false }, 'completed'), false); + t.is(Functions.call_property({ id: 0 }, 'id'), 0); }); diff --git a/src/javascript/tests/for.spec.js b/src/javascript/tests/for.spec.js index d43cf9d4..52e29d48 100644 --- a/src/javascript/tests/for.spec.js +++ b/src/javascript/tests/for.spec.js @@ -1,12 +1,10 @@ +import test from 'ava'; import Core from '../lib/core'; -import chai from 'chai'; const Patterns = Core.Patterns; const SpecialForms = Core.SpecialForms; const Tuple = Core.Tuple; const BitString = Core.BitString; -const expect = chai.expect; - const $ = Patterns.variable(); const collectable = { @@ -19,116 +17,117 @@ const collectable = { values: [Symbol.for('cont'), Patterns.variable()], }), ], - (list, x) => list.concat([x]), + (list, x) => list.concat([x]) ), - Patterns.clause([$, Symbol.for('done')], list => list), + Patterns.clause([$, Symbol.for('done')], list => list) ); return new Tuple([], fun); }, }; -describe('for', () => { - it('simple for', () => { - const gen = Patterns.list_generator($, [1, 2, 3, 4]); - const result = SpecialForms._for( - Patterns.clause([$], x => x * 2), - [gen], - collectable, - ); +test('simple for', t => { + const gen = Patterns.list_generator($, [1, 2, 3, 4]); + const result = SpecialForms._for( + Patterns.clause([$], x => x * 2), + [gen], + collectable + ); - expect(result).to.eql([2, 4, 6, 8]); - }); + t.deepEqual(result, [2, 4, 6, 8]); +}); - it('for with multiple generators', () => { - //for x <- [1, 2], y <- [2, 3], do: x*y +test('for with multiple generators', t => { + //for x <- [1, 2], y <- [2, 3], do: x*y - const gen = Patterns.list_generator($, [1, 2]); - const gen2 = Patterns.list_generator($, [2, 3]); - const result = SpecialForms._for( - Patterns.clause([$, $], (x, y) => x * y), - [gen, gen2], - collectable, - ); + const gen = Patterns.list_generator($, [1, 2]); + const gen2 = Patterns.list_generator($, [2, 3]); + const result = SpecialForms._for( + Patterns.clause([$, $], (x, y) => x * y), + [gen, gen2], + collectable + ); - expect(result).to.eql([2, 3, 4, 6]); - }); + t.deepEqual(result, [2, 3, 4, 6]); +}); - it('for with filter', () => { - //for n <- [1, 2, 3, 4, 5, 6], rem(n, 2) == 0, do: n - const gen = Patterns.list_generator($, [1, 2, 3, 4, 5, 6]); - const result = SpecialForms._for( - Patterns.clause([$], x => x, x => x % 2 === 0), - [gen], - collectable, - ); +test('for with filter', t => { + //for n <- [1, 2, 3, 4, 5, 6], rem(n, 2) == 0, do: n + const gen = Patterns.list_generator($, [1, 2, 3, 4, 5, 6]); + const result = SpecialForms._for( + Patterns.clause([$], x => x, x => x % 2 === 0), + [gen], + collectable + ); - expect(result).to.eql([2, 4, 6]); - }); + t.deepEqual(result, [2, 4, 6]); +}); - it('for with pattern matching', () => { - //for {:user, name} <- [user: "john", admin: "john", user: "meg"], do - // String.upcase(name) - //end +test('for with pattern matching', t => { + //for {:user, name} <- [user: "john", admin: "john", user: "meg"], do + // String.upcase(name) + //end - const gen = Patterns.list_generator([Symbol.for('user'), $], [ + const gen = Patterns.list_generator( + [Symbol.for('user'), $], + [ [Symbol.for('user'), 'john'], [Symbol.for('admin'), 'john'], [Symbol.for('user'), 'meg'], - ]); - - const result = SpecialForms._for( - Patterns.clause([[Symbol.for('user'), $]], name => name.toUpperCase()), - [gen], - collectable, - ); + ] + ); - expect(result).to.eql(['JOHN', 'MEG']); - }); + const result = SpecialForms._for( + Patterns.clause([[Symbol.for('user'), $]], name => name.toUpperCase()), + [gen], + collectable + ); - it('for with bitstring', () => { - //for <> >>, do: {r, g, b} + t.deepEqual(result, ['JOHN', 'MEG']); +}); - const gen = Patterns.bitstring_generator( +test('for with bitstring', t => { + //for <> >>, do: {r, g, b} + + const gen = Patterns.bitstring_generator( + Patterns.bitStringMatch( + BitString.integer({ value: $ }), + BitString.integer({ value: $ }), + BitString.integer({ value: $ }) + ), + new BitString( + BitString.integer(213), + BitString.integer(45), + BitString.integer(132), + BitString.integer(64), + BitString.integer(76), + BitString.integer(32), + BitString.integer(76), + BitString.integer(0), + BitString.integer(0), + BitString.integer(234), + BitString.integer(32), + BitString.integer(15) + ) + ); + + const expression = Patterns.clause( + [ Patterns.bitStringMatch( BitString.integer({ value: $ }), BitString.integer({ value: $ }), - BitString.integer({ value: $ }), + BitString.integer({ value: $ }) ), - new BitString( - BitString.integer(213), - BitString.integer(45), - BitString.integer(132), - BitString.integer(64), - BitString.integer(76), - BitString.integer(32), - BitString.integer(76), - BitString.integer(0), - BitString.integer(0), - BitString.integer(234), - BitString.integer(32), - BitString.integer(15), - ), - ); - - const expression = Patterns.clause( - [ - Patterns.bitStringMatch( - BitString.integer({ value: $ }), - BitString.integer({ value: $ }), - BitString.integer({ value: $ }), - ), - ], - (r, g, b) => new Tuple(r, g, b), - ); - - const result = SpecialForms._for(expression, [gen], collectable); - - expect(result).to.eql([ - new Tuple(213, 45, 132), - new Tuple(64, 76, 32), - new Tuple(76, 0, 0), - new Tuple(234, 32, 15), - ]); - }); + ], + (r, g, b) => new Tuple(r, g, b) + ); + + const result = SpecialForms._for(expression, [gen], collectable); + + t.deepEqual(result, [ + new Tuple(213, 45, 132), + new Tuple(64, 76, 32), + new Tuple(76, 0, 0), + new Tuple(234, 32, 15), + ]); }); diff --git a/src/javascript/tests/try.spec.js b/src/javascript/tests/try.spec.js index b5d9c658..440c7df9 100644 --- a/src/javascript/tests/try.spec.js +++ b/src/javascript/tests/try.spec.js @@ -1,13 +1,10 @@ +import test from 'ava'; import Core from '../lib/core'; const Patterns = Core.Patterns; const SpecialForms = Core.SpecialForms; -import chai from 'chai'; -const expect = chai.expect; - -describe('try', () => { - it('try', () => { - /* +test('try', t => { + /* try do 1 / x else @@ -19,31 +16,30 @@ describe('try', () => { */ - const x = 1; + const x = 1; - const value = SpecialForms._try( - () => { - return 1 / x; - }, - null, - null, - Patterns.defmatch( - Patterns.clause( - [Patterns.variable()], - y => { - return Symbol.for('small'); - }, - y => { - return y < 1 && y > -1; - }, - ), - Patterns.clause([Patterns.wildcard()], () => { - return Symbol.for('large'); - }), + const value = SpecialForms._try( + () => { + return 1 / x; + }, + null, + null, + Patterns.defmatch( + Patterns.clause( + [Patterns.variable()], + y => { + return Symbol.for('small'); + }, + y => { + return y < 1 && y > -1; + } ), - null, - ); + Patterns.clause([Patterns.wildcard()], () => { + return Symbol.for('large'); + }) + ), + null + ); - expect(value).to.equal(Symbol.for('large')); - }); + t.is(value, Symbol.for('large')); }); diff --git a/src/javascript/tests/with.spec.js b/src/javascript/tests/with.spec.js index e1a30150..d57322d8 100644 --- a/src/javascript/tests/with.spec.js +++ b/src/javascript/tests/with.spec.js @@ -1,12 +1,10 @@ import Core from '../lib/core'; -import chai from 'chai'; +import test from 'ava'; const Patterns = Core.Patterns; const SpecialForms = Core.SpecialForms; const Tuple = Core.Tuple; const MatchError = Core.Patterns.MatchError; -const expect = chai.expect; - const $ = Patterns.variable(); function map_fetch(map, key) { @@ -17,9 +15,8 @@ function map_fetch(map, key) { return Symbol.for('error'); } -describe('with', () => { - it('normal', () => { - /* +test('with', t => { + /* opts = %{width: 10, height: 15} with {:ok, width} <- Map.fetch(opts, :width), @@ -29,19 +26,19 @@ describe('with', () => { {:ok, 150} */ - const opts = { width: 10, height: 15 }; + const opts = { width: 10, height: 15 }; - const value = SpecialForms._with( - [new Tuple(Symbol.for('ok'), $), () => map_fetch(opts, 'width')], - [new Tuple(Symbol.for('ok'), $), width => map_fetch(opts, 'height')], - (width, height) => new Tuple(Symbol.for('ok'), width * height), - ); + const value = SpecialForms._with( + [new Tuple(Symbol.for('ok'), $), () => map_fetch(opts, 'width')], + [new Tuple(Symbol.for('ok'), $), width => map_fetch(opts, 'height')], + (width, height) => new Tuple(Symbol.for('ok'), width * height) + ); - expect(value).to.eql(new Tuple(Symbol.for('ok'), 150)); - }); + t.deepEqual(value, new Tuple(Symbol.for('ok'), 150)); +}); - it('without match', () => { - /* +test('with without match', t => { + /* opts = %{width: 10} with {:ok, width} <- Map.fetch(opts, :width), @@ -51,19 +48,19 @@ describe('with', () => { :error */ - const opts = { width: 10 }; + const opts = { width: 10 }; - const value = SpecialForms._with( - [new Tuple(Symbol.for('ok'), $), () => map_fetch(opts, 'width')], - [new Tuple(Symbol.for('ok'), $), width => map_fetch(opts, 'height')], - (width, height) => new Tuple(Symbol.for('ok'), width * height), - ); + const value = SpecialForms._with( + [new Tuple(Symbol.for('ok'), $), () => map_fetch(opts, 'width')], + [new Tuple(Symbol.for('ok'), $), width => map_fetch(opts, 'height')], + (width, height) => new Tuple(Symbol.for('ok'), width * height) + ); - expect(value).to.eql(Symbol.for('error')); - }); + t.deepEqual(value, Symbol.for('error')); +}); - it('bare expression', () => { - /* +test('with bare expression', t => { + /* opts = %{width: 10} with {:ok, width} <- Map.fetch(opts, :width), @@ -74,24 +71,24 @@ describe('with', () => { {:ok, 300} */ - const opts = { width: 10, height: 15 }; + const opts = { width: 10, height: 15 }; - const value = SpecialForms._with( - [new Tuple(Symbol.for('ok'), $), () => map_fetch(opts, 'width')], - [$, width => width * 2], - [ - new Tuple(Symbol.for('ok'), $), - (width, double_width) => map_fetch(opts, 'height'), - ], - (width, double_width, height) => - new Tuple(Symbol.for('ok'), double_width * height), - ); + const value = SpecialForms._with( + [new Tuple(Symbol.for('ok'), $), () => map_fetch(opts, 'width')], + [$, width => width * 2], + [ + new Tuple(Symbol.for('ok'), $), + (width, double_width) => map_fetch(opts, 'height'), + ], + (width, double_width, height) => + new Tuple(Symbol.for('ok'), double_width * height) + ); - expect(value).to.eql(new Tuple(Symbol.for('ok'), 300)); - }); + t.deepEqual(value, new Tuple(Symbol.for('ok'), 300)); +}); - it('with else', () => { - /* +test('with else', t => { + /* opts = %{width: 10} with {:ok, width} <- Map.fetch(opts, :width), @@ -104,27 +101,25 @@ describe('with', () => { {:error, :wrong_data} */ - const opts = { width: 10 }; - - const value = SpecialForms._with( - [new Tuple(Symbol.for('ok'), $), () => map_fetch(opts, 'width')], - [new Tuple(Symbol.for('ok'), $), width => map_fetch(opts, 'height')], - (width, height) => new Tuple(Symbol.for('ok'), width * height), - Patterns.defmatch( - Patterns.clause( - [Symbol.for('error')], - () => new Tuple(Symbol.for('error'), Symbol.for('wrong_data')), - ), - ), - ); - - expect(value).to.eql( - new Tuple(Symbol.for('error'), Symbol.for('wrong_data')), - ); - }); - - it('with else that don`t match', () => { - /* + const opts = { width: 10 }; + + const value = SpecialForms._with( + [new Tuple(Symbol.for('ok'), $), () => map_fetch(opts, 'width')], + [new Tuple(Symbol.for('ok'), $), width => map_fetch(opts, 'height')], + (width, height) => new Tuple(Symbol.for('ok'), width * height), + Patterns.defmatch( + Patterns.clause( + [Symbol.for('error')], + () => new Tuple(Symbol.for('error'), Symbol.for('wrong_data')) + ) + ) + ); + + t.deepEqual(value, new Tuple(Symbol.for('error'), Symbol.for('wrong_data'))); +}); + +test('with else that don`t match', t => { + /* opts = %{width: 10} with {:ok, width} <- Map.fetch(opts, :width), @@ -137,21 +132,20 @@ describe('with', () => { {:error, :wrong_data} */ - const opts = { width: 10 }; - - const withFunction = SpecialForms._with.bind( - null, - [new Tuple(Symbol.for('ok'), $), () => map_fetch(opts, 'width')], - [new Tuple(Symbol.for('ok'), $), width => map_fetch(opts, 'height')], - (width, height) => new Tuple(Symbol.for('ok'), width * height), - Patterns.defmatch( - Patterns.clause( - [Symbol.for('fail')], - () => new Tuple(Symbol.for('error'), Symbol.for('wrong_data')), - ), - ), - ); - - expect(withFunction).to.throw(MatchError, 'No match for: Symbol(error)'); - }); + const opts = { width: 10 }; + + const withFunction = SpecialForms._with.bind( + null, + [new Tuple(Symbol.for('ok'), $), () => map_fetch(opts, 'width')], + [new Tuple(Symbol.for('ok'), $), width => map_fetch(opts, 'height')], + (width, height) => new Tuple(Symbol.for('ok'), width * height), + Patterns.defmatch( + Patterns.clause( + [Symbol.for('fail')], + () => new Tuple(Symbol.for('error'), Symbol.for('wrong_data')) + ) + ) + ); + + t.throws(withFunction, MatchError); }); diff --git a/test/app/spec/atom.spec.js b/test/app/spec/atom.spec.js deleted file mode 100644 index 89e18673..00000000 --- a/test/app/spec/atom.spec.js +++ /dev/null @@ -1,14 +0,0 @@ -const expect = require('chai').expect; -const Elixir = require('../build/Elixir.App'); - -describe('Atom', () => { - it('to_string/1', () => { - const exports = Elixir.load(Elixir.ElixirScript.Atom); - expect(exports.to_string(Symbol.for('héllo'))).to.eq('héllo'); - }); - - it('to_charlist/1', () => { - const exports = Elixir.load(Elixir.ElixirScript.Atom); - expect(exports.to_string(Symbol.for('héllo'))).to.eq('héllo'); - }); -}); diff --git a/test/app/spec/bootstrap/functions.spec.js b/test/app/spec/bootstrap/functions.spec.js deleted file mode 100644 index 2a098233..00000000 --- a/test/app/spec/bootstrap/functions.spec.js +++ /dev/null @@ -1,29 +0,0 @@ -const expect = require('chai').expect; -const Elixir = require('../../build/Elixir.App'); - -describe('Functions', () => { - it('contains', () => { - const Functions = Elixir.load(Elixir.ElixirScript.Bootstrap.Functions); - expect(Functions.contains(1, [])).to.eq(false); - expect(Functions.contains(1, [1, 2, 3])).to.eq(true); - expect(Functions.contains(4, [1, 2, 3])).to.eq(false); - expect(Functions.contains(1, [1])).to.eq(true); - expect(Functions.contains(4, [1])).to.eq(false); - expect(Functions.contains('apple', [1])).to.eq(false); - }); - - it('get_object_keys', () => { - const Functions = Elixir.load(Elixir.ElixirScript.Bootstrap.Functions); - expect(Functions.get_object_keys({})).to.eql([]); - expect(Functions.get_object_keys({ key: 1 })).to.eql(['key']); - expect( - Functions.get_object_keys({ key: 1, [Symbol.for('hi')]: 2 }) - ).to.eql(['key', Symbol.for('hi')]); - }); - - it('is_valid_character', () => { - const Functions = Elixir.load(Elixir.ElixirScript.Bootstrap.Functions); - expect(Functions.is_valid_character(42)).to.eq(true); - expect(Functions.is_valid_character(NaN)).to.eq(false); - }); -}); diff --git a/test/app/spec/enum.spec.js b/test/app/spec/enum.spec.js deleted file mode 100644 index 3a265bfa..00000000 --- a/test/app/spec/enum.spec.js +++ /dev/null @@ -1,126 +0,0 @@ -const expect = require('chai').expect; -const Elixir = require('../build/Elixir.App'); -const Tuple = require('../../../src/javascript/lib/core').default.Tuple; - -const Enum = Elixir.load(Elixir.ElixirScript.Enum); - -describe('Enum', () => { - it('all?/2', () => { - expect(Enum.all__qmark__([2, 4, 6], x => x % 2 === 0)).to.eql(true); - expect(Enum.all__qmark__([2, 3, 4], x => x % 2 === 0)).to.eql(false); - }); - - it('any?/2', () => { - expect(Enum.any__qmark__([2, 4, 6], x => x % 2 === 1)).to.eql(false); - expect(Enum.any__qmark__([2, 3, 4], x => x % 2 === 1)).to.eql(true); - }); - - it('at/3', () => { - expect(Enum.at([2, 4, 6], 0)).to.eql(2); - expect(Enum.at([2, 4, 6], 2)).to.eql(6); - expect(Enum.at([2, 4, 6], 4)).to.eql(null); - expect(Enum.at([2, 4, 6], 4, Symbol.for('none'))).to.eql( - Symbol.for('none'), - ); - - expect(Enum.at([2, 4, 6], -2)).to.eql(4); - expect(Enum.at([2, 4, 6], -4)).to.eql(null); - }); - - it('concat/1', () => { - expect(Enum.concat([[1, [2], 3], [4], [5, 6]])).to.eql([ - 1, - [2], - 3, - 4, - 5, - 6, - ]); - expect(Enum.concat([[], []])).to.eql([]); - expect(Enum.concat([[]])).to.eql([]); - expect(Enum.concat([])).to.eql([]); - }); - - it('concat/2', () => { - expect(Enum.concat([], [1])).to.eql([1]); - expect(Enum.concat([1, [2], 3], [4, 5])).to.eql([1, [2], 3, 4, 5]); - expect(Enum.concat([], [])).to.eql([]); - }); - - it('count/1', () => { - expect(Enum.count([1, 2, 3])).to.eql(3); - expect(Enum.count([])).to.eql(0); - expect(Enum.count([1, true, false, null])).to.eql(4); - }); - - it('count/2', () => { - expect(Enum.count([1, 2, 3], x => x % 2 === 0)).to.eql(1); - expect(Enum.count([], x => x % 2 === 0)).to.eql(0); - expect(Enum.count([1, true, false, null], x => x)).to.eql(2); - }); - - it('drop/2', () => { - expect(Enum.drop([1, 2, 3], 0)).to.eql([1, 2, 3]); - expect(Enum.drop([1, 2, 3], 1)).to.eql([2, 3]); - expect(Enum.drop([1, 2, 3], 2)).to.eql([3]); - expect(Enum.drop([1, 2, 3], 3)).to.eql([]); - expect(Enum.drop([1, 2, 3], 4)).to.eql([]); - expect(Enum.drop([1, 2, 3], -1)).to.eql([1, 2]); - expect(Enum.drop([1, 2, 3], -2)).to.eql([1]); - expect(Enum.drop([1, 2, 3], -4)).to.eql([]); - }); - - it('drop_every/2', () => { - expect(Enum.drop_every([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 2)).to.eql([ - 2, - 4, - 6, - 8, - 10, - ]); - - expect(Enum.drop_every([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 3)).to.eql([ - 2, - 3, - 5, - 6, - 8, - 9, - ]); - - expect(Enum.drop_every([], 2)).to.eql([]); - expect(Enum.drop_every([1, 2], 2)).to.eql([2]); - expect(Enum.drop_every([1, 2, 3], 0)).to.eql([1, 2, 3]); - }); - - it('drop_while/2', () => { - expect(Enum.drop_while([1, 2, 3, 4, 3, 2, 1], x => x <= 3)).to.eql([ - 4, - 3, - 2, - 1, - ]); - - expect(Enum.drop_while([1, 2, 3], _ => false)).to.eql([1, 2, 3]); - expect(Enum.drop_while([1, 2, 3], x => x <= 3)).to.eql([]); - expect(Enum.drop_while([], _ => false)).to.eql([]); - }); - - it('empty?/1', () => { - expect(Enum.empty__qmark__([])).to.eql(true); - expect(Enum.empty__qmark__([1, 2, 3])).to.eql(false); - }); - - it('fetch/2', () => { - expect(Enum.fetch([66], 0)).to.eql(new Tuple(Symbol.for('ok'), 66)); - expect(Enum.fetch([66], -1)).to.eql(new Tuple(Symbol.for('ok'), 66)); - expect(Enum.fetch([66], 1)).to.eql(Symbol.for('error')); - expect(Enum.fetch([66], -2)).to.eql(Symbol.for('error')); - }); - - it('fetch!/2', () => { - expect(Enum.fetch__emark__([2, 4, 6], 0)).to.eql(2); - expect(Enum.fetch__emark__([2, 4, 6], 2)).to.eql(6); - expect(Enum.fetch__emark__([2, 4, 6], -2)).to.eql(4); - }); -}); diff --git a/test/app/spec/exception.spec.js b/test/app/spec/exception.spec.js deleted file mode 100644 index 7e3f19db..00000000 --- a/test/app/spec/exception.spec.js +++ /dev/null @@ -1,39 +0,0 @@ -const expect = require('chai').expect; -const Elixir = require('../build/Elixir.App'); - -describe('Exception', () => { - it('Create Exception', () => { - const ArgumentError = Elixir.load(Elixir.ElixirScript.ArgumentError); - - let struct = ArgumentError.__struct__(); - - expect(Object.getOwnPropertySymbols(struct)).to.eql([ - Symbol.for('__struct__'), - Symbol.for('message'), - Symbol.for('__exception__'), - ]); - - expect(struct[Symbol.for('__struct__')]).to.eql( - Symbol.for('Elixir.ElixirScript.ArgumentError'), - ); - expect(struct[Symbol.for('__exception__')]).to.eql(true); - expect(struct[Symbol.for('message')]).to.eql('argument error'); - - struct = ArgumentError.__struct__({ - [Symbol.for('message')]: 'new argument error', - }); - - expect(struct[Symbol.for('message')]).to.eql('new argument error'); - }); - - it('raise exception', () => { - const User = Elixir.load(Elixir.User); - const ArgumentError = Elixir.load(Elixir.ElixirScript.ArgumentError); - - try { - User.throw_something(); - } catch (e) { - expect(e[Symbol.for('message')]).to.eql('argument error'); - } - }); -}); diff --git a/test/app/spec/integer.spec.js b/test/app/spec/integer.spec.js deleted file mode 100644 index 523d0aca..00000000 --- a/test/app/spec/integer.spec.js +++ /dev/null @@ -1,53 +0,0 @@ -const expect = require('chai').expect; -const Elixir = require('../build/Elixir.App'); - -describe('Integer', () => { - it('is_odd/1', () => { - const Integer = Elixir.load(Elixir.ElixirScript.Integer); - - expect(Integer.is_odd(0)).to.eq(false); - expect(Integer.is_odd(1)).to.eq(true); - expect(Integer.is_odd(2)).to.eq(false); - expect(Integer.is_odd(3)).to.eq(true); - expect(Integer.is_odd(-1)).to.eq(true); - expect(Integer.is_odd(-2)).to.eq(false); - expect(Integer.is_odd(-3)).to.eq(true); - }); - - it('is_even/1', () => { - const Integer = Elixir.load(Elixir.ElixirScript.Integer); - - expect(Integer.is_even(0)).to.eq(true); - expect(Integer.is_even(1)).to.eq(false); - expect(Integer.is_even(2)).to.eq(true); - expect(Integer.is_even(3)).to.eq(false); - expect(Integer.is_even(-1)).to.eq(false); - expect(Integer.is_even(-2)).to.eq(true); - expect(Integer.is_even(-3)).to.eq(false); - }); - - it('parse/2', () => { - const Integer = Elixir.load(Elixir.ElixirScript.Integer); - expect(Integer.parse('12').values).to.eql([12, '']); - expect(Integer.parse('012').values).to.eql([12, '']); - expect(Integer.parse('+12').values).to.eql([12, '']); - expect(Integer.parse('-12').values).to.eql([-12, '']); - expect(Integer.parse('123456789').values).to.eql([123456789, '']); - expect(Integer.parse('12.5').values).to.eql([12, '.5']); - expect(Integer.parse('7.5e-3').values).to.eql([7, '.5e-3']); - // expect(Integer.parse('12x').values).to.eql([12, 'x']); - expect(Integer.parse('++1')).to.eql(Symbol.for('error')); - expect(Integer.parse('--1')).to.eql(Symbol.for('error')); - expect(Integer.parse('+-1')).to.eql(Symbol.for('error')); - expect(Integer.parse('three')).to.eql(Symbol.for('error')); - - expect(Integer.parse('12', 10).values).to.eql([12, '']); - expect(Integer.parse('-12', 12).values).to.eql([-14, '']); - expect(Integer.parse('12345678', 9).values).to.eql([6053444, '']); - expect(Integer.parse('3.14', 4).values).to.eql([3, '.14']); - expect(Integer.parse('64eb', 16).values).to.eql([25835, '']); - // expect(Integer.parse('64eb', 10).values).to.eql([64, 'eb']); - expect(Integer.parse('10', 2).values).to.eql([2, '']); - expect(Integer.parse('++4', 10)).to.eql(Symbol.for('error')); - }); -}); diff --git a/test/app/spec/main.spec.js b/test/app/spec/main.spec.js index f60c9784..9d5ceac0 100644 --- a/test/app/spec/main.spec.js +++ b/test/app/spec/main.spec.js @@ -1,24 +1,20 @@ -const expect = require('chai').expect; +import test from 'ava'; const sinon = require('sinon'); const Elixir = require('../build/Elixir.App'); -describe('Elixir.start', function () { - it('calls the modules start function', function () { - const callback = sinon.spy(); +test('Elixir.start:calls the modules start function', t => { + const callback = sinon.spy(); - Elixir.start(Elixir.Main, callback); + Elixir.start(Elixir.Main, callback); - expect(callback).to.have.been.calledWith('started'); - }); + t.true(callback.called); }); -describe('Elixir.load', function () { - it('loads the modules exports', function () { - const main = Elixir.load(Elixir.Main); +test('Elixir.load:loads the modules exports', t => { + const main = Elixir.load(Elixir.Main); - expect(main).to.have.property('start'); - expect(main).to.have.property('hello'); - expect(main.hello()).to.eq('Hello!'); - }); + t.truthy(main.start); + t.truthy(main.hello); + t.is(main.hello(), 'Hello!'); }); diff --git a/test/app/spec/setup.spec.js b/test/app/spec/setup.spec.js deleted file mode 100644 index 3e9f4714..00000000 --- a/test/app/spec/setup.spec.js +++ /dev/null @@ -1,15 +0,0 @@ -const sinon = require('sinon'); -const chai = require('chai'); -const sinonChai = require('sinon-chai'); - -before(function() { - chai.use(sinonChai); -}); - -beforeEach(function() { - this.sandbox = sinon.sandbox.create(); -}); - -afterEach(function() { - this.sandbox.restore(); -}); diff --git a/test/app/spec/struct.spec.js b/test/app/spec/struct.spec.js deleted file mode 100644 index 765ea491..00000000 --- a/test/app/spec/struct.spec.js +++ /dev/null @@ -1,36 +0,0 @@ -const expect = require('chai').expect; -const Elixir = require('../build/Elixir.App'); - -describe('Struct', () => { - it('Create Struct', () => { - const User = Elixir.load(Elixir.User); - - let struct = User.__struct__(); - - expect(Object.getOwnPropertySymbols(struct)).to.eql([ - Symbol.for('__struct__'), - Symbol.for('first'), - Symbol.for('last'), - ]); - - expect(struct[Symbol.for('__struct__')]).to.eql(Symbol.for('Elixir.User')); - expect(struct[Symbol.for('first')]).to.eql(null); - expect(struct[Symbol.for('last')]).to.eql(null); - - struct = User.__struct__({ [Symbol.for('first')]: 'John' }); - - expect(struct[Symbol.for('first')]).to.eql('John'); - }); - - it('Protocol', () => { - const User = Elixir.load(Elixir.User); - const StringChars = Elixir.load(Elixir.ElixirScript.String.Chars); - - const struct = User.__struct__({ - [Symbol.for('first')]: 'John', - [Symbol.for('last')]: 'Doe', - }); - - expect(StringChars.to_string(struct)).to.eql('JohnDoe'); - }); -}); diff --git a/test/app/spec/tuple.spec.js b/test/app/spec/tuple.spec.js deleted file mode 100644 index c139aecd..00000000 --- a/test/app/spec/tuple.spec.js +++ /dev/null @@ -1,29 +0,0 @@ -const expect = require('chai').expect; -const Elixir = require('../build/Elixir.App'); -const Tuple = require('../../../src/javascript/lib/core').default.Tuple; - -describe('Tuple', () => { - it('duplicate/2', () => { - const TupleModule = Elixir.load(Elixir.ElixirScript.Tuple); - expect(TupleModule.duplicate(Symbol.for('foo'), 0).values).to.eql([]); - expect(TupleModule.duplicate(Symbol.for('foo'), 3).values).to.eql([Symbol.for('foo'), Symbol.for('foo'), Symbol.for('foo')]); - }); - - it('insert_at/3', () => { - const TupleModule = Elixir.load(Elixir.ElixirScript.Tuple); - const t = new Tuple(Symbol.for('bar'), Symbol.for('baz')); - expect(TupleModule.insert_at(t, 0, Symbol.for('foo')).values).to.eql([Symbol.for('foo'), Symbol.for('bar'), Symbol.for('baz')]); - }); - - it('append/2', () => { - const TupleModule = Elixir.load(Elixir.ElixirScript.Tuple); - const t = new Tuple(Symbol.for('foo'), Symbol.for('bar')); - expect(TupleModule.append(t, Symbol.for('baz')).values).to.eql([Symbol.for('foo'), Symbol.for('bar'), Symbol.for('baz')]); - }); - - it('delete_at/2', () => { - const TupleModule = Elixir.load(Elixir.ElixirScript.Tuple); - const t = new Tuple(Symbol.for('foo'), Symbol.for('bar'), Symbol.for('baz')); - expect(TupleModule.delete_at(t, 0).values).to.eql([Symbol.for('bar'), Symbol.for('baz')]); - }); -}); diff --git a/yarn.lock b/yarn.lock index ed077766..c96129c7 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,10 +2,49 @@ # yarn lockfile v1 +"@ava/babel-plugin-throws-helper@^2.0.0": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@ava/babel-plugin-throws-helper/-/babel-plugin-throws-helper-2.0.0.tgz#2fc1fe3c211a71071a4eca7b8f7af5842cd1ae7c" + +"@ava/babel-preset-stage-4@^1.0.0": + version "1.0.0" + resolved "https://registry.yarnpkg.com/@ava/babel-preset-stage-4/-/babel-preset-stage-4-1.0.0.tgz#a613b5e152f529305422546b072d47facfb26291" + dependencies: + babel-plugin-check-es2015-constants "^6.8.0" + babel-plugin-syntax-trailing-function-commas "^6.20.0" + babel-plugin-transform-async-to-generator "^6.16.0" + babel-plugin-transform-es2015-destructuring "^6.19.0" + babel-plugin-transform-es2015-function-name "^6.9.0" + babel-plugin-transform-es2015-modules-commonjs "^6.18.0" + babel-plugin-transform-es2015-parameters "^6.21.0" + babel-plugin-transform-es2015-spread "^6.8.0" + babel-plugin-transform-es2015-sticky-regex "^6.8.0" + babel-plugin-transform-es2015-unicode-regex "^6.11.0" + babel-plugin-transform-exponentiation-operator "^6.8.0" + package-hash "^1.2.0" + +"@ava/babel-preset-transform-test-files@^3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@ava/babel-preset-transform-test-files/-/babel-preset-transform-test-files-3.0.0.tgz#cded1196a8d8d9381a509240ab92e91a5ec069f7" + dependencies: + "@ava/babel-plugin-throws-helper" "^2.0.0" + babel-plugin-espower "^2.3.2" + +"@ava/pretty-format@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@ava/pretty-format/-/pretty-format-1.1.0.tgz#d0a57d25eb9aeab9643bdd1a030642b91c123e28" + dependencies: + ansi-styles "^2.2.1" + esutils "^2.0.2" + "@comandeer/babel-plugin-banner@^1.0.0": version "1.0.0" resolved "https://registry.yarnpkg.com/@comandeer/babel-plugin-banner/-/babel-plugin-banner-1.0.0.tgz#40bcce0bbee084b5b02545a33635d053c248356f" +abbrev@1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.0.tgz#d0554c2256636e2f56e7c2e5ad183f859428d81f" + acorn-jsx@^3.0.0: version "3.0.1" resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-3.0.1.tgz#afdf9488fb1ecefc8348f6fb22f464e32a58b36b" @@ -24,13 +63,31 @@ ajv-keywords@^1.0.0: version "1.5.1" resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-1.5.1.tgz#314dd0a4b3368fad3dfcdc54ede6171b886daf3c" -ajv@^4.7.0: +ajv@^4.7.0, ajv@^4.9.1: version "4.11.5" resolved "https://registry.yarnpkg.com/ajv/-/ajv-4.11.5.tgz#b6ee74657b993a01dce44b7944d56f485828d5bd" dependencies: co "^4.6.0" json-stable-stringify "^1.0.1" +align-text@^0.1.1, align-text@^0.1.3: + version "0.1.4" + resolved "https://registry.yarnpkg.com/align-text/-/align-text-0.1.4.tgz#0cd90a561093f35d0a99256c22b7069433fad117" + dependencies: + kind-of "^3.0.2" + longest "^1.0.1" + repeat-string "^1.5.2" + +amdefine@>=0.0.4: + version "1.0.1" + resolved "https://registry.yarnpkg.com/amdefine/-/amdefine-1.0.1.tgz#4a5282ac164729e93619bcfd3ad151f817ce91f5" + +ansi-align@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ansi-align/-/ansi-align-2.0.0.tgz#c36aeccba563b89ceb556f3690f0b1d9e3547f7f" + dependencies: + string-width "^2.0.0" + ansi-escapes@^1.1.0: version "1.4.0" resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-1.4.0.tgz#d3a8a83b319aa67793662b13e761c7911422306e" @@ -43,29 +100,218 @@ ansi-styles@^2.2.1: version "2.2.1" resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe" +ansi-styles@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.0.0.tgz#5404e93a544c4fec7f048262977bebfe3155e0c1" + dependencies: + color-convert "^1.0.0" + +ansi-styles@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-1.0.0.tgz#cb102df1c56f5123eab8b67cd7b98027a0279178" + +anymatch@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-1.3.0.tgz#a3e52fa39168c825ff57b0248126ce5a8ff95507" + dependencies: + arrify "^1.0.0" + micromatch "^2.1.5" + +append-transform@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/append-transform/-/append-transform-0.4.0.tgz#d76ebf8ca94d276e247a36bad44a4b74ab611991" + dependencies: + default-require-extensions "^1.0.0" + +aproba@^1.0.3: + version "1.1.1" + resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.1.1.tgz#95d3600f07710aa0e9298c726ad5ecf2eacbabab" + +archy@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/archy/-/archy-1.0.0.tgz#f9c8c13757cc1dd7bc379ac77b2c62a5c2868c40" + +are-we-there-yet@~1.1.2: + version "1.1.4" + resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-1.1.4.tgz#bb5dca382bb94f05e15194373d16fd3ba1ca110d" + dependencies: + delegates "^1.0.0" + readable-stream "^2.0.6" + argparse@^1.0.7: version "1.0.9" resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.9.tgz#73d83bc263f86e97f8cc4f6bae1b0e90a7d22c86" dependencies: sprintf-js "~1.0.2" +arr-diff@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-2.0.0.tgz#8f3b827f955a8bd669697e4a4256ac3ceae356cf" + dependencies: + arr-flatten "^1.0.1" + +arr-exclude@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/arr-exclude/-/arr-exclude-1.0.0.tgz#dfc7c2e552a270723ccda04cf3128c8cbfe5c631" + +arr-flatten@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/arr-flatten/-/arr-flatten-1.0.3.tgz#a274ed85ac08849b6bd7847c4580745dc51adfb1" + +array-differ@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/array-differ/-/array-differ-1.0.0.tgz#eff52e3758249d33be402b8bb8e564bb2b5d4031" + +array-find-index@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/array-find-index/-/array-find-index-1.0.2.tgz#df010aa1287e164bbda6f9723b0a96a1ec4187a1" + array-union@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/array-union/-/array-union-1.0.2.tgz#9a34410e4f4e3da23dea375be5be70f24778ec39" dependencies: array-uniq "^1.0.1" -array-uniq@^1.0.1: +array-uniq@^1.0.1, array-uniq@^1.0.2: version "1.0.3" resolved "https://registry.yarnpkg.com/array-uniq/-/array-uniq-1.0.3.tgz#af6ac877a25cc7f74e058894753858dfdb24fdb6" -arrify@^1.0.0: +array-unique@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.2.1.tgz#a1d97ccafcbc2625cc70fadceb36a50c58b01a53" + +arrify@^1.0.0, arrify@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d" -assertion-error@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/assertion-error/-/assertion-error-1.0.2.tgz#13ca515d86206da0bac66e834dd397d87581094c" +asn1@~0.2.3: + version "0.2.3" + resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.3.tgz#dac8787713c9966849fc8180777ebe9c1ddf3b86" + +assert-plus@1.0.0, assert-plus@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" + +assert-plus@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-0.2.0.tgz#d74e1b87e7affc0db8aadb7021f3fe48101ab234" + +async-each@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/async-each/-/async-each-1.0.1.tgz#19d386a1d9edc6e7c1c85d388aedbcc56d33602d" + +async@^1.4.0: + version "1.5.2" + resolved "https://registry.yarnpkg.com/async/-/async-1.5.2.tgz#ec6a61ae56480c0c3cb241c95618e20892f9672a" + +asynckit@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" + +auto-bind@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/auto-bind/-/auto-bind-1.1.0.tgz#93b864dc7ee01a326281775d5c75ca0a751e5961" + +ava-init@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/ava-init/-/ava-init-0.2.0.tgz#9304c8b4c357d66e3dfdae1fbff47b1199d5c55d" + dependencies: + arr-exclude "^1.0.0" + execa "^0.5.0" + has-yarn "^1.0.0" + read-pkg-up "^2.0.0" + write-pkg "^2.0.0" + +ava@^0.19.1: + version "0.19.1" + resolved "https://registry.yarnpkg.com/ava/-/ava-0.19.1.tgz#43dd82435ad19b3980ffca2488f05daab940b273" + dependencies: + "@ava/babel-preset-stage-4" "^1.0.0" + "@ava/babel-preset-transform-test-files" "^3.0.0" + "@ava/pretty-format" "^1.1.0" + arr-flatten "^1.0.1" + array-union "^1.0.1" + array-uniq "^1.0.2" + arrify "^1.0.0" + auto-bind "^1.1.0" + ava-init "^0.2.0" + babel-code-frame "^6.16.0" + babel-core "^6.17.0" + bluebird "^3.0.0" + caching-transform "^1.0.0" + chalk "^1.0.0" + chokidar "^1.4.2" + clean-stack "^1.1.1" + clean-yaml-object "^0.1.0" + cli-cursor "^2.1.0" + cli-spinners "^1.0.0" + cli-truncate "^1.0.0" + co-with-promise "^4.6.0" + code-excerpt "^2.1.0" + common-path-prefix "^1.0.0" + convert-source-map "^1.2.0" + core-assert "^0.2.0" + currently-unhandled "^0.4.1" + debug "^2.2.0" + diff "^3.0.1" + diff-match-patch "^1.0.0" + dot-prop "^4.1.0" + empower-core "^0.6.1" + equal-length "^1.0.0" + figures "^2.0.0" + find-cache-dir "^0.1.1" + fn-name "^2.0.0" + get-port "^3.0.0" + globby "^6.0.0" + has-flag "^2.0.0" + hullabaloo-config-manager "^1.0.0" + ignore-by-default "^1.0.0" + indent-string "^3.0.0" + is-ci "^1.0.7" + is-generator-fn "^1.0.0" + is-obj "^1.0.0" + is-observable "^0.2.0" + is-promise "^2.1.0" + jest-diff "19.0.0" + jest-snapshot "19.0.2" + js-yaml "^3.8.2" + last-line-stream "^1.0.0" + lodash.debounce "^4.0.3" + lodash.difference "^4.3.0" + lodash.flatten "^4.2.0" + lodash.isequal "^4.5.0" + loud-rejection "^1.2.0" + matcher "^0.1.1" + md5-hex "^2.0.0" + meow "^3.7.0" + mkdirp "^0.5.1" + ms "^0.7.1" + multimatch "^2.1.0" + observable-to-promise "^0.5.0" + option-chain "^0.1.0" + package-hash "^2.0.0" + pkg-conf "^2.0.0" + plur "^2.0.0" + pretty-ms "^2.0.0" + require-precompiled "^0.1.0" + resolve-cwd "^1.0.0" + slash "^1.0.0" + source-map-support "^0.4.0" + stack-utils "^1.0.0" + strip-ansi "^3.0.1" + strip-bom-buf "^1.0.0" + supports-color "^3.2.3" + time-require "^0.1.2" + unique-temp-dir "^1.0.0" + update-notifier "^2.1.0" + +aws-sign2@~0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.6.0.tgz#14342dd38dbcc94d0e5b87d763cd63612c0e794f" + +aws4@^1.2.1: + version "1.6.0" + resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.6.0.tgz#83ef5ca860b2b32e4a0deedee8c771b9db57471e" babel-code-frame@^6.16.0, babel-code-frame@^6.22.0: version "6.22.0" @@ -75,7 +321,7 @@ babel-code-frame@^6.16.0, babel-code-frame@^6.22.0: esutils "^2.0.2" js-tokens "^3.0.0" -babel-core@6, babel-core@^6.21.0, babel-core@^6.24.0: +babel-core@6, babel-core@^6.17.0, babel-core@^6.21.0, babel-core@^6.24.0: version "6.24.0" resolved "https://registry.yarnpkg.com/babel-core/-/babel-core-6.24.0.tgz#8f36a0a77f5c155aed6f920b844d23ba56742a02" dependencies: @@ -99,7 +345,7 @@ babel-core@6, babel-core@^6.21.0, babel-core@^6.24.0: slash "^1.0.0" source-map "^0.5.0" -babel-generator@^6.24.0: +babel-generator@^6.1.0, babel-generator@^6.18.0, babel-generator@^6.24.0: version "6.24.0" resolved "https://registry.yarnpkg.com/babel-generator/-/babel-generator-6.24.0.tgz#eba270a8cc4ce6e09a61be43465d7c62c1f87c56" dependencies: @@ -247,12 +493,24 @@ babel-messages@^6.23.0: dependencies: babel-runtime "^6.22.0" -babel-plugin-check-es2015-constants@^6.22.0: +babel-plugin-check-es2015-constants@^6.22.0, babel-plugin-check-es2015-constants@^6.8.0: version "6.22.0" resolved "https://registry.yarnpkg.com/babel-plugin-check-es2015-constants/-/babel-plugin-check-es2015-constants-6.22.0.tgz#35157b101426fd2ffd3da3f75c7d1e91835bbf8a" dependencies: babel-runtime "^6.22.0" +babel-plugin-espower@^2.3.2: + version "2.3.2" + resolved "https://registry.yarnpkg.com/babel-plugin-espower/-/babel-plugin-espower-2.3.2.tgz#5516b8fcdb26c9f0e1d8160749f6e4c65e71271e" + dependencies: + babel-generator "^6.1.0" + babylon "^6.1.0" + call-matcher "^1.0.0" + core-js "^2.0.0" + espower-location-detector "^1.0.0" + espurify "^1.6.0" + estraverse "^4.1.1" + babel-plugin-minify-builtins@^0.0.2: version "0.0.2" resolved "https://registry.yarnpkg.com/babel-plugin-minify-builtins/-/babel-plugin-minify-builtins-0.0.2.tgz#f3be6121763c0c518d5ef82067cef4b615c9498c" @@ -326,11 +584,11 @@ babel-plugin-syntax-exponentiation-operator@^6.8.0: version "6.13.0" resolved "https://registry.yarnpkg.com/babel-plugin-syntax-exponentiation-operator/-/babel-plugin-syntax-exponentiation-operator-6.13.0.tgz#9ee7e8337290da95288201a6a57f4170317830de" -babel-plugin-syntax-trailing-function-commas@^6.22.0: +babel-plugin-syntax-trailing-function-commas@^6.20.0, babel-plugin-syntax-trailing-function-commas@^6.22.0: version "6.22.0" resolved "https://registry.yarnpkg.com/babel-plugin-syntax-trailing-function-commas/-/babel-plugin-syntax-trailing-function-commas-6.22.0.tgz#ba0360937f8d06e40180a43fe0d5616fff532cf3" -babel-plugin-transform-async-to-generator@^6.22.0: +babel-plugin-transform-async-to-generator@^6.16.0, babel-plugin-transform-async-to-generator@^6.22.0: version "6.22.0" resolved "https://registry.yarnpkg.com/babel-plugin-transform-async-to-generator/-/babel-plugin-transform-async-to-generator-6.22.0.tgz#194b6938ec195ad36efc4c33a971acf00d8cd35e" dependencies: @@ -381,7 +639,7 @@ babel-plugin-transform-es2015-computed-properties@^6.22.0: babel-runtime "^6.22.0" babel-template "^6.22.0" -babel-plugin-transform-es2015-destructuring@^6.23.0: +babel-plugin-transform-es2015-destructuring@^6.19.0, babel-plugin-transform-es2015-destructuring@^6.23.0: version "6.23.0" resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-destructuring/-/babel-plugin-transform-es2015-destructuring-6.23.0.tgz#997bb1f1ab967f682d2b0876fe358d60e765c56d" dependencies: @@ -400,7 +658,7 @@ babel-plugin-transform-es2015-for-of@^6.23.0: dependencies: babel-runtime "^6.22.0" -babel-plugin-transform-es2015-function-name@^6.22.0: +babel-plugin-transform-es2015-function-name@^6.22.0, babel-plugin-transform-es2015-function-name@^6.9.0: version "6.22.0" resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-function-name/-/babel-plugin-transform-es2015-function-name-6.22.0.tgz#f5fcc8b09093f9a23c76ac3d9e392c3ec4b77104" dependencies: @@ -422,7 +680,7 @@ babel-plugin-transform-es2015-modules-amd@^6.22.0, babel-plugin-transform-es2015 babel-runtime "^6.22.0" babel-template "^6.22.0" -babel-plugin-transform-es2015-modules-commonjs@^6.23.0, babel-plugin-transform-es2015-modules-commonjs@^6.24.0: +babel-plugin-transform-es2015-modules-commonjs@^6.18.0, babel-plugin-transform-es2015-modules-commonjs@^6.23.0, babel-plugin-transform-es2015-modules-commonjs@^6.24.0: version "6.24.0" resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-commonjs/-/babel-plugin-transform-es2015-modules-commonjs-6.24.0.tgz#e921aefb72c2cc26cb03d107626156413222134f" dependencies: @@ -454,7 +712,7 @@ babel-plugin-transform-es2015-object-super@^6.22.0: babel-helper-replace-supers "^6.22.0" babel-runtime "^6.22.0" -babel-plugin-transform-es2015-parameters@^6.23.0: +babel-plugin-transform-es2015-parameters@^6.21.0, babel-plugin-transform-es2015-parameters@^6.23.0: version "6.23.0" resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-parameters/-/babel-plugin-transform-es2015-parameters-6.23.0.tgz#3a2aabb70c8af945d5ce386f1a4250625a83ae3b" dependencies: @@ -472,13 +730,13 @@ babel-plugin-transform-es2015-shorthand-properties@^6.22.0: babel-runtime "^6.22.0" babel-types "^6.22.0" -babel-plugin-transform-es2015-spread@^6.22.0: +babel-plugin-transform-es2015-spread@^6.22.0, babel-plugin-transform-es2015-spread@^6.8.0: version "6.22.0" resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-spread/-/babel-plugin-transform-es2015-spread-6.22.0.tgz#d6d68a99f89aedc4536c81a542e8dd9f1746f8d1" dependencies: babel-runtime "^6.22.0" -babel-plugin-transform-es2015-sticky-regex@^6.22.0: +babel-plugin-transform-es2015-sticky-regex@^6.22.0, babel-plugin-transform-es2015-sticky-regex@^6.8.0: version "6.22.0" resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-sticky-regex/-/babel-plugin-transform-es2015-sticky-regex-6.22.0.tgz#ab316829e866ee3f4b9eb96939757d19a5bc4593" dependencies: @@ -498,7 +756,7 @@ babel-plugin-transform-es2015-typeof-symbol@^6.23.0: dependencies: babel-runtime "^6.22.0" -babel-plugin-transform-es2015-unicode-regex@^6.22.0: +babel-plugin-transform-es2015-unicode-regex@^6.11.0, babel-plugin-transform-es2015-unicode-regex@^6.22.0: version "6.22.0" resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-unicode-regex/-/babel-plugin-transform-es2015-unicode-regex-6.22.0.tgz#8d9cc27e7ee1decfe65454fb986452a04a613d20" dependencies: @@ -506,7 +764,7 @@ babel-plugin-transform-es2015-unicode-regex@^6.22.0: babel-runtime "^6.22.0" regexpu-core "^2.0.0" -babel-plugin-transform-exponentiation-operator@^6.22.0: +babel-plugin-transform-exponentiation-operator@^6.22.0, babel-plugin-transform-exponentiation-operator@^6.8.0: version "6.22.0" resolved "https://registry.yarnpkg.com/babel-plugin-transform-exponentiation-operator/-/babel-plugin-transform-exponentiation-operator-6.22.0.tgz#d57c8335281918e54ef053118ce6eb108468084d" dependencies: @@ -656,7 +914,7 @@ babel-runtime@^6.0.0, babel-runtime@^6.18.0, babel-runtime@^6.22.0: core-js "^2.4.0" regenerator-runtime "^0.10.0" -babel-template@^6.22.0, babel-template@^6.23.0: +babel-template@^6.16.0, babel-template@^6.22.0, babel-template@^6.23.0: version "6.23.0" resolved "https://registry.yarnpkg.com/babel-template/-/babel-template-6.23.0.tgz#04d4f270adbb3aa704a8143ae26faa529238e638" dependencies: @@ -666,7 +924,7 @@ babel-template@^6.22.0, babel-template@^6.23.0: babylon "^6.11.0" lodash "^4.2.0" -babel-traverse@^6.22.0, babel-traverse@^6.23.0, babel-traverse@^6.23.1: +babel-traverse@^6.18.0, babel-traverse@^6.22.0, babel-traverse@^6.23.0, babel-traverse@^6.23.1: version "6.23.1" resolved "https://registry.yarnpkg.com/babel-traverse/-/babel-traverse-6.23.1.tgz#d3cb59010ecd06a97d81310065f966b699e14f48" dependencies: @@ -680,7 +938,7 @@ babel-traverse@^6.22.0, babel-traverse@^6.23.0, babel-traverse@^6.23.1: invariant "^2.2.0" lodash "^4.2.0" -babel-types@^6.19.0, babel-types@^6.22.0, babel-types@^6.23.0: +babel-types@^6.18.0, babel-types@^6.19.0, babel-types@^6.22.0, babel-types@^6.23.0: version "6.23.0" resolved "https://registry.yarnpkg.com/babel-types/-/babel-types-6.23.0.tgz#bb17179d7538bad38cd0c9e115d340f77e7e9acf" dependencies: @@ -689,7 +947,7 @@ babel-types@^6.19.0, babel-types@^6.22.0, babel-types@^6.23.0: lodash "^4.2.0" to-fast-properties "^1.0.1" -babylon@^6.11.0, babylon@^6.15.0: +babylon@^6.1.0, babylon@^6.11.0, babylon@^6.13.0, babylon@^6.15.0: version "6.16.1" resolved "https://registry.yarnpkg.com/babylon/-/babylon-6.16.1.tgz#30c5a22f481978a9e7f8cdfdf496b11d94b404d3" @@ -697,6 +955,44 @@ balanced-match@^0.4.1: version "0.4.2" resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-0.4.2.tgz#cb3f3e3c732dc0f01ee70b403f302e61d7709838" +bcrypt-pbkdf@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz#63bc5dcb61331b92bc05fd528953c33462a06f8d" + dependencies: + tweetnacl "^0.14.3" + +binary-extensions@^1.0.0: + version "1.8.0" + resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-1.8.0.tgz#48ec8d16df4377eae5fa5884682480af4d95c774" + +block-stream@*: + version "0.0.9" + resolved "https://registry.yarnpkg.com/block-stream/-/block-stream-0.0.9.tgz#13ebfe778a03205cfe03751481ebb4b3300c126a" + dependencies: + inherits "~2.0.0" + +bluebird@^3.0.0: + version "3.5.0" + resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.5.0.tgz#791420d7f551eea2897453a8a77653f96606d67c" + +boom@2.x.x: + version "2.10.1" + resolved "https://registry.yarnpkg.com/boom/-/boom-2.10.1.tgz#39c8918ceff5799f83f9492a848f625add0c766f" + dependencies: + hoek "2.x.x" + +boxen@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/boxen/-/boxen-1.1.0.tgz#b1b69dd522305e807a99deee777dbd6e5167b102" + dependencies: + ansi-align "^2.0.0" + camelcase "^4.0.0" + chalk "^1.1.1" + cli-boxes "^1.0.0" + string-width "^2.0.0" + term-size "^0.1.0" + widest-line "^1.0.0" + brace-expansion@^1.0.0: version "1.1.6" resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.6.tgz#7197d7eaa9b87e648390ea61fc66c84427420df9" @@ -704,16 +1000,20 @@ brace-expansion@^1.0.0: balanced-match "^0.4.1" concat-map "0.0.1" +braces@^1.8.2: + version "1.8.5" + resolved "https://registry.yarnpkg.com/braces/-/braces-1.8.5.tgz#ba77962e12dff969d6b76711e914b737857bf6a7" + dependencies: + expand-range "^1.8.1" + preserve "^0.2.0" + repeat-element "^1.1.2" + browser-resolve@^1.11.0: version "1.11.2" resolved "https://registry.yarnpkg.com/browser-resolve/-/browser-resolve-1.11.2.tgz#8ff09b0a2c421718a1051c260b32e48f442938ce" dependencies: resolve "1.1.7" -browser-stdout@1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/browser-stdout/-/browser-stdout-1.3.0.tgz#f351d32969d32fa5d7a5567154263d928ae3bd1f" - browserslist@^1.4.0: version "1.7.7" resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-1.7.7.tgz#0bd76704258be829b2398bb50e4b62d1a166b0b9" @@ -721,14 +1021,39 @@ browserslist@^1.4.0: caniuse-db "^1.0.30000639" electron-to-chromium "^1.2.7" +buf-compare@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/buf-compare/-/buf-compare-1.0.1.tgz#fef28da8b8113a0a0db4430b0b6467b69730b34a" + buffer-shims@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/buffer-shims/-/buffer-shims-1.0.0.tgz#9978ce317388c649ad8793028c3477ef044a8b51" -builtin-modules@^1.1.0, builtin-modules@^1.1.1: +builtin-modules@^1.0.0, builtin-modules@^1.1.0, builtin-modules@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-1.1.1.tgz#270f076c5a72c02f5b65a47df94c5fe3a278892f" +caching-transform@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/caching-transform/-/caching-transform-1.0.1.tgz#6dbdb2f20f8d8fbce79f3e94e9d1742dcdf5c0a1" + dependencies: + md5-hex "^1.2.0" + mkdirp "^0.5.1" + write-file-atomic "^1.1.4" + +call-matcher@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/call-matcher/-/call-matcher-1.0.1.tgz#5134d077984f712a54dad3cbf62de28dce416ca8" + dependencies: + core-js "^2.0.0" + deep-equal "^1.0.0" + espurify "^1.6.0" + estraverse "^4.0.0" + +call-signature@0.0.2: + version "0.0.2" + resolved "https://registry.yarnpkg.com/call-signature/-/call-signature-0.0.2.tgz#a84abc825a55ef4cb2b028bd74e205a65b9a4996" + caller-path@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/caller-path/-/caller-path-0.1.0.tgz#94085ef63581ecd3daa92444a8fe94e82577751f" @@ -739,17 +1064,55 @@ callsites@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/callsites/-/callsites-0.2.0.tgz#afab96262910a7f33c19a5775825c69f34e350ca" +camelcase-keys@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/camelcase-keys/-/camelcase-keys-2.1.0.tgz#308beeaffdf28119051efa1d932213c91b8f92e7" + dependencies: + camelcase "^2.0.0" + map-obj "^1.0.0" + +camelcase@^1.0.2: + version "1.2.1" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-1.2.1.tgz#9bb5304d2e0b56698b2c758b08a3eaa9daa58a39" + +camelcase@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-2.1.1.tgz#7c1d16d679a1bbe59ca02cacecfb011e201f5a1f" + +camelcase@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-3.0.0.tgz#32fc4b9fcdaf845fcdf7e73bb97cac2261f0ab0a" + +camelcase@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-4.1.0.tgz#d545635be1e33c542649c69173e5de6acfae34dd" + caniuse-db@^1.0.30000639: version "1.0.30000646" resolved "https://registry.yarnpkg.com/caniuse-db/-/caniuse-db-1.0.30000646.tgz#c724b90d61df24286e015fc528d062073c00def4" -chai@^3.5.0: - version "3.5.0" - resolved "https://registry.yarnpkg.com/chai/-/chai-3.5.0.tgz#4d02637b067fe958bdbfdd3a40ec56fef7373247" +capture-stack-trace@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/capture-stack-trace/-/capture-stack-trace-1.0.0.tgz#4a6fa07399c26bba47f0b2496b4d0fb408c5550d" + +caseless@~0.12.0: + version "0.12.0" + resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" + +center-align@^0.1.1: + version "0.1.3" + resolved "https://registry.yarnpkg.com/center-align/-/center-align-0.1.3.tgz#aa0d32629b6ee972200411cbd4461c907bc2b7ad" + dependencies: + align-text "^0.1.3" + lazy-cache "^1.0.3" + +chalk@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-0.4.0.tgz#5199a3ddcd0c1efe23bc08c1b027b06176e0c64f" dependencies: - assertion-error "^1.0.1" - deep-eql "^0.1.3" - type-detect "^1.0.0" + ansi-styles "~1.0.0" + has-color "~0.1.0" + strip-ansi "~0.1.0" chalk@^1.0.0, chalk@^1.1.0, chalk@^1.1.1, chalk@^1.1.3: version "1.1.3" @@ -761,33 +1124,127 @@ chalk@^1.0.0, chalk@^1.1.0, chalk@^1.1.1, chalk@^1.1.3: strip-ansi "^3.0.0" supports-color "^2.0.0" +chokidar@^1.4.2: + version "1.7.0" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-1.7.0.tgz#798e689778151c8076b4b360e5edd28cda2bb468" + dependencies: + anymatch "^1.3.0" + async-each "^1.0.0" + glob-parent "^2.0.0" + inherits "^2.0.1" + is-binary-path "^1.0.0" + is-glob "^2.0.0" + path-is-absolute "^1.0.0" + readdirp "^2.0.0" + optionalDependencies: + fsevents "^1.0.0" + +ci-info@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-1.0.0.tgz#dc5285f2b4e251821683681c381c3388f46ec534" + circular-json@^0.3.1: version "0.3.1" resolved "https://registry.yarnpkg.com/circular-json/-/circular-json-0.3.1.tgz#be8b36aefccde8b3ca7aa2d6afc07a37242c0d2d" +clean-stack@^1.1.1: + version "1.3.0" + resolved "https://registry.yarnpkg.com/clean-stack/-/clean-stack-1.3.0.tgz#9e821501ae979986c46b1d66d2d432db2fd4ae31" + +clean-yaml-object@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/clean-yaml-object/-/clean-yaml-object-0.1.0.tgz#63fb110dc2ce1a84dc21f6d9334876d010ae8b68" + +cli-boxes@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/cli-boxes/-/cli-boxes-1.0.0.tgz#4fa917c3e59c94a004cd61f8ee509da651687143" + cli-cursor@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-1.0.2.tgz#64da3f7d56a54412e59794bd62dc35295e8f2987" dependencies: restore-cursor "^1.0.1" +cli-cursor@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-2.1.0.tgz#b35dac376479facc3e94747d41d0d0f5238ffcb5" + dependencies: + restore-cursor "^2.0.0" + +cli-spinners@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/cli-spinners/-/cli-spinners-1.0.0.tgz#ef987ed3d48391ac3dab9180b406a742180d6e6a" + +cli-truncate@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/cli-truncate/-/cli-truncate-1.0.0.tgz#21eb91f47b3f6560f004db77a769b4668d9c5518" + dependencies: + slice-ansi "0.0.4" + string-width "^2.0.0" + cli-width@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-2.1.0.tgz#b234ca209b29ef66fc518d9b98d5847b00edf00a" +cliui@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-2.1.0.tgz#4b475760ff80264c762c3a1719032e91c7fea0d1" + dependencies: + center-align "^0.1.1" + right-align "^0.1.1" + wordwrap "0.0.2" + +cliui@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-3.2.0.tgz#120601537a916d29940f934da3b48d585a39213d" + dependencies: + string-width "^1.0.1" + strip-ansi "^3.0.1" + wrap-ansi "^2.0.0" + +co-with-promise@^4.6.0: + version "4.6.0" + resolved "https://registry.yarnpkg.com/co-with-promise/-/co-with-promise-4.6.0.tgz#413e7db6f5893a60b942cf492c4bec93db415ab7" + dependencies: + pinkie-promise "^1.0.0" + co@^4.6.0: version "4.6.0" resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184" +code-excerpt@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/code-excerpt/-/code-excerpt-2.1.0.tgz#5dcc081e88f4a7e3b554e9e35d7ef232d47f8147" + dependencies: + convert-to-spaces "^1.0.1" + code-point-at@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" -commander@2.9.0: - version "2.9.0" - resolved "https://registry.yarnpkg.com/commander/-/commander-2.9.0.tgz#9c99094176e12240cb22d6c5146098400fe0f7d4" +color-convert@^1.0.0: + version "1.9.0" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.0.tgz#1accf97dd739b983bf994d56fec8f95853641b7a" + dependencies: + color-name "^1.1.1" + +color-name@^1.1.1: + version "1.1.2" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.2.tgz#5c8ab72b64bd2215d617ae9559ebb148475cf98d" + +combined-stream@^1.0.5, combined-stream@~1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.5.tgz#938370a57b4a51dea2c77c15d5c5fdf895164009" dependencies: - graceful-readlink ">= 1.0.0" + delayed-stream "~1.0.0" + +common-path-prefix@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/common-path-prefix/-/common-path-prefix-1.0.0.tgz#cd52f6f0712e0baab97d6f9732874f22f47752c0" + +commondir@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b" concat-map@0.0.1: version "0.0.1" @@ -801,15 +1258,41 @@ concat-stream@^1.5.2: readable-stream "^2.2.2" typedarray "^0.0.6" +configstore@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/configstore/-/configstore-3.1.0.tgz#45df907073e26dfa1cf4b2d52f5b60545eaa11d1" + dependencies: + dot-prop "^4.1.0" + graceful-fs "^4.1.2" + make-dir "^1.0.0" + unique-string "^1.0.0" + write-file-atomic "^2.0.0" + xdg-basedir "^3.0.0" + +console-control-strings@^1.0.0, console-control-strings@~1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e" + contains-path@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/contains-path/-/contains-path-0.1.0.tgz#fe8cf184ff6670b6baef01a9d4861a5cbec4120a" -convert-source-map@^1.1.0: +convert-source-map@^1.1.0, convert-source-map@^1.2.0, convert-source-map@^1.3.0: version "1.5.0" resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.5.0.tgz#9acd70851c6d5dfdd93d9282e5edf94a03ff46b5" -core-js@^2.4.0: +convert-to-spaces@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/convert-to-spaces/-/convert-to-spaces-1.0.2.tgz#7e3e48bbe6d997b1417ddca2868204b4d3d85715" + +core-assert@^0.2.0: + version "0.2.1" + resolved "https://registry.yarnpkg.com/core-assert/-/core-assert-0.2.1.tgz#f85e2cf9bfed28f773cc8b3fa5c5b69bdc02fe3f" + dependencies: + buf-compare "^1.0.0" + is-error "^2.2.0" + +core-js@^2.0.0, core-js@^2.4.0: version "2.4.1" resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.4.1.tgz#4de911e667b0eae9124e34254b53aea6fc618d3e" @@ -817,34 +1300,96 @@ core-util-is@~1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" +create-error-class@^3.0.0: + version "3.0.2" + resolved "https://registry.yarnpkg.com/create-error-class/-/create-error-class-3.0.2.tgz#06be7abef947a3f14a30fd610671d401bca8b7b6" + dependencies: + capture-stack-trace "^1.0.0" + +cross-spawn-async@^2.1.1: + version "2.2.5" + resolved "https://registry.yarnpkg.com/cross-spawn-async/-/cross-spawn-async-2.2.5.tgz#845ff0c0834a3ded9d160daca6d390906bb288cc" + dependencies: + lru-cache "^4.0.0" + which "^1.2.8" + +cross-spawn@^4, cross-spawn@^4.0.0: + version "4.0.2" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-4.0.2.tgz#7b9247621c23adfdd3856004a823cbe397424d41" + dependencies: + lru-cache "^4.0.1" + which "^1.2.9" + +cryptiles@2.x.x: + version "2.0.5" + resolved "https://registry.yarnpkg.com/cryptiles/-/cryptiles-2.0.5.tgz#3bdfecdc608147c1c67202fa291e7dca59eaa3b8" + dependencies: + boom "2.x.x" + +crypto-random-string@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/crypto-random-string/-/crypto-random-string-1.0.0.tgz#a230f64f568310e1498009940790ec99545bca7e" + +currently-unhandled@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/currently-unhandled/-/currently-unhandled-0.4.1.tgz#988df33feab191ef799a61369dd76c17adf957ea" + dependencies: + array-find-index "^1.0.1" + d@1: version "1.0.0" resolved "https://registry.yarnpkg.com/d/-/d-1.0.0.tgz#754bb5bfe55451da69a58b94d45f4c5b0462d58f" dependencies: es5-ext "^0.10.9" +dashdash@^1.12.0: + version "1.14.1" + resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0" + dependencies: + assert-plus "^1.0.0" + +date-time@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/date-time/-/date-time-0.1.1.tgz#ed2f6d93d9790ce2fd66d5b5ff3edd5bbcbf3b07" + +debug-log@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/debug-log/-/debug-log-1.0.1.tgz#2307632d4c04382b8df8a32f70b895046d52745f" + debug@2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/debug/-/debug-2.2.0.tgz#f87057e995b1a1f6ae6a4960664137bc56f039da" dependencies: ms "0.7.1" -debug@^2.1.1, debug@^2.2.0: +debug@^2.1.1, debug@^2.2.0, debug@^2.6.3: version "2.6.3" resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.3.tgz#0f7eb8c30965ec08c72accfa0130c8b79984141d" dependencies: ms "0.7.2" -deep-eql@^0.1.3: - version "0.1.3" - resolved "https://registry.yarnpkg.com/deep-eql/-/deep-eql-0.1.3.tgz#ef558acab8de25206cd713906d74e56930eb69f2" - dependencies: - type-detect "0.1.1" +decamelize@^1.0.0, decamelize@^1.1.1, decamelize@^1.1.2: + version "1.2.0" + resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" + +deep-equal@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-1.0.1.tgz#f5d260292b660e084eff4cdbc9f08ad3247448b5" + +deep-extend@~0.4.0: + version "0.4.2" + resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.4.2.tgz#48b699c27e334bf89f10892be432f6e4c7d34a7f" deep-is@~0.1.3: version "0.1.3" resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34" +default-require-extensions@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/default-require-extensions/-/default-require-extensions-1.0.0.tgz#f37ea15d3e13ffd9b437d33e1a75b5fb97874cb8" + dependencies: + strip-bom "^2.0.0" + del@^2.0.2: version "2.2.2" resolved "https://registry.yarnpkg.com/del/-/del-2.2.2.tgz#c12c981d067846c84bcaf862cff930d907ffd1a8" @@ -857,15 +1402,31 @@ del@^2.0.2: pinkie-promise "^2.0.0" rimraf "^2.2.8" +delayed-stream@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" + +delegates@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" + detect-indent@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-4.0.0.tgz#f76d064352cdf43a1cb6ce619c4ee3a9475de208" dependencies: repeating "^2.0.0" -diff@1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/diff/-/diff-1.4.0.tgz#7f28d2eb9ee7b15a97efd89ce63dcfdaa3ccbabf" +detect-indent@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-5.0.0.tgz#3871cc0a6a002e8c3e5b3cf7f336264675f06b9d" + +diff-match-patch@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/diff-match-patch/-/diff-match-patch-1.0.0.tgz#1cc3c83a490d67f95d91e39f6ad1f2e086b63048" + +diff@^3.0.0, diff@^3.0.1: + version "3.2.0" + resolved "https://registry.yarnpkg.com/diff/-/diff-3.2.0.tgz#c9ce393a4b7cbd0b058a725c93df299027868ff9" doctrine@1.5.0: version "1.5.0" @@ -881,14 +1442,47 @@ doctrine@^2.0.0: esutils "^2.0.2" isarray "^1.0.0" +dot-prop@^4.1.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-4.1.1.tgz#a8493f0b7b5eeec82525b5c7587fa7de7ca859c1" + dependencies: + is-obj "^1.0.0" + +duplexer3@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/duplexer3/-/duplexer3-0.1.4.tgz#ee01dd1cac0ed3cbc7fdbea37dc0a8f1ce002ce2" + +ecc-jsbn@~0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz#0fc73a9ed5f0d53c38193398523ef7e543777505" + dependencies: + jsbn "~0.1.0" + electron-to-chromium@^1.2.7: version "1.3.2" resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.2.tgz#b8ce5c93b308db0e92f6d0435c46ddec8f6363ab" +empower-core@^0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/empower-core/-/empower-core-0.6.1.tgz#6c187f502fcef7554d57933396aac655483772b1" + dependencies: + call-signature "0.0.2" + core-js "^2.0.0" + +equal-length@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/equal-length/-/equal-length-1.0.1.tgz#21ca112d48ab24b4e1e7ffc0e5339d31fdfc274c" + erlang-types@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/erlang-types/-/erlang-types-1.0.0.tgz#e555bd091667498a01d340d18203231dc96d962f" +error-ex@^1.2.0: + version "1.3.1" + resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.1.tgz#f855a86ce61adc4e8621c3cda21e7a7612c3a8dc" + dependencies: + is-arrayish "^0.2.1" + es5-ext@^0.10.14, es5-ext@^0.10.9, es5-ext@~0.10.14: version "0.10.15" resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.15.tgz#c330a5934c1ee21284a7c081a86e5fd937c91ea6" @@ -896,6 +1490,10 @@ es5-ext@^0.10.14, es5-ext@^0.10.9, es5-ext@~0.10.14: es6-iterator "2" es6-symbol "~3.1" +es6-error@^4.0.1, es6-error@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/es6-error/-/es6-error-4.0.2.tgz#eec5c726eacef51b7f6b73c20db6e1b13b069c98" + es6-iterator@2, es6-iterator@^2.0.1, es6-iterator@~2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/es6-iterator/-/es6-iterator-2.0.1.tgz#8e319c9f0453bf575d374940a655920e59ca5512" @@ -941,7 +1539,7 @@ es6-weak-map@^2.0.1: es6-iterator "^2.0.1" es6-symbol "^3.1.1" -escape-string-regexp@1.0.5, escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5: +escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.4, escape-string-regexp@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" @@ -1028,6 +1626,15 @@ eslint@^3.15.0: text-table "~0.2.0" user-home "^2.0.0" +espower-location-detector@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/espower-location-detector/-/espower-location-detector-1.0.0.tgz#a17b7ecc59d30e179e2bef73fb4137704cb331b5" + dependencies: + is-url "^1.2.1" + path-is-absolute "^1.0.0" + source-map "^0.5.0" + xtend "^4.0.0" + espree@^3.4.0: version "3.4.1" resolved "https://registry.yarnpkg.com/espree/-/espree-3.4.1.tgz#28a83ab4aaed71ed8fe0f5efe61b76a05c13c4d2" @@ -1039,6 +1646,12 @@ esprima@^3.1.1: version "3.1.3" resolved "https://registry.yarnpkg.com/esprima/-/esprima-3.1.3.tgz#fdca51cee6133895e3c88d535ce49dbff62a4633" +espurify@^1.6.0: + version "1.7.0" + resolved "https://registry.yarnpkg.com/espurify/-/espurify-1.7.0.tgz#1c5cf6cbccc32e6f639380bd4f991fab9ba9d226" + dependencies: + core-js "^2.0.0" + esquery@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.0.0.tgz#cfba8b57d7fba93f17298a8a006a04cda13d80fa" @@ -1075,14 +1688,63 @@ event-emitter@~0.3.5: d "1" es5-ext "~0.10.14" +execa@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/execa/-/execa-0.4.0.tgz#4eb6467a36a095fabb2970ff9d5e3fb7bce6ebc3" + dependencies: + cross-spawn-async "^2.1.1" + is-stream "^1.1.0" + npm-run-path "^1.0.0" + object-assign "^4.0.1" + path-key "^1.0.0" + strip-eof "^1.0.0" + +execa@^0.5.0: + version "0.5.1" + resolved "https://registry.yarnpkg.com/execa/-/execa-0.5.1.tgz#de3fb85cb8d6e91c85bcbceb164581785cb57b36" + dependencies: + cross-spawn "^4.0.0" + get-stream "^2.2.0" + is-stream "^1.1.0" + npm-run-path "^2.0.0" + p-finally "^1.0.0" + signal-exit "^3.0.0" + strip-eof "^1.0.0" + exit-hook@^1.0.0: version "1.1.1" resolved "https://registry.yarnpkg.com/exit-hook/-/exit-hook-1.1.1.tgz#f05ca233b48c05d54fff07765df8507e95c02ff8" -fast-levenshtein@~2.0.4: - version "2.0.6" - resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" - +expand-brackets@^0.1.4: + version "0.1.5" + resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-0.1.5.tgz#df07284e342a807cd733ac5af72411e581d1177b" + dependencies: + is-posix-bracket "^0.1.0" + +expand-range@^1.8.1: + version "1.8.2" + resolved "https://registry.yarnpkg.com/expand-range/-/expand-range-1.8.2.tgz#a299effd335fe2721ebae8e257ec79644fc85337" + dependencies: + fill-range "^2.1.0" + +extend@~3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.1.tgz#a755ea7bc1adfcc5a31ce7e762dbaadc5e636444" + +extglob@^0.3.1: + version "0.3.2" + resolved "https://registry.yarnpkg.com/extglob/-/extglob-0.3.2.tgz#2e18ff3d2f49ab2765cec9023f011daa8d8349a1" + dependencies: + is-extglob "^1.0.0" + +extsprintf@1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.0.2.tgz#e1080e0658e300b06294990cc70e1502235fd550" + +fast-levenshtein@~2.0.4: + version "2.0.6" + resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" + figures@^1.3.5: version "1.7.0" resolved "https://registry.yarnpkg.com/figures/-/figures-1.7.0.tgz#cbe1e3affcf1cd44b80cadfed28dc793a9701d2e" @@ -1090,6 +1752,12 @@ figures@^1.3.5: escape-string-regexp "^1.0.5" object-assign "^4.1.0" +figures@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/figures/-/figures-2.0.0.tgz#3ab1a2d2a62c8bfb431a0c94cb797a2fce27c962" + dependencies: + escape-string-regexp "^1.0.5" + file-entry-cache@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-2.0.0.tgz#c392990c3e684783d838b8c84a45d8a048458361" @@ -1097,13 +1765,41 @@ file-entry-cache@^2.0.0: flat-cache "^1.2.1" object-assign "^4.0.1" -find-up@^1.0.0: +filename-regex@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/filename-regex/-/filename-regex-2.0.1.tgz#c1c4b9bee3e09725ddb106b75c1e301fe2f18b26" + +fill-range@^2.1.0: + version "2.2.3" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-2.2.3.tgz#50b77dfd7e469bc7492470963699fe7a8485a723" + dependencies: + is-number "^2.1.0" + isobject "^2.0.0" + randomatic "^1.1.3" + repeat-element "^1.1.2" + repeat-string "^1.5.2" + +find-cache-dir@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-0.1.1.tgz#c8defae57c8a52a8a784f9e31c57c742e993a0b9" + dependencies: + commondir "^1.0.1" + mkdirp "^0.5.1" + pkg-dir "^1.0.0" + +find-up@^1.0.0, find-up@^1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/find-up/-/find-up-1.1.2.tgz#6b2e9822b1a2ce0a60ab64d610eccad53cb24d0f" dependencies: path-exists "^2.0.0" pinkie-promise "^2.0.0" +find-up@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-2.1.0.tgz#45d1b7e506c717ddd482775a2b77920a3c0c57a7" + dependencies: + locate-path "^2.0.0" + flat-cache@^1.2.1: version "1.2.2" resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-1.2.2.tgz#fa86714e72c21db88601761ecf2f555d1abc6b96" @@ -1113,6 +1809,39 @@ flat-cache@^1.2.1: graceful-fs "^4.1.2" write "^0.2.1" +fn-name@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/fn-name/-/fn-name-2.0.1.tgz#5214d7537a4d06a4a301c0cc262feb84188002e7" + +for-in@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" + +for-own@^0.1.4: + version "0.1.5" + resolved "https://registry.yarnpkg.com/for-own/-/for-own-0.1.5.tgz#5265c681a4f294dabbf17c9509b6763aa84510ce" + dependencies: + for-in "^1.0.1" + +foreground-child@^1.3.3, foreground-child@^1.5.3: + version "1.5.6" + resolved "https://registry.yarnpkg.com/foreground-child/-/foreground-child-1.5.6.tgz#4fd71ad2dfde96789b980a5c0a295937cb2f5ce9" + dependencies: + cross-spawn "^4" + signal-exit "^3.0.0" + +forever-agent@~0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" + +form-data@~2.1.1: + version "2.1.4" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.1.4.tgz#33c183acf193276ecaa98143a69e94bfee1750d1" + dependencies: + asynckit "^0.4.0" + combined-stream "^1.0.5" + mime-types "^2.1.12" + formatio@1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/formatio/-/formatio-1.1.1.tgz#5ed3ccd636551097383465d996199100e86161e9" @@ -1123,10 +1852,47 @@ fs.realpath@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" +fsevents@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-1.1.1.tgz#f19fd28f43eeaf761680e519a203c4d0b3d31aff" + dependencies: + nan "^2.3.0" + node-pre-gyp "^0.6.29" + +fstream-ignore@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/fstream-ignore/-/fstream-ignore-1.0.5.tgz#9c31dae34767018fe1d249b24dada67d092da105" + dependencies: + fstream "^1.0.0" + inherits "2" + minimatch "^3.0.0" + +fstream@^1.0.0, fstream@^1.0.10, fstream@^1.0.2: + version "1.0.11" + resolved "https://registry.yarnpkg.com/fstream/-/fstream-1.0.11.tgz#5c1fb1f117477114f0632a0eb4b71b3cb0fd3171" + dependencies: + graceful-fs "^4.1.2" + inherits "~2.0.0" + mkdirp ">=0.5 0" + rimraf "2" + function-bind@^1.0.2: version "1.1.0" resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.0.tgz#16176714c801798e4e8f2cf7f7529467bb4a5771" +gauge@~2.7.3: + version "2.7.4" + resolved "https://registry.yarnpkg.com/gauge/-/gauge-2.7.4.tgz#2c03405c7538c39d7eb37b317022e325fb018bf7" + dependencies: + aproba "^1.0.3" + console-control-strings "^1.0.0" + has-unicode "^2.0.0" + object-assign "^4.1.0" + signal-exit "^3.0.0" + string-width "^1.0.1" + strip-ansi "^3.0.1" + wide-align "^1.1.0" + generate-function@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/generate-function/-/generate-function-2.0.0.tgz#6858fe7c0969b7d4e9093337647ac79f60dfbe74" @@ -1137,18 +1903,49 @@ generate-object-property@^1.1.0: dependencies: is-property "^1.0.0" -glob@7.0.5: - version "7.0.5" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.0.5.tgz#b4202a69099bbb4d292a7c1b95b6682b67ebdc95" +get-caller-file@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-1.0.2.tgz#f702e63127e7e231c160a80c1554acb70d5047e5" + +get-port@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/get-port/-/get-port-3.1.0.tgz#ef01b18a84ca6486970ff99e54446141a73ffd3e" + +get-stdin@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-4.0.1.tgz#b968c6b0a04384324902e8bf1a5df32579a450fe" + +get-stream@^2.2.0: + version "2.3.1" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-2.3.1.tgz#5f38f93f346009666ee0150a054167f91bdd95de" dependencies: - fs.realpath "^1.0.0" - inflight "^1.0.4" - inherits "2" - minimatch "^3.0.2" - once "^1.3.0" - path-is-absolute "^1.0.0" + object-assign "^4.0.1" + pinkie-promise "^2.0.0" -glob@^7.0.0, glob@^7.0.3, glob@^7.0.5: +get-stream@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-3.0.0.tgz#8e943d1358dc37555054ecbe2edb05aa174ede14" + +getpass@^0.1.1: + version "0.1.7" + resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa" + dependencies: + assert-plus "^1.0.0" + +glob-base@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/glob-base/-/glob-base-0.3.0.tgz#dbb164f6221b1c0b1ccf82aea328b497df0ea3c4" + dependencies: + glob-parent "^2.0.0" + is-glob "^2.0.0" + +glob-parent@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-2.0.0.tgz#81383d72db054fcccf5336daa902f182f6edbb28" + dependencies: + is-glob "^2.0.0" + +glob@^7.0.0, glob@^7.0.3, glob@^7.0.5, glob@^7.0.6: version "7.1.1" resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.1.tgz#805211df04faaf1c63a3600306cdf5ade50b2ec8" dependencies: @@ -1174,17 +1971,56 @@ globby@^5.0.0: pify "^2.0.0" pinkie-promise "^2.0.0" -graceful-fs@^4.1.2: +globby@^6.0.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/globby/-/globby-6.1.0.tgz#f5a6d70e8395e21c858fb0489d64df02424d506c" + dependencies: + array-union "^1.0.1" + glob "^7.0.3" + object-assign "^4.0.1" + pify "^2.0.0" + pinkie-promise "^2.0.0" + +got@^6.7.1: + version "6.7.1" + resolved "https://registry.yarnpkg.com/got/-/got-6.7.1.tgz#240cd05785a9a18e561dc1b44b41c763ef1e8db0" + dependencies: + create-error-class "^3.0.0" + duplexer3 "^0.1.4" + get-stream "^3.0.0" + is-redirect "^1.0.0" + is-retry-allowed "^1.0.0" + is-stream "^1.0.0" + lowercase-keys "^1.0.0" + safe-buffer "^5.0.1" + timed-out "^4.0.0" + unzip-response "^2.0.1" + url-parse-lax "^1.0.0" + +graceful-fs@^4.1.11, graceful-fs@^4.1.2, graceful-fs@^4.1.6: version "4.1.11" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.11.tgz#0e8bdfe4d1ddb8854d64e04ea7c00e2a026e5658" -"graceful-readlink@>= 1.0.0": - version "1.0.1" - resolved "https://registry.yarnpkg.com/graceful-readlink/-/graceful-readlink-1.0.1.tgz#4cafad76bc62f02fa039b2f94e9a3dd3a391a725" +handlebars@^4.0.3: + version "4.0.10" + resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.0.10.tgz#3d30c718b09a3d96f23ea4cc1f403c4d3ba9ff4f" + dependencies: + async "^1.4.0" + optimist "^0.6.1" + source-map "^0.4.4" + optionalDependencies: + uglify-js "^2.6" + +har-schema@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-1.0.5.tgz#d263135f43307c02c602afc8fe95970c0151369e" -growl@1.9.2: - version "1.9.2" - resolved "https://registry.yarnpkg.com/growl/-/growl-1.9.2.tgz#0ea7743715db8d8de2c5ede1775e1b45ac85c02f" +har-validator@~4.2.1: + version "4.2.1" + resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-4.2.1.tgz#33481d0f1bbff600dd203d75812a6a5fba002e2a" + dependencies: + ajv "^4.9.1" + har-schema "^1.0.5" has-ansi@^2.0.0: version "2.0.0" @@ -1192,16 +2028,45 @@ has-ansi@^2.0.0: dependencies: ansi-regex "^2.0.0" +has-color@~0.1.0: + version "0.1.7" + resolved "https://registry.yarnpkg.com/has-color/-/has-color-0.1.7.tgz#67144a5260c34fc3cca677d041daf52fe7b78b2f" + has-flag@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-1.0.0.tgz#9d9e793165ce017a00f00418c43f942a7b1d11fa" +has-flag@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-2.0.0.tgz#e8207af1cc7b30d446cc70b734b5e8be18f88d51" + +has-unicode@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9" + +has-yarn@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-yarn/-/has-yarn-1.0.0.tgz#89e25db604b725c8f5976fff0addc921b828a5a7" + has@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/has/-/has-1.0.1.tgz#8461733f538b0837c9361e39a9ab9e9704dc2f28" dependencies: function-bind "^1.0.2" +hawk@~3.1.3: + version "3.1.3" + resolved "https://registry.yarnpkg.com/hawk/-/hawk-3.1.3.tgz#078444bd7c1640b0fe540d2c9b73d59678e8e1c4" + dependencies: + boom "2.x.x" + cryptiles "2.x.x" + hoek "2.x.x" + sntp "1.x.x" + +hoek@2.x.x: + version "2.16.3" + resolved "https://registry.yarnpkg.com/hoek/-/hoek-2.16.3.tgz#20bb7403d3cea398e91dc4710a8ff1b8274a25ed" + home-or-tmp@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/home-or-tmp/-/home-or-tmp-2.0.0.tgz#e36c3f2d2cae7d746a857e38d18d5f32a7882db8" @@ -1209,6 +2074,40 @@ home-or-tmp@^2.0.0: os-homedir "^1.0.0" os-tmpdir "^1.0.1" +hosted-git-info@^2.1.4: + version "2.4.2" + resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.4.2.tgz#0076b9f46a270506ddbaaea56496897460612a67" + +http-signature@~1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.1.1.tgz#df72e267066cd0ac67fb76adf8e134a8fbcf91bf" + dependencies: + assert-plus "^0.2.0" + jsprim "^1.2.2" + sshpk "^1.7.0" + +hullabaloo-config-manager@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/hullabaloo-config-manager/-/hullabaloo-config-manager-1.0.1.tgz#c72be7ba249a67c99b6ba3eb1f55837fa01acd8f" + dependencies: + dot-prop "^4.1.0" + es6-error "^4.0.2" + graceful-fs "^4.1.11" + indent-string "^3.1.0" + json5 "^0.5.1" + lodash.clonedeep "^4.5.0" + lodash.clonedeepwith "^4.5.0" + lodash.isequal "^4.5.0" + lodash.merge "^4.6.0" + md5-hex "^2.0.0" + package-hash "^2.0.0" + pkg-dir "^1.0.0" + resolve-from "^2.0.0" + +ignore-by-default@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/ignore-by-default/-/ignore-by-default-1.0.1.tgz#48ca6d72f6c6a3af00a9ad4ae6876be3889e2b09" + ignore@^3.2.0: version "3.2.6" resolved "https://registry.yarnpkg.com/ignore/-/ignore-3.2.6.tgz#26e8da0644be0bb4cb39516f6c79f0e0f4ffe48c" @@ -1217,6 +2116,16 @@ imurmurhash@^0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" +indent-string@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-2.1.0.tgz#8e2d48348742121b4a8218b7a137e9a52049dc80" + dependencies: + repeating "^2.0.0" + +indent-string@^3.0.0, indent-string@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-3.1.0.tgz#08ff4334603388399b329e6b9538dc7a3cf5de7d" + inflight@^1.0.4: version "1.0.6" resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" @@ -1224,7 +2133,7 @@ inflight@^1.0.4: once "^1.3.0" wrappy "1" -inherits@2, inherits@^2.0.3, inherits@~2.0.1: +inherits@2, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.0, inherits@~2.0.1: version "2.0.3" resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" @@ -1232,6 +2141,10 @@ inherits@2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.1.tgz#b17d08d326b4423e568eff719f91b0b1cbdf69f1" +ini@~1.3.0: + version "1.3.4" + resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.4.tgz#0537cb79daf59b59a1a517dff706c86ec039162e" + inquirer@^0.12.0: version "0.12.0" resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-0.12.0.tgz#1ef2bfd63504df0bc75785fff8c2c41df12f077e" @@ -1260,7 +2173,63 @@ invariant@^2.2.0, invariant@^2.2.2: dependencies: loose-envify "^1.0.0" -is-finite@^1.0.0: +invert-kv@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-1.0.0.tgz#104a8e4aaca6d3d8cd157a8ef8bfab2d7a3ffdb6" + +irregular-plurals@^1.0.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/irregular-plurals/-/irregular-plurals-1.2.0.tgz#38f299834ba8c00c30be9c554e137269752ff3ac" + +is-arrayish@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" + +is-binary-path@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-1.0.1.tgz#75f16642b480f187a711c814161fd3a4a7655898" + dependencies: + binary-extensions "^1.0.0" + +is-buffer@^1.1.5: + version "1.1.5" + resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.5.tgz#1f3b26ef613b214b88cbca23cc6c01d87961eecc" + +is-builtin-module@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-builtin-module/-/is-builtin-module-1.0.0.tgz#540572d34f7ac3119f8f76c30cbc1b1e037affbe" + dependencies: + builtin-modules "^1.0.0" + +is-ci@^1.0.7: + version "1.0.10" + resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-1.0.10.tgz#f739336b2632365061a9d48270cd56ae3369318e" + dependencies: + ci-info "^1.0.0" + +is-dotfile@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-dotfile/-/is-dotfile-1.0.2.tgz#2c132383f39199f8edc268ca01b9b007d205cc4d" + +is-equal-shallow@^0.1.3: + version "0.1.3" + resolved "https://registry.yarnpkg.com/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz#2238098fc221de0bcfa5d9eac4c45d638aa1c534" + dependencies: + is-primitive "^2.0.0" + +is-error@^2.2.0: + version "2.2.1" + resolved "https://registry.yarnpkg.com/is-error/-/is-error-2.2.1.tgz#684a96d84076577c98f4cdb40c6d26a5123bf19c" + +is-extendable@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89" + +is-extglob@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-1.0.0.tgz#ac468177c4943405a092fc8f29760c6ffc6206c0" + +is-finite@^1.0.0, is-finite@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/is-finite/-/is-finite-1.0.2.tgz#cc6677695602be550ef11e8b4aa6305342b6d0aa" dependencies: @@ -1276,6 +2245,16 @@ is-fullwidth-code-point@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" +is-generator-fn@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-generator-fn/-/is-generator-fn-1.0.0.tgz#969d49e1bb3329f6bb7f09089be26578b2ddd46a" + +is-glob@^2.0.0, is-glob@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-2.0.1.tgz#d096f926a3ded5600f3fdfd91198cb0888c2d863" + dependencies: + is-extglob "^1.0.0" + is-my-json-valid@^2.10.0: version "2.16.0" resolved "https://registry.yarnpkg.com/is-my-json-valid/-/is-my-json-valid-2.16.0.tgz#f079dd9bfdae65ee2038aae8acbc86ab109e3693" @@ -1285,6 +2264,26 @@ is-my-json-valid@^2.10.0: jsonpointer "^4.0.0" xtend "^4.0.0" +is-npm@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-npm/-/is-npm-1.0.0.tgz#f2fb63a65e4905b406c86072765a1a4dc793b9f4" + +is-number@^2.0.2, is-number@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-2.1.0.tgz#01fcbbb393463a548f2f466cce16dece49db908f" + dependencies: + kind-of "^3.0.2" + +is-obj@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-1.0.1.tgz#3e4729ac1f5fde025cd7d83a896dab9f4f67db0f" + +is-observable@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/is-observable/-/is-observable-0.2.0.tgz#b361311d83c6e5d726cabf5e250b0237106f5ae2" + dependencies: + symbol-observable "^0.2.2" + is-path-cwd@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-path-cwd/-/is-path-cwd-1.0.0.tgz#d225ec23132e89edd38fda767472e62e65f1106d" @@ -1301,31 +2300,207 @@ is-path-inside@^1.0.0: dependencies: path-is-inside "^1.0.1" +is-plain-obj@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-1.1.0.tgz#71a50c8429dfca773c92a390a4a03b39fcd51d3e" + +is-posix-bracket@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz#3334dc79774368e92f016e6fbc0a88f5cd6e6bc4" + +is-primitive@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-primitive/-/is-primitive-2.0.0.tgz#207bab91638499c07b2adf240a41a87210034575" + +is-promise@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-promise/-/is-promise-2.1.0.tgz#79a2a9ece7f096e80f36d2b2f3bc16c1ff4bf3fa" + is-property@^1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/is-property/-/is-property-1.0.2.tgz#57fe1c4e48474edd65b09911f26b1cd4095dda84" +is-redirect@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-redirect/-/is-redirect-1.0.0.tgz#1d03dded53bd8db0f30c26e4f95d36fc7c87dc24" + is-resolvable@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-resolvable/-/is-resolvable-1.0.0.tgz#8df57c61ea2e3c501408d100fb013cf8d6e0cc62" dependencies: tryit "^1.0.1" -isarray@^1.0.0, isarray@~1.0.0: +is-retry-allowed@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-retry-allowed/-/is-retry-allowed-1.1.0.tgz#11a060568b67339444033d0125a61a20d564fb34" + +is-stream@^1.0.0, is-stream@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" + +is-typedarray@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" + +is-url@^1.2.1: + version "1.2.2" + resolved "https://registry.yarnpkg.com/is-url/-/is-url-1.2.2.tgz#498905a593bf47cc2d9e7f738372bbf7696c7f26" + +is-utf8@^0.2.0, is-utf8@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/is-utf8/-/is-utf8-0.2.1.tgz#4b0da1442104d1b336340e80797e865cf39f7d72" + +isarray@1.0.0, isarray@^1.0.0, isarray@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" +isexe@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" + +isobject@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/isobject/-/isobject-2.1.0.tgz#f065561096a3f1da2ef46272f815c840d87e0c89" + dependencies: + isarray "1.0.0" + +isstream@~0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" + +istanbul-lib-coverage@^1.1.0, istanbul-lib-coverage@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-1.1.1.tgz#73bfb998885299415c93d38a3e9adf784a77a9da" + +istanbul-lib-hook@^1.0.6: + version "1.0.7" + resolved "https://registry.yarnpkg.com/istanbul-lib-hook/-/istanbul-lib-hook-1.0.7.tgz#dd6607f03076578fe7d6f2a630cf143b49bacddc" + dependencies: + append-transform "^0.4.0" + +istanbul-lib-instrument@^1.7.1: + version "1.7.2" + resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-1.7.2.tgz#6014b03d3470fb77638d5802508c255c06312e56" + dependencies: + babel-generator "^6.18.0" + babel-template "^6.16.0" + babel-traverse "^6.18.0" + babel-types "^6.18.0" + babylon "^6.13.0" + istanbul-lib-coverage "^1.1.1" + semver "^5.3.0" + +istanbul-lib-report@^1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/istanbul-lib-report/-/istanbul-lib-report-1.1.1.tgz#f0e55f56655ffa34222080b7a0cd4760e1405fc9" + dependencies: + istanbul-lib-coverage "^1.1.1" + mkdirp "^0.5.1" + path-parse "^1.0.5" + supports-color "^3.1.2" + +istanbul-lib-source-maps@^1.2.0: + version "1.2.1" + resolved "https://registry.yarnpkg.com/istanbul-lib-source-maps/-/istanbul-lib-source-maps-1.2.1.tgz#a6fe1acba8ce08eebc638e572e294d267008aa0c" + dependencies: + debug "^2.6.3" + istanbul-lib-coverage "^1.1.1" + mkdirp "^0.5.1" + rimraf "^2.6.1" + source-map "^0.5.3" + +istanbul-reports@^1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-1.1.1.tgz#042be5c89e175bc3f86523caab29c014e77fee4e" + dependencies: + handlebars "^4.0.3" + +jest-diff@19.0.0, jest-diff@^19.0.0: + version "19.0.0" + resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-19.0.0.tgz#d1563cfc56c8b60232988fbc05d4d16ed90f063c" + dependencies: + chalk "^1.1.3" + diff "^3.0.0" + jest-matcher-utils "^19.0.0" + pretty-format "^19.0.0" + +jest-file-exists@^19.0.0: + version "19.0.0" + resolved "https://registry.yarnpkg.com/jest-file-exists/-/jest-file-exists-19.0.0.tgz#cca2e587a11ec92e24cfeab3f8a94d657f3fceb8" + +jest-matcher-utils@^19.0.0: + version "19.0.0" + resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-19.0.0.tgz#5ecd9b63565d2b001f61fbf7ec4c7f537964564d" + dependencies: + chalk "^1.1.3" + pretty-format "^19.0.0" + +jest-message-util@^19.0.0: + version "19.0.0" + resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-19.0.0.tgz#721796b89c0e4d761606f9ba8cb828a3b6246416" + dependencies: + chalk "^1.1.1" + micromatch "^2.3.11" + +jest-mock@^19.0.0: + version "19.0.0" + resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-19.0.0.tgz#67038641e9607ab2ce08ec4a8cb83aabbc899d01" + +jest-snapshot@19.0.2: + version "19.0.2" + resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-19.0.2.tgz#9c1b216214f7187c38bfd5c70b1efab16b0ff50b" + dependencies: + chalk "^1.1.3" + jest-diff "^19.0.0" + jest-file-exists "^19.0.0" + jest-matcher-utils "^19.0.0" + jest-util "^19.0.2" + natural-compare "^1.4.0" + pretty-format "^19.0.0" + +jest-util@^19.0.2: + version "19.0.2" + resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-19.0.2.tgz#e0a0232a2ab9e6b2b53668bdb3534c2b5977ed41" + dependencies: + chalk "^1.1.1" + graceful-fs "^4.1.6" + jest-file-exists "^19.0.0" + jest-message-util "^19.0.0" + jest-mock "^19.0.0" + jest-validate "^19.0.2" + leven "^2.0.0" + mkdirp "^0.5.1" + +jest-validate@^19.0.2: + version "19.0.2" + resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-19.0.2.tgz#dc534df5f1278d5b63df32b14241d4dbf7244c0c" + dependencies: + chalk "^1.1.1" + jest-matcher-utils "^19.0.0" + leven "^2.0.0" + pretty-format "^19.0.0" + +jodid25519@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/jodid25519/-/jodid25519-1.0.2.tgz#06d4912255093419477d425633606e0e90782967" + dependencies: + jsbn "~0.1.0" + js-tokens@^3.0.0: version "3.0.1" resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.1.tgz#08e9f132484a2c45a30907e9dc4d5567b7f114d7" -js-yaml@^3.5.1: +js-yaml@^3.5.1, js-yaml@^3.8.2: version "3.8.2" resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.8.2.tgz#02d3e2c0f6beab20248d412c352203827d786721" dependencies: argparse "^1.0.7" esprima "^3.1.1" +jsbn@~0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" + jsesc@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-1.3.0.tgz#46c3fec8c1892b12b0833db9bc7622176dbab34b" @@ -1338,17 +2513,21 @@ jsesc@~0.5.0: version "0.5.0" resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-0.5.0.tgz#e7dee66e35d6fc16f710fe91d5cf69f70f08911d" +json-schema@0.2.3: + version "0.2.3" + resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13" + json-stable-stringify@^1.0.0, json-stable-stringify@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz#9a759d39c5f2ff503fd5300646ed445f88c4f9af" dependencies: jsonify "~0.0.0" -json3@3.3.2: - version "3.3.2" - resolved "https://registry.yarnpkg.com/json3/-/json3-3.3.2.tgz#3c0434743df93e2f5c42aee7b19bcb483575f4e1" +json-stringify-safe@~5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" -json5@^0.5.0: +json5@^0.5.0, json5@^0.5.1: version "0.5.1" resolved "https://registry.yarnpkg.com/json5/-/json5-0.5.1.tgz#1eade7acc012034ad84e2396767ead9fa5495821" @@ -1360,6 +2539,51 @@ jsonpointer@^4.0.0: version "4.0.1" resolved "https://registry.yarnpkg.com/jsonpointer/-/jsonpointer-4.0.1.tgz#4fd92cb34e0e9db3c89c8622ecf51f9b978c6cb9" +jsprim@^1.2.2: + version "1.4.0" + resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.0.tgz#a3b87e40298d8c380552d8cc7628a0bb95a22918" + dependencies: + assert-plus "1.0.0" + extsprintf "1.0.2" + json-schema "0.2.3" + verror "1.3.6" + +kind-of@^3.0.2: + version "3.2.2" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64" + dependencies: + is-buffer "^1.1.5" + +last-line-stream@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/last-line-stream/-/last-line-stream-1.0.0.tgz#d1b64d69f86ff24af2d04883a2ceee14520a5600" + dependencies: + through2 "^2.0.0" + +latest-version@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/latest-version/-/latest-version-3.1.0.tgz#a205383fea322b33b5ae3b18abee0dc2f356ee15" + dependencies: + package-json "^4.0.0" + +lazy-cache@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/lazy-cache/-/lazy-cache-1.0.4.tgz#a1d78fc3a50474cb80845d3b3b6e1da49a446e8e" + +lazy-req@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/lazy-req/-/lazy-req-2.0.0.tgz#c9450a363ecdda2e6f0c70132ad4f37f8f06f2b4" + +lcid@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/lcid/-/lcid-1.0.0.tgz#308accafa0bc483a3867b4b6f2b9506251d1b835" + dependencies: + invert-kv "^1.0.0" + +leven@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/leven/-/leven-2.1.0.tgz#c2e7a9f772094dee9d34202ae8acce4687875580" + levn@^0.3.0, levn@~0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee" @@ -1367,60 +2591,71 @@ levn@^0.3.0, levn@~0.3.0: prelude-ls "~1.1.2" type-check "~0.3.2" -lodash._baseassign@^3.0.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/lodash._baseassign/-/lodash._baseassign-3.2.0.tgz#8c38a099500f215ad09e59f1722fd0c52bfe0a4e" +load-json-file@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-1.1.0.tgz#956905708d58b4bab4c2261b04f59f31c99374c0" dependencies: - lodash._basecopy "^3.0.0" - lodash.keys "^3.0.0" + graceful-fs "^4.1.2" + parse-json "^2.2.0" + pify "^2.0.0" + pinkie-promise "^2.0.0" + strip-bom "^2.0.0" -lodash._basecopy@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/lodash._basecopy/-/lodash._basecopy-3.0.1.tgz#8da0e6a876cf344c0ad8a54882111dd3c5c7ca36" +load-json-file@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-2.0.0.tgz#7947e42149af80d696cbf797bcaabcfe1fe29ca8" + dependencies: + graceful-fs "^4.1.2" + parse-json "^2.2.0" + pify "^2.0.0" + strip-bom "^3.0.0" -lodash._basecreate@^3.0.0: - version "3.0.3" - resolved "https://registry.yarnpkg.com/lodash._basecreate/-/lodash._basecreate-3.0.3.tgz#1bc661614daa7fc311b7d03bf16806a0213cf821" +locate-path@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-2.0.0.tgz#2b568b265eec944c6d9c0de9c3dbbbca0354cd8e" + dependencies: + p-locate "^2.0.0" + path-exists "^3.0.0" -lodash._getnative@^3.0.0: - version "3.9.1" - resolved "https://registry.yarnpkg.com/lodash._getnative/-/lodash._getnative-3.9.1.tgz#570bc7dede46d61cdcde687d65d3eecbaa3aaff5" +lodash.clonedeep@^4.5.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz#e23f3f9c4f8fbdde872529c1071857a086e5ccef" -lodash._isiterateecall@^3.0.0: - version "3.0.9" - resolved "https://registry.yarnpkg.com/lodash._isiterateecall/-/lodash._isiterateecall-3.0.9.tgz#5203ad7ba425fae842460e696db9cf3e6aac057c" +lodash.clonedeepwith@^4.5.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/lodash.clonedeepwith/-/lodash.clonedeepwith-4.5.0.tgz#6ee30573a03a1a60d670a62ef33c10cf1afdbdd4" lodash.cond@^4.3.0: version "4.5.2" resolved "https://registry.yarnpkg.com/lodash.cond/-/lodash.cond-4.5.2.tgz#f471a1da486be60f6ab955d17115523dd1d255d5" -lodash.create@3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/lodash.create/-/lodash.create-3.1.1.tgz#d7f2849f0dbda7e04682bb8cd72ab022461debe7" - dependencies: - lodash._baseassign "^3.0.0" - lodash._basecreate "^3.0.0" - lodash._isiterateecall "^3.0.0" +lodash.debounce@^4.0.3: + version "4.0.8" + resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af" -lodash.isarguments@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz#2f573d85c6a24289ff00663b491c1d338ff3458a" +lodash.difference@^4.3.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/lodash.difference/-/lodash.difference-4.5.0.tgz#9ccb4e505d486b91651345772885a2df27fd017c" -lodash.isarray@^3.0.0: - version "3.0.4" - resolved "https://registry.yarnpkg.com/lodash.isarray/-/lodash.isarray-3.0.4.tgz#79e4eb88c36a8122af86f844aa9bcd851b5fbb55" +lodash.flatten@^4.2.0: + version "4.4.0" + resolved "https://registry.yarnpkg.com/lodash.flatten/-/lodash.flatten-4.4.0.tgz#f31c22225a9632d2bbf8e4addbef240aa765a61f" + +lodash.flattendeep@^4.4.0: + version "4.4.0" + resolved "https://registry.yarnpkg.com/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz#fb030917f86a3134e5bc9bec0d69e0013ddfedb2" + +lodash.isequal@^4.5.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/lodash.isequal/-/lodash.isequal-4.5.0.tgz#415c4478f2bcc30120c22ce10ed3226f7d3e18e0" lodash.isplainobject@^4.0.6: version "4.0.6" resolved "https://registry.yarnpkg.com/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz#7c526a52d89b45c45cc690b88163be0497f550cb" -lodash.keys@^3.0.0: - version "3.1.2" - resolved "https://registry.yarnpkg.com/lodash.keys/-/lodash.keys-3.1.2.tgz#4dbc0472b156be50a0b286855d1bd0b0c656098a" - dependencies: - lodash._getnative "^3.0.0" - lodash.isarguments "^3.0.0" - lodash.isarray "^3.0.0" +lodash.merge@^4.6.0: + version "4.6.0" + resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.0.tgz#69884ba144ac33fe699737a6086deffadd0f89c5" lodash.some@^4.6.0: version "4.6.0" @@ -1434,69 +2669,284 @@ lolex@1.3.2: version "1.3.2" resolved "https://registry.yarnpkg.com/lolex/-/lolex-1.3.2.tgz#7c3da62ffcb30f0f5a80a2566ca24e45d8a01f31" +longest@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/longest/-/longest-1.0.1.tgz#30a0b2da38f73770e8294a0d22e6625ed77d0097" + loose-envify@^1.0.0: version "1.3.1" resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.3.1.tgz#d1a8ad33fa9ce0e713d65fdd0ac8b748d478c848" dependencies: js-tokens "^3.0.0" -minimatch@^3.0.2, minimatch@^3.0.3: +loud-rejection@^1.0.0, loud-rejection@^1.2.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/loud-rejection/-/loud-rejection-1.6.0.tgz#5b46f80147edee578870f086d04821cf998e551f" + dependencies: + currently-unhandled "^0.4.1" + signal-exit "^3.0.0" + +lowercase-keys@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-1.0.0.tgz#4e3366b39e7f5457e35f1324bdf6f88d0bfc7306" + +lru-cache@^4.0.0, lru-cache@^4.0.1: + version "4.0.2" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.0.2.tgz#1d17679c069cda5d040991a09dbc2c0db377e55e" + dependencies: + pseudomap "^1.0.1" + yallist "^2.0.0" + +make-dir@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-1.0.0.tgz#97a011751e91dd87cfadef58832ebb04936de978" + dependencies: + pify "^2.3.0" + +map-obj@^1.0.0, map-obj@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/map-obj/-/map-obj-1.0.1.tgz#d933ceb9205d82bdcf4886f6742bdc2b4dea146d" + +matcher@^0.1.1: + version "0.1.2" + resolved "https://registry.yarnpkg.com/matcher/-/matcher-0.1.2.tgz#ef20cbde64c24c50cc61af5b83ee0b1b8ff00101" + dependencies: + escape-string-regexp "^1.0.4" + +md5-hex@^1.2.0, md5-hex@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/md5-hex/-/md5-hex-1.3.0.tgz#d2c4afe983c4370662179b8cad145219135046c4" + dependencies: + md5-o-matic "^0.1.1" + +md5-hex@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/md5-hex/-/md5-hex-2.0.0.tgz#d0588e9f1c74954492ecd24ac0ac6ce997d92e33" + dependencies: + md5-o-matic "^0.1.1" + +md5-o-matic@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/md5-o-matic/-/md5-o-matic-0.1.1.tgz#822bccd65e117c514fab176b25945d54100a03c3" + +meow@^3.7.0: + version "3.7.0" + resolved "https://registry.yarnpkg.com/meow/-/meow-3.7.0.tgz#72cb668b425228290abbfa856892587308a801fb" + dependencies: + camelcase-keys "^2.0.0" + decamelize "^1.1.2" + loud-rejection "^1.0.0" + map-obj "^1.0.1" + minimist "^1.1.3" + normalize-package-data "^2.3.4" + object-assign "^4.0.1" + read-pkg-up "^1.0.1" + redent "^1.0.0" + trim-newlines "^1.0.0" + +merge-source-map@^1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/merge-source-map/-/merge-source-map-1.0.3.tgz#da1415f2722a5119db07b14c4f973410863a2abf" + dependencies: + source-map "^0.5.3" + +micromatch@^2.1.5, micromatch@^2.3.11: + version "2.3.11" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-2.3.11.tgz#86677c97d1720b363431d04d0d15293bd38c1565" + dependencies: + arr-diff "^2.0.0" + array-unique "^0.2.1" + braces "^1.8.2" + expand-brackets "^0.1.4" + extglob "^0.3.1" + filename-regex "^2.0.0" + is-extglob "^1.0.0" + is-glob "^2.0.1" + kind-of "^3.0.2" + normalize-path "^2.0.1" + object.omit "^2.0.0" + parse-glob "^3.0.4" + regex-cache "^0.4.2" + +mime-db@~1.27.0: + version "1.27.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.27.0.tgz#820f572296bbd20ec25ed55e5b5de869e5436eb1" + +mime-types@^2.1.12, mime-types@~2.1.7: + version "2.1.15" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.15.tgz#a4ebf5064094569237b8cf70046776d09fc92aed" + dependencies: + mime-db "~1.27.0" + +mimic-fn@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-1.1.0.tgz#e667783d92e89dbd342818b5230b9d62a672ad18" + +minimatch@^3.0.0, minimatch@^3.0.2, minimatch@^3.0.3: version "3.0.3" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.3.tgz#2a4e4090b96b2db06a9d7df01055a62a77c9b774" dependencies: brace-expansion "^1.0.0" -minimist@0.0.8: +minimist@0.0.8, minimist@~0.0.1: version "0.0.8" resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" -mkdirp@0.5.1, mkdirp@^0.5.0, mkdirp@^0.5.1: +minimist@^1.1.3, minimist@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284" + +"mkdirp@>=0.5 0", mkdirp@^0.5.0, mkdirp@^0.5.1: version "0.5.1" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" dependencies: minimist "0.0.8" -mocha@^3.2.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/mocha/-/mocha-3.2.0.tgz#7dc4f45e5088075171a68896814e6ae9eb7a85e3" - dependencies: - browser-stdout "1.3.0" - commander "2.9.0" - debug "2.2.0" - diff "1.4.0" - escape-string-regexp "1.0.5" - glob "7.0.5" - growl "1.9.2" - json3 "3.3.2" - lodash.create "3.1.1" - mkdirp "0.5.1" - supports-color "3.1.2" - ms@0.7.1: version "0.7.1" resolved "https://registry.yarnpkg.com/ms/-/ms-0.7.1.tgz#9cd13c03adbff25b65effde7ce864ee952017098" -ms@0.7.2: +ms@0.7.2, ms@^0.7.1: version "0.7.2" resolved "https://registry.yarnpkg.com/ms/-/ms-0.7.2.tgz#ae25cf2512b3885a1d95d7f037868d8431124765" +multimatch@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/multimatch/-/multimatch-2.1.0.tgz#9c7906a22fb4c02919e2f5f75161b4cdbd4b2a2b" + dependencies: + array-differ "^1.0.0" + array-union "^1.0.1" + arrify "^1.0.0" + minimatch "^3.0.0" + mute-stream@0.0.5: version "0.0.5" resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.5.tgz#8fbfabb0a98a253d3184331f9e8deb7372fac6c0" +nan@^2.3.0: + version "2.6.2" + resolved "https://registry.yarnpkg.com/nan/-/nan-2.6.2.tgz#e4ff34e6c95fdfb5aecc08de6596f43605a7db45" + natural-compare@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" +node-pre-gyp@^0.6.29: + version "0.6.34" + resolved "https://registry.yarnpkg.com/node-pre-gyp/-/node-pre-gyp-0.6.34.tgz#94ad1c798a11d7fc67381b50d47f8cc18d9799f7" + dependencies: + mkdirp "^0.5.1" + nopt "^4.0.1" + npmlog "^4.0.2" + rc "^1.1.7" + request "^2.81.0" + rimraf "^2.6.1" + semver "^5.3.0" + tar "^2.2.1" + tar-pack "^3.4.0" + +nopt@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/nopt/-/nopt-4.0.1.tgz#d0d4685afd5415193c8c7505602d0d17cd64474d" + dependencies: + abbrev "1" + osenv "^0.1.4" + +normalize-package-data@^2.3.2, normalize-package-data@^2.3.4: + version "2.3.8" + resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.3.8.tgz#d819eda2a9dedbd1ffa563ea4071d936782295bb" + dependencies: + hosted-git-info "^2.1.4" + is-builtin-module "^1.0.0" + semver "2 || 3 || 4 || 5" + validate-npm-package-license "^3.0.1" + +normalize-path@^2.0.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-2.1.1.tgz#1ab28b556e198363a8c1a6f7e6fa20137fe6aed9" + dependencies: + remove-trailing-separator "^1.0.1" + +npm-run-path@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-1.0.0.tgz#f5c32bf595fe81ae927daec52e82f8b000ac3c8f" + dependencies: + path-key "^1.0.0" + +npm-run-path@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-2.0.2.tgz#35a9232dfa35d7067b4cb2ddf2357b1871536c5f" + dependencies: + path-key "^2.0.0" + +npmlog@^4.0.2: + version "4.1.0" + resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.1.0.tgz#dc59bee85f64f00ed424efb2af0783df25d1c0b5" + dependencies: + are-we-there-yet "~1.1.2" + console-control-strings "~1.1.0" + gauge "~2.7.3" + set-blocking "~2.0.0" + number-is-nan@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" +nyc@^10.3.2: + version "10.3.2" + resolved "https://registry.yarnpkg.com/nyc/-/nyc-10.3.2.tgz#f27f4d91f2a9db36c24f574ff5c6efff0233de46" + dependencies: + archy "^1.0.0" + arrify "^1.0.1" + caching-transform "^1.0.0" + convert-source-map "^1.3.0" + debug-log "^1.0.1" + default-require-extensions "^1.0.0" + find-cache-dir "^0.1.1" + find-up "^1.1.2" + foreground-child "^1.5.3" + glob "^7.0.6" + istanbul-lib-coverage "^1.1.0" + istanbul-lib-hook "^1.0.6" + istanbul-lib-instrument "^1.7.1" + istanbul-lib-report "^1.1.0" + istanbul-lib-source-maps "^1.2.0" + istanbul-reports "^1.1.0" + md5-hex "^1.2.0" + merge-source-map "^1.0.2" + micromatch "^2.3.11" + mkdirp "^0.5.0" + resolve-from "^2.0.0" + rimraf "^2.5.4" + signal-exit "^3.0.1" + spawn-wrap "1.2.4" + test-exclude "^4.1.0" + yargs "^7.1.0" + yargs-parser "^5.0.0" + +oauth-sign@~0.8.1: + version "0.8.2" + resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.8.2.tgz#46a6ab7f0aead8deae9ec0565780b7d4efeb9d43" + object-assign@^4.0.1, object-assign@^4.1.0: version "4.1.1" resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" -once@^1.3.0: +object.omit@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/object.omit/-/object.omit-2.0.1.tgz#1a9c744829f39dbb858c76ca3579ae2a54ebd1fa" + dependencies: + for-own "^0.1.4" + is-extendable "^0.1.1" + +observable-to-promise@^0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/observable-to-promise/-/observable-to-promise-0.5.0.tgz#c828f0f0dc47e9f86af8a4977c5d55076ce7a91f" + dependencies: + is-observable "^0.2.0" + symbol-observable "^1.0.4" + +once@^1.3.0, once@^1.3.3: version "1.4.0" resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" dependencies: @@ -1506,6 +2956,25 @@ onetime@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/onetime/-/onetime-1.1.0.tgz#a1f7838f8314c516f05ecefcbc4ccfe04b4ed789" +onetime@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/onetime/-/onetime-2.0.1.tgz#067428230fd67443b2794b22bba528b6867962d4" + dependencies: + mimic-fn "^1.0.0" + +optimist@^0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/optimist/-/optimist-0.6.1.tgz#da3ea74686fa21a19a111c326e90eb15a0196686" + dependencies: + minimist "~0.0.1" + wordwrap "~0.0.2" + +option-chain@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/option-chain/-/option-chain-0.1.1.tgz#e9b811e006f1c0f54802f28295bfc8970f8dcfbd" + dependencies: + object-assign "^4.0.1" + optionator@^0.8.2: version "0.8.2" resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.2.tgz#364c5e409d3f4d6301d6c0b4c05bba50180aeb64" @@ -1517,20 +2986,98 @@ optionator@^0.8.2: type-check "~0.3.2" wordwrap "~1.0.0" -os-homedir@^1.0.0: +os-homedir@^1.0.0, os-homedir@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3" -os-tmpdir@^1.0.1: +os-locale@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-1.4.0.tgz#20f9f17ae29ed345e8bde583b13d2009803c14d9" + dependencies: + lcid "^1.0.0" + +os-tmpdir@^1.0.0, os-tmpdir@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" +osenv@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/osenv/-/osenv-0.1.4.tgz#42fe6d5953df06c8064be6f176c3d05aaaa34644" + dependencies: + os-homedir "^1.0.0" + os-tmpdir "^1.0.0" + +p-finally@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae" + +p-limit@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-1.1.0.tgz#b07ff2d9a5d88bec806035895a2bab66a27988bc" + +p-locate@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-2.0.0.tgz#20a0103b222a70c8fd39cc2e580680f3dde5ec43" + dependencies: + p-limit "^1.1.0" + +package-hash@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/package-hash/-/package-hash-1.2.0.tgz#003e56cd57b736a6ed6114cc2b81542672770e44" + dependencies: + md5-hex "^1.3.0" + +package-hash@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/package-hash/-/package-hash-2.0.0.tgz#78ae326c89e05a4d813b68601977af05c00d2a0d" + dependencies: + graceful-fs "^4.1.11" + lodash.flattendeep "^4.4.0" + md5-hex "^2.0.0" + release-zalgo "^1.0.0" + +package-json@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/package-json/-/package-json-4.0.1.tgz#8869a0401253661c4c4ca3da6c2121ed555f5eed" + dependencies: + got "^6.7.1" + registry-auth-token "^3.0.1" + registry-url "^3.0.3" + semver "^5.1.0" + +parse-glob@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/parse-glob/-/parse-glob-3.0.4.tgz#b2c376cfb11f35513badd173ef0bb6e3a388391c" + dependencies: + glob-base "^0.3.0" + is-dotfile "^1.0.0" + is-extglob "^1.0.0" + is-glob "^2.0.0" + +parse-json@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-2.2.0.tgz#f480f40434ef80741f8469099f8dea18f55a4dc9" + dependencies: + error-ex "^1.2.0" + +parse-ms@^0.1.0: + version "0.1.2" + resolved "https://registry.yarnpkg.com/parse-ms/-/parse-ms-0.1.2.tgz#dd3fa25ed6c2efc7bdde12ad9b46c163aa29224e" + +parse-ms@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/parse-ms/-/parse-ms-1.0.1.tgz#56346d4749d78f23430ca0c713850aef91aa361d" + path-exists@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-2.1.0.tgz#0feb6c64f0fc518d9a754dd5efb62c7022761f4b" dependencies: pinkie-promise "^2.0.0" +path-exists@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515" + path-is-absolute@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" @@ -1539,24 +3086,67 @@ path-is-inside@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/path-is-inside/-/path-is-inside-1.0.2.tgz#365417dede44430d1c11af61027facf074bdfc53" +path-key@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/path-key/-/path-key-1.0.0.tgz#5d53d578019646c0d68800db4e146e6bdc2ac7af" + +path-key@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40" + path-parse@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.5.tgz#3c1adf871ea9cd6c9431b6ea2bd74a0ff055c4c1" -pify@^2.0.0: +path-type@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/path-type/-/path-type-1.1.0.tgz#59c44f7ee491da704da415da5a4070ba4f8fe441" + dependencies: + graceful-fs "^4.1.2" + pify "^2.0.0" + pinkie-promise "^2.0.0" + +path-type@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/path-type/-/path-type-2.0.0.tgz#f012ccb8415b7096fc2daa1054c3d72389594c73" + dependencies: + pify "^2.0.0" + +performance-now@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-0.2.0.tgz#33ef30c5c77d4ea21c5a53869d91b56d8f2555e5" + +pify@^2.0.0, pify@^2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" +pinkie-promise@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/pinkie-promise/-/pinkie-promise-1.0.0.tgz#d1da67f5482563bb7cf57f286ae2822ecfbf3670" + dependencies: + pinkie "^1.0.0" + pinkie-promise@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/pinkie-promise/-/pinkie-promise-2.0.1.tgz#2135d6dfa7a358c069ac9b178776288228450ffa" dependencies: pinkie "^2.0.0" +pinkie@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-1.0.0.tgz#5a47f28ba1015d0201bda7bf0f358e47bec8c7e4" + pinkie@^2.0.0: version "2.0.4" resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870" +pkg-conf@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/pkg-conf/-/pkg-conf-2.0.0.tgz#071c87650403bccfb9c627f58751bfe47c067279" + dependencies: + find-up "^2.0.0" + load-json-file "^2.0.0" + pkg-dir@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-1.0.0.tgz#7a4b508a8d5bb2d629d447056ff4e9c9314cf3d4" @@ -1569,6 +3159,16 @@ pkg-up@^1.0.0: dependencies: find-up "^1.0.0" +plur@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/plur/-/plur-1.0.0.tgz#db85c6814f5e5e5a3b49efc28d604fec62975156" + +plur@^2.0.0: + version "2.1.2" + resolved "https://registry.yarnpkg.com/plur/-/plur-2.1.2.tgz#7482452c1a0f508e3e344eaec312c91c29dc655a" + dependencies: + irregular-plurals "^1.0.0" + pluralize@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/pluralize/-/pluralize-1.2.1.tgz#d1a21483fd22bb41e58a12fa3421823140897c45" @@ -1577,6 +3177,34 @@ prelude-ls@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" +prepend-http@^1.0.1: + version "1.0.4" + resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-1.0.4.tgz#d4f4562b0ce3696e41ac52d0e002e57a635dc6dc" + +preserve@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/preserve/-/preserve-0.2.0.tgz#815ed1f6ebc65926f865b310c0713bcb3315ce4b" + +pretty-format@^19.0.0: + version "19.0.0" + resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-19.0.0.tgz#56530d32acb98a3fa4851c4e2b9d37b420684c84" + dependencies: + ansi-styles "^3.0.0" + +pretty-ms@^0.2.1: + version "0.2.2" + resolved "https://registry.yarnpkg.com/pretty-ms/-/pretty-ms-0.2.2.tgz#da879a682ff33a37011046f13d627f67c73b84f6" + dependencies: + parse-ms "^0.1.0" + +pretty-ms@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/pretty-ms/-/pretty-ms-2.1.0.tgz#4257c256df3fb0b451d6affaab021884126981dc" + dependencies: + is-finite "^1.0.1" + parse-ms "^1.0.0" + plur "^1.0.0" + private@^0.1.6: version "0.1.7" resolved "https://registry.yarnpkg.com/private/-/private-0.1.7.tgz#68ce5e8a1ef0a23bb570cc28537b5332aba63ef1" @@ -1589,7 +3217,65 @@ progress@^1.1.8: version "1.1.8" resolved "https://registry.yarnpkg.com/progress/-/progress-1.1.8.tgz#e260c78f6161cdd9b0e56cc3e0a85de17c7a57be" -readable-stream@^2.2.2: +pseudomap@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3" + +punycode@^1.4.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e" + +qs@~6.4.0: + version "6.4.0" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.4.0.tgz#13e26d28ad6b0ffaa91312cd3bf708ed351e7233" + +randomatic@^1.1.3: + version "1.1.6" + resolved "https://registry.yarnpkg.com/randomatic/-/randomatic-1.1.6.tgz#110dcabff397e9dcff7c0789ccc0a49adf1ec5bb" + dependencies: + is-number "^2.0.2" + kind-of "^3.0.2" + +rc@^1.0.1, rc@^1.1.6, rc@^1.1.7: + version "1.2.1" + resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.1.tgz#2e03e8e42ee450b8cb3dce65be1bf8974e1dfd95" + dependencies: + deep-extend "~0.4.0" + ini "~1.3.0" + minimist "^1.2.0" + strip-json-comments "~2.0.1" + +read-pkg-up@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-1.0.1.tgz#9d63c13276c065918d57f002a57f40a1b643fb02" + dependencies: + find-up "^1.0.0" + read-pkg "^1.0.0" + +read-pkg-up@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-2.0.0.tgz#6b72a8048984e0c41e79510fd5e9fa99b3b549be" + dependencies: + find-up "^2.0.0" + read-pkg "^2.0.0" + +read-pkg@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-1.1.0.tgz#f5ffaa5ecd29cb31c0474bca7d756b6bb29e3f28" + dependencies: + load-json-file "^1.0.0" + normalize-package-data "^2.3.2" + path-type "^1.0.0" + +read-pkg@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-2.0.0.tgz#8ef1c0623c6a6db0dc6713c4bfac46332b2368f8" + dependencies: + load-json-file "^2.0.0" + normalize-package-data "^2.3.2" + path-type "^2.0.0" + +readable-stream@^2.0.2, readable-stream@^2.0.6, readable-stream@^2.1.4, readable-stream@^2.1.5, readable-stream@^2.2.2: version "2.2.6" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.2.6.tgz#8b43aed76e71483938d12a8d46c6cf1a00b1f816" dependencies: @@ -1601,6 +3287,15 @@ readable-stream@^2.2.2: string_decoder "~0.10.x" util-deprecate "~1.0.1" +readdirp@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-2.1.0.tgz#4ed0ad060df3073300c48440373f72d1cc642d78" + dependencies: + graceful-fs "^4.1.2" + minimatch "^3.0.2" + readable-stream "^2.0.2" + set-immediate-shim "^1.0.1" + readline2@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/readline2/-/readline2-1.0.1.tgz#41059608ffc154757b715d9989d199ffbf372e35" @@ -1615,6 +3310,13 @@ rechoir@^0.6.2: dependencies: resolve "^1.1.6" +redent@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/redent/-/redent-1.0.0.tgz#cf916ab1fd5f1f16dfb20822dd6ec7f730c2afde" + dependencies: + indent-string "^2.1.0" + strip-indent "^1.0.1" + regenerate@^1.2.1: version "1.3.2" resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.3.2.tgz#d1941c67bad437e1be76433add5b385f95b19260" @@ -1631,6 +3333,13 @@ regenerator-transform@0.9.8: babel-types "^6.19.0" private "^0.1.6" +regex-cache@^0.4.2: + version "0.4.3" + resolved "https://registry.yarnpkg.com/regex-cache/-/regex-cache-0.4.3.tgz#9b1a6c35d4d0dfcef5711ae651e8e9d3d7114145" + dependencies: + is-equal-shallow "^0.1.3" + is-primitive "^2.0.0" + regexpu-core@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-2.0.0.tgz#49d038837b8dcf8bfa5b9a42139938e6ea2ae240" @@ -1639,6 +3348,19 @@ regexpu-core@^2.0.0: regjsgen "^0.2.0" regjsparser "^0.1.4" +registry-auth-token@^3.0.1: + version "3.3.1" + resolved "https://registry.yarnpkg.com/registry-auth-token/-/registry-auth-token-3.3.1.tgz#fb0d3289ee0d9ada2cbb52af5dfe66cb070d3006" + dependencies: + rc "^1.1.6" + safe-buffer "^5.0.1" + +registry-url@^3.0.3: + version "3.1.0" + resolved "https://registry.yarnpkg.com/registry-url/-/registry-url-3.1.0.tgz#3d4ef870f73dde1d77f0cf9a381432444e174942" + dependencies: + rc "^1.0.1" + regjsgen@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/regjsgen/-/regjsgen-0.2.0.tgz#6c016adeac554f75823fe37ac05b92d5a4edb1f7" @@ -1649,12 +3371,69 @@ regjsparser@^0.1.4: dependencies: jsesc "~0.5.0" +release-zalgo@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/release-zalgo/-/release-zalgo-1.0.0.tgz#09700b7e5074329739330e535c5a90fb67851730" + dependencies: + es6-error "^4.0.1" + +remove-trailing-separator@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/remove-trailing-separator/-/remove-trailing-separator-1.0.1.tgz#615ebb96af559552d4bf4057c8436d486ab63cc4" + +repeat-element@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.2.tgz#ef089a178d1483baae4d93eb98b4f9e4e11d990a" + +repeat-string@^1.5.2: + version "1.6.1" + resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" + repeating@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/repeating/-/repeating-2.0.1.tgz#5214c53a926d3552707527fbab415dbc08d06dda" dependencies: is-finite "^1.0.0" +request@^2.81.0: + version "2.81.0" + resolved "https://registry.yarnpkg.com/request/-/request-2.81.0.tgz#c6928946a0e06c5f8d6f8a9333469ffda46298a0" + dependencies: + aws-sign2 "~0.6.0" + aws4 "^1.2.1" + caseless "~0.12.0" + combined-stream "~1.0.5" + extend "~3.0.0" + forever-agent "~0.6.1" + form-data "~2.1.1" + har-validator "~4.2.1" + hawk "~3.1.3" + http-signature "~1.1.0" + is-typedarray "~1.0.0" + isstream "~0.1.2" + json-stringify-safe "~5.0.1" + mime-types "~2.1.7" + oauth-sign "~0.8.1" + performance-now "^0.2.0" + qs "~6.4.0" + safe-buffer "^5.0.1" + stringstream "~0.0.4" + tough-cookie "~2.3.0" + tunnel-agent "^0.6.0" + uuid "^3.0.0" + +require-directory@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" + +require-main-filename@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-1.0.1.tgz#97f717b69d48784f5f526a6c5aa8ffdda055a4d1" + +require-precompiled@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/require-precompiled/-/require-precompiled-0.1.0.tgz#5a1b52eb70ebed43eb982e974c85ab59571e56fa" + require-uncached@^1.0.2: version "1.0.3" resolved "https://registry.yarnpkg.com/require-uncached/-/require-uncached-1.0.3.tgz#4e0d56d6c9662fd31e43011c4b95aa49955421d3" @@ -1662,10 +3441,20 @@ require-uncached@^1.0.2: caller-path "^0.1.0" resolve-from "^1.0.0" +resolve-cwd@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-1.0.0.tgz#4eaeea41ed040d1702457df64a42b2b07d246f9f" + dependencies: + resolve-from "^2.0.0" + resolve-from@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-1.0.1.tgz#26cbfe935d1aeeeabb29bc3fe5aeb01e93d44226" +resolve-from@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-2.0.0.tgz#9480ab20e94ffa1d9e80a804c7ea147611966b57" + resolve@1.1.7: version "1.1.7" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.1.7.tgz#203114d82ad2c5ed9e8e0411b3932875e889e97b" @@ -1683,7 +3472,20 @@ restore-cursor@^1.0.1: exit-hook "^1.0.0" onetime "^1.0.0" -rimraf@^2.2.8: +restore-cursor@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-2.0.0.tgz#9f7ee287f82fd326d4fd162923d62129eee0dfaf" + dependencies: + onetime "^2.0.0" + signal-exit "^3.0.2" + +right-align@^0.1.1: + version "0.1.3" + resolved "https://registry.yarnpkg.com/right-align/-/right-align-0.1.3.tgz#61339b722fe6a3515689210d24e14c96148613ef" + dependencies: + align-text "^0.1.1" + +rimraf@2, rimraf@^2.2.8, rimraf@^2.3.3, rimraf@^2.5.1, rimraf@^2.5.4, rimraf@^2.6.1: version "2.6.1" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.1.tgz#c2338ec643df7a1b7fe5c54fa86f57428a55f33d" dependencies: @@ -1737,10 +3539,32 @@ rx-lite@^3.1.2: version "3.1.2" resolved "https://registry.yarnpkg.com/rx-lite/-/rx-lite-3.1.2.tgz#19ce502ca572665f3b647b10939f97fd1615f102" +safe-buffer@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.0.1.tgz#d263ca54696cd8a306b5ca6551e92de57918fbe7" + samsam@1.1.2, samsam@~1.1: version "1.1.2" resolved "https://registry.yarnpkg.com/samsam/-/samsam-1.1.2.tgz#bec11fdc83a9fda063401210e40176c3024d1567" +semver-diff@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/semver-diff/-/semver-diff-2.1.0.tgz#4bbb8437c8d37e4b0cf1a68fd726ec6d645d6d36" + dependencies: + semver "^5.0.3" + +"semver@2 || 3 || 4 || 5", semver@^5.0.3, semver@^5.1.0, semver@^5.3.0: + version "5.3.0" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.3.0.tgz#9b2ce5d3de02d17c6012ad326aa6b4d0cf54f94f" + +set-blocking@^2.0.0, set-blocking@~2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" + +set-immediate-shim@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz#4b2b1b27eb808a9f8dcc481a58e5e56f599f3f61" + shelljs@^0.7.5: version "0.7.7" resolved "https://registry.yarnpkg.com/shelljs/-/shelljs-0.7.7.tgz#b2f5c77ef97148f4b4f6e22682e10bba8667cff1" @@ -1749,9 +3573,13 @@ shelljs@^0.7.5: interpret "^1.0.0" rechoir "^0.6.2" -sinon-chai@^2.8.0: - version "2.9.0" - resolved "https://registry.yarnpkg.com/sinon-chai/-/sinon-chai-2.9.0.tgz#34d820042bc9661a14527130d401eb462c49bb84" +signal-exit@^2.0.0: + version "2.1.2" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-2.1.2.tgz#375879b1f92ebc3b334480d038dc546a6d558564" + +signal-exit@^3.0.0, signal-exit@^3.0.1, signal-exit@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d" sinon@^1.17.7: version "1.17.7" @@ -1770,21 +3598,87 @@ slice-ansi@0.0.4: version "0.0.4" resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-0.0.4.tgz#edbf8903f66f7ce2f8eafd6ceed65e264c831b35" +slide@^1.1.5: + version "1.1.6" + resolved "https://registry.yarnpkg.com/slide/-/slide-1.1.6.tgz#56eb027d65b4d2dce6cb2e2d32c4d4afc9e1d707" + +sntp@1.x.x: + version "1.0.9" + resolved "https://registry.yarnpkg.com/sntp/-/sntp-1.0.9.tgz#6541184cc90aeea6c6e7b35e2659082443c66198" + dependencies: + hoek "2.x.x" + +sort-keys@^1.1.1, sort-keys@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/sort-keys/-/sort-keys-1.1.2.tgz#441b6d4d346798f1b4e49e8920adfba0e543f9ad" + dependencies: + is-plain-obj "^1.0.0" + source-map-support@^0.4.0, source-map-support@^0.4.2: version "0.4.14" resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.4.14.tgz#9d4463772598b86271b4f523f6c1f4e02a7d6aef" dependencies: source-map "^0.5.6" -source-map@^0.5.0, source-map@^0.5.6: +source-map@^0.4.4: + version "0.4.4" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.4.4.tgz#eba4f5da9c0dc999de68032d8b4f76173652036b" + dependencies: + amdefine ">=0.0.4" + +source-map@^0.5.0, source-map@^0.5.3, source-map@^0.5.6, source-map@~0.5.1: version "0.5.6" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.6.tgz#75ce38f52bf0733c5a7f0c118d81334a2bb5f412" +spawn-wrap@1.2.4: + version "1.2.4" + resolved "https://registry.yarnpkg.com/spawn-wrap/-/spawn-wrap-1.2.4.tgz#920eb211a769c093eebfbd5b0e7a5d2e68ab2e40" + dependencies: + foreground-child "^1.3.3" + mkdirp "^0.5.0" + os-homedir "^1.0.1" + rimraf "^2.3.3" + signal-exit "^2.0.0" + which "^1.2.4" + +spdx-correct@~1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-1.0.2.tgz#4b3073d933ff51f3912f03ac5519498a4150db40" + dependencies: + spdx-license-ids "^1.0.2" + +spdx-expression-parse@~1.0.0: + version "1.0.4" + resolved "https://registry.yarnpkg.com/spdx-expression-parse/-/spdx-expression-parse-1.0.4.tgz#9bdf2f20e1f40ed447fbe273266191fced51626c" + +spdx-license-ids@^1.0.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-1.2.2.tgz#c9df7a3424594ade6bd11900d596696dc06bac57" + sprintf-js@~1.0.2: version "1.0.3" resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" -string-width@^1.0.1: +sshpk@^1.7.0: + version "1.13.0" + resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.13.0.tgz#ff2a3e4fd04497555fed97b39a0fd82fafb3a33c" + dependencies: + asn1 "~0.2.3" + assert-plus "^1.0.0" + dashdash "^1.12.0" + getpass "^0.1.1" + optionalDependencies: + bcrypt-pbkdf "^1.0.0" + ecc-jsbn "~0.1.1" + jodid25519 "^1.0.0" + jsbn "~0.1.0" + tweetnacl "~0.14.0" + +stack-utils@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/stack-utils/-/stack-utils-1.0.1.tgz#d4f33ab54e8e38778b0ca5cfd3b3afb12db68620" + +string-width@^1.0.1, string-width@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3" dependencies: @@ -1803,30 +3697,68 @@ string_decoder@~0.10.x: version "0.10.31" resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-0.10.31.tgz#62e203bc41766c6c28c9fc84301dab1c5310fa94" -strip-ansi@^3.0.0: +stringstream@~0.0.4: + version "0.0.5" + resolved "https://registry.yarnpkg.com/stringstream/-/stringstream-0.0.5.tgz#4e484cd4de5a0bbbee18e46307710a8a81621878" + +strip-ansi@^3.0.0, strip-ansi@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" dependencies: ansi-regex "^2.0.0" +strip-ansi@~0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-0.1.1.tgz#39e8a98d044d150660abe4a6808acf70bb7bc991" + +strip-bom-buf@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/strip-bom-buf/-/strip-bom-buf-1.0.0.tgz#1cb45aaf57530f4caf86c7f75179d2c9a51dd572" + dependencies: + is-utf8 "^0.2.1" + +strip-bom@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-2.0.0.tgz#6219a85616520491f35788bdbf1447a99c7e6b0e" + dependencies: + is-utf8 "^0.2.0" + strip-bom@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3" +strip-eof@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf" + +strip-indent@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/strip-indent/-/strip-indent-1.0.1.tgz#0c7962a6adefa7bbd4ac366460a638552ae1a0a2" + dependencies: + get-stdin "^4.0.1" + strip-json-comments@~2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" -supports-color@3.1.2: - version "3.1.2" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-3.1.2.tgz#72a262894d9d408b956ca05ff37b2ed8a6e2a2d5" - dependencies: - has-flag "^1.0.0" - supports-color@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" +supports-color@^3.1.2, supports-color@^3.2.3: + version "3.2.3" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-3.2.3.tgz#65ac0504b3954171d8a64946b2ae3cbb8a5f54f6" + dependencies: + has-flag "^1.0.0" + +symbol-observable@^0.2.2: + version "0.2.4" + resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-0.2.4.tgz#95a83db26186d6af7e7a18dbd9760a2f86d08f40" + +symbol-observable@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.0.4.tgz#29bf615d4aa7121bdd898b22d4b3f9bc4e2aa03d" + table@^3.7.8: version "3.8.3" resolved "https://registry.yarnpkg.com/table/-/table-3.8.3.tgz#2bbc542f0fda9861a755d3947fefd8b3f513855f" @@ -1844,18 +3776,85 @@ tailored@2.4.5: dependencies: erlang-types "^1.0.0" -text-table@~0.2.0: +tar-pack@^3.4.0: + version "3.4.0" + resolved "https://registry.yarnpkg.com/tar-pack/-/tar-pack-3.4.0.tgz#23be2d7f671a8339376cbdb0b8fe3fdebf317984" + dependencies: + debug "^2.2.0" + fstream "^1.0.10" + fstream-ignore "^1.0.5" + once "^1.3.3" + readable-stream "^2.1.4" + rimraf "^2.5.1" + tar "^2.2.1" + uid-number "^0.0.6" + +tar@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/tar/-/tar-2.2.1.tgz#8e4d2a256c0e2185c6b18ad694aec968b83cb1d1" + dependencies: + block-stream "*" + fstream "^1.0.2" + inherits "2" + +term-size@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/term-size/-/term-size-0.1.1.tgz#87360b96396cab5760963714cda0d0cbeecad9ca" + dependencies: + execa "^0.4.0" + +test-exclude@^4.1.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/test-exclude/-/test-exclude-4.1.1.tgz#4d84964b0966b0087ecc334a2ce002d3d9341e26" + dependencies: + arrify "^1.0.1" + micromatch "^2.3.11" + object-assign "^4.1.0" + read-pkg-up "^1.0.1" + require-main-filename "^1.0.1" + +text-table@^0.2.0, text-table@~0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" +through2@^2.0.0: + version "2.0.3" + resolved "https://registry.yarnpkg.com/through2/-/through2-2.0.3.tgz#0004569b37c7c74ba39c43f3ced78d1ad94140be" + dependencies: + readable-stream "^2.1.5" + xtend "~4.0.1" + through@^2.3.6: version "2.3.8" resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" +time-require@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/time-require/-/time-require-0.1.2.tgz#f9e12cb370fc2605e11404582ba54ef5ca2b2d98" + dependencies: + chalk "^0.4.0" + date-time "^0.1.1" + pretty-ms "^0.2.1" + text-table "^0.2.0" + +timed-out@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/timed-out/-/timed-out-4.0.1.tgz#f32eacac5a175bea25d7fab565ab3ed8741ef56f" + to-fast-properties@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-1.0.2.tgz#f3f5c0c3ba7299a7ef99427e44633257ade43320" +tough-cookie@~2.3.0: + version "2.3.2" + resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.3.2.tgz#f081f76e4c85720e6c37a5faced737150d84072a" + dependencies: + punycode "^1.4.1" + +trim-newlines@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/trim-newlines/-/trim-newlines-1.0.0.tgz#5887966bb582a4503a41eb524f7d35011815a613" + trim-right@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/trim-right/-/trim-right-1.0.1.tgz#cb2e1203067e0c8de1f614094b9fe45704ea6003" @@ -1864,24 +3863,84 @@ tryit@^1.0.1: version "1.0.3" resolved "https://registry.yarnpkg.com/tryit/-/tryit-1.0.3.tgz#393be730a9446fd1ead6da59a014308f36c289cb" +tunnel-agent@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd" + dependencies: + safe-buffer "^5.0.1" + +tweetnacl@^0.14.3, tweetnacl@~0.14.0: + version "0.14.5" + resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" + type-check@~0.3.2: version "0.3.2" resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.3.2.tgz#5884cab512cf1d355e3fb784f30804b2b520db72" dependencies: prelude-ls "~1.1.2" -type-detect@0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-0.1.1.tgz#0ba5ec2a885640e470ea4e8505971900dac58822" - -type-detect@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-1.0.0.tgz#762217cc06db258ec48908a1298e8b95121e8ea2" - typedarray@^0.0.6: version "0.0.6" resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" +uglify-js@^2.6: + version "2.8.27" + resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-2.8.27.tgz#47787f912b0f242e5b984343be8e35e95f694c9c" + dependencies: + source-map "~0.5.1" + yargs "~3.10.0" + optionalDependencies: + uglify-to-browserify "~1.0.0" + +uglify-to-browserify@~1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz#6e0924d6bda6b5afe349e39a6d632850a0f882b7" + +uid-number@^0.0.6: + version "0.0.6" + resolved "https://registry.yarnpkg.com/uid-number/-/uid-number-0.0.6.tgz#0ea10e8035e8eb5b8e4449f06da1c730663baa81" + +uid2@0.0.3: + version "0.0.3" + resolved "https://registry.yarnpkg.com/uid2/-/uid2-0.0.3.tgz#483126e11774df2f71b8b639dcd799c376162b82" + +unique-string@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/unique-string/-/unique-string-1.0.0.tgz#9e1057cca851abb93398f8b33ae187b99caec11a" + dependencies: + crypto-random-string "^1.0.0" + +unique-temp-dir@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/unique-temp-dir/-/unique-temp-dir-1.0.0.tgz#6dce95b2681ca003eebfb304a415f9cbabcc5385" + dependencies: + mkdirp "^0.5.1" + os-tmpdir "^1.0.1" + uid2 "0.0.3" + +unzip-response@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/unzip-response/-/unzip-response-2.0.1.tgz#d2f0f737d16b0615e72a6935ed04214572d56f97" + +update-notifier@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/update-notifier/-/update-notifier-2.1.0.tgz#ec0c1e53536b76647a24b77cb83966d9315123d9" + dependencies: + boxen "^1.0.0" + chalk "^1.0.0" + configstore "^3.0.0" + is-npm "^1.0.0" + latest-version "^3.0.0" + lazy-req "^2.0.0" + semver-diff "^2.0.0" + xdg-basedir "^3.0.0" + +url-parse-lax@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/url-parse-lax/-/url-parse-lax-1.0.0.tgz#7af8f303645e9bd79a272e7a14ac68bc0609da73" + dependencies: + prepend-http "^1.0.1" + user-home@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/user-home/-/user-home-2.0.0.tgz#9c70bfd8169bc1dcbf48604e0f04b8b49cde9e9f" @@ -1898,20 +3957,153 @@ util-deprecate@~1.0.1: dependencies: inherits "2.0.1" +uuid@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.0.1.tgz#6544bba2dfda8c1cf17e629a3a305e2bb1fee6c1" + +validate-npm-package-license@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.1.tgz#2804babe712ad3379459acfbe24746ab2c303fbc" + dependencies: + spdx-correct "~1.0.0" + spdx-expression-parse "~1.0.0" + +verror@1.3.6: + version "1.3.6" + resolved "https://registry.yarnpkg.com/verror/-/verror-1.3.6.tgz#cff5df12946d297d2baaefaa2689e25be01c005c" + dependencies: + extsprintf "1.0.2" + +which-module@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/which-module/-/which-module-1.0.0.tgz#bba63ca861948994ff307736089e3b96026c2a4f" + +which@^1.2.4, which@^1.2.8, which@^1.2.9: + version "1.2.14" + resolved "https://registry.yarnpkg.com/which/-/which-1.2.14.tgz#9a87c4378f03e827cecaf1acdf56c736c01c14e5" + dependencies: + isexe "^2.0.0" + +wide-align@^1.1.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.2.tgz#571e0f1b0604636ebc0dfc21b0339bbe31341710" + dependencies: + string-width "^1.0.2" + +widest-line@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/widest-line/-/widest-line-1.0.0.tgz#0c09c85c2a94683d0d7eaf8ee097d564bf0e105c" + dependencies: + string-width "^1.0.1" + +window-size@0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/window-size/-/window-size-0.1.0.tgz#5438cd2ea93b202efa3a19fe8887aee7c94f9c9d" + +wordwrap@0.0.2, wordwrap@~0.0.2: + version "0.0.2" + resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-0.0.2.tgz#b79669bb42ecb409f83d583cad52ca17eaa1643f" + wordwrap@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb" +wrap-ansi@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-2.1.0.tgz#d8fc3d284dd05794fe84973caecdd1cf824fdd85" + dependencies: + string-width "^1.0.1" + strip-ansi "^3.0.1" + wrappy@1: version "1.0.2" resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" +write-file-atomic@^1.1.4: + version "1.3.4" + resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-1.3.4.tgz#f807a4f0b1d9e913ae7a48112e6cc3af1991b45f" + dependencies: + graceful-fs "^4.1.11" + imurmurhash "^0.1.4" + slide "^1.1.5" + +write-file-atomic@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-2.1.0.tgz#1769f4b551eedce419f0505deae2e26763542d37" + dependencies: + graceful-fs "^4.1.11" + imurmurhash "^0.1.4" + slide "^1.1.5" + +write-json-file@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/write-json-file/-/write-json-file-2.2.0.tgz#51862506bbb3b619eefab7859f1fd6c6d0530876" + dependencies: + detect-indent "^5.0.0" + graceful-fs "^4.1.2" + make-dir "^1.0.0" + pify "^2.0.0" + sort-keys "^1.1.1" + write-file-atomic "^2.0.0" + +write-pkg@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/write-pkg/-/write-pkg-2.1.0.tgz#353aa44c39c48c21440f5c08ce6abd46141c9c08" + dependencies: + sort-keys "^1.1.2" + write-json-file "^2.0.0" + write@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/write/-/write-0.2.1.tgz#5fc03828e264cea3fe91455476f7a3c566cb0757" dependencies: mkdirp "^0.5.1" -xtend@^4.0.0: +xdg-basedir@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/xdg-basedir/-/xdg-basedir-3.0.0.tgz#496b2cc109eca8dbacfe2dc72b603c17c5870ad4" + +xtend@^4.0.0, xtend@~4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.1.tgz#a5c6d532be656e23db820efb943a1f04998d63af" + +y18n@^3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/y18n/-/y18n-3.2.1.tgz#6d15fba884c08679c0d77e88e7759e811e07fa41" + +yallist@^2.0.0: + version "2.1.2" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52" + +yargs-parser@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-5.0.0.tgz#275ecf0d7ffe05c77e64e7c86e4cd94bf0e1228a" + dependencies: + camelcase "^3.0.0" + +yargs@^7.1.0: + version "7.1.0" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-7.1.0.tgz#6ba318eb16961727f5d284f8ea003e8d6154d0c8" + dependencies: + camelcase "^3.0.0" + cliui "^3.2.0" + decamelize "^1.1.1" + get-caller-file "^1.0.1" + os-locale "^1.4.0" + read-pkg-up "^1.0.1" + require-directory "^2.1.1" + require-main-filename "^1.0.1" + set-blocking "^2.0.0" + string-width "^1.0.2" + which-module "^1.0.0" + y18n "^3.2.1" + yargs-parser "^5.0.0" + +yargs@~3.10.0: + version "3.10.0" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-3.10.0.tgz#f7ee7bd857dd7c1d2d38c0e74efbd681d1431fd1" + dependencies: + camelcase "^1.0.2" + cliui "^2.1.0" + decamelize "^1.0.0" + window-size "0.1.0" From 33fe54e5dc2ffd486bf06b0fcded40a2901a6dac Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Mon, 29 May 2017 10:23:42 -0500 Subject: [PATCH 099/418] Consolidation of protocols --- lib/elixir_script/next/passes/find_used.ex | 43 +++-- lib/elixir_script/next/passes/translate.ex | 5 +- .../next/passes/translate/examples/example.ex | 2 +- .../next/passes/translate/module.ex | 37 ++-- .../next/passes/translate/protocol.ex | 180 ++++++++++++++++++ 5 files changed, 239 insertions(+), 28 deletions(-) create mode 100644 lib/elixir_script/next/passes/translate/protocol.ex diff --git a/lib/elixir_script/next/passes/find_used.ex b/lib/elixir_script/next/passes/find_used.ex index 07cde8f0..43faf4f4 100644 --- a/lib/elixir_script/next/passes/find_used.ex +++ b/lib/elixir_script/next/passes/find_used.ex @@ -69,8 +69,21 @@ defmodule ElixirScript.FindUsed do end defp walk_protocol(module, implementations, pid) do - ModuleState.put_module(pid, module, %{}) - Enum.each(implementations, fn({impl, info}) -> walk_module(impl, info, pid) end) + impls = Enum.map(implementations, fn {impl, %{attributes: attrs}} -> + protocol_impl = Keyword.fetch!(attrs, :protocol_impl) + impl_for = Keyword.fetch!(protocol_impl, :for) + {impl, impl_for} + end) + + first_implementation_functions = implementations |> hd |> elem(1) |> Map.get(:definitions) + + functions = Enum.map(first_implementation_functions, fn { name, _, _, _} -> name end) + + ModuleState.put_module(pid, module, %{protocol: true, impls: impls, functions: functions}) + + Enum.each(implementations, fn {impl, info} -> + walk_module(impl, info, pid) + end) end defp walk({{_name, _arity}, _type, _, clauses}, state) do @@ -105,13 +118,13 @@ defmodule ElixirScript.FindUsed do Enum.each(form, &walk(&1, state)) end - #defp walk(form, state) when is_atom(form) do - #if ElixirScript.Translate.Module.is_elixir_module(form) do - # if ModuleState.get_module(state.pid, form) == nil do - # execute(form, state.pid) - # end - #end - #end + defp walk(form, state) when is_atom(form) and form not in [BitString, Function, PID, Port, Reference, Any, Elixir] do + if ElixirScript.Translate.Module.is_elixir_module(form) do + if ModuleState.get_module(state.pid, form) == nil do + execute(form, state.pid) + end + end + end defp walk({a, b}, state) do walk({:{}, [], [a, b]}, state) @@ -219,6 +232,14 @@ defmodule ElixirScript.FindUsed do Enum.each(clauses, &walk(&1, state)) end + defp walk({{:., _, [:erlang, :apply]}, _, [module, function, params]}, state) do + walk({{:., [], [module, function]}, [], params}, state) + end + + defp walk({{:., _, [:erlang, :apply]}, _, [function, params]}, state) do + walk({function, [], params}, state) + end + defp walk({{:., _, [module, function]}, _, params}, _state) when module in @erlang_modules do IO.inspect {module, function, length(params)} nil @@ -237,11 +258,11 @@ defmodule ElixirScript.FindUsed do nil end - Enum.each(params, &walk(&1, state)) + walk(params, state) end defp walk({:super, _, params}, state) do - Enum.each(params, &walk(&1, state)) + walk(params, state) end defp walk({function, _, params}, state) when is_atom(function) and is_list(params) do diff --git a/lib/elixir_script/next/passes/translate.ex b/lib/elixir_script/next/passes/translate.ex index b32a05bb..8341a30a 100644 --- a/lib/elixir_script/next/passes/translate.ex +++ b/lib/elixir_script/next/passes/translate.ex @@ -11,8 +11,9 @@ defmodule ElixirScript.Translate do """ @spec execute([atom], pid) :: nil def execute(modules, pid) do - Enum.each(modules, fn({module, info}) -> - ElixirScript.Translate.Module.compile(module, info, pid) + Enum.each(modules, fn + {module, info} -> + ElixirScript.Translate.Module.compile(module, info, pid) end) end end diff --git a/lib/elixir_script/next/passes/translate/examples/example.ex b/lib/elixir_script/next/passes/translate/examples/example.ex index 02f457a1..2fc91703 100644 --- a/lib/elixir_script/next/passes/translate/examples/example.ex +++ b/lib/elixir_script/next/passes/translate/examples/example.ex @@ -1,6 +1,6 @@ defmodule Example do def start(_, _) do - Atom.to_string(:gravity) + Base.encode16("Hello") end end diff --git a/lib/elixir_script/next/passes/translate/module.ex b/lib/elixir_script/next/passes/translate/module.ex index 6d3f96bf..eb64d7ad 100644 --- a/lib/elixir_script/next/passes/translate/module.ex +++ b/lib/elixir_script/next/passes/translate/module.ex @@ -9,9 +9,13 @@ defmodule ElixirScript.Translate.Module do Translate the given module's ast to JavaScript AST """ + def compile(module, %{protocol: true} = info, pid) do + ElixirScript.Translate.Protocol.compile(module, info, pid) + end + def compile(module, info, pid) do %{ - attributes: _attrs, + attributes: attrs, compile_opts: _compile_opts, definitions: defs, file: _file, @@ -27,17 +31,22 @@ defmodule ElixirScript.Translate.Module do # Filter so that we only have the # Used functions to compile - used_defs = defs - |> Enum.filter(fn - { _, type, _, _} when type in [:defmacro, :defmacrop] -> false - { name, _, _, _} -> not(name in unreachable) - _ -> true - end) - |> Enum.filter(fn - { {:start, 2}, _, _, _ } -> true - { name, _, _, _} -> name in used - _ -> false - end) + reachable_defs = Enum.filter(defs, fn + { _, type, _, _} when type in [:defmacro, :defmacrop] -> false + { name, _, _, _} -> not(name in unreachable) + _ -> true + end) + + used_defs = if Keyword.has_key?(attrs, :protocol_impl) do + reachable_defs + else + Enum.filter(reachable_defs, fn + { {:start, 2}, _, _, _ } -> true + { name, _, _, _} -> name in used + _ -> false + end) + end + compiled_functions = used_defs |> Enum.map(&Function.compile(&1, state)) @@ -57,8 +66,8 @@ defmodule ElixirScript.Translate.Module do defp make_exports(reachable_defs) do exports = Enum.reduce(reachable_defs, [], fn {{name, arity}, :def, _, _}, list -> - function_name = ElixirScript.Translator.Identifier.make_function_name(name, arity) - list ++ [J.property(function_name, function_name, :init, true)] + function_name = ElixirScript.Translator.Identifier.make_function_name(name, arity) + list ++ [J.property(function_name, function_name, :init, true)] _, list -> list end) diff --git a/lib/elixir_script/next/passes/translate/protocol.ex b/lib/elixir_script/next/passes/translate/protocol.ex new file mode 100644 index 00000000..0b549292 --- /dev/null +++ b/lib/elixir_script/next/passes/translate/protocol.ex @@ -0,0 +1,180 @@ +defmodule ElixirScript.Translate.Protocol do + @moduledoc false + alias ESTree.Tools.Builder, as: J + alias ElixirScript.Translate.Function + alias ElixirScript.Translate.Form + alias ElixirScript.Translator.Identifier + alias ElixirScript.State, as: ModuleState + + + @doc """ + This compiles and consolidates the given protocol + """ + def compile(module, %{protocol: true, impls: impls, functions: functions} = info, pid) do + object = Enum.map(functions, fn {function, arity} -> + {Identifier.make_function_name(function, arity), J.function_expression([], [], J.block_statement([]))} + end) + |> Enum.map(fn({key, value}) -> ElixirScript.Translate.Forms.Map.make_property(key, value) end) + |> J.object_expression + + declarator = J.variable_declarator( + J.identifier("protocol"), + J.call_expression( + J.member_expression( + J.identifier("Bootstrap"), + J.member_expression( + J.identifier(:Core), + J.member_expression( + J.identifier(:Functions), + J.identifier(:defprotocol) + ) + ) + ), + [object] + ) + ) + + declaration = J.variable_declaration([declarator], :const) + + body = build_implementations(impls, pid) + + body = [declaration] ++ body + + js_ast = ElixirScript.ModuleSystems.Namespace.build( + module, + body, + J.identifier("protocol"), + nil + ) + + ModuleState.put_module(pid, module, Map.put(info, :js_ast, hd(js_ast))) + end + + defp build_implementations(impls, pid) do + Enum.map(impls, fn({impl, impl_for}) -> + members = ["Elixir"] ++ Module.split(impl) ++ ["__load"] + + ast = J.call_expression( + Identifier.make_namespace_members(members), + [J.identifier("Elixir")] + ) + + J.call_expression( + J.member_expression( + J.identifier("Bootstrap"), + J.member_expression( + J.identifier(:Core), + J.member_expression( + J.identifier(:Functions), + J.identifier(:defimpl) + ) + ) + ), + [ + J.identifier("protocol"), + map_to_js(impl_for), + ast + ] + ) + end) + end + + defp map_to_js(Integer) do + J.member_expression( + J.member_expression( + J.identifier("Bootstrap"), + J.identifier(:Core) + ), + J.identifier(:Integer) + ) + end + + defp map_to_js(Tuple) do + J.member_expression( + J.member_expression( + J.identifier("Bootstrap"), + J.identifier(:Core) + ), + J.identifier(:Tuple) + ) + end + + defp map_to_js(Atom) do + J.identifier(:Symbol) + end + + defp map_to_js(List) do + J.identifier(:Array) + end + + defp map_to_js(BitString) do + J.member_expression( + J.member_expression( + J.identifier("Bootstrap"), + J.identifier(:Core) + ), + J.identifier(:BitString) + ) + end + + defp map_to_js(Float) do + J.member_expression( + J.member_expression( + J.identifier("Bootstrap"), + J.identifier(:Core) + ), + J.identifier(:Float) + ) + end + + defp map_to_js(Function) do + J.identifier(:Function) + end + + defp map_to_js(PID) do + J.member_expression( + J.member_expression( + J.identifier("Bootstrap"), + J.identifier(:Core) + ), + J.identifier(:PID) + ) + end + + defp map_to_js(Port) do + J.member_expression( + J.identifier("Bootstrap"), + J.identifier(:Port) + ) + end + + defp map_to_js(Reference) do + J.member_expression( + J.identifier("Bootstrap"), + J.identifier(:Reference) + ) + end + + defp map_to_js(Map) do + J.identifier(:Object) + end + + defp map_to_js(Any) do + J.identifier(:null) + end + + defp map_to_js(module) when is_atom(module) do + case Module.split(module) do + ["JS" | rest] -> + Identifier.make_namespace_members(rest) + split_module -> + J.call_expression( + J.member_expression( + J.identifier("Symbol"), + J.identifier("for") + ), + [J.literal(module)] + ) + end + end +end \ No newline at end of file From 25adee94ec317dfe563e19c24c63bda42281b3db Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Mon, 29 May 2017 12:04:41 -0500 Subject: [PATCH 100/418] Inlining erlang operators to javascript ones --- .../next/passes/translate/examples/example.ex | 2 +- .../next/passes/translate/form.ex | 190 +++++++++++++++++- .../lib/core/erlang_compat/erlang.js | 20 ++ .../tests/core/erlang_compat/erlang_spec.js | 21 ++ 4 files changed, 230 insertions(+), 3 deletions(-) diff --git a/lib/elixir_script/next/passes/translate/examples/example.ex b/lib/elixir_script/next/passes/translate/examples/example.ex index 2fc91703..b34d3f63 100644 --- a/lib/elixir_script/next/passes/translate/examples/example.ex +++ b/lib/elixir_script/next/passes/translate/examples/example.ex @@ -1,6 +1,6 @@ defmodule Example do def start(_, _) do - Base.encode16("Hello") + 1 + 1 end end diff --git a/lib/elixir_script/next/passes/translate/form.ex b/lib/elixir_script/next/passes/translate/form.ex index b8f3952b..72184546 100644 --- a/lib/elixir_script/next/passes/translate/form.ex +++ b/lib/elixir_script/next/passes/translate/form.ex @@ -5,6 +5,19 @@ defmodule ElixirScript.Translate.Form do alias ElixirScript.Translator.Identifier alias ElixirScript.Translate.Clause + @erlang_modules [ + :erlang, + :maps, + :lists, + :gen, + :elixir_errors, + :supervisor, + :application, + :code, + :elixir_utils, + :file + ] + @moduledoc """ Handles translation of all forms that are not functions or clauses """ @@ -63,7 +76,7 @@ defmodule ElixirScript.Translate.Form do Bitstring.compile(bitstring, state) end - def compile({:=, _, [left, right]} = match, state) do + def compile({:=, _, [_, _]} = match, state) do Match.compile(match, state) end @@ -139,7 +152,180 @@ defmodule ElixirScript.Translate.Form do ) end - def compile({{:., _, [module, function]}, _, params}, state) when module in [:erlang, :lists, :maps] do + def compile({{:., _, [:erlang, function]}, _, [first]}, state) when function in [:+, :-] do + J.unary_expression( + function, + compile(first, state), + true + ) + end + + def compile({{:., _, [:erlang, :not]}, _, [first]}, state) do + J.unary_expression( + :!, + compile(first, state), + true + ) + end + + def compile({{:., _, [:erlang, :bnot]}, _, [first]}, state) do + J.unary_expression( + :"~", + compile(first, state), + true + ) + end + + def compile({{:., _, [:erlang, :=]}, _, [_, _] = match}, state) do + Match.compile(match, state) + end + + def compile({{:., _, [:erlang, function]}, _, [first, second]}, state) when function in [:+, :-, :*, :/, :==, :>=] do + J.binary_expression( + function, + compile(first, state), + compile(second, state) + ) + end + + def compile({{:., _, [:erlang, :"/="]}, _, [first, second]}, state) do + J.binary_expression( + :!=, + compile(first, state), + compile(second, state) + ) + end + + def compile({{:., _, [:erlang, :"=<"]}, _, [first, second]}, state) do + J.binary_expression( + :<=, + compile(first, state), + compile(second, state) + ) + end + + def compile({{:., _, [:erlang, :"=:="]}, _, [first, second]}, state) do + J.binary_expression( + :===, + compile(first, state), + compile(second, state) + ) + end + + def compile({{:., _, [:erlang, :"=/="]}, _, [first, second]}, state) do + J.binary_expression( + :!==, + compile(first, state), + compile(second, state) + ) + end + + def compile({{:., _, [:erlang, function]}, _, [first, second]}, state) when function in [:andalso, :and] do + J.binary_expression( + :&&, + compile(first, state), + compile(second, state) + ) + end + + def compile({{:., _, [:erlang, function]}, _, [first, second]}, state) when function in [:orelse, :or] do + J.binary_expression( + :||, + compile(first, state), + compile(second, state) + ) + end + + def compile({{:., _, [:erlang, :div]}, _, [first, second]}, state) do + J.binary_expression( + :/, + compile(first, state), + compile(second, state) + ) + end + + def compile({{:., _, [:erlang, :rem]}, _, [first, second]}, state) do + J.binary_expression( + :mod, + compile(first, state), + compile(second, state) + ) + end + + def compile({{:., _, [:erlang, :band]}, _, [first, second]}, state) do + J.binary_expression( + :&, + compile(first, state), + compile(second, state) + ) + end + + def compile({{:., _, [:erlang, :bor]}, _, [first, second]}, state) do + J.binary_expression( + :|, + compile(first, state), + compile(second, state) + ) + end + + def compile({{:., _, [:erlang, :bsl]}, _, [first, second]}, state) do + J.binary_expression( + :"<<", + compile(first, state), + compile(second, state) + ) + end + + def compile({{:., _, [:erlang, :bsl]}, _, [first, second]}, state) do + J.binary_expression( + :">>", + compile(first, state), + compile(second, state) + ) + end + + def compile({{:., _, [:erlang, :bxor]}, _, [first, second]}, state) do + J.binary_expression( + :">>", + compile(first, state), + compile(second, state) + ) + end + + def compile({{:., _, [:erlang, :++]}, _, [_, _] = params}, state) do + J.call_expression( + J.member_expression( + J.member_expression( + J.member_expression( + J.identifier("Bootstrap"), + J.identifier("Core") + ), + J.identifier(:erlang) + ), + J.identifier("list_concatenation2") + ), + Enum.map(params, &compile(&1, state)) + ) + end + + def compile({{:., _, [:erlang, :--]}, _, [_, _] = params}, state) do + J.call_expression( + J.member_expression( + J.member_expression( + J.member_expression( + J.identifier("Bootstrap"), + J.identifier("Core") + ), + J.identifier(:erlang) + ), + J.identifier("list_substraction2") + ), + Enum.map(params, &compile(&1, state)) + ) + end + + + def compile({{:., _, [module, function]}, _, params}, state) when module in @erlang_modules do J.call_expression( J.member_expression( J.member_expression( diff --git a/src/javascript/lib/core/erlang_compat/erlang.js b/src/javascript/lib/core/erlang_compat/erlang.js index 6de89420..0b09676c 100644 --- a/src/javascript/lib/core/erlang_compat/erlang.js +++ b/src/javascript/lib/core/erlang_compat/erlang.js @@ -8,6 +8,26 @@ function atom_to_binary2(atom, encoding = Symbol.for('utf8')) { return Symbol.keyFor(atom); } +function list_concatenation2(list1, list2) { + return list1.concat(list2); +} + +function list_subtraction2(list1, list2) { + const list = [...list1]; + + for (const item of list2) { + const index = list.indexOf(item); + + if (index > -1) { + list.splice(index, 1); + } + } + + return list; +} + export default { atom_to_binary2, + list_concatenation2, + list_subtraction2, }; diff --git a/src/javascript/tests/core/erlang_compat/erlang_spec.js b/src/javascript/tests/core/erlang_compat/erlang_spec.js index 299f56f5..31460192 100644 --- a/src/javascript/tests/core/erlang_compat/erlang_spec.js +++ b/src/javascript/tests/core/erlang_compat/erlang_spec.js @@ -13,3 +13,24 @@ test('atom_to_binary2', t => { Error ); }); + +test('list_concatenation2', t => { + t.deepEqual(Core.erlang.list_concatenation2([], []), []); + t.deepEqual(Core.erlang.list_concatenation2([1], []), [1]); + t.deepEqual(Core.erlang.list_concatenation2([1, 2, 3], [4, 5, 6]), [ + 1, + 2, + 3, + 4, + 5, + 6, + ]); +}); + +test('list_subtraction2', t => { + t.deepEqual(Core.erlang.list_subtraction2([], []), []); + t.deepEqual(Core.erlang.list_subtraction2([1], []), [1]); + t.deepEqual(Core.erlang.list_subtraction2([1, 2, 3], [4, 5, 6]), [1, 2, 3]); + t.deepEqual(Core.erlang.list_subtraction2([1, 2, 3], [1, 2, 3]), []); + t.deepEqual(Core.erlang.list_subtraction2([1, 2, 3], [1, 2]), [3]); +}); From 8410fd4d817da9c795cd01398767636f850b922a Mon Sep 17 00:00:00 2001 From: Joe Ellis Date: Mon, 29 May 2017 14:59:11 -0500 Subject: [PATCH 101/418] Remove some credo warnings --- .credo.exs | 4 ++-- lib/elixir_script/cli.ex | 10 +++++----- lib/elixir_script/passes/java_script_ast.ex | 6 +++--- lib/elixir_script/passes/java_script_code.ex | 3 ++- .../translator/kernel/special_forms/bitstring.ex | 2 +- .../translator/kernel/special_forms/fn.ex | 6 +++--- .../translator/kernel/special_forms/quote.ex | 2 +- lib/elixir_script/watcher.ex | 2 +- 8 files changed, 18 insertions(+), 17 deletions(-) diff --git a/.credo.exs b/.credo.exs index 5c1f8ef1..916e4f57 100644 --- a/.credo.exs +++ b/.credo.exs @@ -98,9 +98,9 @@ {Credo.Check.Refactor.NegatedConditionsInUnless}, {Credo.Check.Refactor.NegatedConditionsWithElse}, {Credo.Check.Refactor.Nesting}, - {Credo.Check.Refactor.PipeChainStart}, + {Credo.Check.Refactor.PipeChainStart, false}, {Credo.Check.Refactor.UnlessWithElse}, - {Credo.Check.Refactor.VariableRebinding}, + {Credo.Check.Refactor.VariableRebinding, false}, {Credo.Check.Warning.BoolOperationOnSameValues}, {Credo.Check.Warning.IExPry}, diff --git a/lib/elixir_script/cli.ex b/lib/elixir_script/cli.ex index e1e573eb..4bc60ab7 100644 --- a/lib/elixir_script/cli.ex +++ b/lib/elixir_script/cli.ex @@ -45,9 +45,9 @@ defmodule ElixirScript.CLI do options: --js-module [:] A js module used in your code. ex: React:react - Multiple can be defined + Multiple can be defined -f --format [format] module format of output. options: es (default), common, umd - -o --output [path] places output at the given path. + -o --output [path] places output at the given path. Can be a directory or filename. -e --elixir read input as elixir code string --remove-unused Removes unused modules from output @@ -121,8 +121,8 @@ defmodule ElixirScript.CLI do defp build_js_modules(values) do values - |> Enum.map(fn x -> - [identifier, path] = String.split(x,":", trim: true) + |> Enum.map(fn x -> + [identifier, path] = String.split(x, ":", trim: true) { format_identifier(identifier), format_path(path) } end) end @@ -132,7 +132,7 @@ defmodule ElixirScript.CLI do |> String.split(".") |> Module.concat end - + defp format_path(path) do path diff --git a/lib/elixir_script/passes/java_script_ast.ex b/lib/elixir_script/passes/java_script_ast.ex index 7a95f0eb..9b0ab7e0 100644 --- a/lib/elixir_script/passes/java_script_ast.ex +++ b/lib/elixir_script/passes/java_script_ast.ex @@ -8,12 +8,12 @@ defmodule ElixirScript.Passes.JavaScriptAST do State.set_module_data(compiler_data.state, compiler_data.data) State.set_loaded_modules(compiler_data.state, Map.get(compiler_data, :loaded_modules, [])) - data = compiler_data.state + data = compiler_data.state |> State.get_module_data - |> Enum.reject(fn {_,module_data} -> + |> Enum.reject(fn {_, module_data} -> module_data.app == :elixir && opts.import_standard_libs == false end) - |> Enum.map(fn({module_name, module_data}) -> + |> Enum.map(fn({module_name, module_data}) -> module_data = compile(module_data, opts, compiler_data.state) {module_name, module_data} end) diff --git a/lib/elixir_script/passes/java_script_code.ex b/lib/elixir_script/passes/java_script_code.ex index 7eb2f7ef..37e212ba 100644 --- a/lib/elixir_script/passes/java_script_code.ex +++ b/lib/elixir_script/passes/java_script_code.ex @@ -1,6 +1,7 @@ defmodule ElixirScript.Passes.JavaScriptCode do @moduledoc false - alias ESTree.Tools.{Builder, Generator} + alias ESTree.Tools.Builder + alias ESTree.Tools.Generator def execute(compiler_data, _) do parent = self diff --git a/lib/elixir_script/translator/kernel/special_forms/bitstring.ex b/lib/elixir_script/translator/kernel/special_forms/bitstring.ex index 00107d8d..bf0dc832 100644 --- a/lib/elixir_script/translator/kernel/special_forms/bitstring.ex +++ b/lib/elixir_script/translator/kernel/special_forms/bitstring.ex @@ -120,7 +120,7 @@ defmodule ElixirScript.Translator.Bitstring do end def make_interpolated_string(elements, env) do - translated_elements = Enum.map(elements, fn(x)-> + translated_elements = Enum.map(elements, fn(x) -> case x do elem when is_binary(elem) -> Translator.translate!(elem, env) diff --git a/lib/elixir_script/translator/kernel/special_forms/fn.ex b/lib/elixir_script/translator/kernel/special_forms/fn.ex index 80a6de81..5e0afb65 100644 --- a/lib/elixir_script/translator/kernel/special_forms/fn.ex +++ b/lib/elixir_script/translator/kernel/special_forms/fn.ex @@ -30,7 +30,7 @@ defmodule ElixirScript.Translator.Function do ({_, _, [{:when, _, [{_, _, params}, guards]}, body]}) -> body = convert_to_try(body) - process_function_body(params, body, env, name, guards) + process_function_body(params, body, env, name, guards) ({_, _, [{_, _, params}, body]}) -> body = convert_to_try(body) @@ -212,7 +212,7 @@ defmodule ElixirScript.Translator.Function do return_statement = case declaration do %ESTree.ArrayPattern{elements: elements} -> - if(length(elements) == 1) do + if length(elements) == 1 do JS.return_statement(hd(declaration.elements)) else JS.return_statement(JS.array_expression(declaration.elements)) @@ -233,7 +233,7 @@ defmodule ElixirScript.Translator.Function do end - list = Enum.take(list, length(list)-1) + list = Enum.take(list, length(list) - 1) |> Enum.map(fn(x) -> case x do %ESTree.MemberExpression{} -> diff --git a/lib/elixir_script/translator/kernel/special_forms/quote.ex b/lib/elixir_script/translator/kernel/special_forms/quote.ex index d0b7d03d..63341757 100644 --- a/lib/elixir_script/translator/kernel/special_forms/quote.ex +++ b/lib/elixir_script/translator/kernel/special_forms/quote.ex @@ -15,7 +15,7 @@ defmodule ElixirScript.Translator.Quote do (_) -> false end) - if(has_unquote_splicing) do + if has_unquote_splicing do expr = Enum.map(expr, fn ({:unquote_splicing, _, [param]}) -> make_unquote_slicing(param, env) diff --git a/lib/elixir_script/watcher.ex b/lib/elixir_script/watcher.ex index b54cc03e..2b7134d6 100644 --- a/lib/elixir_script/watcher.ex +++ b/lib/elixir_script/watcher.ex @@ -23,7 +23,7 @@ defmodule ElixirScript.Watcher do try do if input_changed?(to_string(path), state) do - Logger.debug "Event: #{inspect event} Path: #{path}" + Logger.debug fn -> "Event: #{inspect event} Path: #{path}" end ElixirScript.compile_path(state[:input], state[:options]) end rescue From cd9001d0987587ca44ec2ea935c04c23692844cd Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Mon, 29 May 2017 16:25:02 -0500 Subject: [PATCH 102/418] Make receive a runtime error. Add warning when receive is encountered. Refactor how functions are implemented --- Supported.md | 2006 ----------------- lib/elixir_script/gen/supported.ex | 165 -- lib/elixir_script/next/compiler.ex | 1 - .../next/passes/translate/clause.ex | 2 +- .../next/passes/translate/examples/example.ex | 12 +- .../next/passes/translate/form.ex | 9 +- .../next/passes/translate/forms/receive.ex | 26 + .../next/passes/translate/function.ex | 100 +- .../next/passes/translate/module.ex | 1 + src/javascript/lib/core/special_forms.js | 9 +- 10 files changed, 148 insertions(+), 2183 deletions(-) delete mode 100644 Supported.md delete mode 100644 lib/elixir_script/gen/supported.ex create mode 100644 lib/elixir_script/next/passes/translate/forms/receive.ex diff --git a/Supported.md b/Supported.md deleted file mode 100644 index 69be84e1..00000000 --- a/Supported.md +++ /dev/null @@ -1,2006 +0,0 @@ -# Supported Elixir Modules -List all public modules in the Elixir Standard Libary. If a function or macro is supported in ElixirScript, it is checked -## Access -- [ ] `all/0` -- [ ] `at/1` -- [ ] `elem/1` -- [ ] `fetch/2` -- [ ] `get/2` -- [ ] `get/3` -- [ ] `get_and_update/3` -- [ ] `key/1` -- [ ] `key/2` -- [ ] `key!/1` -- [ ] `pop/2` -## Agent -- [ ] `cast/2` -- [ ] `cast/4` -- [X] `get/2` -- [ ] `get/3` -- [ ] `get/4` -- [ ] `get/5` -- [X] `get_and_update/2` -- [ ] `get_and_update/3` -- [ ] `get_and_update/4` -- [ ] `get_and_update/5` -- [X] `start/1` -- [X] `start/2` -- [ ] `start/3` -- [ ] `start/4` -- [X] `start_link/1` -- [X] `start_link/2` -- [ ] `start_link/3` -- [ ] `start_link/4` -- [X] `stop/1` -- [ ] `stop/2` -- [ ] `stop/3` -- [X] `update/2` -- [ ] `update/3` -- [ ] `update/4` -- [ ] `update/5` -## Application -- [ ] `app_dir/1` -- [ ] `app_dir/2` -- [ ] `delete_env/2` -- [ ] `delete_env/3` -- [ ] `ensure_all_started/1` -- [ ] `ensure_all_started/2` -- [ ] `ensure_started/1` -- [ ] `ensure_started/2` -- [ ] `fetch_env/2` -- [ ] `fetch_env!/2` -- [ ] `format_error/1` -- [ ] `get_all_env/1` -- [ ] `get_application/1` -- [ ] `get_env/2` -- [ ] `get_env/3` -- [ ] `load/1` -- [ ] `loaded_applications/0` -- [ ] `put_env/3` -- [ ] `put_env/4` -- [ ] `spec/1` -- [ ] `spec/2` -- [ ] `start/1` -- [ ] `start/2` -- [ ] `started_applications/0` -- [ ] `started_applications/1` -- [ ] `stop/1` -- [ ] `unload/1` -- [ ] `__using__/1` -## ArgumentError -- [X] `__struct__/0` -- [X] `__struct__/1` -- [X] `exception/1` -- [X] `message/1` -## ArithmeticError -- [ ] `__struct__/0` -- [ ] `__struct__/1` -- [ ] `exception/1` -- [ ] `message/1` -## Atom -- [X] `to_char_list/1` -- [ ] `to_charlist/1` -- [X] `to_string/1` -## BadArityError -- [ ] `__struct__/0` -- [ ] `__struct__/1` -- [ ] `exception/1` -- [ ] `message/1` -## BadBooleanError -- [ ] `__struct__/0` -- [ ] `__struct__/1` -- [ ] `exception/1` -- [ ] `message/1` -## BadFunctionError -- [ ] `__struct__/0` -- [ ] `__struct__/1` -- [ ] `exception/1` -- [ ] `message/1` -## BadMapError -- [ ] `__struct__/0` -- [ ] `__struct__/1` -- [ ] `exception/1` -- [ ] `message/1` -## BadStructError -- [ ] `__struct__/0` -- [ ] `__struct__/1` -- [ ] `exception/1` -- [ ] `message/1` -## Base -- [ ] `decode16/1` -- [ ] `decode16/2` -- [ ] `decode16!/1` -- [ ] `decode16!/2` -- [ ] `decode32/1` -- [ ] `decode32/2` -- [ ] `decode32!/1` -- [ ] `decode32!/2` -- [X] `decode64/1` -- [ ] `decode64/2` -- [X] `decode64!/1` -- [ ] `decode64!/2` -- [ ] `encode16/1` -- [ ] `encode16/2` -- [ ] `encode32/1` -- [ ] `encode32/2` -- [X] `encode64/1` -- [ ] `encode64/2` -- [ ] `hex_decode32/1` -- [ ] `hex_decode32/2` -- [ ] `hex_decode32!/1` -- [ ] `hex_decode32!/2` -- [ ] `hex_encode32/1` -- [ ] `hex_encode32/2` -- [ ] `url_decode64/1` -- [ ] `url_decode64/2` -- [ ] `url_decode64!/1` -- [ ] `url_decode64!/2` -- [ ] `url_encode64/1` -- [ ] `url_encode64/2` -## Behaviour -- [ ] `__using__/1` -- [ ] `defcallback/1` -- [ ] `defmacrocallback/1` -## Bitwise -- [X] `&&&/2` -- [X] `<<>>/2` -- [X] `^^^/2` -- [ ] `__using__/1` -- [X] `band/2` -- [X] `bnot/1` -- [X] `bor/2` -- [X] `bsl/2` -- [X] `bsr/2` -- [X] `bxor/2` -- [X] `|||/2` -- [X] `~~~/1` -## Calendar -## Calendar.ISO -- [ ] `date/3` -- [ ] `date_to_iso8601/3` -- [ ] `date_to_string/3` -- [ ] `datetime_to_iso8601/11` -- [ ] `datetime_to_string/11` -- [ ] `day_of_week/3` -- [ ] `days_in_month/2` -- [ ] `from_unix/2` -- [ ] `leap_year?/1` -- [ ] `naive_datetime_to_iso8601/7` -- [ ] `naive_datetime_to_string/7` -- [ ] `parse_microsecond/1` -- [ ] `parse_offset/1` -- [ ] `time_to_iso8601/4` -- [ ] `time_to_string/4` -## CaseClauseError -- [ ] `__struct__/0` -- [ ] `__struct__/1` -- [ ] `exception/1` -- [ ] `message/1` -## Code -- [ ] `append_path/1` -- [ ] `available_compiler_options/0` -- [ ] `compile_quoted/1` -- [ ] `compile_quoted/2` -- [ ] `compile_string/1` -- [ ] `compile_string/2` -- [ ] `compiler_options/0` -- [ ] `compiler_options/1` -- [ ] `delete_path/1` -- [ ] `ensure_compiled/1` -- [ ] `ensure_compiled?/1` -- [ ] `ensure_loaded/1` -- [ ] `ensure_loaded?/1` -- [ ] `eval_file/1` -- [ ] `eval_file/2` -- [ ] `eval_quoted/1` -- [ ] `eval_quoted/2` -- [ ] `eval_quoted/3` -- [ ] `eval_string/1` -- [ ] `eval_string/2` -- [ ] `eval_string/3` -- [ ] `get_docs/2` -- [ ] `load_file/1` -- [ ] `load_file/2` -- [ ] `loaded_files/0` -- [ ] `prepend_path/1` -- [ ] `require_file/1` -- [ ] `require_file/2` -- [ ] `string_to_quoted/1` -- [ ] `string_to_quoted/2` -- [ ] `string_to_quoted!/1` -- [ ] `string_to_quoted!/2` -- [ ] `unload_files/1` -## Code.LoadError -- [ ] `__struct__/0` -- [ ] `__struct__/1` -- [ ] `exception/1` -- [ ] `message/1` -## Collectable -- [X] `__protocol__/1` -- [X] `impl_for/1` -- [X] `impl_for!/1` -- [X] `into/1` -## Collectable.BitString -- [X] `__impl__/1` -- [X] `into/1` -## Collectable.File.Stream -- [ ] `__impl__/1` -- [ ] `into/1` -## Collectable.HashDict -- [ ] `__impl__/1` -- [ ] `into/1` -## Collectable.HashSet -- [ ] `__impl__/1` -- [ ] `into/1` -## Collectable.IO.Stream -- [ ] `__impl__/1` -- [ ] `into/1` -## Collectable.List -- [X] `__impl__/1` -- [X] `into/1` -## Collectable.Map -- [X] `__impl__/1` -- [X] `into/1` -## Collectable.MapSet -- [ ] `__impl__/1` -- [ ] `into/1` -## CompileError -- [ ] `__struct__/0` -- [ ] `__struct__/1` -- [ ] `exception/1` -- [ ] `message/1` -## CondClauseError -- [ ] `__struct__/0` -- [ ] `__struct__/1` -- [ ] `exception/1` -- [ ] `message/1` -## Date -- [ ] `__struct__/0` -- [ ] `__struct__/1` -- [ ] `compare/2` -- [ ] `day_of_week/1` -- [ ] `days_in_month/1` -- [ ] `from_erl/1` -- [ ] `from_erl!/1` -- [ ] `from_iso8601/1` -- [ ] `from_iso8601!/1` -- [ ] `leap_year?/1` -- [ ] `new/3` -- [ ] `to_erl/1` -- [ ] `to_iso8601/1` -- [ ] `to_string/1` -- [ ] `utc_today/0` -## DateTime -- [ ] `__struct__/0` -- [ ] `__struct__/1` -- [ ] `compare/2` -- [ ] `from_iso8601/1` -- [ ] `from_naive/2` -- [ ] `from_naive!/2` -- [ ] `from_unix/1` -- [ ] `from_unix/2` -- [ ] `from_unix!/1` -- [ ] `from_unix!/2` -- [ ] `to_date/1` -- [ ] `to_iso8601/1` -- [ ] `to_naive/1` -- [ ] `to_string/1` -- [ ] `to_time/1` -- [ ] `to_unix/1` -- [ ] `to_unix/2` -- [ ] `utc_now/0` -## Dict -- [ ] `delete/2` -- [ ] `drop/2` -- [ ] `empty/1` -- [ ] `equal?/2` -- [ ] `fetch/2` -- [ ] `fetch!/2` -- [ ] `get/2` -- [ ] `get/3` -- [ ] `get_and_update/3` -- [ ] `get_lazy/3` -- [ ] `has_key?/2` -- [ ] `keys/1` -- [ ] `merge/2` -- [ ] `merge/3` -- [ ] `pop/2` -- [ ] `pop/3` -- [ ] `pop_lazy/3` -- [ ] `put/3` -- [ ] `put_new/3` -- [ ] `put_new_lazy/3` -- [ ] `size/1` -- [ ] `split/2` -- [ ] `take/2` -- [ ] `to_list/1` -- [ ] `update/4` -- [ ] `update!/3` -- [ ] `values/1` -- [ ] `__using__/1` -## Enum -- [X] `all?/1` -- [X] `all?/2` -- [X] `any?/1` -- [X] `any?/2` -- [X] `at/2` -- [X] `at/3` -- [ ] `chunk/2` -- [ ] `chunk/3` -- [ ] `chunk/4` -- [ ] `chunk_by/2` -- [X] `concat/1` -- [X] `concat/2` -- [X] `count/1` -- [X] `count/2` -- [ ] `dedup/1` -- [ ] `dedup_by/2` -- [X] `drop/2` -- [X] `drop_every/2` -- [X] `drop_while/2` -- [X] `each/2` -- [X] `empty?/1` -- [X] `fetch/2` -- [X] `fetch!/2` -- [X] `filter/2` -- [X] `filter_map/3` -- [X] `find/2` -- [X] `find/3` -- [ ] `find_index/2` -- [ ] `find_value/2` -- [ ] `find_value/3` -- [ ] `flat_map/2` -- [ ] `flat_map_reduce/3` -- [ ] `group_by/2` -- [ ] `group_by/3` -- [ ] `intersperse/2` -- [X] `into/2` -- [X] `into/3` -- [ ] `join/1` -- [ ] `join/2` -- [X] `map/2` -- [ ] `map_every/3` -- [ ] `map_join/2` -- [ ] `map_join/3` -- [X] `map_reduce/3` -- [ ] `max/1` -- [ ] `max/2` -- [ ] `max_by/2` -- [ ] `max_by/3` -- [X] `member?/2` -- [ ] `min/1` -- [ ] `min/2` -- [ ] `min_by/2` -- [ ] `min_by/3` -- [ ] `min_max/1` -- [ ] `min_max/2` -- [ ] `min_max_by/2` -- [ ] `min_max_by/3` -- [ ] `partition/2` -- [ ] `random/1` -- [X] `reduce/2` -- [X] `reduce/3` -- [ ] `reduce_while/3` -- [ ] `reject/2` -- [X] `reverse/1` -- [X] `reverse/2` -- [ ] `reverse_slice/3` -- [ ] `scan/2` -- [ ] `scan/3` -- [ ] `shuffle/1` -- [ ] `slice/2` -- [ ] `slice/3` -- [ ] `sort/1` -- [ ] `sort/2` -- [ ] `sort_by/2` -- [ ] `sort_by/3` -- [ ] `split/2` -- [ ] `split_while/2` -- [ ] `split_with/2` -- [ ] `sum/1` -- [X] `take/2` -- [X] `take_every/2` -- [ ] `take_random/2` -- [X] `take_while/2` -- [X] `to_list/1` -- [ ] `uniq/1` -- [ ] `uniq/2` -- [ ] `uniq_by/2` -- [ ] `unzip/1` -- [ ] `with_index/1` -- [ ] `with_index/2` -- [ ] `zip/1` -- [ ] `zip/2` -## Enum.EmptyError -- [ ] `__struct__/0` -- [ ] `__struct__/1` -- [ ] `exception/1` -- [ ] `message/1` -## Enum.OutOfBoundsError -- [X] `__struct__/0` -- [X] `__struct__/1` -- [X] `exception/1` -- [X] `message/1` -## Enumerable -- [X] `__protocol__/1` -- [X] `count/1` -- [X] `impl_for/1` -- [X] `impl_for!/1` -- [X] `member?/2` -- [X] `reduce/3` -## Enumerable.File.Stream -- [ ] `__impl__/1` -- [ ] `count/1` -- [ ] `member?/2` -- [ ] `reduce/3` -## Enumerable.Function -- [ ] `__impl__/1` -- [ ] `count/1` -- [ ] `member?/2` -- [ ] `reduce/3` -## Enumerable.GenEvent.Stream -- [ ] `__impl__/1` -- [ ] `count/1` -- [ ] `member?/2` -- [ ] `reduce/3` -## Enumerable.HashDict -- [ ] `__impl__/1` -- [ ] `count/1` -- [ ] `member?/2` -- [ ] `reduce/3` -## Enumerable.HashSet -- [ ] `__impl__/1` -- [ ] `count/1` -- [ ] `member?/2` -- [ ] `reduce/3` -## Enumerable.IO.Stream -- [ ] `__impl__/1` -- [ ] `count/1` -- [ ] `member?/2` -- [ ] `reduce/3` -## Enumerable.List -- [X] `__impl__/1` -- [X] `count/1` -- [X] `member?/2` -- [X] `reduce/3` -## Enumerable.Map -- [X] `__impl__/1` -- [X] `count/1` -- [X] `member?/2` -- [X] `reduce/3` -## Enumerable.MapSet -- [ ] `__impl__/1` -- [ ] `count/1` -- [ ] `member?/2` -- [ ] `reduce/3` -## Enumerable.Range -- [ ] `__impl__/1` -- [ ] `count/1` -- [ ] `member?/2` -- [ ] `reduce/3` -## Enumerable.Stream -- [ ] `__impl__/1` -- [ ] `count/1` -- [ ] `member?/2` -- [ ] `reduce/3` -## ErlangError -- [ ] `__struct__/0` -- [ ] `__struct__/1` -- [ ] `exception/1` -- [ ] `message/1` -- [ ] `normalize/2` -## Exception -- [ ] `exception?/1` -- [ ] `format/2` -- [ ] `format/3` -- [ ] `format_banner/2` -- [ ] `format_banner/3` -- [ ] `format_exit/1` -- [ ] `format_fa/2` -- [ ] `format_file_line/2` -- [ ] `format_file_line/3` -- [ ] `format_mfa/3` -- [ ] `format_stacktrace/0` -- [ ] `format_stacktrace/1` -- [ ] `format_stacktrace_entry/1` -- [ ] `message/1` -- [ ] `normalize/2` -- [ ] `normalize/3` -## File -- [ ] `cd/1` -- [ ] `cd!/1` -- [ ] `cd!/2` -- [ ] `chgrp/2` -- [ ] `chgrp!/2` -- [ ] `chmod/2` -- [ ] `chmod!/2` -- [ ] `chown/2` -- [ ] `chown!/2` -- [ ] `close/1` -- [ ] `copy/2` -- [ ] `copy/3` -- [ ] `copy!/2` -- [ ] `copy!/3` -- [ ] `cp/2` -- [ ] `cp/3` -- [ ] `cp!/2` -- [ ] `cp!/3` -- [ ] `cp_r/2` -- [ ] `cp_r/3` -- [ ] `cp_r!/2` -- [ ] `cp_r!/3` -- [ ] `cwd/0` -- [ ] `cwd!/0` -- [ ] `dir?/1` -- [ ] `exists?/1` -- [ ] `ln_s/2` -- [ ] `ls/0` -- [ ] `ls/1` -- [ ] `ls!/0` -- [ ] `ls!/1` -- [ ] `lstat/1` -- [ ] `lstat/2` -- [ ] `lstat!/1` -- [ ] `lstat!/2` -- [ ] `mkdir/1` -- [ ] `mkdir!/1` -- [ ] `mkdir_p/1` -- [ ] `mkdir_p!/1` -- [ ] `open/1` -- [ ] `open/2` -- [ ] `open/3` -- [ ] `open!/1` -- [ ] `open!/2` -- [ ] `open!/3` -- [ ] `read/1` -- [ ] `read!/1` -- [ ] `regular?/1` -- [ ] `rename/2` -- [ ] `rm/1` -- [ ] `rm!/1` -- [ ] `rm_rf/1` -- [ ] `rm_rf!/1` -- [ ] `rmdir/1` -- [ ] `rmdir!/1` -- [ ] `stat/1` -- [ ] `stat/2` -- [ ] `stat!/1` -- [ ] `stat!/2` -- [ ] `stream!/1` -- [ ] `stream!/2` -- [ ] `stream!/3` -- [ ] `touch/1` -- [ ] `touch/2` -- [ ] `touch!/1` -- [ ] `touch!/2` -- [ ] `write/2` -- [ ] `write/3` -- [ ] `write!/2` -- [ ] `write!/3` -- [ ] `write_stat/2` -- [ ] `write_stat/3` -- [ ] `write_stat!/2` -- [ ] `write_stat!/3` -## File.CopyError -- [ ] `__struct__/0` -- [ ] `__struct__/1` -- [ ] `exception/1` -- [ ] `message/1` -## File.Error -- [ ] `__struct__/0` -- [ ] `__struct__/1` -- [ ] `exception/1` -- [ ] `message/1` -## File.Stat -- [ ] `__struct__/0` -- [ ] `__struct__/1` -- [ ] `from_record/1` -- [ ] `to_record/1` -## File.Stream -- [ ] `__build__/3` -- [ ] `__struct__/0` -- [ ] `__struct__/1` -## Float -- [ ] `ceil/1` -- [ ] `ceil/2` -- [ ] `floor/1` -- [ ] `floor/2` -- [ ] `parse/1` -- [ ] `ratio/1` -- [ ] `round/1` -- [ ] `round/2` -- [ ] `to_char_list/1` -- [ ] `to_char_list/2` -- [ ] `to_charlist/1` -- [ ] `to_string/1` -- [ ] `to_string/2` -## FunctionClauseError -- [ ] `__struct__/0` -- [ ] `__struct__/1` -- [ ] `exception/1` -- [ ] `message/1` -## GenEvent -- [ ] `ack_notify/2` -- [ ] `add_handler/3` -- [ ] `add_mon_handler/3` -- [ ] `call/3` -- [ ] `call/4` -- [ ] `format_status/2` -- [ ] `init_hib/4` -- [ ] `init_it/6` -- [ ] `notify/2` -- [ ] `remove_handler/3` -- [ ] `start/0` -- [ ] `start/1` -- [ ] `start_link/0` -- [ ] `start_link/1` -- [ ] `stop/1` -- [ ] `stop/2` -- [ ] `stop/3` -- [ ] `stream/1` -- [ ] `stream/2` -- [ ] `swap_handler/5` -- [ ] `swap_mon_handler/5` -- [ ] `sync_notify/2` -- [ ] `system_code_change/4` -- [ ] `system_continue/3` -- [ ] `system_get_state/1` -- [ ] `system_replace_state/2` -- [ ] `system_terminate/4` -- [ ] `which_handlers/1` -- [ ] `__using__/1` -## GenEvent.Stream -- [ ] `__struct__/0` -- [ ] `__struct__/1` -- [ ] `code_change/3` -- [ ] `handle_call/2` -- [ ] `handle_event/2` -- [ ] `handle_info/2` -- [ ] `init/1` -- [ ] `terminate/2` -## GenServer -- [ ] `abcast/2` -- [ ] `abcast/3` -- [ ] `call/2` -- [ ] `call/3` -- [ ] `cast/2` -- [ ] `multi_call/2` -- [ ] `multi_call/3` -- [ ] `multi_call/4` -- [ ] `reply/2` -- [ ] `start/2` -- [ ] `start/3` -- [ ] `start_link/2` -- [ ] `start_link/3` -- [ ] `stop/1` -- [ ] `stop/2` -- [ ] `stop/3` -- [ ] `whereis/1` -- [ ] `__using__/1` -## HashDict -- [ ] `__struct__/0` -- [ ] `__struct__/1` -- [ ] `delete/2` -- [ ] `dict_delete/2` -- [ ] `drop/2` -- [ ] `equal?/2` -- [ ] `fetch/2` -- [ ] `fetch!/2` -- [ ] `get/2` -- [ ] `get/3` -- [ ] `get_and_update/3` -- [ ] `get_lazy/3` -- [ ] `has_key?/2` -- [ ] `keys/1` -- [ ] `merge/2` -- [ ] `merge/3` -- [ ] `new/0` -- [ ] `pop/2` -- [ ] `pop/3` -- [ ] `pop_lazy/3` -- [ ] `put/3` -- [ ] `put_new/3` -- [ ] `put_new_lazy/3` -- [ ] `reduce/3` -- [ ] `size/1` -- [ ] `split/2` -- [ ] `take/2` -- [ ] `to_list/1` -- [ ] `update/4` -- [ ] `update!/3` -- [ ] `values/1` -## HashSet -- [ ] `__struct__/0` -- [ ] `__struct__/1` -- [ ] `delete/2` -- [ ] `difference/2` -- [ ] `disjoint?/2` -- [ ] `equal?/2` -- [ ] `intersection/2` -- [ ] `member?/2` -- [ ] `new/0` -- [ ] `put/2` -- [ ] `reduce/3` -- [ ] `size/1` -- [ ] `subset?/2` -- [ ] `to_list/1` -- [ ] `union/2` -## IO -- [ ] `binread/1` -- [ ] `binread/2` -- [ ] `binstream/2` -- [ ] `binwrite/1` -- [ ] `binwrite/2` -- [ ] `chardata_to_string/1` -- [ ] `each_binstream/2` -- [ ] `each_stream/2` -- [ ] `getn/1` -- [ ] `getn/2` -- [ ] `getn/3` -- [ ] `gets/1` -- [ ] `gets/2` -- [X] `inspect/1` -- [X] `inspect/2` -- [ ] `inspect/3` -- [ ] `iodata_length/1` -- [ ] `iodata_to_binary/1` -- [X] `puts/1` -- [X] `puts/2` -- [ ] `read/1` -- [ ] `read/2` -- [ ] `stream/2` -- [X] `warn/1` -- [ ] `warn/2` -- [ ] `write/1` -- [ ] `write/2` -## IO.ANSI -- [ ] `black/0` -- [ ] `black_background/0` -- [ ] `blink_off/0` -- [ ] `blink_rapid/0` -- [ ] `blink_slow/0` -- [ ] `blue/0` -- [ ] `blue_background/0` -- [ ] `bright/0` -- [ ] `clear/0` -- [ ] `clear_line/0` -- [ ] `color/1` -- [ ] `color/3` -- [ ] `color_background/1` -- [ ] `color_background/3` -- [ ] `conceal/0` -- [ ] `crossed_out/0` -- [ ] `cyan/0` -- [ ] `cyan_background/0` -- [ ] `default_background/0` -- [ ] `default_color/0` -- [ ] `enabled?/0` -- [ ] `encircled/0` -- [ ] `faint/0` -- [ ] `font_1/0` -- [ ] `font_2/0` -- [ ] `font_3/0` -- [ ] `font_4/0` -- [ ] `font_5/0` -- [ ] `font_6/0` -- [ ] `font_7/0` -- [ ] `font_8/0` -- [ ] `font_9/0` -- [ ] `format/1` -- [ ] `format/2` -- [ ] `format_fragment/1` -- [ ] `format_fragment/2` -- [ ] `framed/0` -- [ ] `green/0` -- [ ] `green_background/0` -- [ ] `home/0` -- [ ] `inverse/0` -- [ ] `inverse_off/0` -- [ ] `italic/0` -- [ ] `light_black/0` -- [ ] `light_black_background/0` -- [ ] `light_blue/0` -- [ ] `light_blue_background/0` -- [ ] `light_cyan/0` -- [ ] `light_cyan_background/0` -- [ ] `light_green/0` -- [ ] `light_green_background/0` -- [ ] `light_magenta/0` -- [ ] `light_magenta_background/0` -- [ ] `light_red/0` -- [ ] `light_red_background/0` -- [ ] `light_white/0` -- [ ] `light_white_background/0` -- [ ] `light_yellow/0` -- [ ] `light_yellow_background/0` -- [ ] `magenta/0` -- [ ] `magenta_background/0` -- [ ] `no_underline/0` -- [ ] `normal/0` -- [ ] `not_framed_encircled/0` -- [ ] `not_italic/0` -- [ ] `not_overlined/0` -- [ ] `overlined/0` -- [ ] `primary_font/0` -- [ ] `red/0` -- [ ] `red_background/0` -- [ ] `reset/0` -- [ ] `reverse/0` -- [ ] `reverse_off/0` -- [ ] `underline/0` -- [ ] `white/0` -- [ ] `white_background/0` -- [ ] `yellow/0` -- [ ] `yellow_background/0` -## IO.Stream -- [ ] `__build__/3` -- [ ] `__struct__/0` -- [ ] `__struct__/1` -## IO.StreamError -- [ ] `__struct__/0` -- [ ] `__struct__/1` -- [ ] `exception/1` -- [ ] `message/1` -## Inspect -- [ ] `__protocol__/1` -- [ ] `impl_for/1` -- [ ] `impl_for!/1` -- [ ] `inspect/2` -## Inspect.Algebra -- [ ] `break/0` -- [ ] `break/1` -- [ ] `color/3` -- [ ] `concat/1` -- [ ] `concat/2` -- [ ] `empty/0` -- [ ] `fold_doc/2` -- [ ] `format/2` -- [ ] `glue/2` -- [ ] `glue/3` -- [ ] `group/1` -- [ ] `line/2` -- [ ] `nest/2` -- [ ] `space/2` -- [ ] `surround/3` -- [ ] `surround_many/5` -- [ ] `surround_many/6` -- [ ] `to_doc/2` -## Inspect.Any -- [ ] `__impl__/1` -- [ ] `inspect/2` -## Inspect.Atom -- [ ] `__impl__/1` -- [ ] `inspect/1` -- [ ] `inspect/2` -## Inspect.BitString -- [ ] `__impl__/1` -- [ ] `escape/2` -- [ ] `escape_char/1` -- [ ] `inspect/2` -## Inspect.Date -- [ ] `__impl__/1` -- [ ] `inspect/2` -## Inspect.Error -- [ ] `__struct__/0` -- [ ] `__struct__/1` -- [ ] `exception/1` -- [ ] `message/1` -## Inspect.Float -- [ ] `__impl__/1` -- [ ] `inspect/2` -## Inspect.Function -- [ ] `__impl__/1` -- [ ] `inspect/2` -## Inspect.HashDict -- [ ] `__impl__/1` -- [ ] `inspect/2` -## Inspect.HashSet -- [ ] `__impl__/1` -- [ ] `inspect/2` -## Inspect.Integer -- [ ] `__impl__/1` -- [ ] `inspect/2` -## Inspect.List -- [ ] `__impl__/1` -- [ ] `inspect/2` -- [ ] `keyword/2` -- [ ] `keyword?/1` -- [ ] `printable?/1` -## Inspect.Map -- [ ] `__impl__/1` -- [ ] `inspect/2` -- [ ] `inspect/3` -## Inspect.MapSet -- [ ] `__impl__/1` -- [ ] `inspect/2` -## Inspect.NaiveDateTime -- [ ] `__impl__/1` -- [ ] `inspect/2` -## Inspect.Opts -- [ ] `__struct__/0` -- [ ] `__struct__/1` -## Inspect.PID -- [ ] `__impl__/1` -- [ ] `inspect/2` -## Inspect.Port -- [ ] `__impl__/1` -- [ ] `inspect/2` -## Inspect.Range -- [ ] `__impl__/1` -- [ ] `inspect/2` -## Inspect.Reference -- [ ] `__impl__/1` -- [ ] `inspect/2` -## Inspect.Regex -- [ ] `__impl__/1` -- [ ] `inspect/2` -## Inspect.Stream -- [ ] `__impl__/1` -- [ ] `inspect/2` -## Inspect.Time -- [ ] `__impl__/1` -- [ ] `inspect/2` -## Inspect.Tuple -- [ ] `__impl__/1` -- [ ] `inspect/2` -## Inspect.Version -- [ ] `__impl__/1` -- [ ] `inspect/2` -## Inspect.Version.Requirement -- [ ] `__impl__/1` -- [ ] `inspect/2` -## Integer -- [ ] `digits/1` -- [ ] `digits/2` -- [ ] `floor_div/2` -- [ ] `mod/2` -- [X] `parse/1` -- [X] `parse/2` -- [X] `to_char_list/1` -- [ ] `to_charlist/1` -- [ ] `to_charlist/2` -- [ ] `to_string/1` -- [ ] `to_string/2` -- [ ] `undigits/1` -- [ ] `undigits/2` -- [X] `is_even/1` -- [X] `is_odd/1` -## Kernel -- [X] `!=/2` -- [X] `!==/2` -- [X] `*/2` -- [X] `+/1` -- [X] `+/2` -- [X] `++/2` -- [X] `-/1` -- [X] `-/2` -- [X] `--/2` -- [X] `//2` -- [X] `/2` -- [X] `>=/2` -- [X] `abs/1` -- [X] `apply/2` -- [X] `apply/3` -- [X] `binary_part/3` -- [ ] `bit_size/1` -- [ ] `byte_size/1` -- [X] `div/2` -- [X] `elem/2` -- [ ] `exit/1` -- [ ] `function_exported?/3` -- [ ] `get_and_update_in/3` -- [ ] `get_in/2` -- [X] `hd/1` -- [ ] `inspect/1` -- [ ] `inspect/2` -- [X] `is_atom/1` -- [X] `is_binary/1` -- [X] `is_bitstring/1` -- [X] `is_boolean/1` -- [X] `is_float/1` -- [X] `is_function/1` -- [X] `is_function/2` -- [X] `is_integer/1` -- [X] `is_list/1` -- [X] `is_map/1` -- [X] `is_number/1` -- [X] `is_pid/1` -- [X] `is_port/1` -- [X] `is_reference/1` -- [X] `is_tuple/1` -- [X] `length/1` -- [ ] `macro_exported?/3` -- [ ] `make_ref/0` -- [X] `map_size/1` -- [X] `max/2` -- [X] `min/2` -- [ ] `node/0` -- [ ] `node/1` -- [ ] `not/1` -- [ ] `pop_in/2` -- [ ] `put_elem/3` -- [ ] `put_in/3` -- [X] `rem/2` -- [X] `round/1` -- [ ] `self/0` -- [ ] `send/2` -- [ ] `spawn/1` -- [ ] `spawn/3` -- [ ] `spawn_link/1` -- [ ] `spawn_link/3` -- [ ] `spawn_monitor/1` -- [ ] `spawn_monitor/3` -- [ ] `struct/1` -- [ ] `struct/2` -- [ ] `struct!/1` -- [ ] `struct!/2` -- [X] `throw/1` -- [X] `tl/1` -- [X] `trunc/1` -- [X] `tuple_size/1` -- [ ] `update_in/3` -- [X] `!/1` -- [X] `&&/2` -- [X] `../2` -- [X] `<>/2` -- [X] `@/1` -- [ ] `alias!/1` -- [X] `and/2` -- [ ] `binding/0` -- [ ] `binding/1` -- [X] `def/1` -- [X] `def/2` -- [X] `defdelegate/2` -- [X] `defexception/1` -- [X] `defimpl/2` -- [X] `defimpl/3` -- [X] `defmacro/1` -- [X] `defmacro/2` -- [X] `defmacrop/1` -- [X] `defmacrop/2` -- [X] `defmodule/2` -- [X] `defoverridable/1` -- [X] `defp/1` -- [X] `defp/2` -- [X] `defprotocol/2` -- [X] `defstruct/1` -- [ ] `destructure/2` -- [ ] `get_and_update_in/2` -- [X] `if/2` -- [X] `in/2` -- [X] `is_nil/1` -- [X] `match?/2` -- [X] `or/2` -- [ ] `pop_in/1` -- [ ] `put_in/2` -- [X] `raise/1` -- [X] `raise/2` -- [ ] `reraise/2` -- [ ] `reraise/3` -- [ ] `sigil_C/2` -- [ ] `sigil_D/2` -- [ ] `sigil_N/2` -- [ ] `sigil_R/2` -- [ ] `sigil_S/2` -- [ ] `sigil_T/2` -- [ ] `sigil_W/2` -- [ ] `sigil_c/2` -- [X] `sigil_r/2` -- [ ] `sigil_s/2` -- [ ] `sigil_w/2` -- [ ] `to_char_list/1` -- [ ] `to_charlist/1` -- [X] `to_string/1` -- [X] `unless/2` -- [ ] `update_in/2` -- [X] `use/1` -- [X] `use/2` -- [ ] `var!/1` -- [ ] `var!/2` -- [X] `|>/2` -- [X] `||/2` -## Kernel.ErrorHandler -- [ ] `ensure_compiled/2` -- [ ] `ensure_loaded/1` -- [ ] `undefined_function/3` -- [ ] `undefined_lambda/3` -## Kernel.ParallelCompiler -- [ ] `files/1` -- [ ] `files/2` -- [ ] `files_to_path/2` -- [ ] `files_to_path/3` -## Kernel.ParallelRequire -- [ ] `files/1` -- [ ] `files/2` -## Kernel.SpecialForms -- [X] `%/2` -- [X] `%{}/1` -- [X] `&/1` -- [X] `./2` -- [X] `::/2` -- [X] `<<>>/1` -- [X] `=/2` -- [X] `^/1` -- [X] `__CALLER__/0` -- [X] `__DIR__/0` -- [X] `__ENV__/0` -- [X] `__MODULE__/0` -- [X] `__aliases__/1` -- [X] `__block__/1` -- [X] `alias/2` -- [X] `case/2` -- [X] `cond/1` -- [X] `fn/1` -- [X] `for/1` -- [X] `import/2` -- [X] `quote/2` -- [ ] `receive/1` -- [X] `require/2` -- [X] `super/1` -- [X] `try/1` -- [X] `unquote/1` -- [X] `unquote_splicing/1` -- [X] `with/1` -- [X] `{}/1` -## Kernel.Typespec -- [ ] `beam_callbacks/1` -- [ ] `beam_specs/1` -- [ ] `beam_typedocs/1` -- [ ] `beam_types/1` -- [ ] `define_spec/3` -- [ ] `define_type/3` -- [ ] `define_type/4` -- [ ] `defines_callback?/3` -- [ ] `defines_spec?/3` -- [ ] `defines_type?/3` -- [ ] `defspec/3` -- [ ] `deftype/3` -- [ ] `spec_to_ast/2` -- [ ] `spec_to_signature/1` -- [ ] `translate_spec/3` -- [ ] `translate_type/3` -- [ ] `type_to_ast/1` -- [ ] `type_to_signature/1` -- [ ] `defcallback/1` -- [ ] `defmacrocallback/1` -- [ ] `defopaque/1` -- [ ] `defoptional_callbacks/1` -- [ ] `defspec/1` -- [ ] `deftype/1` -- [ ] `deftypep/1` -## KeyError -- [ ] `__struct__/0` -- [ ] `__struct__/1` -- [ ] `exception/1` -- [ ] `message/1` -## Keyword -- [ ] `delete/2` -- [ ] `delete/3` -- [ ] `delete_first/2` -- [ ] `drop/2` -- [ ] `equal?/2` -- [ ] `fetch/2` -- [ ] `fetch!/2` -- [X] `get/2` -- [X] `get/3` -- [ ] `get_and_update/3` -- [ ] `get_and_update!/3` -- [ ] `get_lazy/3` -- [ ] `get_values/2` -- [X] `has_key?/2` -- [ ] `keys/1` -- [ ] `keyword?/1` -- [ ] `merge/2` -- [ ] `merge/3` -- [X] `new/0` -- [ ] `new/1` -- [ ] `new/2` -- [ ] `pop/2` -- [ ] `pop/3` -- [ ] `pop_first/2` -- [ ] `pop_first/3` -- [ ] `pop_lazy/3` -- [ ] `put/3` -- [ ] `put_new/3` -- [ ] `put_new_lazy/3` -- [ ] `size/1` -- [ ] `split/2` -- [ ] `take/2` -- [ ] `to_list/1` -- [ ] `update/4` -- [ ] `update!/3` -- [ ] `values/1` -## List -- [X] `delete/2` -- [X] `delete_at/2` -- [X] `duplicate/2` -- [X] `first/1` -- [X] `flatten/1` -- [X] `flatten/2` -- [X] `foldl/3` -- [X] `foldr/3` -- [X] `insert_at/3` -- [X] `keydelete/3` -- [X] `keyfind/3` -- [X] `keyfind/4` -- [X] `keymember?/3` -- [X] `keyreplace/4` -- [ ] `keysort/2` -- [ ] `keystore/4` -- [ ] `keytake/3` -- [X] `last/1` -- [ ] `myers_difference/2` -- [ ] `pop_at/2` -- [ ] `pop_at/3` -- [X] `replace_at/3` -- [ ] `to_atom/1` -- [ ] `to_existing_atom/1` -- [ ] `to_float/1` -- [ ] `to_integer/1` -- [ ] `to_integer/2` -- [ ] `to_string/1` -- [X] `to_tuple/1` -- [X] `update_at/3` -- [X] `wrap/1` -- [X] `zip/1` -## List.Chars -- [ ] `__protocol__/1` -- [ ] `impl_for/1` -- [ ] `impl_for!/1` -- [ ] `to_char_list/1` -- [ ] `to_charlist/1` -## List.Chars.Atom -- [ ] `__impl__/1` -- [ ] `to_charlist/1` -## List.Chars.BitString -- [ ] `__impl__/1` -- [ ] `to_charlist/1` -## List.Chars.Float -- [ ] `__impl__/1` -- [ ] `to_charlist/1` -## List.Chars.Integer -- [ ] `__impl__/1` -- [ ] `to_charlist/1` -## List.Chars.List -- [ ] `__impl__/1` -- [ ] `to_charlist/1` -## Macro -- [ ] `camelize/1` -- [ ] `decompose_call/1` -- [ ] `escape/1` -- [ ] `escape/2` -- [ ] `expand/2` -- [ ] `expand_once/2` -- [ ] `pipe/3` -- [ ] `pipe_warning/1` -- [ ] `postwalk/2` -- [ ] `postwalk/3` -- [ ] `prewalk/2` -- [ ] `prewalk/3` -- [ ] `to_string/1` -- [ ] `to_string/2` -- [ ] `traverse/4` -- [ ] `underscore/1` -- [ ] `unescape_string/1` -- [ ] `unescape_string/2` -- [ ] `unescape_tokens/1` -- [ ] `unescape_tokens/2` -- [ ] `unpipe/1` -- [ ] `update_meta/2` -- [ ] `validate/1` -- [ ] `var/2` -- [ ] `binary_ops/0` -- [ ] `unary_ops/0` -## Macro.Env -- [X] `__struct__/0` -- [X] `__struct__/1` -- [ ] `in_guard?/1` -- [ ] `in_match?/1` -- [ ] `location/1` -- [ ] `stacktrace/1` -## Map -- [X] `delete/2` -- [X] `drop/2` -- [X] `equal?/2` -- [X] `fetch/2` -- [X] `fetch!/2` -- [X] `from_struct/1` -- [X] `get/2` -- [X] `get/3` -- [X] `get_and_update/3` -- [ ] `get_and_update!/3` -- [X] `get_lazy/3` -- [X] `has_key?/2` -- [X] `keys/1` -- [X] `merge/2` -- [ ] `merge/3` -- [X] `new/0` -- [ ] `new/1` -- [ ] `new/2` -- [X] `pop/2` -- [X] `pop/3` -- [X] `pop_lazy/3` -- [X] `put/3` -- [X] `put_new/3` -- [X] `put_new_lazy/3` -- [X] `size/1` -- [X] `split/2` -- [X] `take/2` -- [X] `to_list/1` -- [X] `update/4` -- [X] `update!/3` -- [X] `values/1` -## MapSet -- [X] `__struct__/0` -- [X] `__struct__/1` -- [X] `delete/2` -- [X] `difference/2` -- [X] `disjoint?/2` -- [X] `equal?/2` -- [X] `intersection/2` -- [X] `member?/2` -- [X] `new/0` -- [ ] `new/1` -- [ ] `new/2` -- [X] `put/2` -- [X] `size/1` -- [X] `subset?/2` -- [X] `to_list/1` -- [X] `union/2` -## MatchError -- [ ] `__struct__/0` -- [ ] `__struct__/1` -- [ ] `exception/1` -- [ ] `message/1` -## Module -- [ ] `add_doc/5` -- [ ] `add_doc/6` -- [ ] `compile_doc/6` -- [ ] `concat/1` -- [ ] `concat/2` -- [ ] `create/3` -- [ ] `defines?/2` -- [ ] `defines?/3` -- [ ] `definitions_in/1` -- [ ] `definitions_in/2` -- [ ] `delete_attribute/2` -- [ ] `eval_quoted/2` -- [ ] `eval_quoted/3` -- [ ] `eval_quoted/4` -- [ ] `get_attribute/2` -- [ ] `get_attribute/3` -- [ ] `make_overridable/2` -- [ ] `open?/1` -- [ ] `overridable?/2` -- [ ] `put_attribute/3` -- [ ] `put_attribute/5` -- [ ] `register_attribute/3` -- [ ] `safe_concat/1` -- [ ] `safe_concat/2` -- [ ] `split/1` -- [ ] `store_typespec/3` -## NaiveDateTime -- [ ] `__struct__/0` -- [ ] `__struct__/1` -- [ ] `add/2` -- [ ] `add/3` -- [ ] `compare/2` -- [ ] `diff/2` -- [ ] `diff/3` -- [ ] `from_erl/1` -- [ ] `from_erl/2` -- [ ] `from_erl!/1` -- [ ] `from_erl!/2` -- [ ] `from_iso8601/1` -- [ ] `from_iso8601!/1` -- [ ] `new/2` -- [ ] `new/6` -- [ ] `new/7` -- [ ] `to_date/1` -- [ ] `to_erl/1` -- [ ] `to_iso8601/1` -- [ ] `to_string/1` -- [ ] `to_time/1` -- [ ] `utc_now/0` -## Node -- [ ] `alive?/0` -- [ ] `connect/1` -- [ ] `disconnect/1` -- [ ] `get_cookie/0` -- [ ] `list/0` -- [ ] `list/1` -- [ ] `monitor/2` -- [ ] `monitor/3` -- [ ] `ping/1` -- [ ] `self/0` -- [ ] `set_cookie/1` -- [ ] `set_cookie/2` -- [ ] `spawn/2` -- [ ] `spawn/3` -- [ ] `spawn/4` -- [ ] `spawn/5` -- [ ] `spawn_link/2` -- [ ] `spawn_link/4` -- [ ] `start/1` -- [ ] `start/2` -- [ ] `start/3` -- [ ] `stop/0` -## OptionParser -- [ ] `get_option_key/1` -- [ ] `next/1` -- [ ] `next/2` -- [ ] `parse/1` -- [ ] `parse/2` -- [ ] `parse!/1` -- [ ] `parse!/2` -- [ ] `parse_head/1` -- [ ] `parse_head/2` -- [ ] `parse_head!/1` -- [ ] `parse_head!/2` -- [ ] `split/1` -- [ ] `to_argv/1` -- [ ] `to_argv/2` -## OptionParser.ParseError -- [ ] `__struct__/0` -- [ ] `__struct__/1` -- [ ] `exception/1` -- [ ] `message/1` -## Path -- [ ] `absname/1` -- [ ] `absname/2` -- [ ] `basename/1` -- [ ] `basename/2` -- [ ] `dirname/1` -- [ ] `expand/1` -- [ ] `expand/2` -- [ ] `extname/1` -- [ ] `join/1` -- [ ] `join/2` -- [ ] `relative/1` -- [ ] `relative_to/2` -- [ ] `relative_to_cwd/1` -- [ ] `rootname/1` -- [ ] `rootname/2` -- [ ] `split/1` -- [ ] `type/1` -- [ ] `wildcard/1` -- [ ] `wildcard/2` -## Path.Wildcard -- [ ] `list_dir/1` -- [ ] `read_link_info/1` -## Port -- [ ] `close/1` -- [ ] `command/2` -- [ ] `command/3` -- [ ] `connect/2` -- [ ] `info/1` -- [ ] `info/2` -- [ ] `list/0` -- [ ] `open/2` -## Process -- [ ] `alive?/1` -- [ ] `cancel_timer/1` -- [ ] `delete/1` -- [ ] `demonitor/1` -- [ ] `demonitor/2` -- [ ] `exit/2` -- [ ] `flag/2` -- [ ] `flag/3` -- [ ] `get/0` -- [ ] `get/1` -- [ ] `get/2` -- [ ] `get_keys/0` -- [ ] `get_keys/1` -- [ ] `group_leader/0` -- [ ] `group_leader/2` -- [ ] `hibernate/3` -- [ ] `info/1` -- [ ] `info/2` -- [ ] `link/1` -- [ ] `list/0` -- [ ] `monitor/1` -- [ ] `put/2` -- [ ] `read_timer/1` -- [ ] `register/2` -- [ ] `registered/0` -- [ ] `send/3` -- [ ] `send_after/3` -- [ ] `send_after/4` -- [ ] `sleep/1` -- [ ] `spawn/2` -- [ ] `spawn/4` -- [ ] `unlink/1` -- [ ] `unregister/1` -- [ ] `whereis/1` -## Protocol -- [ ] `__builtin__/0` -- [ ] `__derive__/3` -- [ ] `__ensure_defimpl__/3` -- [ ] `__functions_spec__/1` -- [ ] `__impl__/2` -- [ ] `__protocol__/2` -- [ ] `__spec__?/3` -- [ ] `assert_impl!/2` -- [ ] `assert_protocol!/1` -- [ ] `consolidate/2` -- [ ] `consolidated?/1` -- [ ] `extract_impls/2` -- [ ] `extract_protocols/1` -- [ ] `def/1` -- [ ] `derive/2` -- [ ] `derive/3` -## Protocol.UndefinedError -- [ ] `__struct__/0` -- [ ] `__struct__/1` -- [ ] `exception/1` -- [ ] `message/1` -## Range -- [X] `__struct__/0` -- [X] `__struct__/1` -- [X] `new/2` -- [X] `range?/1` -## Record -- [ ] `__access__/4` -- [ ] `__access__/5` -- [ ] `__fields__/2` -- [ ] `__keyword__/3` -- [ ] `extract/2` -- [ ] `extract_all/1` -- [ ] `defrecord/2` -- [ ] `defrecord/3` -- [ ] `defrecordp/2` -- [ ] `defrecordp/3` -- [ ] `is_record/1` -- [ ] `is_record/2` -## Record.Extractor -- [ ] `extract/2` -- [ ] `extract_all/1` -## Regex -- [ ] `__struct__/0` -- [ ] `__struct__/1` -- [X] `compile/1` -- [X] `compile/2` -- [X] `compile!/1` -- [X] `compile!/2` -- [ ] `escape/1` -- [X] `match?/2` -- [ ] `named_captures/2` -- [ ] `named_captures/3` -- [ ] `names/1` -- [X] `opts/1` -- [ ] `re_pattern/1` -- [X] `regex?/1` -- [X] `replace/3` -- [X] `replace/4` -- [X] `run/2` -- [X] `run/3` -- [X] `scan/2` -- [X] `scan/3` -- [X] `source/1` -- [ ] `split/2` -- [ ] `split/3` -- [ ] `unescape_map/1` -## Regex.CompileError -- [ ] `__struct__/0` -- [ ] `__struct__/1` -- [ ] `exception/1` -- [ ] `message/1` -## Registry -- [ ] `dispatch/3` -- [ ] `keys/2` -- [ ] `lookup/2` -- [ ] `match/3` -- [ ] `meta/2` -- [ ] `put_meta/3` -- [ ] `register/3` -- [ ] `register_name/2` -- [ ] `send/2` -- [ ] `start_link/2` -- [ ] `start_link/3` -- [ ] `unregister/2` -- [ ] `unregister_name/1` -- [ ] `update_value/3` -- [ ] `whereis_name/1` -## RuntimeError -- [X] `__struct__/0` -- [X] `__struct__/1` -- [X] `exception/1` -- [X] `message/1` -## Set -- [ ] `delete/2` -- [ ] `difference/2` -- [ ] `disjoint?/2` -- [ ] `empty/1` -- [ ] `equal?/2` -- [ ] `intersection/2` -- [ ] `member?/2` -- [ ] `put/2` -- [ ] `size/1` -- [ ] `subset?/2` -- [ ] `to_list/1` -- [ ] `union/2` -## Stream -- [ ] `__struct__/0` -- [ ] `__struct__/1` -- [ ] `chunk/2` -- [ ] `chunk/3` -- [ ] `chunk/4` -- [ ] `chunk_by/2` -- [ ] `concat/1` -- [ ] `concat/2` -- [ ] `cycle/1` -- [ ] `dedup/1` -- [ ] `dedup_by/2` -- [ ] `drop/2` -- [ ] `drop_every/2` -- [ ] `drop_while/2` -- [ ] `each/2` -- [ ] `filter/2` -- [ ] `filter_map/3` -- [ ] `flat_map/2` -- [ ] `interval/1` -- [ ] `into/2` -- [ ] `into/3` -- [ ] `iterate/2` -- [ ] `map/2` -- [ ] `map_every/3` -- [ ] `reject/2` -- [ ] `repeatedly/1` -- [ ] `resource/3` -- [ ] `run/1` -- [ ] `scan/2` -- [ ] `scan/3` -- [ ] `take/2` -- [ ] `take_every/2` -- [ ] `take_while/2` -- [ ] `timer/1` -- [ ] `transform/3` -- [ ] `transform/4` -- [ ] `unfold/2` -- [ ] `uniq/1` -- [ ] `uniq/2` -- [ ] `uniq_by/2` -- [ ] `with_index/1` -- [ ] `with_index/2` -- [ ] `zip/1` -- [ ] `zip/2` -## String -- [X] `at/2` -- [X] `capitalize/1` -- [ ] `chunk/2` -- [X] `codepoints/1` -- [X] `contains?/2` -- [X] `downcase/1` -- [X] `duplicate/2` -- [X] `ends_with?/2` -- [ ] `equivalent?/2` -- [X] `first/1` -- [X] `graphemes/1` -- [ ] `jaro_distance/2` -- [X] `last/1` -- [X] `length/1` -- [ ] `ljust/2` -- [ ] `ljust/3` -- [ ] `lstrip/1` -- [ ] `lstrip/2` -- [X] `match?/2` -- [ ] `myers_difference/2` -- [X] `next_codepoint/1` -- [X] `next_grapheme/1` -- [ ] `next_grapheme_size/1` -- [ ] `normalize/2` -- [ ] `pad_leading/2` -- [ ] `pad_leading/3` -- [ ] `pad_trailing/2` -- [ ] `pad_trailing/3` -- [ ] `printable?/1` -- [ ] `replace/3` -- [ ] `replace/4` -- [ ] `replace_leading/3` -- [ ] `replace_prefix/3` -- [ ] `replace_suffix/3` -- [ ] `replace_trailing/3` -- [X] `reverse/1` -- [ ] `rjust/2` -- [ ] `rjust/3` -- [ ] `rstrip/1` -- [ ] `rstrip/2` -- [ ] `slice/2` -- [ ] `slice/3` -- [X] `split/1` -- [X] `split/2` -- [X] `split/3` -- [ ] `split_at/2` -- [ ] `splitter/2` -- [ ] `splitter/3` -- [X] `starts_with?/2` -- [ ] `strip/1` -- [ ] `strip/2` -- [X] `to_atom/1` -- [X] `to_char_list/1` -- [ ] `to_charlist/1` -- [X] `to_existing_atom/1` -- [X] `to_float/1` -- [X] `to_integer/1` -- [X] `to_integer/2` -- [ ] `trim/1` -- [ ] `trim/2` -- [ ] `trim_leading/1` -- [ ] `trim_leading/2` -- [ ] `trim_trailing/1` -- [ ] `trim_trailing/2` -- [X] `upcase/1` -- [ ] `valid?/1` -- [X] `valid_character?/1` -## String.Casing -- [ ] `downcase/1` -- [ ] `titlecase_once/1` -- [ ] `upcase/1` -## String.Chars -- [X] `__protocol__/1` -- [X] `impl_for/1` -- [X] `impl_for!/1` -- [X] `to_string/1` -## String.Chars.Atom -- [X] `__impl__/1` -- [X] `to_string/1` -## String.Chars.BitString -- [X] `__impl__/1` -- [X] `to_string/1` -## String.Chars.Date -- [ ] `__impl__/1` -- [ ] `to_string/1` -## String.Chars.DateTime -- [ ] `__impl__/1` -- [ ] `to_string/1` -## String.Chars.Float -- [X] `__impl__/1` -- [X] `to_string/1` -## String.Chars.Integer -- [X] `__impl__/1` -- [X] `to_string/1` -## String.Chars.List -- [X] `__impl__/1` -- [X] `to_string/1` -## String.Chars.NaiveDateTime -- [ ] `__impl__/1` -- [ ] `to_string/1` -## String.Chars.Time -- [ ] `__impl__/1` -- [ ] `to_string/1` -## String.Chars.URI -- [ ] `__impl__/1` -- [ ] `to_string/1` -## String.Chars.Version -- [ ] `__impl__/1` -- [ ] `to_string/1` -## String.Chars.Version.Requirement -- [ ] `__impl__/1` -- [ ] `to_string/1` -## String.Unicode -- [ ] `codepoints/1` -- [ ] `graphemes/1` -- [ ] `length/1` -- [ ] `next_codepoint/1` -- [ ] `next_grapheme_size/1` -- [ ] `split_at/2` -- [ ] `version/0` -## StringIO -- [ ] `close/1` -- [ ] `code_change/3` -- [ ] `contents/1` -- [ ] `flush/1` -- [ ] `handle_call/3` -- [ ] `handle_cast/2` -- [ ] `handle_info/2` -- [ ] `init/1` -- [ ] `open/1` -- [ ] `open/2` -- [ ] `terminate/2` -## Supervisor -- [ ] `count_children/1` -- [ ] `delete_child/2` -- [ ] `restart_child/2` -- [ ] `start_child/2` -- [ ] `start_link/2` -- [ ] `start_link/3` -- [ ] `stop/1` -- [ ] `stop/2` -- [ ] `stop/3` -- [ ] `terminate_child/2` -- [ ] `which_children/1` -- [ ] `__using__/1` -## Supervisor.Spec -- [ ] `supervise/2` -- [ ] `supervisor/2` -- [ ] `supervisor/3` -- [ ] `worker/2` -- [ ] `worker/3` -## SyntaxError -- [ ] `__struct__/0` -- [ ] `__struct__/1` -- [ ] `exception/1` -- [ ] `message/1` -## System -- [ ] `argv/0` -- [ ] `argv/1` -- [ ] `at_exit/1` -- [ ] `build_info/0` -- [ ] `cmd/2` -- [ ] `cmd/3` -- [ ] `compiled_endianness/0` -- [ ] `convert_time_unit/3` -- [ ] `cwd/0` -- [ ] `cwd!/0` -- [ ] `delete_env/1` -- [ ] `endianness/0` -- [ ] `find_executable/1` -- [ ] `get_env/0` -- [ ] `get_env/1` -- [ ] `get_pid/0` -- [ ] `halt/0` -- [ ] `halt/1` -- [ ] `monotonic_time/0` -- [ ] `monotonic_time/1` -- [ ] `os_time/0` -- [ ] `os_time/1` -- [ ] `otp_release/0` -- [ ] `put_env/1` -- [ ] `put_env/2` -- [ ] `schedulers/0` -- [ ] `schedulers_online/0` -- [ ] `stacktrace/0` -- [ ] `system_time/0` -- [ ] `system_time/1` -- [ ] `time_offset/0` -- [ ] `time_offset/1` -- [ ] `tmp_dir/0` -- [ ] `tmp_dir!/0` -- [ ] `unique_integer/0` -- [ ] `unique_integer/1` -- [ ] `user_home/0` -- [ ] `user_home!/0` -- [ ] `version/0` -## SystemLimitError -- [ ] `__struct__/0` -- [ ] `__struct__/1` -- [ ] `exception/1` -- [ ] `message/1` -## Task -- [ ] `__struct__/0` -- [ ] `__struct__/1` -- [ ] `async/1` -- [ ] `async/3` -- [ ] `async_stream/2` -- [ ] `async_stream/3` -- [ ] `async_stream/4` -- [ ] `async_stream/5` -- [ ] `await/1` -- [ ] `await/2` -- [ ] `find/2` -- [ ] `shutdown/1` -- [ ] `shutdown/2` -- [ ] `start/1` -- [ ] `start/3` -- [ ] `start_link/1` -- [ ] `start_link/3` -- [ ] `yield/1` -- [ ] `yield/2` -- [ ] `yield_many/1` -- [ ] `yield_many/2` -## Task.Supervisor -- [ ] `async/2` -- [ ] `async/4` -- [ ] `async_nolink/2` -- [ ] `async_nolink/4` -- [ ] `async_stream/3` -- [ ] `async_stream/4` -- [ ] `async_stream/5` -- [ ] `async_stream/6` -- [ ] `async_stream_nolink/3` -- [ ] `async_stream_nolink/4` -- [ ] `async_stream_nolink/5` -- [ ] `async_stream_nolink/6` -- [ ] `children/1` -- [ ] `start_child/2` -- [ ] `start_child/4` -- [ ] `start_link/0` -- [ ] `start_link/1` -- [ ] `terminate_child/2` -## Time -- [ ] `__struct__/0` -- [ ] `__struct__/1` -- [ ] `compare/2` -- [ ] `from_erl/1` -- [ ] `from_erl/2` -- [ ] `from_erl!/1` -- [ ] `from_erl!/2` -- [ ] `from_iso8601/1` -- [ ] `from_iso8601!/1` -- [ ] `new/3` -- [ ] `new/4` -- [ ] `to_erl/1` -- [ ] `to_iso8601/1` -- [ ] `to_string/1` -- [ ] `utc_now/0` -## TokenMissingError -- [ ] `__struct__/0` -- [ ] `__struct__/1` -- [ ] `exception/1` -- [ ] `message/1` -## TryClauseError -- [ ] `__struct__/0` -- [ ] `__struct__/1` -- [ ] `exception/1` -- [ ] `message/1` -## Tuple -- [X] `append/2` -- [X] `delete_at/2` -- [X] `duplicate/2` -- [X] `insert_at/3` -- [X] `to_list/1` -## URI -- [ ] `__struct__/0` -- [ ] `__struct__/1` -- [ ] `char_reserved?/1` -- [ ] `char_unescaped?/1` -- [ ] `char_unreserved?/1` -- [ ] `decode/1` -- [ ] `decode_query/1` -- [ ] `decode_query/2` -- [ ] `decode_www_form/1` -- [ ] `default_port/1` -- [ ] `default_port/2` -- [ ] `encode/1` -- [ ] `encode/2` -- [ ] `encode_query/1` -- [ ] `encode_www_form/1` -- [ ] `merge/2` -- [ ] `parse/1` -- [ ] `path_to_segments/1` -- [ ] `query_decoder/1` -- [ ] `to_string/1` -## UndefinedFunctionError -- [ ] `__struct__/0` -- [ ] `__struct__/1` -- [ ] `exception/1` -- [ ] `message/1` -## UnicodeConversionError -- [ ] `__struct__/0` -- [ ] `__struct__/1` -- [ ] `exception/1` -- [ ] `message/1` -## Version -- [ ] `__struct__/0` -- [ ] `__struct__/1` -- [ ] `compare/2` -- [ ] `compile_requirement/1` -- [ ] `match?/2` -- [ ] `match?/3` -- [ ] `parse/1` -- [ ] `parse!/1` -- [ ] `parse_requirement/1` -## Version.InvalidRequirementError -- [ ] `__struct__/0` -- [ ] `__struct__/1` -- [ ] `exception/1` -- [ ] `message/1` -## Version.InvalidVersionError -- [ ] `__struct__/0` -- [ ] `__struct__/1` -- [ ] `exception/1` -- [ ] `message/1` -## Version.Requirement -- [ ] `__struct__/0` -- [ ] `__struct__/1` -## WithClauseError -- [ ] `__struct__/0` -- [ ] `__struct__/1` -- [ ] `exception/1` -- [ ] `message/1` diff --git a/lib/elixir_script/gen/supported.ex b/lib/elixir_script/gen/supported.ex deleted file mode 100644 index 904ac938..00000000 --- a/lib/elixir_script/gen/supported.ex +++ /dev/null @@ -1,165 +0,0 @@ -defmodule ElixirScript.Gen.Supported do - @moduledoc false - @private_modules [ - Kernel.Utils, - String.Normalizer, - Version.Parser, - IO.ANSI.Sequence, - Version.Parser.DSL, - String.Break, - IO.ANSI.Docs, - Kernel.LexicalTracker, - Task.Supervised, - Supervisor.Default, - Registry.Partition, - Module.LocalsTracker, - Kernel.CLI, - Registry.Supervisor, - Stream.Reducers, - Agent.Server, - ] - - def generate() do - File.open!("Supported.md", [:write], &write_to_file/1) - end - - def write_to_file(file) do - IO.puts(file, "# Supported Elixir Modules") - IO.puts(file, "List all public modules in the Elixir Standard Libary. If a function or macro is supported in ElixirScript, it is checked") - module_map = get_module_list() - - Enum.each(module_map, fn({elixir_module, elixir_script_module}) -> - IO.puts(file, "## #{inspect elixir_module}") - exports = elixir_module.__info__(:functions) ++ elixir_module.__info__(:macros) - - elixir_script_exports = cond do - elixir_script_module == ElixirScript.Kernel.SpecialForms -> - extra(elixir_script_module) - Code.ensure_loaded?(elixir_script_module) -> - elixir_script_module.__info__(:functions) ++ elixir_script_module.__info__(:macros) ++ extra(elixir_script_module) - true -> - [] - end - - Enum.each(exports, fn({func, arity}) -> - if Enum.member?(elixir_script_exports, {func, arity}) do - IO.puts(file, "- [X] `#{func}/#{arity}`") - else - IO.puts(file, "- [ ] `#{func}/#{arity}`") - end - end) - end) - end - - defp get_module_list() do - Application.spec(:elixir, :modules) - |> Enum.filter(&is_public(&1)) - |> Enum.sort(fn(x, y) -> to_string(x) >= to_string(y) end) - |> Enum.reduce(Keyword.new, fn(x, acc) -> - try do - elixirscript_module = (["ElixirScript"] ++ Module.split(x)) |> Module.concat() - Keyword.put(acc, x, elixirscript_module) - rescue - FunctionClauseError -> - acc - end - end) - end - - defp is_public(m) when m in @private_modules do - false - end - - defp is_public(_) do - true - end - - defp extra(ElixirScript.Kernel.SpecialForms) do - [ - %: 2, - %{}: 1, - &: 1, - ".": 2, - "::": 2, - <<>>: 1, - =: 2, - ^: 1, - __CALLER__: 0, - __DIR__: 0, - __ENV__: 0, - __MODULE__: 0, - __aliases__: 1, - __block__: 1, - alias: 2, - case: 2, - cond: 1, - fn: 1, - for: 1, - import: 2, - quote: 2, - require: 2, - super: 1, - try: 1, - unquote: 1, - unquote_splicing: 1, - with: 1, - {}: 1, - ] - end - - defp extra(ElixirScript.Kernel) do - [ - !=: 2, - !==: 2, - *: 2, - +: 1, - +: 2, - ++: 2, - -: 1, - -: 2, - --: 2, - /: 2, - <: 2, - <=: 2, - ==: 2, - ===: 2, - =~: 2, - >: 2, - >=: 2, - div: 2, - rem: 2, - !: 1, - &&: 2, - <>: 2, - @: 1, - and: 2, - def: 1, - def: 2, - defdelegate: 2, - defexception: 1, - defimpl: 2, - defimpl: 3, - defmacro: 1, - defmacro: 2, - defmacrop: 1, - defmacrop: 2, - defmodule: 2, - defoverridable: 1, - defp: 1, - defp: 2, - defprotocol: 2, - defstruct: 1, - raise: 1, - raise: 2, - or: 2, - use: 1, - use: 2, - ||: 2, - ] - end - - - defp extra(_) do - [] - end -end \ No newline at end of file diff --git a/lib/elixir_script/next/compiler.ex b/lib/elixir_script/next/compiler.ex index 0fa7bb21..e93317d6 100644 --- a/lib/elixir_script/next/compiler.ex +++ b/lib/elixir_script/next/compiler.ex @@ -32,7 +32,6 @@ defmodule ElixirScript.Compiler do |> Map.put(:entry_modules, entry_modules) options = default_options - IO.inspect options Map.put(options, :module_formatter, get_module_formatter(options[:format])) end diff --git a/lib/elixir_script/next/passes/translate/clause.ex b/lib/elixir_script/next/passes/translate/clause.ex index ca1553ee..eafbce62 100644 --- a/lib/elixir_script/next/passes/translate/clause.ex +++ b/lib/elixir_script/next/passes/translate/clause.ex @@ -90,7 +90,7 @@ defmodule ElixirScript.Translate.Clause do [J.return_statement(J.identifier("null"))] end - defp compile_guard(params, guards, state) do + def compile_guard(params, guards, state) do guards = guards |> List.wrap diff --git a/lib/elixir_script/next/passes/translate/examples/example.ex b/lib/elixir_script/next/passes/translate/examples/example.ex index b34d3f63..768b9970 100644 --- a/lib/elixir_script/next/passes/translate/examples/example.ex +++ b/lib/elixir_script/next/passes/translate/examples/example.ex @@ -1,6 +1,16 @@ defmodule Example do def start(_, _) do - 1 + 1 +receive do + {:selector, i, value} when is_integer(i) -> + value + value when is_atom(value) -> + value + _ -> + IO.puts :stderr, "Unexpected message received" +after + 5000 -> + IO.puts :stderr, "No message in 5 seconds" +end end end diff --git a/lib/elixir_script/next/passes/translate/form.ex b/lib/elixir_script/next/passes/translate/form.ex index 72184546..9cc1abc0 100644 --- a/lib/elixir_script/next/passes/translate/form.ex +++ b/lib/elixir_script/next/passes/translate/form.ex @@ -1,9 +1,10 @@ defmodule ElixirScript.Translate.Form do alias ESTree.Tools.Builder, as: J - alias ElixirScript.Translate.Forms.{Bitstring, Match, Call, Try, For, Struct} + alias ElixirScript.Translate.Forms.{Bitstring, Match, Call, Try, For, Struct, Receive} alias ElixirScript.Translate.Functions.{Erlang, Lists, Maps} alias ElixirScript.Translator.Identifier alias ElixirScript.Translate.Clause + require Logger @erlang_modules [ :erlang, @@ -133,9 +134,11 @@ defmodule ElixirScript.Translate.Form do ) end - def compile({:receive, context, _}, _state) do + def compile({:receive, context, [blocks]}, state) do line = Keyword.get(context, :line, 1) - raise ElixirScript.CompileError, message: "Line: #{line} receive not supported" + {function, arity} = Map.get(state, :function) + Logger.warn "receive not supported, Module: #{inspect state.module}, Function: #{function}/#{arity}, Line: #{line}" + Receive.compile(blocks, state) end def compile({:try, _, [blocks]}, state) do diff --git a/lib/elixir_script/next/passes/translate/forms/receive.ex b/lib/elixir_script/next/passes/translate/forms/receive.ex new file mode 100644 index 00000000..99a25c7e --- /dev/null +++ b/lib/elixir_script/next/passes/translate/forms/receive.ex @@ -0,0 +1,26 @@ +defmodule ElixirScript.Translate.Forms.Receive do + @moduledoc false + alias ESTree.Tools.Builder, as: J + + def compile(blocks, state) do + receive_block = Keyword.get(blocks, :do) + after_block = Keyword.get(blocks, :after, nil) + + receive_function = J.member_expression( + J.member_expression( + J.identifier("Bootstrap"), + J.member_expression( + J.identifier("Core"), + J.identifier("SpecialForms") + ) + ), + J.identifier("receive") + ) + + J.call_expression( + receive_function, + [] + ) + + end +end \ No newline at end of file diff --git a/lib/elixir_script/next/passes/translate/function.ex b/lib/elixir_script/next/passes/translate/function.ex index b3204e65..50d83a2d 100644 --- a/lib/elixir_script/next/passes/translate/function.ex +++ b/lib/elixir_script/next/passes/translate/function.ex @@ -1,6 +1,8 @@ defmodule ElixirScript.Translate.Function do alias ESTree.Tools.Builder, as: J alias ElixirScript.Translate.Clause + alias ElixirScript.Translate.Forms.Pattern + alias ElixirScript.Translate.Form @moduledoc """ Translates the given Elixir function AST into the @@ -20,18 +22,108 @@ defmodule ElixirScript.Translate.Function do def compile({{name, arity}, type, _, clauses}, state) do state = Map.put(state, :function, {name, arity}) + clauses = compile_clauses(clauses, state) + + arg_matches_declarator = J.variable_declarator( + J.identifier("__arg_matches__"), + J.identifier("null") + ) + + arg_matches_declaration = J.variable_declaration([arg_matches_declarator], :let) declarator = J.variable_declarator( ElixirScript.Translator.Identifier.make_function_name(name, arity), - J.call_expression( + J.function_expression( + [J.rest_element(J.identifier("__function_args__"))], + [], + J.block_statement([ + arg_matches_declaration, + clauses, + J.throw_statement( + J.call_expression( + J.member_expression( + patterns_ast(), + J.identifier("MatchError") + ), + [J.identifier("__function_args__")] + ) + ) + ]) + ) + ) + + J.variable_declaration([declarator], :const) + end + + defp compile_clauses(clauses, state) do + clauses + |> Enum.map(&compile_clause(&1, state)) + |> Enum.map(fn {patterns, params, guards, body} -> + IO.inspect guards + match_or_default_call = J.call_expression( J.member_expression( patterns_ast(), - J.identifier("defmatch") + J.identifier("match_or_default") + ), + [J.array_expression(patterns), J.identifier("__function_args__"), guards] + ) + + J.if_statement( + J.binary_expression( + :!==, + J.assignment_expression(:=, J.identifier("__arg_matches__"), match_or_default_call), + J.identifier("null") ), - Enum.map(clauses, &Clause.compile(&1, state)) + J.block_statement(body) ) + end) + |> Enum.reverse + |> Enum.reduce(nil, fn + if_ast, nil -> + if_ast + if_ast, ast -> + %{if_ast | alternate: ast} + end) + end + + defp compile_clause({ _, args, guards, body}, state) do + {patterns, params} = Pattern.compile(args, state) + guard = Clause.compile_guard(params, guards, state) + + body = case body do + nil -> + J.identifier("null") + {:__block__, _, block_body} -> + Enum.map(block_body, &Form.compile(&1, state)) + |> List.flatten + b when is_list(b) -> + Enum.map(b, &Form.compile(&1, state)) + |> List.flatten + _ -> + Form.compile(body, state) + end + + body = Clause.return_last_statement(body) + + declarator = J.variable_declarator( + J.array_expression(params), + J.identifier("__arg_matches__") ) - J.variable_declaration([declarator], :const) + declaration = J.variable_declaration([declarator], :const) + + body = [declaration] ++ body + {patterns, params, guard, body} + end + + defp compile_clause({:->, _, [[{:when, _, params}], body ]}, state) do + guards = List.last(params) + params = params |> Enum.reverse |> tl |> Enum.reverse + + compile_clause({[], params, guards, body}, state) + end + + defp compile_clause({:->, _, [params, body]}, state) do + compile_clause({[], params, [], body}, state) end end diff --git a/lib/elixir_script/next/passes/translate/module.ex b/lib/elixir_script/next/passes/translate/module.ex index eb64d7ad..8b7c02d2 100644 --- a/lib/elixir_script/next/passes/translate/module.ex +++ b/lib/elixir_script/next/passes/translate/module.ex @@ -26,6 +26,7 @@ defmodule ElixirScript.Translate.Module do } = info state = %{ + module: module, pid: pid } diff --git a/src/javascript/lib/core/special_forms.js b/src/javascript/lib/core/special_forms.js index 7be8c643..b093fee6 100644 --- a/src/javascript/lib/core/special_forms.js +++ b/src/javascript/lib/core/special_forms.js @@ -23,7 +23,7 @@ function _for(expression, generators, collectable_protocol, into = []) { if (expression.guard.apply(this, value)) { result = fun( result, - new Core.Tuple(Symbol.for('cont'), expression.fn.apply(this, value)), + new Core.Tuple(Symbol.for('cont'), expression.fn.apply(this, value)) ); } } @@ -57,7 +57,7 @@ function _try( rescue_function, catch_fun, else_function, - after_function, + after_function ) { let result = null; @@ -141,10 +141,15 @@ function _with(...args) { return successFunction(...argsToPass); } +function receive(clauses, after) { + console.warn('Receive not supported'); +} + export default { _case, cond, _for, _try, _with, + receive, }; From 037b29b108d2b0fd4e415cd1a940d5a86f8b3d63 Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Tue, 30 May 2017 22:03:40 -0500 Subject: [PATCH 103/418] passing along state in order to increment variable count --- lib/elixir_script/next/passes/find_used.ex | 1 - .../next/passes/translate/clause.ex | 25 ++- .../next/passes/translate/examples/example.ex | 13 +- .../next/passes/translate/form.ex | 149 ++++++++++++------ .../next/passes/translate/forms/bitstring.ex | 18 +-- .../next/passes/translate/forms/call.ex | 6 +- .../next/passes/translate/forms/for.ex | 23 +-- .../next/passes/translate/forms/map.ex | 20 ++- .../next/passes/translate/forms/match.ex | 9 +- .../next/passes/translate/forms/pattern.ex | 45 +++++- .../next/passes/translate/forms/receive.ex | 3 +- .../next/passes/translate/forms/struct.ex | 6 +- .../next/passes/translate/forms/try.ex | 19 ++- .../next/passes/translate/function.ex | 17 +- .../next/passes/translate/module.ex | 4 +- 15 files changed, 239 insertions(+), 119 deletions(-) diff --git a/lib/elixir_script/next/passes/find_used.ex b/lib/elixir_script/next/passes/find_used.ex index 43faf4f4..b0bf6fbd 100644 --- a/lib/elixir_script/next/passes/find_used.ex +++ b/lib/elixir_script/next/passes/find_used.ex @@ -241,7 +241,6 @@ defmodule ElixirScript.FindUsed do end defp walk({{:., _, [module, function]}, _, params}, _state) when module in @erlang_modules do - IO.inspect {module, function, length(params)} nil end diff --git a/lib/elixir_script/next/passes/translate/clause.ex b/lib/elixir_script/next/passes/translate/clause.ex index eafbce62..57f0abce 100644 --- a/lib/elixir_script/next/passes/translate/clause.ex +++ b/lib/elixir_script/next/passes/translate/clause.ex @@ -16,7 +16,7 @@ defmodule ElixirScript.Translate.Clause do ) def compile({ _, args, guards, body}, state) do - {patterns, params} = Pattern.compile(args, state) + {patterns, params, state} = Pattern.compile(args, state) guard = compile_guard(params, guards, state) body = case body do @@ -34,7 +34,7 @@ defmodule ElixirScript.Translate.Clause do body = return_last_statement(body) - J.call_expression( + ast = J.call_expression( J.member_expression( @patterns, J.identifier("clause") @@ -49,6 +49,8 @@ defmodule ElixirScript.Translate.Clause do guard ] ) + + { ast, state } end def compile({:->, _, [[{:when, _, params}], body ]}, state) do @@ -74,6 +76,23 @@ defmodule ElixirScript.Translate.Clause do [ast] end + defp do_return_last_statement([%ESTree.VariableDeclaration{} = head | tail]) do + declaration = hd(head.declarations).id + + return_statement = case declaration do + %ESTree.ArrayPattern{elements: elements} -> + if(length(elements) == 1) do + J.return_statement(hd(declaration.elements)) + else + J.return_statement(J.array_expression(declaration.elements)) + end + _ -> + J.return_statement(declaration) + end + + [return_statement, head] ++ tail + end + defp do_return_last_statement([head]) do [J.return_statement(head)] end @@ -96,7 +115,7 @@ defmodule ElixirScript.Translate.Clause do |> List.wrap |> Enum.reverse |> process_guards - |> Form.compile(state) + |> Form.compile!(state) J.function_expression( params, diff --git a/lib/elixir_script/next/passes/translate/examples/example.ex b/lib/elixir_script/next/passes/translate/examples/example.ex index 768b9970..5db58d5a 100644 --- a/lib/elixir_script/next/passes/translate/examples/example.ex +++ b/lib/elixir_script/next/passes/translate/examples/example.ex @@ -1,16 +1,7 @@ defmodule Example do def start(_, _) do -receive do - {:selector, i, value} when is_integer(i) -> - value - value when is_atom(value) -> - value - _ -> - IO.puts :stderr, "Unexpected message received" -after - 5000 -> - IO.puts :stderr, "No message in 5 seconds" -end + a = 1 + a = 2 end end diff --git a/lib/elixir_script/next/passes/translate/form.ex b/lib/elixir_script/next/passes/translate/form.ex index 9cc1abc0..b8181a25 100644 --- a/lib/elixir_script/next/passes/translate/form.ex +++ b/lib/elixir_script/next/passes/translate/form.ex @@ -23,32 +23,42 @@ defmodule ElixirScript.Translate.Form do Handles translation of all forms that are not functions or clauses """ - def compile(nil, _) do - J.identifier("null") + def compile!(ast, state) do + {js_ast, _} = compile(ast, state) + + js_ast + end + + def compile(nil, state) do + { J.identifier("null"), state } end - def compile(form, _) when is_boolean(form) or is_integer(form) or is_float(form) or is_binary(form) do - J.literal(form) + def compile(form, state) when is_boolean(form) or is_integer(form) or is_float(form) or is_binary(form) do + { J.literal(form), state } end def compile(form, state) when is_list(form) do - J.array_expression( - Enum.map(form, &compile(&1, state)) + ast = J.array_expression( + Enum.map(form, &compile!(&1, state)) ) + + { ast, state } end def compile(form, state) when is_atom(form) do if ElixirScript.Translate.Module.is_elixir_module(form) do members = if form == Elixir, do: ["Elixir"], else: ["Elixir"] ++ Module.split(form) - J.identifier(Enum.join(members, "_")) + { J.identifier(Enum.join(members, "_")), state } else - J.call_expression( + ast = J.call_expression( J.member_expression( J.identifier("Symbol"), J.identifier("for") ), [J.literal(form)] ) + + { ast, state } end end @@ -57,7 +67,7 @@ defmodule ElixirScript.Translate.Form do end def compile({:{}, _, elements}, state) do - J.call_expression( + ast = J.call_expression( J.member_expression( J.member_expression( J.identifier("Bootstrap"), @@ -65,7 +75,7 @@ defmodule ElixirScript.Translate.Form do ), J.identifier("Tuple") ), - Enum.map(elements, &compile(&1, state)) + Enum.map(elements, &compile!(&1, state)) ) end @@ -95,19 +105,22 @@ defmodule ElixirScript.Translate.Form do ElixirScript.Translate.Function.patterns_ast(), J.identifier("defmatch") ), - Enum.map(clauses, &Clause.compile(&1, state)) + Enum.map(clauses, fn x -> Clause.compile(x, state) |> elem(0) end) ) - J.call_expression( + ast = J.call_expression( J.member_expression( func, J.identifier("call")), [J.identifier(:this), compile(condition, state)] ) + + { ast, state } end def compile({:cond, _, [[do: clauses]]}, state) do processed_clauses = Enum.map(clauses, fn({:->, _, [clause, clause_body]}) -> - translated_body = Enum.map(List.wrap(clause_body), &compile(&1, state)) - |> Clause.return_last_statement + { translated_body, state } = Enum.map_reduce(List.wrap(clause_body), state, &compile(&1, &2)) + + translated_body = Clause.return_last_statement(translated_body) translated_body = J.function_expression([], [], J.block_statement(translated_body)) translated_clause = compile(hd(clause), state) @@ -128,10 +141,12 @@ defmodule ElixirScript.Translate.Form do J.identifier("cond") ) - J.call_expression( + ast = J.call_expression( cond_function, processed_clauses ) + + { ast, state } end def compile({:receive, context, [blocks]}, state) do @@ -146,37 +161,47 @@ defmodule ElixirScript.Translate.Form do end def compile({:fn, _, clauses}, state) do - J.call_expression( + {clauses_ast, _} = Enum.map_reduce(clauses, state, &Clause.compile(&1, &2)) + + ast = J.call_expression( J.member_expression( ElixirScript.Translate.Function.patterns_ast(), J.identifier("defmatch") ), - Enum.map(clauses, &Clause.compile(&1, state)) + clauses_ast ) + + {ast, state} end def compile({{:., _, [:erlang, function]}, _, [first]}, state) when function in [:+, :-] do - J.unary_expression( + ast = J.unary_expression( function, compile(first, state), true ) + + {ast, state} end def compile({{:., _, [:erlang, :not]}, _, [first]}, state) do - J.unary_expression( + ast = J.unary_expression( :!, compile(first, state), true ) + + {ast, state} end def compile({{:., _, [:erlang, :bnot]}, _, [first]}, state) do - J.unary_expression( + ast = J.unary_expression( :"~", compile(first, state), true ) + + {ast, state} end def compile({{:., _, [:erlang, :=]}, _, [_, _] = match}, state) do @@ -184,119 +209,147 @@ defmodule ElixirScript.Translate.Form do end def compile({{:., _, [:erlang, function]}, _, [first, second]}, state) when function in [:+, :-, :*, :/, :==, :>=] do - J.binary_expression( + ast = J.binary_expression( function, compile(first, state), compile(second, state) ) + + {ast, state} end def compile({{:., _, [:erlang, :"/="]}, _, [first, second]}, state) do - J.binary_expression( + ast = J.binary_expression( :!=, compile(first, state), compile(second, state) ) + + {ast, state} end def compile({{:., _, [:erlang, :"=<"]}, _, [first, second]}, state) do - J.binary_expression( + ast = J.binary_expression( :<=, compile(first, state), compile(second, state) ) + + {ast, state} end def compile({{:., _, [:erlang, :"=:="]}, _, [first, second]}, state) do - J.binary_expression( + ast = J.binary_expression( :===, compile(first, state), compile(second, state) ) + + {ast, state} end def compile({{:., _, [:erlang, :"=/="]}, _, [first, second]}, state) do - J.binary_expression( + ast = J.binary_expression( :!==, compile(first, state), compile(second, state) ) + + {ast, state} end def compile({{:., _, [:erlang, function]}, _, [first, second]}, state) when function in [:andalso, :and] do - J.binary_expression( + ast = J.binary_expression( :&&, compile(first, state), compile(second, state) ) + + {ast, state} end def compile({{:., _, [:erlang, function]}, _, [first, second]}, state) when function in [:orelse, :or] do - J.binary_expression( + ast = J.binary_expression( :||, compile(first, state), compile(second, state) ) + + {ast, state} end def compile({{:., _, [:erlang, :div]}, _, [first, second]}, state) do - J.binary_expression( + ast = J.binary_expression( :/, compile(first, state), compile(second, state) ) + + {ast, state} end def compile({{:., _, [:erlang, :rem]}, _, [first, second]}, state) do - J.binary_expression( + ast = J.binary_expression( :mod, compile(first, state), compile(second, state) ) + + {ast, state} end def compile({{:., _, [:erlang, :band]}, _, [first, second]}, state) do - J.binary_expression( + ast = J.binary_expression( :&, compile(first, state), compile(second, state) ) + + {ast, state} end def compile({{:., _, [:erlang, :bor]}, _, [first, second]}, state) do - J.binary_expression( + ast = J.binary_expression( :|, compile(first, state), compile(second, state) ) + + {ast, state} end def compile({{:., _, [:erlang, :bsl]}, _, [first, second]}, state) do - J.binary_expression( + ast = J.binary_expression( :"<<", compile(first, state), compile(second, state) ) + + {ast, state} end def compile({{:., _, [:erlang, :bsl]}, _, [first, second]}, state) do - J.binary_expression( + ast = J.binary_expression( :">>", compile(first, state), compile(second, state) ) + + {ast, state} end def compile({{:., _, [:erlang, :bxor]}, _, [first, second]}, state) do - J.binary_expression( + ast = J.binary_expression( :">>", compile(first, state), compile(second, state) ) + + {ast, state} end def compile({{:., _, [:erlang, :++]}, _, [_, _] = params}, state) do - J.call_expression( + ast = J.call_expression( J.member_expression( J.member_expression( J.member_expression( @@ -309,10 +362,12 @@ defmodule ElixirScript.Translate.Form do ), Enum.map(params, &compile(&1, state)) ) + + {ast, state} end def compile({{:., _, [:erlang, :--]}, _, [_, _] = params}, state) do - J.call_expression( + ast = J.call_expression( J.member_expression( J.member_expression( J.member_expression( @@ -325,11 +380,13 @@ defmodule ElixirScript.Translate.Form do ), Enum.map(params, &compile(&1, state)) ) + + {ast, state} end def compile({{:., _, [module, function]}, _, params}, state) when module in @erlang_modules do - J.call_expression( + ast = J.call_expression( J.member_expression( J.member_expression( J.member_expression( @@ -340,7 +397,7 @@ defmodule ElixirScript.Translate.Form do ), ElixirScript.Translator.Identifier.make_function_name(function, length(params)) ), - Enum.map(params, &compile(&1, state)) + Enum.map(params, &compile!(&1, state)) ) end @@ -351,29 +408,33 @@ defmodule ElixirScript.Translate.Form do def compile({:super, context, params}, state) do {function_name, _} = Map.get(state, :function) - J.call_expression( + ast = J.call_expression( ElixirScript.Translator.Identifier.make_function_name(function_name, length(params)), - Enum.map(params, &compile(&1, state)) + Enum.map(params, &compile!(&1, state)) ) + + {ast, state} end def compile({function_name, _, params}, state) when is_list(params) do - case function_name do + ast = case function_name do a when is_atom(a) -> J.call_expression( ElixirScript.Translator.Identifier.make_function_name(function_name, length(params)), - Enum.map(params, &compile(&1, state)) + Enum.map(params, &compile!(&1, state)) ) _ -> J.call_expression( compile(function_name, state), - Enum.map(params, &compile(&1, state)) + Enum.map(params, &compile!(&1, state)) ) end + + {ast, state} end def compile({var, _, _}, state) do - ElixirScript.Translator.Identifier.make_identifier(var) + { ElixirScript.Translator.Identifier.make_identifier(var), state } end end diff --git a/lib/elixir_script/next/passes/translate/forms/bitstring.ex b/lib/elixir_script/next/passes/translate/forms/bitstring.ex index e6d23408..14af8f2b 100644 --- a/lib/elixir_script/next/passes/translate/forms/bitstring.ex +++ b/lib/elixir_script/next/passes/translate/forms/bitstring.ex @@ -16,15 +16,15 @@ defmodule ElixirScript.Translate.Forms.Bitstring do Enum.map(elements, &compile_element(&1, state)) ) - js_ast + { js_ast, state } end def compile_element(element, state) when is_number(element) do - do_compile_element({:integer, Form.compile(element, state)}) + do_compile_element({:integer, Form.compile!(element, state)}) end def compile_element(element, state) when is_binary(element) do - do_compile_element({:binary, Form.compile(element, state)}) + do_compile_element({:binary, Form.compile!(element, state)}) end def compile_element({:<<>>, [], elements}, state) do @@ -66,7 +66,7 @@ defmodule ElixirScript.Translate.Forms.Bitstring do end def translate_element(element, state) do - Form.compile(element, state) + Form.compile!(element, state) end defp handle_type_adjectives({:-, _, types}, ast, state) do @@ -75,10 +75,10 @@ defmodule ElixirScript.Translate.Forms.Bitstring do {:-, _, sub_types} -> handle_type_adjectives({:-, [], sub_types}, current_ast, state) {:*, _, [size, unit]} -> - size_ast = do_compile_element({:size, current_ast, [Form.compile(size, state)]}) - do_compile_element({:unit, size_ast, [Form.compile(unit, state)]}) + size_ast = do_compile_element({:size, current_ast, [Form.compile!(size, state)]}) + do_compile_element({:unit, size_ast, [Form.compile!(unit, state)]}) {the_type, _, params} when is_list(params) -> - do_compile_element({the_type, current_ast, Enum.map(params, &Form.compile(&1, state))}) + do_compile_element({the_type, current_ast, Enum.map(params, &Form.compile!(&1, state))}) {the_type, _, _} -> do_compile_element({the_type, current_ast}) end @@ -123,9 +123,9 @@ defmodule ElixirScript.Translate.Forms.Bitstring do translated_elements = Enum.map(elements, fn(x)-> case x do elem when is_binary(elem) -> - Form.compile(elem, state) + Form.compile!(elem, state) {:::, _, data} -> - Form.compile(hd(data), state) + Form.compile!(hd(data), state) end end) diff --git a/lib/elixir_script/next/passes/translate/forms/call.ex b/lib/elixir_script/next/passes/translate/forms/call.ex index 0715538a..cd6cb269 100644 --- a/lib/elixir_script/next/passes/translate/forms/call.ex +++ b/lib/elixir_script/next/passes/translate/forms/call.ex @@ -11,13 +11,15 @@ defmodule ElixirScript.Translate.Forms.Call do ElixirScript.Translator.Identifier.make_function_name(function, length(params)) end - J.call_expression( + ast = J.call_expression( J.member_expression( process_module_name(module, state), function_name ), - Enum.map(params, &Form.compile(&1, state)) + Enum.map(params, &Form.compile!(&1, state)) ) + + {ast, state} end defp process_module_name(module, state) when is_atom(module) do diff --git a/lib/elixir_script/next/passes/translate/forms/for.ex b/lib/elixir_script/next/passes/translate/forms/for.ex index 5c8aeb42..930b6a10 100644 --- a/lib/elixir_script/next/passes/translate/forms/for.ex +++ b/lib/elixir_script/next/passes/translate/forms/for.ex @@ -33,7 +33,7 @@ defmodule ElixirScript.Translate.Forms.For do JS.identifier("Collectable") ) - JS.call_expression( + ast = JS.call_expression( JS.member_expression( JS.member_expression( JS.identifier("Bootstrap"), @@ -46,6 +46,8 @@ defmodule ElixirScript.Translate.Forms.For do ), [expression, generators, collectable, into] ) + + {ast, state} end defp handle_args(nil, module_state) do @@ -63,7 +65,7 @@ defmodule ElixirScript.Translate.Forms.For do {var, collection} end) - {patterns, params} = Pattern.compile([{:<<>>, [], bs_parts}], module_state) + {patterns, params, state} = Pattern.compile([{:<<>>, [], bs_parts}], module_state) gen = JS.call_expression( JS.member_expression( @@ -76,13 +78,13 @@ defmodule ElixirScript.Translate.Forms.For do ), JS.identifier("bitstring_generator") ), - [hd(patterns), Form.compile(collection, module_state)] + [hd(patterns), Form.compile!(collection, module_state)] ) %{state | generators: state.generators ++ [gen], args: state.args ++ params, patterns: state.patterns ++ patterns} ({:<-, _, [identifier, enum]}, state) -> - {patterns, params} = Pattern.compile([identifier], module_state) + {patterns, params, module_state} = Pattern.compile([identifier], module_state) gen = JS.call_expression( JS.member_expression( @@ -95,17 +97,17 @@ defmodule ElixirScript.Translate.Forms.For do ), JS.identifier("list_generator") ), - [hd(patterns), Form.compile(enum, module_state)] + [hd(patterns), Form.compile!(enum, module_state)] ) %{state | generators: state.generators ++ [gen], args: state.args ++ params, patterns: state.patterns ++ patterns} ([into: expression], state) -> - %{state | into: Form.compile(expression, module_state)} + %{state | into: Form.compile!(expression, module_state)} ([into: expression, do: expression2], state) -> fun = create_function_expression(expression2, state, module_state) - %{state | into: Form.compile(expression, module_state), fun: fun} + %{state | into: Form.compile!(expression, module_state), fun: fun} ([do: expression], state) -> fun = create_function_expression(expression, state, module_state) @@ -120,8 +122,11 @@ defmodule ElixirScript.Translate.Forms.For do defp create_function_expression(ast, state, module_state) do - ast = Enum.map(List.wrap(ast), &Form.compile(&1, module_state)) - |> Clause.return_last_statement + { ast, module_state } = Enum.map_reduce(List.wrap(ast), module_state, fn x, acc_state -> + Form.compile(x, acc_state) + end) + + ast = Clause.return_last_statement(ast) JS.function_expression( state.args, diff --git a/lib/elixir_script/next/passes/translate/forms/map.ex b/lib/elixir_script/next/passes/translate/forms/map.ex index a33624ef..54aa74de 100644 --- a/lib/elixir_script/next/passes/translate/forms/map.ex +++ b/lib/elixir_script/next/passes/translate/forms/map.ex @@ -3,10 +3,10 @@ defmodule ElixirScript.Translate.Forms.Map do alias ElixirScript.Translate.Form def compile({:%{}, _, [{:|, _, [map, new_values]}]}, state) do - map = Form.compile(map, state) - data = Form.compile({:%{}, [], new_values}, state) + { map, state } = Form.compile(map, state) + { data, state } = Form.compile({:%{}, [], new_values}, state) - J.call_expression( + ast = J.call_expression( J.member_expression( J.member_expression( J.identifier("Bootstrap"), @@ -19,20 +19,28 @@ defmodule ElixirScript.Translate.Forms.Map do ), [map, data] ) + + { ast, state } end def compile({:%{}, _, properties}, state) do - properties + ast = properties |> Enum.map(fn ({x, y}) -> case x do {_, _, nil } -> - J.property(Form.compile(x, state), Form.compile(y, state), :init, false, false, true) + {key, _} = Form.compile(x, state) + {value, _} = Form.compile(y, state) + J.property(key, value, :init, false, false, true) _ -> - make_property(Form.compile(x, state), Form.compile(y, state)) + {key, _} = Form.compile(x, state) + {value, _} = Form.compile(y, state) + make_property(key, value) end end) |> J.object_expression + + {ast, state} end def make_property(%ESTree.Identifier{} = key, value) do diff --git a/lib/elixir_script/next/passes/translate/forms/match.ex b/lib/elixir_script/next/passes/translate/forms/match.ex index 67fabcc2..9dbd453c 100644 --- a/lib/elixir_script/next/passes/translate/forms/match.ex +++ b/lib/elixir_script/next/passes/translate/forms/match.ex @@ -4,9 +4,9 @@ defmodule ElixirScript.Translate.Forms.Match do alias ElixirScript.Translate.Forms.{Pattern} def compile({:=, _, [left, right]}, state) do - right_ast = Form.compile(right, state) + { right_ast, state } = Form.compile(right, state) - { patterns, params } = Pattern.compile([left], state) + { patterns, params, state } = Pattern.compile([left], state) declarator = J.variable_declarator( J.array_pattern(params), @@ -38,7 +38,7 @@ defmodule ElixirScript.Translate.Forms.Match do array_pattern end - js_ast + { js_ast, state } end @@ -83,8 +83,7 @@ defmodule ElixirScript.Translate.Forms.Match do defp make_variable_declaration_and_group(ref_declarator, array_pattern) do ref_declaration = J.variable_declaration([ref_declarator], :let) - #[array_pattern, ref_declaration] - array_pattern + [array_pattern, ref_declaration] end end \ No newline at end of file diff --git a/lib/elixir_script/next/passes/translate/forms/pattern.ex b/lib/elixir_script/next/passes/translate/forms/pattern.ex index 5ed3ba6b..08c5fa5d 100644 --- a/lib/elixir_script/next/passes/translate/forms/pattern.ex +++ b/lib/elixir_script/next/passes/translate/forms/pattern.ex @@ -2,7 +2,7 @@ defmodule ElixirScript.Translate.Forms.Pattern do alias ElixirScript.Translator.PatternMatching, as: PM alias ESTree.Tools.Builder, as: J alias ElixirScript.Translate.Form - alias ElixirScript.Translate.Forms.{Bitstring, Map} + alias ElixirScript.Translate.Forms.{Bitstring} @moduledoc """ Handles all pattern matching translations @@ -15,14 +15,43 @@ defmodule ElixirScript.Translate.Forms.Pattern do {pattern, param} = process_pattern(x, state) { patterns ++ List.wrap(pattern), params ++ List.wrap(param) } end) + |> update_env(state) + end + + defp update_env({ patterns, params }, state) do + { params, state } = Enum.map_reduce(params, state, fn + (%ESTree.Identifier{name: :undefined} = param, state) -> + { param, state } + + (%ESTree.Identifier{} = param, state) -> + state = update_variable(param.name, state) + new_name = get_variable_name(param.name, state) + + { %{ param | name: new_name }, state } + + (param, state) -> + { param, state } + end) + + { patterns, params, state } + end + + defp get_variable_name(function, state) do + number = Map.get(state.vars, function) + String.to_atom("#{function}#{number}") + end + + defp update_variable(name, state) do + vars = Map.update(state.vars, name, 0, fn val -> val + 1 end) + Map.put(state, :vars, vars) end defp process_pattern(term, state) when is_number(term) or is_binary(term) or is_boolean(term) or is_atom(term) or is_nil(term) do - { [Form.compile(term, state)], [] } + { [Form.compile!(term, state)], [] } end defp process_pattern({:^, _, [value]}, state) do - { [PM.bound(Form.compile(value, state))], [nil] } + { [PM.bound(Form.compile!(value, state))], [nil] } end defp process_pattern({:_, _, _}, _) do @@ -34,7 +63,7 @@ defmodule ElixirScript.Translate.Forms.Pattern do end defp process_pattern({:{}, _, elements }, state) do - { patterns, params } = elements + { patterns, params, state } = elements |> Enum.map(&compile([&1], state)) |> reduce_patterns(state) @@ -57,7 +86,7 @@ defmodule ElixirScript.Translate.Forms.Pattern do end defp process_pattern(list, state) when is_list(list) do - { patterns, params } = list + { patterns, params, state } = list |> Enum.map(&compile([&1], state)) |> reduce_patterns(state) @@ -69,9 +98,9 @@ defmodule ElixirScript.Translate.Forms.Pattern do {pattern, params} = process_pattern(value, state) property = case key do {:^, _, [the_key]} -> - J.property(Form.compile(the_key, state), hd(List.wrap(pattern)), :init, false, false, true) + J.property(Form.compile!(the_key, state), hd(List.wrap(pattern)), :init, false, false, true) _ -> - Map.make_property(Form.compile(key, state), hd(List.wrap(pattern))) + ElixirScript.Translate.Forms.Map.make_property(Form.compile!(key, state), hd(List.wrap(pattern))) end { property, params } @@ -112,7 +141,7 @@ defmodule ElixirScript.Translate.Forms.Pattern do end defp process_pattern({:<>, _, [prefix, value]}, state) do - { [PM.starts_with(prefix)], [Form.compile(value, state)] } + { [PM.starts_with(prefix)], [Form.compile!(value, state)] } end defp process_pattern({:=, _, [{name, _, _}, right]}, state) do diff --git a/lib/elixir_script/next/passes/translate/forms/receive.ex b/lib/elixir_script/next/passes/translate/forms/receive.ex index 99a25c7e..8d021a7e 100644 --- a/lib/elixir_script/next/passes/translate/forms/receive.ex +++ b/lib/elixir_script/next/passes/translate/forms/receive.ex @@ -17,10 +17,11 @@ defmodule ElixirScript.Translate.Forms.Receive do J.identifier("receive") ) - J.call_expression( + ast = J.call_expression( receive_function, [] ) + { ast, state } end end \ No newline at end of file diff --git a/lib/elixir_script/next/passes/translate/forms/struct.ex b/lib/elixir_script/next/passes/translate/forms/struct.ex index 4b4e83fd..e88bc492 100644 --- a/lib/elixir_script/next/passes/translate/forms/struct.ex +++ b/lib/elixir_script/next/passes/translate/forms/struct.ex @@ -4,13 +4,15 @@ defmodule ElixirScript.Translate.Forms.Struct do alias ElixirScript.Translator.Identifier def compile({:%, _, [module, params]}, state) do - J.call_expression( + ast = J.call_expression( J.member_expression( process_module_name(module), J.identifier("__struct__1") ), - [Form.compile(params, state)] + [Form.compile!(params, state)] ) + + { ast, state } end defp process_module_name(module) do diff --git a/lib/elixir_script/next/passes/translate/forms/try.ex b/lib/elixir_script/next/passes/translate/forms/try.ex index 940bc7ae..dafaacb3 100644 --- a/lib/elixir_script/next/passes/translate/forms/try.ex +++ b/lib/elixir_script/next/passes/translate/forms/try.ex @@ -23,7 +23,7 @@ defmodule ElixirScript.Translate.Forms.Try do end catch_block = if catch_block do - Form.compile({:fn, [], catch_block}, state) + Form.compile!({:fn, [], catch_block}, state) else JS.identifier(:null) end @@ -35,7 +35,7 @@ defmodule ElixirScript.Translate.Forms.Try do end else_block = if else_block do - Form.compile({:fn, [], else_block}, state) + Form.compile!({:fn, [], else_block}, state) else JS.identifier(:null) end @@ -60,15 +60,17 @@ defmodule ElixirScript.Translate.Forms.Try do ] ) - js_ast + { js_ast, state } end defp process_rescue_block(rescue_block, state) do processed_clauses = Enum.map(rescue_block, fn {:->, _, [ [{:in, _, [param, names]} = pattern], body]} -> - Clause.compile({[], [param], [{{:., [], [Enum, :member?]}, [], [param, names]}], body}, state) + {ast, _} = Clause.compile({[], [param], [{{:., [], [Enum, :member?]}, [], [param, names]}], body}, state) + ast {:->, _, [ [param], body]} -> - Clause.compile({[], [param], [], body}, state) + {ast, _} = Clause.compile({[], [param], [], body}, state) + ast end) @@ -90,9 +92,10 @@ defmodule ElixirScript.Translate.Forms.Try do end defp prepare_function_body(body, state) do - body + {ast, state} = body |> List.wrap - |> Enum.map(&Form.compile(&1, state)) - |> Clause.return_last_statement + |> Enum.map_reduce(state, &Form.compile(&1, &2)) + + Clause.return_last_statement(ast) end end diff --git a/lib/elixir_script/next/passes/translate/function.ex b/lib/elixir_script/next/passes/translate/function.ex index 50d83a2d..1844ad31 100644 --- a/lib/elixir_script/next/passes/translate/function.ex +++ b/lib/elixir_script/next/passes/translate/function.ex @@ -52,14 +52,13 @@ defmodule ElixirScript.Translate.Function do ) ) - J.variable_declaration([declarator], :const) + { J.variable_declaration([declarator], :const), state } end defp compile_clauses(clauses, state) do clauses |> Enum.map(&compile_clause(&1, state)) |> Enum.map(fn {patterns, params, guards, body} -> - IO.inspect guards match_or_default_call = J.call_expression( J.member_expression( patterns_ast(), @@ -87,20 +86,22 @@ defmodule ElixirScript.Translate.Function do end defp compile_clause({ _, args, guards, body}, state) do - {patterns, params} = Pattern.compile(args, state) + state = Map.put(state, :vars, %{}) + + {patterns, params, state} = Pattern.compile(args, state) guard = Clause.compile_guard(params, guards, state) body = case body do nil -> J.identifier("null") {:__block__, _, block_body} -> - Enum.map(block_body, &Form.compile(&1, state)) - |> List.flatten + {list, _} = Enum.map_reduce(block_body, state, &Form.compile(&1, &2)) + List.flatten(list) b when is_list(b) -> - Enum.map(b, &Form.compile(&1, state)) - |> List.flatten + {list, _} = Enum.map_reduce(b, state, &Form.compile(&1, &2)) + List.flatten(list) _ -> - Form.compile(body, state) + Form.compile!(body, state) end body = Clause.return_last_statement(body) diff --git a/lib/elixir_script/next/passes/translate/module.ex b/lib/elixir_script/next/passes/translate/module.ex index 8b7c02d2..79a7b3fb 100644 --- a/lib/elixir_script/next/passes/translate/module.ex +++ b/lib/elixir_script/next/passes/translate/module.ex @@ -49,8 +49,8 @@ defmodule ElixirScript.Translate.Module do end - compiled_functions = used_defs - |> Enum.map(&Function.compile(&1, state)) + { compiled_functions, _ } = used_defs + |> Enum.map_reduce(state, &Function.compile(&1, &2)) exports = make_exports(used_defs) From 7150eeeef92726afa4f4366eab9609c9c5849f4a Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Wed, 31 May 2017 19:57:27 -0500 Subject: [PATCH 104/418] Update elixirscript cli and mix task to use new compiler --- lib/elixir_script/cli.ex | 48 +++++++++----------- lib/elixir_script/watcher.ex | 2 +- lib/mix/tasks/compile.elixir_script.ex | 63 +++++++++----------------- lib/mix/tasks/elixirscript.watch.ex | 38 ++-------------- mix.exs | 16 ++----- package.json | 2 +- test/{app/src => support}/main.ex | 0 test/{app/src => support}/user.ex | 0 8 files changed, 54 insertions(+), 115 deletions(-) rename test/{app/src => support}/main.ex (100%) rename test/{app/src => support}/user.ex (100%) diff --git a/lib/elixir_script/cli.ex b/lib/elixir_script/cli.ex index e1e573eb..6910d561 100644 --- a/lib/elixir_script/cli.ex +++ b/lib/elixir_script/cli.ex @@ -4,13 +4,19 @@ defmodule ElixirScript.CLI do @app_version Mix.Project.config()[:version] @switches [ - output: :string, elixir: :boolean, - help: :boolean, full_build: :boolean, version: :boolean, - watch: :boolean, format: :string, js_module: [:string, :keep], remove_unused: :boolean + output: :string, + help: :boolean, + version: :boolean, + watch: :boolean, + format: :string, + js_module: [:string, :keep] ] @aliases [ - o: :output, e: :elixir, h: :help, v: :version, f: :format + o: :output, + h: :help, + v: :version, + f: :format ] def main(argv) do @@ -39,9 +45,8 @@ defmodule ElixirScript.CLI do def help_message() do """ - usage: elixirscript [options] - path to elixir files or - the elixir code string if passed the -e flag + usage: elixirscript [options] + the entry module of your application options: --js-module [:] A js module used in your code. ex: React:react @@ -49,9 +54,6 @@ defmodule ElixirScript.CLI do -f --format [format] module format of output. options: es (default), common, umd -o --output [path] places output at the given path. Can be a directory or filename. - -e --elixir read input as elixir code string - --remove-unused Removes unused modules from output - --full-build informs the compiler to do a full build instead of an incremental one -v --version the current version number -h --help this message """ @@ -79,27 +81,18 @@ defmodule ElixirScript.CLI do js_modules = Keyword.get_values(options, :js_module) |> build_js_modules - compile_opts = %{ - include_path: true, - core_path: Keyword.get(options, :core_path, "Elixir.Bootstrap"), - full_build: Keyword.get(options, :full_build, false), + compile_opts = [ output: Keyword.get(options, :output, :stdout), format: String.to_atom(Keyword.get(options, :format, "es")), js_modules: js_modules, - remove_unused: Keyword.get(options, :remove_unused, false) - } + ] - case options[:elixir] do - true -> - ElixirScript.compile(input, compile_opts) - _ -> - input = handle_input(input) - ElixirScript.compile_path(input, compile_opts) - - if watch do - ElixirScript.Watcher.start_link(input, compile_opts) - :timer.sleep :infinity - end + input = handle_input(input) + ElixirScript.Compiler.compile(input, compile_opts) + + if watch do + ElixirScript.Watcher.start_link(input, compile_opts) + :timer.sleep :infinity end end @@ -117,6 +110,7 @@ defmodule ElixirScript.CLI do input = input |> Enum.map(fn(x) -> String.split(x, [" ", ","], trim: true) end) |> List.flatten + |> Enum.map(fn(x) -> Module.concat([x]) end) end defp build_js_modules(values) do diff --git a/lib/elixir_script/watcher.ex b/lib/elixir_script/watcher.ex index b54cc03e..8d484de1 100644 --- a/lib/elixir_script/watcher.ex +++ b/lib/elixir_script/watcher.ex @@ -24,7 +24,7 @@ defmodule ElixirScript.Watcher do try do if input_changed?(to_string(path), state) do Logger.debug "Event: #{inspect event} Path: #{path}" - ElixirScript.compile_path(state[:input], state[:options]) + ElixirScript.Compiler.compile(state[:input], state[:options]) end rescue x -> diff --git a/lib/mix/tasks/compile.elixir_script.ex b/lib/mix/tasks/compile.elixir_script.ex index e448a117..0abf7e9c 100644 --- a/lib/mix/tasks/compile.elixir_script.ex +++ b/lib/mix/tasks/compile.elixir_script.ex @@ -14,13 +14,13 @@ defmodule Mix.Tasks.Compile.ElixirScript do version: "0.1.0", elixir: "~> 1.0", deps: deps, - elixir_script: [ input: "src/exjs", output: "dest/js"], - compilers: [:elixir_script] ++ Mix.compilers + elixir_script: [ entry: Example, output: "dest/js"], + compilers: Mix.compilers ++ [:elixir_script] ] end Available options are: - * `input`: The folder to look for Elixirscript files in. (defaults to `lib/elixirscript`) + * `input`: The module or modules that are the entry to your application (required) * `output`: The path of the generated JavaScript file. (defaults to `priv/elixirscript`) If path ends in `.js` then that will be the name of the file. If a directory is given, @@ -47,50 +47,30 @@ defmodule Mix.Tasks.Compile.ElixirScript do end defp do_compile(elixirscript_base, app) do - elixirscript_config = get_elixirscript_config() - File.mkdir_p!(elixirscript_base) - elixirscript_path = Path.join([elixirscript_base, "#{app}"]) - - input_path = elixirscript_config - |> Keyword.get(:input) - |> List.wrap - |> Enum.map(fn(path) -> - Path.absname(path) - end) - |> Enum.join("\n") - - File.write!(elixirscript_path, input_path) - - paths = [elixirscript_base, "*"] - |> Path.join() - |> Path.wildcard - |> Enum.map(fn(path) -> - app = Path.basename(path) - paths = path |> File.read!() |> String.split("\n") - {app, paths} - end) - |> Map.new - - output_path = Keyword.get(elixirscript_config, :output) - format = Keyword.get(elixirscript_config, :format) - js_modules = Keyword.get(elixirscript_config, :js_modules, []) - - ElixirScript.compile_path(paths, %{output: output_path, format: format, js_modules: js_modules}) + + {input, opts} = get_compiler_params() + ElixirScript.compiler.compile(input, opts) end def clean do - elixirscript_config = get_elixirscript_config() - output_path = Keyword.get(elixirscript_config, :output) - - path = ElixirScript.Passes.HandleOutput.get_js_path(output_path) - - if File.exists?(path) do - File.rm!(path) - end - + #TODO: Figure out how to clean :ok end + @doc false + def get_compiler_params() do + elixirscript_config = get_elixirscript_config() + input = Keyword.fetch!(elixirscript_config, :input) + opts = [ + output: Keyword.get(elixirscript_config, :output), + format: Keyword.get(elixirscript_config, :format), + js_modules: Keyword.get(elixirscript_config, :js_modules, []) + ] + + {input, opts} + end + + defp get_elixirscript_config() do config = Mix.Project.config exjs_config = cond do @@ -107,7 +87,6 @@ defmodule Mix.Tasks.Compile.ElixirScript do defp defaults() do [ - input: "lib/elixirscript", output: "priv/elixirscript", format: :es ] diff --git a/lib/mix/tasks/elixirscript.watch.ex b/lib/mix/tasks/elixirscript.watch.ex index ace5bbc6..5235d700 100644 --- a/lib/mix/tasks/elixirscript.watch.ex +++ b/lib/mix/tasks/elixirscript.watch.ex @@ -14,51 +14,23 @@ defmodule Mix.Tasks.Elixirscript.Watch do version: "0.1.0", elixir: "~> 1.0", deps: deps, - elixir_script: [ input: "src/exjs", output: "dest/js"], - compilers: [:elixir_script] ++ Mix.compilers + elixir_script: [ input: Example, output: "dest/js"], + compilers: Mix.compilers ++ [:elixir_script] ] end """ - - def run(_) do Mix.Task.run "app.start" - elixirscript_config = get_elixirscript_config() - input_path = Keyword.get(elixirscript_config, :input) - output_path = Keyword.get(elixirscript_config, :output) - format = Keyword.get(elixirscript_config, :format) - js_modules = Keyword.get(elixirscript_config, :js_modules, []) + {input, opts} = Mix.Tasks.Compile.ElixirScript.get_compiler_params() {:ok, _} = ElixirScript.Watcher.start_link( - input_path, - %{output: output_path, format: format, js_modules: js_modules} + input, + opts ) :timer.sleep :infinity end - defp get_elixirscript_config() do - config = Mix.Project.config - exjs_config = cond do - Keyword.has_key?(config, :elixir_script) -> - Keyword.get(config, :elixir_script, []) - Keyword.has_key?(config, :elixirscript) -> - Keyword.get(config, :elixirscript, []) - true -> - defaults() - end - - Keyword.merge(defaults(), exjs_config) - end - - defp defaults() do - [ - input: "lib/elixirscript", - output: "priv/elixirscript", - format: :es - ] - end - end diff --git a/mix.exs b/mix.exs index a9b380f3..8a5a9573 100644 --- a/mix.exs +++ b/mix.exs @@ -5,8 +5,8 @@ defmodule ElixirScript.Mixfile do [ app: :elixir_script, version: "0.28.0-dev", - elixir: "~> 1.0", - elixirc_paths: elixirc_paths(), + elixir: "~> 1.5-dev", + elixirc_paths: elixirc_paths(Mix.env), escript: escript_config(), deps: deps(), description: description(), @@ -36,7 +36,8 @@ defmodule ElixirScript.Mixfile do ] end - defp elixirc_paths(), do: ["lib", "priv/std_lib"] + defp elixirc_paths(:test), do: ["lib", "priv/std_lib", "test/support"] + defp elixirc_paths(_), do: ["lib", "priv/std_lib"] defp escript_config do [main_module: ElixirScript.CLI, name: "elixirscript"] @@ -62,8 +63,7 @@ defmodule ElixirScript.Mixfile do defp aliases do [dist: &dist/1, - install: &install/1, - supported: &supported/1] + install: &install/1] end def dist(_) do @@ -106,10 +106,4 @@ defmodule ElixirScript.Mixfile do IO.puts("installed at /usr/local/elixirscript") end - def supported(_) do - Mix.Task.run "app.start" - - ElixirScript.Gen.Supported.generate() - end - end diff --git a/package.json b/package.json index 90b86fb4..55cc3f34 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,7 @@ "build": "rollup -c rollup.config.js", "clean": "rm -rf priv/build", "test": "nyc ava src/javascript/tests", - "build:test-app": "mix elixirscript test/app/src/ -f common -o test/app/build/", + "build:test-app": "MIX_ENV=test mix elixirscript Main -f common -o test/app/build/", "test-app": "yarn run build:test-app && NODE_ENV=test ava 'test/app/spec/**/*.spec.js'" }, "repository": { diff --git a/test/app/src/main.ex b/test/support/main.ex similarity index 100% rename from test/app/src/main.ex rename to test/support/main.ex diff --git a/test/app/src/user.ex b/test/support/user.ex similarity index 100% rename from test/app/src/user.ex rename to test/support/user.ex From 30aa2fab7ed59e77ef1b1fedc9b6392c819fb7ae Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Wed, 31 May 2017 22:00:48 -0500 Subject: [PATCH 105/418] Fix some compilation errors found from testing --- .../next/passes/translate/examples/example.ex | 3 +- .../next/passes/translate/form.ex | 25 +++++++++++++---- .../next/passes/translate/forms/pattern.ex | 28 +++++++++++++------ 3 files changed, 41 insertions(+), 15 deletions(-) diff --git a/lib/elixir_script/next/passes/translate/examples/example.ex b/lib/elixir_script/next/passes/translate/examples/example.ex index 5db58d5a..6d09d63f 100644 --- a/lib/elixir_script/next/passes/translate/examples/example.ex +++ b/lib/elixir_script/next/passes/translate/examples/example.ex @@ -1,7 +1,8 @@ defmodule Example do def start(_, _) do a = 1 - a = 2 + [d, b, c] = [1, 2, 3] + [e | g] = [1, 2, 3] end end diff --git a/lib/elixir_script/next/passes/translate/form.ex b/lib/elixir_script/next/passes/translate/form.ex index b8181a25..9024fde1 100644 --- a/lib/elixir_script/next/passes/translate/form.ex +++ b/lib/elixir_script/next/passes/translate/form.ex @@ -46,20 +46,20 @@ defmodule ElixirScript.Translate.Form do end def compile(form, state) when is_atom(form) do - if ElixirScript.Translate.Module.is_elixir_module(form) do + ast = if ElixirScript.Translate.Module.is_elixir_module(form) do members = if form == Elixir, do: ["Elixir"], else: ["Elixir"] ++ Module.split(form) - { J.identifier(Enum.join(members, "_")), state } + J.identifier(Enum.join(members, "_")) else - ast = J.call_expression( + J.call_expression( J.member_expression( J.identifier("Symbol"), J.identifier("for") ), [J.literal(form)] ) - - { ast, state } end + + { ast, state } end def compile({a, b}, state) do @@ -77,6 +77,8 @@ defmodule ElixirScript.Translate.Form do ), Enum.map(elements, &compile!(&1, state)) ) + + {ast, state} end def compile({:%{}, _, _} = map, state) do @@ -384,6 +386,15 @@ defmodule ElixirScript.Translate.Form do {ast, state} end + def compile({{:., _, [function_name]}, _, params}, state) do + ast = J.call_expression( + compile!(function_name, state), + Enum.map(params, &compile!(&1, state)) + ) + + {ast, state} + end + def compile({{:., _, [module, function]}, _, params}, state) when module in @erlang_modules do ast = J.call_expression( @@ -399,6 +410,8 @@ defmodule ElixirScript.Translate.Form do ), Enum.map(params, &compile!(&1, state)) ) + + {ast, state} end def compile({{:., _, [_, _]}, _, _} = ast, state) do @@ -425,7 +438,7 @@ defmodule ElixirScript.Translate.Form do ) _ -> J.call_expression( - compile(function_name, state), + compile!(function_name, state), Enum.map(params, &compile!(&1, state)) ) end diff --git a/lib/elixir_script/next/passes/translate/forms/pattern.ex b/lib/elixir_script/next/passes/translate/forms/pattern.ex index 08c5fa5d..8cbab551 100644 --- a/lib/elixir_script/next/passes/translate/forms/pattern.ex +++ b/lib/elixir_script/next/passes/translate/forms/pattern.ex @@ -10,12 +10,16 @@ defmodule ElixirScript.Translate.Forms.Pattern do def compile(patterns, state) do patterns - |> Enum.reduce({[], []}, fn + |> do_compile(state) + |> update_env(state) + end + + defp do_compile(patterns, state) do + Enum.reduce(patterns, {[], []}, fn x, { patterns, params } -> {pattern, param} = process_pattern(x, state) { patterns ++ List.wrap(pattern), params ++ List.wrap(param) } - end) - |> update_env(state) + end) end defp update_env({ patterns, params }, state) do @@ -63,8 +67,8 @@ defmodule ElixirScript.Translate.Forms.Pattern do end defp process_pattern({:{}, _, elements }, state) do - { patterns, params, state } = elements - |> Enum.map(&compile([&1], state)) + { patterns, params } = elements + |> Enum.map(&do_compile([&1], state)) |> reduce_patterns(state) pattern = J.object_expression([ @@ -86,13 +90,21 @@ defmodule ElixirScript.Translate.Forms.Pattern do end defp process_pattern(list, state) when is_list(list) do - { patterns, params, state } = list - |> Enum.map(&compile([&1], state)) + { patterns, params } = list + |> Enum.map(&do_compile([&1], state)) |> reduce_patterns(state) {[J.array_expression(patterns)], params} end + defp process_pattern({:|, _, [head, tail]}, state) do + { head_patterns, head_params } = process_pattern(head, state) + { tail_patterns, tail_params } = process_pattern(tail, state) + params = head_params ++ tail_params + + { [PM.head_tail(hd(head_patterns), hd(tail_patterns))], params } + end + defp process_pattern({:%{}, _, props}, state) do properties = Enum.map(props, fn({key, value}) -> {pattern, params} = process_pattern(value, state) @@ -164,7 +176,7 @@ defmodule ElixirScript.Translate.Forms.Pattern do end defp unify(target, source, state) do - { patterns, params } = compile([source], state) + { patterns, params } = do_compile([source], state) { [PM.capture(hd(patterns))], params ++ [ElixirScript.Translator.Identifier.make_identifier(target)] } end end From e5dabf516a7dff3e8447a106887603b4996e5a74 Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Thu, 1 Jun 2017 19:23:43 -0500 Subject: [PATCH 106/418] Combining functions with same names and different arities --- .../next/passes/translate/clause.ex | 4 +-- .../next/passes/translate/examples/example.ex | 1 - .../next/passes/translate/form.ex | 8 +++--- .../next/passes/translate/forms/call.ex | 2 +- .../next/passes/translate/forms/for.ex | 4 +-- .../next/passes/translate/forms/try.ex | 4 +-- .../next/passes/translate/function.ex | 2 +- .../next/passes/translate/module.ex | 16 +++++++++-- .../next/passes/translate/protocol.ex | 4 +-- .../kernel/special_forms/identifier.ex | 4 +-- .../lib/core/erlang_compat/erlang.js | 12 ++++---- .../lib/core/erlang_compat/lists.js | 4 +-- src/javascript/lib/core/erlang_compat/maps.js | 8 +++--- .../tests/core/erlang_compat/erlang_spec.js | 28 +++++++++---------- .../tests/core/erlang_compat/lists_spec.js | 4 +-- .../tests/core/erlang_compat/maps_spec.js | 14 +++++----- 16 files changed, 64 insertions(+), 55 deletions(-) diff --git a/lib/elixir_script/next/passes/translate/clause.ex b/lib/elixir_script/next/passes/translate/clause.ex index 57f0abce..1747c8a3 100644 --- a/lib/elixir_script/next/passes/translate/clause.ex +++ b/lib/elixir_script/next/passes/translate/clause.ex @@ -41,7 +41,7 @@ defmodule ElixirScript.Translate.Clause do ), [ J.array_expression(patterns), - J.function_expression( + J.arrow_function_expression( params, [], J.block_statement(body) @@ -117,7 +117,7 @@ defmodule ElixirScript.Translate.Clause do |> process_guards |> Form.compile!(state) - J.function_expression( + J.arrow_function_expression( params, [], J.block_statement([ diff --git a/lib/elixir_script/next/passes/translate/examples/example.ex b/lib/elixir_script/next/passes/translate/examples/example.ex index 6d09d63f..438be849 100644 --- a/lib/elixir_script/next/passes/translate/examples/example.ex +++ b/lib/elixir_script/next/passes/translate/examples/example.ex @@ -4,5 +4,4 @@ defmodule Example do [d, b, c] = [1, 2, 3] [e | g] = [1, 2, 3] end - end diff --git a/lib/elixir_script/next/passes/translate/form.ex b/lib/elixir_script/next/passes/translate/form.ex index 9024fde1..32d7af28 100644 --- a/lib/elixir_script/next/passes/translate/form.ex +++ b/lib/elixir_script/next/passes/translate/form.ex @@ -123,7 +123,7 @@ defmodule ElixirScript.Translate.Form do { translated_body, state } = Enum.map_reduce(List.wrap(clause_body), state, &compile(&1, &2)) translated_body = Clause.return_last_statement(translated_body) - translated_body = J.function_expression([], [], J.block_statement(translated_body)) + translated_body = J.arrow_function_expression([], [], J.block_statement(translated_body)) translated_clause = compile(hd(clause), state) @@ -406,7 +406,7 @@ defmodule ElixirScript.Translate.Form do ), J.identifier(module) ), - ElixirScript.Translator.Identifier.make_function_name(function, length(params)) + ElixirScript.Translator.Identifier.make_function_name(function) ), Enum.map(params, &compile!(&1, state)) ) @@ -422,7 +422,7 @@ defmodule ElixirScript.Translate.Form do {function_name, _} = Map.get(state, :function) ast = J.call_expression( - ElixirScript.Translator.Identifier.make_function_name(function_name, length(params)), + ElixirScript.Translator.Identifier.make_function_name(function_name), Enum.map(params, &compile!(&1, state)) ) @@ -433,7 +433,7 @@ defmodule ElixirScript.Translate.Form do ast = case function_name do a when is_atom(a) -> J.call_expression( - ElixirScript.Translator.Identifier.make_function_name(function_name, length(params)), + ElixirScript.Translator.Identifier.make_function_name(function_name), Enum.map(params, &compile!(&1, state)) ) _ -> diff --git a/lib/elixir_script/next/passes/translate/forms/call.ex b/lib/elixir_script/next/passes/translate/forms/call.ex index cd6cb269..704330bd 100644 --- a/lib/elixir_script/next/passes/translate/forms/call.ex +++ b/lib/elixir_script/next/passes/translate/forms/call.ex @@ -8,7 +8,7 @@ defmodule ElixirScript.Translate.Forms.Call do ElixirScript.Translate.Module.is_js_module(module, state) -> ElixirScript.Translator.Identifier.make_extern_function_name(function) true -> - ElixirScript.Translator.Identifier.make_function_name(function, length(params)) + ElixirScript.Translator.Identifier.make_function_name(function) end ast = J.call_expression( diff --git a/lib/elixir_script/next/passes/translate/forms/for.ex b/lib/elixir_script/next/passes/translate/forms/for.ex index 930b6a10..940773da 100644 --- a/lib/elixir_script/next/passes/translate/forms/for.ex +++ b/lib/elixir_script/next/passes/translate/forms/for.ex @@ -10,7 +10,7 @@ defmodule ElixirScript.Translate.Forms.For do generators = JS.array_expression(args.generators) into = args.into || JS.array_expression([]) - filter = args.filter || JS.function_expression([], [], JS.block_statement([JS.return_statement(JS.identifier("true"))])) + filter = args.filter || JS.arrow_function_expression([], [], JS.block_statement([JS.return_statement(JS.identifier("true"))])) fun = args.fun @@ -128,7 +128,7 @@ defmodule ElixirScript.Translate.Forms.For do ast = Clause.return_last_statement(ast) - JS.function_expression( + JS.arrow_function_expression( state.args, [], JS.block_statement(ast) diff --git a/lib/elixir_script/next/passes/translate/forms/try.ex b/lib/elixir_script/next/passes/translate/forms/try.ex index dafaacb3..52bf3076 100644 --- a/lib/elixir_script/next/passes/translate/forms/try.ex +++ b/lib/elixir_script/next/passes/translate/forms/try.ex @@ -14,7 +14,7 @@ defmodule ElixirScript.Translate.Forms.Try do translated_body = prepare_function_body(try_block, state) translated_body = JS.block_statement(translated_body) - try_block = JS.function_expression([], [], translated_body) + try_block = JS.arrow_function_expression([], [], translated_body) rescue_block = if rescue_block do process_rescue_block(rescue_block, state) @@ -88,7 +88,7 @@ defmodule ElixirScript.Translate.Forms.Try do translated_body = prepare_function_body(after_block, state) translated_body = JS.block_statement(translated_body) - JS.function_expression([], [], translated_body) + JS.arrow_function_expression([], [], translated_body) end defp prepare_function_body(body, state) do diff --git a/lib/elixir_script/next/passes/translate/function.ex b/lib/elixir_script/next/passes/translate/function.ex index 1844ad31..aee6819c 100644 --- a/lib/elixir_script/next/passes/translate/function.ex +++ b/lib/elixir_script/next/passes/translate/function.ex @@ -32,7 +32,7 @@ defmodule ElixirScript.Translate.Function do arg_matches_declaration = J.variable_declaration([arg_matches_declarator], :let) declarator = J.variable_declarator( - ElixirScript.Translator.Identifier.make_function_name(name, arity), + ElixirScript.Translator.Identifier.make_function_name(name), J.function_expression( [J.rest_element(J.identifier("__function_args__"))], [], diff --git a/lib/elixir_script/next/passes/translate/module.ex b/lib/elixir_script/next/passes/translate/module.ex index 79a7b3fb..e447f9b2 100644 --- a/lib/elixir_script/next/passes/translate/module.ex +++ b/lib/elixir_script/next/passes/translate/module.ex @@ -48,11 +48,21 @@ defmodule ElixirScript.Translate.Module do end) end + #we combine our function arities + combined_defs = used_defs + |> Enum.sort(fn { {name1, arity1}, _, _, _ }, { {name2, arity2}, _, _, _ } -> "#{name1}#{arity1}" < "#{name2}#{arity2}" end) + |> Enum.group_by(fn {{name, _}, _, _, _ } -> name end) + |> Enum.map(fn {group, funs} -> + {_, type, _, _} = hd(funs) + Enum.reduce(funs, {{group, nil}, type, [], []}, fn {_, _, _, clauses}, {name, type, context, acc_clauses} -> + {name, type, context, acc_clauses ++ clauses} + end) + end) - { compiled_functions, _ } = used_defs + { compiled_functions, _ } = combined_defs |> Enum.map_reduce(state, &Function.compile(&1, &2)) - exports = make_exports(used_defs) + exports = make_exports(combined_defs) js_ast = ElixirScript.ModuleSystems.Namespace.build( module, @@ -67,7 +77,7 @@ defmodule ElixirScript.Translate.Module do defp make_exports(reachable_defs) do exports = Enum.reduce(reachable_defs, [], fn {{name, arity}, :def, _, _}, list -> - function_name = ElixirScript.Translator.Identifier.make_function_name(name, arity) + function_name = ElixirScript.Translator.Identifier.make_identifier(name) list ++ [J.property(function_name, function_name, :init, true)] _, list -> list diff --git a/lib/elixir_script/next/passes/translate/protocol.ex b/lib/elixir_script/next/passes/translate/protocol.ex index 0b549292..d64375bd 100644 --- a/lib/elixir_script/next/passes/translate/protocol.ex +++ b/lib/elixir_script/next/passes/translate/protocol.ex @@ -11,8 +11,8 @@ defmodule ElixirScript.Translate.Protocol do This compiles and consolidates the given protocol """ def compile(module, %{protocol: true, impls: impls, functions: functions} = info, pid) do - object = Enum.map(functions, fn {function, arity} -> - {Identifier.make_function_name(function, arity), J.function_expression([], [], J.block_statement([]))} + object = Enum.map(functions, fn {function, _} -> + {Identifier.make_function_name(function), J.function_expression([], [], J.block_statement([]))} end) |> Enum.map(fn({key, value}) -> ElixirScript.Translate.Forms.Map.make_property(key, value) end) |> J.object_expression diff --git a/lib/elixir_script/translator/kernel/special_forms/identifier.ex b/lib/elixir_script/translator/kernel/special_forms/identifier.ex index 99586343..584082e6 100644 --- a/lib/elixir_script/translator/kernel/special_forms/identifier.ex +++ b/lib/elixir_script/translator/kernel/special_forms/identifier.ex @@ -86,9 +86,9 @@ defmodule ElixirScript.Translator.Identifier do |> make_alias end - def make_function_name(name, arity) when is_atom(name) do + def make_function_name(name) when is_atom(name) do name = filter_name(name) - JS.identifier("#{name}#{arity}") + JS.identifier(name) end def make_extern_function_name(name) do diff --git a/src/javascript/lib/core/erlang_compat/erlang.js b/src/javascript/lib/core/erlang_compat/erlang.js index 0b09676c..81b89a66 100644 --- a/src/javascript/lib/core/erlang_compat/erlang.js +++ b/src/javascript/lib/core/erlang_compat/erlang.js @@ -1,6 +1,6 @@ // http://erlang.org/doc/man/erlang.html -function atom_to_binary2(atom, encoding = Symbol.for('utf8')) { +function atom_to_binary(atom, encoding = Symbol.for('utf8')) { if (encoding !== Symbol.for('utf8')) { throw new Error(`unsupported encoding ${encoding}`); } @@ -8,11 +8,11 @@ function atom_to_binary2(atom, encoding = Symbol.for('utf8')) { return Symbol.keyFor(atom); } -function list_concatenation2(list1, list2) { +function list_concatenation(list1, list2) { return list1.concat(list2); } -function list_subtraction2(list1, list2) { +function list_subtraction(list1, list2) { const list = [...list1]; for (const item of list2) { @@ -27,7 +27,7 @@ function list_subtraction2(list1, list2) { } export default { - atom_to_binary2, - list_concatenation2, - list_subtraction2, + atom_to_binary, + list_concatenation, + list_subtraction, }; diff --git a/src/javascript/lib/core/erlang_compat/lists.js b/src/javascript/lib/core/erlang_compat/lists.js index 1d2814df..8157461d 100644 --- a/src/javascript/lib/core/erlang_compat/lists.js +++ b/src/javascript/lib/core/erlang_compat/lists.js @@ -1,9 +1,9 @@ // http://erlang.org/doc/man/lists.html -function reverse1(list) { +function reverse(list) { return [...list].reverse(); } export default { - reverse1, + reverse, }; diff --git a/src/javascript/lib/core/erlang_compat/maps.js b/src/javascript/lib/core/erlang_compat/maps.js index 97e42b91..fdda87d3 100644 --- a/src/javascript/lib/core/erlang_compat/maps.js +++ b/src/javascript/lib/core/erlang_compat/maps.js @@ -5,7 +5,7 @@ const OK = Symbol.for('ok'); const ERROR = Symbol.for('error'); const BADMAP = Symbol.for('badmap'); -function find2(key, map) { +function find(key, map) { if (map instanceof Object === false) { return new ErlangTypes.Tuple(BADMAP, map); } @@ -19,7 +19,7 @@ function find2(key, map) { return ERROR; } -function fold3(fun, init, map) { +function fold(fun, init, map) { let acc = init; for (const [key, value] of Object.entries(map)) { @@ -30,6 +30,6 @@ function fold3(fun, init, map) { } export default { - find2, - fold3, + find, + fold, }; diff --git a/src/javascript/tests/core/erlang_compat/erlang_spec.js b/src/javascript/tests/core/erlang_compat/erlang_spec.js index 31460192..6bc6d4d0 100644 --- a/src/javascript/tests/core/erlang_compat/erlang_spec.js +++ b/src/javascript/tests/core/erlang_compat/erlang_spec.js @@ -1,23 +1,23 @@ import test from 'ava'; import Core from '../../../lib/core'; -test('atom_to_binary2', t => { - t.is(Core.erlang.atom_to_binary2(Symbol.for('error')), 'error'); +test('atom_to_binary', t => { + t.is(Core.erlang.atom_to_binary(Symbol.for('error')), 'error'); t.is( - Core.erlang.atom_to_binary2(Symbol.for('error'), Symbol.for('utf8')), + Core.erlang.atom_to_binary(Symbol.for('error'), Symbol.for('utf8')), 'error' ); t.throws( - () => Core.erlang.atom_to_binary2(Symbol.for('error'), Symbol.for('utf16')), + () => Core.erlang.atom_to_binary(Symbol.for('error'), Symbol.for('utf16')), Error ); }); -test('list_concatenation2', t => { - t.deepEqual(Core.erlang.list_concatenation2([], []), []); - t.deepEqual(Core.erlang.list_concatenation2([1], []), [1]); - t.deepEqual(Core.erlang.list_concatenation2([1, 2, 3], [4, 5, 6]), [ +test('list_concatenation', t => { + t.deepEqual(Core.erlang.list_concatenation([], []), []); + t.deepEqual(Core.erlang.list_concatenation([1], []), [1]); + t.deepEqual(Core.erlang.list_concatenation([1, 2, 3], [4, 5, 6]), [ 1, 2, 3, @@ -27,10 +27,10 @@ test('list_concatenation2', t => { ]); }); -test('list_subtraction2', t => { - t.deepEqual(Core.erlang.list_subtraction2([], []), []); - t.deepEqual(Core.erlang.list_subtraction2([1], []), [1]); - t.deepEqual(Core.erlang.list_subtraction2([1, 2, 3], [4, 5, 6]), [1, 2, 3]); - t.deepEqual(Core.erlang.list_subtraction2([1, 2, 3], [1, 2, 3]), []); - t.deepEqual(Core.erlang.list_subtraction2([1, 2, 3], [1, 2]), [3]); +test('list_subtraction', t => { + t.deepEqual(Core.erlang.list_subtraction([], []), []); + t.deepEqual(Core.erlang.list_subtraction([1], []), [1]); + t.deepEqual(Core.erlang.list_subtraction([1, 2, 3], [4, 5, 6]), [1, 2, 3]); + t.deepEqual(Core.erlang.list_subtraction([1, 2, 3], [1, 2, 3]), []); + t.deepEqual(Core.erlang.list_subtraction([1, 2, 3], [1, 2]), [3]); }); diff --git a/src/javascript/tests/core/erlang_compat/lists_spec.js b/src/javascript/tests/core/erlang_compat/lists_spec.js index e86e6d46..4e3fbb4e 100644 --- a/src/javascript/tests/core/erlang_compat/lists_spec.js +++ b/src/javascript/tests/core/erlang_compat/lists_spec.js @@ -1,6 +1,6 @@ import test from 'ava'; import Core from '../../../lib/core'; -test('reverse1', t => { - t.deepEqual(Core.lists.reverse1([1, 2, 3]), [3, 2, 1]); +test('reverse', t => { + t.deepEqual(Core.lists.reverse([1, 2, 3]), [3, 2, 1]); }); diff --git a/src/javascript/tests/core/erlang_compat/maps_spec.js b/src/javascript/tests/core/erlang_compat/maps_spec.js index 41d78acd..805c7172 100644 --- a/src/javascript/tests/core/erlang_compat/maps_spec.js +++ b/src/javascript/tests/core/erlang_compat/maps_spec.js @@ -1,22 +1,22 @@ import test from 'ava'; import Core from '../../../lib/core'; -test('find2', t => { +test('find', t => { let myMap = {}; - let result = Core.maps.find2('t', myMap); + let result = Core.maps.find('t', myMap); t.is(result, Symbol.for('error')); myMap = 'Hello'; - result = Core.maps.find2('t', myMap); + result = Core.maps.find('t', myMap); t.deepEqual(result.values, [Symbol.for('badmap'), myMap]); myMap = { t: 'b' }; - result = Core.maps.find2('t', myMap); + result = Core.maps.find('t', myMap); t.deepEqual(result.values, [Symbol.for('ok'), 'b']); }); -test('fold3', t => { - let myMap = { a: 1, b: 2 }; - let result = Core.maps.fold3((k, v, acc) => acc + v, 0, myMap); +test('fold', t => { + const myMap = { a: 1, b: 2 }; + const result = Core.maps.fold((k, v, acc) => acc + v, 0, myMap); t.is(result, 3); }); From a125a003433f8af19ae713553d2d42b7d45e4fa0 Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Fri, 2 Jun 2017 07:42:23 -0500 Subject: [PATCH 107/418] Add remote test. --- .../next/passes/translate/clause.ex | 10 +- .../next/passes/translate/examples/example.ex | 11 +- .../next/passes/translate/form.ex | 277 +----------------- .../next/passes/translate/forms/call.ex | 41 --- .../next/passes/translate/forms/pattern.ex | 6 +- .../next/passes/translate/forms/remote.ex | 163 +++++++++++ .../kernel/special_forms/identifier.ex | 2 +- .../lib/core/erlang_compat/erlang.js | 118 ++++++++ .../passes/translate/forms/remote_test.exs | 14 + 9 files changed, 322 insertions(+), 320 deletions(-) delete mode 100644 lib/elixir_script/next/passes/translate/forms/call.ex create mode 100644 lib/elixir_script/next/passes/translate/forms/remote.ex create mode 100644 test/next/passes/translate/forms/remote_test.exs diff --git a/lib/elixir_script/next/passes/translate/clause.ex b/lib/elixir_script/next/passes/translate/clause.ex index 1747c8a3..dca321a1 100644 --- a/lib/elixir_script/next/passes/translate/clause.ex +++ b/lib/elixir_script/next/passes/translate/clause.ex @@ -23,13 +23,13 @@ defmodule ElixirScript.Translate.Clause do nil -> J.identifier("null") {:__block__, _, block_body} -> - Enum.map(block_body, &Form.compile(&1, state)) - |> List.flatten + {list, _} = Enum.map_reduce(block_body, state, &Form.compile(&1, &2)) + List.flatten(list) b when is_list(b) -> - Enum.map(b, &Form.compile(&1, state)) - |> List.flatten + {list, _} = Enum.map_reduce(b, state, &Form.compile(&1, &2)) + List.flatten(list) _ -> - Form.compile(body, state) + Form.compile!(body, state) end body = return_last_statement(body) diff --git a/lib/elixir_script/next/passes/translate/examples/example.ex b/lib/elixir_script/next/passes/translate/examples/example.ex index 438be849..49367a3d 100644 --- a/lib/elixir_script/next/passes/translate/examples/example.ex +++ b/lib/elixir_script/next/passes/translate/examples/example.ex @@ -1,7 +1,10 @@ defmodule Example do - def start(_, _) do - a = 1 - [d, b, c] = [1, 2, 3] - [e | g] = [1, 2, 3] + def start(v, _) do + case v do + :normal -> + "yolo" + _ -> + "yolo too" + end end end diff --git a/lib/elixir_script/next/passes/translate/form.ex b/lib/elixir_script/next/passes/translate/form.ex index 32d7af28..55aefe78 100644 --- a/lib/elixir_script/next/passes/translate/form.ex +++ b/lib/elixir_script/next/passes/translate/form.ex @@ -1,24 +1,11 @@ defmodule ElixirScript.Translate.Form do alias ESTree.Tools.Builder, as: J - alias ElixirScript.Translate.Forms.{Bitstring, Match, Call, Try, For, Struct, Receive} + alias ElixirScript.Translate.Forms.{Bitstring, Match, Try, For, Struct, Receive, Remote} alias ElixirScript.Translate.Functions.{Erlang, Lists, Maps} alias ElixirScript.Translator.Identifier alias ElixirScript.Translate.Clause require Logger - @erlang_modules [ - :erlang, - :maps, - :lists, - :gen, - :elixir_errors, - :supervisor, - :application, - :code, - :elixir_utils, - :file - ] - @moduledoc """ Handles translation of all forms that are not functions or clauses """ @@ -112,7 +99,7 @@ defmodule ElixirScript.Translate.Form do ast = J.call_expression( J.member_expression( func, J.identifier("call")), - [J.identifier(:this), compile(condition, state)] + [J.identifier(:this), compile!(condition, state)] ) { ast, state } @@ -176,276 +163,30 @@ defmodule ElixirScript.Translate.Form do {ast, state} end - def compile({{:., _, [:erlang, function]}, _, [first]}, state) when function in [:+, :-] do - ast = J.unary_expression( - function, - compile(first, state), - true - ) - - {ast, state} - end - - def compile({{:., _, [:erlang, :not]}, _, [first]}, state) do - ast = J.unary_expression( - :!, - compile(first, state), - true - ) - - {ast, state} - end - - def compile({{:., _, [:erlang, :bnot]}, _, [first]}, state) do - ast = J.unary_expression( - :"~", - compile(first, state), - true - ) - - {ast, state} - end - - def compile({{:., _, [:erlang, :=]}, _, [_, _] = match}, state) do - Match.compile(match, state) - end - - def compile({{:., _, [:erlang, function]}, _, [first, second]}, state) when function in [:+, :-, :*, :/, :==, :>=] do - ast = J.binary_expression( - function, - compile(first, state), - compile(second, state) - ) - - {ast, state} - end - - def compile({{:., _, [:erlang, :"/="]}, _, [first, second]}, state) do - ast = J.binary_expression( - :!=, - compile(first, state), - compile(second, state) - ) - - {ast, state} - end - - def compile({{:., _, [:erlang, :"=<"]}, _, [first, second]}, state) do - ast = J.binary_expression( - :<=, - compile(first, state), - compile(second, state) - ) - - {ast, state} - end - - def compile({{:., _, [:erlang, :"=:="]}, _, [first, second]}, state) do - ast = J.binary_expression( - :===, - compile(first, state), - compile(second, state) - ) - - {ast, state} - end - - def compile({{:., _, [:erlang, :"=/="]}, _, [first, second]}, state) do - ast = J.binary_expression( - :!==, - compile(first, state), - compile(second, state) - ) - - {ast, state} - end - - def compile({{:., _, [:erlang, function]}, _, [first, second]}, state) when function in [:andalso, :and] do - ast = J.binary_expression( - :&&, - compile(first, state), - compile(second, state) - ) - - {ast, state} - end - - def compile({{:., _, [:erlang, function]}, _, [first, second]}, state) when function in [:orelse, :or] do - ast = J.binary_expression( - :||, - compile(first, state), - compile(second, state) - ) - - {ast, state} - end - - def compile({{:., _, [:erlang, :div]}, _, [first, second]}, state) do - ast = J.binary_expression( - :/, - compile(first, state), - compile(second, state) - ) - - {ast, state} - end - - def compile({{:., _, [:erlang, :rem]}, _, [first, second]}, state) do - ast = J.binary_expression( - :mod, - compile(first, state), - compile(second, state) - ) - - {ast, state} - end - - def compile({{:., _, [:erlang, :band]}, _, [first, second]}, state) do - ast = J.binary_expression( - :&, - compile(first, state), - compile(second, state) - ) - - {ast, state} - end - - def compile({{:., _, [:erlang, :bor]}, _, [first, second]}, state) do - ast = J.binary_expression( - :|, - compile(first, state), - compile(second, state) - ) - - {ast, state} - end - - def compile({{:., _, [:erlang, :bsl]}, _, [first, second]}, state) do - ast = J.binary_expression( - :"<<", - compile(first, state), - compile(second, state) - ) - - {ast, state} - end - - def compile({{:., _, [:erlang, :bsl]}, _, [first, second]}, state) do - ast = J.binary_expression( - :">>", - compile(first, state), - compile(second, state) - ) - - {ast, state} - end - - def compile({{:., _, [:erlang, :bxor]}, _, [first, second]}, state) do - ast = J.binary_expression( - :">>", - compile(first, state), - compile(second, state) - ) - - {ast, state} - end - - def compile({{:., _, [:erlang, :++]}, _, [_, _] = params}, state) do - ast = J.call_expression( - J.member_expression( - J.member_expression( - J.member_expression( - J.identifier("Bootstrap"), - J.identifier("Core") - ), - J.identifier(:erlang) - ), - J.identifier("list_concatenation2") - ), - Enum.map(params, &compile(&1, state)) - ) - - {ast, state} - end - - def compile({{:., _, [:erlang, :--]}, _, [_, _] = params}, state) do - ast = J.call_expression( - J.member_expression( - J.member_expression( - J.member_expression( - J.identifier("Bootstrap"), - J.identifier("Core") - ), - J.identifier(:erlang) - ), - J.identifier("list_substraction2") - ), - Enum.map(params, &compile(&1, state)) - ) - - {ast, state} - end - - def compile({{:., _, [function_name]}, _, params}, state) do - ast = J.call_expression( - compile!(function_name, state), - Enum.map(params, &compile!(&1, state)) - ) - - {ast, state} + def compile({:., _, call} = ast, state) when is_list(call) do + Remote.compile(ast, state) end + def compile({:super, context, params}, state) when is_list(params) do + {function_name, _} = Map.get(state, :function) - def compile({{:., _, [module, function]}, _, params}, state) when module in @erlang_modules do ast = J.call_expression( - J.member_expression( - J.member_expression( - J.member_expression( - J.identifier("Bootstrap"), - J.identifier("Core") - ), - J.identifier(module) - ), - ElixirScript.Translator.Identifier.make_function_name(function) - ), + ElixirScript.Translator.Identifier.make_function_name(function_name), Enum.map(params, &compile!(&1, state)) ) {ast, state} end - def compile({{:., _, [_, _]}, _, _} = ast, state) do - Call.compile(ast, state) - end - - def compile({:super, context, params}, state) do - {function_name, _} = Map.get(state, :function) - + def compile({function, _, params}, state) when is_list(params) do ast = J.call_expression( - ElixirScript.Translator.Identifier.make_function_name(function_name), + compile!(function, state), Enum.map(params, &compile!(&1, state)) ) {ast, state} end - def compile({function_name, _, params}, state) when is_list(params) do - ast = case function_name do - a when is_atom(a) -> - J.call_expression( - ElixirScript.Translator.Identifier.make_function_name(function_name), - Enum.map(params, &compile!(&1, state)) - ) - _ -> - J.call_expression( - compile!(function_name, state), - Enum.map(params, &compile!(&1, state)) - ) - end - - {ast, state} - end - def compile({var, _, _}, state) do { ElixirScript.Translator.Identifier.make_identifier(var), state } end diff --git a/lib/elixir_script/next/passes/translate/forms/call.ex b/lib/elixir_script/next/passes/translate/forms/call.ex deleted file mode 100644 index 704330bd..00000000 --- a/lib/elixir_script/next/passes/translate/forms/call.ex +++ /dev/null @@ -1,41 +0,0 @@ -defmodule ElixirScript.Translate.Forms.Call do - alias ESTree.Tools.Builder, as: J - alias ElixirScript.Translate.Form - alias ElixirScript.Translator.Identifier - - def compile({{:., _, [module, function]}, _, params}, state) do - function_name = cond do - ElixirScript.Translate.Module.is_js_module(module, state) -> - ElixirScript.Translator.Identifier.make_extern_function_name(function) - true -> - ElixirScript.Translator.Identifier.make_function_name(function) - end - - ast = J.call_expression( - J.member_expression( - process_module_name(module, state), - function_name - ), - Enum.map(params, &Form.compile!(&1, state)) - ) - - {ast, state} - end - - defp process_module_name(module, state) when is_atom(module) do - cond do - ElixirScript.Translate.Module.is_js_module(module, state) -> - members = tl(Module.split(module)) - Identifier.make_namespace_members(members) - ElixirScript.Translate.Module.is_elixir_module(module) -> - members = ["Elixir"] ++ Module.split(module) - J.identifier(Enum.join(members, "_")) - true -> - ElixirScript.Translator.Identifier.make_identifier(module) - end - end - - defp process_module_name(module, state) do - Form.compile(module, state) - end -end diff --git a/lib/elixir_script/next/passes/translate/forms/pattern.ex b/lib/elixir_script/next/passes/translate/forms/pattern.ex index 8cbab551..bb5f29ab 100644 --- a/lib/elixir_script/next/passes/translate/forms/pattern.ex +++ b/lib/elixir_script/next/passes/translate/forms/pattern.ex @@ -122,7 +122,7 @@ defmodule ElixirScript.Translate.Forms.Pattern do { props ++ [prop], params ++ param } end) - { J.object_expression(List.wrap(props)), params } + { [J.object_expression(List.wrap(props))], params } end defp process_pattern({:<<>>, _, elements}, state) do @@ -152,6 +152,10 @@ defmodule ElixirScript.Translate.Forms.Pattern do { [PM.head_tail(hd(head_patterns), hd(tail_patterns))], params } end + defp process_pattern({{:., _, [:erlang, :++]}, _, [prefix, value]}, state) do + { [PM.starts_with(prefix)], [Form.compile!(value, state)] } + end + defp process_pattern({:<>, _, [prefix, value]}, state) do { [PM.starts_with(prefix)], [Form.compile!(value, state)] } end diff --git a/lib/elixir_script/next/passes/translate/forms/remote.ex b/lib/elixir_script/next/passes/translate/forms/remote.ex new file mode 100644 index 00000000..5736e752 --- /dev/null +++ b/lib/elixir_script/next/passes/translate/forms/remote.ex @@ -0,0 +1,163 @@ +defmodule ElixirScript.Translate.Forms.Remote do + alias ESTree.Tools.Builder, as: J + alias ElixirScript.Translate.Form + alias ElixirScript.Translator.Identifier + + @erlang_modules [ + :erlang, + :maps, + :lists, + :gen, + :elixir_errors, + :supervisor, + :application, + :code, + :elixir_utils, + :file + ] + + def compile({:., _, [:erlang, :+]}, state) do + ast = erlang_compat_function("erlang", "plus") + { ast, state } + end + + def compile({:., _, [:erlang, :-]}, state) do + ast = erlang_compat_function("erlang", "minus") + { ast, state } + end + + def compile({:., _, [:erlang, :*]}, state) do + ast = erlang_compat_function("erlang", "multiply") + { ast, state } + end + + def compile({:., _, [:erlang, :/]}, state) do + ast = erlang_compat_function("erlang", "div") + { ast, state } + end + + def compile({:., _, [:erlang, :==]}, state) do + ast = erlang_compat_function("erlang", "equal") + { ast, state } + end + + def compile({:., _, [:erlang, :>]}, state) do + ast = erlang_compat_function("erlang", "greaterThan") + { ast, state } + end + + def compile({:., _, [:erlang, :>=]}, state) do + ast = erlang_compat_function("erlang", "greaterThanOrEqualTo") + { ast, state } + end + + def compile({:., _, [:erlang, :"/="]}, state) do + ast = erlang_compat_function("erlang", "doesNotEqual") + { ast, state } + end + + def compile({:., _, [:erlang, :"<"]}, state) do + ast = erlang_compat_function("erlang", "lessThan") + { ast, state } + end + + def compile({:., _, [:erlang, :"=<"]}, state) do + ast = erlang_compat_function("erlang", "lessThanOrEqualTo") + { ast, state } + end + + def compile({:., _, [:erlang, :"=:="]}, state) do + ast = erlang_compat_function("erlang", "strictlyEqual") + { ast, state } + end + + def compile({:., _, [:erlang, :"=/="]}, state) do + ast = erlang_compat_function("erlang", "doesNotStrictlyEqual") + { ast, state } + end + + def compile({:., _, [:erlang, function]}, state) when function in [:andalso, :and] do + ast = erlang_compat_function("erlang", "and") + { ast, state } + end + + def compile({:., _, [:erlang, function]}, state) when function in [:orelse, :or] do + ast = erlang_compat_function("erlang", "or") + { ast, state } + end + + def compile({:., _, [:erlang, :++]}, state) do + ast = erlang_compat_function("erlang", "list_concatenation") + { ast, state } + end + + def compile({:., _, [:erlang, :--]}, state) do + ast = erlang_compat_function("erlang", "list_substraction") + { ast, state } + end + + def compile({:., _, [module, function]}, state) when module in @erlang_modules do + ast = J.member_expression( + J.member_expression( + J.member_expression( + J.identifier("Bootstrap"), + J.identifier("Core") + ), + J.identifier(module) + ), + ElixirScript.Translator.Identifier.make_function_name(function) + ) + + { ast, state } + end + + def compile({:., _, [function_name]}, state) do + Form.compile(function_name, state) + end + + def compile({:., _, [module, function]}, state) do + function_name = cond do + ElixirScript.Translate.Module.is_js_module(module, state) -> + ElixirScript.Translator.Identifier.make_extern_function_name(function) + true -> + ElixirScript.Translator.Identifier.make_function_name(function) + end + + ast = J.member_expression( + process_module_name(module, state), + function_name + ) + + {ast, state} + end + + defp process_module_name(module, state) when is_atom(module) do + cond do + ElixirScript.Translate.Module.is_js_module(module, state) -> + members = tl(Module.split(module)) + Identifier.make_namespace_members(members) + ElixirScript.Translate.Module.is_elixir_module(module) -> + members = ["Elixir"] ++ Module.split(module) + J.identifier(Enum.join(members, "_")) + true -> + ElixirScript.Translator.Identifier.make_identifier(module) + end + end + + defp process_module_name(module, state) do + Form.compile!(module, state) + end + + defp erlang_compat_function(module, function) do + J.member_expression( + J.member_expression( + J.member_expression( + J.identifier("Bootstrap"), + J.identifier("Core") + ), + J.identifier(module) + ), + ElixirScript.Translator.Identifier.make_function_name(function) + ) + end +end \ No newline at end of file diff --git a/lib/elixir_script/translator/kernel/special_forms/identifier.ex b/lib/elixir_script/translator/kernel/special_forms/identifier.ex index 584082e6..850c6417 100644 --- a/lib/elixir_script/translator/kernel/special_forms/identifier.ex +++ b/lib/elixir_script/translator/kernel/special_forms/identifier.ex @@ -86,7 +86,7 @@ defmodule ElixirScript.Translator.Identifier do |> make_alias end - def make_function_name(name) when is_atom(name) do + def make_function_name(name) do name = filter_name(name) JS.identifier(name) end diff --git a/src/javascript/lib/core/erlang_compat/erlang.js b/src/javascript/lib/core/erlang_compat/erlang.js index 81b89a66..9847b836 100644 --- a/src/javascript/lib/core/erlang_compat/erlang.js +++ b/src/javascript/lib/core/erlang_compat/erlang.js @@ -26,8 +26,126 @@ function list_subtraction(list1, list2) { return list; } +function plus(left, right) { + if (!right) { + return +left; + } + + return left + right; +} + +function minus(left, right) { + if (!right) { + return -left; + } + + return left - right; +} + +function multiply(left, right) { + return left * right; +} + +function div(left, right) { + return left / right; +} + +function equal(left, right) { + return left == right; +} + +function doesNotEqual(left, right) { + return left != right; +} + +function greaterThan(left, right) { + return left > right; +} + +function greaterThanOrEqualTo(left, right) { + return left >= right; +} + +function lessThan(left, right) { + return left < right; +} + +function lessThanOrEqualTo(left, right) { + return left <= right; +} + +function strictlyEqual(left, right) { + return left === right; +} + +function doesNotStrictlyEqual(left, right) { + return left !== right; +} + +function and(left, right) { + return left && right; +} + +function or(left, right) { + return left || right; +} + +function not(x) { + return !x; +} + +function rem(left, right) { + return left % right; +} + +function band(left, right) { + return left & right; +} + +function bor(left, right) { + return left | right; +} + +function bnot(x) { + return ~x; +} + +function bsl(left, right) { + return left << right; +} + +function bsr(left, right) { + return left >> right; +} + +function bxor(left, right) { + return left ^ right; +} + export default { atom_to_binary, list_concatenation, list_subtraction, + plus, + minus, + multiply, + div, + equal, + greaterThan, + greaterThanOrEqualTo, + lessThan, + lessThanOrEqualTo, + doesNotEqual, + strictlyEqual, + doesNotStrictlyEqual, + and, + or, + not, + rem, + band, + bor, + bsl, + bsr, + bxor, + bnot, }; diff --git a/test/next/passes/translate/forms/remote_test.exs b/test/next/passes/translate/forms/remote_test.exs new file mode 100644 index 00000000..95f7f750 --- /dev/null +++ b/test/next/passes/translate/forms/remote_test.exs @@ -0,0 +1,14 @@ +defmodule ElixirScript.Translate.Forms.Remote.Test do + use ExUnit.Case + alias ElixirScript.Translate.Forms.Remote + alias ESTree.Tools.Builder, as: J + + test "call to variable" do + ast = {:., [line: 644], [{:fun, [line: 644], nil}]} + state = %{function: {:each, nil}, module: Enum, vars: %{:_ => 0, "entry" => 0, "enumerable" => 0, "fun" => 0}} + + {js_ast, _} = Remote.compile(ast, state) + assert js_ast == J.identifier("fun") + end + +end \ No newline at end of file From d8bd1d6bd3ae8045223f3eb64c689bcfea53c140 Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Fri, 2 Jun 2017 20:51:09 -0500 Subject: [PATCH 108/418] Fixed bugs from testing. Got app test working again --- .../next/passes/translate/clause.ex | 5 +++- .../next/passes/translate/form.ex | 27 ++++++++++++++----- .../next/passes/translate/forms/for.ex | 6 +++-- .../next/passes/translate/forms/pattern.ex | 2 +- .../next/passes/translate/forms/try.ex | 4 ++- .../next/passes/translate/function.ex | 3 ++- lib/elixir_script/passes/create_js_modules.ex | 2 +- test/app/spec/main.spec.js | 10 +------ test/support/main.ex | 8 +----- 9 files changed, 37 insertions(+), 30 deletions(-) diff --git a/lib/elixir_script/next/passes/translate/clause.ex b/lib/elixir_script/next/passes/translate/clause.ex index dca321a1..1816ab34 100644 --- a/lib/elixir_script/next/passes/translate/clause.ex +++ b/lib/elixir_script/next/passes/translate/clause.ex @@ -30,9 +30,12 @@ defmodule ElixirScript.Translate.Clause do List.flatten(list) _ -> Form.compile!(body, state) + |> List.wrap + |> List.flatten end - body = return_last_statement(body) + body = body + |> return_last_statement ast = J.call_expression( J.member_expression( diff --git a/lib/elixir_script/next/passes/translate/form.ex b/lib/elixir_script/next/passes/translate/form.ex index 55aefe78..dad4b9b4 100644 --- a/lib/elixir_script/next/passes/translate/form.ex +++ b/lib/elixir_script/next/passes/translate/form.ex @@ -1,6 +1,6 @@ defmodule ElixirScript.Translate.Form do alias ESTree.Tools.Builder, as: J - alias ElixirScript.Translate.Forms.{Bitstring, Match, Try, For, Struct, Receive, Remote} + alias ElixirScript.Translate.Forms.{Bitstring, Match, Try, For, Struct, Receive, Remote, Pattern} alias ElixirScript.Translate.Functions.{Erlang, Lists, Maps} alias ElixirScript.Translator.Identifier alias ElixirScript.Translate.Clause @@ -62,7 +62,7 @@ defmodule ElixirScript.Translate.Form do ), J.identifier("Tuple") ), - Enum.map(elements, &compile!(&1, state)) + Enum.map(elements, &compile!(&1, state)) |> List.flatten ) {ast, state} @@ -94,7 +94,7 @@ defmodule ElixirScript.Translate.Form do ElixirScript.Translate.Function.patterns_ast(), J.identifier("defmatch") ), - Enum.map(clauses, fn x -> Clause.compile(x, state) |> elem(0) end) + Enum.map(clauses, fn x -> Clause.compile(x, state) |> elem(0) end) |> List.flatten ) ast = J.call_expression( @@ -109,10 +109,13 @@ defmodule ElixirScript.Translate.Form do processed_clauses = Enum.map(clauses, fn({:->, _, [clause, clause_body]}) -> { translated_body, state } = Enum.map_reduce(List.wrap(clause_body), state, &compile(&1, &2)) - translated_body = Clause.return_last_statement(translated_body) + translated_body = translated_body + |> List.flatten + |> Clause.return_last_statement + translated_body = J.arrow_function_expression([], [], J.block_statement(translated_body)) - translated_clause = compile(hd(clause), state) + { translated_clause, _ } = compile(hd(clause), state) J.array_expression([translated_clause, translated_body]) @@ -172,7 +175,16 @@ defmodule ElixirScript.Translate.Form do ast = J.call_expression( ElixirScript.Translator.Identifier.make_function_name(function_name), - Enum.map(params, &compile!(&1, state)) + Enum.map(params, &compile!(&1, state)) |> List.flatten + ) + + {ast, state} + end + + def compile({var, _, params}, state) when is_list(params) and is_atom(var) do + ast = J.call_expression( + ElixirScript.Translator.Identifier.make_function_name(var), + Enum.map(params, &compile!(&1, state)) |> List.flatten ) {ast, state} @@ -181,13 +193,14 @@ defmodule ElixirScript.Translate.Form do def compile({function, _, params}, state) when is_list(params) do ast = J.call_expression( compile!(function, state), - Enum.map(params, &compile!(&1, state)) + Enum.map(params, &compile!(&1, state)) |> List.flatten ) {ast, state} end def compile({var, _, _}, state) do + var = Pattern.get_variable_name(to_string(var), state) { ElixirScript.Translator.Identifier.make_identifier(var), state } end diff --git a/lib/elixir_script/next/passes/translate/forms/for.ex b/lib/elixir_script/next/passes/translate/forms/for.ex index 940773da..8e67424d 100644 --- a/lib/elixir_script/next/passes/translate/forms/for.ex +++ b/lib/elixir_script/next/passes/translate/forms/for.ex @@ -65,7 +65,7 @@ defmodule ElixirScript.Translate.Forms.For do {var, collection} end) - {patterns, params, state} = Pattern.compile([{:<<>>, [], bs_parts}], module_state) + {patterns, params, module_state} = Pattern.compile([{:<<>>, [], bs_parts}], module_state) gen = JS.call_expression( JS.member_expression( @@ -126,7 +126,9 @@ defmodule ElixirScript.Translate.Forms.For do Form.compile(x, acc_state) end) - ast = Clause.return_last_statement(ast) + ast = ast + |> List.flatten + |> Clause.return_last_statement JS.arrow_function_expression( state.args, diff --git a/lib/elixir_script/next/passes/translate/forms/pattern.ex b/lib/elixir_script/next/passes/translate/forms/pattern.ex index bb5f29ab..8cccd93d 100644 --- a/lib/elixir_script/next/passes/translate/forms/pattern.ex +++ b/lib/elixir_script/next/passes/translate/forms/pattern.ex @@ -40,7 +40,7 @@ defmodule ElixirScript.Translate.Forms.Pattern do { patterns, params, state } end - defp get_variable_name(function, state) do + def get_variable_name(function, state) do number = Map.get(state.vars, function) String.to_atom("#{function}#{number}") end diff --git a/lib/elixir_script/next/passes/translate/forms/try.ex b/lib/elixir_script/next/passes/translate/forms/try.ex index 52bf3076..4488e49c 100644 --- a/lib/elixir_script/next/passes/translate/forms/try.ex +++ b/lib/elixir_script/next/passes/translate/forms/try.ex @@ -96,6 +96,8 @@ defmodule ElixirScript.Translate.Forms.Try do |> List.wrap |> Enum.map_reduce(state, &Form.compile(&1, &2)) - Clause.return_last_statement(ast) + ast + |> List.flatten + |> Clause.return_last_statement end end diff --git a/lib/elixir_script/next/passes/translate/function.ex b/lib/elixir_script/next/passes/translate/function.ex index aee6819c..9dd6726b 100644 --- a/lib/elixir_script/next/passes/translate/function.ex +++ b/lib/elixir_script/next/passes/translate/function.ex @@ -104,7 +104,8 @@ defmodule ElixirScript.Translate.Function do Form.compile!(body, state) end - body = Clause.return_last_statement(body) + body = body + |> Clause.return_last_statement declarator = J.variable_declarator( J.array_expression(params), diff --git a/lib/elixir_script/passes/create_js_modules.ex b/lib/elixir_script/passes/create_js_modules.ex index 2ba89848..a0cff524 100644 --- a/lib/elixir_script/passes/create_js_modules.ex +++ b/lib/elixir_script/passes/create_js_modules.ex @@ -100,7 +100,7 @@ defmodule ElixirScript.Passes.CreateJSModules do ), [JS.identifier("Elixir")] ), - JS.identifier("start2") + JS.identifier("start") ), [ElixirScript.Translator.Primitive.make_atom(:normal), JS.identifier(:args)] ) diff --git a/test/app/spec/main.spec.js b/test/app/spec/main.spec.js index 9d5ceac0..eb44ba0e 100644 --- a/test/app/spec/main.spec.js +++ b/test/app/spec/main.spec.js @@ -6,15 +6,7 @@ const Elixir = require('../build/Elixir.App'); test('Elixir.start:calls the modules start function', t => { const callback = sinon.spy(); - Elixir.start(Elixir.Main, callback); + Elixir.start(Elixir.Main, [callback]); t.true(callback.called); }); - -test('Elixir.load:loads the modules exports', t => { - const main = Elixir.load(Elixir.Main); - - t.truthy(main.start); - t.truthy(main.hello); - t.is(main.hello(), 'Hello!'); -}); diff --git a/test/support/main.ex b/test/support/main.ex index 61d6451b..a18d3d90 100644 --- a/test/support/main.ex +++ b/test/support/main.ex @@ -1,11 +1,5 @@ defmodule Main do - def start(:normal, callback) do - elem({1, 2}, 0) - Enum.map([], fn(x) -> x end) + def start(:normal, [callback]) do callback.("started") end - - def hello do - "Hello!" - end end From 9375656db8e06e6d994e6c09549560af75d779a5 Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Sat, 3 Jun 2017 03:57:58 -0500 Subject: [PATCH 109/418] Correct ++ pattern matching implementation. Temp fix for travis CI build --- .travis.yml | 13 +++++++++---- .../next/passes/translate/forms/pattern.ex | 16 ++++------------ lib/elixir_script/translator/state.ex | 2 ++ test/cli_test.exs | 6 +++--- test/next/passes/translate/forms/remote_test.exs | 2 +- 5 files changed, 19 insertions(+), 20 deletions(-) diff --git a/.travis.yml b/.travis.yml index a1fb4260..3b000081 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,15 +1,20 @@ sudo: false -language: elixir -elixir: - - 1.4.2 +language: erlang +#language: elixir +#elixir: +# - 1.5.0 otp_release: - - 19.0 + - 20.0-rc1 env: - TRAVIS_NODE_VERSION="7" install: - rm -rf ~/.nvm && git clone https://github.com/creationix/nvm.git ~/.nvm && (cd ~/.nvm && git checkout `git describe --abbrev=0 --tags`) && source ~/.nvm/nvm.sh && nvm install $TRAVIS_NODE_VERSION - npm install -g yarn - yarn +before_script: + - wget http://s3.hex.pm/builds/elixir/master.zip + - unzip -d elixir master.zip + - export PATH=$(pwd)/elixir/bin:${PATH} script: - mix local.hex --force - mix local.rebar --force diff --git a/lib/elixir_script/next/passes/translate/forms/pattern.ex b/lib/elixir_script/next/passes/translate/forms/pattern.ex index 8cccd93d..6b120564 100644 --- a/lib/elixir_script/next/passes/translate/forms/pattern.ex +++ b/lib/elixir_script/next/passes/translate/forms/pattern.ex @@ -105,6 +105,10 @@ defmodule ElixirScript.Translate.Forms.Pattern do { [PM.head_tail(hd(head_patterns), hd(tail_patterns))], params } end + defp process_pattern({{:., _, [:erlang, :++]}, context, [head, tail]}, state) do + process_pattern({:|, context, [head, tail]}, state) + end + defp process_pattern({:%{}, _, props}, state) do properties = Enum.map(props, fn({key, value}) -> {pattern, params} = process_pattern(value, state) @@ -144,18 +148,6 @@ defmodule ElixirScript.Translate.Forms.Pattern do { [PM.bitstring_match(elements)], params } end - defp process_pattern([{:|, _, [head, tail]}], state) do - { head_patterns, head_params } = process_pattern(head, state) - { tail_patterns, tail_params } = process_pattern(tail, state) - params = head_params ++ tail_params - - { [PM.head_tail(hd(head_patterns), hd(tail_patterns))], params } - end - - defp process_pattern({{:., _, [:erlang, :++]}, _, [prefix, value]}, state) do - { [PM.starts_with(prefix)], [Form.compile!(value, state)] } - end - defp process_pattern({:<>, _, [prefix, value]}, state) do { [PM.starts_with(prefix)], [Form.compile!(value, state)] } end diff --git a/lib/elixir_script/translator/state.ex b/lib/elixir_script/translator/state.ex index b5fff798..a7f27da3 100644 --- a/lib/elixir_script/translator/state.ex +++ b/lib/elixir_script/translator/state.ex @@ -30,6 +30,8 @@ defmodule ElixirScript.Translator.State do rescue FunctionClauseError -> acc + ArgumentError -> + acc end end) end diff --git a/test/cli_test.exs b/test/cli_test.exs index 6fab0232..05244867 100644 --- a/test/cli_test.exs +++ b/test/cli_test.exs @@ -1,8 +1,8 @@ defmodule ElixirScript.CLI.Test do use ExUnit.Case - test "parse_args -e expands to elixir" do - {_, args} = ElixirScript.CLI.parse_args(["1 + 1", "-e"]) - assert args == [elixir: true] + test "parse_args -js-module includes js module" do + {_, args} = ElixirScript.CLI.parse_args(["Example", "--js-module", "React:react"]) + assert args == [js_module: "React:react"] end end diff --git a/test/next/passes/translate/forms/remote_test.exs b/test/next/passes/translate/forms/remote_test.exs index 95f7f750..c4de0df5 100644 --- a/test/next/passes/translate/forms/remote_test.exs +++ b/test/next/passes/translate/forms/remote_test.exs @@ -8,7 +8,7 @@ defmodule ElixirScript.Translate.Forms.Remote.Test do state = %{function: {:each, nil}, module: Enum, vars: %{:_ => 0, "entry" => 0, "enumerable" => 0, "fun" => 0}} {js_ast, _} = Remote.compile(ast, state) - assert js_ast == J.identifier("fun") + assert js_ast == J.identifier("fun0") end end \ No newline at end of file From 495d023473a675e3f3a0b366a1c07e3d0a4543a0 Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Sat, 3 Jun 2017 04:05:32 -0500 Subject: [PATCH 110/418] Trying elixir master in travis config --- .travis.yml | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/.travis.yml b/.travis.yml index 3b000081..147b09f6 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,8 +1,7 @@ sudo: false -language: erlang -#language: elixir -#elixir: -# - 1.5.0 +language: elixir +elixir: + - master otp_release: - 20.0-rc1 env: @@ -11,10 +10,6 @@ install: - rm -rf ~/.nvm && git clone https://github.com/creationix/nvm.git ~/.nvm && (cd ~/.nvm && git checkout `git describe --abbrev=0 --tags`) && source ~/.nvm/nvm.sh && nvm install $TRAVIS_NODE_VERSION - npm install -g yarn - yarn -before_script: - - wget http://s3.hex.pm/builds/elixir/master.zip - - unzip -d elixir master.zip - - export PATH=$(pwd)/elixir/bin:${PATH} script: - mix local.hex --force - mix local.rebar --force From 672cc5c28a40476095c42ed6faa0fe9f1e73101a Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Sat, 3 Jun 2017 04:11:57 -0500 Subject: [PATCH 111/418] Updating travis config again --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 147b09f6..c24a0e1a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,7 +1,7 @@ sudo: false language: elixir elixir: - - master + - 1.5.0-dev otp_release: - 20.0-rc1 env: @@ -11,8 +11,8 @@ install: - npm install -g yarn - yarn script: - - mix local.hex --force - mix local.rebar --force + - mix local.hex --force - mix deps.get - mix compile - yarn build From eb20acfe3f403b10f8eea2dcb84d56c9a8756521 Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Sun, 4 Jun 2017 19:29:41 -0500 Subject: [PATCH 112/418] Add some tests for the Form module --- .../next/passes/translate/examples/example.ex | 9 +- .../next/passes/translate/form.ex | 17 ++- .../next/passes/translate/forms/remote.ex | 21 ++- .../next/passes/translate/forms/struct.ex | 22 ---- .../next/passes/translate/module.ex | 13 ++ test/next/passes/translate/form_test.exs | 121 ++++++++++++++++++ 6 files changed, 165 insertions(+), 38 deletions(-) delete mode 100644 lib/elixir_script/next/passes/translate/forms/struct.ex create mode 100644 test/next/passes/translate/form_test.exs diff --git a/lib/elixir_script/next/passes/translate/examples/example.ex b/lib/elixir_script/next/passes/translate/examples/example.ex index 49367a3d..dd298938 100644 --- a/lib/elixir_script/next/passes/translate/examples/example.ex +++ b/lib/elixir_script/next/passes/translate/examples/example.ex @@ -1,10 +1,5 @@ defmodule Example do - def start(v, _) do - case v do - :normal -> - "yolo" - _ -> - "yolo too" - end + def start(_, _) do + -1 end end diff --git a/lib/elixir_script/next/passes/translate/form.ex b/lib/elixir_script/next/passes/translate/form.ex index dad4b9b4..917663be 100644 --- a/lib/elixir_script/next/passes/translate/form.ex +++ b/lib/elixir_script/next/passes/translate/form.ex @@ -1,6 +1,6 @@ defmodule ElixirScript.Translate.Form do alias ESTree.Tools.Builder, as: J - alias ElixirScript.Translate.Forms.{Bitstring, Match, Try, For, Struct, Receive, Remote, Pattern} + alias ElixirScript.Translate.Forms.{Bitstring, Match, Try, For, Receive, Remote, Pattern} alias ElixirScript.Translate.Functions.{Erlang, Lists, Maps} alias ElixirScript.Translator.Identifier alias ElixirScript.Translate.Clause @@ -34,8 +34,7 @@ defmodule ElixirScript.Translate.Form do def compile(form, state) when is_atom(form) do ast = if ElixirScript.Translate.Module.is_elixir_module(form) do - members = if form == Elixir, do: ["Elixir"], else: ["Elixir"] ++ Module.split(form) - J.identifier(Enum.join(members, "_")) + Remote.process_module_name(form, state) else J.call_expression( J.member_expression( @@ -80,8 +79,16 @@ defmodule ElixirScript.Translate.Form do Match.compile(match, state) end - def compile({:%, _, [_, _]} = ast, state) do - Struct.compile(ast, state) + def compile({:%, _, [module, params]}, state) do + ast = J.call_expression( + J.member_expression( + Remote.process_module_name(module), + J.identifier("__struct__") + ), + [Form.compile!(params, state)] + ) + + { ast, state } end def compile({:for, _, _} = ast, state) do diff --git a/lib/elixir_script/next/passes/translate/forms/remote.ex b/lib/elixir_script/next/passes/translate/forms/remote.ex index 5736e752..6b7d0df6 100644 --- a/lib/elixir_script/next/passes/translate/forms/remote.ex +++ b/lib/elixir_script/next/passes/translate/forms/remote.ex @@ -1,4 +1,6 @@ defmodule ElixirScript.Translate.Forms.Remote do + @moduledoc false + alias ESTree.Tools.Builder, as: J alias ElixirScript.Translate.Form alias ElixirScript.Translator.Identifier @@ -16,6 +18,13 @@ defmodule ElixirScript.Translate.Forms.Remote do :file ] + @doc """ + Compiles functions into JavaScript AST. + These are not actual function calls, but + the function identifiers themselves. Also + includes function heads for converting some + erlang functions into JavaScript functions. + """ def compile({:., _, [:erlang, :+]}, state) do ast = erlang_compat_function("erlang", "plus") { ast, state } @@ -131,20 +140,24 @@ defmodule ElixirScript.Translate.Forms.Remote do {ast, state} end - defp process_module_name(module, state) when is_atom(module) do + def process_module_name(module, state) when is_atom(module) do cond do ElixirScript.Translate.Module.is_js_module(module, state) -> members = tl(Module.split(module)) Identifier.make_namespace_members(members) ElixirScript.Translate.Module.is_elixir_module(module) -> - members = ["Elixir"] ++ Module.split(module) - J.identifier(Enum.join(members, "_")) + members = ["Elixir"] ++ Module.split(module) ++ ["__load"] + + J.call_expression( + Identifier.make_namespace_members(members), + [J.identifier("Elixir")] + ) true -> ElixirScript.Translator.Identifier.make_identifier(module) end end - defp process_module_name(module, state) do + def process_module_name(module, state) do Form.compile!(module, state) end diff --git a/lib/elixir_script/next/passes/translate/forms/struct.ex b/lib/elixir_script/next/passes/translate/forms/struct.ex deleted file mode 100644 index e88bc492..00000000 --- a/lib/elixir_script/next/passes/translate/forms/struct.ex +++ /dev/null @@ -1,22 +0,0 @@ -defmodule ElixirScript.Translate.Forms.Struct do - alias ESTree.Tools.Builder, as: J - alias ElixirScript.Translate.Form - alias ElixirScript.Translator.Identifier - - def compile({:%, _, [module, params]}, state) do - ast = J.call_expression( - J.member_expression( - process_module_name(module), - J.identifier("__struct__1") - ), - [Form.compile!(params, state)] - ) - - { ast, state } - end - - defp process_module_name(module) do - members = ["Elixir"] ++ Module.split(module) - Identifier.make_namespace_members(members) - end -end diff --git a/lib/elixir_script/next/passes/translate/module.ex b/lib/elixir_script/next/passes/translate/module.ex index e447f9b2..89b8388e 100644 --- a/lib/elixir_script/next/passes/translate/module.ex +++ b/lib/elixir_script/next/passes/translate/module.ex @@ -14,6 +14,9 @@ defmodule ElixirScript.Translate.Module do end def compile(module, info, pid) do + if Atom.to_string(module) == "Elixir.Example" do + IO.inspect info + end %{ attributes: attrs, compile_opts: _compile_opts, @@ -86,6 +89,10 @@ defmodule ElixirScript.Translate.Module do J.object_expression(exports) end + @doc """ + Determins if the given atom + is an Elixir function + """ def is_elixir_module(Elixir) do true end @@ -105,6 +112,12 @@ defmodule ElixirScript.Translate.Module do false end + @doc """ + Determines is given function is a JS module. + A JS module is either one that begins with "JS" + or is a module defined from the js_modules compiler + opt + """ def is_js_module(module, state) do cond do module in ModuleState.get_javascript_modules(state.pid) -> diff --git a/test/next/passes/translate/form_test.exs b/test/next/passes/translate/form_test.exs new file mode 100644 index 00000000..e93dab3b --- /dev/null +++ b/test/next/passes/translate/form_test.exs @@ -0,0 +1,121 @@ +defmodule ElixirScript.Translate.Forms.Test do + use ExUnit.Case + alias ElixirScript.Translate.Form + alias ElixirScript.Translator.Identifier + alias ESTree.Tools.Builder, as: J + + + setup_all do + {:ok, pid} = ElixirScript.State.start_link(%{}) + + state = %{ + pid: pid + } + + [state: state] + end + + test "integer" do + ast = 1 + state = %{} + + {js_ast, _} = Form.compile(ast, state) + assert js_ast == J.literal(1) + end + + test "boolean" do + ast = true + state = %{} + + {js_ast, _} = Form.compile(ast, state) + assert js_ast == J.literal(true) + end + + test "float" do + ast = 1.0 + state = %{} + + {js_ast, _} = Form.compile(ast, state) + assert js_ast == J.literal(1.0) + end + + test "binary" do + ast = "hello" + state = %{} + + {js_ast, _} = Form.compile(ast, state) + assert js_ast == J.literal("hello") + end + + test "atom" do + ast = :tiger + state = %{} + + {js_ast, _} = Form.compile(ast, state) + assert js_ast == J.call_expression( + J.member_expression( + J.identifier("Symbol"), + J.identifier("for") + ), + [J.literal(:tiger)] + ) + end + + test "module", %{state: state} do + ast = IO + + {js_ast, _} = Form.compile(ast, state) + assert js_ast == J.call_expression( + Identifier.make_namespace_members(["Elixir", "IO", "__load"]), + [J.identifier("Elixir")] + ) + end + + test "tuple" do + ast = {1, 2} + state = %{} + + {js_ast, _} = Form.compile(ast, state) + assert js_ast == J.call_expression( + J.member_expression( + J.member_expression( + J.identifier("Bootstrap"), + J.identifier("Core") + ), + J.identifier("Tuple") + ), + [J.literal(1), J.literal(2)] + ) + end + + test "list" do + ast = [1, 2] + state = %{} + + {js_ast, _} = Form.compile(ast, state) + assert js_ast == J.array_expression([J.literal(1), J.literal(2)]) + end + + test "super" do + ast = {:super, [], [1]} + state = %{function: {:my_function, nil}} + + {js_ast, _} = Form.compile(ast, state) + assert js_ast == J.call_expression( + J.identifier("my_function"), + [J.literal(1)] + ) + end + + test "local function" do + ast = {:my_function, [], [1]} + state = %{} + + {js_ast, _} = Form.compile(ast, state) + assert js_ast == J.call_expression( + J.identifier("my_function"), + [J.literal(1)] + ) + end + +end \ No newline at end of file From da96e97034504d768a096ed04cd5fbbe197803ac Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Fri, 9 Jun 2017 17:55:22 -0500 Subject: [PATCH 113/418] More updates from testing --- .../next/passes/translate/form.ex | 4 +- .../next/passes/translate/forms/map.ex | 16 ++-- .../next/passes/translate/forms/receive.ex | 8 +- .../next/passes/translate/module.ex | 8 ++ test/next/passes/translate/forms/map_test.exs | 74 +++++++++++++++++++ .../passes/translate/forms/receive_test.exs | 26 +++++++ .../passes/translate/forms/remote_test.exs | 4 +- 7 files changed, 125 insertions(+), 15 deletions(-) create mode 100644 test/next/passes/translate/forms/map_test.exs create mode 100644 test/next/passes/translate/forms/receive_test.exs diff --git a/lib/elixir_script/next/passes/translate/form.ex b/lib/elixir_script/next/passes/translate/form.ex index 917663be..58b95de0 100644 --- a/lib/elixir_script/next/passes/translate/form.ex +++ b/lib/elixir_script/next/passes/translate/form.ex @@ -82,10 +82,10 @@ defmodule ElixirScript.Translate.Form do def compile({:%, _, [module, params]}, state) do ast = J.call_expression( J.member_expression( - Remote.process_module_name(module), + Remote.process_module_name(module, state), J.identifier("__struct__") ), - [Form.compile!(params, state)] + [compile!(params, state)] ) { ast, state } diff --git a/lib/elixir_script/next/passes/translate/forms/map.ex b/lib/elixir_script/next/passes/translate/forms/map.ex index 54aa74de..ce1ee7f5 100644 --- a/lib/elixir_script/next/passes/translate/forms/map.ex +++ b/lib/elixir_script/next/passes/translate/forms/map.ex @@ -8,16 +8,14 @@ defmodule ElixirScript.Translate.Forms.Map do ast = J.call_expression( J.member_expression( - J.member_expression( - J.identifier("Bootstrap"), - J.member_expression( - J.identifier("Core"), - J.identifier("SpecialForms") - ) - ), - J.identifier("map_update") + J.identifier("Object"), + J.identifier("assign") ), - [map, data] + [ + J.object_expression([]), + map, + data + ] ) { ast, state } diff --git a/lib/elixir_script/next/passes/translate/forms/receive.ex b/lib/elixir_script/next/passes/translate/forms/receive.ex index 8d021a7e..6a51bf24 100644 --- a/lib/elixir_script/next/passes/translate/forms/receive.ex +++ b/lib/elixir_script/next/passes/translate/forms/receive.ex @@ -2,9 +2,13 @@ defmodule ElixirScript.Translate.Forms.Receive do @moduledoc false alias ESTree.Tools.Builder, as: J + @doc """ + receive is not supported just yet, but we compile it + to a stub function for now + """ def compile(blocks, state) do - receive_block = Keyword.get(blocks, :do) - after_block = Keyword.get(blocks, :after, nil) + _receive_block = Keyword.get(blocks, :do) + _after_block = Keyword.get(blocks, :after, nil) receive_function = J.member_expression( J.member_expression( diff --git a/lib/elixir_script/next/passes/translate/module.ex b/lib/elixir_script/next/passes/translate/module.ex index 89b8388e..7ea9752e 100644 --- a/lib/elixir_script/next/passes/translate/module.ex +++ b/lib/elixir_script/next/passes/translate/module.ex @@ -2,6 +2,7 @@ defmodule ElixirScript.Translate.Module do @moduledoc false alias ESTree.Tools.Builder, as: J alias ElixirScript.Translate.Function + alias ElixirScript.Translate.Form alias ElixirScript.Translator.Identifier alias ElixirScript.State, as: ModuleState @@ -86,6 +87,13 @@ defmodule ElixirScript.Translate.Module do list end) + # Add an attribute to use to determine if this is a module + # Will be used by the is_atom implementation + exports ++ [ElixirScript.Translate.Forms.Map.make_property( + Form.compile!("__MODULE__", %{}), + Form.compile!(true, %{}) + )] + J.object_expression(exports) end diff --git a/test/next/passes/translate/forms/map_test.exs b/test/next/passes/translate/forms/map_test.exs new file mode 100644 index 00000000..ad826766 --- /dev/null +++ b/test/next/passes/translate/forms/map_test.exs @@ -0,0 +1,74 @@ +defmodule ElixirScript.Translate.Forms.Map.Test do + use ExUnit.Case + alias ElixirScript.Translate.Form + alias ESTree.Tools.Builder, as: J + + test "map with atom key" do + properties = [a: 1] + ast = {:%{}, [], properties} + state = %{} + + {js_ast, _} = Form.compile(ast, state) + assert js_ast == J.object_expression([ + J.property( + J.call_expression( + J.member_expression( + J.identifier("Symbol"), + J.identifier("for") + ), + [J.literal(:a)] + ), + J.literal(1), + :init, false, false, true + ) + ]) + end + + test "map with string key" do + properties = [{"a", 1}] + ast = {:%{}, [], properties} + state = %{} + + {js_ast, _} = Form.compile(ast, state) + assert js_ast == J.object_expression([ + J.property( + J.identifier("a"), + J.literal(1) + ) + ]) + end + + + test "map update" do + properties = [{"a", 1}] + map_ast = {:%{}, [], properties} + new_values = [{"a", 2}] + state = %{} + + ast = {:%{}, [], [{:|, [], [map_ast, new_values]}]} + + {js_ast, _} = Form.compile(ast, state) + assert js_ast == J.call_expression( + J.member_expression( + J.identifier("Object"), + J.identifier("assign") + ), + [ + J.object_expression([]), + J.object_expression([ + J.property( + J.identifier("a"), + J.literal(1) + ) + ]), + J.object_expression([ + J.property( + J.identifier("a"), + J.literal(2) + ) + ]) + ] + ) + end + +end \ No newline at end of file diff --git a/test/next/passes/translate/forms/receive_test.exs b/test/next/passes/translate/forms/receive_test.exs new file mode 100644 index 00000000..32d55f67 --- /dev/null +++ b/test/next/passes/translate/forms/receive_test.exs @@ -0,0 +1,26 @@ +defmodule ElixirScript.Translate.Forms.Receive.Test do + use ExUnit.Case + alias ElixirScript.Translate.Form + alias ESTree.Tools.Builder, as: J + + test "call to variable" do + ast = {:receive, [line: 644], [[do: 1, after: 2]]} + state = %{function: {:each, nil}, module: __MODULE__} + + {js_ast, _} = Form.compile(ast, state) + assert js_ast == J.call_expression( + J.member_expression( + J.member_expression( + J.identifier("Bootstrap"), + J.member_expression( + J.identifier("Core"), + J.identifier("SpecialForms") + ) + ), + J.identifier("receive") + ), + [] + ) + end + +end \ No newline at end of file diff --git a/test/next/passes/translate/forms/remote_test.exs b/test/next/passes/translate/forms/remote_test.exs index c4de0df5..993108d9 100644 --- a/test/next/passes/translate/forms/remote_test.exs +++ b/test/next/passes/translate/forms/remote_test.exs @@ -1,13 +1,13 @@ defmodule ElixirScript.Translate.Forms.Remote.Test do use ExUnit.Case - alias ElixirScript.Translate.Forms.Remote + alias ElixirScript.Translate.Form alias ESTree.Tools.Builder, as: J test "call to variable" do ast = {:., [line: 644], [{:fun, [line: 644], nil}]} state = %{function: {:each, nil}, module: Enum, vars: %{:_ => 0, "entry" => 0, "enumerable" => 0, "fun" => 0}} - {js_ast, _} = Remote.compile(ast, state) + {js_ast, _} = Form.compile(ast, state) assert js_ast == J.identifier("fun0") end From 626602f014c367d942449cafb639f47e7ad8872e Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Fri, 9 Jun 2017 18:01:27 -0500 Subject: [PATCH 114/418] Update travis.yml --- .travis.yml | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/.travis.yml b/.travis.yml index c24a0e1a..91f6a3b3 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,7 +1,5 @@ sudo: false -language: elixir -elixir: - - 1.5.0-dev +language: erlang otp_release: - 20.0-rc1 env: @@ -10,11 +8,14 @@ install: - rm -rf ~/.nvm && git clone https://github.com/creationix/nvm.git ~/.nvm && (cd ~/.nvm && git checkout `git describe --abbrev=0 --tags`) && source ~/.nvm/nvm.sh && nvm install $TRAVIS_NODE_VERSION - npm install -g yarn - yarn -script: +before_script: + - wget http://s3.hex.pm/builds/elixir/master.zip + - unzip -d elixir master.zip + - export PATH=$(pwd)/elixir/bin:${PATH} - mix local.rebar --force - mix local.hex --force - mix deps.get - - mix compile +script: - yarn build - mix test - yarn test From 2d98dd641452337085e43e3c0bac9ab7c1dcbf14 Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Fri, 9 Jun 2017 18:30:53 -0500 Subject: [PATCH 115/418] Add is_* functions --- .../lib/core/erlang_compat/erlang.js | 71 +++++++++++++++++++ 1 file changed, 71 insertions(+) diff --git a/src/javascript/lib/core/erlang_compat/erlang.js b/src/javascript/lib/core/erlang_compat/erlang.js index 9847b836..eb3f78c6 100644 --- a/src/javascript/lib/core/erlang_compat/erlang.js +++ b/src/javascript/lib/core/erlang_compat/erlang.js @@ -1,4 +1,5 @@ // http://erlang.org/doc/man/erlang.html +import ErlangTypes from 'erlang-types'; function atom_to_binary(atom, encoding = Symbol.for('utf8')) { if (encoding !== Symbol.for('utf8')) { @@ -122,6 +123,62 @@ function bxor(left, right) { return left ^ right; } +function is_atom(value) { + return value instanceof Symbol || value.__MODULE__ === true; +} + +function is_bitstring(value) { + return value instanceof ErlangTypes.BitString; +} + +function is_boolean(value) { + return value instanceof Boolean; +} + +function is_float(value) { + return value instanceof Number && !Number.isInteger(value); +} + +function is_function(value) { + return value instanceof Function; +} + +function is_integer(value) { + return Number.isInteger(value); +} + +function is_list(value) { + return Array.isArray(value); +} + +function is_map(value) { + return value instanceof Object; +} + +function is_number(value) { + return value instanceof Number; +} + +function is_pid(value) { + return value instanceof ErlangTypes.PID; +} + +function is_port() { + return false; +} + +function is_reference(value) { + return value instanceof ErlangTypes.Reference; +} + +function is_tuple(value) { + return value instanceof ErlangTypes.Tuple; +} + +function is_binary(value) { + return value instanceof String; +} + export default { atom_to_binary, list_concatenation, @@ -148,4 +205,18 @@ export default { bsr, bxor, bnot, + is_bitstring, + is_boolean, + is_float, + is_function, + is_integer, + is_list, + is_map, + is_number, + is_pid, + is_port, + is_reference, + is_tuple, + is_atom, + is_binary, }; From 0d62e2dabe4886d502cc53c671d5e694b8ed5fbe Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Fri, 9 Jun 2017 20:59:00 -0500 Subject: [PATCH 116/418] Fix issue where Elixir module was crashing module name processing --- lib/elixir_script/next/passes/output.ex | 12 +++++++++--- .../next/passes/translate/forms/remote.ex | 9 ++++++++- lib/elixir_script/next/passes/translate/module.ex | 8 +++----- 3 files changed, 20 insertions(+), 9 deletions(-) diff --git a/lib/elixir_script/next/passes/output.ex b/lib/elixir_script/next/passes/output.ex index f2cdd164..925897ab 100644 --- a/lib/elixir_script/next/passes/output.ex +++ b/lib/elixir_script/next/passes/output.ex @@ -36,7 +36,8 @@ defmodule ElixirScript.Output do end defp concat(code) do - "'use strict';\n" <> ElixirScript.get_bootstrap_js("iife") <> "\n" <> code + bootstrap_code = ElixirScript.get_bootstrap_js("iife") + "'use strict';\n#{bootstrap_code}\n#{code}" end defp prepare_js_ast(js_ast) do @@ -54,8 +55,13 @@ defmodule ElixirScript.Output do end end - defp output(code, nil), do: code - defp output(code, :stdout), do: IO.puts(code) + defp output(code, nil) do + code + end + + defp output(code, :stdout) do + IO.puts(code) + end defp output(code, path) do file_name = case Path.extname(path) do diff --git a/lib/elixir_script/next/passes/translate/forms/remote.ex b/lib/elixir_script/next/passes/translate/forms/remote.ex index 6b7d0df6..bb881afe 100644 --- a/lib/elixir_script/next/passes/translate/forms/remote.ex +++ b/lib/elixir_script/next/passes/translate/forms/remote.ex @@ -144,7 +144,14 @@ defmodule ElixirScript.Translate.Forms.Remote do cond do ElixirScript.Translate.Module.is_js_module(module, state) -> members = tl(Module.split(module)) - Identifier.make_namespace_members(members) + Identifier.make_namespace_members(members) + module === Elixir -> + members = ["Elixir", "__load"] + + J.call_expression( + Identifier.make_namespace_members(members), + [J.identifier("Elixir")] + ) ElixirScript.Translate.Module.is_elixir_module(module) -> members = ["Elixir"] ++ Module.split(module) ++ ["__load"] diff --git a/lib/elixir_script/next/passes/translate/module.ex b/lib/elixir_script/next/passes/translate/module.ex index 7ea9752e..e16fbe8d 100644 --- a/lib/elixir_script/next/passes/translate/module.ex +++ b/lib/elixir_script/next/passes/translate/module.ex @@ -101,15 +101,11 @@ defmodule ElixirScript.Translate.Module do Determins if the given atom is an Elixir function """ - def is_elixir_module(Elixir) do - true - end - def is_elixir_module(module) when is_atom(module) do str_module = Atom.to_string(module) case str_module do - "Elixir." <> _ -> + "Elixir" <> _ -> true _ -> false @@ -130,6 +126,8 @@ defmodule ElixirScript.Translate.Module do cond do module in ModuleState.get_javascript_modules(state.pid) -> true + module === Elixir -> + false is_elixir_module(module) and hd(Module.split(module)) == "JS" -> true true -> From e95aa8ba89705caa282022421e3a840eff2519c5 Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Sun, 11 Jun 2017 10:33:05 -0500 Subject: [PATCH 117/418] Optimizations to not compile or output modules with no public functions --- lib/elixir_script/next/compiler.ex | 17 +- .../next/passes/find_used_functions.ex | 254 ++++++++++++++++++ .../{find_used.ex => find_used_modules.ex} | 25 +- .../next/passes/translate/module.ex | 42 +-- lib/elixir_script/next/state.ex | 7 + 5 files changed, 301 insertions(+), 44 deletions(-) create mode 100644 lib/elixir_script/next/passes/find_used_functions.ex rename lib/elixir_script/next/passes/{find_used.ex => find_used_modules.ex} (92%) diff --git a/lib/elixir_script/next/compiler.ex b/lib/elixir_script/next/compiler.ex index e93317d6..faf38459 100644 --- a/lib/elixir_script/next/compiler.ex +++ b/lib/elixir_script/next/compiler.ex @@ -3,15 +3,24 @@ defmodule ElixirScript.Compiler do Compiles the given modules to JavaScript. """ + @doc """ + Takes either a module name or a list of module names as + the entry point(s) of an application/library. From there + it will determine which modules and functions are needed + to be compiled. + """ @spec compile([atom], []) :: nil def compile(entry_modules, opts \\ []) do opts = build_compiler_options(opts, entry_modules) {:ok, pid} = ElixirScript.State.start_link(opts) - IO.puts "Finding used modules and functions" - entry_modules - |> List.wrap - |> ElixirScript.FindUsed.execute(pid) + entry_modules = List.wrap(entry_modules) + + IO.puts "Finding used modules" + ElixirScript.FindUsedModules.execute(entry_modules, pid) + + IO.puts "Finding used functions" + ElixirScript.FindUsedFunctions.execute(entry_modules, pid) IO.puts "Compiling" modules = ElixirScript.State.list_modules(pid) diff --git a/lib/elixir_script/next/passes/find_used_functions.ex b/lib/elixir_script/next/passes/find_used_functions.ex new file mode 100644 index 00000000..30af88af --- /dev/null +++ b/lib/elixir_script/next/passes/find_used_functions.ex @@ -0,0 +1,254 @@ +defmodule ElixirScript.FindUsedFunctions do + @moduledoc false + alias ElixirScript.State, as: ModuleState + + @doc """ + Takes a list of entry modules and finds modules they use along with + documenting the functions used. The data collected about used functions + is used to filter only the used functions for compilation + """ + @spec execute([atom], pid) :: nil + def execute(entry_modules, pid) do + Enum.each(entry_modules, fn + module -> + walk_module(module, pid) + end) + end + + defp walk_module(module, pid) do + %{ + attributes: _attrs, + compile_opts: _compile_opts, + definitions: defs, + file: _file, + line: _line, + module: ^module, + unreachable: unreachable + } = ModuleState.get_module(pid, module) + + reachable_defs = Enum.filter(defs, fn + { _, type, _, _} when type in [:defmacro, :defmacrop] -> false + { name, _, _, _} -> not(name in unreachable) + _ -> true + end) + + state = %{ + pid: pid, + module: module + } + + Enum.each(reachable_defs, fn({name, _type, _, _clauses}) -> + ModuleState.add_used(state.pid, module, name) + end) + + Enum.each(reachable_defs, &walk(&1, state)) + end + + defp walk_module(module, function, arity, pid) do + function = {function, arity} + + unless ModuleState.has_used?(pid, module, function) do + %{ + attributes: _attrs, + compile_opts: _compile_opts, + definitions: defs, + file: _file, + line: _line, + module: ^module, + unreachable: unreachable + } = ModuleState.get_module(pid, module) + + state = %{ + pid: pid, + module: module + } + + reachable_defs = Enum.filter(defs, fn + { _, type, _, _} when type in [:defmacro, :defmacrop] -> false + { name, _, _, _} -> not(name in [function]) + _ -> true + end) + + Enum.each(reachable_defs, fn({name, _type, _, _clauses}) -> + ModuleState.add_used(state.pid, module, name) + end) + + Enum.each(reachable_defs, &walk(&1, state)) + end + end + + defp walk({{_name, _arity}, _type, _, clauses}, state) do + Enum.each(clauses, &walk(&1, state)) + end + + defp walk({ _, _args, _guards, body}, state) do + case body do + nil -> + nil + {:__block__, _, block_body} -> + Enum.map(block_body, &walk(&1, state)) + b when is_list(b) -> + Enum.map(b, &walk(&1, state)) + _ -> + walk(body, state) + end + end + + defp walk({:->, _, [[{:when, _, params}], body ]}, state) do + guards = List.last(params) + params = params |> Enum.reverse |> tl |> Enum.reverse + + walk({[], params, guards, body}, state) + end + + defp walk({:->, _, [params, body]}, state) do + walk({[], params, [], body}, state) + end + + defp walk(form, state) when is_list(form) do + Enum.each(form, &walk(&1, state)) + end + + defp walk({a, b}, state) do + walk({:{}, [], [a, b]}, state) + end + + defp walk({:{}, _, elements}, state) do + Enum.each(elements, &walk(&1, state)) + end + + defp walk({:%{}, _, properties}, state) do + Enum.each(properties, fn (val) -> walk(val, state) end) + end + + defp walk({:<<>>, _, elements}, state) do + Enum.each(elements, fn (val) -> walk(val, state) end) + end + + defp walk({:=, _, [left, right]}, state) do + walk(left, state) + walk(right, state) + end + + defp walk({:%, _, [module, params]}, state) do + walk(params, state) + end + + defp walk({:for, _, generators}, state) do + Enum.each(generators, fn + {:<<>>, _, body} -> + walk(body, state) + + {:<-, _, [identifier, enum]} -> + walk(identifier, state) + walk(enum, state) + + [into: expression] -> + walk(expression, state) + + [into: expression, do: expression2] -> + walk(expression, state) + walk(expression2, state) + + [do: expression] -> + walk(expression, state) + + filter -> + walk(filter, state) + end) + end + + defp walk({:case, _, [condition, [do: clauses]]}, state) do + Enum.each(clauses, &walk(&1, state)) + walk(condition, state) + end + + defp walk({:cond, _, [[do: clauses]]}, state) do + Enum.each(clauses, fn({:->, _, [clause, clause_body]}) -> + Enum.each(List.wrap(clause_body), &walk(&1, state)) + walk(hd(clause), state) + end) + end + + defp walk({:receive, _context, _}, _state) do + nil + end + + defp walk({:try, _, [blocks]}, state) do + try_block = Keyword.get(blocks, :do) + rescue_block = Keyword.get(blocks, :rescue, nil) + catch_block = Keyword.get(blocks, :catch, nil) + after_block = Keyword.get(blocks, :after, nil) + else_block = Keyword.get(blocks, :else, nil) + + Enum.each(List.wrap(try_block), &walk(&1, state)) + + if rescue_block do + Enum.each(rescue_block, fn + {:->, _, [ [{:in, _, [param, names]}], body]} -> + walk({[], [param], [{{:., [], [Enum, :member?]}, [], [param, names]}], body}, state) + {:->, _, [ [param], body]} -> + walk({[], [param], [], body}, state) + end) + end + + if catch_block do + walk({:fn, [], catch_block}, state) + end + + if after_block do + Enum.each(List.wrap(after_block), &walk(&1, state)) + end + + if else_block do + walk({:fn, [], else_block}, state) + end + end + + defp walk({:fn, _, clauses}, state) do + Enum.each(clauses, &walk(&1, state)) + end + + defp walk({{:., _, [:erlang, :apply]}, _, [module, function, params]}, state) do + walk({{:., [], [module, function]}, [], params}, state) + end + + defp walk({{:., _, [:erlang, :apply]}, _, [function, params]}, state) do + walk({function, [], params}, state) + end + + defp walk({{:., _, [module, function]}, _, params}, state) do + cond do + ElixirScript.Translate.Module.is_js_module(module, state) -> + nil + ElixirScript.Translate.Module.is_elixir_module(module) -> + walk_module(module, function, length(params), state.pid) + true -> + nil + end + + walk(params, state) + end + + defp walk({:super, _, params}, state) do + walk(params, state) + end + + defp walk({function, _, params}, state) when function in [:|, :::] do + nil + end + + defp walk({function, _, params}, state) when is_atom(function) and is_list(params) do + walk_module(state.module, function, length(params), state.pid) + Enum.each(params, &walk(&1, state)) + end + + defp walk({_, _, params}, state) when is_list(params) do + Enum.each(params, &walk(&1, state)) + end + + defp walk(_, _) do + nil + end + +end \ No newline at end of file diff --git a/lib/elixir_script/next/passes/find_used.ex b/lib/elixir_script/next/passes/find_used_modules.ex similarity index 92% rename from lib/elixir_script/next/passes/find_used.ex rename to lib/elixir_script/next/passes/find_used_modules.ex index b0bf6fbd..466b1bd6 100644 --- a/lib/elixir_script/next/passes/find_used.ex +++ b/lib/elixir_script/next/passes/find_used_modules.ex @@ -1,24 +1,9 @@ -defmodule ElixirScript.FindUsed do +defmodule ElixirScript.FindUsedModules do @moduledoc false - alias ElixirScript.State, as: ModuleState - - @erlang_modules [ - :erlang, - :maps, - :lists, - :gen, - :elixir_errors, - :supervisor, - :application, - :code, - :elixir_utils, - :file - ] + alias ElixirScript.State, as: ModuleState @doc """ - Takes a list of entry modules and finds modules they use along with - documenting the functions used. The data collected about used functions - is used to filter only the used functions for compilation + Takes a list of entry modules and finds modules they use. """ @spec execute([atom], pid) :: nil def execute(modules, pid) do @@ -240,10 +225,6 @@ defmodule ElixirScript.FindUsed do walk({function, [], params}, state) end - defp walk({{:., _, [module, function]}, _, params}, _state) when module in @erlang_modules do - nil - end - defp walk({{:., _, [module, function]}, _, params}, state) do cond do ElixirScript.Translate.Module.is_js_module(module, state) -> diff --git a/lib/elixir_script/next/passes/translate/module.ex b/lib/elixir_script/next/passes/translate/module.ex index e16fbe8d..86b48e5e 100644 --- a/lib/elixir_script/next/passes/translate/module.ex +++ b/lib/elixir_script/next/passes/translate/module.ex @@ -15,9 +15,6 @@ defmodule ElixirScript.Translate.Module do end def compile(module, info, pid) do - if Atom.to_string(module) == "Elixir.Example" do - IO.inspect info - end %{ attributes: attrs, compile_opts: _compile_opts, @@ -53,7 +50,30 @@ defmodule ElixirScript.Translate.Module do end #we combine our function arities - combined_defs = used_defs + combined_defs = combine_defs(used_defs) + exports = make_exports(combined_defs) + + # Don't skip compilation and output of modules that don't have + # any public functions + case exports do + %ESTree.ObjectExpression{ properties: [] } -> + ModuleState.put_module(pid, module, Map.put(info, :js_ast, J.program([]))) + _ -> + { compiled_functions, _ } = Enum.map_reduce(combined_defs, state, &Function.compile(&1, &2)) + + js_ast = ElixirScript.ModuleSystems.Namespace.build( + module, + compiled_functions, + exports, + nil + ) + + ModuleState.put_module(pid, module, Map.put(info, :js_ast, hd(js_ast))) + end + end + + defp combine_defs(used_defs) do + used_defs |> Enum.sort(fn { {name1, arity1}, _, _, _ }, { {name2, arity2}, _, _, _ } -> "#{name1}#{arity1}" < "#{name2}#{arity2}" end) |> Enum.group_by(fn {{name, _}, _, _, _ } -> name end) |> Enum.map(fn {group, funs} -> @@ -62,20 +82,6 @@ defmodule ElixirScript.Translate.Module do {name, type, context, acc_clauses ++ clauses} end) end) - - { compiled_functions, _ } = combined_defs - |> Enum.map_reduce(state, &Function.compile(&1, &2)) - - exports = make_exports(combined_defs) - - js_ast = ElixirScript.ModuleSystems.Namespace.build( - module, - compiled_functions, - exports, - nil - ) - - ModuleState.put_module(pid, module, Map.put(info, :js_ast, hd(js_ast))) end defp make_exports(reachable_defs) do diff --git a/lib/elixir_script/next/state.ex b/lib/elixir_script/next/state.ex index 711d8244..b199e9e8 100644 --- a/lib/elixir_script/next/state.ex +++ b/lib/elixir_script/next/state.ex @@ -36,6 +36,13 @@ defmodule ElixirScript.State do end) end + def has_used?(pid, module, func) do + Agent.get(pid, fn(state) -> + module_info = Keyword.get(state.modules, module) + Enum.find(module_info.used, fn(x) -> x == func end) != nil + end) + end + def add_used(pid, module, {_function, _arity} = func) do Agent.update(pid, fn(state) -> module_info = Keyword.get(state.modules, module) From 374b06130710445b1f67afafc5a1ca8205106554 Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Sun, 11 Jun 2017 11:42:52 -0500 Subject: [PATCH 118/418] Update version and CHANGELOG.md --- CHANGELOG.md | 2 +- mix.exs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 710e2cbd..b484b9e3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,7 +4,7 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/) and this project adheres to [Semantic Versioning](http://semver.org/). -## [0.28.0-dev] +## [0.28.0] - 2017-06-11 ### Added - `remove-unused` option that will remove all unused modules from output diff --git a/mix.exs b/mix.exs index a9b380f3..3be99d87 100644 --- a/mix.exs +++ b/mix.exs @@ -4,7 +4,7 @@ defmodule ElixirScript.Mixfile do def project do [ app: :elixir_script, - version: "0.28.0-dev", + version: "0.28.0", elixir: "~> 1.0", elixirc_paths: elixirc_paths(), escript: escript_config(), From 6e2f8f34b54b82c46d940a0ad5dbe615c34f53e5 Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Sun, 11 Jun 2017 14:21:32 -0500 Subject: [PATCH 119/418] Save mix.exs from merge --- lib/elixir_script/next/beam.ex | 12 ++++++++++++ mix.exs | 6 ------ 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/lib/elixir_script/next/beam.ex b/lib/elixir_script/next/beam.ex index d9838c28..f9611c5a 100644 --- a/lib/elixir_script/next/beam.ex +++ b/lib/elixir_script/next/beam.ex @@ -8,6 +8,18 @@ defmodule ElixirScript.Beam do all the protocol implementations """ @spec debug_info(atom) :: {:ok | :error, map | binary} + def debug_info(module) + + #Replacing String module with our ElixirScript's version + def debug_info(String) do + case debug_info(ElixirScript.String) do + {:ok, info} -> + {:ok, Map.put(info, :module, String)} + e -> + e + end + end + def debug_info(module) when is_atom(module) do #TODO: Get modified date from _beam_path to check for cached version? with {_, beam, _beam_path} <- :code.get_object_code(module), diff --git a/mix.exs b/mix.exs index cbe149f9..8a5a9573 100644 --- a/mix.exs +++ b/mix.exs @@ -4,15 +4,9 @@ defmodule ElixirScript.Mixfile do def project do [ app: :elixir_script, -<<<<<<< HEAD version: "0.28.0-dev", elixir: "~> 1.5-dev", elixirc_paths: elixirc_paths(Mix.env), -======= - version: "0.28.0", - elixir: "~> 1.0", - elixirc_paths: elixirc_paths(), ->>>>>>> master escript: escript_config(), deps: deps(), description: description(), From 48e3225e2861c5f368d3d931a73f921f987ac3b8 Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Sun, 11 Jun 2017 17:23:15 -0500 Subject: [PATCH 120/418] Fixes from compiler testing. Replace String compilation with ElixirScript.String --- .tool-versions | 6 +-- .../next/passes/find_used_functions.ex | 42 ++++++++----------- .../next/passes/find_used_modules.ex | 17 +++++--- .../next/passes/translate/examples/example.ex | 5 --- .../next/passes/translate/examples/size.ex | 16 ------- .../next/passes/translate/form.ex | 14 ++++++- .../next/passes/translate/forms/remote.ex | 20 ++++++++- .../next/passes/translate/module.ex | 2 +- .../next/passes/translate/module_state.ex | 21 ---------- priv/std_lib/string.ex | 7 +++- 10 files changed, 71 insertions(+), 79 deletions(-) delete mode 100644 lib/elixir_script/next/passes/translate/examples/example.ex delete mode 100644 lib/elixir_script/next/passes/translate/examples/size.ex delete mode 100644 lib/elixir_script/next/passes/translate/module_state.ex diff --git a/.tool-versions b/.tool-versions index d588b60f..e84347ce 100644 --- a/.tool-versions +++ b/.tool-versions @@ -1,3 +1,3 @@ -erlang ref-OTP-20.0-rc1 -elixir ref-9873e42 -nodejs 7.10.0 \ No newline at end of file +erlang ref-OTP-20.0-rc2 +elixir ref-d19a92b +nodejs 8.1.0 \ No newline at end of file diff --git a/lib/elixir_script/next/passes/find_used_functions.ex b/lib/elixir_script/next/passes/find_used_functions.ex index 30af88af..4fef005e 100644 --- a/lib/elixir_script/next/passes/find_used_functions.ex +++ b/lib/elixir_script/next/passes/find_used_functions.ex @@ -46,34 +46,23 @@ defmodule ElixirScript.FindUsedFunctions do defp walk_module(module, function, arity, pid) do function = {function, arity} - unless ModuleState.has_used?(pid, module, function) do - %{ - attributes: _attrs, - compile_opts: _compile_opts, - definitions: defs, - file: _file, - line: _line, - module: ^module, - unreachable: unreachable - } = ModuleState.get_module(pid, module) + info = ModuleState.get_module(pid, module) state = %{ pid: pid, module: module } - reachable_defs = Enum.filter(defs, fn - { _, type, _, _} when type in [:defmacro, :defmacrop] -> false - { name, _, _, _} -> not(name in [function]) - _ -> true - end) - - Enum.each(reachable_defs, fn({name, _type, _, _clauses}) -> - ModuleState.add_used(state.pid, module, name) - end) + reachable_def = Enum.find(Map.get(info, :definitions, []), fn { name, _, _, _} -> name == function end) - Enum.each(reachable_defs, &walk(&1, state)) + case reachable_def do + nil -> + nil + {name, _type, _, _clauses} = func -> + ModuleState.add_used(state.pid, module, name) + walk(func, state) + end end end @@ -105,6 +94,15 @@ defmodule ElixirScript.FindUsedFunctions do walk({[], params, [], body}, state) end + defp walk({:|, _, [head, tail]}, state) do + walk(head, state) + walk(tail, state) + end + + defp walk({:::, _, _}, state) do + nil + end + defp walk(form, state) when is_list(form) do Enum.each(form, &walk(&1, state)) end @@ -234,10 +232,6 @@ defmodule ElixirScript.FindUsedFunctions do walk(params, state) end - defp walk({function, _, params}, state) when function in [:|, :::] do - nil - end - defp walk({function, _, params}, state) when is_atom(function) and is_list(params) do walk_module(state.module, function, length(params), state.pid) Enum.each(params, &walk(&1, state)) diff --git a/lib/elixir_script/next/passes/find_used_modules.ex b/lib/elixir_script/next/passes/find_used_modules.ex index 466b1bd6..a74848fa 100644 --- a/lib/elixir_script/next/passes/find_used_modules.ex +++ b/lib/elixir_script/next/passes/find_used_modules.ex @@ -99,12 +99,21 @@ defmodule ElixirScript.FindUsedModules do walk({[], params, [], body}, state) end + defp walk({:|, _, [head, tail]}, state) do + walk(head, state) + walk(tail, state) + end + + defp walk({:::, _, _}, state) do + nil + end + defp walk(form, state) when is_list(form) do Enum.each(form, &walk(&1, state)) end defp walk(form, state) when is_atom(form) and form not in [BitString, Function, PID, Port, Reference, Any, Elixir] do - if ElixirScript.Translate.Module.is_elixir_module(form) do + if ElixirScript.Translate.Module.is_elixir_module(form) and !ElixirScript.Translate.Module.is_js_module(form, state) do if ModuleState.get_module(state.pid, form) == nil do execute(form, state.pid) end @@ -133,7 +142,7 @@ defmodule ElixirScript.FindUsedModules do end defp walk({:%, _, [module, params]}, state) do - if ElixirScript.Translate.Module.is_elixir_module(module) do + if ElixirScript.Translate.Module.is_elixir_module(module) and !ElixirScript.Translate.Module.is_js_module(module, state) do if ModuleState.get_module(state.pid, module) == nil do do_execute(module, state.pid) end @@ -233,7 +242,6 @@ defmodule ElixirScript.FindUsedModules do if ModuleState.get_module(state.pid, module) == nil do execute(module, state.pid) end - ModuleState.add_used(state.pid, module, {function, length(params)}) true -> nil end @@ -245,8 +253,7 @@ defmodule ElixirScript.FindUsedModules do walk(params, state) end - defp walk({function, _, params}, state) when is_atom(function) and is_list(params) do - ModuleState.add_used(state.pid, state.module, {function, length(params)}) + defp walk({function, _, params}, state) when is_atom(function) and is_list(params) do Enum.each(params, &walk(&1, state)) end diff --git a/lib/elixir_script/next/passes/translate/examples/example.ex b/lib/elixir_script/next/passes/translate/examples/example.ex deleted file mode 100644 index dd298938..00000000 --- a/lib/elixir_script/next/passes/translate/examples/example.ex +++ /dev/null @@ -1,5 +0,0 @@ -defmodule Example do - def start(_, _) do - -1 - end -end diff --git a/lib/elixir_script/next/passes/translate/examples/size.ex b/lib/elixir_script/next/passes/translate/examples/size.ex deleted file mode 100644 index 10dadd44..00000000 --- a/lib/elixir_script/next/passes/translate/examples/size.ex +++ /dev/null @@ -1,16 +0,0 @@ -defprotocol Example.Size do - def size(data) -end - -defimpl Example.Size, for: BitString do - - def size(string), do: byte_size(string) -end - -defimpl Example.Size, for: Map do - def size(map), do: map_size(map) -end - -defimpl Example.Size, for: Tuple do - def size(tuple), do: tuple_size(tuple) -end \ No newline at end of file diff --git a/lib/elixir_script/next/passes/translate/form.ex b/lib/elixir_script/next/passes/translate/form.ex index 58b95de0..2c2d2a1e 100644 --- a/lib/elixir_script/next/passes/translate/form.ex +++ b/lib/elixir_script/next/passes/translate/form.ex @@ -24,6 +24,18 @@ defmodule ElixirScript.Translate.Form do { J.literal(form), state } end + def compile({:|, _, [head, tail]}, state) do + ast = J.call_expression( + J.member_expression( + J.array_expression([compile!(head, state)]), + J.identifier("concat") + ), + [compile!(tail, state)] + ) + + { ast, state } + end + def compile(form, state) when is_list(form) do ast = J.array_expression( Enum.map(form, &compile!(&1, state)) @@ -151,7 +163,7 @@ defmodule ElixirScript.Translate.Form do def compile({:receive, context, [blocks]}, state) do line = Keyword.get(context, :line, 1) {function, arity} = Map.get(state, :function) - Logger.warn "receive not supported, Module: #{inspect state.module}, Function: #{function}/#{arity}, Line: #{line}" + Logger.warn "receive not supported, Module: #{inspect state.module}, Function: #{function}, Line: #{line}" Receive.compile(blocks, state) end diff --git a/lib/elixir_script/next/passes/translate/forms/remote.ex b/lib/elixir_script/next/passes/translate/forms/remote.ex index bb881afe..f28543a8 100644 --- a/lib/elixir_script/next/passes/translate/forms/remote.ex +++ b/lib/elixir_script/next/passes/translate/forms/remote.ex @@ -143,8 +143,7 @@ defmodule ElixirScript.Translate.Forms.Remote do def process_module_name(module, state) when is_atom(module) do cond do ElixirScript.Translate.Module.is_js_module(module, state) -> - members = tl(Module.split(module)) - Identifier.make_namespace_members(members) + process_js_module_name(module, state) module === Elixir -> members = ["Elixir", "__load"] @@ -168,6 +167,23 @@ defmodule ElixirScript.Translate.Forms.Remote do Form.compile!(module, state) end + defp process_js_module_name(module, state) do + case Module.split(module) do + ["JS"] -> + J.member_expression( + J.member_expression( + J.identifier("Bootstrap"), + J.identifier("Core") + ), + J.identifier("global") + ) + ["JS" | rest] -> + Identifier.make_namespace_members(rest) + x -> + Identifier.make_namespace_members(x) + end + end + defp erlang_compat_function(module, function) do J.member_expression( J.member_expression( diff --git a/lib/elixir_script/next/passes/translate/module.ex b/lib/elixir_script/next/passes/translate/module.ex index 86b48e5e..b18d02da 100644 --- a/lib/elixir_script/next/passes/translate/module.ex +++ b/lib/elixir_script/next/passes/translate/module.ex @@ -57,7 +57,7 @@ defmodule ElixirScript.Translate.Module do # any public functions case exports do %ESTree.ObjectExpression{ properties: [] } -> - ModuleState.put_module(pid, module, Map.put(info, :js_ast, J.program([]))) + nil _ -> { compiled_functions, _ } = Enum.map_reduce(combined_defs, state, &Function.compile(&1, &2)) diff --git a/lib/elixir_script/next/passes/translate/module_state.ex b/lib/elixir_script/next/passes/translate/module_state.ex deleted file mode 100644 index 8e2afdd2..00000000 --- a/lib/elixir_script/next/passes/translate/module_state.ex +++ /dev/null @@ -1,21 +0,0 @@ -defmodule ElixirScript.Translate.ModuleState do - def start_link(module) do - Agent.start_link(fn -> %{ module: module, refs: [] } end) - end - - def stop(pid) do - Agent.stop(pid) - end - - def put_module_ref(pid, module) do - Agent.update(pid, fn(x) -> - %{x | refs: Enum.uniq([module | x.refs]) } - end) - end - - def get_module_refs(pid) do - Agent.get(pid, fn(x) -> - x.refs - end) - end -end \ No newline at end of file diff --git a/priv/std_lib/string.ex b/priv/std_lib/string.ex index 1ff6bcee..3d5465bc 100644 --- a/priv/std_lib/string.ex +++ b/priv/std_lib/string.ex @@ -199,6 +199,11 @@ defmodule ElixirScript.String do end def valid_character?(codepoint) do - ElixirScript.Bootstrap.Functions.is_valid_character(codepoint) + try do + JS.String.fromCodePoint(codepoint) != nil + rescue + _ -> + false + end end end From 1189826772715b80a1aba7bfea8ab63737d21bf1 Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Sun, 11 Jun 2017 19:17:28 -0500 Subject: [PATCH 121/418] Skip loading JS module --- lib/elixir_script/next/passes/find_used_functions.ex | 4 ++++ lib/elixir_script/next/passes/find_used_modules.ex | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/lib/elixir_script/next/passes/find_used_functions.ex b/lib/elixir_script/next/passes/find_used_functions.ex index 4fef005e..a13c15e0 100644 --- a/lib/elixir_script/next/passes/find_used_functions.ex +++ b/lib/elixir_script/next/passes/find_used_functions.ex @@ -215,6 +215,10 @@ defmodule ElixirScript.FindUsedFunctions do walk({function, [], params}, state) end + defp walk({{:., _, [JS, _]}, _, params}, state) do + walk(params, state) + end + defp walk({{:., _, [module, function]}, _, params}, state) do cond do ElixirScript.Translate.Module.is_js_module(module, state) -> diff --git a/lib/elixir_script/next/passes/find_used_modules.ex b/lib/elixir_script/next/passes/find_used_modules.ex index a74848fa..e68ca080 100644 --- a/lib/elixir_script/next/passes/find_used_modules.ex +++ b/lib/elixir_script/next/passes/find_used_modules.ex @@ -234,6 +234,10 @@ defmodule ElixirScript.FindUsedModules do walk({function, [], params}, state) end + defp walk({{:., _, [JS, _]}, _, params}, state) do + walk(params, state) + end + defp walk({{:., _, [module, function]}, _, params}, state) do cond do ElixirScript.Translate.Module.is_js_module(module, state) -> From 26d9dcfa8bba1d99a9528a9cd39fcb0647196342 Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Mon, 12 Jun 2017 20:22:09 -0500 Subject: [PATCH 122/418] Add module to handle JS function calls --- GettingStarted.md | 95 ++------------ JavascriptInterop.md | 6 - lib/elixir_script/next/passes/output.ex | 9 +- .../next/passes/output/js_module.ex | 116 ++++++++++++++++++ .../next/passes/translate/form.ex | 12 +- .../next/passes/translate/forms/js.ex | 69 +++++++++++ .../next/passes/translate/forms/map.ex | 2 +- .../next/passes/translate/forms/pattern.ex | 6 +- .../next/passes/translate/forms/remote.ex | 13 +- .../next/passes/translate/function.ex | 2 +- .../next/passes/translate/identifier.ex | 92 ++++++++++++++ .../next/passes/translate/module.ex | 4 +- .../next/passes/translate/protocol.ex | 2 +- lib/elixir_script/watcher.ex | 12 +- mix.exs | 2 +- 15 files changed, 315 insertions(+), 127 deletions(-) create mode 100644 lib/elixir_script/next/passes/output/js_module.ex create mode 100644 lib/elixir_script/next/passes/translate/forms/js.ex create mode 100644 lib/elixir_script/next/passes/translate/identifier.ex diff --git a/GettingStarted.md b/GettingStarted.md index 6870c716..c5b4681b 100644 --- a/GettingStarted.md +++ b/GettingStarted.md @@ -1,85 +1,16 @@ # Getting Started with ElixirScript -The intent of this guide is to get you started with ElixirScript. It will give you instructions on using ElixirScript. I will go over the two ways you can use Elixirscript: - -* As a CLI -* As a mix dependency - -### CLI - -**macOS**: Elixirscript is available via homebrew `brew install elixirscript`. For everyone else, please read below - -Step 1: Get CLI - -You can download the elixirscript CLI from the [releases page on github](https://github.com/bryanjos/elixirscript/releases). It is a tar file named elixirscript.tar.gz. - -Step 2: Untar - -Next, untar elixirscript.tar.gz - - tar -xvzf elixirscript.tar.gz - -You will want to put the bin folder from the uncompressed folder into your path. This should allow you to use the elixirscript CLI. - -Step 3: Use - -This is the help output of elixirscript - - usage: elixirscript [options] - path to elixir files or - the elixir code string if passed the -e flag - options: - --js-module [:] A js module used in your code. ex: React:react - Multiple can be defined - -f --format [format] module format of output. options: es (default), common, umd - -o --output [path] places output at the given path. - Can be a directory or filename. - -e --elixir read input as elixir code string - --full-build informs the compiler to do a full build instead of an incremental one - -v --version the current version number - -h --help this message - -the `` is the elixir code string or file path you want to convert from elixir to javascript. Below is an example of using a code string and turning it into JavaScript - - $ elixirscript ":atom" -e - -elixirscript also takes a path to your `.ex` files as well: - - $ elixirscript "src" -o "dist" - -If you look in the dist folder you'll see a file called `Elixir.App.js` - -To start your application import the bundle according to whichever module format was selected and -then call start giving it the module and the initial args. - -Ex. If you have a module like so -```elixir -defmodule Example do - start(type, args) do - :console.log("Hello, world") - end -end -``` - -You would start it like so - -```javascript -//ES module example -import Elixir from './Elixir.App' -Elixir.start(Elixir.Example, []) -``` - -### Mix dependency +The intent of this guide is to get you started with ElixirScript. It will give you instructions on using ElixirScript. Adding Elixirscript to your mix project gives you the ability to add it to your list of mix compilers. This means when you `mix compile`, Elixirscript will compile your code as well. Add dependency to your deps in mix.exs: ``` elixir -{:elixir_script, "~> 0.26"} +{:elixir_script, "~> 0.29"} ``` -Elixirscript uses default input, output and module formats if options are not given. If you wish to change any or all options, add an `elixir_script` key to your project configuration. +Elixirscript uses default output and module formats if options are not given. If you wish to change any or all options, add an `elixir_script` key to your project configuration. ``` elixir def project do @@ -89,7 +20,7 @@ Elixirscript uses default input, output and module formats if options are not gi elixir: "~> 1.0", deps: deps, elixir_script: [ - input: "lib/elixirscript", + input: MyEntryModule, output: "priv/elixirscript/Elixir.App.js", format: :es, js_modules: [ @@ -98,14 +29,14 @@ Elixirscript uses default input, output and module formats if options are not gi {Phoenix, "phoenix", default: false} ] ], - compilers: [:elixir_script] ++ Mix.compilers + compilers: Mix.compilers ++ [:elixir_script] ] end ``` Available options are: -* `input`: The folder to look for Elixirscript files in. (defaults to `lib/elixirscript`) +* `input`: The entry module(s) for your application or library * `output`: The path of the generated JavaScript file. (defaults to `priv/elixirscript`) @@ -126,20 +57,8 @@ Available options are: ### Macros -Elixirscript supports public macros. Private macros are currently unsupported. +Elixirscript supports all macros ### JavaScript Interop Check out the [JavaScript Interoperability](JavaScriptInterop.html) documentation - -#### Frontend Project Boilerplate - -There is an [elixirscript frontend boilerplate project](https://github.com/elixirscript/elixirscript-project-boilerplate). This setup uses gulp and webpack to build and bundle assets. - -#### elixirscript-brunch - -There is an Brunch plugin, [elixirscript-brunch](https://www.npmjs.com/package/elixirscript-brunch). - -#### elixirscript-loader - -There is also a webpack loader, [elixirscript-loader](https://www.npmjs.com/package/elixirscript-loader). diff --git a/JavascriptInterop.md b/JavascriptInterop.md index 13095e2f..db0c0e45 100644 --- a/JavascriptInterop.md +++ b/JavascriptInterop.md @@ -58,12 +58,6 @@ If using ElixirScript in a mix project, you can do so inside of the ElixirScript end ``` -Or if using the CLI, you can do so by passing each module via the `js-module` flag - -``` -elixirscript "app/elixirscript" -o dist --js-module React:react --js-module ReactDOM:react-dom -``` - Interacting with these modules works the same as interacting with an ElixirScript module ```elixir diff --git a/lib/elixir_script/next/passes/output.ex b/lib/elixir_script/next/passes/output.ex index 925897ab..cec29f28 100644 --- a/lib/elixir_script/next/passes/output.ex +++ b/lib/elixir_script/next/passes/output.ex @@ -23,16 +23,13 @@ defmodule ElixirScript.Output do end defp bundle(modules, opts) do - ElixirScript.Passes.CreateJSModules.compile(modules, opts) - - js_code = modules - |> ElixirScript.Passes.CreateJSModules.compile(opts) + modules + |> ElixirScript.Output.JSModule.compile(opts) |> List.wrap |> Builder.program |> prepare_js_ast |> Generator.generate - - concat(js_code) + |> concat end defp concat(code) do diff --git a/lib/elixir_script/next/passes/output/js_module.ex b/lib/elixir_script/next/passes/output/js_module.ex new file mode 100644 index 00000000..60eba1e9 --- /dev/null +++ b/lib/elixir_script/next/passes/output/js_module.ex @@ -0,0 +1,116 @@ +defmodule ElixirScript.Output.JSModule do + @moduledoc false + + alias ESTree.Tools.Builder, as: J + + def compile(body, opts) do + declarator = J.variable_declarator( + J.identifier("Elixir"), + J.object_expression([]) + ) + + elixir = J.variable_declaration([declarator], :const) + + table_additions = Enum.map(opts.js_modules, fn + {module, path} -> add_import_to_table(module) + {module, path, _} -> add_import_to_table(module) + end) + + ast = opts.module_formatter.build( + [], + opts.js_modules, + [elixir, create_atom_table(), start, load] ++ table_additions ++ body, + J.identifier("Elixir") + ) + + ast + end + + def start do + J.assignment_expression( + :=, + J.member_expression( + J.identifier("Elixir"), + J.identifier("start") + ), + J.function_expression( + [J.identifier(:app), J.identifier(:args)], + [], + J.block_statement([ + J.call_expression( + J.member_expression( + J.call_expression( + J.member_expression( + J.identifier(:app), + J.identifier("__load") + ), + [J.identifier("Elixir")] + ), + J.identifier("start") + ), + [ElixirScript.Translator.Primitive.make_atom(:normal), J.identifier(:args)] + ) + ]) + ) + ) + end + + def load do + J.assignment_expression( + :=, + J.member_expression( + J.identifier("Elixir"), + J.identifier("load") + ), + J.function_expression( + [J.identifier(:module)], + [], + J.block_statement([ + J.return_statement( + J.call_expression( + J.member_expression( + J.identifier(:module), + J.identifier("__load") + ), + [J.identifier("Elixir")] + ) + ) + ]) + ) + ) + end + + defp create_atom_table() do + J.assignment_expression( + :=, + J.member_expression( + J.identifier("Elixir"), + J.identifier("__table__") + ), + J.object_expression([]) + ) + end + + defp add_import_to_table(module_name) do + ref = ElixirScript.Translate.Identifier.make_namespace_members(module_name) + J.assignment_expression( + :=, + J.member_expression( + J.member_expression( + J.identifier("Elixir"), + J.identifier("__table__") + ), + J.call_expression( + J.member_expression( + J.identifier("Symbol"), + J.identifier("for") + ), + [J.literal(ref.name)] + ), + true + ), + ref + ) + end + +end \ No newline at end of file diff --git a/lib/elixir_script/next/passes/translate/form.ex b/lib/elixir_script/next/passes/translate/form.ex index 2c2d2a1e..b049af01 100644 --- a/lib/elixir_script/next/passes/translate/form.ex +++ b/lib/elixir_script/next/passes/translate/form.ex @@ -2,7 +2,7 @@ defmodule ElixirScript.Translate.Form do alias ESTree.Tools.Builder, as: J alias ElixirScript.Translate.Forms.{Bitstring, Match, Try, For, Receive, Remote, Pattern} alias ElixirScript.Translate.Functions.{Erlang, Lists, Maps} - alias ElixirScript.Translator.Identifier + alias ElixirScript.Translate.Identifier alias ElixirScript.Translate.Clause require Logger @@ -185,6 +185,10 @@ defmodule ElixirScript.Translate.Form do {ast, state} end + def compile({{:., _, [JS, _]}, _, _} = ast, state) do + ElixirScript.Translate.Forms.JS.compile(ast, state) + end + def compile({:., _, call} = ast, state) when is_list(call) do Remote.compile(ast, state) end @@ -193,7 +197,7 @@ defmodule ElixirScript.Translate.Form do {function_name, _} = Map.get(state, :function) ast = J.call_expression( - ElixirScript.Translator.Identifier.make_function_name(function_name), + ElixirScript.Translate.Identifier.make_function_name(function_name), Enum.map(params, &compile!(&1, state)) |> List.flatten ) @@ -202,7 +206,7 @@ defmodule ElixirScript.Translate.Form do def compile({var, _, params}, state) when is_list(params) and is_atom(var) do ast = J.call_expression( - ElixirScript.Translator.Identifier.make_function_name(var), + ElixirScript.Translate.Identifier.make_function_name(var), Enum.map(params, &compile!(&1, state)) |> List.flatten ) @@ -220,7 +224,7 @@ defmodule ElixirScript.Translate.Form do def compile({var, _, _}, state) do var = Pattern.get_variable_name(to_string(var), state) - { ElixirScript.Translator.Identifier.make_identifier(var), state } + { ElixirScript.Translate.Identifier.make_identifier(var), state } end end diff --git a/lib/elixir_script/next/passes/translate/forms/js.ex b/lib/elixir_script/next/passes/translate/forms/js.ex new file mode 100644 index 00000000..11250f99 --- /dev/null +++ b/lib/elixir_script/next/passes/translate/forms/js.ex @@ -0,0 +1,69 @@ +defmodule ElixirScript.Translate.Forms.JS do + @moduledoc false + alias ESTree.Tools.Builder, as: J + alias ElixirScript.Translate.Form + + def global() do + Builder.member_expression( + Builder.member_expression( + Builder.identifier("Bootstrap"), + Builder.identifier("Core") + ), + Builder.identifier("global") + ) + end + + def compile({{:., _, [JS, :debugger]}, _, _}, state) do + ast = J.debugger_statement() + {ast, state} + end + + def compile({{:., _, [JS, :this]}, _, _}, state) do + ast = J.this_expression() + {ast, state} + end + + def compile({{:., _, [JS, :new]}, _, [module, params]}, state) do + members = Module.split(module) + + params = case params do + p when is_list(p) -> + Enum.map(params, &Form.compile!(&1, state)) + p -> + [J.rest_element(Form.compile!(params, state))] + end + + ast = J.new_expression( + ElixirScript.Translate.Identifier.make_namespace_members(members), + params + ) + + {ast, state} + end + + defp do_translate({{:., _, [JS, :throw]}, _, [term]}, state) do + ast = J.throw_statement( + Form.compile!(term, state) + ) + + {ast, state} + end + + defp do_translate({{:., _, [JS, :import]}, _, [term]}, state) do + ast = J.call_expression( + J.identifier("import"), + [Form.compile!(term, state)] + ) + + {ast, state} + end + + defp do_translate({{:., _, [JS, function]}, _, params}, state) do + ast = J.call_expression( + J.identifier(function), + Enum.map(params, &Form.compile!(&1, state)) + ) + + {ast, state} + end +end \ No newline at end of file diff --git a/lib/elixir_script/next/passes/translate/forms/map.ex b/lib/elixir_script/next/passes/translate/forms/map.ex index ce1ee7f5..49480138 100644 --- a/lib/elixir_script/next/passes/translate/forms/map.ex +++ b/lib/elixir_script/next/passes/translate/forms/map.ex @@ -50,7 +50,7 @@ defmodule ElixirScript.Translate.Forms.Map do true -> J.literal(k) false -> - ElixirScript.Translator.Identifier.make_identifier(k) + ElixirScript.Translate.Identifier.make_identifier(k) end J.property(key, value) diff --git a/lib/elixir_script/next/passes/translate/forms/pattern.ex b/lib/elixir_script/next/passes/translate/forms/pattern.ex index 6b120564..d0f07d07 100644 --- a/lib/elixir_script/next/passes/translate/forms/pattern.ex +++ b/lib/elixir_script/next/passes/translate/forms/pattern.ex @@ -133,7 +133,7 @@ defmodule ElixirScript.Translate.Forms.Pattern do params = Enum.reduce(elements, [], fn ({:::, _, [{ variable, _, params }, _]}, state) when is_nil(params) when is_list(params) and length(params) == 0 -> - state ++ [ElixirScript.Translator.Identifier.make_identifier(variable)] + state ++ [ElixirScript.Translate.Identifier.make_identifier(variable)] _, state -> state end) @@ -161,7 +161,7 @@ defmodule ElixirScript.Translate.Forms.Pattern do end defp process_pattern({var, _, _}, _) do - { [PM.parameter()], [ElixirScript.Translator.Identifier.make_identifier(var)] } + { [PM.parameter()], [ElixirScript.Translate.Identifier.make_identifier(var)] } end defp reduce_patterns(patterns, _) do @@ -173,6 +173,6 @@ defmodule ElixirScript.Translate.Forms.Pattern do defp unify(target, source, state) do { patterns, params } = do_compile([source], state) - { [PM.capture(hd(patterns))], params ++ [ElixirScript.Translator.Identifier.make_identifier(target)] } + { [PM.capture(hd(patterns))], params ++ [ElixirScript.Translate.Identifier.make_identifier(target)] } end end diff --git a/lib/elixir_script/next/passes/translate/forms/remote.ex b/lib/elixir_script/next/passes/translate/forms/remote.ex index f28543a8..6d4a751a 100644 --- a/lib/elixir_script/next/passes/translate/forms/remote.ex +++ b/lib/elixir_script/next/passes/translate/forms/remote.ex @@ -3,7 +3,7 @@ defmodule ElixirScript.Translate.Forms.Remote do alias ESTree.Tools.Builder, as: J alias ElixirScript.Translate.Form - alias ElixirScript.Translator.Identifier + alias ElixirScript.Translate.Identifier @erlang_modules [ :erlang, @@ -25,6 +25,7 @@ defmodule ElixirScript.Translate.Forms.Remote do includes function heads for converting some erlang functions into JavaScript functions. """ + def compile({:., _, [:erlang, :+]}, state) do ast = erlang_compat_function("erlang", "plus") { ast, state } @@ -114,7 +115,7 @@ defmodule ElixirScript.Translate.Forms.Remote do ), J.identifier(module) ), - ElixirScript.Translator.Identifier.make_function_name(function) + ElixirScript.Translate.Identifier.make_function_name(function) ) { ast, state } @@ -127,9 +128,9 @@ defmodule ElixirScript.Translate.Forms.Remote do def compile({:., _, [module, function]}, state) do function_name = cond do ElixirScript.Translate.Module.is_js_module(module, state) -> - ElixirScript.Translator.Identifier.make_extern_function_name(function) + ElixirScript.Translate.Identifier.make_extern_function_name(function) true -> - ElixirScript.Translator.Identifier.make_function_name(function) + ElixirScript.Translate.Identifier.make_function_name(function) end ast = J.member_expression( @@ -159,7 +160,7 @@ defmodule ElixirScript.Translate.Forms.Remote do [J.identifier("Elixir")] ) true -> - ElixirScript.Translator.Identifier.make_identifier(module) + ElixirScript.Translate.Identifier.make_identifier(module) end end @@ -193,7 +194,7 @@ defmodule ElixirScript.Translate.Forms.Remote do ), J.identifier(module) ), - ElixirScript.Translator.Identifier.make_function_name(function) + ElixirScript.Translate.Identifier.make_function_name(function) ) end end \ No newline at end of file diff --git a/lib/elixir_script/next/passes/translate/function.ex b/lib/elixir_script/next/passes/translate/function.ex index 9dd6726b..ad5a5e6f 100644 --- a/lib/elixir_script/next/passes/translate/function.ex +++ b/lib/elixir_script/next/passes/translate/function.ex @@ -32,7 +32,7 @@ defmodule ElixirScript.Translate.Function do arg_matches_declaration = J.variable_declaration([arg_matches_declarator], :let) declarator = J.variable_declarator( - ElixirScript.Translator.Identifier.make_function_name(name), + ElixirScript.Translate.Identifier.make_function_name(name), J.function_expression( [J.rest_element(J.identifier("__function_args__"))], [], diff --git a/lib/elixir_script/next/passes/translate/identifier.ex b/lib/elixir_script/next/passes/translate/identifier.ex new file mode 100644 index 00000000..5c95e03a --- /dev/null +++ b/lib/elixir_script/next/passes/translate/identifier.ex @@ -0,0 +1,92 @@ +defmodule ElixirScript.Translate.Identifier do + @moduledoc false + alias ESTree.Tools.Builder, as: J + + @js_reserved_words [ + :break, + :case, + :class, + :const, + :continue, + :debugger, + :default, + :delete, + :do, + :else, + :export, + :extends, + :finally, + :function, + :if, + :import, + :in, + :instanceof, + :new, + :return, + :super, + :switch, + :throw, + :try, + :typeof, + :var, + :void, + :while, + :with, + :yield + ] + + def make_identifier([ast]) do + make_identifier(ast) + end + + def make_identifier(ast) do + ast + |> filter_name + |> J.identifier + end + + defp filter_name(name) when is_tuple(name) do + name + end + + defp filter_name(reserved_word) when reserved_word in @js_reserved_words do + "__#{Atom.to_string(reserved_word)}__" + end + + defp filter_name(name) do + to_string(name) + |> String.replace("?", "__qmark__") + |> String.replace("!", "__emark__") + end + + defp make_alias([x]) do + make_identifier(x) + end + + defp make_alias([h|t]) do + J.member_expression(make_alias(t), make_identifier(h)) + end + + def make_namespace_members(module_name) do + case module_name do + m when is_list(m) -> + m + m when is_binary(m) -> + String.split(m, ".") + m when is_atom(m) -> + Module.split(m) + end + |> Enum.reverse + |> make_alias + end + + def make_function_name(name) do + name = filter_name(name) + J.identifier(name) + end + + def make_extern_function_name(name) do + J.identifier("#{name}") + end + +end diff --git a/lib/elixir_script/next/passes/translate/module.ex b/lib/elixir_script/next/passes/translate/module.ex index b18d02da..68e2388d 100644 --- a/lib/elixir_script/next/passes/translate/module.ex +++ b/lib/elixir_script/next/passes/translate/module.ex @@ -3,7 +3,7 @@ defmodule ElixirScript.Translate.Module do alias ESTree.Tools.Builder, as: J alias ElixirScript.Translate.Function alias ElixirScript.Translate.Form - alias ElixirScript.Translator.Identifier + alias ElixirScript.Translate.Identifier alias ElixirScript.State, as: ModuleState @doc """ @@ -87,7 +87,7 @@ defmodule ElixirScript.Translate.Module do defp make_exports(reachable_defs) do exports = Enum.reduce(reachable_defs, [], fn {{name, arity}, :def, _, _}, list -> - function_name = ElixirScript.Translator.Identifier.make_identifier(name) + function_name = ElixirScript.Translate.Identifier.make_identifier(name) list ++ [J.property(function_name, function_name, :init, true)] _, list -> list diff --git a/lib/elixir_script/next/passes/translate/protocol.ex b/lib/elixir_script/next/passes/translate/protocol.ex index d64375bd..baaed852 100644 --- a/lib/elixir_script/next/passes/translate/protocol.ex +++ b/lib/elixir_script/next/passes/translate/protocol.ex @@ -3,7 +3,7 @@ defmodule ElixirScript.Translate.Protocol do alias ESTree.Tools.Builder, as: J alias ElixirScript.Translate.Function alias ElixirScript.Translate.Form - alias ElixirScript.Translator.Identifier + alias ElixirScript.Translate.Identifier alias ElixirScript.State, as: ModuleState diff --git a/lib/elixir_script/watcher.ex b/lib/elixir_script/watcher.ex index 8d484de1..5f6de96c 100644 --- a/lib/elixir_script/watcher.ex +++ b/lib/elixir_script/watcher.ex @@ -35,15 +35,11 @@ defmodule ElixirScript.Watcher do end defp input_changed?(path, state) do - file = Path.basename(path) - - case file do - "." <> _ -> - false + case Path.extname(path) do + ".beam" -> + true _ -> - Enum.any?(List.wrap(state[:input]), fn(x) -> - path == Path.absname(Path.join([x, file])) - end) + false end end end diff --git a/mix.exs b/mix.exs index 8a5a9573..83839435 100644 --- a/mix.exs +++ b/mix.exs @@ -4,7 +4,7 @@ defmodule ElixirScript.Mixfile do def project do [ app: :elixir_script, - version: "0.28.0-dev", + version: "0.29.0-dev", elixir: "~> 1.5-dev", elixirc_paths: elixirc_paths(Mix.env), escript: escript_config(), From 6d4d62575b549580b23b707f75eeba1c55018657 Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Tue, 13 Jun 2017 02:15:08 -0500 Subject: [PATCH 123/418] Some fixes for pattern compilation --- .../next/passes/translate/form.ex | 20 ++++++++- .../next/passes/translate/forms/js.ex | 41 +++++++++++++++---- .../next/passes/translate/forms/pattern.ex | 8 +++- .../next/passes/translate/forms/try.ex | 10 ++--- .../next/passes/translate/function.ex | 17 ++++++++ src/javascript/lib/core/functions.js | 8 ++++ test/support/main.ex | 7 ++++ 7 files changed, 93 insertions(+), 18 deletions(-) diff --git a/lib/elixir_script/next/passes/translate/form.ex b/lib/elixir_script/next/passes/translate/form.ex index b049af01..195f2aa6 100644 --- a/lib/elixir_script/next/passes/translate/form.ex +++ b/lib/elixir_script/next/passes/translate/form.ex @@ -65,7 +65,7 @@ defmodule ElixirScript.Translate.Form do end def compile({:{}, _, elements}, state) do - ast = J.call_expression( + ast = J.new_expression( J.member_expression( J.member_expression( J.identifier("Bootstrap"), @@ -79,6 +79,15 @@ defmodule ElixirScript.Translate.Form do {ast, state} end + def compile({:&, _, [{:/, _, [{{:., _, [_module, _function]} = ast, [], []}, _]}]}, state) do + Remote.compile(ast, state) + end + + def compile({:&, _, [{:/, _, [{var, _, _}, _]}]}, state) do + ast = ElixirScript.Translate.Identifier.make_function_name(var) + {ast, state} + end + def compile({:%{}, _, _} = map, state) do ElixirScript.Translate.Forms.Map.compile(map, state) end @@ -213,6 +222,15 @@ defmodule ElixirScript.Translate.Form do {ast, state} end + def compile({function, _, []}, state) do + ast = J.call_expression( + ElixirScript.Translate.Forms.JS.call_property(), + [compile!(function, state)] + ) + + {ast, state} + end + def compile({function, _, params}, state) when is_list(params) do ast = J.call_expression( compile!(function, state), diff --git a/lib/elixir_script/next/passes/translate/forms/js.ex b/lib/elixir_script/next/passes/translate/forms/js.ex index 11250f99..49da8f7b 100644 --- a/lib/elixir_script/next/passes/translate/forms/js.ex +++ b/lib/elixir_script/next/passes/translate/forms/js.ex @@ -3,13 +3,26 @@ defmodule ElixirScript.Translate.Forms.JS do alias ESTree.Tools.Builder, as: J alias ElixirScript.Translate.Form + def call_property() do + J.member_expression( + J.member_expression( + J.identifier("Bootstrap"), + J.member_expression( + J.identifier("Core"), + J.identifier("Functions") + ) + ), + J.identifier("call_property") + ) + end + def global() do - Builder.member_expression( - Builder.member_expression( - Builder.identifier("Bootstrap"), - Builder.identifier("Core") + J.member_expression( + J.member_expression( + J.identifier("Bootstrap"), + J.identifier("Core") ), - Builder.identifier("global") + J.identifier("global") ) end @@ -41,7 +54,7 @@ defmodule ElixirScript.Translate.Forms.JS do {ast, state} end - defp do_translate({{:., _, [JS, :throw]}, _, [term]}, state) do + def compile({{:., _, [JS, :throw]}, _, [term]}, state) do ast = J.throw_statement( Form.compile!(term, state) ) @@ -49,7 +62,7 @@ defmodule ElixirScript.Translate.Forms.JS do {ast, state} end - defp do_translate({{:., _, [JS, :import]}, _, [term]}, state) do + def compile({{:., _, [JS, :import]}, _, [term]}, state) do ast = J.call_expression( J.identifier("import"), [Form.compile!(term, state)] @@ -58,7 +71,19 @@ defmodule ElixirScript.Translate.Forms.JS do {ast, state} end - defp do_translate({{:., _, [JS, function]}, _, params}, state) do + def compile({{:., _, [JS, function]}, _, []}, state) do + ast = J.call_expression( + call_property(), + [ + global(), + Form.compile!(to_string(function), state) + ] + ) + + {ast, state} + end + + def compile({{:., _, [JS, function]}, _, params}, state) do ast = J.call_expression( J.identifier(function), Enum.map(params, &Form.compile!(&1, state)) diff --git a/lib/elixir_script/next/passes/translate/forms/pattern.ex b/lib/elixir_script/next/passes/translate/forms/pattern.ex index d0f07d07..17f16e6d 100644 --- a/lib/elixir_script/next/passes/translate/forms/pattern.ex +++ b/lib/elixir_script/next/passes/translate/forms/pattern.ex @@ -109,6 +109,10 @@ defmodule ElixirScript.Translate.Forms.Pattern do process_pattern({:|, context, [head, tail]}, state) end + defp process_pattern({:%, _, [module, {:%{}, _, props}]}, state) do + process_pattern({:%{}, [], [__struct__: module] ++ props}, state) + end + defp process_pattern({:%{}, _, props}, state) do properties = Enum.map(props, fn({key, value}) -> {pattern, params} = process_pattern(value, state) @@ -152,11 +156,11 @@ defmodule ElixirScript.Translate.Forms.Pattern do { [PM.starts_with(prefix)], [Form.compile!(value, state)] } end - defp process_pattern({:=, _, [{name, _, _}, right]}, state) do + defp process_pattern({:=, _, [{name, _, _}, right]}, state) when not name in [:%, :{}, :^, :%{}, :<<>>] do unify(name, right, state) end - defp process_pattern({:=, _, [left, {name, _, _}]}, state) do + defp process_pattern({:=, _, [left, {name, _, _}]}, state) when not name in [:%, :{}, :^, :%{}, :<<>>] do unify(name, left, state) end diff --git a/lib/elixir_script/next/passes/translate/forms/try.ex b/lib/elixir_script/next/passes/translate/forms/try.ex index 4488e49c..2729e39f 100644 --- a/lib/elixir_script/next/passes/translate/forms/try.ex +++ b/lib/elixir_script/next/passes/translate/forms/try.ex @@ -2,7 +2,7 @@ defmodule ElixirScript.Translate.Forms.Try do @moduledoc false alias ESTree.Tools.Builder, as: JS alias ElixirScript.Translate.Clause - alias ElixirScript.Translate.Form + alias ElixirScript.Translate.{Form, Function} def compile(blocks, state) do try_block = Keyword.get(blocks, :do) @@ -92,12 +92,8 @@ defmodule ElixirScript.Translate.Forms.Try do end defp prepare_function_body(body, state) do - {ast, state} = body - |> List.wrap - |> Enum.map_reduce(state, &Form.compile(&1, &2)) + {ast, state} = Function.compile_block(body, state) - ast - |> List.flatten - |> Clause.return_last_statement + Clause.return_last_statement(ast) end end diff --git a/lib/elixir_script/next/passes/translate/function.ex b/lib/elixir_script/next/passes/translate/function.ex index ad5a5e6f..457a3df8 100644 --- a/lib/elixir_script/next/passes/translate/function.ex +++ b/lib/elixir_script/next/passes/translate/function.ex @@ -128,4 +128,21 @@ defmodule ElixirScript.Translate.Function do defp compile_clause({:->, _, [params, body]}, state) do compile_clause({[], params, [], body}, state) end + + def compile_block(block, state) do + ast = case block do + nil -> + J.identifier("null") + {:__block__, _, block_body} -> + {list, _} = Enum.map_reduce(block_body, state, &Form.compile(&1, &2)) + List.flatten(list) + b when is_list(b) -> + {list, _} = Enum.map_reduce(b, state, &Form.compile(&1, &2)) + List.flatten(list) + _ -> + Form.compile!(block, state) + end + + {ast, state} + end end diff --git a/src/javascript/lib/core/functions.js b/src/javascript/lib/core/functions.js index 9df6ba34..423f323a 100644 --- a/src/javascript/lib/core/functions.js +++ b/src/javascript/lib/core/functions.js @@ -23,6 +23,14 @@ function iterator_to_reducer(iterable, acc, fun) { } function call_property(item, property) { + if (!property) { + if (item instanceof Function) { + return item(); + } + + return item; + } + let prop = null; if ( diff --git a/test/support/main.ex b/test/support/main.ex index a18d3d90..66ec84e4 100644 --- a/test/support/main.ex +++ b/test/support/main.ex @@ -1,5 +1,12 @@ defmodule Main do def start(:normal, [callback]) do callback.("started") + user = %User{} + user.first + draw() + end + + defp draw() do + JS.console.log("Here") end end From 14412ca8bab60f91861fb1ef0ed04a85790a6629 Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Thu, 15 Jun 2017 19:42:51 -0500 Subject: [PATCH 124/418] Turned named functions into function declarations. Fixed bugs where assignment was in case and cond expressions --- lib/elixir_script/next/passes/translate/form.ex | 12 ++++++++++-- .../next/passes/translate/forms/match.ex | 16 +++++++++++++++- .../next/passes/translate/function.ex | 10 ++++------ 3 files changed, 29 insertions(+), 9 deletions(-) diff --git a/lib/elixir_script/next/passes/translate/form.ex b/lib/elixir_script/next/passes/translate/form.ex index 195f2aa6..e9db55c3 100644 --- a/lib/elixir_script/next/passes/translate/form.ex +++ b/lib/elixir_script/next/passes/translate/form.ex @@ -116,6 +116,15 @@ defmodule ElixirScript.Translate.Form do For.compile(ast, state) end + def compile({:case, _, [{:=, _, [left, _]} = match, [do: clauses]]}, state) do + {match_ast, state} = compile(match, state) + {case_ast, state} = compile({:case, [], [left, [do: clauses]]}, state) + + match_ast = List.wrap(match_ast) + + { match_ast ++ [case_ast], state } + end + def compile({:case, _, [condition, [do: clauses]]}, state) do func = J.call_expression( J.member_expression( @@ -135,10 +144,9 @@ defmodule ElixirScript.Translate.Form do def compile({:cond, _, [[do: clauses]]}, state) do processed_clauses = Enum.map(clauses, fn({:->, _, [clause, clause_body]}) -> - { translated_body, state } = Enum.map_reduce(List.wrap(clause_body), state, &compile(&1, &2)) + { translated_body, state } = ElixirScript.Translate.Function.compile_block(clause_body, state) translated_body = translated_body - |> List.flatten |> Clause.return_last_statement translated_body = J.arrow_function_expression([], [], J.block_statement(translated_body)) diff --git a/lib/elixir_script/next/passes/translate/forms/match.ex b/lib/elixir_script/next/passes/translate/forms/match.ex index 9dbd453c..6a2a8613 100644 --- a/lib/elixir_script/next/passes/translate/forms/match.ex +++ b/lib/elixir_script/next/passes/translate/forms/match.ex @@ -6,6 +6,13 @@ defmodule ElixirScript.Translate.Forms.Match do def compile({:=, _, [left, right]}, state) do { right_ast, state } = Form.compile(right, state) + {var_dec, right_ast} = case right_ast do + [variable_declaration, x] -> + {variable_declaration, x} + x -> + {nil, x} + end + { patterns, params, state } = Pattern.compile([left], state) declarator = J.variable_declarator( @@ -35,7 +42,14 @@ defmodule ElixirScript.Translate.Forms.Match do {:{}, _, _ } -> make_tuple_ref(array_pattern, params) _ -> - array_pattern + List.wrap(array_pattern) + end + + js_ast = case var_dec do + nil -> + js_ast + x -> + [x] ++ js_ast end { js_ast, state } diff --git a/lib/elixir_script/next/passes/translate/function.ex b/lib/elixir_script/next/passes/translate/function.ex index 457a3df8..1740164d 100644 --- a/lib/elixir_script/next/passes/translate/function.ex +++ b/lib/elixir_script/next/passes/translate/function.ex @@ -31,9 +31,8 @@ defmodule ElixirScript.Translate.Function do arg_matches_declaration = J.variable_declaration([arg_matches_declarator], :let) - declarator = J.variable_declarator( - ElixirScript.Translate.Identifier.make_function_name(name), - J.function_expression( + function_dec = J.function_declaration( + ElixirScript.Translate.Identifier.make_function_name(name), [J.rest_element(J.identifier("__function_args__"))], [], J.block_statement([ @@ -50,9 +49,8 @@ defmodule ElixirScript.Translate.Function do ) ]) ) - ) - { J.variable_declaration([declarator], :const), state } + { function_dec, state } end defp compile_clauses(clauses, state) do @@ -145,4 +143,4 @@ defmodule ElixirScript.Translate.Function do {ast, state} end -end +end \ No newline at end of file From 660cd718d408022593fcd578be9c6e51363a9603 Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Thu, 15 Jun 2017 20:59:29 -0500 Subject: [PATCH 125/418] Made it so variables defined in parameters work --- .../next/passes/find_used_functions.ex | 2 + .../next/passes/translate/form.ex | 62 +++++++++++++------ .../next/passes/translate/function.ex | 39 +++++++++++- 3 files changed, 82 insertions(+), 21 deletions(-) diff --git a/lib/elixir_script/next/passes/find_used_functions.ex b/lib/elixir_script/next/passes/find_used_functions.ex index a13c15e0..6285f446 100644 --- a/lib/elixir_script/next/passes/find_used_functions.ex +++ b/lib/elixir_script/next/passes/find_used_functions.ex @@ -129,6 +129,8 @@ defmodule ElixirScript.FindUsedFunctions do end defp walk({:%, _, [module, params]}, state) do + ModuleState.add_used(state.pid, module, {:__struct__, 0}) + ModuleState.add_used(state.pid, module, {:__struct__, 1}) walk(params, state) end diff --git a/lib/elixir_script/next/passes/translate/form.ex b/lib/elixir_script/next/passes/translate/form.ex index e9db55c3..f530e8cb 100644 --- a/lib/elixir_script/next/passes/translate/form.ex +++ b/lib/elixir_script/next/passes/translate/form.ex @@ -188,18 +188,8 @@ defmodule ElixirScript.Translate.Form do Try.compile(blocks, state) end - def compile({:fn, _, clauses}, state) do - {clauses_ast, _} = Enum.map_reduce(clauses, state, &Clause.compile(&1, &2)) - - ast = J.call_expression( - J.member_expression( - ElixirScript.Translate.Function.patterns_ast(), - J.identifier("defmatch") - ), - clauses_ast - ) - - {ast, state} + def compile({:fn, _, _} = ast, state) do + ElixirScript.Translate.Function.compile(ast, state) end def compile({{:., _, [JS, _]}, _, _} = ast, state) do @@ -212,22 +202,35 @@ defmodule ElixirScript.Translate.Form do def compile({:super, context, params}, state) when is_list(params) do {function_name, _} = Map.get(state, :function) + {var_decs, params} = compile_params(params, state) ast = J.call_expression( ElixirScript.Translate.Identifier.make_function_name(function_name), - Enum.map(params, &compile!(&1, state)) |> List.flatten + params ) - {ast, state} + case var_decs do + [] -> + {ast, state} + _ -> + {var_decs ++ List.wrap(ast), state} + end end def compile({var, _, params}, state) when is_list(params) and is_atom(var) do + {var_decs, params} = compile_params(params, state) + ast = J.call_expression( ElixirScript.Translate.Identifier.make_function_name(var), - Enum.map(params, &compile!(&1, state)) |> List.flatten + params ) - {ast, state} + case var_decs do + [] -> + {ast, state} + _ -> + {var_decs ++ List.wrap(ast), state} + end end def compile({function, _, []}, state) do @@ -240,17 +243,38 @@ defmodule ElixirScript.Translate.Form do end def compile({function, _, params}, state) when is_list(params) do + {var_decs, params} = compile_params(params, state) + ast = J.call_expression( compile!(function, state), - Enum.map(params, &compile!(&1, state)) |> List.flatten + params ) - {ast, state} + case var_decs do + [] -> + {ast, state} + _ -> + {var_decs ++ List.wrap(ast), state} + end end - def compile({var, _, _}, state) do + def compile({var, _, _} = ast, state) do var = Pattern.get_variable_name(to_string(var), state) { ElixirScript.Translate.Identifier.make_identifier(var), state } end + defp compile_params(params, state) do + {params, var_decs} = Enum.map_reduce(params, [], fn + ({:=, _, [left, _]} = ast, acc) -> + {ast, state} = compile(ast, state) + left = compile!(left, state) + + {left, acc ++ List.wrap(ast)} + (x, acc) -> + {compile!(x, state), acc} + end) + + {var_decs, params} + end + end diff --git a/lib/elixir_script/next/passes/translate/function.ex b/lib/elixir_script/next/passes/translate/function.ex index 1740164d..d50a0be9 100644 --- a/lib/elixir_script/next/passes/translate/function.ex +++ b/lib/elixir_script/next/passes/translate/function.ex @@ -20,7 +20,38 @@ defmodule ElixirScript.Translate.Function do ) end - def compile({{name, arity}, type, _, clauses}, state) do + def compile({:fn, _, clauses}, state) do + clauses = compile_clauses(clauses, state) + + arg_matches_declarator = J.variable_declarator( + J.identifier("__arg_matches__"), + J.identifier("null") + ) + + arg_matches_declaration = J.variable_declaration([arg_matches_declarator], :let) + + function_dec = J.arrow_function_expression( + [J.rest_element(J.identifier("__function_args__"))], + [], + J.block_statement([ + arg_matches_declaration, + clauses, + J.throw_statement( + J.call_expression( + J.member_expression( + patterns_ast(), + J.identifier("MatchError") + ), + [J.identifier("__function_args__")] + ) + ) + ]) + ) + + { function_dec, state } + end + + def compile({{name, arity}, _type, _, clauses}, state) do state = Map.put(state, :function, {name, arity}) clauses = compile_clauses(clauses, state) @@ -84,7 +115,11 @@ defmodule ElixirScript.Translate.Function do end defp compile_clause({ _, args, guards, body}, state) do - state = Map.put(state, :vars, %{}) + state = if !Map.has_key?(state, :vars) do + Map.put(state, :vars, %{}) + else + state + end {patterns, params, state} = Pattern.compile(args, state) guard = Clause.compile_guard(params, guards, state) From 50500776fcc4ccaf5538dad8bd26eb1e0ad47e9a Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Fri, 16 Jun 2017 23:10:59 -0500 Subject: [PATCH 126/418] Crawling protocol implementation functions to make sure to get used functions --- .../next/passes/find_used_functions.ex | 58 +++++++++++------ .../next/passes/find_used_modules.ex | 63 ++++++++++--------- .../next/passes/translate/forms/pattern.ex | 2 +- .../next/passes/translate/module.ex | 1 + test/support/main.ex | 7 --- 5 files changed, 76 insertions(+), 55 deletions(-) diff --git a/lib/elixir_script/next/passes/find_used_functions.ex b/lib/elixir_script/next/passes/find_used_functions.ex index 6285f446..e656a580 100644 --- a/lib/elixir_script/next/passes/find_used_functions.ex +++ b/lib/elixir_script/next/passes/find_used_functions.ex @@ -13,6 +13,14 @@ defmodule ElixirScript.FindUsedFunctions do module -> walk_module(module, pid) end) + + modules = ElixirScript.State.list_modules(pid) + Enum.each(modules, fn + {module, info} -> + if get_in(info, [:attributes, :protocol_impl]) do + walk_module(module, pid) + end + end) end defp walk_module(module, pid) do @@ -71,16 +79,7 @@ defmodule ElixirScript.FindUsedFunctions do end defp walk({ _, _args, _guards, body}, state) do - case body do - nil -> - nil - {:__block__, _, block_body} -> - Enum.map(block_body, &walk(&1, state)) - b when is_list(b) -> - Enum.map(b, &walk(&1, state)) - _ -> - walk(body, state) - end + walk_block(body, state) end defp walk({:->, _, [[{:when, _, params}], body ]}, state) do @@ -112,7 +111,7 @@ defmodule ElixirScript.FindUsedFunctions do end defp walk({:{}, _, elements}, state) do - Enum.each(elements, &walk(&1, state)) + walk(elements, state) end defp walk({:%{}, _, properties}, state) do @@ -148,10 +147,10 @@ defmodule ElixirScript.FindUsedFunctions do [into: expression, do: expression2] -> walk(expression, state) - walk(expression2, state) + walk_block(expression2, state) [do: expression] -> - walk(expression, state) + walk_block(expression, state) filter -> walk(filter, state) @@ -170,8 +169,15 @@ defmodule ElixirScript.FindUsedFunctions do end) end - defp walk({:receive, _context, _}, _state) do - nil + defp walk({:receive, _context, blocks}, state) do + do_block = Keyword.get(blocks, :do) + after_block = Keyword.get(blocks, :after, nil) + + walk_block(do_block, state) + + if after_block do + Enum.each(List.wrap(after_block), &walk(&1, state)) + end end defp walk({:try, _, [blocks]}, state) do @@ -181,7 +187,7 @@ defmodule ElixirScript.FindUsedFunctions do after_block = Keyword.get(blocks, :after, nil) else_block = Keyword.get(blocks, :else, nil) - Enum.each(List.wrap(try_block), &walk(&1, state)) + walk_block(try_block, state) if rescue_block do Enum.each(rescue_block, fn @@ -240,15 +246,29 @@ defmodule ElixirScript.FindUsedFunctions do defp walk({function, _, params}, state) when is_atom(function) and is_list(params) do walk_module(state.module, function, length(params), state.pid) - Enum.each(params, &walk(&1, state)) + walk(params, state) end - defp walk({_, _, params}, state) when is_list(params) do - Enum.each(params, &walk(&1, state)) + defp walk({value, _, params}, state) when is_list(params) do + walk(value, state) + walk(params, state) end defp walk(_, _) do nil end + defp walk_block(block, state) do + case block do + nil -> + nil + {:__block__, _, block_body} -> + Enum.each(block_body, &walk(&1, state)) + b when is_list(b) -> + Enum.each(b, &walk(&1, state)) + _ -> + walk(block, state) + end + end + end \ No newline at end of file diff --git a/lib/elixir_script/next/passes/find_used_modules.ex b/lib/elixir_script/next/passes/find_used_modules.ex index e68ca080..bbb70cfd 100644 --- a/lib/elixir_script/next/passes/find_used_modules.ex +++ b/lib/elixir_script/next/passes/find_used_modules.ex @@ -68,7 +68,7 @@ defmodule ElixirScript.FindUsedModules do Enum.each(implementations, fn {impl, info} -> walk_module(impl, info, pid) - end) + end) end defp walk({{_name, _arity}, _type, _, clauses}, state) do @@ -76,16 +76,7 @@ defmodule ElixirScript.FindUsedModules do end defp walk({ _, _args, _guards, body}, state) do - case body do - nil -> - nil - {:__block__, _, block_body} -> - Enum.map(block_body, &walk(&1, state)) - b when is_list(b) -> - Enum.map(b, &walk(&1, state)) - _ -> - walk(body, state) - end + walk_block(body, state) end defp walk({:->, _, [[{:when, _, params}], body ]}, state) do @@ -165,10 +156,10 @@ defmodule ElixirScript.FindUsedModules do [into: expression, do: expression2] -> walk(expression, state) - walk(expression2, state) + walk_block(expression2, state) [do: expression] -> - walk(expression, state) + walk_block(expression, state) filter -> walk(filter, state) @@ -187,8 +178,15 @@ defmodule ElixirScript.FindUsedModules do end) end - defp walk({:receive, _context, _}, _state) do - nil + defp walk({:receive, _context, blocks}, state) do + do_block = Keyword.get(blocks, :do) + after_block = Keyword.get(blocks, :after, nil) + + walk_block(do_block, state) + + if after_block do + Enum.each(List.wrap(after_block), &walk(&1, state)) + end end defp walk({:try, _, [blocks]}, state) do @@ -198,7 +196,7 @@ defmodule ElixirScript.FindUsedModules do after_block = Keyword.get(blocks, :after, nil) else_block = Keyword.get(blocks, :else, nil) - Enum.each(List.wrap(try_block), &walk(&1, state)) + walk_block(try_block, state) if rescue_block do Enum.each(rescue_block, fn @@ -234,11 +232,11 @@ defmodule ElixirScript.FindUsedModules do walk({function, [], params}, state) end - defp walk({{:., _, [JS, _]}, _, params}, state) do - walk(params, state) + defp walk({:., _, [JS, _]}, state) do + nil end - defp walk({{:., _, [module, function]}, _, params}, state) do + defp walk({:., _, [module, function]}, state) do cond do ElixirScript.Translate.Module.is_js_module(module, state) -> nil @@ -247,26 +245,35 @@ defmodule ElixirScript.FindUsedModules do execute(module, state.pid) end true -> - nil + walk(module, state) + walk(function, state) end - - walk(params, state) end defp walk({:super, _, params}, state) do walk(params, state) end - defp walk({function, _, params}, state) when is_atom(function) and is_list(params) do - Enum.each(params, &walk(&1, state)) - end - - defp walk({_, _, params}, state) when is_list(params) do - Enum.each(params, &walk(&1, state)) + defp walk({function, _, params}, state) when is_list(params) do + walk(function, state) + walk(params, state) end defp walk(_, _) do nil end + defp walk_block(block, state) do + case block do + nil -> + nil + {:__block__, _, block_body} -> + Enum.each(block_body, &walk(&1, state)) + b when is_list(b) -> + Enum.each(b, &walk(&1, state)) + _ -> + walk(block, state) + end + end + end \ No newline at end of file diff --git a/lib/elixir_script/next/passes/translate/forms/pattern.ex b/lib/elixir_script/next/passes/translate/forms/pattern.ex index 17f16e6d..803a725c 100644 --- a/lib/elixir_script/next/passes/translate/forms/pattern.ex +++ b/lib/elixir_script/next/passes/translate/forms/pattern.ex @@ -55,7 +55,7 @@ defmodule ElixirScript.Translate.Forms.Pattern do end defp process_pattern({:^, _, [value]}, state) do - { [PM.bound(Form.compile!(value, state))], [nil] } + { [PM.bound(Form.compile!(value, state))], [] } end defp process_pattern({:_, _, _}, _) do diff --git a/lib/elixir_script/next/passes/translate/module.ex b/lib/elixir_script/next/passes/translate/module.ex index 68e2388d..7dda9eae 100644 --- a/lib/elixir_script/next/passes/translate/module.ex +++ b/lib/elixir_script/next/passes/translate/module.ex @@ -44,6 +44,7 @@ defmodule ElixirScript.Translate.Module do else Enum.filter(reachable_defs, fn { {:start, 2}, _, _, _ } -> true + { {:__struct__, _}, _, _, _ } -> true { name, _, _, _} -> name in used _ -> false end) diff --git a/test/support/main.ex b/test/support/main.ex index 66ec84e4..a18d3d90 100644 --- a/test/support/main.ex +++ b/test/support/main.ex @@ -1,12 +1,5 @@ defmodule Main do def start(:normal, [callback]) do callback.("started") - user = %User{} - user.first - draw() - end - - defp draw() do - JS.console.log("Here") end end From 62306b7774a6902c19dc71d29f40b04249ab61f4 Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Thu, 22 Jun 2017 21:53:53 -0500 Subject: [PATCH 127/418] Updated pattern matching library and erlang types library --- .tool-versions | 2 +- .../next/passes/translate/forms/pattern.ex | 44 +- .../next/passes/translate/function.ex | 4 +- .../next/passes/translate/module.ex | 18 +- package.json | 6 +- rollup.config.js | 2 +- src/javascript/lib/core/protocol.js | 28 +- test/support/main.ex | 1 + yarn.lock | 755 +++++++++--------- 9 files changed, 452 insertions(+), 408 deletions(-) diff --git a/.tool-versions b/.tool-versions index e84347ce..3f0ad299 100644 --- a/.tool-versions +++ b/.tool-versions @@ -1,3 +1,3 @@ -erlang ref-OTP-20.0-rc2 +erlang 20.0 elixir ref-d19a92b nodejs 8.1.0 \ No newline at end of file diff --git a/lib/elixir_script/next/passes/translate/forms/pattern.ex b/lib/elixir_script/next/passes/translate/forms/pattern.ex index 803a725c..14e4f4f9 100644 --- a/lib/elixir_script/next/passes/translate/forms/pattern.ex +++ b/lib/elixir_script/next/passes/translate/forms/pattern.ex @@ -59,7 +59,7 @@ defmodule ElixirScript.Translate.Forms.Pattern do end defp process_pattern({:_, _, _}, _) do - { [PM.wildcard()], [J.identifier(:_)] } + { [PM.parameter()], [J.identifier(:_)] } end defp process_pattern({a, b}, state) do @@ -110,20 +110,40 @@ defmodule ElixirScript.Translate.Forms.Pattern do end defp process_pattern({:%, _, [module, {:%{}, _, props}]}, state) do - process_pattern({:%{}, [], [__struct__: module] ++ props}, state) + process_pattern({:%{}, [], [__module__struct__: module] ++ props}, state) end defp process_pattern({:%{}, _, props}, state) do - properties = Enum.map(props, fn({key, value}) -> - {pattern, params} = process_pattern(value, state) - property = case key do - {:^, _, [the_key]} -> - J.property(Form.compile!(the_key, state), hd(List.wrap(pattern)), :init, false, false, true) - _ -> - ElixirScript.Translate.Forms.Map.make_property(Form.compile!(key, state), hd(List.wrap(pattern))) - end - - { property, params } + properties = Enum.map(props, fn + {:__module__struct__, module} -> + a = J.object_expression([%ESTree.Property{ + key: J.identifier("__MODULE__"), + value: J.call_expression( + J.member_expression( + J.identifier("Symbol"), + J.identifier("for") + ), + [J.literal(to_string(module))] + ) + }]) + + property = ElixirScript.Translate.Forms.Map.make_property( + Form.compile!(:__struct__, state), + a + ) + + { property, [] } + + {key, value} -> + {pattern, params} = process_pattern(value, state) + property = case key do + {:^, _, [the_key]} -> + J.property(Form.compile!(the_key, state), hd(List.wrap(pattern)), :init, false, false, true) + _ -> + ElixirScript.Translate.Forms.Map.make_property(Form.compile!(key, state), hd(List.wrap(pattern))) + end + + { property, params } end) {props, params} = Enum.reduce(properties, {[], []}, fn({prop, param}, {props, params}) -> diff --git a/lib/elixir_script/next/passes/translate/function.ex b/lib/elixir_script/next/passes/translate/function.ex index d50a0be9..ba6e1fc1 100644 --- a/lib/elixir_script/next/passes/translate/function.ex +++ b/lib/elixir_script/next/passes/translate/function.ex @@ -37,7 +37,7 @@ defmodule ElixirScript.Translate.Function do arg_matches_declaration, clauses, J.throw_statement( - J.call_expression( + J.new_expression( J.member_expression( patterns_ast(), J.identifier("MatchError") @@ -70,7 +70,7 @@ defmodule ElixirScript.Translate.Function do arg_matches_declaration, clauses, J.throw_statement( - J.call_expression( + J.new_expression( J.member_expression( patterns_ast(), J.identifier("MatchError") diff --git a/lib/elixir_script/next/passes/translate/module.ex b/lib/elixir_script/next/passes/translate/module.ex index 7dda9eae..9f716f80 100644 --- a/lib/elixir_script/next/passes/translate/module.ex +++ b/lib/elixir_script/next/passes/translate/module.ex @@ -52,7 +52,7 @@ defmodule ElixirScript.Translate.Module do #we combine our function arities combined_defs = combine_defs(used_defs) - exports = make_exports(combined_defs) + exports = make_exports(module, combined_defs) # Don't skip compilation and output of modules that don't have # any public functions @@ -85,7 +85,7 @@ defmodule ElixirScript.Translate.Module do end) end - defp make_exports(reachable_defs) do + defp make_exports(module, reachable_defs) do exports = Enum.reduce(reachable_defs, [], fn {{name, arity}, :def, _, _}, list -> function_name = ElixirScript.Translate.Identifier.make_identifier(name) @@ -96,10 +96,16 @@ defmodule ElixirScript.Translate.Module do # Add an attribute to use to determine if this is a module # Will be used by the is_atom implementation - exports ++ [ElixirScript.Translate.Forms.Map.make_property( - Form.compile!("__MODULE__", %{}), - Form.compile!(true, %{}) - )] + exports = exports ++ [%ESTree.Property{ + key: J.identifier("__MODULE__"), + value: J.call_expression( + J.member_expression( + J.identifier("Symbol"), + J.identifier("for") + ), + [J.literal(to_string(module))] + ) + }] J.object_expression(exports) end diff --git a/package.json b/package.json index 55cc3f34..23da045b 100644 --- a/package.json +++ b/package.json @@ -22,8 +22,8 @@ "author": "", "license": "MIT", "dependencies": { - "erlang-types": "^1.0.0", - "tailored": "2.4.5" + "erlang-types": "^1.0.1", + "tailored": "^2.4.6" }, "devDependencies": { "ava": "^0.19.1", @@ -48,4 +48,4 @@ "babelrc": true } } -} \ No newline at end of file +} diff --git a/rollup.config.js b/rollup.config.js index a318efdf..c06836ac 100644 --- a/rollup.config.js +++ b/rollup.config.js @@ -10,7 +10,7 @@ export default { babel({ babelrc: false, }), - babili({}), + //babili({}), ], targets: [{ dest: 'priv/build/iife/Elixir.Bootstrap.js', format: 'iife' }], }; diff --git a/src/javascript/lib/core/protocol.js b/src/javascript/lib/core/protocol.js index 02fb4f08..5ae04ddf 100644 --- a/src/javascript/lib/core/protocol.js +++ b/src/javascript/lib/core/protocol.js @@ -11,7 +11,12 @@ class Protocol { const thing = args[0]; let fun = null; - if (Number.isInteger(thing) && this.hasImplementation(Core.Integer)) { + if (thing === null && this.hasImplementation(Symbol('null'))) { + fun = this.registry.get(Symbol)[funName]; + } else if ( + Number.isInteger(thing) && + this.hasImplementation(Core.Integer) + ) { fun = this.registry.get(Core.Integer)[funName]; } else if ( typeof thing === 'number' && @@ -20,14 +25,19 @@ class Protocol { ) { fun = this.registry.get(Core.Float)[funName]; } else if ( - typeof thing === 'string' && this.hasImplementation(Core.BitString) + typeof thing === 'string' && + this.hasImplementation(Core.BitString) ) { fun = this.registry.get(Core.BitString)[funName]; } else if ( - thing[Symbol.for('__struct__')] && this.hasImplementation(thing) + thing && + thing[Symbol.for('__struct__')] && + this.hasImplementation(thing) ) { - fun = this.registry.get(thing[Symbol.for('__struct__')])[funName]; - } else if (this.hasImplementation(thing)) { + fun = this.registry.get(thing[Symbol.for('__struct__')].__MODULE__)[ + funName + ]; + } else if (thing !== null && this.hasImplementation(thing)) { fun = this.registry.get(thing.constructor)[funName]; } else if (this.fallback) { fun = this.fallback[funName]; @@ -57,11 +67,13 @@ class Protocol { hasImplementation(thing) { if ( - thing === Core.Integer || thing === Core.Float || thing === Core.BitString + thing === Core.Integer || + thing === Core.Float || + thing === Core.BitString ) { return this.registry.has(thing); - } else if (thing[Symbol.for('__struct__')]) { - return this.registry.has(thing[Symbol.for('__struct__')]); + } else if (thing && thing[Symbol.for('__struct__')]) { + return this.registry.has(thing[Symbol.for('__struct__')].__MODULE__); } return this.registry.has(thing.constructor); diff --git a/test/support/main.ex b/test/support/main.ex index a18d3d90..c37a6f0e 100644 --- a/test/support/main.ex +++ b/test/support/main.ex @@ -1,5 +1,6 @@ defmodule Main do def start(:normal, [callback]) do callback.("started") + Enum.each(1..5, fn(x) -> JS.console.log(x) end) end end diff --git a/yarn.lock b/yarn.lock index c96129c7..7ceffecc 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7,8 +7,8 @@ resolved "https://registry.yarnpkg.com/@ava/babel-plugin-throws-helper/-/babel-plugin-throws-helper-2.0.0.tgz#2fc1fe3c211a71071a4eca7b8f7af5842cd1ae7c" "@ava/babel-preset-stage-4@^1.0.0": - version "1.0.0" - resolved "https://registry.yarnpkg.com/@ava/babel-preset-stage-4/-/babel-preset-stage-4-1.0.0.tgz#a613b5e152f529305422546b072d47facfb26291" + version "1.1.0" + resolved "https://registry.yarnpkg.com/@ava/babel-preset-stage-4/-/babel-preset-stage-4-1.1.0.tgz#ae60be881a0babf7d35f52aba770d1f6194f76bd" dependencies: babel-plugin-check-es2015-constants "^6.8.0" babel-plugin-syntax-trailing-function-commas "^6.20.0" @@ -64,8 +64,8 @@ ajv-keywords@^1.0.0: resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-1.5.1.tgz#314dd0a4b3368fad3dfcdc54ede6171b886daf3c" ajv@^4.7.0, ajv@^4.9.1: - version "4.11.5" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-4.11.5.tgz#b6ee74657b993a01dce44b7944d56f485828d5bd" + version "4.11.8" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-4.11.8.tgz#82ffb02b29e662ae53bdc20af15947706739c536" dependencies: co "^4.6.0" json-stable-stringify "^1.0.1" @@ -101,8 +101,8 @@ ansi-styles@^2.2.1: resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe" ansi-styles@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.0.0.tgz#5404e93a544c4fec7f048262977bebfe3155e0c1" + version "3.1.0" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.1.0.tgz#09c202d5c917ec23188caa5c9cb9179cd9547750" dependencies: color-convert "^1.0.0" @@ -124,8 +124,8 @@ append-transform@^0.4.0: default-require-extensions "^1.0.0" aproba@^1.0.3: - version "1.1.1" - resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.1.1.tgz#95d3600f07710aa0e9298c726ad5ecf2eacbabab" + version "1.1.2" + resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.1.2.tgz#45c6629094de4e96f693ef7eab74ae079c240fc1" archy@^1.0.0: version "1.0.0" @@ -321,20 +321,20 @@ babel-code-frame@^6.16.0, babel-code-frame@^6.22.0: esutils "^2.0.2" js-tokens "^3.0.0" -babel-core@6, babel-core@^6.17.0, babel-core@^6.21.0, babel-core@^6.24.0: - version "6.24.0" - resolved "https://registry.yarnpkg.com/babel-core/-/babel-core-6.24.0.tgz#8f36a0a77f5c155aed6f920b844d23ba56742a02" +babel-core@6, babel-core@^6.17.0, babel-core@^6.21.0, babel-core@^6.24.0, babel-core@^6.24.1: + version "6.25.0" + resolved "https://registry.yarnpkg.com/babel-core/-/babel-core-6.25.0.tgz#7dd42b0463c742e9d5296deb3ec67a9322dad729" dependencies: babel-code-frame "^6.22.0" - babel-generator "^6.24.0" - babel-helpers "^6.23.0" + babel-generator "^6.25.0" + babel-helpers "^6.24.1" babel-messages "^6.23.0" - babel-register "^6.24.0" + babel-register "^6.24.1" babel-runtime "^6.22.0" - babel-template "^6.23.0" - babel-traverse "^6.23.1" - babel-types "^6.23.0" - babylon "^6.11.0" + babel-template "^6.25.0" + babel-traverse "^6.25.0" + babel-types "^6.25.0" + babylon "^6.17.2" convert-source-map "^1.1.0" debug "^2.1.1" json5 "^0.5.0" @@ -345,84 +345,84 @@ babel-core@6, babel-core@^6.17.0, babel-core@^6.21.0, babel-core@^6.24.0: slash "^1.0.0" source-map "^0.5.0" -babel-generator@^6.1.0, babel-generator@^6.18.0, babel-generator@^6.24.0: - version "6.24.0" - resolved "https://registry.yarnpkg.com/babel-generator/-/babel-generator-6.24.0.tgz#eba270a8cc4ce6e09a61be43465d7c62c1f87c56" +babel-generator@^6.1.0, babel-generator@^6.18.0, babel-generator@^6.25.0: + version "6.25.0" + resolved "https://registry.yarnpkg.com/babel-generator/-/babel-generator-6.25.0.tgz#33a1af70d5f2890aeb465a4a7793c1df6a9ea9fc" dependencies: babel-messages "^6.23.0" babel-runtime "^6.22.0" - babel-types "^6.23.0" + babel-types "^6.25.0" detect-indent "^4.0.0" jsesc "^1.3.0" lodash "^4.2.0" source-map "^0.5.0" trim-right "^1.0.1" -babel-helper-builder-binary-assignment-operator-visitor@^6.22.0: - version "6.22.0" - resolved "https://registry.yarnpkg.com/babel-helper-builder-binary-assignment-operator-visitor/-/babel-helper-builder-binary-assignment-operator-visitor-6.22.0.tgz#29df56be144d81bdeac08262bfa41d2c5e91cdcd" +babel-helper-builder-binary-assignment-operator-visitor@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-builder-binary-assignment-operator-visitor/-/babel-helper-builder-binary-assignment-operator-visitor-6.24.1.tgz#cce4517ada356f4220bcae8a02c2b346f9a56664" dependencies: - babel-helper-explode-assignable-expression "^6.22.0" + babel-helper-explode-assignable-expression "^6.24.1" babel-runtime "^6.22.0" - babel-types "^6.22.0" + babel-types "^6.24.1" -babel-helper-call-delegate@^6.22.0: - version "6.22.0" - resolved "https://registry.yarnpkg.com/babel-helper-call-delegate/-/babel-helper-call-delegate-6.22.0.tgz#119921b56120f17e9dae3f74b4f5cc7bcc1b37ef" +babel-helper-call-delegate@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-call-delegate/-/babel-helper-call-delegate-6.24.1.tgz#ece6aacddc76e41c3461f88bfc575bd0daa2df8d" dependencies: - babel-helper-hoist-variables "^6.22.0" + babel-helper-hoist-variables "^6.24.1" babel-runtime "^6.22.0" - babel-traverse "^6.22.0" - babel-types "^6.22.0" + babel-traverse "^6.24.1" + babel-types "^6.24.1" -babel-helper-define-map@^6.23.0: - version "6.23.0" - resolved "https://registry.yarnpkg.com/babel-helper-define-map/-/babel-helper-define-map-6.23.0.tgz#1444f960c9691d69a2ced6a205315f8fd00804e7" +babel-helper-define-map@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-define-map/-/babel-helper-define-map-6.24.1.tgz#7a9747f258d8947d32d515f6aa1c7bd02204a080" dependencies: - babel-helper-function-name "^6.23.0" + babel-helper-function-name "^6.24.1" babel-runtime "^6.22.0" - babel-types "^6.23.0" + babel-types "^6.24.1" lodash "^4.2.0" babel-helper-evaluate-path@^0.0.3: version "0.0.3" resolved "https://registry.yarnpkg.com/babel-helper-evaluate-path/-/babel-helper-evaluate-path-0.0.3.tgz#1d103ac9d4a59e5d431842212f151785f7ac547b" -babel-helper-explode-assignable-expression@^6.22.0: - version "6.22.0" - resolved "https://registry.yarnpkg.com/babel-helper-explode-assignable-expression/-/babel-helper-explode-assignable-expression-6.22.0.tgz#c97bf76eed3e0bae4048121f2b9dae1a4e7d0478" +babel-helper-explode-assignable-expression@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-explode-assignable-expression/-/babel-helper-explode-assignable-expression-6.24.1.tgz#f25b82cf7dc10433c55f70592d5746400ac22caa" dependencies: babel-runtime "^6.22.0" - babel-traverse "^6.22.0" - babel-types "^6.22.0" + babel-traverse "^6.24.1" + babel-types "^6.24.1" babel-helper-flip-expressions@^0.0.2: version "0.0.2" resolved "https://registry.yarnpkg.com/babel-helper-flip-expressions/-/babel-helper-flip-expressions-0.0.2.tgz#7bab2cf61162bc92703e9b298ef512bcf77d6787" -babel-helper-function-name@^6.22.0, babel-helper-function-name@^6.23.0: - version "6.23.0" - resolved "https://registry.yarnpkg.com/babel-helper-function-name/-/babel-helper-function-name-6.23.0.tgz#25742d67175c8903dbe4b6cb9d9e1fcb8dcf23a6" +babel-helper-function-name@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-function-name/-/babel-helper-function-name-6.24.1.tgz#d3475b8c03ed98242a25b48351ab18399d3580a9" dependencies: - babel-helper-get-function-arity "^6.22.0" + babel-helper-get-function-arity "^6.24.1" babel-runtime "^6.22.0" - babel-template "^6.23.0" - babel-traverse "^6.23.0" - babel-types "^6.23.0" + babel-template "^6.24.1" + babel-traverse "^6.24.1" + babel-types "^6.24.1" -babel-helper-get-function-arity@^6.22.0: - version "6.22.0" - resolved "https://registry.yarnpkg.com/babel-helper-get-function-arity/-/babel-helper-get-function-arity-6.22.0.tgz#0beb464ad69dc7347410ac6ade9f03a50634f5ce" +babel-helper-get-function-arity@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-get-function-arity/-/babel-helper-get-function-arity-6.24.1.tgz#8f7782aa93407c41d3aa50908f89b031b1b6853d" dependencies: babel-runtime "^6.22.0" - babel-types "^6.22.0" + babel-types "^6.24.1" -babel-helper-hoist-variables@^6.22.0: - version "6.22.0" - resolved "https://registry.yarnpkg.com/babel-helper-hoist-variables/-/babel-helper-hoist-variables-6.22.0.tgz#3eacbf731d80705845dd2e9718f600cfb9b4ba72" +babel-helper-hoist-variables@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-hoist-variables/-/babel-helper-hoist-variables-6.24.1.tgz#1ecb27689c9d25513eadbc9914a73f5408be7a76" dependencies: babel-runtime "^6.22.0" - babel-types "^6.22.0" + babel-types "^6.24.1" babel-helper-is-nodes-equiv@^0.0.1: version "0.0.1" @@ -436,56 +436,60 @@ babel-helper-mark-eval-scopes@^0.0.3: version "0.0.3" resolved "https://registry.yarnpkg.com/babel-helper-mark-eval-scopes/-/babel-helper-mark-eval-scopes-0.0.3.tgz#902f75aeb537336edc35eb9f52b6f09db7785328" -babel-helper-optimise-call-expression@^6.23.0: - version "6.23.0" - resolved "https://registry.yarnpkg.com/babel-helper-optimise-call-expression/-/babel-helper-optimise-call-expression-6.23.0.tgz#f3ee7eed355b4282138b33d02b78369e470622f5" +babel-helper-mark-eval-scopes@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/babel-helper-mark-eval-scopes/-/babel-helper-mark-eval-scopes-0.1.1.tgz#4554345edf9f2549427bd2098e530253f8af2992" + +babel-helper-optimise-call-expression@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-optimise-call-expression/-/babel-helper-optimise-call-expression-6.24.1.tgz#f7a13427ba9f73f8f4fa993c54a97882d1244257" dependencies: babel-runtime "^6.22.0" - babel-types "^6.23.0" + babel-types "^6.24.1" -babel-helper-regex@^6.22.0: - version "6.22.0" - resolved "https://registry.yarnpkg.com/babel-helper-regex/-/babel-helper-regex-6.22.0.tgz#79f532be1647b1f0ee3474b5f5c3da58001d247d" +babel-helper-regex@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-regex/-/babel-helper-regex-6.24.1.tgz#d36e22fab1008d79d88648e32116868128456ce8" dependencies: babel-runtime "^6.22.0" - babel-types "^6.22.0" + babel-types "^6.24.1" lodash "^4.2.0" -babel-helper-remap-async-to-generator@^6.22.0: - version "6.22.0" - resolved "https://registry.yarnpkg.com/babel-helper-remap-async-to-generator/-/babel-helper-remap-async-to-generator-6.22.0.tgz#2186ae73278ed03b8b15ced089609da981053383" +babel-helper-remap-async-to-generator@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-remap-async-to-generator/-/babel-helper-remap-async-to-generator-6.24.1.tgz#5ec581827ad723fecdd381f1c928390676e4551b" dependencies: - babel-helper-function-name "^6.22.0" + babel-helper-function-name "^6.24.1" babel-runtime "^6.22.0" - babel-template "^6.22.0" - babel-traverse "^6.22.0" - babel-types "^6.22.0" + babel-template "^6.24.1" + babel-traverse "^6.24.1" + babel-types "^6.24.1" -babel-helper-remove-or-void@^0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/babel-helper-remove-or-void/-/babel-helper-remove-or-void-0.0.1.tgz#f602790e465acf2dfbe84fb3dd210c43a2dd7262" +babel-helper-remove-or-void@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/babel-helper-remove-or-void/-/babel-helper-remove-or-void-0.1.1.tgz#9d7e1856dc6fafcb41b283a416730dc1844f66d7" -babel-helper-replace-supers@^6.22.0, babel-helper-replace-supers@^6.23.0: - version "6.23.0" - resolved "https://registry.yarnpkg.com/babel-helper-replace-supers/-/babel-helper-replace-supers-6.23.0.tgz#eeaf8ad9b58ec4337ca94223bacdca1f8d9b4bfd" +babel-helper-replace-supers@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-replace-supers/-/babel-helper-replace-supers-6.24.1.tgz#bf6dbfe43938d17369a213ca8a8bf74b6a90ab1a" dependencies: - babel-helper-optimise-call-expression "^6.23.0" + babel-helper-optimise-call-expression "^6.24.1" babel-messages "^6.23.0" babel-runtime "^6.22.0" - babel-template "^6.23.0" - babel-traverse "^6.23.0" - babel-types "^6.23.0" + babel-template "^6.24.1" + babel-traverse "^6.24.1" + babel-types "^6.24.1" babel-helper-to-multiple-sequence-expressions@^0.0.4: version "0.0.4" resolved "https://registry.yarnpkg.com/babel-helper-to-multiple-sequence-expressions/-/babel-helper-to-multiple-sequence-expressions-0.0.4.tgz#d94414b386b6286fbaad77f073dea9b34324b01c" -babel-helpers@^6.23.0: - version "6.23.0" - resolved "https://registry.yarnpkg.com/babel-helpers/-/babel-helpers-6.23.0.tgz#4f8f2e092d0b6a8808a4bde79c27f1e2ecf0d992" +babel-helpers@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helpers/-/babel-helpers-6.24.1.tgz#3471de9caec388e5c850e597e58a26ddf37602b2" dependencies: babel-runtime "^6.22.0" - babel-template "^6.23.0" + babel-template "^6.24.1" babel-messages@^6.23.0: version "6.23.0" @@ -525,11 +529,11 @@ babel-plugin-minify-constant-folding@^0.0.4: jsesc "^2.4.0" babel-plugin-minify-dead-code-elimination@^0.1.4: - version "0.1.4" - resolved "https://registry.yarnpkg.com/babel-plugin-minify-dead-code-elimination/-/babel-plugin-minify-dead-code-elimination-0.1.4.tgz#18b6ecfab77c29caca061d8210fa3495001e4fa1" + version "0.1.7" + resolved "https://registry.yarnpkg.com/babel-plugin-minify-dead-code-elimination/-/babel-plugin-minify-dead-code-elimination-0.1.7.tgz#774f536f347b98393a27baa717872968813c342c" dependencies: - babel-helper-mark-eval-scopes "^0.0.3" - babel-helper-remove-or-void "^0.0.1" + babel-helper-mark-eval-scopes "^0.1.1" + babel-helper-remove-or-void "^0.1.1" lodash.some "^4.6.0" babel-plugin-minify-flip-comparisons@^0.0.2: @@ -589,10 +593,10 @@ babel-plugin-syntax-trailing-function-commas@^6.20.0, babel-plugin-syntax-traili resolved "https://registry.yarnpkg.com/babel-plugin-syntax-trailing-function-commas/-/babel-plugin-syntax-trailing-function-commas-6.22.0.tgz#ba0360937f8d06e40180a43fe0d5616fff532cf3" babel-plugin-transform-async-to-generator@^6.16.0, babel-plugin-transform-async-to-generator@^6.22.0: - version "6.22.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-async-to-generator/-/babel-plugin-transform-async-to-generator-6.22.0.tgz#194b6938ec195ad36efc4c33a971acf00d8cd35e" + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-async-to-generator/-/babel-plugin-transform-async-to-generator-6.24.1.tgz#6536e378aff6cb1d5517ac0e40eb3e9fc8d08761" dependencies: - babel-helper-remap-async-to-generator "^6.22.0" + babel-helper-remap-async-to-generator "^6.24.1" babel-plugin-syntax-async-functions "^6.8.0" babel-runtime "^6.22.0" @@ -609,35 +613,35 @@ babel-plugin-transform-es2015-block-scoped-functions@^6.22.0: babel-runtime "^6.22.0" babel-plugin-transform-es2015-block-scoping@^6.23.0: - version "6.23.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-block-scoping/-/babel-plugin-transform-es2015-block-scoping-6.23.0.tgz#e48895cf0b375be148cd7c8879b422707a053b51" + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-block-scoping/-/babel-plugin-transform-es2015-block-scoping-6.24.1.tgz#76c295dc3a4741b1665adfd3167215dcff32a576" dependencies: babel-runtime "^6.22.0" - babel-template "^6.23.0" - babel-traverse "^6.23.0" - babel-types "^6.23.0" + babel-template "^6.24.1" + babel-traverse "^6.24.1" + babel-types "^6.24.1" lodash "^4.2.0" babel-plugin-transform-es2015-classes@^6.23.0, babel-plugin-transform-es2015-classes@^6.9.0: - version "6.23.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-classes/-/babel-plugin-transform-es2015-classes-6.23.0.tgz#49b53f326202a2fd1b3bbaa5e2edd8a4f78643c1" + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-classes/-/babel-plugin-transform-es2015-classes-6.24.1.tgz#5a4c58a50c9c9461e564b4b2a3bfabc97a2584db" dependencies: - babel-helper-define-map "^6.23.0" - babel-helper-function-name "^6.23.0" - babel-helper-optimise-call-expression "^6.23.0" - babel-helper-replace-supers "^6.23.0" + babel-helper-define-map "^6.24.1" + babel-helper-function-name "^6.24.1" + babel-helper-optimise-call-expression "^6.24.1" + babel-helper-replace-supers "^6.24.1" babel-messages "^6.23.0" babel-runtime "^6.22.0" - babel-template "^6.23.0" - babel-traverse "^6.23.0" - babel-types "^6.23.0" + babel-template "^6.24.1" + babel-traverse "^6.24.1" + babel-types "^6.24.1" babel-plugin-transform-es2015-computed-properties@^6.22.0: - version "6.22.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-computed-properties/-/babel-plugin-transform-es2015-computed-properties-6.22.0.tgz#7c383e9629bba4820c11b0425bdd6290f7f057e7" + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-computed-properties/-/babel-plugin-transform-es2015-computed-properties-6.24.1.tgz#6fe2a8d16895d5634f4cd999b6d3480a308159b3" dependencies: babel-runtime "^6.22.0" - babel-template "^6.22.0" + babel-template "^6.24.1" babel-plugin-transform-es2015-destructuring@^6.19.0, babel-plugin-transform-es2015-destructuring@^6.23.0: version "6.23.0" @@ -646,11 +650,11 @@ babel-plugin-transform-es2015-destructuring@^6.19.0, babel-plugin-transform-es20 babel-runtime "^6.22.0" babel-plugin-transform-es2015-duplicate-keys@^6.22.0: - version "6.22.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-duplicate-keys/-/babel-plugin-transform-es2015-duplicate-keys-6.22.0.tgz#672397031c21610d72dd2bbb0ba9fb6277e1c36b" + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-duplicate-keys/-/babel-plugin-transform-es2015-duplicate-keys-6.24.1.tgz#73eb3d310ca969e3ef9ec91c53741a6f1576423e" dependencies: babel-runtime "^6.22.0" - babel-types "^6.22.0" + babel-types "^6.24.1" babel-plugin-transform-es2015-for-of@^6.23.0: version "6.23.0" @@ -659,12 +663,12 @@ babel-plugin-transform-es2015-for-of@^6.23.0: babel-runtime "^6.22.0" babel-plugin-transform-es2015-function-name@^6.22.0, babel-plugin-transform-es2015-function-name@^6.9.0: - version "6.22.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-function-name/-/babel-plugin-transform-es2015-function-name-6.22.0.tgz#f5fcc8b09093f9a23c76ac3d9e392c3ec4b77104" + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-function-name/-/babel-plugin-transform-es2015-function-name-6.24.1.tgz#834c89853bc36b1af0f3a4c5dbaa94fd8eacaa8b" dependencies: - babel-helper-function-name "^6.22.0" + babel-helper-function-name "^6.24.1" babel-runtime "^6.22.0" - babel-types "^6.22.0" + babel-types "^6.24.1" babel-plugin-transform-es2015-literals@^6.22.0: version "6.22.0" @@ -672,63 +676,63 @@ babel-plugin-transform-es2015-literals@^6.22.0: dependencies: babel-runtime "^6.22.0" -babel-plugin-transform-es2015-modules-amd@^6.22.0, babel-plugin-transform-es2015-modules-amd@^6.24.0: - version "6.24.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-amd/-/babel-plugin-transform-es2015-modules-amd-6.24.0.tgz#a1911fb9b7ec7e05a43a63c5995007557bcf6a2e" +babel-plugin-transform-es2015-modules-amd@^6.22.0, babel-plugin-transform-es2015-modules-amd@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-amd/-/babel-plugin-transform-es2015-modules-amd-6.24.1.tgz#3b3e54017239842d6d19c3011c4bd2f00a00d154" dependencies: - babel-plugin-transform-es2015-modules-commonjs "^6.24.0" + babel-plugin-transform-es2015-modules-commonjs "^6.24.1" babel-runtime "^6.22.0" - babel-template "^6.22.0" + babel-template "^6.24.1" -babel-plugin-transform-es2015-modules-commonjs@^6.18.0, babel-plugin-transform-es2015-modules-commonjs@^6.23.0, babel-plugin-transform-es2015-modules-commonjs@^6.24.0: - version "6.24.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-commonjs/-/babel-plugin-transform-es2015-modules-commonjs-6.24.0.tgz#e921aefb72c2cc26cb03d107626156413222134f" +babel-plugin-transform-es2015-modules-commonjs@^6.18.0, babel-plugin-transform-es2015-modules-commonjs@^6.23.0, babel-plugin-transform-es2015-modules-commonjs@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-commonjs/-/babel-plugin-transform-es2015-modules-commonjs-6.24.1.tgz#d3e310b40ef664a36622200097c6d440298f2bfe" dependencies: - babel-plugin-transform-strict-mode "^6.22.0" + babel-plugin-transform-strict-mode "^6.24.1" babel-runtime "^6.22.0" - babel-template "^6.23.0" - babel-types "^6.23.0" + babel-template "^6.24.1" + babel-types "^6.24.1" babel-plugin-transform-es2015-modules-systemjs@^6.23.0: - version "6.23.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-systemjs/-/babel-plugin-transform-es2015-modules-systemjs-6.23.0.tgz#ae3469227ffac39b0310d90fec73bfdc4f6317b0" + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-systemjs/-/babel-plugin-transform-es2015-modules-systemjs-6.24.1.tgz#ff89a142b9119a906195f5f106ecf305d9407d23" dependencies: - babel-helper-hoist-variables "^6.22.0" + babel-helper-hoist-variables "^6.24.1" babel-runtime "^6.22.0" - babel-template "^6.23.0" + babel-template "^6.24.1" babel-plugin-transform-es2015-modules-umd@^6.23.0: - version "6.24.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-umd/-/babel-plugin-transform-es2015-modules-umd-6.24.0.tgz#fd5fa63521cae8d273927c3958afd7c067733450" + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-umd/-/babel-plugin-transform-es2015-modules-umd-6.24.1.tgz#ac997e6285cd18ed6176adb607d602344ad38468" dependencies: - babel-plugin-transform-es2015-modules-amd "^6.24.0" + babel-plugin-transform-es2015-modules-amd "^6.24.1" babel-runtime "^6.22.0" - babel-template "^6.23.0" + babel-template "^6.24.1" babel-plugin-transform-es2015-object-super@^6.22.0: - version "6.22.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-object-super/-/babel-plugin-transform-es2015-object-super-6.22.0.tgz#daa60e114a042ea769dd53fe528fc82311eb98fc" + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-object-super/-/babel-plugin-transform-es2015-object-super-6.24.1.tgz#24cef69ae21cb83a7f8603dad021f572eb278f8d" dependencies: - babel-helper-replace-supers "^6.22.0" + babel-helper-replace-supers "^6.24.1" babel-runtime "^6.22.0" babel-plugin-transform-es2015-parameters@^6.21.0, babel-plugin-transform-es2015-parameters@^6.23.0: - version "6.23.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-parameters/-/babel-plugin-transform-es2015-parameters-6.23.0.tgz#3a2aabb70c8af945d5ce386f1a4250625a83ae3b" + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-parameters/-/babel-plugin-transform-es2015-parameters-6.24.1.tgz#57ac351ab49caf14a97cd13b09f66fdf0a625f2b" dependencies: - babel-helper-call-delegate "^6.22.0" - babel-helper-get-function-arity "^6.22.0" + babel-helper-call-delegate "^6.24.1" + babel-helper-get-function-arity "^6.24.1" babel-runtime "^6.22.0" - babel-template "^6.23.0" - babel-traverse "^6.23.0" - babel-types "^6.23.0" + babel-template "^6.24.1" + babel-traverse "^6.24.1" + babel-types "^6.24.1" babel-plugin-transform-es2015-shorthand-properties@^6.22.0: - version "6.22.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-shorthand-properties/-/babel-plugin-transform-es2015-shorthand-properties-6.22.0.tgz#8ba776e0affaa60bff21e921403b8a652a2ff723" + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-shorthand-properties/-/babel-plugin-transform-es2015-shorthand-properties-6.24.1.tgz#24f875d6721c87661bbd99a4622e51f14de38aa0" dependencies: babel-runtime "^6.22.0" - babel-types "^6.22.0" + babel-types "^6.24.1" babel-plugin-transform-es2015-spread@^6.22.0, babel-plugin-transform-es2015-spread@^6.8.0: version "6.22.0" @@ -737,12 +741,12 @@ babel-plugin-transform-es2015-spread@^6.22.0, babel-plugin-transform-es2015-spre babel-runtime "^6.22.0" babel-plugin-transform-es2015-sticky-regex@^6.22.0, babel-plugin-transform-es2015-sticky-regex@^6.8.0: - version "6.22.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-sticky-regex/-/babel-plugin-transform-es2015-sticky-regex-6.22.0.tgz#ab316829e866ee3f4b9eb96939757d19a5bc4593" + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-sticky-regex/-/babel-plugin-transform-es2015-sticky-regex-6.24.1.tgz#00c1cdb1aca71112cdf0cf6126c2ed6b457ccdbc" dependencies: - babel-helper-regex "^6.22.0" + babel-helper-regex "^6.24.1" babel-runtime "^6.22.0" - babel-types "^6.22.0" + babel-types "^6.24.1" babel-plugin-transform-es2015-template-literals@^6.22.0: version "6.22.0" @@ -757,18 +761,18 @@ babel-plugin-transform-es2015-typeof-symbol@^6.23.0: babel-runtime "^6.22.0" babel-plugin-transform-es2015-unicode-regex@^6.11.0, babel-plugin-transform-es2015-unicode-regex@^6.22.0: - version "6.22.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-unicode-regex/-/babel-plugin-transform-es2015-unicode-regex-6.22.0.tgz#8d9cc27e7ee1decfe65454fb986452a04a613d20" + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-unicode-regex/-/babel-plugin-transform-es2015-unicode-regex-6.24.1.tgz#d38b12f42ea7323f729387f18a7c5ae1faeb35e9" dependencies: - babel-helper-regex "^6.22.0" + babel-helper-regex "^6.24.1" babel-runtime "^6.22.0" regexpu-core "^2.0.0" babel-plugin-transform-exponentiation-operator@^6.22.0, babel-plugin-transform-exponentiation-operator@^6.8.0: - version "6.22.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-exponentiation-operator/-/babel-plugin-transform-exponentiation-operator-6.22.0.tgz#d57c8335281918e54ef053118ce6eb108468084d" + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-exponentiation-operator/-/babel-plugin-transform-exponentiation-operator-6.24.1.tgz#2ab0c9c7f3098fa48907772bb813fe41e8de3a0e" dependencies: - babel-helper-builder-binary-assignment-operator-visitor "^6.22.0" + babel-helper-builder-binary-assignment-operator-visitor "^6.24.1" babel-plugin-syntax-exponentiation-operator "^6.8.0" babel-runtime "^6.22.0" @@ -777,61 +781,59 @@ babel-plugin-transform-inline-consecutive-adds@^0.0.2: resolved "https://registry.yarnpkg.com/babel-plugin-transform-inline-consecutive-adds/-/babel-plugin-transform-inline-consecutive-adds-0.0.2.tgz#a58fcecfc09c08fbf9373a5a3e70746c03d01fc1" babel-plugin-transform-member-expression-literals@^6.8.1: - version "6.8.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-member-expression-literals/-/babel-plugin-transform-member-expression-literals-6.8.1.tgz#60b78cb2b814ac71dd6104ef51c496c62e877337" + version "6.8.4" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-member-expression-literals/-/babel-plugin-transform-member-expression-literals-6.8.4.tgz#05679bc40596b91293401959aa1620ab1b2be437" babel-plugin-transform-merge-sibling-variables@^6.8.2: - version "6.8.2" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-merge-sibling-variables/-/babel-plugin-transform-merge-sibling-variables-6.8.2.tgz#498acd07481ab340c1bad8b726c2fad1b8f644e5" + version "6.8.5" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-merge-sibling-variables/-/babel-plugin-transform-merge-sibling-variables-6.8.5.tgz#03abdf107c61241913eb268ddede6d5bc541862c" babel-plugin-transform-minify-booleans@^6.8.0: - version "6.8.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-minify-booleans/-/babel-plugin-transform-minify-booleans-6.8.0.tgz#b1a48864a727847696b84eae36fa4d085a54b42b" - dependencies: - babel-runtime "^6.0.0" + version "6.8.2" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-minify-booleans/-/babel-plugin-transform-minify-booleans-6.8.2.tgz#8451579f706e702c1e1ab2756de5c8ea369cf07c" babel-plugin-transform-property-literals@^6.8.1: - version "6.8.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-property-literals/-/babel-plugin-transform-property-literals-6.8.1.tgz#05ed01f6024820b18f1d0495c80fe287176bccd9" + version "6.8.4" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-property-literals/-/babel-plugin-transform-property-literals-6.8.4.tgz#6ad311110b80a192a56efb5ddf4fe3ca6f7a61da" + dependencies: + esutils "^2.0.2" babel-plugin-transform-regenerator@^6.22.0: - version "6.22.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-regenerator/-/babel-plugin-transform-regenerator-6.22.0.tgz#65740593a319c44522157538d690b84094617ea6" + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-regenerator/-/babel-plugin-transform-regenerator-6.24.1.tgz#b8da305ad43c3c99b4848e4fe4037b770d23c418" dependencies: - regenerator-transform "0.9.8" + regenerator-transform "0.9.11" babel-plugin-transform-regexp-constructors@^0.0.6: version "0.0.6" resolved "https://registry.yarnpkg.com/babel-plugin-transform-regexp-constructors/-/babel-plugin-transform-regexp-constructors-0.0.6.tgz#0d92607f0d26268296980cb7c1dea5f2dd3e1e20" babel-plugin-transform-remove-console@^6.8.1: - version "6.8.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-remove-console/-/babel-plugin-transform-remove-console-6.8.1.tgz#38f6a6ca1581e76b75fc2c6fdcf909deadee7d6a" + version "6.8.4" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-remove-console/-/babel-plugin-transform-remove-console-6.8.4.tgz#41fddac19a729a4c3dd7ef2964eac07b096f9a8f" babel-plugin-transform-remove-debugger@^6.8.1: - version "6.8.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-remove-debugger/-/babel-plugin-transform-remove-debugger-6.8.1.tgz#aabd0be107f8299094defe8e1ba8ccf4b114d07f" + version "6.8.4" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-remove-debugger/-/babel-plugin-transform-remove-debugger-6.8.4.tgz#f85704a08adaa71b55d77005b5b94e9b9df21f6e" babel-plugin-transform-remove-undefined@^0.0.5: version "0.0.5" resolved "https://registry.yarnpkg.com/babel-plugin-transform-remove-undefined/-/babel-plugin-transform-remove-undefined-0.0.5.tgz#12ef11805e06e861dd2eb0c7cc041d2184b8f410" babel-plugin-transform-simplify-comparison-operators@^6.8.1: - version "6.8.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-simplify-comparison-operators/-/babel-plugin-transform-simplify-comparison-operators-6.8.1.tgz#a307088e0d1c728081777fba568f4107396ab25c" + version "6.8.4" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-simplify-comparison-operators/-/babel-plugin-transform-simplify-comparison-operators-6.8.4.tgz#2aa24a262d664c8cb3e125a306c798d7a2de08d5" -babel-plugin-transform-strict-mode@^6.22.0: - version "6.22.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-strict-mode/-/babel-plugin-transform-strict-mode-6.22.0.tgz#e008df01340fdc87e959da65991b7e05970c8c7c" +babel-plugin-transform-strict-mode@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-strict-mode/-/babel-plugin-transform-strict-mode-6.24.1.tgz#d5faf7aa578a65bbe591cf5edae04a0c67020758" dependencies: babel-runtime "^6.22.0" - babel-types "^6.22.0" + babel-types "^6.24.1" babel-plugin-transform-undefined-to-void@^6.8.0: - version "6.8.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-undefined-to-void/-/babel-plugin-transform-undefined-to-void-6.8.0.tgz#bc5b6b4908d3b1262170e67cb3963903ddce167e" - dependencies: - babel-runtime "^6.0.0" + version "6.8.2" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-undefined-to-void/-/babel-plugin-transform-undefined-to-void-6.8.2.tgz#fe2b1d294eb05e87524eb93724dea6e2c3d66fa1" babel-preset-babili@^0.0.12: version "0.0.12" @@ -862,8 +864,8 @@ babel-preset-babili@^0.0.12: lodash.isplainobject "^4.0.6" babel-preset-env@^1.3.2: - version "1.3.2" - resolved "https://registry.yarnpkg.com/babel-preset-env/-/babel-preset-env-1.3.2.tgz#08eabd2bf810c3678069f7e052323419f1448749" + version "1.5.2" + resolved "https://registry.yarnpkg.com/babel-preset-env/-/babel-preset-env-1.5.2.tgz#cd4ae90a6e94b709f97374b33e5f8b983556adef" dependencies: babel-plugin-check-es2015-constants "^6.22.0" babel-plugin-syntax-trailing-function-commas "^6.22.0" @@ -892,14 +894,15 @@ babel-preset-env@^1.3.2: babel-plugin-transform-es2015-unicode-regex "^6.22.0" babel-plugin-transform-exponentiation-operator "^6.22.0" babel-plugin-transform-regenerator "^6.22.0" - browserslist "^1.4.0" + browserslist "^2.1.2" invariant "^2.2.2" + semver "^5.3.0" -babel-register@^6.24.0: - version "6.24.0" - resolved "https://registry.yarnpkg.com/babel-register/-/babel-register-6.24.0.tgz#5e89f8463ba9970356d02eb07dabe3308b080cfd" +babel-register@^6.24.0, babel-register@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-register/-/babel-register-6.24.1.tgz#7e10e13a2f71065bdfad5a1787ba45bca6ded75f" dependencies: - babel-core "^6.24.0" + babel-core "^6.24.1" babel-runtime "^6.22.0" core-js "^2.4.0" home-or-tmp "^2.0.0" @@ -907,53 +910,53 @@ babel-register@^6.24.0: mkdirp "^0.5.1" source-map-support "^0.4.2" -babel-runtime@^6.0.0, babel-runtime@^6.18.0, babel-runtime@^6.22.0: +babel-runtime@^6.18.0, babel-runtime@^6.22.0: version "6.23.0" resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-6.23.0.tgz#0a9489f144de70efb3ce4300accdb329e2fc543b" dependencies: core-js "^2.4.0" regenerator-runtime "^0.10.0" -babel-template@^6.16.0, babel-template@^6.22.0, babel-template@^6.23.0: - version "6.23.0" - resolved "https://registry.yarnpkg.com/babel-template/-/babel-template-6.23.0.tgz#04d4f270adbb3aa704a8143ae26faa529238e638" +babel-template@^6.16.0, babel-template@^6.24.1, babel-template@^6.25.0: + version "6.25.0" + resolved "https://registry.yarnpkg.com/babel-template/-/babel-template-6.25.0.tgz#665241166b7c2aa4c619d71e192969552b10c071" dependencies: babel-runtime "^6.22.0" - babel-traverse "^6.23.0" - babel-types "^6.23.0" - babylon "^6.11.0" + babel-traverse "^6.25.0" + babel-types "^6.25.0" + babylon "^6.17.2" lodash "^4.2.0" -babel-traverse@^6.18.0, babel-traverse@^6.22.0, babel-traverse@^6.23.0, babel-traverse@^6.23.1: - version "6.23.1" - resolved "https://registry.yarnpkg.com/babel-traverse/-/babel-traverse-6.23.1.tgz#d3cb59010ecd06a97d81310065f966b699e14f48" +babel-traverse@^6.18.0, babel-traverse@^6.24.1, babel-traverse@^6.25.0: + version "6.25.0" + resolved "https://registry.yarnpkg.com/babel-traverse/-/babel-traverse-6.25.0.tgz#2257497e2fcd19b89edc13c4c91381f9512496f1" dependencies: babel-code-frame "^6.22.0" babel-messages "^6.23.0" babel-runtime "^6.22.0" - babel-types "^6.23.0" - babylon "^6.15.0" + babel-types "^6.25.0" + babylon "^6.17.2" debug "^2.2.0" globals "^9.0.0" invariant "^2.2.0" lodash "^4.2.0" -babel-types@^6.18.0, babel-types@^6.19.0, babel-types@^6.22.0, babel-types@^6.23.0: - version "6.23.0" - resolved "https://registry.yarnpkg.com/babel-types/-/babel-types-6.23.0.tgz#bb17179d7538bad38cd0c9e115d340f77e7e9acf" +babel-types@^6.18.0, babel-types@^6.19.0, babel-types@^6.24.1, babel-types@^6.25.0: + version "6.25.0" + resolved "https://registry.yarnpkg.com/babel-types/-/babel-types-6.25.0.tgz#70afb248d5660e5d18f811d91c8303b54134a18e" dependencies: babel-runtime "^6.22.0" esutils "^2.0.2" lodash "^4.2.0" to-fast-properties "^1.0.1" -babylon@^6.1.0, babylon@^6.11.0, babylon@^6.13.0, babylon@^6.15.0: - version "6.16.1" - resolved "https://registry.yarnpkg.com/babylon/-/babylon-6.16.1.tgz#30c5a22f481978a9e7f8cdfdf496b11d94b404d3" +babylon@^6.1.0, babylon@^6.13.0, babylon@^6.17.2: + version "6.17.4" + resolved "https://registry.yarnpkg.com/babylon/-/babylon-6.17.4.tgz#3e8b7402b88d22c3423e137a1577883b15ff869a" -balanced-match@^0.4.1: - version "0.4.2" - resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-0.4.2.tgz#cb3f3e3c732dc0f01ee70b403f302e61d7709838" +balanced-match@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" bcrypt-pbkdf@^1.0.0: version "1.0.1" @@ -993,11 +996,11 @@ boxen@^1.0.0: term-size "^0.1.0" widest-line "^1.0.0" -brace-expansion@^1.0.0: - version "1.1.6" - resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.6.tgz#7197d7eaa9b87e648390ea61fc66c84427420df9" +brace-expansion@^1.1.7: + version "1.1.8" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.8.tgz#c07b211c7c952ec1f8efd51a77ef0d1d3990a292" dependencies: - balanced-match "^0.4.1" + balanced-match "^1.0.0" concat-map "0.0.1" braces@^1.8.2: @@ -1014,21 +1017,17 @@ browser-resolve@^1.11.0: dependencies: resolve "1.1.7" -browserslist@^1.4.0: - version "1.7.7" - resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-1.7.7.tgz#0bd76704258be829b2398bb50e4b62d1a166b0b9" +browserslist@^2.1.2: + version "2.1.5" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-2.1.5.tgz#e882550df3d1cd6d481c1a3e0038f2baf13a4711" dependencies: - caniuse-db "^1.0.30000639" - electron-to-chromium "^1.2.7" + caniuse-lite "^1.0.30000684" + electron-to-chromium "^1.3.14" buf-compare@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/buf-compare/-/buf-compare-1.0.1.tgz#fef28da8b8113a0a0db4430b0b6467b69730b34a" -buffer-shims@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/buffer-shims/-/buffer-shims-1.0.0.tgz#9978ce317388c649ad8793028c3477ef044a8b51" - builtin-modules@^1.0.0, builtin-modules@^1.1.0, builtin-modules@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-1.1.1.tgz#270f076c5a72c02f5b65a47df94c5fe3a278892f" @@ -1087,9 +1086,9 @@ camelcase@^4.0.0: version "4.1.0" resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-4.1.0.tgz#d545635be1e33c542649c69173e5de6acfae34dd" -caniuse-db@^1.0.30000639: - version "1.0.30000646" - resolved "https://registry.yarnpkg.com/caniuse-db/-/caniuse-db-1.0.30000646.tgz#c724b90d61df24286e015fc528d062073c00def4" +caniuse-lite@^1.0.30000684: + version "1.0.30000693" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000693.tgz#c9c6298697c71fdf6cb13eefe8aa93926f2f8613" capture-stack-trace@^1.0.0: version "1.0.0" @@ -1356,17 +1355,11 @@ debug-log@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/debug-log/-/debug-log-1.0.1.tgz#2307632d4c04382b8df8a32f70b895046d52745f" -debug@2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/debug/-/debug-2.2.0.tgz#f87057e995b1a1f6ae6a4960664137bc56f039da" +debug@^2.1.1, debug@^2.2.0, debug@^2.6.3, debug@^2.6.8: + version "2.6.8" + resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.8.tgz#e731531ca2ede27d188222427da17821d68ff4fc" dependencies: - ms "0.7.1" - -debug@^2.1.1, debug@^2.2.0, debug@^2.6.3: - version "2.6.3" - resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.3.tgz#0f7eb8c30965ec08c72accfa0130c8b79984141d" - dependencies: - ms "0.7.2" + ms "2.0.0" decamelize@^1.0.0, decamelize@^1.1.1, decamelize@^1.1.2: version "1.2.0" @@ -1458,13 +1451,13 @@ ecc-jsbn@~0.1.1: dependencies: jsbn "~0.1.0" -electron-to-chromium@^1.2.7: - version "1.3.2" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.2.tgz#b8ce5c93b308db0e92f6d0435c46ddec8f6363ab" +electron-to-chromium@^1.3.14: + version "1.3.14" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.14.tgz#64af0f9efd3c3c6acd57d71f83b49ca7ee9c4b43" empower-core@^0.6.1: - version "0.6.1" - resolved "https://registry.yarnpkg.com/empower-core/-/empower-core-0.6.1.tgz#6c187f502fcef7554d57933396aac655483772b1" + version "0.6.2" + resolved "https://registry.yarnpkg.com/empower-core/-/empower-core-0.6.2.tgz#5adef566088e31fba80ba0a36df47d7094169144" dependencies: call-signature "0.0.2" core-js "^2.0.0" @@ -1473,9 +1466,9 @@ equal-length@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/equal-length/-/equal-length-1.0.1.tgz#21ca112d48ab24b4e1e7ffc0e5339d31fdfc274c" -erlang-types@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/erlang-types/-/erlang-types-1.0.0.tgz#e555bd091667498a01d340d18203231dc96d962f" +erlang-types@^1.0.0, erlang-types@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/erlang-types/-/erlang-types-1.0.1.tgz#943a57a9324e0d0edc0273690a8c702686d9b780" error-ex@^1.2.0: version "1.3.1" @@ -1484,8 +1477,8 @@ error-ex@^1.2.0: is-arrayish "^0.2.1" es5-ext@^0.10.14, es5-ext@^0.10.9, es5-ext@~0.10.14: - version "0.10.15" - resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.15.tgz#c330a5934c1ee21284a7c081a86e5fd937c91ea6" + version "0.10.23" + resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.23.tgz#7578b51be974207a5487821b56538c224e4e7b38" dependencies: es6-iterator "2" es6-symbol "~3.1" @@ -1553,8 +1546,8 @@ escope@^3.6.0: estraverse "^4.1.1" eslint-config-airbnb-base@^11.1.0: - version "11.1.2" - resolved "https://registry.yarnpkg.com/eslint-config-airbnb-base/-/eslint-config-airbnb-base-11.1.2.tgz#259209a7678bf693e31cbe8f953f206b6aa7ccc3" + version "11.2.0" + resolved "https://registry.yarnpkg.com/eslint-config-airbnb-base/-/eslint-config-airbnb-base-11.2.0.tgz#19a9dc4481a26f70904545ec040116876018f853" eslint-import-resolver-node@^0.2.0: version "0.2.3" @@ -1565,26 +1558,26 @@ eslint-import-resolver-node@^0.2.0: resolve "^1.1.6" eslint-module-utils@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.0.0.tgz#a6f8c21d901358759cdc35dbac1982ae1ee58bce" + version "2.1.1" + resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.1.1.tgz#abaec824177613b8a95b299639e1b6facf473449" dependencies: - debug "2.2.0" + debug "^2.6.8" pkg-dir "^1.0.0" eslint-plugin-import@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.2.0.tgz#72ba306fad305d67c4816348a4699a4229ac8b4e" + version "2.5.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.5.0.tgz#293b5ea7910a901a05a47ccdd7546e611725406c" dependencies: builtin-modules "^1.1.1" contains-path "^0.1.0" - debug "^2.2.0" + debug "^2.6.8" doctrine "1.5.0" eslint-import-resolver-node "^0.2.0" eslint-module-utils "^2.0.0" has "^1.0.1" lodash.cond "^4.3.0" minimatch "^3.0.3" - pkg-up "^1.0.0" + read-pkg-up "^2.0.0" eslint@^3.15.0: version "3.19.0" @@ -1636,8 +1629,8 @@ espower-location-detector@^1.0.0: xtend "^4.0.0" espree@^3.4.0: - version "3.4.1" - resolved "https://registry.yarnpkg.com/espree/-/espree-3.4.1.tgz#28a83ab4aaed71ed8fe0f5efe61b76a05c13c4d2" + version "3.4.3" + resolved "https://registry.yarnpkg.com/espree/-/espree-3.4.3.tgz#2910b5ccd49ce893c2ffffaab4fd8b3a31b82374" dependencies: acorn "^5.0.1" acorn-jsx "^3.0.0" @@ -1659,20 +1652,16 @@ esquery@^1.0.0: estraverse "^4.0.0" esrecurse@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.1.0.tgz#4713b6536adf7f2ac4f327d559e7756bff648220" + version "4.2.0" + resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.2.0.tgz#fa9568d98d3823f9a41d91e902dcab9ea6e5b163" dependencies: - estraverse "~4.1.0" + estraverse "^4.1.0" object-assign "^4.0.1" -estraverse@^4.0.0, estraverse@^4.1.1, estraverse@^4.2.0: +estraverse@^4.0.0, estraverse@^4.1.0, estraverse@^4.1.1, estraverse@^4.2.0: version "4.2.0" resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.2.0.tgz#0dee3fed31fcd469618ce7342099fc1afa0bdb13" -estraverse@~4.1.0: - version "4.1.1" - resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.1.1.tgz#f6caca728933a850ef90661d0e17982ba47111a2" - estree-walker@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-0.2.1.tgz#bdafe8095383d8414d5dc2ecf4c9173b6db9412e" @@ -1794,7 +1783,7 @@ find-up@^1.0.0, find-up@^1.1.2: path-exists "^2.0.0" pinkie-promise "^2.0.0" -find-up@^2.0.0: +find-up@^2.0.0, find-up@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/find-up/-/find-up-2.1.0.tgz#45d1b7e506c717ddd482775a2b77920a3c0c57a7" dependencies: @@ -1853,11 +1842,11 @@ fs.realpath@^1.0.0: resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" fsevents@^1.0.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-1.1.1.tgz#f19fd28f43eeaf761680e519a203c4d0b3d31aff" + version "1.1.2" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-1.1.2.tgz#3282b713fb3ad80ede0e9fcf4611b5aa6fc033f4" dependencies: nan "^2.3.0" - node-pre-gyp "^0.6.29" + node-pre-gyp "^0.6.36" fstream-ignore@^1.0.5: version "1.0.5" @@ -1946,19 +1935,19 @@ glob-parent@^2.0.0: is-glob "^2.0.0" glob@^7.0.0, glob@^7.0.3, glob@^7.0.5, glob@^7.0.6: - version "7.1.1" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.1.tgz#805211df04faaf1c63a3600306cdf5ade50b2ec8" + version "7.1.2" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.2.tgz#c19c9df9a028702d678612384a6552404c636d15" dependencies: fs.realpath "^1.0.0" inflight "^1.0.4" inherits "2" - minimatch "^3.0.2" + minimatch "^3.0.4" once "^1.3.0" path-is-absolute "^1.0.0" globals@^9.0.0, globals@^9.14.0: - version "9.17.0" - resolved "https://registry.yarnpkg.com/globals/-/globals-9.17.0.tgz#0c0ca696d9b9bb694d2e5470bd37777caad50286" + version "9.18.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-9.18.0.tgz#aa3896b3e69b487f17e31ed2143d69a8e30c2d8a" globby@^5.0.0: version "5.0.0" @@ -2087,8 +2076,8 @@ http-signature@~1.1.0: sshpk "^1.7.0" hullabaloo-config-manager@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/hullabaloo-config-manager/-/hullabaloo-config-manager-1.0.1.tgz#c72be7ba249a67c99b6ba3eb1f55837fa01acd8f" + version "1.1.1" + resolved "https://registry.yarnpkg.com/hullabaloo-config-manager/-/hullabaloo-config-manager-1.1.1.tgz#1d9117813129ad035fd9e8477eaf066911269fe3" dependencies: dot-prop "^4.1.0" es6-error "^4.0.2" @@ -2101,16 +2090,21 @@ hullabaloo-config-manager@^1.0.0: lodash.merge "^4.6.0" md5-hex "^2.0.0" package-hash "^2.0.0" - pkg-dir "^1.0.0" - resolve-from "^2.0.0" + pkg-dir "^2.0.0" + resolve-from "^3.0.0" + safe-buffer "^5.0.1" ignore-by-default@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/ignore-by-default/-/ignore-by-default-1.0.1.tgz#48ca6d72f6c6a3af00a9ad4ae6876be3889e2b09" ignore@^3.2.0: - version "3.2.6" - resolved "https://registry.yarnpkg.com/ignore/-/ignore-3.2.6.tgz#26e8da0644be0bb4cb39516f6c79f0e0f4ffe48c" + version "3.3.3" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-3.3.3.tgz#432352e57accd87ab3110e82d3fea0e47812156d" + +import-lazy@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/import-lazy/-/import-lazy-2.1.0.tgz#05698e3d45c88e8d7e9d92cb0584e77f096f3e43" imurmurhash@^0.1.4: version "0.1.4" @@ -2133,7 +2127,7 @@ inflight@^1.0.4: once "^1.3.0" wrappy "1" -inherits@2, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.0, inherits@~2.0.1: +inherits@2, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.0, inherits@~2.0.3: version "2.0.3" resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" @@ -2164,8 +2158,8 @@ inquirer@^0.12.0: through "^2.3.6" interpret@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.0.2.tgz#f4f623f0bb7122f15f5717c8e254b8161b5c5b2d" + version "1.0.3" + resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.0.3.tgz#cbc35c62eeee73f19ab7b10a801511401afc0f90" invariant@^2.2.0, invariant@^2.2.2: version "2.2.2" @@ -2208,8 +2202,8 @@ is-ci@^1.0.7: ci-info "^1.0.0" is-dotfile@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/is-dotfile/-/is-dotfile-1.0.2.tgz#2c132383f39199f8edc268ca01b9b007d205cc4d" + version "1.0.3" + resolved "https://registry.yarnpkg.com/is-dotfile/-/is-dotfile-1.0.3.tgz#a6a2f32ffd2dfb04f5ca25ecd0f6b83cf798a1e1" is-equal-shallow@^0.1.3: version "0.1.3" @@ -2268,12 +2262,18 @@ is-npm@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-npm/-/is-npm-1.0.0.tgz#f2fb63a65e4905b406c86072765a1a4dc793b9f4" -is-number@^2.0.2, is-number@^2.1.0: +is-number@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/is-number/-/is-number-2.1.0.tgz#01fcbbb393463a548f2f466cce16dece49db908f" dependencies: kind-of "^3.0.2" +is-number@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-3.0.0.tgz#24fd6201a4782cf50561c810276afc7d12d71195" + dependencies: + kind-of "^3.0.2" + is-obj@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-1.0.1.tgz#3e4729ac1f5fde025cd7d83a896dab9f4f67db0f" @@ -2480,19 +2480,13 @@ jest-validate@^19.0.2: leven "^2.0.0" pretty-format "^19.0.0" -jodid25519@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/jodid25519/-/jodid25519-1.0.2.tgz#06d4912255093419477d425633606e0e90782967" - dependencies: - jsbn "~0.1.0" - js-tokens@^3.0.0: version "3.0.1" resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.1.tgz#08e9f132484a2c45a30907e9dc4d5567b7f114d7" js-yaml@^3.5.1, js-yaml@^3.8.2: - version "3.8.2" - resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.8.2.tgz#02d3e2c0f6beab20248d412c352203827d786721" + version "3.8.4" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.8.4.tgz#520b4564f86573ba96662af85a8cafa7b4b5a6f6" dependencies: argparse "^1.0.7" esprima "^3.1.1" @@ -2506,8 +2500,8 @@ jsesc@^1.3.0: resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-1.3.0.tgz#46c3fec8c1892b12b0833db9bc7622176dbab34b" jsesc@^2.4.0: - version "2.4.0" - resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.4.0.tgz#8568d223ff69c0b5e081b4f8edf5a23d978c9867" + version "2.5.1" + resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.1.tgz#e421a2a8e20d6b0819df28908f782526b96dd1fe" jsesc@~0.5.0: version "0.5.0" @@ -2554,6 +2548,12 @@ kind-of@^3.0.2: dependencies: is-buffer "^1.1.5" +kind-of@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-4.0.0.tgz#20813df3d712928b207378691a45066fae72dd57" + dependencies: + is-buffer "^1.1.5" + last-line-stream@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/last-line-stream/-/last-line-stream-1.0.0.tgz#d1b64d69f86ff24af2d04883a2ceee14520a5600" @@ -2570,10 +2570,6 @@ lazy-cache@^1.0.3: version "1.0.4" resolved "https://registry.yarnpkg.com/lazy-cache/-/lazy-cache-1.0.4.tgz#a1d78fc3a50474cb80845d3b3b6e1da49a446e8e" -lazy-req@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/lazy-req/-/lazy-req-2.0.0.tgz#c9450a363ecdda2e6f0c70132ad4f37f8f06f2b4" - lcid@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/lcid/-/lcid-1.0.0.tgz#308accafa0bc483a3867b4b6f2b9506251d1b835" @@ -2691,11 +2687,11 @@ lowercase-keys@^1.0.0: resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-1.0.0.tgz#4e3366b39e7f5457e35f1324bdf6f88d0bfc7306" lru-cache@^4.0.0, lru-cache@^4.0.1: - version "4.0.2" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.0.2.tgz#1d17679c069cda5d040991a09dbc2c0db377e55e" + version "4.1.1" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.1.1.tgz#622e32e82488b49279114a4f9ecf45e7cd6bba55" dependencies: - pseudomap "^1.0.1" - yallist "^2.0.0" + pseudomap "^1.0.2" + yallist "^2.1.2" make-dir@^1.0.0: version "1.0.0" @@ -2745,10 +2741,10 @@ meow@^3.7.0: trim-newlines "^1.0.0" merge-source-map@^1.0.2: - version "1.0.3" - resolved "https://registry.yarnpkg.com/merge-source-map/-/merge-source-map-1.0.3.tgz#da1415f2722a5119db07b14c4f973410863a2abf" + version "1.0.4" + resolved "https://registry.yarnpkg.com/merge-source-map/-/merge-source-map-1.0.4.tgz#a5de46538dae84d4114cc5ea02b4772a6346701f" dependencies: - source-map "^0.5.3" + source-map "^0.5.6" micromatch@^2.1.5, micromatch@^2.3.11: version "2.3.11" @@ -2782,11 +2778,11 @@ mimic-fn@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-1.1.0.tgz#e667783d92e89dbd342818b5230b9d62a672ad18" -minimatch@^3.0.0, minimatch@^3.0.2, minimatch@^3.0.3: - version "3.0.3" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.3.tgz#2a4e4090b96b2db06a9d7df01055a62a77c9b774" +minimatch@^3.0.0, minimatch@^3.0.2, minimatch@^3.0.3, minimatch@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" dependencies: - brace-expansion "^1.0.0" + brace-expansion "^1.1.7" minimist@0.0.8, minimist@~0.0.1: version "0.0.8" @@ -2802,13 +2798,13 @@ minimist@^1.1.3, minimist@^1.2.0: dependencies: minimist "0.0.8" -ms@0.7.1: - version "0.7.1" - resolved "https://registry.yarnpkg.com/ms/-/ms-0.7.1.tgz#9cd13c03adbff25b65effde7ce864ee952017098" +ms@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" -ms@0.7.2, ms@^0.7.1: - version "0.7.2" - resolved "https://registry.yarnpkg.com/ms/-/ms-0.7.2.tgz#ae25cf2512b3885a1d95d7f037868d8431124765" +ms@^0.7.1: + version "0.7.3" + resolved "https://registry.yarnpkg.com/ms/-/ms-0.7.3.tgz#708155a5e44e33f5fd0fc53e81d0d40a91be1fff" multimatch@^2.1.0: version "2.1.0" @@ -2831,9 +2827,9 @@ natural-compare@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" -node-pre-gyp@^0.6.29: - version "0.6.34" - resolved "https://registry.yarnpkg.com/node-pre-gyp/-/node-pre-gyp-0.6.34.tgz#94ad1c798a11d7fc67381b50d47f8cc18d9799f7" +node-pre-gyp@^0.6.36: + version "0.6.36" + resolved "https://registry.yarnpkg.com/node-pre-gyp/-/node-pre-gyp-0.6.36.tgz#db604112cb74e0d477554e9b505b17abddfab786" dependencies: mkdirp "^0.5.1" nopt "^4.0.1" @@ -3153,11 +3149,11 @@ pkg-dir@^1.0.0: dependencies: find-up "^1.0.0" -pkg-up@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/pkg-up/-/pkg-up-1.0.0.tgz#3e08fb461525c4421624a33b9f7e6d0af5b05a26" +pkg-dir@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-2.0.0.tgz#f6d5d1109e19d63edf428e0bd57e12777615334b" dependencies: - find-up "^1.0.0" + find-up "^2.1.0" plur@^1.0.0: version "1.0.0" @@ -3217,7 +3213,7 @@ progress@^1.1.8: version "1.1.8" resolved "https://registry.yarnpkg.com/progress/-/progress-1.1.8.tgz#e260c78f6161cdd9b0e56cc3e0a85de17c7a57be" -pseudomap@^1.0.1: +pseudomap@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3" @@ -3230,11 +3226,11 @@ qs@~6.4.0: resolved "https://registry.yarnpkg.com/qs/-/qs-6.4.0.tgz#13e26d28ad6b0ffaa91312cd3bf708ed351e7233" randomatic@^1.1.3: - version "1.1.6" - resolved "https://registry.yarnpkg.com/randomatic/-/randomatic-1.1.6.tgz#110dcabff397e9dcff7c0789ccc0a49adf1ec5bb" + version "1.1.7" + resolved "https://registry.yarnpkg.com/randomatic/-/randomatic-1.1.7.tgz#c7abe9cc8b87c0baa876b19fde83fd464797e38c" dependencies: - is-number "^2.0.2" - kind-of "^3.0.2" + is-number "^3.0.0" + kind-of "^4.0.0" rc@^1.0.1, rc@^1.1.6, rc@^1.1.7: version "1.2.1" @@ -3276,15 +3272,15 @@ read-pkg@^2.0.0: path-type "^2.0.0" readable-stream@^2.0.2, readable-stream@^2.0.6, readable-stream@^2.1.4, readable-stream@^2.1.5, readable-stream@^2.2.2: - version "2.2.6" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.2.6.tgz#8b43aed76e71483938d12a8d46c6cf1a00b1f816" + version "2.3.2" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.2.tgz#5a04df05e4f57fe3f0dc68fdd11dc5c97c7e6f4d" dependencies: - buffer-shims "^1.0.0" core-util-is "~1.0.0" - inherits "~2.0.1" + inherits "~2.0.3" isarray "~1.0.0" process-nextick-args "~1.0.6" - string_decoder "~0.10.x" + safe-buffer "~5.1.0" + string_decoder "~1.0.0" util-deprecate "~1.0.1" readdirp@^2.0.0: @@ -3322,12 +3318,12 @@ regenerate@^1.2.1: resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.3.2.tgz#d1941c67bad437e1be76433add5b385f95b19260" regenerator-runtime@^0.10.0: - version "0.10.3" - resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.10.3.tgz#8c4367a904b51ea62a908ac310bf99ff90a82a3e" + version "0.10.5" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.10.5.tgz#336c3efc1220adcedda2c9fab67b5a7955a33658" -regenerator-transform@0.9.8: - version "0.9.8" - resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.9.8.tgz#0f88bb2bc03932ddb7b6b7312e68078f01026d6c" +regenerator-transform@0.9.11: + version "0.9.11" + resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.9.11.tgz#3a7d067520cb7b7176769eb5ff868691befe1283" dependencies: babel-runtime "^6.18.0" babel-types "^6.19.0" @@ -3378,8 +3374,8 @@ release-zalgo@^1.0.0: es6-error "^4.0.1" remove-trailing-separator@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/remove-trailing-separator/-/remove-trailing-separator-1.0.1.tgz#615ebb96af559552d4bf4057c8436d486ab63cc4" + version "1.0.2" + resolved "https://registry.yarnpkg.com/remove-trailing-separator/-/remove-trailing-separator-1.0.2.tgz#69b062d978727ad14dc6b56ba4ab772fd8d70511" repeat-element@^1.1.2: version "1.1.2" @@ -3455,13 +3451,17 @@ resolve-from@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-2.0.0.tgz#9480ab20e94ffa1d9e80a804c7ea147611966b57" +resolve-from@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-3.0.0.tgz#b22c7af7d9d6881bc8b6e653335eebcb0a188748" + resolve@1.1.7: version "1.1.7" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.1.7.tgz#203114d82ad2c5ed9e8e0411b3932875e889e97b" resolve@^1.1.6: - version "1.3.2" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.3.2.tgz#1f0442c9e0cbb8136e87b9305f932f46c7f28235" + version "1.3.3" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.3.3.tgz#655907c3469a8680dc2de3a275a8fdd69691f0e5" dependencies: path-parse "^1.0.5" @@ -3539,9 +3539,9 @@ rx-lite@^3.1.2: version "3.1.2" resolved "https://registry.yarnpkg.com/rx-lite/-/rx-lite-3.1.2.tgz#19ce502ca572665f3b647b10939f97fd1615f102" -safe-buffer@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.0.1.tgz#d263ca54696cd8a306b5ca6551e92de57918fbe7" +safe-buffer@^5.0.1, safe-buffer@~5.1.0: + version "5.1.1" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.1.tgz#893312af69b2123def71f57889001671eeb2c853" samsam@1.1.2, samsam@~1.1: version "1.1.2" @@ -3566,8 +3566,8 @@ set-immediate-shim@^1.0.1: resolved "https://registry.yarnpkg.com/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz#4b2b1b27eb808a9f8dcc481a58e5e56f599f3f61" shelljs@^0.7.5: - version "0.7.7" - resolved "https://registry.yarnpkg.com/shelljs/-/shelljs-0.7.7.tgz#b2f5c77ef97148f4b4f6e22682e10bba8667cff1" + version "0.7.8" + resolved "https://registry.yarnpkg.com/shelljs/-/shelljs-0.7.8.tgz#decbcf874b0d1e5fb72e14b164a9683048e9acb3" dependencies: glob "^7.0.0" interpret "^1.0.0" @@ -3615,8 +3615,8 @@ sort-keys@^1.1.1, sort-keys@^1.1.2: is-plain-obj "^1.0.0" source-map-support@^0.4.0, source-map-support@^0.4.2: - version "0.4.14" - resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.4.14.tgz#9d4463772598b86271b4f523f6c1f4e02a7d6aef" + version "0.4.15" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.4.15.tgz#03202df65c06d2bd8c7ec2362a193056fef8d3b1" dependencies: source-map "^0.5.6" @@ -3660,8 +3660,8 @@ sprintf-js@~1.0.2: resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" sshpk@^1.7.0: - version "1.13.0" - resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.13.0.tgz#ff2a3e4fd04497555fed97b39a0fd82fafb3a33c" + version "1.13.1" + resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.13.1.tgz#512df6da6287144316dc4c18fe1cf1d940739be3" dependencies: asn1 "~0.2.3" assert-plus "^1.0.0" @@ -3670,7 +3670,6 @@ sshpk@^1.7.0: optionalDependencies: bcrypt-pbkdf "^1.0.0" ecc-jsbn "~0.1.1" - jodid25519 "^1.0.0" jsbn "~0.1.0" tweetnacl "~0.14.0" @@ -3693,9 +3692,11 @@ string-width@^2.0.0: is-fullwidth-code-point "^2.0.0" strip-ansi "^3.0.0" -string_decoder@~0.10.x: - version "0.10.31" - resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-0.10.31.tgz#62e203bc41766c6c28c9fc84301dab1c5310fa94" +string_decoder@~1.0.0: + version "1.0.3" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.0.3.tgz#0fc67d7c141825de94282dd536bec6b9bce860ab" + dependencies: + safe-buffer "~5.1.0" stringstream@~0.0.4: version "0.0.5" @@ -3770,9 +3771,9 @@ table@^3.7.8: slice-ansi "0.0.4" string-width "^2.0.0" -tailored@2.4.5: - version "2.4.5" - resolved "https://registry.yarnpkg.com/tailored/-/tailored-2.4.5.tgz#c100530d8c2978a0b75228159a46bfe636fa70d6" +tailored@^2.4.6: + version "2.4.6" + resolved "https://registry.yarnpkg.com/tailored/-/tailored-2.4.6.tgz#1425d01bfc0e69ae0f8edb7030f82d6f0239d00f" dependencies: erlang-types "^1.0.0" @@ -3842,8 +3843,8 @@ timed-out@^4.0.0: resolved "https://registry.yarnpkg.com/timed-out/-/timed-out-4.0.1.tgz#f32eacac5a175bea25d7fab565ab3ed8741ef56f" to-fast-properties@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-1.0.2.tgz#f3f5c0c3ba7299a7ef99427e44633257ade43320" + version "1.0.3" + resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-1.0.3.tgz#b83571fa4d8c25b82e231b06e3a3055de4ca1a47" tough-cookie@~2.3.0: version "2.3.2" @@ -3884,8 +3885,8 @@ typedarray@^0.0.6: resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" uglify-js@^2.6: - version "2.8.27" - resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-2.8.27.tgz#47787f912b0f242e5b984343be8e35e95f694c9c" + version "2.8.29" + resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-2.8.29.tgz#29c5733148057bb4e1f75df35b7a9cb72e6a59dd" dependencies: source-map "~0.5.1" yargs "~3.10.0" @@ -3923,15 +3924,15 @@ unzip-response@^2.0.1: resolved "https://registry.yarnpkg.com/unzip-response/-/unzip-response-2.0.1.tgz#d2f0f737d16b0615e72a6935ed04214572d56f97" update-notifier@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/update-notifier/-/update-notifier-2.1.0.tgz#ec0c1e53536b76647a24b77cb83966d9315123d9" + version "2.2.0" + resolved "https://registry.yarnpkg.com/update-notifier/-/update-notifier-2.2.0.tgz#1b5837cf90c0736d88627732b661c138f86de72f" dependencies: boxen "^1.0.0" chalk "^1.0.0" configstore "^3.0.0" + import-lazy "^2.1.0" is-npm "^1.0.0" latest-version "^3.0.0" - lazy-req "^2.0.0" semver-diff "^2.0.0" xdg-basedir "^3.0.0" @@ -3958,8 +3959,8 @@ util-deprecate@~1.0.1: inherits "2.0.1" uuid@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.0.1.tgz#6544bba2dfda8c1cf17e629a3a305e2bb1fee6c1" + version "3.1.0" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.1.0.tgz#3dd3d3e790abc24d7b0d3a034ffababe28ebbc04" validate-npm-package-license@^3.0.1: version "3.0.1" @@ -4000,10 +4001,14 @@ window-size@0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/window-size/-/window-size-0.1.0.tgz#5438cd2ea93b202efa3a19fe8887aee7c94f9c9d" -wordwrap@0.0.2, wordwrap@~0.0.2: +wordwrap@0.0.2: version "0.0.2" resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-0.0.2.tgz#b79669bb42ecb409f83d583cad52ca17eaa1643f" +wordwrap@~0.0.2: + version "0.0.3" + resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-0.0.3.tgz#a3d5da6cd5c0bc0008d37234bbaf1bed63059107" + wordwrap@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb" @@ -4071,7 +4076,7 @@ y18n@^3.2.1: version "3.2.1" resolved "https://registry.yarnpkg.com/y18n/-/y18n-3.2.1.tgz#6d15fba884c08679c0d77e88e7759e811e07fa41" -yallist@^2.0.0: +yallist@^2.1.2: version "2.1.2" resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52" From 2b887244cfab89f902176ca9e948b3a1e7ce8ce4 Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Thu, 22 Jun 2017 21:54:26 -0500 Subject: [PATCH 128/418] Add .vscode to gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 382f0cac..9a234b19 100644 --- a/.gitignore +++ b/.gitignore @@ -21,3 +21,4 @@ stdlib_state.bin *.log .nyc_output test/app/build +.vscode From f510f1e67d00982ff20e2562c22249945b26eb0d Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Sun, 25 Jun 2017 14:54:38 -0500 Subject: [PATCH 129/418] Update .travis.yml to use elixir 1.5-rc.0. Add foreach implementation to lists --- .tool-versions | 2 +- .travis.yml | 19 +++++++++---------- .../lib/core/erlang_compat/lists.js | 7 +++++++ test/support/main.ex | 2 +- 4 files changed, 18 insertions(+), 12 deletions(-) diff --git a/.tool-versions b/.tool-versions index 3f0ad299..1c908046 100644 --- a/.tool-versions +++ b/.tool-versions @@ -1,3 +1,3 @@ erlang 20.0 -elixir ref-d19a92b +elixir ref-v1.5.0-rc.0 nodejs 8.1.0 \ No newline at end of file diff --git a/.travis.yml b/.travis.yml index 91f6a3b3..3333d660 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,21 +1,20 @@ sudo: false -language: erlang +language: elixir +elixir: + - 1.5.0-rc.0 otp_release: - - 20.0-rc1 + - 20.0 env: - - TRAVIS_NODE_VERSION="7" + - TRAVIS_NODE_VERSION="8" install: - rm -rf ~/.nvm && git clone https://github.com/creationix/nvm.git ~/.nvm && (cd ~/.nvm && git checkout `git describe --abbrev=0 --tags`) && source ~/.nvm/nvm.sh && nvm install $TRAVIS_NODE_VERSION - npm install -g yarn - yarn -before_script: - - wget http://s3.hex.pm/builds/elixir/master.zip - - unzip -d elixir master.zip - - export PATH=$(pwd)/elixir/bin:${PATH} - - mix local.rebar --force +script: - mix local.hex --force + - mix local.rebar --force - mix deps.get -script: + - mix compile - yarn build - mix test - yarn test @@ -26,4 +25,4 @@ notifications: - https://webhooks.gitter.im/e/fbd8944d285c0696dc41 on_success: always # options: [always|never|change] default: always on_failure: always # options: [always|never|change] default: always - on_start: never # options: [always|never|change] default: always + on_start: never # options: [always|never|change] default: always \ No newline at end of file diff --git a/src/javascript/lib/core/erlang_compat/lists.js b/src/javascript/lib/core/erlang_compat/lists.js index 8157461d..a926fab9 100644 --- a/src/javascript/lib/core/erlang_compat/lists.js +++ b/src/javascript/lib/core/erlang_compat/lists.js @@ -4,6 +4,13 @@ function reverse(list) { return [...list].reverse(); } +function foreach(fun, list) { + list.forEach(x => fun(x)); + + return Symbol.for('ok'); +} + export default { reverse, + foreach, }; diff --git a/test/support/main.ex b/test/support/main.ex index c37a6f0e..ec6b49bd 100644 --- a/test/support/main.ex +++ b/test/support/main.ex @@ -1,6 +1,6 @@ defmodule Main do def start(:normal, [callback]) do callback.("started") - Enum.each(1..5, fn(x) -> JS.console.log(x) end) + Enum.each(%{a: 1}, fn(x) -> JS.console.log(x) end) end end From f07fac7669de578d3cfad2c0f67e80f601875aee Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Sun, 25 Jun 2017 15:06:52 -0500 Subject: [PATCH 130/418] Fix tests. --- test/next/passes/translate/form_test.exs | 2 +- test/support/main.ex | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/test/next/passes/translate/form_test.exs b/test/next/passes/translate/form_test.exs index e93dab3b..5d8dc95c 100644 --- a/test/next/passes/translate/form_test.exs +++ b/test/next/passes/translate/form_test.exs @@ -76,7 +76,7 @@ defmodule ElixirScript.Translate.Forms.Test do state = %{} {js_ast, _} = Form.compile(ast, state) - assert js_ast == J.call_expression( + assert js_ast == J.new_expression( J.member_expression( J.member_expression( J.identifier("Bootstrap"), diff --git a/test/support/main.ex b/test/support/main.ex index ec6b49bd..a18d3d90 100644 --- a/test/support/main.ex +++ b/test/support/main.ex @@ -1,6 +1,5 @@ defmodule Main do def start(:normal, [callback]) do callback.("started") - Enum.each(%{a: 1}, fn(x) -> JS.console.log(x) end) end end From 4080313f57ccc96d63b5c8231d4a69a501994624 Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Sun, 25 Jun 2017 17:22:31 -0500 Subject: [PATCH 131/418] Update documentation --- CONTRIBUTING.md | 12 +++--------- FAQ.md | 27 --------------------------- README.md | 20 +------------------- 3 files changed, 4 insertions(+), 55 deletions(-) delete mode 100644 FAQ.md diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index b9884e8a..9be626f1 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -18,7 +18,7 @@ Good bug reports are extremely helpful - thank you! Guidelines for bug reports: 1. **Use the GitHub issue search** — [check if the issue has already been - reported](https://github.com/bryanjos/elixirscript/search?type=Issues). + reported](https://github.com/elixirscript/elixirscript/search?type=Issues). 2. **Check if the issue has been fixed** — try to reproduce it using the `master` branch in the repository. @@ -64,16 +64,13 @@ found in Elixir in ElixirScript. ElixirScript is broken up into the following parts: * The compiler, written in Elixir -* The standard library modules, written in Elixir -* The javascript core +* The JavaScript core The ElixirScript compiler is in the `lib` folder of the project. Here is where Elixir code is converted into JavaScript. -The standard library modules are in the `priv/std_lib` folder. - The JavaScript code is in the `src/javascript`. -This is where features such as pattern matching and the special forms are implemented. +This is where the special forms and the Erlang Compatibility Layer are defined The ElixirScript tests can be run using `mix test` @@ -82,9 +79,6 @@ The JavaScript tests can be run using `yarn test` Please make sure all tests pass after making changes. Also make sure to include tests for the changes you made. -Contributing to the standard library may be the easiest and most rewarding changes. -Don't see a module, function or macro from Elixir in ElixirScript yet? You can help by implementing it. - ## Pull requests Good pull requests - patches, improvements, new features - are a fantastic diff --git a/FAQ.md b/FAQ.md deleted file mode 100644 index 92ba2f7e..00000000 --- a/FAQ.md +++ /dev/null @@ -1,27 +0,0 @@ -# FAQ - -# Q. How do I get started? - -### A. Check out the [Getting Started](GettingStarted.md) Guide for more info. - -# Q. How much is implemented? - -### A. Check out the [Supported Modules, Functions, and Macros](Supported.md) - -## Q. Can I use it today? - -### A. Yes, but realize this is not at 1.0 yet. - -You **can** use ElixirScript on your front ends and have it work and interoperate with JavaScript modules. The problem is that most of the standard library is incomplete. - -## Q. Can I use pattern matching? - -### A. Yes - -## Q. Can I use processes? - -### A. ElixirScript does not support processes - -## Q. What about OTP? - -### A. ElixirScript does not support OTP diff --git a/README.md b/README.md index 300f89b5..a3a106c0 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ The goal is to convert a subset (or full set) of Elixir code to JavaScript, prov Requirements =========== * Erlang 20 or greater -* Elixir 1.5 or greater +* Elixir 1.5 or greater (must be compiled with Erlang 20 or greater) * Node (only for development) Usage @@ -67,21 +67,3 @@ Contributing ======== Please check the [CONTRIBUTING.md](CONTRIBUTING.md) - - -### Example projects -* [hello](https://github.com/bryanjos/hello) Shows using Phoenix + Elixirscript with file watching -* [Elixirscript frontend boilerplate](https://github.com/elixirscript/elixirscript-project-boilerplate) A boilerplate project for elixirscript frontends -* [Elixirscript React example](https://github.com/bryanjos/elixirscript_react) An example of using with React -* [Elixirscript AWS Lambda example](https://github.com/bryanjos/elixirscript_lambda) - -#### Using with Brunch -There is a plugin for using ElixirScript in your Brunch project -[here](https://www.npmjs.com/package/elixirscript-brunch) - -#### Using with Webpack -There is a loader for using ElixirScript in your Webpack project -[here](https://www.npmjs.com/package/elixirscript-loader) - -#### 1.0 Roadmap -There is a [1.0.0 Milestone](https://github.com/bryanjos/elixirscript/milestones/1.0.0) defined which includes issues that are needed to be cleared before 1.0 can be reached. From 01a51b395c05a227b759544d61f849d498d272bf Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Sun, 25 Jun 2017 18:22:56 -0500 Subject: [PATCH 132/418] Removed old compiler code and promoted new compiler code --- lib/elixir_script.ex | 238 ----- lib/elixir_script/{next => }/beam.ex | 0 lib/elixir_script/{next => }/compiler.ex | 0 lib/elixir_script/lib/js.ex | 40 + .../elixir_script/lib}/string.ex | 13 +- lib/elixir_script/module_systems/common.ex | 2 +- lib/elixir_script/module_systems/es.ex | 4 +- lib/elixir_script/module_systems/namespace.ex | 6 +- lib/elixir_script/module_systems/umd.ex | 2 +- lib/elixir_script/passes/ast_from_file.ex | 26 - .../passes/consolidate_protocols.ex | 103 --- lib/elixir_script/passes/create_js_modules.ex | 169 ---- lib/elixir_script/passes/find_functions.ex | 92 -- lib/elixir_script/passes/find_load_only.ex | 33 - lib/elixir_script/passes/find_modules.ex | 181 ---- .../{next => }/passes/find_used_functions.ex | 0 .../{next => }/passes/find_used_modules.ex | 0 lib/elixir_script/passes/handle_output.ex | 62 -- .../passes/handle_overridables.ex | 87 -- lib/elixir_script/passes/init.ex | 10 - lib/elixir_script/passes/java_script_ast.ex | 43 - lib/elixir_script/passes/java_script_code.ex | 32 - lib/elixir_script/passes/load_modules.ex | 27 - .../passes/load_modules_for_quoted.ex | 28 - lib/elixir_script/{next => }/passes/output.ex | 12 +- .../{next => }/passes/output/js_module.ex | 10 +- lib/elixir_script/passes/remove_unused.ex | 31 - .../{next => }/passes/translate.ex | 0 .../{next => }/passes/translate/clause.ex | 0 .../{next => }/passes/translate/form.ex | 0 .../passes/translate/forms/bitstring.ex | 4 +- .../{next => }/passes/translate/forms/for.ex | 0 .../{next => }/passes/translate/forms/js.ex | 0 .../{next => }/passes/translate/forms/map.ex | 0 .../passes/translate/forms/match.ex | 0 .../passes/translate/forms/pattern.ex | 4 +- .../translate/forms/pattern/patterns.ex | 114 +++ .../passes/translate/forms/receive.ex | 0 .../passes/translate/forms/remote.ex | 0 .../{next => }/passes/translate/forms/try.ex | 0 .../{next => }/passes/translate/function.ex | 0 .../{next => }/passes/translate/identifier.ex | 0 .../{next => }/passes/translate/module.ex | 0 .../{next => }/passes/translate/protocol.ex | 0 lib/elixir_script/{next => }/state.ex | 0 lib/elixir_script/translator.ex | 738 ---------------- lib/elixir_script/translator/empty.ex | 8 - lib/elixir_script/translator/group.ex | 30 - lib/elixir_script/translator/kernel/def.ex | 39 - .../translator/kernel/defimpl.ex | 137 --- .../translator/kernel/defmodule.ex | 267 ------ .../translator/kernel/defprotocol.ex | 93 -- .../translator/kernel/expression.ex | 18 - lib/elixir_script/translator/kernel/js.ex | 237 ----- .../kernel/special_forms/bitstring.ex | 147 ---- .../translator/kernel/special_forms/block.ex | 14 - .../translator/kernel/special_forms/call.ex | 214 ----- .../kernel/special_forms/capture.ex | 44 - .../translator/kernel/special_forms/case.ex | 17 - .../translator/kernel/special_forms/cond.ex | 34 - .../translator/kernel/special_forms/fn.ex | 254 ------ .../translator/kernel/special_forms/for.ex | 130 --- .../kernel/special_forms/identifier.ex | 98 --- .../translator/kernel/special_forms/map.ex | 91 -- .../translator/kernel/special_forms/match.ex | 93 -- .../kernel/special_forms/primitive.ex | 99 --- .../translator/kernel/special_forms/quote.ex | 87 -- .../translator/kernel/special_forms/struct.ex | 116 --- .../translator/kernel/special_forms/try.ex | 115 --- .../translator/kernel/special_forms/with.ex | 52 -- lib/elixir_script/translator/lexical_scope.ex | 394 --------- .../translator/pattern_matching.ex | 278 ------ lib/elixir_script/translator/rewriter.ex | 495 ----------- lib/elixir_script/translator/state.ex | 143 --- .../translator/unsupported_error.ex | 8 - lib/elixir_script/translator/utils.ex | 65 -- lib/mix/tasks/compile.elixir_script.ex | 2 +- priv/std_lib/agent.ex | 54 -- priv/std_lib/atom.ex | 13 - priv/std_lib/base.ex | 30 - priv/std_lib/bitwise.ex | 74 -- priv/std_lib/bootstrap/functions.ex | 70 -- priv/std_lib/collectable.ex | 34 - priv/std_lib/enum.ex | 358 -------- priv/std_lib/enum/out_of_bounds_error.ex | 3 - priv/std_lib/enumerable.ex | 38 - priv/std_lib/exceptions.ex | 7 - priv/std_lib/integer.ex | 29 - priv/std_lib/io.ex | 22 - priv/std_lib/js.ex | 108 --- priv/std_lib/kernel.ex | 209 ----- priv/std_lib/keyword.ex | 46 - priv/std_lib/list.ex | 265 ------ priv/std_lib/macro/env.ex | 37 - priv/std_lib/map.ex | 204 ----- priv/std_lib/map_set.ex | 100 --- priv/std_lib/module.ex | 9 - priv/std_lib/range.ex | 12 - priv/std_lib/regex.ex | 71 -- priv/std_lib/store.ex | 45 - priv/std_lib/string/chars.ex | 48 -- priv/std_lib/tuple.ex | 63 -- rollup.config.js | 5 +- .../lib/core/erlang_compat/erlang.js | 40 +- test/cli_test.exs | 8 - test/passes/create_js_modules_test.exs | 30 - test/passes/handle_output_test.exs | 21 - .../{next => }/passes/translate/form_test.exs | 2 +- .../passes/translate/forms/map_test.exs | 0 .../passes/translate/forms/receive_test.exs | 0 .../passes/translate/forms/remote_test.exs | 0 test/prelude/js_test.exs | 52 -- test/prelude/kernel_test.exs | 44 - test/support/main.ex | 3 + test/test_helper.exs | 84 -- test/translator/access_test.exs | 14 - test/translator/atom_test.exs | 14 - test/translator/bitstring_test.exs | 95 -- test/translator/bitwise_test.exs | 15 - test/translator/bug_test.exs | 161 ---- test/translator/capture_test.exs | 131 --- test/translator/case_test.exs | 211 ----- test/translator/commonjs_test.exs | 22 - test/translator/cond_test.exs | 58 -- test/translator/defdelegate_test.exs | 28 - test/translator/defmodule_test.exs | 176 ---- test/translator/for_test.exs | 202 ----- test/translator/function_test.exs | 815 ------------------ test/translator/js_test.exs | 55 -- test/translator/kernel_test.exs | 89 -- test/translator/list_test.exs | 70 -- test/translator/map_test.exs | 87 -- test/translator/match_test.exs | 84 -- test/translator/nil_test.exs | 9 - test/translator/number_test.exs | 18 - test/translator/pattern_matching_test.exs | 257 ------ test/translator/quote_test.exs | 142 --- test/translator/string_test.exs | 43 - test/translator/struct_test.exs | 233 ----- test/translator/try_test.exs | 231 ----- test/translator/tuple_test.exs | 35 - test/translator/umd_test.exs | 29 - test/translator/with_test.exs | 75 -- 143 files changed, 224 insertions(+), 11343 deletions(-) rename lib/elixir_script/{next => }/beam.ex (100%) rename lib/elixir_script/{next => }/compiler.ex (100%) create mode 100644 lib/elixir_script/lib/js.ex rename {priv/std_lib => lib/elixir_script/lib}/string.ex (94%) delete mode 100644 lib/elixir_script/passes/ast_from_file.ex delete mode 100644 lib/elixir_script/passes/consolidate_protocols.ex delete mode 100644 lib/elixir_script/passes/create_js_modules.ex delete mode 100644 lib/elixir_script/passes/find_functions.ex delete mode 100644 lib/elixir_script/passes/find_load_only.ex delete mode 100644 lib/elixir_script/passes/find_modules.ex rename lib/elixir_script/{next => }/passes/find_used_functions.ex (100%) rename lib/elixir_script/{next => }/passes/find_used_modules.ex (100%) delete mode 100644 lib/elixir_script/passes/handle_output.ex delete mode 100644 lib/elixir_script/passes/handle_overridables.ex delete mode 100644 lib/elixir_script/passes/init.ex delete mode 100644 lib/elixir_script/passes/java_script_ast.ex delete mode 100644 lib/elixir_script/passes/java_script_code.ex delete mode 100644 lib/elixir_script/passes/load_modules.ex delete mode 100644 lib/elixir_script/passes/load_modules_for_quoted.ex rename lib/elixir_script/{next => }/passes/output.ex (85%) rename lib/elixir_script/{next => }/passes/output/js_module.ex (92%) delete mode 100644 lib/elixir_script/passes/remove_unused.ex rename lib/elixir_script/{next => }/passes/translate.ex (100%) rename lib/elixir_script/{next => }/passes/translate/clause.ex (100%) rename lib/elixir_script/{next => }/passes/translate/form.ex (100%) rename lib/elixir_script/{next => }/passes/translate/forms/bitstring.ex (96%) rename lib/elixir_script/{next => }/passes/translate/forms/for.ex (100%) rename lib/elixir_script/{next => }/passes/translate/forms/js.ex (100%) rename lib/elixir_script/{next => }/passes/translate/forms/map.ex (100%) rename lib/elixir_script/{next => }/passes/translate/forms/match.ex (100%) rename lib/elixir_script/{next => }/passes/translate/forms/pattern.ex (98%) create mode 100644 lib/elixir_script/passes/translate/forms/pattern/patterns.ex rename lib/elixir_script/{next => }/passes/translate/forms/receive.ex (100%) rename lib/elixir_script/{next => }/passes/translate/forms/remote.ex (100%) rename lib/elixir_script/{next => }/passes/translate/forms/try.ex (100%) rename lib/elixir_script/{next => }/passes/translate/function.ex (100%) rename lib/elixir_script/{next => }/passes/translate/identifier.ex (100%) rename lib/elixir_script/{next => }/passes/translate/module.ex (100%) rename lib/elixir_script/{next => }/passes/translate/protocol.ex (100%) rename lib/elixir_script/{next => }/state.ex (100%) delete mode 100644 lib/elixir_script/translator.ex delete mode 100644 lib/elixir_script/translator/empty.ex delete mode 100644 lib/elixir_script/translator/group.ex delete mode 100644 lib/elixir_script/translator/kernel/def.ex delete mode 100644 lib/elixir_script/translator/kernel/defimpl.ex delete mode 100644 lib/elixir_script/translator/kernel/defmodule.ex delete mode 100644 lib/elixir_script/translator/kernel/defprotocol.ex delete mode 100644 lib/elixir_script/translator/kernel/expression.ex delete mode 100644 lib/elixir_script/translator/kernel/js.ex delete mode 100644 lib/elixir_script/translator/kernel/special_forms/bitstring.ex delete mode 100644 lib/elixir_script/translator/kernel/special_forms/block.ex delete mode 100644 lib/elixir_script/translator/kernel/special_forms/call.ex delete mode 100644 lib/elixir_script/translator/kernel/special_forms/capture.ex delete mode 100644 lib/elixir_script/translator/kernel/special_forms/case.ex delete mode 100644 lib/elixir_script/translator/kernel/special_forms/cond.ex delete mode 100644 lib/elixir_script/translator/kernel/special_forms/fn.ex delete mode 100644 lib/elixir_script/translator/kernel/special_forms/for.ex delete mode 100644 lib/elixir_script/translator/kernel/special_forms/identifier.ex delete mode 100644 lib/elixir_script/translator/kernel/special_forms/map.ex delete mode 100644 lib/elixir_script/translator/kernel/special_forms/match.ex delete mode 100644 lib/elixir_script/translator/kernel/special_forms/primitive.ex delete mode 100644 lib/elixir_script/translator/kernel/special_forms/quote.ex delete mode 100644 lib/elixir_script/translator/kernel/special_forms/struct.ex delete mode 100644 lib/elixir_script/translator/kernel/special_forms/try.ex delete mode 100644 lib/elixir_script/translator/kernel/special_forms/with.ex delete mode 100644 lib/elixir_script/translator/lexical_scope.ex delete mode 100644 lib/elixir_script/translator/pattern_matching.ex delete mode 100644 lib/elixir_script/translator/rewriter.ex delete mode 100644 lib/elixir_script/translator/state.ex delete mode 100644 lib/elixir_script/translator/unsupported_error.ex delete mode 100644 lib/elixir_script/translator/utils.ex delete mode 100644 priv/std_lib/agent.ex delete mode 100644 priv/std_lib/atom.ex delete mode 100644 priv/std_lib/base.ex delete mode 100644 priv/std_lib/bitwise.ex delete mode 100644 priv/std_lib/bootstrap/functions.ex delete mode 100644 priv/std_lib/collectable.ex delete mode 100644 priv/std_lib/enum.ex delete mode 100644 priv/std_lib/enum/out_of_bounds_error.ex delete mode 100644 priv/std_lib/enumerable.ex delete mode 100644 priv/std_lib/exceptions.ex delete mode 100644 priv/std_lib/integer.ex delete mode 100644 priv/std_lib/io.ex delete mode 100644 priv/std_lib/js.ex delete mode 100644 priv/std_lib/kernel.ex delete mode 100644 priv/std_lib/keyword.ex delete mode 100644 priv/std_lib/list.ex delete mode 100644 priv/std_lib/macro/env.ex delete mode 100644 priv/std_lib/map.ex delete mode 100644 priv/std_lib/map_set.ex delete mode 100644 priv/std_lib/module.ex delete mode 100644 priv/std_lib/range.ex delete mode 100644 priv/std_lib/regex.ex delete mode 100644 priv/std_lib/store.ex delete mode 100644 priv/std_lib/string/chars.ex delete mode 100644 priv/std_lib/tuple.ex delete mode 100644 test/cli_test.exs delete mode 100644 test/passes/create_js_modules_test.exs delete mode 100644 test/passes/handle_output_test.exs rename test/{next => }/passes/translate/form_test.exs (98%) rename test/{next => }/passes/translate/forms/map_test.exs (100%) rename test/{next => }/passes/translate/forms/receive_test.exs (100%) rename test/{next => }/passes/translate/forms/remote_test.exs (100%) delete mode 100644 test/prelude/js_test.exs delete mode 100644 test/prelude/kernel_test.exs delete mode 100644 test/translator/access_test.exs delete mode 100644 test/translator/atom_test.exs delete mode 100644 test/translator/bitstring_test.exs delete mode 100644 test/translator/bitwise_test.exs delete mode 100644 test/translator/bug_test.exs delete mode 100644 test/translator/capture_test.exs delete mode 100644 test/translator/case_test.exs delete mode 100644 test/translator/commonjs_test.exs delete mode 100644 test/translator/cond_test.exs delete mode 100644 test/translator/defdelegate_test.exs delete mode 100644 test/translator/defmodule_test.exs delete mode 100644 test/translator/for_test.exs delete mode 100644 test/translator/function_test.exs delete mode 100644 test/translator/js_test.exs delete mode 100644 test/translator/kernel_test.exs delete mode 100644 test/translator/list_test.exs delete mode 100644 test/translator/map_test.exs delete mode 100644 test/translator/match_test.exs delete mode 100644 test/translator/nil_test.exs delete mode 100644 test/translator/number_test.exs delete mode 100644 test/translator/pattern_matching_test.exs delete mode 100644 test/translator/quote_test.exs delete mode 100644 test/translator/string_test.exs delete mode 100644 test/translator/struct_test.exs delete mode 100644 test/translator/try_test.exs delete mode 100644 test/translator/tuple_test.exs delete mode 100644 test/translator/umd_test.exs delete mode 100644 test/translator/with_test.exs diff --git a/lib/elixir_script.ex b/lib/elixir_script.ex index 298b80c9..d92c6861 100644 --- a/lib/elixir_script.ex +++ b/lib/elixir_script.ex @@ -1,240 +1,2 @@ defmodule ElixirScript do - require Logger - - @moduledoc """ - Translates Elixir into JavaScript. - - All compile functions return a list of - transpiled javascript code or a tuple consisting of - the file name for the code and the transpiled javascript code. - - All compile functions also take an optional opts parameter - that controls transpiler output. - - Available options are: - * `:include_path` - a boolean controlling whether to return just the JavaScript code - or a tuple of the file name and the JavaScript code - * `:core_path` - The es6 import path used to import the elixirscript core. - When using this option, the Elixir.js file is not exported - * `:full_build` - For compile_path, tells the compiler to perform a full build instead of incremental one - * `:output` - option to tell compiler how to output data - * `nil`: Return as list - * `:stdout`: Write to standard out - * `path (string)`: Write to specified path - """ - - defmacro __using__(_) do - quote do - import Kernel, except: [ - if: 2, unless: 2, abs: 1, apply: 2, apply: 3, binary_part: 3, hd: 1, - tl: 1, is_atom: 1, is_binary: 1, is_bitstring: 1, is_boolean: 1, is_float: 1, - is_function: 1, is_function: 2, is_integer: 1, is_list: 1, is_number: 1, - is_pid: 1, is_tuple: 1, is_map: 1, is_port: 1, is_reference: 1, length: 1, - map_size: 1, max: 2, min: 2, round: 1, trunc: 1, tuple_size: 1, elem: 2, is_nil: 1, - make_ref: 1, spawn: 1, spawn: 3, spawn_link: 1, spawn_link: 3, spawn_monitor: 1, - spawn_monitor: 3, send: 2, self: 0, match?: 2, to_string: 1, "|>": 2, in: 2, "..": 2, - sigil_r: 2 - ] - import ElixirScript.Kernel - require JS - end - end - - # This is the serialized state of the ElixirScript.State module containing references to the standard library - @lib_path Application.get_env(:elixir_script, :lib_path) - @version Mix.Project.config[:version] - - @doc """ - Compiles the given Elixir code string - """ - @spec compile(binary, Map.t) :: [binary | {binary, binary} | :ok] - def compile(elixir_code, opts \\ %{}) do - elixir_code - |> List.wrap - |> Enum.map(fn(x) -> - x - |> Code.string_to_quoted! - |> compile_quoted(opts) - end) - |> List.flatten - end - - @doc """ - Compiles the given Elixir code in quoted form - """ - @spec compile_quoted(Macro.t, Map.t) :: [binary | {binary, binary} | :ok] - def compile_quoted(quoted, opts \\ %{}) do - - opts = build_compiler_options(opts) - - data = quoted - |> get_modules_from_quoted - |> Enum.map(fn(x) -> %{ast: x, app: :app} end) - - std_lib_quoted = get_quoted_std_lib() - - %{data: std_lib_quoted ++ data} - |> ElixirScript.Passes.Init.execute(opts) - |> shared_passes(opts) - end - - defp shared_passes(compiler_data, opts) do - compiler_data - |> ElixirScript.Passes.FindModules.execute(opts) - |> ElixirScript.Passes.FindLoadOnly.execute(opts) - |> ElixirScript.Passes.HandleOverridables.execute(opts) - |> ElixirScript.Passes.FindFunctions.execute(opts) - |> ElixirScript.Passes.JavaScriptAST.execute(opts) - |> ElixirScript.Passes.ConsolidateProtocols.execute(opts) - |> ElixirScript.Passes.RemoveUnused.execute(opts) - |> ElixirScript.Passes.CreateJSModules.execute(opts) - |> ElixirScript.Passes.JavaScriptCode.execute(opts) - |> ElixirScript.Passes.HandleOutput.execute(opts) - end - - defp get_quoted_std_lib() do - files = [get_std_lib_path(), "**", "*.ex"] - |> Path.join - |> Path.wildcard - - files - |> Enum.map(fn path -> File.read!(path) end) - |> Enum.map(&Code.string_to_quoted!(&1)) - |> Enum.flat_map(&get_modules_from_quoted(&1)) - |> Enum.map(fn(x) -> %{ast: x, app: :elixir} end) - end - - defp get_modules_from_quoted(quoted) do - results = case quoted do - {:__block__, _, list} -> - {modules, not_modules} = Enum.partition(list, - fn - {type, _, _ } when type in [:defprotocol, :defimpl, :defmodule] -> - true - _ -> - false - end) - - temp_module = case not_modules do - [] -> - [] - _ -> - [{:defmodule, [], [{:__aliases__, [], [:ElixirScript, :Temp]}, [do: { :__block__, [], not_modules }]]}] - end - - modules ++ temp_module - - {type, _, _ } = x when type in [:defprotocol, :defimpl, :defmodule] -> - x - x -> - {:defmodule, [], [{:__aliases__, [], [:ElixirScript, :Temp]}, [do: { :__block__, [], [x] }]]} - end - - List.wrap(results) - end - - @doc """ - Compiles the elixir files found at the given path - """ - @spec compile_path(binary | [binary] | map, Map.t) :: [binary | {binary, binary} | :ok] - def compile_path(path, opts \\ %{}) - - def compile_path(path, opts) when is_binary(path) do - compile_path([path], opts) - end - - def compile_path(path, opts) when is_list(path) do - built_opts = build_compiler_options(opts) - - app_name = cond do - !is_nil(built_opts[:app]) -> - built_opts[:app] - Code.ensure_loaded?(Mix) -> - Mix.Project.config()[:app] - true -> - :app - end - - compile_path(Map.put(%{}, app_name, path), opts) - end - - def compile_path(path, opts) do - opts = build_compiler_options(opts) - - deps = path - |> Map.to_list - |> Enum.map(fn {app, path} -> {app, List.wrap(path)} end) - - deps_wrapped = [{:elixir, List.wrap(get_std_lib_path())}] ++ deps - - result = %{data: deps_wrapped} - |> ElixirScript.Passes.Init.execute(opts) - |> ElixirScript.Passes.ASTFromFile.execute(opts) - |> ElixirScript.Passes.LoadModules.execute(opts) - |> shared_passes(opts) - - result - end - - defp build_compiler_options(opts) do - default_options = Map.new - |> Map.put(:include_path, false) - |> Map.put(:root, nil) - |> Map.put(:env, __ENV__) - |> Map.put(:import_standard_libs, true) - |> Map.put(:core_path, "Elixir.Bootstrap") - |> Map.put(:full_build, false) - |> Map.put(:output, nil) - |> Map.put(:app, :app) - |> Map.put(:format, :es) - |> Map.put(:js_modules, []) - |> Map.put(:remove_unused, false) - - options = Map.merge(default_options, opts) - Map.put(options, :module_formatter, get_module_formatter(options[:format])) - end - - defp get_module_formatter(:umd) do - ElixirScript.ModuleSystems.UMD - end - - defp get_module_formatter(:common) do - ElixirScript.ModuleSystems.Common - end - - defp get_module_formatter(_) do - ElixirScript.ModuleSystems.ES - end - - @doc """ - Returns the contents of the bootrstrap js file - """ - @spec get_bootstrap_js(string) :: string - def get_bootstrap_js(module_format) do - path = Path.join([operating_path, "build", to_string(module_format), "Elixir.Bootstrap.js"]) - File.read!(path) - end - - #Gets path to js files whether the mix project is available - #or when used as an escript - defp operating_path() do - case @lib_path do - nil -> - if Code.ensure_loaded?(Mix.Project) do - Path.join([Mix.Project.build_path, "lib", "elixir_script", "priv"]) - else - split_path = Path.split(Application.app_dir(:elixirscript)) - replaced_path = List.delete_at(split_path, length(split_path) - 1) - replaced_path = List.delete_at(replaced_path, length(replaced_path) - 1) - Path.join(replaced_path) - end - lib_path -> - lib_path - end - end - - defp get_std_lib_path() do - Path.join([operating_path(), "std_lib"]) - end - end diff --git a/lib/elixir_script/next/beam.ex b/lib/elixir_script/beam.ex similarity index 100% rename from lib/elixir_script/next/beam.ex rename to lib/elixir_script/beam.ex diff --git a/lib/elixir_script/next/compiler.ex b/lib/elixir_script/compiler.ex similarity index 100% rename from lib/elixir_script/next/compiler.ex rename to lib/elixir_script/compiler.ex diff --git a/lib/elixir_script/lib/js.ex b/lib/elixir_script/lib/js.ex new file mode 100644 index 00000000..990a2110 --- /dev/null +++ b/lib/elixir_script/lib/js.ex @@ -0,0 +1,40 @@ +defmodule JS do + @moduledoc """ + This module defines macros and functions which implement + JavaScript functionality that may not translate easily to + Elixir. For instance, creating a new object + """ + + @doc """ + Creates new JavaScript objects. + + ex: + JS.new User, ["first_name", "last_name"] + """ + defmacro new(module, params) + + @doc """ + Returns the type of the given value + """ + defmacro typeof(value) + + @doc """ + Determines if value is an instance of type. + """ + defmacro instanceof(value, type) + + @doc """ + Throws the term given + """ + defmacro throw(term) + + @doc """ + Creates a breakpoint for JavaScript debuggers to stop at + """ + defmacro debugger() + + @doc """ + The current JavaScript context + """ + defmacro this() +end diff --git a/priv/std_lib/string.ex b/lib/elixir_script/lib/string.ex similarity index 94% rename from priv/std_lib/string.ex rename to lib/elixir_script/lib/string.ex index 3d5465bc..6ace3e43 100644 --- a/priv/std_lib/string.ex +++ b/lib/elixir_script/lib/string.ex @@ -3,11 +3,11 @@ defmodule ElixirScript.String do import Kernel, except: [length: 1] def to_atom(str) do - JS.Symbol.for(str) + :erlang.binary_to_atom(str, :utf8) end def to_existing_atom(str) do - JS.Symbol.for(str) + :erlang.binary_to_existing_atom(str, :utf8) end def to_char_list(str) do @@ -198,12 +198,7 @@ defmodule ElixirScript.String do do_codepoints(str.substr(1), codepoint_list ++ [first(str).codePointAt(0)]) end - def valid_character?(codepoint) do - try do - JS.String.fromCodePoint(codepoint) != nil - rescue - _ -> - false - end + def valid?(str) do + is_binary(str) end end diff --git a/lib/elixir_script/module_systems/common.ex b/lib/elixir_script/module_systems/common.ex index c3caf08a..f5c01065 100644 --- a/lib/elixir_script/module_systems/common.ex +++ b/lib/elixir_script/module_systems/common.ex @@ -21,7 +21,7 @@ defmodule ElixirScript.ModuleSystems.Common do end defp import_module(module_name, from) do - js_module_name = ElixirScript.Translator.Identifier.make_namespace_members(module_name) + js_module_name = ElixirScript.Translate.Identifier.make_namespace_members(module_name) do_import_module(js_module_name, from) end diff --git a/lib/elixir_script/module_systems/es.ex b/lib/elixir_script/module_systems/es.ex index 4423d064..81f5bd4c 100644 --- a/lib/elixir_script/module_systems/es.ex +++ b/lib/elixir_script/module_systems/es.ex @@ -22,7 +22,7 @@ defmodule ElixirScript.ModuleSystems.ES do end defp import_namespace_module(module_name, from) do - js_module_name = ElixirScript.Translator.Identifier.make_namespace_members(module_name) + js_module_name = ElixirScript.Translate.Identifier.make_namespace_members(module_name) import_specifier = JS.import_namespace_specifier( js_module_name, @@ -33,7 +33,7 @@ defmodule ElixirScript.ModuleSystems.ES do end defp import_module(import_name, from) do - js_module_name = ElixirScript.Translator.Identifier.make_namespace_members(import_name) + js_module_name = ElixirScript.Translate.Identifier.make_namespace_members(import_name) import_specifier = JS.import_default_specifier( js_module_name diff --git a/lib/elixir_script/module_systems/namespace.ex b/lib/elixir_script/module_systems/namespace.ex index ba2f0724..92caa561 100644 --- a/lib/elixir_script/module_systems/namespace.ex +++ b/lib/elixir_script/module_systems/namespace.ex @@ -4,7 +4,7 @@ defmodule ElixirScript.ModuleSystems.Namespace do alias ElixirScript.Translator alias ElixirScript.Translator.State alias ElixirScript.Translator.Utils - alias ElixirScript.Translator.Identifier + alias ElixirScript.Translate.Identifier def build(module_name, body, exports, env) do List.wrap(make_namespace_body(module_name, body, exports)) @@ -69,12 +69,12 @@ defmodule ElixirScript.ModuleSystems.Namespace do JS.identifier("__exports") ) - exports = [JS.return_statement(JS.identifier("__exports"))] + exports = [JS.return_statement(JS.identifier("__exports"))] make = JS.member_expression( JS.call_expression( build_namespace(), - [JS.identifier("Elixir"), JS.literal(Utils.name_to_js_file_name(module_name))] + [JS.identifier("Elixir"), JS.literal(Enum.join(["Elixir"] ++ Module.split(module_name), "."))] ), JS.identifier("__load") ) diff --git a/lib/elixir_script/module_systems/umd.ex b/lib/elixir_script/module_systems/umd.ex index 5a94cb5c..c0f0d7a6 100644 --- a/lib/elixir_script/module_systems/umd.ex +++ b/lib/elixir_script/module_systems/umd.ex @@ -21,7 +21,7 @@ defmodule ElixirScript.ModuleSystems.UMD do end defp import_module(module_name, from) do - js_module_name = ElixirScript.Translator.Identifier.make_namespace_members(module_name) + js_module_name = ElixirScript.Translate.Identifier.make_namespace_members(module_name) {js_module_name, JS.literal(from)} end diff --git a/lib/elixir_script/passes/ast_from_file.ex b/lib/elixir_script/passes/ast_from_file.ex deleted file mode 100644 index 271ccdec..00000000 --- a/lib/elixir_script/passes/ast_from_file.ex +++ /dev/null @@ -1,26 +0,0 @@ -defmodule ElixirScript.Passes.ASTFromFile do - @moduledoc false - - def execute(compiler_data, opts) do - data = Enum.reduce(compiler_data.data, [], fn({dep, paths}, list) -> - - file_paths = paths - |> Enum.flat_map(fn(path) -> Path.join([path, "**", "*.{ex,exs,exjs}"]) |> Path.wildcard end) - |> Enum.reduce([], fn(path, list) -> - quoted = path - |> File.read! - |> Code.string_to_quoted! - - stat = File.stat!(path) - - list ++ [%{path: path, app: dep, stat: stat, ast: quoted}] - end) - - - list ++ file_paths - end) - - Map.put(compiler_data, :data, data) - end - -end diff --git a/lib/elixir_script/passes/consolidate_protocols.ex b/lib/elixir_script/passes/consolidate_protocols.ex deleted file mode 100644 index f0c40d2b..00000000 --- a/lib/elixir_script/passes/consolidate_protocols.ex +++ /dev/null @@ -1,103 +0,0 @@ -defmodule ElixirScript.Passes.ConsolidateProtocols do - @moduledoc false - alias ESTree.Tools.Builder, as: JS - alias ElixirScript.Translator.Utils - alias ElixirScript.Translator.State - alias ElixirScript.Translator.Identifier - require Logger - - def execute(compiler_data, opts) do - State.set_module_data(compiler_data.state, compiler_data.data) - data = State.get_module_data(compiler_data.state) - - only_protocols_and_impls = Enum.filter(data, fn - ({_, %{type: :module}}) -> - false - ({_, %{type: :consolidated}}) -> - false - _ -> - true - end) - - grouped = group_protocol_data(only_protocols_and_impls) - consolidated_protocols = update_protocols(grouped, opts) - - data = Enum.reduce(consolidated_protocols, data, fn({ key, value }, d) -> Keyword.put(d, key, value) end) - - %{ compiler_data | data: data } - end - - - defp group_protocol_data(data) do - Enum.reduce(data, %{}, fn({module_name, module_data} = dat, state) -> - if module_data.type == :protocol do - existing = Map.get(state, module_name, %{}) - existing = Map.put(existing, :protocol, dat) - Map.put(state, module_name, existing) - else - existing = Map.get(state, module_data.implements, %{}) - existing_protocol_data = Map.get(existing, :impls, []) - existing_protocol_data = existing_protocol_data ++ [dat] - existing = Map.put(existing, :impls, existing_protocol_data) - Map.put(state, module_data.implements, existing) - end - end) - end - - defp update_protocols(grouped_protocol_data, opts) do - Enum.map(grouped_protocol_data, fn - ({ protocol_name, %{ protocol: protocol, impls: impls } }) -> - make_defimpl(protocol_name, protocol, Enum.uniq(impls), opts) - - ({ protocol_name, %{ protocol: protocol } }) -> - make_defimpl(protocol_name, protocol, [], opts) - end) - end - - defp make_defimpl(name, {_, protocol}, implementations, compiler_opts) do - declarator = JS.variable_declarator( - JS.identifier("impls"), - JS.array_expression([]) - ) - - declaration = JS.variable_declaration([declarator], :let) - - default = JS.export_default_declaration(JS.identifier("impls")) - - protocol_name = Atom.to_string(name) - - app_name = protocol.app - - body = Enum.map(implementations, fn({_, impl_data}) -> - x = Utils.quoted_to_name(impl_data.for) - members = ["Elixir"] ++ Module.split(name) ++ ["DefImpl", "Elixir"] ++ Module.split(x) ++ ["__load"] - ast = JS.call_expression( - Identifier.make_namespace_members(members), - [JS.identifier("Elixir")] - ) - - - JS.call_expression( - JS.member_expression( - JS.identifier("impls"), - JS.identifier("push") - ), - [ast] - ) - end) - - module_name = String.to_atom(protocol_name <> ".DefImpl") - module_data = %{ - name: name, - module: String.to_atom(protocol_name <> ".DefImpl"), - body: [declaration] ++ body, - exports: JS.identifier("impls"), - app: app_name, - type: :consolidated, - protocol: name - } - - {module_name, module_data} - end - -end diff --git a/lib/elixir_script/passes/create_js_modules.ex b/lib/elixir_script/passes/create_js_modules.ex deleted file mode 100644 index a0cff524..00000000 --- a/lib/elixir_script/passes/create_js_modules.ex +++ /dev/null @@ -1,169 +0,0 @@ -defmodule ElixirScript.Passes.CreateJSModules do - @moduledoc false - alias ElixirScript.Translator.Utils - alias ESTree.Tools.Builder, as: JS - - def execute(compiler_data, opts) do - namespace_modules = Enum.reduce(compiler_data.data, [], fn - ({_, %{load_only: true} = module_data}, acc) -> - acc - - ({module_name, module_data}, acc) -> - if module_data.app == :elixir && opts.import_standard_libs == false do - acc - else - body = generate_namespace_module( - module_data.type, - module_name, - Map.get(module_data, :javascript_module, module_data), - opts, - compiler_data.state - ) - - acc ++ List.wrap(body) - end - end) - - compiled = compile(namespace_modules, opts) - Map.put(compiler_data, :compiled, compiled) - end - - defp generate_namespace_module(:consolidated, module_name, js_module, opts, state) do - env = ElixirScript.Translator.LexicalScope.module_scope( - js_module.name, - Utils.name_to_js_file_name(js_module.name) <> ".js", - opts.env, - state, - opts) - - body = ElixirScript.ModuleSystems.Namespace.build( - module_name, - js_module.body, - js_module.exports, - env - ) - - body - end - - defp generate_namespace_module(_, module_name, js_module, _, _) do - body = ElixirScript.ModuleSystems.Namespace.build( - module_name, - js_module.body, - js_module.exports, - js_module.env - ) - - body - end - - def compile(body, opts) do - declarator = JS.variable_declarator( - JS.identifier("Elixir"), - JS.object_expression([]) - ) - - elixir = JS.variable_declaration([declarator], :const) - - table_additions = Enum.map(opts.js_modules, fn - {module, path} -> add_import_to_table(module) - {module, path, _} -> add_import_to_table(module) - end) - - ast = opts.module_formatter.build( - [], - opts.js_modules, - [elixir, create_atom_table(), start, load] ++ table_additions ++ body, - JS.identifier("Elixir") - ) - - ast - end - - def start do - JS.assignment_expression( - :=, - JS.member_expression( - JS.identifier("Elixir"), - JS.identifier("start") - ), - JS.function_expression( - [JS.identifier(:app), JS.identifier(:args)], - [], - JS.block_statement([ - JS.call_expression( - JS.member_expression( - JS.call_expression( - JS.member_expression( - JS.identifier(:app), - JS.identifier("__load") - ), - [JS.identifier("Elixir")] - ), - JS.identifier("start") - ), - [ElixirScript.Translator.Primitive.make_atom(:normal), JS.identifier(:args)] - ) - ]) - ) - ) - end - - def load do - JS.assignment_expression( - :=, - JS.member_expression( - JS.identifier("Elixir"), - JS.identifier("load") - ), - JS.function_expression( - [JS.identifier(:module)], - [], - JS.block_statement([ - JS.return_statement( - JS.call_expression( - JS.member_expression( - JS.identifier(:module), - JS.identifier("__load") - ), - [JS.identifier("Elixir")] - ) - ) - ]) - ) - ) - end - - defp create_atom_table() do - JS.assignment_expression( - :=, - JS.member_expression( - JS.identifier("Elixir"), - JS.identifier("__table__") - ), - JS.object_expression([]) - ) - end - - defp add_import_to_table(module_name) do - ref = ElixirScript.Translator.Identifier.make_namespace_members(module_name) - JS.assignment_expression( - :=, - JS.member_expression( - JS.member_expression( - JS.identifier("Elixir"), - JS.identifier("__table__") - ), - JS.call_expression( - JS.member_expression( - JS.identifier("Symbol"), - JS.identifier("for") - ), - [JS.literal(ref.name)] - ), - true - ), - ref - ) - end -end diff --git a/lib/elixir_script/passes/find_functions.ex b/lib/elixir_script/passes/find_functions.ex deleted file mode 100644 index 0d627984..00000000 --- a/lib/elixir_script/passes/find_functions.ex +++ /dev/null @@ -1,92 +0,0 @@ -defmodule ElixirScript.Passes.FindFunctions do - @moduledoc false - @function_types [:def, :defp, :defgen, :defgenp, :defmacro, :defmacrop] - - def execute(data, _) do - new_data = Enum.map(data.data, fn { module_name, module_data } -> - - %{ - def: functions, - defp: private_functions, - defgen: generators, - defgenp: private_generators, - defmacro: macros, - defmacrop: private_macros, - defdelegate: delegates - } = get_functions_from_module(module_data.ast) - - module_data = Map.put(module_data, :functions, functions ++ generators ++ delegates) - |> Map.put(:private_functions, private_functions ++ private_generators) - |> Map.put(:macros, macros) - |> Map.put(:private_macros, private_macros) - - {module_name, module_data} - end) - - %{data | data: new_data} - end - - defp get_functions_from_module({:__block__, _, list}) do - Enum.reduce(list, new_function_map(), fn - ({type, _, [{:when, _, [{name, _, params} | _guards] }, _] }, state) when type in @function_types and is_atom(params) -> - arity = 0 - add_function_to_map(state, type, name, arity) - - ({type, _, [{:when, _, [{name, _, params} | _guards] }, _] }, state) when type in @function_types -> - arity = if is_nil(params), do: 0, else: length(params) - add_function_to_map(state, type, name, arity) - - ({type, _, [{name, _, params}, _]}, state) when type in @function_types and is_atom(params) -> - arity = 0 - add_function_to_map(state, type, name, arity) - - ({type, _, [{name, _, params}, _]}, state) when type in @function_types -> - arity = if is_nil(params), do: 0, else: length(params) - add_function_to_map(state, type, name, arity) - - ({type, _, [{name, _, params}]}, state) when is_atom(params) and type in @function_types -> - arity = 0 - add_function_to_map(state, type, name, arity) - - ({type, _, [{name, _, params}]}, state) when type in @function_types -> - arity = length(params) - add_function_to_map(state, type, name, arity) - - ({:defdelegate, _, [{name, _, params}], _}, state) -> - arity = length(params) - add_function_to_map(state, :defdelegate, name, arity) - - _, state -> - state - - end) - end - - defp new_function_map() do - %{ - def: Keyword.new, - defp: Keyword.new, - defgen: Keyword.new, - defgenp: Keyword.new, - defmacro: Keyword.new, - defmacrop: Keyword.new, - defdelegate: Keyword.new - } - end - - defp get_functions_from_module(_) do - new_function_map() - end - - defp add_function_to_map(map, type, name, arity) do - list = Map.get(map, type) - - if {name, arity} in list do - map - else - Map.put(map, type, list ++ [{ name, arity }]) - end - end - - -end diff --git a/lib/elixir_script/passes/find_load_only.ex b/lib/elixir_script/passes/find_load_only.ex deleted file mode 100644 index 86fb0754..00000000 --- a/lib/elixir_script/passes/find_load_only.ex +++ /dev/null @@ -1,33 +0,0 @@ -defmodule ElixirScript.Passes.FindLoadOnly do - @moduledoc false - - def execute(compiler_data, opts) do - data = compiler_data.data - |> Enum.map(fn({module_name, module_data}) -> - - {_, load_only} = Macro.prewalk(module_data.ast, false, fn - ({:@, _, [{:load_only, _, [true]}]} = ast, state) -> - {ast, true} - - ({:@, _, [{:load_only, _, [false]}]} = ast, state) -> - {ast, false} - - ({:@, _, [{:load_only, _, []}]} = ast, state) -> - {ast, true} - - (ast, state) -> - {ast, state} - end) - - { module_name, Map.put(module_data, :load_only, load_only) } - - end) - - - - %{ compiler_data | data: data } - end - - - -end diff --git a/lib/elixir_script/passes/find_modules.ex b/lib/elixir_script/passes/find_modules.ex deleted file mode 100644 index 143a77f5..00000000 --- a/lib/elixir_script/passes/find_modules.ex +++ /dev/null @@ -1,181 +0,0 @@ -defmodule ElixirScript.Passes.FindModules do - @moduledoc false - alias ElixirScript.Translator.Utils - alias ElixirScript.Translator.State - - @spec execute(map, map) :: map - def execute(compiler_data, opts) do - data = Enum.reduce(compiler_data.data, [], fn(data, list) -> - quoted = update_quoted(data.ast) - { _, modules } = Macro.postwalk(quoted, [], &get_defmodules(&1, &2, opts, compiler_data)) - - modules = Enum.map(modules, fn(x) -> { x.name, Map.merge(data, x) } end) - list ++ modules - end) - - Map.put(compiler_data, :data, data) - end - - defp get_defmodules({:defprotocol, _, [{:__aliases__, _, _} = the_alias, [do: {:__block__, _, _} = block]]} = ast, state, _, _) do - s = %{ name: Utils.quoted_to_name(the_alias), type: :protocol, ast: block } - { ast, state ++ [s] } - end - - defp get_defmodules({:defprotocol, _, [{:__aliases__, _, _} = the_alias, [do: spec]]} = ast, state, _, _) do - s = %{ name: Utils.quoted_to_name(the_alias), type: :protocol, ast: {:__block__, [], [spec]} } - { ast, state ++ [s] } - end - - defp get_defmodules({:defimpl, _, [ the_alias, [for: {:__aliases__, _, type_name} = type], [do: {:__block__, context, spec}] ]} = ast, state, _, compiler_data) do - {:__aliases__, _, original_name} = Utils.name_to_quoted(State.get_module_name(compiler_data.state, the_alias)) - name = original_name ++ [DefImpl] ++ [Elixir] ++ type_name - s = %{name: Utils.quoted_to_name({:__aliases__, [], name}), type: :impl, for: type, ast: {:__block__, context, spec}, implements: Utils.quoted_to_name({:__aliases__, [], original_name}) } - { ast, state ++ [s] } - end - - defp get_defmodules({:defimpl, _, [ the_alias, [for: {:__aliases__, _, type_name} = type], [do: spec] ]} = ast, state, _, compiler_data) do - {:__aliases__, _, original_name} = Utils.name_to_quoted(State.get_module_name(compiler_data.state, the_alias)) - name = original_name ++ [DefImpl] ++ [Elixir] ++ type_name - s = %{name: Utils.quoted_to_name({:__aliases__, [], name}), type: :impl, for: type, ast: {:__block__, [], [spec]}, implements: Utils.quoted_to_name({:__aliases__, [], original_name}) } - { ast, state ++ [s] } - end - - defp get_defmodules({:defmodule, _, [{:__aliases__, _, [:ElixirScript, :Temp]}, [do: body]]} = ast, state, _, _) do - s = %{name: ElixirScript.Temp, type: :module, ast: body } - { ast, state ++ [s] } - end - - - defp get_defmodules({:defmodule, _, [{:__aliases__, _, _}, [do: _]]} = ast, state, opts, _) do - { ast, do_module_processing(ast, state, opts) } - end - - defp get_defmodules(ast, state, _, _) do - { ast, state } - end - - - defp do_module_processing({:defmodule, _context1, [{:__aliases__, _, name} = the_alias, [do: body]]}, state, opts) do - { body, inner_modules } = make_inner_module_aliases(body) - - aliases = Enum.map(inner_modules, fn - ({:defmodule, _, [{:__aliases__, _, inner_module_name}, [do: _inner_module_body]]}) -> - { :alias, [], [{:__aliases__, [alias: false], name ++ inner_module_name}, [as: {:__aliases__, [alias: false], inner_module_name }] ] } - end) - - state = do_module_processing_state(inner_modules, state, name, aliases, opts) - - [%{name: Utils.quoted_to_name(the_alias), type: :module, ast: do_module_processing_body(body, aliases, opts) }] ++ state - end - - defp do_module_processing_state(inner_modules, state, name, aliases, opts) do - Enum.reduce(inner_modules, state, fn - ({:defmodule, context1, [{:__aliases__, context2, inner_module_name}, [do: inner_module_body]]}, state) -> - - module_name = Utils.quoted_to_name({:__aliases__, [], tl(name) ++ inner_module_name}) - state = Enum.reject(state, fn(x) -> x.name == module_name end) - - this_module_aliases = aliases -- [{ :alias, [], [{:__aliases__, [alias: false], name ++ inner_module_name}, [as: {:__aliases__, [alias: false], inner_module_name }] ] }] - - do_module_processing( - {:defmodule, context1, [{:__aliases__, context2, name ++ inner_module_name}, [do: add_aliases_to_body(inner_module_body, this_module_aliases)]]}, - state, opts) - end) - end - - defp do_module_processing_body(body, aliases, opts) do - body - |> case do - {:__block__, context, list } -> - list = - list - |> Enum.map(fn - {:use, _, [module, _] } = using -> - {:use, handle_use_expression(using, module, opts) } - {:use, _, [module] } = using -> - {:use, handle_use_expression(using, module, opts) } - ast -> - {:expanded, ast} - end) - |> Enum.reduce([], fn - {:use, {:__block__, _, list}}, state -> - state ++ list - {:use, ast}, state -> - state ++ [ast] - {:expanded, ast}, state -> - state ++ [ast] - end) - - {:__block__, context, list} - _ -> - body - end - |> add_aliases_to_body(aliases) - end - - defp add_aliases_to_body(body, aliases) do - case body do - { :__block__, context, body } -> - { :__block__, context, aliases ++ List.wrap(body) } - _ -> - { :__block__, [], aliases ++ List.wrap(body) } - end - end - - defp make_inner_module_aliases(body) do - case body do - nil -> - { { :__block__, [], [] }, [] } - - {:__block__, context, list2 } -> - { list2, inner_modules } = Enum.partition(list2, fn - {:defmodule, _, [{:__aliases__, _, _inner_module_name}, [do: _inner_module_body]]} -> - false - _ -> - true - end) - - { {:__block__, context, list2}, inner_modules } - {:defmodule, _, [{:__aliases__, context, _inner_module_name}, [do: _inner_module_body]]} = mod -> - { {:__block__, context, [] }, [mod] } - _ -> - { body, [] } - end - end - - defp handle_use_expression(using_ast, module, opts) do - module = Utils.quoted_to_name(module) - - eval = """ - require #{inspect module} - __ENV__ - """ - {env, _} = Code.eval_string(eval, [], opts.env) - - - case Macro.expand(using_ast, env) do - {:__block__, _, - [{:__block__, _, - [{:require, _, _}, - {{:., _, [_, :__using__]}, _, _} = ast]}]} -> - Macro.expand_once(ast, env) - end - end - - defp update_quoted(quoted) do - Macro.prewalk(quoted, fn - ({name, context, parms}) -> - context = - if context[:import] == Kernel do - Keyword.update!(context, :import, fn(_) -> ElixirScript.Kernel end) - else - context - end - - {name, context, parms} - (x) -> - x - end) - end - -end diff --git a/lib/elixir_script/next/passes/find_used_functions.ex b/lib/elixir_script/passes/find_used_functions.ex similarity index 100% rename from lib/elixir_script/next/passes/find_used_functions.ex rename to lib/elixir_script/passes/find_used_functions.ex diff --git a/lib/elixir_script/next/passes/find_used_modules.ex b/lib/elixir_script/passes/find_used_modules.ex similarity index 100% rename from lib/elixir_script/next/passes/find_used_modules.ex rename to lib/elixir_script/passes/find_used_modules.ex diff --git a/lib/elixir_script/passes/handle_output.ex b/lib/elixir_script/passes/handle_output.ex deleted file mode 100644 index eb956cdf..00000000 --- a/lib/elixir_script/passes/handle_output.ex +++ /dev/null @@ -1,62 +0,0 @@ -defmodule ElixirScript.Passes.HandleOutput do - @moduledoc false - alias ElixirScript.Translator.State - @generated_name "Elixir.App.js" - - def execute(compiler_data, opts) do - State.stop(compiler_data.state) - out(compiler_data, opts) - end - - defp out(compiler_output, %{output: nil} = compiler_opts) do - compiler_output - |> process_include_path(compiler_opts) - end - - defp out(compiler_output, %{output: :stdout} = compiler_opts) do - out = compiler_output - |> process_include_path(compiler_opts) - - code = case out do - {code, _} -> code - code -> code - end - - IO.write(concat(code)) - end - - defp out(compiler_output, %{output: output_path, core_path: _}) do - file_name = get_js_path(output_path) - - if !File.exists?(Path.dirname(file_name)) do - File.mkdir_p!(Path.dirname(file_name)) - end - - File.write!(file_name, concat(compiler_output.generated)) - end - - defp concat(code) do - "'use strict';\n" <> ElixirScript.get_bootstrap_js("iife") <> "\n" <> code - end - - def get_js_path(nil), do: @generated_name - def get_js_path(:stdout), do: @generated_name - - def get_js_path(output_path) do - case Path.extname(output_path) do - ".js" -> - output_path - _ -> - Path.join([output_path, @generated_name]) - end - end - - defp process_include_path(compiler_output, compiler_opts) do - case compiler_opts.include_path do - true -> - {compiler_output.generated, get_js_path(compiler_opts.output)} - false -> - compiler_output.generated - end - end -end diff --git a/lib/elixir_script/passes/handle_overridables.ex b/lib/elixir_script/passes/handle_overridables.ex deleted file mode 100644 index 44ae2b90..00000000 --- a/lib/elixir_script/passes/handle_overridables.ex +++ /dev/null @@ -1,87 +0,0 @@ -defmodule ElixirScript.Passes.HandleOverridables do - @moduledoc false - @function_types [:def, :defp] - - def execute(compiler_data, opts) do - new_data = Enum.map(compiler_data.data, fn { module_name, module_data } -> - overridables = get_overridables(module_data.ast) - ast = handle_overridable(module_data.ast, overridables) - module_data = Map.put(module_data, :ast, ast) - - {module_name, module_data} - end) - - Map.put(compiler_data, :data, new_data) - end - - defp get_overridables({:__block__, [], body}) do - defover = Enum.find(body, fn - {:defoverridable, _, _} -> - true - _ -> - false - end) - - if is_nil(defover) do - [] - else - {:defoverridable, _, [overridables]} = defover - overridables - end - end - - defp handle_overridable(ast, []) do - ast - end - - defp handle_overridable({:__block__, [], body}, overridables) do - result = body - |> Enum.reduce(%{overridables: [], overridable_found: false, body: []}, fn - {type, def_context, [{name, context, params}, function_body] } = ast, %{overridable_found: false} = acc when type in @function_types -> - Map.put(acc, :overridables, acc.overridables ++ [ast]) - - {:defoverridable, _, _}, acc -> - Map.put(acc, :overridable_found, true) - x, acc -> - Map.put(acc, :body, acc.body ++ [x]) - end) - - processed_overridables = Enum.map(result.overridables, fn - {type, def_context, [{name, context, params}, function_body] } = ast when type in @function_types -> - arity = get_arity(params) - - found = Enum.any?(result.body, fn - {type, _, [{name_from_body, _, params_from_body}, _] } -> - if {name, arity} == {name_from_body, get_arity(params_from_body)} do - true - else - false - end - _ -> - false - end) - - if found do - super_name = String.to_atom("__super__" <> to_string(name)) - {:defp, def_context, [{super_name, context, params}, function_body] } - else - ast - end - end) - - body = processed_overridables ++ result.body - {:__block__, [], body} - end - - defp get_arity(params) do - cond do - is_nil(params) -> - 0 - is_atom(params) -> - 0 - true -> - length(params) - end - end - -end \ No newline at end of file diff --git a/lib/elixir_script/passes/init.ex b/lib/elixir_script/passes/init.ex deleted file mode 100644 index 3ac9d5d9..00000000 --- a/lib/elixir_script/passes/init.ex +++ /dev/null @@ -1,10 +0,0 @@ -defmodule ElixirScript.Passes.Init do - @moduledoc false - alias ElixirScript.Translator.State - - def execute(compiler_data, opts) do - {:ok, pid} = State.start_link(opts, []) - Map.put(compiler_data, :state, pid) - end - -end diff --git a/lib/elixir_script/passes/java_script_ast.ex b/lib/elixir_script/passes/java_script_ast.ex deleted file mode 100644 index 9b0ab7e0..00000000 --- a/lib/elixir_script/passes/java_script_ast.ex +++ /dev/null @@ -1,43 +0,0 @@ -defmodule ElixirScript.Passes.JavaScriptAST do - @moduledoc false - alias ElixirScript.Translator.Utils - alias ElixirScript.Translator.State - - def execute(compiler_data, opts) do - - State.set_module_data(compiler_data.state, compiler_data.data) - State.set_loaded_modules(compiler_data.state, Map.get(compiler_data, :loaded_modules, [])) - - data = compiler_data.state - |> State.get_module_data - |> Enum.reject(fn {_, module_data} -> - module_data.app == :elixir && opts.import_standard_libs == false - end) - |> Enum.map(fn({module_name, module_data}) -> - module_data = compile(module_data, opts, compiler_data.state) - {module_name, module_data} - end) - - %{ compiler_data | data: data } - end - - defp compile(%{load_only: true} = module_data, opts, state) do - module_data - end - - defp compile(module_data, opts, state) do - - env = ElixirScript.Translator.LexicalScope.module_scope(module_data.name, Utils.name_to_js_file_name(module_data.name) <> ".js", opts.env, state, opts) - - module = case module_data.type do - :module -> - ElixirScript.Translator.Defmodule.make_module(module_data.name, module_data.ast, env) - :protocol -> - ElixirScript.Translator.Defprotocol.make(module_data.name, module_data.functions, env) - :impl -> - ElixirScript.Translator.Defimpl.make(module_data.name, module_data.for, module_data.ast, env) - end - - Map.put(module_data, :javascript_module, module) - end -end diff --git a/lib/elixir_script/passes/java_script_code.ex b/lib/elixir_script/passes/java_script_code.ex deleted file mode 100644 index 37e212ba..00000000 --- a/lib/elixir_script/passes/java_script_code.ex +++ /dev/null @@ -1,32 +0,0 @@ -defmodule ElixirScript.Passes.JavaScriptCode do - @moduledoc false - alias ESTree.Tools.Builder - alias ESTree.Tools.Generator - - def execute(compiler_data, _) do - parent = self - - js_code = compiler_data.compiled - |> List.wrap - |> Builder.program - |> prepare_js_ast - |> Generator.generate - - Map.put(compiler_data, :generated, js_code) - end - - defp prepare_js_ast(js_ast) do - case js_ast do - modules when is_list(modules) -> - modules - |> Enum.reduce([], &(&2 ++ &1.body)) - |> Builder.program - %ElixirScript.Translator.Group{body: body} -> - Builder.program(body) - %ElixirScript.Translator.Empty{} -> - Builder.program([]) - _ -> - js_ast - end - end -end diff --git a/lib/elixir_script/passes/load_modules.ex b/lib/elixir_script/passes/load_modules.ex deleted file mode 100644 index 85e2edb2..00000000 --- a/lib/elixir_script/passes/load_modules.ex +++ /dev/null @@ -1,27 +0,0 @@ -defmodule ElixirScript.Passes.LoadModules do - @moduledoc false - def execute(compiler_data, _) do - ex_files = compiler_data.data - |> Enum.filter(fn - {_, %{app: :elixir}} -> - false - %{app: :elixir} -> - false - _ -> true - end) - |> Enum.map(fn - { _, %{path: path} } -> path - %{path: path} -> path - end) - - loaded_modules = case Enum.reverse(ex_files) do - [] -> - [] - files -> - Kernel.ParallelCompiler.files(files) - end - - Map.put(compiler_data, :loaded_modules, loaded_modules) - end - -end diff --git a/lib/elixir_script/passes/load_modules_for_quoted.ex b/lib/elixir_script/passes/load_modules_for_quoted.ex deleted file mode 100644 index 7c737dd1..00000000 --- a/lib/elixir_script/passes/load_modules_for_quoted.ex +++ /dev/null @@ -1,28 +0,0 @@ -defmodule ElixirScript.Passes.LoadModulesForQuoted do - @moduledoc false - def execute(compiler_data, _) do - quoted = compiler_data.data - |> Enum.filter(fn - {_, %{app: :elixir}} -> - false - %{app: :elixir} -> - false - _ -> true - end) - |> Enum.map(fn - {_, %{ast: ast}} -> ast - %{ast: ast} -> ast - end) - - loaded_modules = Map.get(compiler_data, :loaded_modules, []) - - loaded_modules_from_quoted = quoted - |> Enum.map(&Code.compile_quoted(&1)) - |> List.flatten - |> Enum.map(fn {mod, _} -> mod end) - - - Map.put(compiler_data, :loaded_modules, loaded_modules ++ loaded_modules_from_quoted) - end - -end \ No newline at end of file diff --git a/lib/elixir_script/next/passes/output.ex b/lib/elixir_script/passes/output.ex similarity index 85% rename from lib/elixir_script/next/passes/output.ex rename to lib/elixir_script/passes/output.ex index cec29f28..9b175f90 100644 --- a/lib/elixir_script/next/passes/output.ex +++ b/lib/elixir_script/passes/output.ex @@ -33,20 +33,22 @@ defmodule ElixirScript.Output do end defp concat(code) do - bootstrap_code = ElixirScript.get_bootstrap_js("iife") + bootstrap_code = get_bootstrap_js() "'use strict';\n#{bootstrap_code}\n#{code}" end + defp get_bootstrap_js() do + operating_path = Path.join([Mix.Project.build_path, "lib", "elixir_script", "priv"]) + path = Path.join([operating_path, "build", "iife", "Elixir.Bootstrap.js"]) + File.read!(path) + end + defp prepare_js_ast(js_ast) do case js_ast do modules when is_list(modules) -> modules |> Enum.reduce([], &(&2 ++ &1.body)) |> Builder.program - %ElixirScript.Translator.Group{body: body} -> - Builder.program(body) - %ElixirScript.Translator.Empty{} -> - Builder.program([]) _ -> js_ast end diff --git a/lib/elixir_script/next/passes/output/js_module.ex b/lib/elixir_script/passes/output/js_module.ex similarity index 92% rename from lib/elixir_script/next/passes/output/js_module.ex rename to lib/elixir_script/passes/output/js_module.ex index 60eba1e9..c0aa3346 100644 --- a/lib/elixir_script/next/passes/output/js_module.ex +++ b/lib/elixir_script/passes/output/js_module.ex @@ -27,6 +27,14 @@ defmodule ElixirScript.Output.JSModule do end def start do + normal = J.call_expression( + J.member_expression( + J.identifier("Symbol"), + J.identifier("for") + ), + [J.literal("normal")] + ) + J.assignment_expression( :=, J.member_expression( @@ -48,7 +56,7 @@ defmodule ElixirScript.Output.JSModule do ), J.identifier("start") ), - [ElixirScript.Translator.Primitive.make_atom(:normal), J.identifier(:args)] + [normal, J.identifier(:args)] ) ]) ) diff --git a/lib/elixir_script/passes/remove_unused.ex b/lib/elixir_script/passes/remove_unused.ex deleted file mode 100644 index 728f511b..00000000 --- a/lib/elixir_script/passes/remove_unused.ex +++ /dev/null @@ -1,31 +0,0 @@ -defmodule ElixirScript.Passes.RemoveUnused do - @moduledoc false - alias ElixirScript.Translator.Utils - alias ElixirScript.Translator.State - - def execute(compiler_data, %{remove_unused: false}) do - compiler_data - end - - def execute(compiler_data, opts) do - module_refs = State.list_module_references(compiler_data.state) - - data = Enum.reject(compiler_data.data, fn - {_, %{type: :impl} = module_data} -> - length(Keyword.get(module_refs, module_data.implements, [])) == 0 - {_, %{type: :consolidated} = module_data} -> - length(Keyword.get(module_refs, module_data.protocol, [])) == 0 - {module, module_data} -> - cond do - Enum.member?(module_data.functions, {:start, 2}) -> - false - length(Keyword.get(module_refs, module, [])) > 0 -> - false - true -> - true - end - end) - - %{ compiler_data | data: data } - end -end \ No newline at end of file diff --git a/lib/elixir_script/next/passes/translate.ex b/lib/elixir_script/passes/translate.ex similarity index 100% rename from lib/elixir_script/next/passes/translate.ex rename to lib/elixir_script/passes/translate.ex diff --git a/lib/elixir_script/next/passes/translate/clause.ex b/lib/elixir_script/passes/translate/clause.ex similarity index 100% rename from lib/elixir_script/next/passes/translate/clause.ex rename to lib/elixir_script/passes/translate/clause.ex diff --git a/lib/elixir_script/next/passes/translate/form.ex b/lib/elixir_script/passes/translate/form.ex similarity index 100% rename from lib/elixir_script/next/passes/translate/form.ex rename to lib/elixir_script/passes/translate/form.ex diff --git a/lib/elixir_script/next/passes/translate/forms/bitstring.ex b/lib/elixir_script/passes/translate/forms/bitstring.ex similarity index 96% rename from lib/elixir_script/next/passes/translate/forms/bitstring.ex rename to lib/elixir_script/passes/translate/forms/bitstring.ex index 14af8f2b..dfe5f495 100644 --- a/lib/elixir_script/next/passes/translate/forms/bitstring.ex +++ b/lib/elixir_script/passes/translate/forms/bitstring.ex @@ -57,10 +57,10 @@ defmodule ElixirScript.Translate.Forms.Bitstring do do_compile_element({:binary, translate_element(element, state)}) end - def translate_element(ElixirScript.Translator.PatternMatching, _) do + def translate_element(ElixirScript.Translate.Forms.Pattern.Patterns, _) do JS.object_expression([JS.property( JS.literal("value"), - ElixirScript.Translator.PatternMatching.parameter() + ElixirScript.Translate.Forms.Pattern.Patterns.parameter() ) ]) end diff --git a/lib/elixir_script/next/passes/translate/forms/for.ex b/lib/elixir_script/passes/translate/forms/for.ex similarity index 100% rename from lib/elixir_script/next/passes/translate/forms/for.ex rename to lib/elixir_script/passes/translate/forms/for.ex diff --git a/lib/elixir_script/next/passes/translate/forms/js.ex b/lib/elixir_script/passes/translate/forms/js.ex similarity index 100% rename from lib/elixir_script/next/passes/translate/forms/js.ex rename to lib/elixir_script/passes/translate/forms/js.ex diff --git a/lib/elixir_script/next/passes/translate/forms/map.ex b/lib/elixir_script/passes/translate/forms/map.ex similarity index 100% rename from lib/elixir_script/next/passes/translate/forms/map.ex rename to lib/elixir_script/passes/translate/forms/map.ex diff --git a/lib/elixir_script/next/passes/translate/forms/match.ex b/lib/elixir_script/passes/translate/forms/match.ex similarity index 100% rename from lib/elixir_script/next/passes/translate/forms/match.ex rename to lib/elixir_script/passes/translate/forms/match.ex diff --git a/lib/elixir_script/next/passes/translate/forms/pattern.ex b/lib/elixir_script/passes/translate/forms/pattern.ex similarity index 98% rename from lib/elixir_script/next/passes/translate/forms/pattern.ex rename to lib/elixir_script/passes/translate/forms/pattern.ex index 14e4f4f9..89587f5f 100644 --- a/lib/elixir_script/next/passes/translate/forms/pattern.ex +++ b/lib/elixir_script/passes/translate/forms/pattern.ex @@ -1,5 +1,5 @@ defmodule ElixirScript.Translate.Forms.Pattern do - alias ElixirScript.Translator.PatternMatching, as: PM + alias ElixirScript.Translate.Forms.Pattern.Patterns, as: PM alias ESTree.Tools.Builder, as: J alias ElixirScript.Translate.Form alias ElixirScript.Translate.Forms.{Bitstring} @@ -164,7 +164,7 @@ defmodule ElixirScript.Translate.Forms.Pattern do elements = Enum.map(elements, fn ({:::, context, [{ _, _, params }, options]}) when is_atom(params) -> - Bitstring.compile_element({:::, context, [ElixirScript.Translator.PatternMatching, options]}, state) + Bitstring.compile_element({:::, context, [ElixirScript.Translate.Forms.Pattern.Patterns, options]}, state) x -> Bitstring.compile_element(x, state) end) diff --git a/lib/elixir_script/passes/translate/forms/pattern/patterns.ex b/lib/elixir_script/passes/translate/forms/pattern/patterns.ex new file mode 100644 index 00000000..d914080f --- /dev/null +++ b/lib/elixir_script/passes/translate/forms/pattern/patterns.ex @@ -0,0 +1,114 @@ +defmodule ElixirScript.Translate.Forms.Pattern.Patterns do + alias ESTree.Tools.Builder, as: J + + @patterns J.member_expression( + J.member_expression( + J.identifier("Bootstrap"), + J.identifier("Core") + ), + J.identifier("Patterns") + ) + + @wildcard J.member_expression( + @patterns, + J.identifier(:wildcard) + ) + + @parameter J.member_expression( + @patterns, + J.identifier(:variable) + ) + + @head_tail J.member_expression( + @patterns, + J.identifier(:headTail) + ) + + @starts_with J.member_expression( + @patterns, + J.identifier(:startsWith) + ) + + @capture J.member_expression( + @patterns, + J.identifier(:capture) + ) + + @bound J.member_expression( + @patterns, + J.identifier(:bound) + ) + + @_type J.member_expression( + @patterns, + J.identifier(:type) + ) + + @bitstring_match J.member_expression( + @patterns, + J.identifier(:bitStringMatch) + ) + + def wildcard() do + J.call_expression( + @wildcard, + [] + ) + end + + def parameter() do + J.call_expression( + @parameter, + [] + ) + end + + def parameter(default_value) do + J.call_expression( + @parameter, + [default_value] + ) + end + + def head_tail(headParameter, tailParameter) do + J.call_expression( + @head_tail, + [headParameter, tailParameter] + ) + end + + def starts_with(prefix) do + J.call_expression( + @starts_with, + [J.literal(prefix)] + ) + end + + def capture(value) do + J.call_expression( + @capture, + [value] + ) + end + + def bound(value) do + J.call_expression( + @bound, + [value] + ) + end + + def type(prototype, value) do + J.call_expression( + @_type, + [prototype, value] + ) + end + + def bitstring_match(values) do + J.call_expression( + @bitstring_match, + values + ) + end +end \ No newline at end of file diff --git a/lib/elixir_script/next/passes/translate/forms/receive.ex b/lib/elixir_script/passes/translate/forms/receive.ex similarity index 100% rename from lib/elixir_script/next/passes/translate/forms/receive.ex rename to lib/elixir_script/passes/translate/forms/receive.ex diff --git a/lib/elixir_script/next/passes/translate/forms/remote.ex b/lib/elixir_script/passes/translate/forms/remote.ex similarity index 100% rename from lib/elixir_script/next/passes/translate/forms/remote.ex rename to lib/elixir_script/passes/translate/forms/remote.ex diff --git a/lib/elixir_script/next/passes/translate/forms/try.ex b/lib/elixir_script/passes/translate/forms/try.ex similarity index 100% rename from lib/elixir_script/next/passes/translate/forms/try.ex rename to lib/elixir_script/passes/translate/forms/try.ex diff --git a/lib/elixir_script/next/passes/translate/function.ex b/lib/elixir_script/passes/translate/function.ex similarity index 100% rename from lib/elixir_script/next/passes/translate/function.ex rename to lib/elixir_script/passes/translate/function.ex diff --git a/lib/elixir_script/next/passes/translate/identifier.ex b/lib/elixir_script/passes/translate/identifier.ex similarity index 100% rename from lib/elixir_script/next/passes/translate/identifier.ex rename to lib/elixir_script/passes/translate/identifier.ex diff --git a/lib/elixir_script/next/passes/translate/module.ex b/lib/elixir_script/passes/translate/module.ex similarity index 100% rename from lib/elixir_script/next/passes/translate/module.ex rename to lib/elixir_script/passes/translate/module.ex diff --git a/lib/elixir_script/next/passes/translate/protocol.ex b/lib/elixir_script/passes/translate/protocol.ex similarity index 100% rename from lib/elixir_script/next/passes/translate/protocol.ex rename to lib/elixir_script/passes/translate/protocol.ex diff --git a/lib/elixir_script/next/state.ex b/lib/elixir_script/state.ex similarity index 100% rename from lib/elixir_script/next/state.ex rename to lib/elixir_script/state.ex diff --git a/lib/elixir_script/translator.ex b/lib/elixir_script/translator.ex deleted file mode 100644 index d71914a9..00000000 --- a/lib/elixir_script/translator.ex +++ /dev/null @@ -1,738 +0,0 @@ -defmodule ElixirScript.Translator do - @moduledoc false - alias ElixirScript.Translator.Primitive - alias ElixirScript.Translator.Identifier - alias ElixirScript.Translator.Expression - alias ElixirScript.Translator.Match - alias ElixirScript.Translator.Map - alias ElixirScript.Translator.Function - alias ElixirScript.Translator.Call - alias ElixirScript.Translator.Def - alias ElixirScript.Translator.Capture - alias ElixirScript.Translator.Cond - alias ElixirScript.Translator.Case - alias ElixirScript.Translator.For - alias ElixirScript.Translator.Try - alias ElixirScript.Translator.With - alias ElixirScript.Translator.Block - alias ElixirScript.Translator.Struct - alias ElixirScript.Translator.Defmodule - alias ElixirScript.Translator.Utils - alias ElixirScript.Translator.Bitstring - alias ElixirScript.Translator.Quote - alias ElixirScript.Translator.Utils - alias ElixirScript.Translator.JS, as: JSLib - alias ESTree.Tools.Builder, as: JS - alias ElixirScript.Translator.Rewriter - - # A list of erlang modules. These are rewritten into equivalent - # JavaScript functions using ElixirScript.Translator.Rewriter - @erlang_modules [ - :erlang, - :maps, - :lists, - :gen, - :elixir_errors, - :supervisor, - :application, - :code, - :elixir_utils, - :file - ] - - @module_attributes_to_ignore [ - :doc, :moduledoc, :type, :typep, :spec, - :opaque, :callback, :macrocallback, :after_compile, - :before_compile, :behaviour, :compile, :file, - :on_definition, :on_load, :dialyzer, :vsn, :external_resource - ] - - @function_types [:def, :defp, :defgen, :defgenp] - @generator_types [:defgen, :defgenp] - - - @doc """ - Translates the given Elixir AST to JavaScript AST. The given `env` is a `ElixirScript.Macro.Env` - used to track the variables, imports, aliases, and scopes like `Macro.Env`. The JavaScript AST and - the an updated `ElixirScript.Macro.Env` is returned - """ - @spec translate(term, ElixirScript.Macro.Env.t) :: { ESTree.Node.t, ElixirScript.Macro.Env.t } - def translate(ast, env) do - do_translate(ast, env) - end - - - @doc """ - Same as `translate/2`, but returns only the JavaScript AST - """ - @spec translate!(term, ElixirScript.Macro.Env.t) :: ESTree.Node.t - def translate!(ast, env) do - { js_ast, _ } = translate(ast, env) - js_ast - end - - defp do_translate({{:., _, [{:__aliases__, _, [:JS]}, function_name]}, _, params }, env) when function_name in @generator_types do - do_translate({function_name, [], params}, env) - end - - defp do_translate({{:., _, [{:__aliases__, _, [:JS]}, function_name]}, _, params }, env) do - JSLib.translate_js_function(function_name, params, env) - end - - defp do_translate({{:., _, [{:__aliases__, context, [:JS | rest]}, function_name]}, _, params }, env) do - JSLib.translate_js_function({:__aliases__, context, rest}, function_name, params, env) - end - - defp do_translate({:__aliases__, context, [:JS | rest]}, env) do - JSLib.translate_js_module({:__aliases__, context, rest}, env) - end - - defp do_translate(ast, env) when is_number(ast) or is_binary(ast) or is_boolean(ast) or is_nil(ast) do - { Primitive.make_literal(ast), env } - end - - defp do_translate(ast, env) when is_atom(ast) do - { Primitive.make_atom(ast), env } - end - - defp do_translate([ {:|, _, [left, right] } ], env) do - quoted = quote do - [unquote(left)].concat(unquote(right)) - end - - translate(quoted, env) - end - - defp do_translate(ast, env) when is_list(ast) do - Primitive.make_list(ast, env) - end - - defp do_translate({ one, two }, env) do - quoted = quote do - JS.new(Bootstrap.Core.Tuple, [unquote(one), unquote(two)]) - end - - translate(quoted, env) - end - - defp do_translate({operator, _, [value]}, env) when operator in [:-, :!, :+] do - Expression.make_unary_expression(operator, value, env) - end - - defp do_translate({:not, _, [value]}, env) do - Expression.make_unary_expression(:!, value, env) - end - - defp do_translate({:"~~~", _, [value]}, env) do - Expression.make_unary_expression(:"~~~", value, env) - end - - defp do_translate({operator, _, [left, right]}, env) when operator in [:+, :-, :/, :*, :==, :!=, :&&, :||, :>, :<, :>=, :<=, :===, :!==, :"**"] do - Expression.make_binary_expression(operator, left, right, env) - end - - defp do_translate({:&&&, _, [left, right]}, env) do - Expression.make_binary_expression(:&, left, right, env) - end - - defp do_translate({:<<<, _, [left, right]}, env) do - Expression.make_binary_expression(:<, left, right, env) - end - - defp do_translate({:>>>, _, [left, right]}, env) do - Expression.make_binary_expression(:^, left, right, env) - end - - defp do_translate({:^^^, _, [left, right]}, env) do - Expression.make_binary_expression(:^, left, right, env) - end - - defp do_translate({:|||, _, [left, right]}, env) do - Expression.make_binary_expression(:|, left, right, env) - end - - defp do_translate({:and, _, [left, right]}, env) do - Expression.make_binary_expression(:&&, left, right, env) - end - - defp do_translate({:or, _, [left, right]}, env) do - Expression.make_binary_expression(:||, left, right, env) - end - - defp do_translate({:div, _, [left, right]}, env) do - Expression.make_binary_expression(:/, left, right, env) - end - - defp do_translate({:rem, _, [left, right]}, env) do - Expression.make_binary_expression(:%, left, right, env) - end - - defp do_translate({:<>, context, [left, right]}, env) do - translate({:+, context, [left, right]}, env) - end - - defp do_translate({:++, _, [left, right]}, env) do - translate({{:., [], [left, :concat]}, [], [right]}, env) - end - - defp do_translate({:&, _, [number]}, env) when is_number(number) do - { Identifier.make_identifier(String.to_atom("__#{number}")), env } - end - - defp do_translate({:&, _, [{:/, _, [{{:., _, [module_name, function_name]}, _, []}, arity]}]}, env) do - module_name = create_module_name(module_name, env) - js_ast = case module_name do - {mod, :local} -> - Capture.make_capture(mod, function_name, arity, env) - mod -> - Capture.make_extern_capture(mod, function_name, arity, env) - end - - { js_ast, env } - end - - defp do_translate({:&, _, [{:/, _, [{function_name, _, _}, arity]}]}, env) do - { Capture.make_capture(function_name, arity, env), env } - end - - defp do_translate({:&, _, [body]}, env) do - params = Capture.find_value_placeholders(body) |> List.flatten - Function.make_anonymous_function([{:->, [], [params, body]}], env) - end - - defp do_translate({:@, _, [{name, _, _}]}, env) - when name in @module_attributes_to_ignore do - { %ElixirScript.Translator.Empty{}, env } - end - - defp do_translate({:@, _, [{name, _, [value]}]}, env) do - { Defmodule.make_attribute(name, value, env), env } - end - - defp do_translate({:@, _, [{name, _, _}]}, env) do - { Identifier.make_identifier(name), env } - end - - defp do_translate({:%, _, [alias_info, data]}, env) do - module = case create_module_name(alias_info, env) do - {module, _} -> - module - module -> - module - end - Call.make_module_function_call(module, :__struct__, [data], env) - end - - defp do_translate({:%{}, _, [{:|, _, [map, data]}]}, env) do - Map.make_map_update(map, data, env) - end - - defp do_translate({:%{}, _, properties}, env) do - { Map.make_object(properties, env), env } - end - - defp do_translate({:<<>>, _, elements}, env) do - is_interpolated_string = Enum.all?(elements, fn(x) -> - case x do - b when is_binary(b) -> - true - {:::, _, [_target, {:binary, _, _}]} -> - true - _ -> - false - end - end) - - case is_interpolated_string do - true -> - Bitstring.make_interpolated_string(elements, env) - _ -> - Bitstring.make_bitstring(elements, env) - end - end - - defp do_translate({{:., _, [erlang_module, _]}, _, _} = erlang_function_call, env) when erlang_module in @erlang_modules do - Rewriter.rewrite(erlang_function_call) - |> translate(env) - end - - defp do_translate({{:., _, [Access, :get]}, _, [target, property]}, env) do - { Map.make_get_property(target, property, env), env } - end - - defp do_translate({:super, _, params }, env) do - { name, _ } = env.function - super_name = String.to_atom("__super__" <> to_string(name)) - - Call.make_local_function_call(super_name, params, env) - end - - defp do_translate({{:., _, [function_name]}, _, params}, env) do - Call.make_local_function_call(function_name, params, env) - end - - defp do_translate({:., _, [{:__aliases__, _, _} = module_name, function_name]} = ast, env) do - do_translate({{:., [], [module_name, function_name]}, [], []}, env) - end - - defp do_translate({{:., _, [{:__aliases__, _, _} = module_name, function_name]}, _, [] } = ast, env) do - expanded_ast = Macro.expand(ast, env.env) - - if expanded_ast == ast do - module_name = create_module_name(module_name, env) - case module_name do - {mod, :local} -> - Call.make_module_function_call(mod, function_name, env) - mod -> - Call.make_extern_function_or_property_call(mod, function_name, env) - end - else - translate(expanded_ast, env) - end - end - - defp do_translate({:., _, [module_name, function_name]} = ast, env) do - expanded_ast = Macro.expand(ast, env.env) - - if expanded_ast == ast do - Call.make_function_or_property_call(module_name, function_name, env) - else - translate(expanded_ast, env) - end - end - - defp do_translate({{:., _, [{:__aliases__, _, _} = module_name, function_name]}, _, params } = ast, env) do - expanded_ast = Macro.expand(ast, env.env) - - if expanded_ast == ast do - module_name = create_module_name(module_name, env) - case module_name do - {mod, :local} -> - Call.make_module_function_call(mod, function_name, params, env) - mod -> - Call.make_extern_function_call(mod, function_name, params, env) - end - else - translate(expanded_ast, env) - end - end - - defp do_translate({{:., _, [module_name, function_name]}, _, params} = ast, env) when is_atom(module_name) and is_atom(function_name) do - expanded_ast = Macro.expand(ast, env.env) - - if expanded_ast == ast do - Call.make_function_call(module_name, function_name, params, env) - else - translate(expanded_ast, env) - end - end - - defp do_translate({{:., _, [module_name, function_name]}, _, params } = ast, env) do - expanded_ast = Macro.expand(ast, env.env) - - if expanded_ast == ast do - Call.make_function_call(module_name, function_name, params, env) - else - translate(expanded_ast, env) - end - end - - defp do_translate({:__aliases__, _, aliases} = ast, env) do - module_name = create_module_name(ast, env) - case module_name do - {mod, :local} -> - Call.make_module_name(mod, env) - mod -> - Call.make_extern_module_name(mod, env) - end - end - - defp do_translate({:__MODULE__, _, _ }, env) do - module_name = create_module_name(env.module, env) - mod = case module_name do - {mod, _} -> - mod - mod -> - mod - end - - translate(mod, env) - end - - defp do_translate({:__block__, _, expressions }, env) do - Block.make_block(expressions, env) - end - - defp do_translate({:__DIR__, _, _}, env) do - case env.file do - nil -> - { JS.identifier(:null), env } - filepath -> - { JS.literal(Path.dirname(filepath)), env } - end - end - - defp do_translate({:try, _, [ blocks ]}, env) do - Try.make_try(blocks, env) - end - - defp do_translate({:with, _, args }, env ) do - With.make_with(args, env) - end - - defp do_translate({:super, _, _expressions }, _ ) do - raise ElixirScript.Translator.UnsupportedError, "super" - end - - defp do_translate({:__CALLER__, _, _expressions }, env) do - env_to_translate = ElixirScript.Translator.LexicalScope.caller(env) - - quoted = Macro.escape(env_to_translate) - translate(quoted, env) - end - - defp do_translate({:__ENV__, _, _expressions }, env) do - env_to_translate = ElixirScript.Translator.LexicalScope.env(env) - - quoted = Macro.escape(env_to_translate) - translate(quoted, env) - end - - defp do_translate({:quote, _, [[do: expr]]}, env) do - { Quote.make_quote([], expr, env), env } - end - - defp do_translate({:quote, _, [opts, [do: expr]]}, env) do - { Quote.make_quote(opts, expr, env), env } - end - - defp do_translate({:import, _, [{{:., _, [{:__aliases__, _, head_import_name}, :{}]}, _, tail_imports }]}, env) do - env = Enum.reduce(tail_imports, env, fn({:__aliases__, context, name}, acc) -> - full_module_name = { :__aliases__, context, head_import_name ++ name } - - module_name = Utils.quoted_to_name(full_module_name) - ElixirScript.Translator.LexicalScope.add_import(acc, module_name) - end) - - { %ElixirScript.Translator.Empty{}, env } - end - - - defp do_translate({:import, _, [{:__aliases__, _, _} = module_name]}, env) do - module_name = Utils.quoted_to_name(module_name) - - env = ElixirScript.Translator.LexicalScope.add_import(env, module_name) - { %ElixirScript.Translator.Empty{}, env } - end - - defp do_translate({:import, _, [{:__aliases__, _, _} = module_name, options]}, env) do - module_name = Utils.quoted_to_name(module_name) - - env = ElixirScript.Translator.LexicalScope.add_import(env, module_name, options) - - { %ElixirScript.Translator.Empty{}, env } - end - - defp do_translate({:alias, _, [{{:., _, [{:__aliases__, _, head_alias_name}, :{}]}, _, tail_aliases }]}, env) do - env = Enum.reduce(tail_aliases, env, fn({:__aliases__, context, name}, acc) -> - full_module_name = { :__aliases__, context, head_alias_name ++ name } - - module_name = Utils.quoted_to_name(full_module_name) - alias_name = Utils.quoted_to_name({:__aliases__, [], [List.last(name)] }) - - ElixirScript.Translator.LexicalScope.add_alias(acc, module_name, alias_name) - end) - - { %ElixirScript.Translator.Empty{}, env } - end - - defp do_translate({:alias, _, [{:__aliases__, _, _} = module_name] }, env) do - {_, _, name} = module_name - name = [List.last(name)] - - module_name = Utils.quoted_to_name(module_name) - alias_name = Utils.quoted_to_name({:__aliases__, [], name }) - - env = ElixirScript.Translator.LexicalScope.add_alias(env, module_name, alias_name) - { %ElixirScript.Translator.Empty{}, env } - end - - defp do_translate({:alias, _, [{:__aliases__, _, _} = module_name, [as: {:__aliases__, _, _} = alias_name]]}, env) do - module_name = Utils.quoted_to_name(module_name) - alias_name = Utils.quoted_to_name(alias_name) - - env = ElixirScript.Translator.LexicalScope.add_alias(env, module_name, alias_name) - { %ElixirScript.Translator.Empty{}, env } - end - - defp do_translate({:require, _, [{{:., _, [{:__aliases__, _, head_require_name}, :{}]}, _, tail_requires }]}, env) do - env = Enum.reduce(tail_requires, env, fn({:__aliases__, context, name}, acc) -> - full_module_name = { :__aliases__, context, head_require_name ++ name } - - module_name = Utils.quoted_to_name(full_module_name) - ElixirScript.Translator.LexicalScope.add_require(acc, module_name) - end) - - { %ElixirScript.Translator.Empty{}, env } - end - - defp do_translate({:require, _, [{:__aliases__, _, _} = module_name] }, env) do - module_name = Utils.quoted_to_name(module_name) - env = ElixirScript.Translator.LexicalScope.add_require(env, module_name) - { %ElixirScript.Translator.Empty{}, env } - end - - defp do_translate({:require, _, [{:__aliases__, _, _} = module_name, [as: {:__aliases__, _, _} = alias_name]]}, env) do - module_name = Utils.quoted_to_name(module_name) - alias_name = Utils.quoted_to_name(alias_name) - - env = ElixirScript.Translator.LexicalScope.add_require(env, module_name, alias_name) - { %ElixirScript.Translator.Empty{}, env } - end - - defp do_translate({:case, _, [condition, [do: clauses]]}, env) do - Case.make_case(condition, clauses, env) - end - - defp do_translate({:cond, _, [[do: clauses]]}, env) do - Cond.make_cond(clauses, env) - end - - defp do_translate({:for, _, generators}, env) do - For.make_for(generators, env) - end - - defp do_translate({:fn, _, clauses}, env) do - Function.make_anonymous_function(clauses, env) - end - - defp do_translate({:receive, _, _ }, _) do - raise ElixirScript.Translator.UnsupportedError, "receive" - end - - defp do_translate({:{}, _, elements}, env) do - quoted = quote do - JS.new(Bootstrap.Core.Tuple, unquote(elements)) - end - - translate(quoted, env) - end - - defp do_translate({:=, _, [left, right]}, env) do - Match.make_match(left, right, env) - end - - defp do_translate({function, _, [{:when, _, [{name, _, _params} | _guards] }, _] } = ast, env) when function in @generator_types do - {js_ast, _} = Def.process_function(name, [ast], %{ env | context: :generator}) - {js_ast, env} - end - - defp do_translate({function, _, [{name, _, params}, _]} = ast, env) when function in @generator_types and is_atom(params) do - {js_ast, _} = Def.process_function(name, [ast], %{ env | context: :generator}) - {js_ast, env} - end - - defp do_translate({function, _, [{name, _, _params}, _]} = ast, env) when function in @generator_types do - {js_ast, _} = Def.process_function(name, [ast], %{ env | context: :generator}) - {js_ast, env} - end - - defp do_translate({function, _, [{:when, _, [{name, _, _params} | _guards] }, _] } = ast, env) when function in @function_types do - Def.process_function(name, [ast], env) - end - - defp do_translate({function, _, [{name, _, params}, _]} = ast, env) when function in @function_types and is_atom(params) do - Def.process_function(name, [ast], env) - end - - defp do_translate({function, _, [{name, _, _params}, _]} = ast, env) when function in @function_types do - Def.process_function(name, [ast], env) - end - - defp do_translate({:defdelegate, _, [{name, _, params}, options]}, env) do - Def.process_delegate(name, params, options, env) - end - - defp do_translate({:defstruct, _, [attributes]}, env) do - { Struct.make_struct(attributes, env), env } - end - - defp do_translate({:defexception, _, [attributes]}, env) do - { Struct.make_struct(attributes ++ [__exception__: true], env), env } - end - - defp do_translate({:defmodule, _, [{:__aliases__, _, module_name_list}, [do: body]]}, env) do - { Defmodule.make_module(module_name_list, body, env), env } - end - - defp do_translate({:defprotocol, _, _}, env) do - { %ElixirScript.Translator.Empty{}, env } - end - - defp do_translate({:defmacro, _, _}, env) do - { %ElixirScript.Translator.Empty{}, env } - end - - defp do_translate({:defmacrop, _, _}, env) do - { %ElixirScript.Translator.Empty{}, env } - end - - defp do_translate({:defimpl, _, _}, env) do - { %ElixirScript.Translator.Empty{}, env } - end - - defp do_translate({:|, _, [item, list]}, env) do - quoted = quote do - [unquote(item)].concat(unquote(list)) - end - - translate(quoted, env) - end - - defp do_translate({:raise, _, [alias_info, attributes]}, env) when is_list(attributes) do - module = case create_module_name(alias_info, env) do - {module, _} -> - module - module -> - module - end - - {call, _} = Call.make_module_function_call(module, :__struct__, [{:%{}, [], attributes }], env) - - js_ast = JS.throw_statement(call) - - { js_ast, env } - end - - defp do_translate({:raise, _, [alias_info, message]}, env) do - module = case create_module_name(alias_info, env) do - {module, _} -> - module - module -> - module - end - - {call, _} = Call.make_module_function_call(module, :__struct__, [{:%{}, [], [message: message] }], env) - - js_ast = JS.throw_statement(call) - - { js_ast, env } - end - - defp do_translate({:raise, _, [{:__aliases__, _, _} = alias_info]}, env) do - module = case create_module_name(alias_info, env) do - {module, _} -> - module - module -> - module - end - - {call, _} = Call.make_module_function_call(module, :__struct__, [], env) - - js_ast = JS.throw_statement(call) - - { js_ast, env } - end - - defp do_translate({:raise, _, [message]}, env) do - js_ast = JS.throw_statement( - JS.object_expression( - [ - Map.make_property(translate!(:__struct__, env), translate!(:RuntimeError, env)), - Map.make_property(translate!(:__exception__, env), translate!(true, env)), - Map.make_property(translate!(:message, env), translate!(message, env)) - ] - ) - ) - - { js_ast, env } - end - - defp do_translate({name, _, params} = ast, env) when is_list(params) do - if is_from_js_module(name, params, env) do - do_translate({{:., [], [{:__aliases__, [], [:JS]}, name]}, [], params }, env) - else - expanded_ast = Macro.expand(ast, env.env) - if expanded_ast == ast do - name_arity = {name, length(params)} - module = ElixirScript.Translator.State.get_module(env.state, env.module) - - cond do - name_arity in module.functions or name_arity in module.private_functions -> - Call.make_local_function_call(name, params, env) - ElixirScript.Translator.LexicalScope.find_module(env, name_arity) -> - imported_module_name = ElixirScript.Translator.LexicalScope.find_module(env, name_arity) - Call.make_module_function_call(imported_module_name, name, params, env) - true -> - Call.make_local_function_call(name, params, env) - end - - else - translate(expanded_ast, env) - end - end - end - - defp do_translate({ name, _context, params }, env) when is_atom(params) do - cond do - is_from_js_module(name, params, env) -> - do_translate({{:., [], [{:__aliases__, [], [:JS]}, name]}, [], params }, env) - ElixirScript.Translator.LexicalScope.has_var?(env, name) -> - name = case env.vars[name] do - 0 -> - name - num -> - String.to_atom("#{name}#{num}") - end - - { Identifier.make_identifier(name), env } - has_function?(env.module, {name, 0}, env) -> - Call.make_local_function_call(name, [], env) - ElixirScript.Translator.LexicalScope.find_module(env, {name, 0}) -> - imported_module_name = ElixirScript.Translator.LexicalScope.find_module(env, {name, 0}) - Call.make_module_function_call(imported_module_name, name, params, env) - true -> - { Identifier.make_identifier(name), env } - end - end - - defp is_from_js_module(name, params, env) do - func = if is_list(params) do - {name, length(params)} - else - {name, 0} - end - - {_, macros} = Enum.find(env.env.macros, {nil, []}, fn({k, v}) -> to_string(k) == "Elixir.JS" end) - {_, functions} = Enum.find(env.env.functions, {nil, []}, fn({k, v}) -> to_string(k) == "Elixir.JS" end) - - js = macros ++ functions - - if func in js do - true - else - false - end - end - - def create_module_name(module_name, env) do - module_name = Utils.quoted_to_name(module_name) - candiate_module_name = ElixirScript.Translator.State.get_module_name(env.state, module_name) - - if ElixirScript.Translator.LexicalScope.get_module_name(env, candiate_module_name) in ElixirScript.Translator.State.list_module_names(env.state) do - { ElixirScript.Translator.LexicalScope.get_module_name(env, candiate_module_name), :local } - else - module_name - end - end - - def has_function?(module_name, name_arity, env) do - case ElixirScript.Translator.State.get_module(env.state, module_name) do - nil -> - false - module -> - name_arity in module.functions or name_arity in module.private_functions - end - end - -end diff --git a/lib/elixir_script/translator/empty.ex b/lib/elixir_script/translator/empty.ex deleted file mode 100644 index 1456cc4f..00000000 --- a/lib/elixir_script/translator/empty.ex +++ /dev/null @@ -1,8 +0,0 @@ -defmodule ElixirScript.Translator.Empty do - @moduledoc false - - # Represents no translation to JS AST - - @type t :: %ElixirScript.Translator.Empty{} - defstruct type: "Empty" -end diff --git a/lib/elixir_script/translator/group.ex b/lib/elixir_script/translator/group.ex deleted file mode 100644 index 391315ff..00000000 --- a/lib/elixir_script/translator/group.ex +++ /dev/null @@ -1,30 +0,0 @@ -defmodule ElixirScript.Translator.Group do - @moduledoc false - - # Represents a collection of JavaScript AST. - # Contents in body are expanded within outer AST before JS code generation - - @type t :: %ElixirScript.Translator.Group{ - type: binary, - body: [ESTree.Statement.t] - } - defstruct type: "Group", body: [] - - def inflate_groups(body) do - Enum.map(body, fn(x) -> - case x do - %ElixirScript.Translator.Empty{} -> - [] - %ElixirScript.Translator.Group{body: group_body} -> - group_body - %ESTree.BlockStatement{} -> - %ESTree.BlockStatement{ body: inflate_groups(x.body) } - %ESTree.IfStatement{} -> - %{x | consequent: inflate_groups(x.consequent), alternate: inflate_groups(x.alternate) } - _ -> - x - end - end) - |> List.flatten - end -end diff --git a/lib/elixir_script/translator/kernel/def.ex b/lib/elixir_script/translator/kernel/def.ex deleted file mode 100644 index 6fee1fb1..00000000 --- a/lib/elixir_script/translator/kernel/def.ex +++ /dev/null @@ -1,39 +0,0 @@ -defmodule ElixirScript.Translator.Def do - @moduledoc false - alias ESTree.Tools.Builder, as: JS - alias ElixirScript.Translator.Function - alias ElixirScript.Translator.Identifier - alias ElixirScript.Translator - - def process_function(name, functions, env) do - { result, _ } = Function.make_anonymous_function(functions, env, name) - - declarator = JS.variable_declarator( - Identifier.make_identifier(name), - result - ) - - { JS.variable_declaration([declarator], :const), env } - end - - def process_delegate(name, params, options, env) do - translated_params = Enum.map(params, &Translator.translate!(&1, env)) - to = options[:to] - as = options[:as] || name - - function = JS.function_expression(translated_params, [], - JS.block_statement([ - JS.return_statement( - Translator.translate!({{:., [], [to, as]}, [], params}, env) - ) - ]) - ) - - declarator = JS.variable_declarator( - Identifier.make_identifier(name), - function - ) - - { JS.variable_declaration([declarator], :const), env } - end -end diff --git a/lib/elixir_script/translator/kernel/defimpl.ex b/lib/elixir_script/translator/kernel/defimpl.ex deleted file mode 100644 index 0e1dde5d..00000000 --- a/lib/elixir_script/translator/kernel/defimpl.ex +++ /dev/null @@ -1,137 +0,0 @@ -defmodule ElixirScript.Translator.Defimpl do - @moduledoc false - alias ESTree.Tools.Builder, as: JS - alias ElixirScript.Translator.Defmodule - alias ElixirScript.Translator.State - alias ElixirScript.Translator.Utils - - def make(name, type, body, env) do - - type = map_to_js(type, env) - {body, export} = Defmodule.process_module(name, body, env) - - protocol_name = Atom.to_string(name) |> String.split(".DefImpl.") |> hd |> String.to_atom - - export = JS.object_expression([ - JS.property( - JS.literal("Type"), - type - ), - JS.property( - JS.literal("Implementation"), - export - ) - ]) - - %{ - name: Utils.quoted_to_name({:__aliases__, [], name }), - exports: export, - body: body, - app_name: State.get_module(env.state, name).app, - protocol: protocol_name, - env: env - } - end - - defp map_to_js({:__aliases__, _, [:Integer]}, _) do - JS.member_expression( - JS.member_expression( - JS.identifier("Bootstrap"), - JS.identifier(:Core) - ), - JS.identifier(:Integer) - ) - end - - defp map_to_js({:__aliases__, _, [:Tuple]}, _) do - JS.member_expression( - JS.member_expression( - JS.identifier("Bootstrap"), - JS.identifier(:Core) - ), - JS.identifier(:Tuple) - ) - end - - defp map_to_js({:__aliases__, _, [:Atom]}, _) do - JS.identifier(:Symbol) - end - - defp map_to_js({:__aliases__, _, [:List]}, _) do - JS.identifier(:Array) - end - - defp map_to_js({:__aliases__, _, [:BitString]}, _) do - JS.member_expression( - JS.member_expression( - JS.identifier("Bootstrap"), - JS.identifier(:Core) - ), - JS.identifier(:BitString) - ) - end - - defp map_to_js({:__aliases__, _, [:Float]}, _) do - JS.member_expression( - JS.member_expression( - JS.identifier("Bootstrap"), - JS.identifier(:Core) - ), - JS.identifier(:Float) - ) - end - - defp map_to_js({:__aliases__, _, [:Function]}, _) do - JS.identifier(:Function) - end - - defp map_to_js({:__aliases__, _, [:PID]}, _) do - JS.member_expression( - JS.member_expression( - JS.identifier("Bootstrap"), - JS.identifier(:Core) - ), - JS.identifier(:PID) - ) - end - - defp map_to_js({:__aliases__, _, [:Port]}, _) do - JS.member_expression( - JS.identifier("Bootstrap"), - JS.identifier(:Port) - ) - end - - defp map_to_js({:__aliases__, _, [:Reference]}, _) do - JS.member_expression( - JS.identifier("Bootstrap"), - JS.identifier(:Reference) - ) - end - - defp map_to_js({:__aliases__, _, [:Map]}, _) do - JS.identifier(:Object) - end - - defp map_to_js({:__aliases__, context, [:JS | rest]}, env) do - ElixirScript.Translator.JS.translate_js_module({:__aliases__, context, rest}, env) - |> elem(0) - end - - defp map_to_js({:__aliases__, _, [:Any]}, _) do - JS.identifier(:null) - end - - - defp map_to_js({:__aliases__, _, _} = module, env) do - module = case ElixirScript.Translator.create_module_name(module, env) do - {module, _} -> - module - module -> - module - end - - ElixirScript.Translator.translate!(module, env) - end - -end diff --git a/lib/elixir_script/translator/kernel/defmodule.ex b/lib/elixir_script/translator/kernel/defmodule.ex deleted file mode 100644 index eb77bc00..00000000 --- a/lib/elixir_script/translator/kernel/defmodule.ex +++ /dev/null @@ -1,267 +0,0 @@ -defmodule ElixirScript.Translator.Defmodule do - @moduledoc false - alias ESTree.Tools.Builder, as: JS - alias ElixirScript.Translator - alias ElixirScript.Translator.State - alias ElixirScript.Translator.Utils - alias ElixirScript.Translator.Group - alias ElixirScript.Translator.Def - alias ElixirScript.Translator.Identifier - - def make_module(ElixirScript.Temp, body, env) do - { body, _ } = translate_body(body, env) - %{ - name: ElixirScript.Temp, - body: body |> Group.inflate_groups, - exports: nil, - app_name: ElixirScript.Translator.State.get(env.state).compiler_opts.app, - env: env - } - end - - def make_module(module, nil, env) do - %{ - name: module, - body: [], - exports: nil, - app_name: ElixirScript.Translator.State.get(env.state).compiler_opts.app, - env: env - } - end - - def make_module(module, body, env) do - {body, exported_object} = process_module(module, body, env) - app_name = State.get_module(env.state, module).app - - result = %{ - name: Utils.quoted_to_name({:__aliases__, [], module }), - exports: exported_object, - body: body, - app_name: app_name, - env: env - } - - result - end - - def process_module(module, body, env) do - { body, functions } = extract_functions_from_module(body) - - { body, env } = translate_body(body, env) - - { exported_functions, private_functions } = process_functions(functions, env) - - struct_prop = if has_struct?(body) do - [JS.property(Identifier.make_identifier("__struct__"), Identifier.make_identifier("__struct__"), :init, true)] - else - [] - end - - info_prop = [JS.property(Identifier.make_identifier("__info__"), Identifier.make_identifier("__info__"), :init, true)] - - body = Enum.map(body, fn(x) -> - case x do - %ESTree.CallExpression{} -> - JS.expression_statement(x) - _ -> - x - end - end) - - body = Group.inflate_groups(body) - - exported_object = JS.object_expression( - info_prop ++ struct_prop ++ - Enum.map(exported_functions, fn({key, _value}) -> - JS.property(Identifier.make_identifier(key), Identifier.make_identifier(key), :init, true) - end) - ) - - exported_functions = Enum.map(exported_functions, fn({_key, value}) -> value end) - private_functions = Enum.map(private_functions, fn({_key, value}) -> value end) - - body = private_functions ++ exported_functions ++ [make_info_function(env)] ++ body - {body, exported_object} - end - - def translate_body(body, env) do - { body, env } = Translator.translate(body, env) - - body = case body do - [%ESTree.BlockStatement{ body: body }] -> - body - %ESTree.BlockStatement{ body: body } -> - body - _ -> - List.wrap(body) - end - - { body, env } - end - - def extract_functions_from_module({:__block__, meta, body_list}) do - { body_list, functions } = Enum.map_reduce(body_list, - %{exported: Map.new(), private: Map.new(), exported_generators: Map.new(), private_generators: Map.new()}, fn - ({:def, _, [{:when, _, [{name, _, _} | _guards] }, _] } = function, state) -> - { - nil, - %{ state | exported: Map.put(state.exported, name, Map.get(state.exported, name, []) ++ [function]) } - } - ({:def, _, [{name, _, _}, _]} = function, state) -> - { - nil, - %{ state | exported: Map.put(state.exported, name, Map.get(state.exported, name, []) ++ [function]) } - } - ({:defp, _, [{:when, _, [{name, _, _} | _guards] }, _] } = function, state) -> - { - nil, - %{ state | private: Map.put(state.private, name, Map.get(state.private, name, []) ++ [function]) } - } - ({:defp, _, [{name, _, _}, _]} = function, state) -> - { - nil, - %{ state | private: Map.put(state.private, name, Map.get(state.private, name, []) ++ [function]) } - } - ({:defgen, _, [{:when, _, [{name, _, _} | _guards] }, _] } = function, state) -> - { - nil, - %{ state | exported_generators: Map.put(state.exported_generators, name, Map.get(state.exported_generators, name, []) ++ [function]) } - } - ({:defgen, _, [{name, _, _}, _]} = function, state) -> - { - nil, - %{ state | exported_generators: Map.put(state.exported_generators, name, Map.get(state.exported_generators, name, []) ++ [function]) } - } - ({:defgenp, _, [{:when, _, [{name, _, _} | _guards] }, _] } = function, state) -> - { - nil, - %{ state | private_generators: Map.put(state.private_generators, name, Map.get(state.private_generators, name, []) ++ [function]) } - } - ({:defgenp, _, [{name, _, _}, _]} = function, state) -> - { - nil, - %{ state | private_generators: Map.put(state.private_generators, name, Map.get(state.private_generators, name, []) ++ [function]) } - } - (x, state) -> - { x, state } - end) - - body_list = Enum.filter(body_list, fn(x) -> !is_nil(x) end) - body = {:__block__, meta, body_list} - - { body, functions } - end - - def extract_functions_from_module(body) do - extract_functions_from_module({:__block__, [], List.wrap(body)}) - end - - def extract_imports_from_body(body) do - Enum.partition(body, fn(x) -> - case x do - %ESTree.ImportDeclaration{} -> - true - _ -> - false - end - end) - end - - def has_struct?(body) do - val = Enum.find(body, fn(x) -> - case x do - %ESTree.VariableDeclaration{declarations: [%ESTree.VariableDeclarator{id: %ESTree.Identifier{name: "__struct__"} } ] } -> - true - _ -> - false - end - end) - - val != nil - end - - defp make_defstruct_property(_, []) do - [] - end - - defp make_defstruct_property(module_name, [the_struct]) do - module_js_name = Utils.name_to_js_name(module_name) - - case the_struct do - %ESTree.VariableDeclaration{declarations: [%ESTree.VariableDeclarator{id: %ESTree.Identifier{name: ^module_js_name} } ] } -> - [JS.property(JS.identifier(module_js_name), JS.identifier(module_js_name), :init, true)] - end - end - - def process_functions(%{ exported: exported, private: private, exported_generators: exported_generators, private_generators: private_generators }, env) do - exported_functions = Enum.map(Map.keys(exported), fn(key) -> - functions = Map.get(exported, key) - - { functions, _ } = Def.process_function(key, functions, env) - { key, functions } - end) - - exported_generators = Enum.map(Map.keys(exported_generators), fn(key) -> - functions = Map.get(exported_generators, key) - - { functions, _ } = Def.process_function(key, functions, %{ env | context: :generator}) - { key, functions } - end) - - private_functions = Enum.map(Map.keys(private), fn(key) -> - functions = Map.get(private, key) - { functions, _ } = Def.process_function(key, functions, env) - { key, functions } - end) - - private_generators = Enum.map(Map.keys(private_generators), fn(key) -> - functions = Map.get(private_generators, key) - { functions, _ } = Def.process_function(key, functions, %{ env | context: :generator}) - { key, functions } - end) - - { exported_functions ++ exported_generators, private_functions ++ private_generators } - end - - def make_attribute(name, value, env) do - declarator = JS.variable_declarator( - Identifier.make_identifier(name), - ElixirScript.Translator.translate!(value, env) - ) - - JS.variable_declaration([declarator], :const) - end - - def make_info_function(env) do - functions = Keyword.get(env.functions, env.module, []) - macros = Keyword.get(env.macros, env.module, []) - - info_case = quote do - case kind do - :functions -> - unquote(functions) - :macros -> - unquote(macros) - :module -> - unquote(env.module) - end - end - - translated_case = ElixirScript.Translator.translate!(info_case, env) - - declarator = JS.variable_declarator( - Identifier.make_identifier("__info__"), - JS.function_expression( - [JS.identifier("kind")], - [], - JS.block_statement([ - JS.return_statement(translated_case) - ]) - ) - ) - - JS.variable_declaration([declarator], :const) - - end - -end diff --git a/lib/elixir_script/translator/kernel/defprotocol.ex b/lib/elixir_script/translator/kernel/defprotocol.ex deleted file mode 100644 index f41ee42b..00000000 --- a/lib/elixir_script/translator/kernel/defprotocol.ex +++ /dev/null @@ -1,93 +0,0 @@ -defmodule ElixirScript.Translator.Defprotocol do - @moduledoc false - - alias ESTree.Tools.Builder, as: JS - alias ElixirScript.Translator.Defmodule - alias ElixirScript.Translator.Map - alias ElixirScript.Translator.Utils - alias ElixirScript.Translator.State - alias ElixirScript.Translator.Identifier - require Logger - - @doc """ - Takes a protocol and turns it into a module - """ - def make(name, functions, env) do - { body, _ } = Defmodule.translate_body( {:__block__, [], [] }, env) - app_name = State.get_module(env.state, name).app - - object = process_spec_functions(functions) - |> Enum.map(fn({key, value}) -> - Map.make_property(Identifier.make_identifier(key), value) - end) - |> JS.object_expression - - declarator = JS.variable_declarator( - JS.identifier(Utils.name_to_js_name(name)), - JS.call_expression( - JS.member_expression( - JS.identifier("Bootstrap"), - JS.member_expression( - JS.identifier(:Core), - JS.member_expression( - JS.identifier(:Functions), - JS.identifier(:defprotocol) - ) - ) - ), - [object] - ) - ) - - declaration = JS.variable_declaration([declarator], :const) - - implementation_name_split = Module.split(name) ++ ["DefImpl"] - implementation_name = Enum.join(["Elixir"] ++ implementation_name_split, "$") - implementation_name_module = Module.concat(implementation_name_split) - - implementations = JS.for_of_statement( - JS.variable_declaration([JS.variable_declarator( - JS.object_pattern([ - JS.assignment_property(JS.identifier("Type")), - JS.assignment_property(JS.identifier("Implementation")) - ]), - nil - )], :let), - JS.identifier(implementation_name), - JS.call_expression( - JS.member_expression( - JS.identifier("Bootstrap"), - JS.member_expression( - JS.identifier(:Core), - JS.member_expression( - JS.identifier(:Functions), - JS.identifier(:defimpl) - ) - ) - ), - [ - JS.identifier(Utils.name_to_js_name(name)), - JS.identifier("Type"), - JS.identifier("Implementation") - ] - ) - ) - - body = body ++ [declaration] ++ [implementations] - defimpl_import = ElixirScript.ModuleSystems.Namespace.import_module(implementation_name_module) - - %{ - name: name, - body: [defimpl_import] ++ body, - exports: JS.identifier(Utils.name_to_js_name(name)), - app_name: app_name, - env: env - } - end - - defp process_spec_functions(functions) do - Enum.map(Keyword.keys(functions), fn(function_name) -> - {function_name, JS.function_expression([], [], JS.block_statement([]))} - end) - end -end diff --git a/lib/elixir_script/translator/kernel/expression.ex b/lib/elixir_script/translator/kernel/expression.ex deleted file mode 100644 index 583e52a4..00000000 --- a/lib/elixir_script/translator/kernel/expression.ex +++ /dev/null @@ -1,18 +0,0 @@ -defmodule ElixirScript.Translator.Expression do - @moduledoc false - alias ESTree.Tools.Builder - alias ElixirScript.Translator - - def make_unary_expression(operator, expr, env) do - { js_ast, env } = Translator.translate(expr, env) - { Builder.unary_expression(operator, true, js_ast), env } - end - - def make_binary_expression(operator, left, right, env) do - { left, _ } = Translator.translate(left, env) - { right, _ } = Translator.translate(right, env) - - { Builder.binary_expression(operator, left, right), env } - end - -end diff --git a/lib/elixir_script/translator/kernel/js.ex b/lib/elixir_script/translator/kernel/js.ex deleted file mode 100644 index ea0c52e6..00000000 --- a/lib/elixir_script/translator/kernel/js.ex +++ /dev/null @@ -1,237 +0,0 @@ -defmodule ElixirScript.Translator.JS do - @moduledoc false - - alias ESTree.Tools.Builder - alias ElixirScript.Translator - alias ElixirScript.Translator.Utils - alias ElixirScript.Translator.Identifier - - def call_property() do - Builder.member_expression( - Builder.member_expression( - Builder.identifier("Bootstrap"), - Builder.member_expression( - Builder.identifier("Core"), - Builder.identifier("Functions") - ) - ), - Builder.identifier("call_property") - ) - end - - def global() do - Builder.member_expression( - Builder.member_expression( - Builder.identifier("Bootstrap"), - Builder.identifier("Core") - ), - Builder.identifier("global") - ) - end - - @doc false - def translate_js_function({:__aliases__, _, module}, name, params, env) do - { do_translate(module, {name, [], params}, env), env } - end - - @doc false - def translate_js_function(name, params, env) do - { do_translate({name, [], params}, env), env } - end - - def translate_js_module(module, env) do - { do_translate(module, env), env } - end - - defp do_translate({:__aliases__, _, module}, env) do - Identifier.make_namespace_members(module) - end - - defp do_translate({op, _, [param]}, env) when op in [:typeof, :delete, :void, :-, :+, :!, :"~"] do - Builder.unary_expression( - op, - true, - Translator.translate!(param, env) - ) - end - - defp do_translate({op, _, [value, type]}, env) when op in [:"**", :==, :!=, :===, :!==, :<, :<=, :>, :>=, :"<<", :">>", :<<<, :+, :-, :*, :/, :%, :|, :^, :&, :in, :instanceof] do - Builder.binary_expression( - op, - Translator.translate!(value, env), - Translator.translate!(type, env) - ) - end - - defp do_translate({op, _, [value, type]}, env) when op in [:||, :&&] do - Builder.logical_expression( - op, - Translator.translate!(value, env), - Translator.translate!(type, env) - ) - end - - defp do_translate({:yield, _, []}, _) do - Builder.yield_expression() - end - - defp do_translate({:yield, _, [term]}, env) do - Builder.yield_expression( - Translator.translate!(term, env) - ) - end - - defp do_translate({:yield_to, _, [term]}, env) do - Builder.yield_expression( - Translator.translate!(term, env), - true - ) - end - - defp do_translate({:throw, _, [term]}, env) do - Builder.throw_statement( - Translator.translate!(term, env) - ) - end - - defp do_translate({:throw, _, [term]}, env) do - Builder.throw_statement( - Translator.translate!(term, env) - ) - end - - defp do_translate({:new, _, [module_name, params]}, env) when not is_list(params) do - Builder.new_expression( - Translator.translate!(module_name, env), - [Builder.rest_element(Translator.translate!(params, env))] - ) - end - - defp do_translate({:new, _, [module_name, params]}, env) do - Builder.new_expression( - Translator.translate!(module_name, env), - Enum.map(params, &Translator.translate!(&1, env)) - ) - end - - defp do_translate({:update, _, [object, map]}, env) do - quoted = quote do - JS.Object.assign(unquote(object), unquote(map)) - end - - Translator.translate!(quoted, env) - end - - defp do_translate({:update, _, [object, key, value]}, env) do - Builder.assignment_expression( - :=, - Builder.member_expression( - Translator.translate!(object, env), - Translator.translate!(key, env), - true - ), - Translator.translate!(value, env) - ) - end - - defp do_translate({:import, _, [term]}, env) do - Builder.call_expression( - Builder.identifier("import"), - [Translator.translate!(term, env)] - ) - end - - defp do_translate({:debugger, _, _}, env) do - Builder.debugger_statement() - end - - defp do_translate({:this, _, _}, env) do - Builder.this_expression() - end - - defp do_translate({:__delete__, _, [expr]}, env) do - {result, _} = ElixirScript.Translator.Expression.make_unary_expression(:delete, expr, env) - result - end - - defp do_translate({:__bnot__, _, [expr]}, env) do - {result, _} = ElixirScript.Translator.Expression.make_unary_expression(:"~", expr, env) - result - end - - defp do_translate({:__band__, _, [left, right]}, env) do - {result, _} = ElixirScript.Translator.Expression.make_binary_expression(:&, left, right, env) - result - end - - defp do_translate({:__bor__, _, [left, right]}, env) do - {result, _} = ElixirScript.Translator.Expression.make_binary_expression(:|, left, right, env) - result - end - - defp do_translate({:__bsl__, _, [left, right]}, env) do - {result, _} = ElixirScript.Translator.Expression.make_binary_expression(:"<<", left, right, env) - result - end - - defp do_translate({:__bsr__, _, [left, right]}, env) do - {result, _} = ElixirScript.Translator.Expression.make_binary_expression(:">>", left, right, env) - result - end - - defp do_translate({:__bxor__, _, [left, right]}, env) do - {result, _} = ElixirScript.Translator.Expression.make_binary_expression(:^, left, right, env) - result - end - - defp do_translate({function, _, []}, env) do - Builder.call_expression( - call_property(), - [ - global(), - Translator.translate!(to_string(function), env) - ] - ) - end - - defp do_translate({function, _, params}, env) do - Builder.call_expression( - Builder.member_expression( - global(), - Builder.identifier(function) - ), - Enum.map(params, &Translator.translate!(&1, env)) - ) - end - - defp do_translate(module, {function, _, []}, env) do - members = Identifier.make_namespace_members(module) - - Builder.call_expression( - call_property(), - [ - Builder.member_expression( - global(), - members - ), - Translator.translate!(to_string(function), env) - ] - ) - end - - defp do_translate(module, {function, _, params}, env) do - members = Identifier.make_namespace_members(module) - - Builder.call_expression( - Builder.member_expression( - Builder.member_expression( - global(), - members - ), - Builder.identifier(function) - ), - Enum.map(params, &Translator.translate!(&1, env)) - ) - end - -end diff --git a/lib/elixir_script/translator/kernel/special_forms/bitstring.ex b/lib/elixir_script/translator/kernel/special_forms/bitstring.ex deleted file mode 100644 index bf0dc832..00000000 --- a/lib/elixir_script/translator/kernel/special_forms/bitstring.ex +++ /dev/null @@ -1,147 +0,0 @@ -defmodule ElixirScript.Translator.Bitstring do - @moduledoc false - alias ESTree.Tools.Builder, as: JS - alias ElixirScript.Translator - - - def make_bitstring(elements, env) do - js_ast = JS.new_expression( - JS.member_expression( - JS.member_expression( - JS.identifier("Bootstrap"), - JS.identifier("Core") - ), - JS.identifier("BitString") - ), - Enum.map(elements, &make_bitstring_element(&1, env)) - ) - - { js_ast, env } - end - - def make_bitstring_element(element, env) when is_number(element) do - do_make_bitstring_element({:integer, Translator.translate!(element, env)}) - end - - def make_bitstring_element(element, env) when is_binary(element) do - do_make_bitstring_element({:binary, Translator.translate!(element, env)}) - end - - def make_bitstring_element({:<<>>, [], elements}, env) do - {ast, _} = make_bitstring(elements, env) - ast - end - - def make_bitstring_element({:::, _, [element, {type, _, _}]}, env) when type in [:integer, :float, :bitstring, :bits, :binary, :bytes, :utf8, :utf16, :utf32, :signed, :unsigned] do - do_make_bitstring_element({type, translate_element(element, env)}) - end - - def make_bitstring_element({:::, _, [element, {type, _, params}]}, env) when type in [:size, :unit] do - do_make_bitstring_element({type, translate_element(element, env), Enum.map(params, &translate_element(&1, env))}) - end - - def make_bitstring_element({:::, _, [element, {:*, _, [size, unit]}]}, env) do - size_ast = do_make_bitstring_element({:size, translate_element(element, env), [translate_element(size, env)]}) - do_make_bitstring_element({:unit, size_ast, [translate_element(unit, env)]}) - end - - def make_bitstring_element({:::, _, [element, {:-, _, types}]}, env) do - handle_type_adjectives({:-, [], types}, translate_element(element, env), env) - end - - def make_bitstring_element({:::, _, [element, size]}, env) do - do_make_bitstring_element({:size, translate_element(element, env), [translate_element(size, env)]}) - end - - def make_bitstring_element(element, env) do - do_make_bitstring_element({:binary, translate_element(element, env)}) - end - - def translate_element(ElixirScript.Translator.PatternMatching, _) do - JS.object_expression([JS.property( - JS.literal("value"), - ElixirScript.Translator.PatternMatching.parameter() - ) - ]) - end - - def translate_element(element, env) do - Translator.translate!(element, env) - end - - defp handle_type_adjectives({:-, _, types}, ast, env) do - Enum.reduce(types, ast, fn(type, current_ast) -> - case type do - {:-, _, sub_types} -> - handle_type_adjectives({:-, [], sub_types}, current_ast, env) - {:*, _, [size, unit]} -> - size_ast = do_make_bitstring_element({:size, current_ast, [Translator.translate!(size, env)]}) - do_make_bitstring_element({:unit, size_ast, [Translator.translate!(unit, env)]}) - {the_type, _, params} when is_list(params) -> - do_make_bitstring_element({the_type, current_ast, Enum.map(params, &Translator.translate!(&1, env))}) - {the_type, _, _} -> - do_make_bitstring_element({the_type, current_ast}) - end - end) - end - - defp bitstring_class() do - JS.member_expression( - JS.member_expression( - JS.identifier("Bootstrap"), - JS.identifier("Core") - ), - JS.identifier("BitString") - ) - end - - defp do_make_bitstring_element({type, ast}) do - JS.call_expression( - JS.member_expression( - bitstring_class, - JS.identifier(type) - ), - [ - ast - ] - ) - end - - defp do_make_bitstring_element({type, ast, params}) when is_list(params) do - JS.call_expression( - JS.member_expression( - bitstring_class, - JS.identifier(type) - ), - [ - ast - ] ++ params - ) - end - - def make_interpolated_string(elements, env) do - translated_elements = Enum.map(elements, fn(x) -> - case x do - elem when is_binary(elem) -> - Translator.translate!(elem, env) - {:::, _, data} -> - Translator.translate!(hd(data), env) - end - end) - - { do_make_interpolated_string(tl(translated_elements), hd(translated_elements), env), env } - end - - defp do_make_interpolated_string([], ast, _) do - ast - end - - defp do_make_interpolated_string(elements, ast, env) do - JS.binary_expression( - :+, - ast, - do_make_interpolated_string(tl(elements), hd(elements), env) - ) - end - -end diff --git a/lib/elixir_script/translator/kernel/special_forms/block.ex b/lib/elixir_script/translator/kernel/special_forms/block.ex deleted file mode 100644 index 52689574..00000000 --- a/lib/elixir_script/translator/kernel/special_forms/block.ex +++ /dev/null @@ -1,14 +0,0 @@ -defmodule ElixirScript.Translator.Block do - @moduledoc false - alias ESTree.Tools.Builder, as: JS - alias ElixirScript.Translator - - def make_block(expressions, env) do - { list, env } = Enum.map_reduce(expressions, env, fn(x, updated_env) -> - Translator.translate(x, updated_env) - end) - - { JS.block_statement(list), env } - end - -end diff --git a/lib/elixir_script/translator/kernel/special_forms/call.ex b/lib/elixir_script/translator/kernel/special_forms/call.ex deleted file mode 100644 index 2356c5a6..00000000 --- a/lib/elixir_script/translator/kernel/special_forms/call.ex +++ /dev/null @@ -1,214 +0,0 @@ -defmodule ElixirScript.Translator.Call do - @moduledoc false - alias ESTree.Tools.Builder, as: JS - alias ElixirScript.Translator - alias ElixirScript.Translator.Utils - alias ElixirScript.Translator.Identifier - - def make_module_name(module_name, env) do - members = ["Elixir"] ++ Module.split(module_name) - { Identifier.make_namespace_members(members), env } - end - - def make_extern_module_name(module_name, env) do - members = Module.split(module_name) - { Identifier.make_namespace_members(members), env } - end - - def make_local_function_call({fun, _, nil}, params, env) do - ast = JS.call_expression( - Identifier.make_identifier(fun), - Enum.map(params, &Translator.translate!(&1, env)) - ) - - {ast, env} - end - - def make_local_function_call(function_name, params, env) do - ast = JS.call_expression( - Identifier.make_identifier(function_name), - Enum.map(params, &Translator.translate!(&1, env)) - ) - - {ast, env} - end - - def make_module_function_call(module_name, function_name, params, env) do - ElixirScript.Translator.State.add_module_reference(env.state, env.module, module_name) - - members = ["Elixir"] ++ Module.split(module_name) ++ ["__load"] - - ast = JS.call_expression( - JS.member_expression( - JS.call_expression( - Identifier.make_namespace_members(members), - [JS.identifier("Elixir")] - ), - Identifier.make_identifier(function_name) - ), - Enum.map(params, &Translator.translate!(&1, env)) - ) - - {ast, env} - end - - def make_module_function_call(module_name, function_name, env) do - ElixirScript.Translator.State.add_module_reference(env.state, env.module, module_name) - make_module_function_call(module_name, function_name, [], env) - end - - def make_extern_function_or_property_call(module_name, function_name, env) do - members = Module.split(module_name) - Identifier.make_namespace_members(members) - - js_ast = JS.call_expression( - JS.member_expression( - JS.member_expression( - JS.identifier("Bootstrap"), - JS.member_expression( - JS.identifier("Core"), - JS.identifier("Functions") - ) - ), - JS.identifier("call_property") - ), - [ - Identifier.make_namespace_members(members), - Translator.translate!(to_string(function_name), env) - ] - ) - - {js_ast, env} - end - - def make_extern_function_call(module_name, function_name, params, env) do - members = Module.split(module_name) ++ [to_string(function_name)] - - ast = JS.call_expression( - Identifier.make_namespace_members(members), - Enum.map(params, &Translator.translate!(&1, env)) - ) - - {ast, env} - end - - def make_function_or_property_call(module_name, function_name, env) do - js_ast = JS.call_expression( - JS.member_expression( - JS.member_expression( - JS.identifier("Bootstrap"), - JS.member_expression( - JS.identifier("Core"), - JS.identifier("Functions") - ) - ), - JS.identifier("call_property") - ), - [ - Translator.translate!(module_name, env), - Translator.translate!(to_string(function_name), env) - ] - ) - - { js_ast, env } - end - - def make_function_call(module_name, function_name, [], env) when is_atom(module_name) and is_atom(function_name) do - js_ast = JS.call_expression( - JS.member_expression( - JS.member_expression( - JS.identifier("Bootstrap"), - JS.member_expression( - JS.identifier("Core"), - JS.identifier("Functions") - ) - ), - JS.identifier("call_property") - ), - [ - Identifier.make_identifier(module_name), - Translator.translate!(to_string(function_name), env) - ] - ) - - {js_ast, env} - end - - def make_function_call(module_name, function_name, params, env) when is_atom(module_name) and is_atom(function_name) do - js_ast = JS.call_expression( - JS.member_expression( - Identifier.make_identifier(module_name), - Identifier.make_identifier(function_name) - ), - Enum.map(params, &Translator.translate!(&1, env)) - ) - - {js_ast, env} - end - - def make_function_call({{:., _, _}, _, _} = module_name, function_name, [], env) do - js_ast = JS.call_expression( - JS.member_expression( - JS.member_expression( - JS.identifier("Bootstrap"), - JS.member_expression( - JS.identifier("Core"), - JS.identifier("Functions") - ) - ), - JS.identifier("call_property") - ), - [ - Translator.translate!(module_name, env), - Translator.translate!(to_string(function_name), env) - ] - ) - - {js_ast, env} - end - - def make_function_call({{:., _, _}, _, _} = module_name, function_name, params, env) do - js_ast = JS.call_expression( - JS.member_expression( - Translator.translate!(module_name, env), - Identifier.make_identifier(function_name) - ), - Enum.map(params, &Translator.translate!(&1, env)) - ) - - {js_ast, env} - end - - def make_function_call(module_name, function_name, [], env) do - js_ast = JS.call_expression( - JS.member_expression( - JS.member_expression( - JS.identifier("Bootstrap"), - JS.member_expression( - JS.identifier("Core"), - JS.identifier("Functions") - ) - ), - JS.identifier("call_property") - ), - [ - Translator.translate!(module_name, env), - Translator.translate!(to_string(function_name), env) - ] - ) - - {js_ast, env} - end - - def make_function_call(module_name, function_name, params, env) do - call = JS.call_expression( - JS.member_expression( - Translator.translate!(module_name, env), - Identifier.make_identifier(function_name) - ), - Enum.map(params, &Translator.translate!(&1, env)) - ) - - { call, env } - end -end diff --git a/lib/elixir_script/translator/kernel/special_forms/capture.ex b/lib/elixir_script/translator/kernel/special_forms/capture.ex deleted file mode 100644 index ec398f95..00000000 --- a/lib/elixir_script/translator/kernel/special_forms/capture.ex +++ /dev/null @@ -1,44 +0,0 @@ -defmodule ElixirScript.Translator.Capture do - @moduledoc false - - alias ESTree.Tools.Builder, as: JS - alias ElixirScript.Translator.PatternMatching - alias ElixirScript.Translator.Function - alias ElixirScript.Translator.Call - alias ElixirScript.Translator.Identifier - alias ElixirScript.Translator - - def make_capture(function_name, _, _) do - Identifier.make_identifier(function_name) - end - - def make_capture(module_name, function_name, _, env) do - members = ["Elixir"] ++ Module.split(module_name) ++ ["__load"] - - ast = JS.member_expression( - JS.call_expression( - Identifier.make_namespace_members(members), - [JS.identifier("Elixir")] - ), - Identifier.make_identifier(function_name) - ) - end - - def make_extern_capture(module_name, function_name, _, env) do - members = Module.split(module_name) ++ [to_string(function_name)] - Identifier.make_namespace_members(members) - end - - def find_value_placeholders(ast) do - case ast do - list when is_list(list) -> - Enum.map(list, &find_value_placeholders(&1)) - {:&, _, [number]} when is_number(number) -> - [{String.to_atom("__#{number}"), [], ElixirScript.Translator.Capture}] - tuple when is_tuple(tuple) -> - Enum.map(Tuple.to_list(tuple), &find_value_placeholders(&1)) - _ -> - [] - end - end -end diff --git a/lib/elixir_script/translator/kernel/special_forms/case.ex b/lib/elixir_script/translator/kernel/special_forms/case.ex deleted file mode 100644 index 5d1215e3..00000000 --- a/lib/elixir_script/translator/kernel/special_forms/case.ex +++ /dev/null @@ -1,17 +0,0 @@ -defmodule ElixirScript.Translator.Case do - @moduledoc false - alias ESTree.Tools.Builder, as: JS - alias ElixirScript.Translator - alias ElixirScript.Translator.Function - - def make_case(condition, clauses, env) do - { func, env } = Function.make_anonymous_function(clauses, env) - - js_ast = JS.call_expression( - JS.member_expression( func, JS.identifier("call")), - [JS.identifier(:this), Translator.translate!(condition, env)] - ) - - { js_ast, env } - end -end diff --git a/lib/elixir_script/translator/kernel/special_forms/cond.ex b/lib/elixir_script/translator/kernel/special_forms/cond.ex deleted file mode 100644 index a9959972..00000000 --- a/lib/elixir_script/translator/kernel/special_forms/cond.ex +++ /dev/null @@ -1,34 +0,0 @@ -defmodule ElixirScript.Translator.Cond do - @moduledoc false - - alias ESTree.Tools.Builder, as: JS - alias ElixirScript.Translator - alias ElixirScript.Translator.Primitive - alias ElixirScript.Translator.Function - - def make_cond(clauses, env) do - js_ast = JS.call_expression( - JS.member_expression( - Primitive.special_forms(), - JS.identifier("cond") - ), - process_cond(clauses, env) - ) - - { js_ast, env } - end - - defp process_cond(clauses, env) do - Enum.map(clauses, fn({:->, _, [clause, clause_body]}) -> - { translated_body, env } = Function.prepare_function_body(clause_body, env) - - translated_body = JS.block_statement(translated_body) - function = JS.function_expression([], [], translated_body) - translated_clause = Translator.translate!(hd(clause), env) - - - Primitive.make_list_no_translate([translated_clause, function]) - end) - end - -end diff --git a/lib/elixir_script/translator/kernel/special_forms/fn.ex b/lib/elixir_script/translator/kernel/special_forms/fn.ex deleted file mode 100644 index 5e0afb65..00000000 --- a/lib/elixir_script/translator/kernel/special_forms/fn.ex +++ /dev/null @@ -1,254 +0,0 @@ -defmodule ElixirScript.Translator.Function do - @moduledoc false - alias ESTree.Tools.Builder, as: JS - alias ElixirScript.Translator - alias ElixirScript.Translator.Group - alias ElixirScript.Translator.PatternMatching - alias ElixirScript.Translator.Block - - @patterns JS.member_expression( - JS.member_expression( - JS.identifier("Bootstrap"), - JS.identifier("Core") - ), - JS.identifier("Patterns") - ) - - @spec make_anonymous_function(list(), ElixirScript.Translator.LexicalScope.t, binary | atom) :: tuple() - def make_anonymous_function(functions, env, name \\ nil) - - def make_anonymous_function(functions, env, name) do - clauses = functions - |> Enum.map(fn - ({:->, _, [[{:when, _, params}], body ]}) -> - guards = List.last(params) - params = params |> Enum.reverse |> tl |> Enum.reverse - process_function_body(params, body, env, name, guards) - - ({:->, _, [params, body]}) -> - process_function_body(params, body, env, name) - - ({_, _, [{:when, _, [{_, _, params}, guards]}, body]}) -> - body = convert_to_try(body) - process_function_body(params, body, env, name, guards) - - ({_, _, [{_, _, params}, body]}) -> - body = convert_to_try(body) - process_function_body(params, body, env, name) - - ({_, _, [{_, _, params}]}) -> - process_function_body(params, [], env, name) - end) - - {make_defmatch(clauses, env.context == :generator), env} - end - - defp convert_to_try([do: body]) do - body - end - - defp convert_to_try(function_kw_list) do - {:__block__, [], [{:try, [], [function_kw_list]}]} - end - - defp make_defmatch(clauses, true) do - JS.call_expression( - JS.member_expression( - @patterns, - JS.identifier("defmatchgen") - ), - clauses - ) - end - - defp make_defmatch(clauses, _) do - JS.call_expression( - JS.member_expression( - @patterns, - JS.identifier("defmatch") - ), - clauses - ) - end - - defp process_function_body(params, body, env, name, guards \\ nil) do - env = ElixirScript.Translator.LexicalScope.function_scope(env, {name, get_arity(params)}) - - {patterns, params, env} = process_params(params, env) - {body, _} = make_function_body(body, env) - - if guards do - guards = case guards do - {:when, _, whens} -> - whens - wh -> - List.wrap(wh) - end - - guards = guards - |> Enum.reverse - |> process_guards - - {guard_body, _} = prepare_function_body(guards, %{env | context: :guard}) - - guard_body = JS.block_statement(guard_body) - make_function_clause(patterns, params, body, guard_body, env.context == :generator) - else - make_function_clause(patterns, params, body, nil, env.context == :generator) - end - end - - defp process_guards([guard]) do - guard - end - - defp process_guards([head | tail]) do - {:or, [], [process_guards(tail), head]} - end - - defp wrap_params(params) when is_atom(params), do: [] - defp wrap_params(params), do: List.wrap(params) - - @spec make_function_body(list | tuple, ElixirScript.Translator.LexicalScope.t) :: tuple() - def make_function_body(body, env) do - {body, _} = body - |> prepare_function_body(env) - - - {JS.block_statement(body), env} - end - - defp get_arity(params) when is_atom(params), do: 0 - defp get_arity(params) when is_tuple(params), do: 1 - defp get_arity(params), do: length(params) - - defp make_params(params) do - Enum.filter(params, fn - (%ESTree.Identifier{name: :undefined}) -> false - (_) -> true - end) - end - - defp process_params(params, env) do - params = wrap_params(params) - {patterns, params, env} = PatternMatching.process_match(params, env) - {patterns, make_params(params), env} - end - - defp make_function_clause(patterns, params, body, guard_body, is_generator?) do - params = Enum.filter(params, fn(x) -> is_nil(x) == false end) - - arguments = case guard_body do - nil -> - [ - JS.array_expression(patterns), - JS.function_expression(params, [], body, is_generator?) - ] - _ -> - [ - JS.array_expression(patterns), - JS.function_expression(params, [], body, is_generator?), - JS.function_expression(params, [], guard_body) - ] - end - - - JS.call_expression( - JS.member_expression( - @patterns, - JS.identifier("clause") - ), - arguments - ) - end - - def prepare_function_body(body, env) do - {list, env} = case body do - nil -> - {[], env} - list when is_list(list) -> - t = Translator.translate!(list, env) - {[t], env} - {:__block__, _, list} -> - Enum.map_reduce(list, env, fn(x, env) -> - Translator.translate(x, env) - end) - _ -> - Enum.map_reduce(List.wrap(body), env, fn(x, env) -> - Translator.translate(x, env) - end) - end - - list = Group.inflate_groups(list) - |> return_last_expression - - {list, env} - end - - defp return_last_expression(nil) do - nil - end - - defp return_last_expression([]) do - [JS.return_statement(JS.literal(nil))] - end - - defp return_last_expression(%ESTree.BlockStatement{} = block) do - %ESTree.BlockStatement{block | body: return_last_expression(block.body)} - end - - defp return_last_expression(list) when is_list(list) do - last_item = List.last(list) - - last_item = case last_item do - %ESTree.YieldExpression{} -> - JS.return_statement(last_item) - %ESTree.Literal{} -> - JS.return_statement(last_item) - %ESTree.Identifier{} -> - JS.return_statement(last_item) - %ESTree.VariableDeclaration{} -> - declaration = hd(last_item.declarations).id - - return_statement = case declaration do - %ESTree.ArrayPattern{elements: elements} -> - if length(elements) == 1 do - JS.return_statement(hd(declaration.elements)) - else - JS.return_statement(JS.array_expression(declaration.elements)) - end - _ -> - JS.return_statement(declaration) - end - - [last_item, return_statement] - %ESTree.BlockStatement{} -> - last_item = %ESTree.BlockStatement{last_item | body: return_last_expression(last_item.body)} - _ -> - if String.contains?(last_item.type, "Expression") do - JS.return_statement(last_item) - else - [last_item, JS.return_statement(JS.literal(nil))] - end - end - - - list = Enum.take(list, length(list) - 1) - |> Enum.map(fn(x) -> - case x do - %ESTree.MemberExpression{} -> - JS.expression_statement(x) - %ESTree.CallExpression{} -> - JS.expression_statement(x) - _ -> - x - end - end) - - if is_list(last_item) do - list ++ last_item - else - list ++ [last_item] - end - end -end diff --git a/lib/elixir_script/translator/kernel/special_forms/for.ex b/lib/elixir_script/translator/kernel/special_forms/for.ex deleted file mode 100644 index e690f710..00000000 --- a/lib/elixir_script/translator/kernel/special_forms/for.ex +++ /dev/null @@ -1,130 +0,0 @@ -defmodule ElixirScript.Translator.For do - @moduledoc false - alias ESTree.Tools.Builder, as: JS - alias ElixirScript.Translator - alias ElixirScript.Translator.PatternMatching - alias ElixirScript.Translator.Primitive - alias ElixirScript.Translator.Function - alias ElixirScript.Translator.Utils - alias ElixirScript.Translator.Identifier - - def make_for(generators, env) do - ElixirScript.Translator.State.add_module_reference(env.state, env.module, ElixirScript.Collectable) - args = handle_args(generators, env) - - generators = JS.array_expression(args.generators) - - into = args.into || Primitive.make_list_no_translate([]) - filter = args.filter || JS.function_expression([], [], JS.block_statement([JS.return_statement(JS.identifier("true"))])) - fun = args.fun - - members = ["Elixir"] ++ Module.split(ElixirScript.Collectable) ++ ["__load"] - - collectable_module = JS.call_expression( - Identifier.make_namespace_members(members), - [JS.identifier("Elixir")] - ) - - - expression = JS.call_expression( - JS.member_expression( - JS.member_expression( - JS.member_expression( - JS.identifier("Bootstrap"), - JS.identifier("Core") - ), - JS.identifier("Patterns") - ), - JS.identifier("clause") - ), - [JS.array_expression(args.patterns), fun, filter] - ) - - js_ast = JS.call_expression( - JS.member_expression( - Primitive.special_forms(), - JS.identifier("_for") - ), - [expression, generators, collectable_module, into] - ) - - {js_ast, env} - end - - defp handle_args(generators, env) do - Enum.reduce(generators, %{generators: [], args: [], filter: nil, fun: nil, into: nil, patterns: []}, fn - - ({:<<>>, _, body}, state) -> - {bs_parts, collection} = Enum.map_reduce(body, nil, fn - {:::, _, _} = ast, state -> - {ast, state} - {:<-, _, [var, collection]}, _ -> - {var, collection} - end) - - {patterns, params, env} = PatternMatching.process_match([{:<<>>, [], bs_parts}], env) - - gen = JS.call_expression( - JS.member_expression( - JS.member_expression( - JS.member_expression( - JS.identifier("Bootstrap"), - JS.identifier("Core") - ), - JS.identifier("Patterns") - ), - JS.identifier("bitstring_generator") - ), - [hd(patterns), Translator.translate!(collection, env)] - ) - - %{state | generators: state.generators ++ [gen], args: state.args ++ params, patterns: state.patterns ++ patterns} - - ({:<-, _, [identifier, enum]}, state) -> - {patterns, params, env} = PatternMatching.process_match([identifier], env) - - gen = JS.call_expression( - JS.member_expression( - JS.member_expression( - JS.member_expression( - JS.identifier("Bootstrap"), - JS.identifier("Core") - ), - JS.identifier("Patterns") - ), - JS.identifier("list_generator") - ), - [hd(patterns), Translator.translate!(enum, env)] - ) - - %{state | generators: state.generators ++ [gen], args: state.args ++ params, patterns: state.patterns ++ patterns} - ([into: expression], state) -> - %{state | into: Translator.translate(expression, env)} - - ([into: expression, do: expression2], state) -> - fun = create_function_expression(expression2, env, state) - - %{state | into: Translator.translate!(expression, env), fun: fun} - - ([do: expression], state) -> - fun = create_function_expression(expression, env, state) - - %{state | fun: fun} - (filter, state) -> - fun = create_function_expression(filter, env, state) - - %{state | filter: fun} - end) - end - - - defp create_function_expression(ast, env, state) do - {ast, _} = Function.make_function_body(ast, env) - - JS.function_expression( - state.args, - [], - ast - ) - end -end diff --git a/lib/elixir_script/translator/kernel/special_forms/identifier.ex b/lib/elixir_script/translator/kernel/special_forms/identifier.ex deleted file mode 100644 index 850c6417..00000000 --- a/lib/elixir_script/translator/kernel/special_forms/identifier.ex +++ /dev/null @@ -1,98 +0,0 @@ -defmodule ElixirScript.Translator.Identifier do - @moduledoc false - alias ESTree.Tools.Builder, as: JS - - @js_reserved_words [ - :break, - :case, - :class, - :const, - :continue, - :debugger, - :default, - :delete, - :do, - :else, - :export, - :extends, - :finally, - :function, - :if, - :import, - :in, - :instanceof, - :new, - :return, - :super, - :switch, - :throw, - :try, - :typeof, - :var, - :void, - :while, - :with, - :yield - ] - - def make_identifier({:__aliases__, _, aliases}) do - aliases - |> Enum.reverse - |> make_alias - end - - def make_identifier([ast]) do - make_identifier(ast) - end - - def make_identifier(ast) do - ast - |> filter_name - |> JS.identifier - end - - defp filter_name(name) when is_tuple(name) do - name - end - - defp filter_name(reserved_word) when reserved_word in @js_reserved_words do - "__#{Atom.to_string(reserved_word)}__" - end - - defp filter_name(name) do - to_string(name) - |> String.replace("?", "__qmark__") - |> String.replace("!", "__emark__") - end - - defp make_alias([x]) do - make_identifier(x) - end - - defp make_alias([h|t]) do - JS.member_expression(make_alias(t), make_identifier(h)) - end - - def make_namespace_members(module_name) do - case module_name do - m when is_list(m) -> - m - m when is_binary(m) -> - String.split(m, ".") - m when is_atom(m) -> - Module.split(m) - end - |> Enum.reverse - |> make_alias - end - - def make_function_name(name) do - name = filter_name(name) - JS.identifier(name) - end - - def make_extern_function_name(name) do - JS.identifier("#{name}") - end - -end diff --git a/lib/elixir_script/translator/kernel/special_forms/map.ex b/lib/elixir_script/translator/kernel/special_forms/map.ex deleted file mode 100644 index 77e4382b..00000000 --- a/lib/elixir_script/translator/kernel/special_forms/map.ex +++ /dev/null @@ -1,91 +0,0 @@ -defmodule ElixirScript.Translator.Map do - @moduledoc false - alias ESTree.Tools.Builder, as: JS - alias ElixirScript.Translator - alias ElixirScript.Translator.Primitive - - def make_map(object_expression) do - JS.call_expression( - JS.member_expression( - JS.identifier(:Object), - JS.identifier(:freeze) - ), - [object_expression] - ) - end - - def make_get_property(target, property, env) do - JS.member_expression( - Translator.translate!(target, env), - Translator.translate!(property, env), - true - ) - end - - def make_object(properties, env) do - properties - |> Enum.map(fn - ({x, {:__aliases__, _, [value]}}) -> make_property(Translator.translate!(x, env), JS.identifier(value)) - ({x, y}) -> - case x do - {_, _, atom } when is_atom(atom) -> - JS.property(Translator.translate!(x, env), Translator.translate!(y, env), :init, false, false, true) - _ -> - make_property(Translator.translate!(x, env), Translator.translate!(y, env)) - end - end) - |> JS.object_expression - |> make_map - end - - def make_property(%ESTree.Identifier{} = key, value) do - JS.property(key, value) - end - - def make_property(%ESTree.Literal{value: k}, value) when is_binary(k) do - key = case String.contains?(k, "-") do - true -> - JS.literal(k) - false -> - JS.identifier(k) - end - - JS.property(key, value) - end - - def make_property(key, value) do - JS.property(key, value, :init, false, false, true) - end - - def make_shorthand_property(%ESTree.Identifier{} = key) do - JS.property(key, key, :init, true) - end - - def make_map_update(map, data, env) do - map = Translator.translate!(map, env) - data = Translator.translate!({:%{}, [], data}, env) - - js_ast = JS.call_expression( - JS.member_expression( - JS.identifier("Object"), - JS.identifier("freeze") - ), - [ - JS.call_expression( - JS.member_expression( - JS.identifier("Object"), - JS.identifier("assign") - ), - [ - JS.object_expression([]), - map, - data - ] - ) - ] - ) - - { js_ast, env } - end - -end diff --git a/lib/elixir_script/translator/kernel/special_forms/match.ex b/lib/elixir_script/translator/kernel/special_forms/match.ex deleted file mode 100644 index b59ffd64..00000000 --- a/lib/elixir_script/translator/kernel/special_forms/match.ex +++ /dev/null @@ -1,93 +0,0 @@ -defmodule ElixirScript.Translator.Match do - @moduledoc false - alias ESTree.Tools.Builder, as: JS - alias ElixirScript.Translator - alias ElixirScript.Translator.PatternMatching - alias ElixirScript.Translator.Primitive - - def make_match(left, right, env) do - { right_ast, env } = Translator.translate(right, env) - - { patterns, params, env } = PatternMatching.process_match([left], env) - - declarator = JS.variable_declarator( - JS.array_pattern(params), - JS.call_expression( - JS.member_expression( - JS.member_expression( - JS.member_expression( - JS.identifier("Bootstrap"), - JS.identifier("Core") - ), - JS.identifier("Patterns") - ), - JS.identifier("match") - ), - [hd(patterns), right_ast] - ) - ) - - array_pattern = JS.variable_declaration([declarator], :let) - - js_ast = case left do - list when is_list(list) -> - make_list_ref(array_pattern, params) - { _, _ } -> - make_tuple_ref(array_pattern, params) - {:{}, _, _ } -> - make_tuple_ref(array_pattern, params) - _ -> - array_pattern - end - - { js_ast, env } - end - - defp make_list_ref(array_pattern, params) do - {ref, params} = make_params(params) - - ref_declarator = JS.variable_declarator( - ref, - Primitive.do_make_list(params) - ) - - make_variable_declaration_and_group(ref_declarator, array_pattern) - end - - defp make_tuple_ref(array_pattern, params) do - {ref, params} = make_params(params) - - ref_declarator = JS.variable_declarator( - ref, - JS.new_expression( - JS.member_expression( - JS.identifier("Bootstrap"), - JS.member_expression( - JS.identifier("Core"), - JS.identifier("Tuple") - ) - ), - params - ) - ) - - make_variable_declaration_and_group(ref_declarator, array_pattern) - end - - - defp make_params(params) do - ref = JS.identifier("_ref") - - params = Enum.map(params, fn - (nil) -> JS.identifier(:undefined) - (x) -> x - end) - - { ref, params } - end - - defp make_variable_declaration_and_group(ref_declarator, array_pattern) do - ref_declaration = JS.variable_declaration([ref_declarator], :let) - %ElixirScript.Translator.Group{ body: [array_pattern, ref_declaration] } - end -end diff --git a/lib/elixir_script/translator/kernel/special_forms/primitive.ex b/lib/elixir_script/translator/kernel/special_forms/primitive.ex deleted file mode 100644 index 292ccbcc..00000000 --- a/lib/elixir_script/translator/kernel/special_forms/primitive.ex +++ /dev/null @@ -1,99 +0,0 @@ -defmodule ElixirScript.Translator.Primitive do - @moduledoc false - alias ESTree.Tools.Builder, as: JS - alias ElixirScript.Translator - alias ElixirScript.Translator.Quote - - def special_forms() do - JS.member_expression( - JS.identifier("Bootstrap"), - JS.member_expression( - JS.identifier("Core"), - JS.identifier("SpecialForms") - ) - ) - end - - def tuple_class() do - JS.member_expression( - JS.member_expression( - JS.identifier("Bootstrap"), - JS.identifier("Core") - ), - JS.identifier("Tuple") - ) - end - - def list_ast() do - JS.member_expression( - JS.member_expression( - JS.identifier("Bootstrap"), - JS.member_expression( - JS.identifier("Core"), - JS.identifier("SpecialForms") - ) - ), - JS.identifier("list") - ) - end - - def make_atom(ast) when is_atom(ast) do - JS.call_expression( - JS.member_expression( - JS.identifier("Symbol"), - JS.identifier("for") - ), - [JS.literal(ast)] - ) - end - - def make_literal(ast) when is_number(ast) or is_binary(ast) or is_boolean(ast) or is_nil(ast) do - JS.literal(ast) - end - - def make_list(ast, env) when is_list(ast) do - js_ast = Enum.map(ast, &Translator.translate!(&1, env)) - |> do_make_list - - { js_ast, env } - end - - def make_list_quoted(opts, ast, env) when is_list(ast) do - Enum.map(ast, fn(x) -> Quote.make_quote(opts, x, env) end) - |> do_make_list - end - - def make_list_no_translate(ast) when is_list(ast) do - do_make_list(ast) - end - - def do_make_list(ast) do - JS.call_expression( - JS.member_expression( - JS.identifier("Object"), - JS.identifier("freeze") - ), - [JS.array_expression(ast)] - ) - end - - def make_tuple({ one, two }, env) do - make_tuple([one, two], env) - end - - def make_tuple(elements, env) do - list = Enum.map(elements, &Translator.translate!(&1, env)) - - js_ast = JS.new_expression(tuple_class, list) - - { js_ast, env } - end - - def make_tuple_quoted(opts, elements, env) do - JS.new_expression( - tuple_class, - Enum.map(elements, fn(x) -> Quote.make_quote(opts, x, env) end) - ) - end - -end diff --git a/lib/elixir_script/translator/kernel/special_forms/quote.ex b/lib/elixir_script/translator/kernel/special_forms/quote.ex deleted file mode 100644 index 63341757..00000000 --- a/lib/elixir_script/translator/kernel/special_forms/quote.ex +++ /dev/null @@ -1,87 +0,0 @@ -defmodule ElixirScript.Translator.Quote do - @moduledoc false - - alias ESTree.Tools.Builder, as: JS - alias ElixirScript.Translator - alias ElixirScript.Translator.Primitive - - def make_quote(_opts, expr, env) when is_number(expr) or is_binary(expr) or is_boolean(expr) or is_nil(expr) or is_atom(expr) do - Translator.translate!(expr, env) - end - - def make_quote(opts, expr, env) when is_list(expr) do - has_unquote_splicing = Enum.any?(expr, fn - ({:unquote_splicing, _, _}) -> true - (_) -> false - end) - - if has_unquote_splicing do - expr = Enum.map(expr, fn - ({:unquote_splicing, _, [param]}) -> - make_unquote_slicing(param, env) - (x) -> - Primitive.make_list_no_translate([make_quote(opts, x, env)]) - end - ) - - JS.call_expression( - JS.member_expression( - JS.identifier("Bootstrap"), - JS.member_expression( - JS.identifier("Enum"), - JS.identifier("concat") - ) - ), - expr - ) - else - Primitive.make_list_quoted(opts, expr, env) - end - end - - def make_quote(opts, {one, two}, env) do - Primitive.make_tuple_quoted(opts, [one, two], env) - end - - def make_quote([unquote: false] = opts, {:unquote, context, params}, env) do - Primitive.make_tuple_quoted(opts, [:unquote, context, params], env) - end - - def make_quote([context: {_, _, [new_context]}] = opts, {name, context, params}, env) do - updated_context = Keyword.put(context, :context, new_context) - Primitive.make_tuple_quoted(opts, [name, updated_context, params], env) - end - - def make_quote(_, {:alias!, _, [the_alias]}, _) do - the_alias - end - - def make_quote(_, {:unquote, _, [param]}, env) do - make_unquote(param, env) - end - - def make_quote(opts, {name, context, elements }, env) do - if is_in_bind_quoted(opts[:bind_quoted], name) do - Translator.translate!({name, context, elements }, env) - else - Primitive.make_tuple_quoted(opts, [name, context, elements], env) - end - end - - def make_unquote(expr, env) do - Translator.translate!(expr, env) - end - - def make_unquote_slicing(expr, env) do - Translator.translate!(expr, env) - end - - defp is_in_bind_quoted(nil, _) do - false - end - - defp is_in_bind_quoted(binds, name) do - binds[name] != nil - end - -end diff --git a/lib/elixir_script/translator/kernel/special_forms/struct.ex b/lib/elixir_script/translator/kernel/special_forms/struct.ex deleted file mode 100644 index 6d9f522f..00000000 --- a/lib/elixir_script/translator/kernel/special_forms/struct.ex +++ /dev/null @@ -1,116 +0,0 @@ -defmodule ElixirScript.Translator.Struct do - @moduledoc false - alias ESTree.Tools.Builder, as: JS - alias ElixirScript.Translator - alias ElixirScript.Translator.Utils - alias ElixirScript.Translator.Map - alias ElixirScript.Translator.Identifier - - def make_struct(attributes, env) do - struct_name = Map.make_property(Translator.translate!(:__struct__, env), Translator.translate!({:__MODULE__, [], []}, env)) - - defaults = Enum.map(attributes, fn - ({x, y}) -> - Map.make_property( - Translator.translate!(x, env), - Translator.translate!(y, env) - ) - (x) -> - Map.make_property( - Translator.translate!(x, env), - Translator.translate!(nil, env) - ) - end) - - keys = Enum.map(attributes, fn - ({x, _}) -> - Translator.translate!(x, env) - (x) -> - Translator.translate!(x, env) - end) - - keys = JS.array_expression(keys) - defaults = JS.object_expression([struct_name] ++ defaults) - - allowed_keys = JS.variable_declaration([JS.variable_declarator( - JS.identifier("allowed_keys"), - keys - )], :const) - - value_keys = JS.variable_declaration([JS.variable_declarator( - JS.identifier("value_keys"), - JS.call_expression( - JS.member_expression( - JS.identifier("Object"), - JS.identifier("keys") - ), - [JS.identifier("values")] - ) - )], :const) - - every_call = JS.call_expression( - JS.member_expression( - JS.identifier("value_keys"), - JS.identifier("every") - ), - [ - JS.function_expression([JS.identifier("key")], [], JS.block_statement([ - JS.return_statement( - JS.call_expression( - JS.member_expression( - JS.identifier("allowed_keys"), - JS.identifier("includes") - ), - [JS.identifier("key")] - ) - ) - ])) - ] - ) - - every_call_result = JS.variable_declaration([JS.variable_declarator( - JS.identifier("every_call_result"), - every_call - )], :const) - - bottom = JS.if_statement( - JS.identifier("every_call_result"), - JS.block_statement([ - JS.return_statement( - JS.call_expression( - JS.member_expression( - JS.identifier("Object"), - JS.identifier("assign") - ), - [JS.object_expression([]), defaults, JS.identifier("values")] - ) - ) - ]), - JS.block_statement([ - JS.throw_statement( - JS.literal("Unallowed key found") - ) - ]) - ) - - func = JS.function_expression([ - %ESTree.AssignmentPattern{ - left: JS.identifier("values"), - right: JS.object_expression([]) - } - ], - [], - JS.block_statement([ - allowed_keys, - value_keys, - every_call_result, - bottom - ])) - - JS.variable_declaration([JS.variable_declarator( - JS.identifier("__struct__"), - func - )], :const) - end - -end diff --git a/lib/elixir_script/translator/kernel/special_forms/try.ex b/lib/elixir_script/translator/kernel/special_forms/try.ex deleted file mode 100644 index 94276f23..00000000 --- a/lib/elixir_script/translator/kernel/special_forms/try.ex +++ /dev/null @@ -1,115 +0,0 @@ -defmodule ElixirScript.Translator.Try do - @moduledoc false - alias ESTree.Tools.Builder, as: JS - alias ElixirScript.Translator.Function - alias ElixirScript.Translator.Primitive - - def make_try(blocks, env) do - try_block = Keyword.get(blocks, :do) - rescue_block = Keyword.get(blocks, :rescue, nil) - catch_block = Keyword.get(blocks, :catch, nil) - after_block = Keyword.get(blocks, :after, nil) - else_block = Keyword.get(blocks, :else, nil) - - { translated_body, _ } = Function.prepare_function_body(try_block, env) - - translated_body = JS.block_statement(translated_body) - try_block = JS.function_expression([], [], translated_body) - - rescue_block = if rescue_block do - process_rescue_block(rescue_block, env) - else - JS.identifier(:null) - end - - catch_block = if catch_block do - process_catch_block(catch_block, env) - else - JS.identifier(:null) - end - - after_block = if after_block do - process_after_block(after_block, env) - else - JS.identifier(:null) - end - - else_block = if else_block do - Function.make_anonymous_function(else_block, env) - |> elem(0) - else - JS.identifier(:null) - end - - js_ast = JS.call_expression( - JS.member_expression( - Primitive.special_forms(), - JS.identifier("_try") - ), - [ - try_block, - rescue_block, - catch_block, - else_block, - after_block - ] - ) - - { js_ast, env } - end - - defp process_rescue_block(rescue_block, env) do - { func, _ } = Enum.map(rescue_block, fn(x) -> - case x do - {:->, _, [[{value, _, module}], block]} when not is_list(module) -> - {:->, [], [[{value, [], convert_to_struct(module, env)}], block]} - {:->, _, [[{:in, meta, [value, error_names]}], block]} -> - error_names = Enum.map(error_names, fn(x) -> - convert_to_struct(x, env) - end) - - guards = {:in, meta, [value, error_names]} - - {:->, [], [ [{:when, [], [value | [guards]]}], block ]} - {:->, _, [error_names, block]} -> - Enum.map(error_names, fn(x) -> - {:->, [], [[convert_to_struct(x, env)], block]} - end) - end - end) - |> List.flatten - |> Function.make_anonymous_function(env) - - func - end - - defp process_catch_block(catch_block, env) do - {func, _} = catch_block - |> Function.make_anonymous_function(env) - - func - end - - defp process_after_block(after_block, env) do - { translated_body, _ } = Function.prepare_function_body(after_block, env) - translated_body = JS.block_statement(translated_body) - - JS.function_expression([], [], translated_body) - end - - defp convert_to_struct([module], env) do - convert_to_struct(module, env) - end - - defp convert_to_struct(module, env) do - case module do - {:__aliases__, _, _} = alias_ast -> - alias_ast = ElixirScript.Translator.State.get_module_name(env.state, alias_ast) - |> ElixirScript.Translator.Utils.name_to_quoted - - {:%, [], [alias_ast, {:%{}, [], []}]} - ast -> - ast - end - end -end diff --git a/lib/elixir_script/translator/kernel/special_forms/with.ex b/lib/elixir_script/translator/kernel/special_forms/with.ex deleted file mode 100644 index dbd8b7bf..00000000 --- a/lib/elixir_script/translator/kernel/special_forms/with.ex +++ /dev/null @@ -1,52 +0,0 @@ -defmodule ElixirScript.Translator.With do - @moduledoc false - - alias ESTree.Tools.Builder, as: JS - alias ElixirScript.Translator.Function - alias ElixirScript.Translator.Primitive - alias ElixirScript.Translator.PatternMatching - - def make_with(args, env) do - result = Enum.reduce(args, %{ expressions: [], arguments: [] }, fn - {symbol, _, [pattern, expr] }, state when symbol in [:<-, :=] -> - {body , _} = Function.prepare_function_body(expr, env) - translated_body = JS.block_statement(body) - expr_function = JS.function_expression(state.arguments, [], translated_body) - - { patterns, params, _ } = PatternMatching.process_match([pattern], env) - - %{state | arguments: state.arguments ++ params, - expressions: state.expressions ++ [ JS.array_expression([hd(patterns), expr_function]) ] } - - [do: expr], state -> - expr_function = process_do_block(expr, state.arguments, env) - - %{state | expressions: state.expressions ++ [ expr_function ] } - [do: do_expr, else: else_expr], state -> - do_function = process_do_block(do_expr, state.arguments, env) - - { else_function, _ } = Function.make_anonymous_function(else_expr, env) - - %{state | expressions: state.expressions ++ [ do_function, else_function ] } - end) - - expressions = result.expressions - - js_ast = JS.call_expression( - JS.member_expression( - Primitive.special_forms(), - JS.identifier("_with") - ), - expressions - ) - - { js_ast, env } - - end - - defp process_do_block(expr, arguments, env) do - {body , _} = Function.prepare_function_body(expr, env) - translated_body = JS.block_statement(body) - JS.function_expression(arguments, [], translated_body) - end -end diff --git a/lib/elixir_script/translator/lexical_scope.ex b/lib/elixir_script/translator/lexical_scope.ex deleted file mode 100644 index f202e549..00000000 --- a/lib/elixir_script/translator/lexical_scope.ex +++ /dev/null @@ -1,394 +0,0 @@ -defmodule ElixirScript.Translator.LexicalScope do - @moduledoc false - - @type t :: %ElixirScript.Translator.LexicalScope{ - module: atom, - file: binary, - line: non_neg_integer, - function: { atom, non_neg_integer } | nil, - context: :match | :guard | :generator | nil, - aliases: [{atom, atom}], - requires: [atom], - functions: [{atom, [{ atom, non_neg_integer }]}], - macros: [{atom, [{ atom, non_neg_integer }]}], - macro_aliases: [{atom, {integer, atom}}], - context_modules: [atom], - vars: [{atom, atom | non_neg_integer}], - export_vars: [{atom, atom | non_neg_integer}] | nil, - lexical_tracker: nil, - caller: t | nil, - env: nil, - state: pid, - format: atom, - module_formatter: atom - } - - defstruct [ - module: nil, - file: nil, - line: 0, - function: nil, - context: nil, - aliases: [], - requires: [], - functions: [], - macros: [], - macro_aliases: [], - context_modules: [], - vars: [], - export_vars: nil, - lexical_tracker: nil, - caller: nil, - env: nil, - state: nil, - format: :es, - module_formatter: ElixirScript.ModuleSystems.ES - ] - - def env(scope) do - %Macro.Env{ - module: scope.module, - file: scope.file, - line: scope.line, - function: scope.function, - context: scope.context, - aliases: scope.aliases, - requires: scope.requires, - functions: scope.functions, - macros: scope.macros, - macro_aliases: scope.macro_aliases, - context_modules: scope.context_modules, - vars: Enum.map(scope.vars, fn({key, _}) -> {key, nil} end), - export_vars: scope.export_vars, - lexical_tracker: scope.lexical_tracker - } - end - - def caller(scope) do - %Macro.Env{ - module: scope.caller.module, - file: scope.caller.file, - line: scope.caller.line, - function: scope.caller.function, - context: scope.caller.context, - aliases: scope.caller.aliases, - requires: scope.caller.requires, - functions: scope.caller.functions, - macros: scope.caller.macros, - macro_aliases: scope.caller.macro_aliases, - context_modules: scope.caller.context_modules, - vars: Enum.map(scope.vars, fn({key, _}) -> {key, nil} end), - export_vars: scope.caller.export_vars, - lexical_tracker: scope.caller.lexical_tracker - } - end - - def module_scope(ElixirScript.Temp, filename, env, state, opts) do - - env = %ElixirScript.Translator.LexicalScope { - module: ElixirScript.Temp, file: filename, requires: [], - functions: [], - macros: [], - env: env, - state: state, - format: opts.format, - module_formatter: opts.module_formatter - } - - add_import(env, ElixirScript.Kernel) - end - - def module_scope(module_name, filename, env, state, opts) do - module = ElixirScript.Translator.State.get_module(state, module_name) - - env = %ElixirScript.Translator.LexicalScope { - module: module_name, file: filename, requires: [], - functions: [{ module.name, module.functions}], - macros: [{module.name, module.macros}], - env: env, - state: state, - format: opts.format, - module_formatter: opts.module_formatter - } - - env = add_import(env, ElixirScript.Kernel) - - cond do - module_name == JS -> - env - ElixirScript.Translator.State.is_module_loaded?(env.state, module_name) and length(module.macros) > 0 -> - add_import(env, module_name, [only: :macros]) - true -> - env - end - end - - def function_scope(env, { _, _ } = func) do - %{ env | function: func, caller: env} - end - - def function_scope(env, nil) do - %{ env | function: nil, caller: env } - end - - def find_module(env, name_arity) do - result = Enum.find(env.functions ++ env.macros, fn({_, functions}) -> - name_arity in functions - end) - - if result == nil do - nil - else - elem(result, 0) - end - - end - - def add_var(env, variable_name) when is_binary(variable_name) do - add_var(env, String.to_atom(variable_name)) - end - - def add_var(env, variable_name) do - %{ env | vars: Keyword.update(env.vars, variable_name, 0, &(&1 + 1)) } - end - - def get_var(env, variable_name) when is_binary(variable_name) do - get_var(env, String.to_atom(variable_name)) - end - - def get_var(env, variable_name) do - count = Keyword.get(env.vars, variable_name, nil) - - case count do - nil -> - nil - 0 -> - String.to_atom(Atom.to_string(variable_name)) - _ -> - String.to_atom(Atom.to_string(variable_name) <> to_string(count)) - end - end - - def has_var?(env, variable_name) when is_binary(variable_name) do - has_var?(env, String.to_atom(variable_name)) - end - - def has_var?(env, variable_name) do - Keyword.get(env.vars, variable_name, nil) != nil - end - - defp get_module(env, Kernel) do - get_module(env, ElixirScript.Kernel) - end - - defp get_module(env, module_name) do - module = ElixirScript.Translator.State.get_module(env.state, get_module_name(env, module_name)) - - unless module do - module_name = case module_name do - {:__aliases__, _, _} -> - ElixirScript.Translator.Utils.quoted_to_name(module_name) - |> Atom.to_string - |> String.split(".") - |> tl - |> Enum.join(".") - _ -> - module_name - end - - raise "Module #{inspect module_name} not found" - end - - if Map.get(module, :load_only, false) == false do - ElixirScript.Translator.State.add_module_reference(env.state, env.module, module.name) - end - - module - end - - defp has_module?(env, module_name) do - try do - module = get_module(env, module_name) - case module do - %{load_only: true} -> - false - _ -> - true - end - rescue - _ -> - false - end - end - - def add_alias(env, module_name, alias_name) do - module = get_module(env, module_name) - %{ env | aliases: Enum.uniq(env.aliases ++ [{alias_name, module.name}]) } - end - - def add_import(env, module_name) do - check_for_module_existence(env, module_name) - ElixirScript.Translator.State.add_module_reference(env.state, env.module, module_name) - - env = if ElixirScript.Translator.State.is_module_loaded?(env.state, module_name) do - add_import_macro(env, module_name, []) - else - env - end - - if has_module?(env, module_name) do - module = get_module(env, module_name) - %{ env | requires: Enum.uniq(env.requires ++ [module.name]), - functions: env.functions ++ [{ module.name, module.functions }] - } - else - env - end - end - - def add_import(env, module_name, [only: :functions]) do - module = get_module(env, module_name) - ElixirScript.Translator.State.add_module_reference(env.state, env.module, module_name) - - %{ env | functions: List.keydelete(env.functions, module_name, 0) ++ [{ module.name, module.functions }], - requires: Enum.uniq(env.requires ++ [module.name]) - } - end - - def add_import(env, module_name, [only: :macros]) do - if !ElixirScript.Translator.State.is_module_loaded?(env.state, module_name) do - raise "Module #{inspect module_name} not found" - end - - add_import_macro(env, module_name, [only: :macros]) - end - - def add_import(env, module_name, [only: only]) do - check_for_module_existence(env, module_name) - ElixirScript.Translator.State.add_module_reference(env.state, env.module, module_name) - - env = if ElixirScript.Translator.State.is_module_loaded?(env.state, module_name) do - list = module_name.__info__(:macros) - list = Enum.filter(list, fn(mac) -> mac in only end) - add_import_macro(env, module_name, [only: list]) - else - env - end - - if has_module?(env, module_name) do - module = get_module(env, module_name) - - functions = Enum.filter(module.functions, fn(func) -> - func in only - end) - - %{ env | requires: Enum.uniq(env.requires ++ [module.name]), - functions: List.keydelete(env.functions, module.name, 0) ++ [{ module.name, functions }] } - else - env - end - end - - def add_import(env, module_name, [except: except]) do - check_for_module_existence(env, module_name) - ElixirScript.Translator.State.add_module_reference(env.state, env.module, module_name) - - env = if ElixirScript.Translator.State.is_module_loaded?(env.state, module_name) do - list = module_name.__info__(:macros) - list = Enum.filter(list, fn(mac) -> mac in except end) - add_import_macro(env, module_name, [except: list]) - else - env - end - - if has_module?(env, module_name) do - module = get_module(env, module_name) - {_, current_functions } = List.keyfind(env.functions, module.name, 0, { module.name, module.functions }) - - functions = Enum.filter(current_functions, fn(func) -> not(func in except) end) - - %{ env | requires: env.requires ++ [module.name], - functions: List.keydelete(env.functions, module.name, 0) ++ [{ module.name, functions }] } - else - env - end - end - - def add_require(env, module_name) do - check_for_module_existence(env, module_name) - ElixirScript.Translator.State.add_module_reference(env.state, env.module, module_name) - - env = if ElixirScript.Translator.State.is_module_loaded?(env.state, module_name) do - add_require_macro(env, module_name, []) - else - env - end - - if has_module?(env, module_name) do - module = get_module(env, module_name) - %{ env | requires: Enum.uniq(env.requires ++ [module.name]) } - else - env - end - end - - def add_require(env, module_name, alias_name) do - check_for_module_existence(env, module_name) - ElixirScript.Translator.State.add_module_reference(env.state, env.module, module_name) - - env = if ElixirScript.Translator.State.is_module_loaded?(env.state, module_name) do - add_require_macro(env, module_name, [as: alias_name]) - else - env - end - - if has_module?(env, module_name) do - module = get_module(env, module_name) - %{ env | aliases: Enum.uniq(env.aliases ++ [{alias_name, module.name}]), - requires: Enum.uniq(env.requires ++ [module.name]) } - else - env - end - end - - def get_module_name(env, module_name) do - module_name = ElixirScript.Translator.State.get_module_name(env.state, module_name) - - if Keyword.has_key?(env.aliases, module_name) do - Keyword.fetch!(env.aliases, module_name) - else - module_name - end - - end - - defp check_for_module_existence(env, module_name) do - if ElixirScript.Translator.State.is_module_loaded?(env.state, module_name) == false and has_module?(env, module_name) == false do - raise "Module #{inspect module_name} not found" - end - end - - - defp add_import_macro(elixirscript_env, module, opts) do - eval = """ - import #{inspect module}, #{inspect opts} - __ENV__ - """ - - do_macro(eval, elixirscript_env) - end - - defp add_require_macro(elixirscript_env, module, opts) do - eval = """ - require #{inspect module}, #{inspect opts} - __ENV__ - """ - - do_macro(eval, elixirscript_env) - end - - defp do_macro(eval, elixirscript_env) do - {env, _} = Code.eval_string(eval, [], elixirscript_env.env) - %{ elixirscript_env | env: env } - end -end diff --git a/lib/elixir_script/translator/pattern_matching.ex b/lib/elixir_script/translator/pattern_matching.ex deleted file mode 100644 index d03892b5..00000000 --- a/lib/elixir_script/translator/pattern_matching.ex +++ /dev/null @@ -1,278 +0,0 @@ -defmodule ElixirScript.Translator.PatternMatching do - @moduledoc false - - alias ESTree.Tools.Builder, as: JS - alias ElixirScript.Translator - alias ElixirScript.Translator.Primitive - alias ElixirScript.Translator.Identifier - alias ElixirScript.Translator.Map - alias ElixirScript.Translator.Struct - alias ElixirScript.Translator.Bitstring - alias ElixirScript.Translator.Utils - - @patterns JS.member_expression( - JS.member_expression( - JS.identifier("Bootstrap"), - JS.identifier("Core") - ), - JS.identifier("Patterns") - ) - - @wildcard JS.member_expression( - @patterns, - JS.identifier(:wildcard) - ) - - @parameter JS.member_expression( - @patterns, - JS.identifier(:variable) - ) - - @head_tail JS.member_expression( - @patterns, - JS.identifier(:headTail) - ) - - @starts_with JS.member_expression( - @patterns, - JS.identifier(:startsWith) - ) - - @capture JS.member_expression( - @patterns, - JS.identifier(:capture) - ) - - @bound JS.member_expression( - @patterns, - JS.identifier(:bound) - ) - - @_type JS.member_expression( - @patterns, - JS.identifier(:type) - ) - - @bitstring_match JS.member_expression( - @patterns, - JS.identifier(:bitStringMatch) - ) - - def wildcard() do - JS.call_expression( - @wildcard, - [] - ) - end - - def parameter() do - JS.call_expression( - @parameter, - [] - ) - end - - def parameter(default_value) do - JS.call_expression( - @parameter, - [default_value] - ) - end - - def head_tail(headParameter, tailParameter) do - JS.call_expression( - @head_tail, - [headParameter, tailParameter] - ) - end - - def starts_with(prefix) do - JS.call_expression( - @starts_with, - [JS.literal(prefix)] - ) - end - - def capture(value) do - JS.call_expression( - @capture, - [value] - ) - end - - def bound(value) do - JS.call_expression( - @bound, - [value] - ) - end - - def type(prototype, value) do - JS.call_expression( - @_type, - [prototype, value] - ) - end - - def bitstring_match(values) do - JS.call_expression( - @bitstring_match, - values - ) - end - - - def process_match(params, env) do - build_match(params, env) - |> update_env(env) - end - - defp update_env({ patterns, params }, env) do - - { params, env } = Enum.map_reduce(params, env, fn - (%ESTree.Identifier{name: :undefined} = param, env) -> - { param, env } - - (%ESTree.Identifier{} = param, env) -> - env = ElixirScript.Translator.LexicalScope.add_var(env, param.name) - new_name = ElixirScript.Translator.LexicalScope.get_var(env, param.name) - - { %{ param | name: new_name }, env } - - (param, env) -> - { param, env } - end) - - { patterns, params, env } - end - - def build_match(params, env) do - Enum.map(params, &do_build_match(&1, env)) - |> reduce_patterns - end - - defp do_build_match({:^, _, [value]}, env) do - { [bound(Translator.translate!(value, env))], [nil] } - end - - defp do_build_match({:_, _, _}, _) do - { [parameter()], [JS.identifier(:__ignored__)] } - end - - defp do_build_match({:<<>>, _, elements}, env) do - params = Enum.reduce(elements, [], fn - ({:::, _, [{ variable, _, params }, _]}, state) when is_atom(params) -> - state ++ [JS.identifier(variable)] - _, state -> - state - end) - - elements = Enum.map(elements, fn - ({:::, context, [{ _, _, params }, options]}) when is_atom(params) -> - Bitstring.make_bitstring_element({:::, context, [ElixirScript.Translator.PatternMatching, options]}, env) - x -> - Bitstring.make_bitstring_element(x, env) - end) - - { [bitstring_match(elements)], params } - end - - defp do_build_match([{:|, _, [head, tail]}], env) do - { head_patterns, head_params } = do_build_match(head, env) - { tail_patterns, tail_params } = do_build_match(tail, env) - params = head_params ++ tail_params - - { [head_tail(hd(head_patterns), hd(tail_patterns))], params } - end - - defp do_build_match({:<>, _, [prefix, value]}, env) do - { [starts_with(prefix)], [Translator.translate!(value, env)] } - end - - defp do_build_match({:%{}, _, props}, env) do - properties = Enum.map(props, fn({key, value}) -> - {pattern, params} = do_build_match(value, env) - property = case key do - {:^, _, [the_key]} -> - JS.property(Translator.translate!(the_key, env), hd(List.wrap(pattern)), :init, false, false, true) - _ -> - Map.make_property(Translator.translate!(key, env), hd(List.wrap(pattern))) - end - - { property, params } - end) - - {props, params} = Enum.reduce(properties, {[], []}, fn({prop, param}, {props, params}) -> - { props ++ [prop], params ++ param } - end) - - { JS.object_expression(List.wrap(props)), params } - end - - defp do_build_match({:%, _, [{:__aliases__, _, name}, {:%{}, meta, props}]}, env) do - module_name = ElixirScript.Translator.State.get_module_name(env.state, Utils.quoted_to_name(name)) - name = Utils.name_to_js_file_name(module_name) - {pattern, params} = do_build_match({:%{}, meta, [__struct__: String.to_atom(name)] ++ props}, env) - - { pattern, params } - end - - defp do_build_match({:=, _, [{name, _, _}, right]}, env) when not name in [:%, :{}, :__aliases__, :^, :%{}] do - unify(name, right, env) - end - - defp do_build_match({:=, _, [left, {name, _, _}]}, env) when not name in [:%, :{}, :__aliases__, :^, :%{}] do - unify(name, left, env) - end - - defp do_build_match(list, env) when is_list(list) do - { patterns, params } = list - |> Enum.map(&build_match([&1], env)) - |> reduce_patterns - - {[Primitive.make_list_no_translate(patterns)], params} - end - - defp do_build_match(term, env) when is_number(term) or is_binary(term) or is_boolean(term) or is_atom(term) or is_nil(term) do - { [Translator.translate!(term, env)], [] } - end - - defp do_build_match({ one, two }, env) do - do_build_match({:{}, [], [one, two]}, env) - end - - defp do_build_match({:{}, _, list}, env) do - { patterns, params } = list - |> Enum.map(&build_match([&1], env)) - |> reduce_patterns - - tuple_pattern = JS.new_expression( - Primitive.tuple_class(), - patterns - ) - - { [tuple_pattern], params } - end - - defp do_build_match({:\\, _, [{name, _, _}, default]}, env) do - { [parameter(Translator.translate!(default, env))], [Identifier.make_identifier(name)] } - end - - - defp do_build_match({name, _, _}, _) do - { [parameter()], [Identifier.make_identifier(name)] } - end - - defp reduce_patterns(patterns) do - patterns - |> Enum.reduce({ [], [] }, fn({ pattern, new_param }, { patterns, new_params }) -> - { patterns ++ List.wrap(pattern), new_params ++ List.wrap(new_param) } - end) - end - - defp unify(target, source, env) do - { patterns, params } = build_match([source], env) - { [capture(hd(patterns))], params ++ [Identifier.make_identifier(target)] } - end - -end diff --git a/lib/elixir_script/translator/rewriter.ex b/lib/elixir_script/translator/rewriter.ex deleted file mode 100644 index cd018686..00000000 --- a/lib/elixir_script/translator/rewriter.ex +++ /dev/null @@ -1,495 +0,0 @@ -defmodule ElixirScript.Translator.Rewriter do - @moduledoc false - - # :erlang, :lists, :maps, :beam_lib, :binary, :calendar, :digraph, - # :epp, :erl_lint, :erl_internal, :erl_expand_records, :erl_eval, - # :ets, :filename, :gen_event, :gen_server, :io, :io_lib, :math, - # :ordsets, :proc_lib, :rand, :re, :sets, :supervisor,:sys, :timer, - # :unicode, :os, :application, :code, :gen_tcp, :error_logger, :gen, - # :file - # http://erlang.org/doc/applications.html - - - def rewrite({{:., _, [:erlang, :abs]}, _, [number]}) do - quote do: Math.abs(unquote(number)) - end - - def rewrite({{:., _, [:erlang, :apply]}, _, [fun, args]}) do - quote do: unquote(fun).apply(nil, unquote(args)) - end - - def rewrite({{:., _, [:erlang, :apply]}, _, [module, fun, args]}) do - quote do: unquote(module).unquote(fun).apply(nil, unquote(args)) - end - - def rewrite({{:., _, [:erlang, :binary_part]}, _, [binary, start, length]})do - quote do: unquote(binary).substring(unquote(start), unquote(length)) - end - - def rewrite({{:., _, [:erlang, :bit_size]}, _, [bitstring]})do - quote do: unquote(bitstring).bit_size - end - - def rewrite({{:., _, [:erlang, :byte_size]}, _, [bitstring]})do - quote do: unquote(bitstring).byte_size - end - - def rewrite({{:., _, [:erlang, :div]}, _, [left, right]}) do - quote do: unquote(left) / unquote(right) - end - - def rewrite({{:., _, [:erlang, :exit]}, _, [reason]}) do - # TODO: implement exit - quote do: nil - end - - def rewrite({{:., _, [:erlang, :hd]}, _, [list]}) do - quote do: unquote(list)[0] - end - - def rewrite({{:., _, [:erlang, :is_atom]}, _, [term]}) do - quote do: JS.typeof(unquote(term)) === "symbol" - end - - def rewrite({{:., _, [:erlang, :is_binary]}, _, [term]}) do - quote do: JS.typeof(unquote(term)) === "string" - end - - def rewrite({{:., _, [:erlang, :is_bitstring]}, _, [term]}) do - quote do: is_binary(unquote(term)) || JS.instanceof(unquote(term), Bootstrap.Core.BitString) - end - - def rewrite({{:., _, [:erlang, :is_boolean]}, _, [term]}) do - quote do: JS.typeof(unquote(term)) === "boolean" || JS.instanceof(unquote(term), Boolean) - end - - def rewrite({{:., _, [:erlang, :is_float]}, _, [term]}) do - quote do: (JS.typeof(unquote(term)) === "number" || JS.instanceof(unquote(term), Number)) && !Number.isInteger(unquote(term)) - end - - def rewrite({{:., _, [:erlang, :is_function]}, _, [term]}) do - quote do: JS.typeof(unquote(term)) === "function" || JS.instanceof(unquote(term), Function) - end - - def rewrite({{:., _, [:erlang, :is_function]}, _, [term, _]}) do - quote do: JS.typeof(unquote(term)) === "function" || JS.instanceof(unquote(term), Function) - end - - def rewrite({{:., _, [:erlang, :is_integer]}, _, [term]}) do - quote do: Number.isInteger(unquote(term)) - end - - def rewrite({{:., _, [:erlang, :is_list]}, _, [term]}) do - quote do: Array.isArray(unquote(term)) - end - - def rewrite({{:., _, [:erlang, :is_number]}, _, [term]}) do - quote do: JS.typeof(unquote(term)) === "number" || JS.instanceof(unquote(term), Number) - end - - def rewrite({{:., _, [:erlang, :is_pid]}, _, [term]}) do - quote do: JS.instanceof(unquote(term), Bootstrap.Core.PID) - end - - def rewrite({{:., _, [:erlang, :is_port]}, _, [_term]}) do - #TODO implement is_port - quote do: false - end - - def rewrite({{:., _, [:erlang, :is_reference]}, _, [_term]}) do - #TODO implement is_reference - quote do: false - end - - def rewrite({{:., _, [:erlang, :is_tuple]}, _, [term]}) do - quote do: JS.instanceof(unquote(term), Bootstrap.Core.Tuple) - end - - def rewrite({{:., _, [:erlang, :is_map]}, _, [term]}) do - quote do: JS.typeof(unquote(term)) === "object" || JS.instanceof(unquote(term), Object) - end - - def rewrite({{:., _, [:erlang, :length]}, _, [list]}) do - quote do: unquote(list).length - end - - def rewrite({{:., _, [:erlang, :make_ref]}, _, []}) do - #TODO: implement make_ref - quote do: nil - end - - def rewrite({{:., _, [:erlang, :map_size]}, _, [map]}) do - quote do: Object.keys(unquote(map)).length - end - - def rewrite({{:., _, [:erlang, :max]}, _, [first, second]}) do - quote do: Math.max(unquote(first), unquote(second)) - end - - def rewrite({{:., _, [:erlang, :min]}, _, [first, second]}) do - quote do: Math.min(unquote(first), unquote(second)) - end - - def rewrite({{:., _, [:erlang, :node]}, _, []}) do - quote do: :nonode@nohost - end - - def rewrite({{:., _, [:erlang, :node]}, _, [_]}) do - quote do: :nonode@nohost - end - - def rewrite({{:., _, [:erlang, :rem]}, _, [first, second]}) do - {:%, [], [first, second]} - end - - def rewrite({{:., _, [:erlang, :round]}, _, [number]}) do - quote do: Math.round(unquote(number)) - end - - def rewrite({{:., _, [:erlang, :send]}, _, [dest, msg]}) do - #TODO implement send - quote do: unquote(msg) - end - - def rewrite({{:., _, [:erlang, :self]}, _, []}) do - #TODO: implement self - quote do: nil - end - - def rewrite({{:., _, [:erlang, :spawn]}, _, [_fun]}) do - #TODO: implement spawn - quote do: nil - end - - def rewrite({{:., _, [:erlang, :spawn]}, _, [_module, _fun, _args]}) do - #TODO: implement spawn - quote do: nil - end - - def rewrite({{:., _, [:erlang, :spawn_link]}, _, [_fun]}) do - #TODO: implement spawn_link - quote do: nil - end - - def rewrite({{:., _, [:erlang, :spawn_link]}, _, [_module, _fun, _args]}) do - #TODO: implement spawn_link - quote do: nil - end - - def rewrite({{:., _, [:erlang, :spawn_monitor]}, _, [_fun]}) do - #TODO: implement spawn_monitor - quote do: nil - end - - def rewrite({{:., _, [:erlang, :spawn_monitor]}, _, [_module, _fun, _args]}) do - #TODO: implement spawn_monitor - quote do: nil - end - - def rewrite({{:., _, [:erlang, :throw]}, _, [term]}) do - quote do: JS.throw(unquote(term)) - end - - def rewrite({{:., _, [:erlang, :tl]}, _, [list]}) do - quote do: unquote(list).splice(1) - end - - def rewrite({{:., _, [:erlang, :trunc]}, _, [number]}) do - quote do: Math.floor(unquote(number)) - end - - def rewrite({{:., _, [:erlang, :tuple_size]}, _, [tuple]}) do - quote do: unquote(tuple).length - end - - def rewrite({{:., _, [:erlang, operator]}, _, [left, right]}) when operator in [:+, :-, :*, :/, :<, :>, :>=, :==] do - {operator, [], [left, right]} - end - - def rewrite({{:., _, [:erlang, operator]}, _, [value]}) when operator in [:+, :-] do - {operator, [], [value]} - end - - def rewrite({{:., _, [:erlang, :++]}, _, [left, right]}) do - quote do: unquote(left).concat(unquote(right)) - end - - def rewrite({{:., _, [:erlang, :--]}, _, [list, element]}) do - quote do: unquote(list).slice(unquote(list).indexOf(unquote(element)) + 1) - end - - def rewrite({{:., _, [:erlang, :not]}, _, [value]}) do - {:!, [], [value]} - end - - def rewrite({{:., _, [:erlang, :"=<"]}, _, [left, right]}) do - {:<=, [], [left, right]} - end - - def rewrite({{:., _, [:erlang, :"/="]}, _, [left, right]}) do - {:!=, [], [left, right]} - end - - def rewrite({{:., _, [:erlang, :"=:="]}, _, [left, right]}) do - {:===, [], [left, right]} - end - - def rewrite({{:., _, [:erlang, :"=/="]}, _, [left, right]}) do - {:!==, [], [left, right]} - end - - def rewrite({{:., _, [:erlang, :element]}, _, [index, tuple]}) do - quote do: unquote(tuple).get(unquote(index) - 1) - end - - def rewrite({{:., _, [:erlang, :setelement]}, _, [index, tuple, value]}) do - quote do: unquote(tuple).put_elem(unquote(index) - 1, unquote(value)) - end - - def rewrite({{:., _, [:erlang, :orelse]}, _, [left, right]}) do - {:||, [], [left, right]} - end - - def rewrite({{:., _, [:erlang, :or]}, _, [left, right]}) do - {:||, [], [left, right]} - end - - def rewrite({{:., _, [:erlang, :andalso]}, _, [left, right]}) do - {:&&, [], [left, right]} - end - - def rewrite({{:., _, [:erlang, :error]}, _, [error]}) do - quote do: JS.throw(unquote(error)) - end - - def rewrite({{:., _, [:erlang, :raise]}, _, [_class, reason, _stacktrace]}) do - quote do: JS.throw(unquote(reason)) - end - - def rewrite({{:., _, [:erlang, :atom_to_binary]}, _, [atom, _]}) do - quote do: Symbol.keyFor(unquote(atom)) - end - - def rewrite({{:., _, [:erlang, :atom_to_list]}, _, [atom]}) do - quote do: to_string(unquote(atom)).split("") - end - - def rewrite({{:., _, [:erlang, :bnot]}, _, [expr]}) do - {:"~", [], [expr]} - end - - def rewrite({{:., _, [:erlang, :band]}, _, [left, right]}) do - {:&, [], [left, right]} - end - - def rewrite({{:., _, [:erlang, :bor]}, _, [left, right]}) do - {:|, [], [left, right]} - end - - def rewrite({{:., _, [:erlang, :bxor]}, _, [left, right]}) do - {:^, [], [left, right]} - end - - def rewrite({{:., _, [:erlang, :bsl]}, _, [left, right]}) do - {:"<<", [], [left, right]} - end - - def rewrite({{:., _, [:erlang, :bsr]}, _, [left, right]}) do - {:">>", [], [left, right]} - end - - def rewrite({{:., _, [:erlang, :function_exported]}, _, [_, _, _]}) do - quote do: true - end - - def rewrite({{:., _, [:erlang, :make_tuple]}, _, [size, data]}) do - quote do: JS.new(Bootstrap.Core.Tuple, List.duplicate(unquote(size), unquote(data))) - end - - def rewrite({{:., _, [:erlang, :insert_element]}, _, [index, tuple, term]}) do - quote do: unquote(tuple).put_elem(unquote(index) - 1, unquote(term)) - end - - def rewrite({{:., _, [:erlang, :tuple_to_list]}, _, [tuple]}) do - quote do: unquote(tuple).values - end - - def rewrite({{:., _, [:erlang, :append_element]}, _, [tuple, value]}) do - quote do: unquote(tuple).put_elem(unquote(tuple).length, unquote(value)) - end - - def rewrite({{:., _, [:erlang, :delete_element]}, _, [index, tuple]}) do - quote do: unquote(tuple).remove_elem(unquote(index)) - end - - def rewrite({{:., _, [:lists, :map]}, _, [fun, list]}) do - quote do: unquote(list).map(unquote(fun)) - end - - def rewrite({{:., _, [:lists, :member]}, _, [elem, list]}) do - quote do: unquote(list).indexOf(unquote(elem)) > -1 - end - - def rewrite({{:., _, [:lists, :foldl]}, _, [fun, acc, list]}) do - quote do: List.foldl(unquote(fun), unquote(acc), unquote(list)) - end - - def rewrite({{:., _, [:lists, :foldr]}, _, [fun, acc, list]}) do - quote do: List.foldr(unquote(fun), unquote(acc), unquote(list)) - end - - def rewrite({{:., _, [:lists, :keymember]}, _, [key, n, list]}) do - quote do: List.keymember?(unquote(list), unquote(key), unquote(n)) - end - - def rewrite({{:., _, [:lists, :keydelete]}, _, [key, n, list]}) do - quote do: List.keydelete(unquote(list), unquote(key), unquote(n)) - end - - def rewrite({{:., _, [:lists, :keyfind]}, _, [key, n, list]}) do - quote do: List.keyfind(unquote(list), unquote(key), unquote(n)) - end - - def rewrite({{:., _, [:lists, :keyreplace]}, _, [key, n, list, newtuple]}) do - quote do: List.keyreplace(unquote(list), unquote(key), unquote(n), unquote(newtuple)) - end - - def rewrite({{:., _, [:lists, :keysort]}, _, [n, tuplelist]}) do - #TODO: implement keysort - quote do: unquote(tuplelist) - end - - def rewrite({{:., _, [:lists, :reverse]}, _, [list]}) do - quote do: ElixirScript.Bootstrap.Functions.reverse(unquote(list)) - end - - def rewrite({{:., _, [:lists, :reverse]}, _, [list, tail]}) do - quote do: ElixirScript.Bootstrap.Functions.reverse(unquote(list)) ++ unquote(tail) - end - - def rewrite({{:., _, [:lists, :flatten]}, _, [list]}) do - quote do: List.flatten(unquote(list)) - end - - def rewrite({{:., _, [:lists, :flatten]}, _, [list, tail]}) do - quote do: List.flatten(unquote(list), unquote(tail)) - end - - def rewrite({{:., _, [:lists, :delete]}, _, [elem, list]}) do - quote do: List.delete(unquote(list), unquote(elem)) - end - - def rewrite({{:., _, [:lists, :duplicate]}, _, [n, elem]}) do - quote do: List.duplicate(unquote(n), unquote(elem)) - end - - def rewrite({{:., _, [:lists, :sort]}, _, [list]}) do - quote do: unquote(list).sort() - end - - #TODO: Implement sort - def rewrite({{:., _, [:lists, :sort]}, _, [_fun, list]}) do - quote do: unquote(list) - end - - def rewrite({{:., _, [:lists, :filter]}, _, [pred, list]}) do - quote do: unquote(list).filter(unquote(pred)) - end - - def rewrite({{:., _, [:lists, :concat]}, _, [things]}) do - quote do: unquote(things).join("") - end - - def rewrite({{:., _, [:erlang, :binary_to_atom]}, _, [binary, _]}) do - quote do: Symbol.for(unquote(binary)) - end - - def rewrite({{:., _, [:erlang, :binary_to_existing_atom]}, _, [binary, _]}) do - quote do: Symbol.for(unquote(binary)) - end - - def rewrite({{:., _, [:erlang, :list_to_atom]}, _, [char_list]}) do - quote do: Symbol.for(unquote(char_list)) - end - - def rewrite({{:., _, [:erlang, :list_to_existing_atom]}, _, [char_list]}) do - quote do: Symbol.for(unquote(char_list)) - end - - def rewrite({{:., _, [:erlang, :list_to_tuple]}, _, [list]}) do - quote do: JS.new(Bootstrap.Core.Tuple, unquote(list)) - end - - def rewrite({{:., _, [:erlang, :list_to_float]}, _, [list]}) do - quote do: JS.parseFloat(unquote(list)) - end - - def rewrite({{:., _, [:erlang, :list_to_integer]}, _, [list]}) do - quote do: JS.parseInt(unquote(list)) - end - - def rewrite({{:., _, [:erlang, :list_to_integer]}, _, [list, base]}) do - quote do: JS.parseInt(unquote(list), unquote(base)) - end - - def rewrite({{:., _, [:erlang, :integer_to_binary]}, _, [integer]}) do - quote do: unquote(integer).toString() - end - - def rewrite({{:., _, [:erlang, :integer_to_binary]}, _, [integer, base]}) do - quote do: unquote(integer).toString(unquote(base)) - end - - def rewrite({{:., _, [:erlang, :integer_to_list]}, _, [integer]}) do - quote do: unquote(integer).toString() - end - - def rewrite({{:., _, [:erlang, :integer_to_list]}, _, [integer, base]}) do - quote do: unquote(integer).toString(unquote(base)) - end - - def rewrite({{:., _, [:erlang, :float_to_binary]}, _, [float]}) do - quote do: unquote(float).toString() - end - - def rewrite({{:., _, [:erlang, :float_to_binary]}, _, [float, base]}) do - quote do: unquote(float).toString(unquote(base)) - end - - def rewrite({{:., _, [:erlang, :float_to_list]}, _, [float]}) do - quote do: unquote(float).toString() - end - - def rewrite({{:., _, [:erlang, :float_to_list]}, _, [float, base]}) do - quote do: unquote(float).toString(unquote(base)) - end - - def rewrite({{:., _, [:erlang, :binary_to_float]}, _, [binary]}) do - quote do: JS.parseFloat(unquote(binary)) - end - - def rewrite({{:., _, [:erlang, :binary_to_integer]}, _, [binary]}) do - quote do: JS.parseInt(unquote(binary)) - end - - def rewrite({{:., _, [:erlang, :binary_to_integer]}, _, [binary, base]}) do - quote do: JS.parseInt(unquote(binary), unquote(base)) - end - - def rewrite({{:., _, [:maps, :is_key]}, _, [key, map]}) do - quote do: unquote(key) in ElixirScript.Bootstrap.Functions.get_object_keys(unquote(map)) - end - - def rewrite({{:., _, [:maps, :put]}, _, [key, value, map]}) do - quote do: ElixirScript.Bootstrap.Functions.add_property_to_map(unquote(map), unquote(key), unquote(value)) - end - - def rewrite({{:., _, [:maps, :update]}, _, [key, value, map]}) do - quote do: Map.update!(unquote(map), unquote(key), fn(_) -> unquote(value) end) - end - - def rewrite({{:., _, [:maps, :remove]}, _, [key, map]}) do - quote do: ElixirScript.Bootstrap.Functions.delete_property_from_map(unquote(map), unquote(key)) - end - -end diff --git a/lib/elixir_script/translator/state.ex b/lib/elixir_script/translator/state.ex deleted file mode 100644 index a7f27da3..00000000 --- a/lib/elixir_script/translator/state.ex +++ /dev/null @@ -1,143 +0,0 @@ -# This agent holds references to the compiler options, a map all of the modules, and -# a map of modules that define the standard library. -# -# The modules map has the module's name a the key and a ElixirScript.Module struct as the value. -# -# The std_lib_map holds a mapping of the Elixir standard lib module to the -# version implemented here in ElixirScript. -defmodule ElixirScript.Translator.State do - @moduledoc false - alias ElixirScript.Translator.Utils - - def start_link(compiler_opts, loaded_modules) do - Agent.start_link(fn -> - %{ - compiler_opts: compiler_opts, - modules: Keyword.new, - std_lib_map: build_standard_lib_map(), - loaded_modules: [JS | loaded_modules], - module_references: Keyword.new() - } - end) - end - - defp build_standard_lib_map() do - Application.spec(:elixir, :modules) - |> Enum.reduce(Map.new, fn(x, acc) -> - try do - elixirscript_module = (["ElixirScript"] ++ Module.split(x)) |> Module.concat() - Map.put(acc, x, elixirscript_module) - rescue - FunctionClauseError -> - acc - ArgumentError -> - acc - end - end) - end - - def set_module_data(pid, module_data) do - Agent.update(pid, fn state -> - %{ state | modules: Keyword.merge(state.modules, module_data) } - end) - end - - def get_module_data(pid) do - Agent.get(pid, fn state -> - state.modules - end) - end - - def set_loaded_modules(pid, modules) do - Agent.update(pid, fn state -> - %{ state | loaded_modules: [ JS | modules ] } - end) - end - - def get(pid) do - Agent.get(pid, &(&1)) - end - - def get_module_name(pid, {:__aliases__, _, _} = name) do - get_module_name(pid, Utils.quoted_to_name(name)) - end - - def get_module_name(pid, module_name) do - Agent.get(pid, fn(state) -> - do_get_module_name(module_name, state) - end) - end - - defp do_get_module_name(module_name, state) do - std_lib_map = state.std_lib_map - case Map.get(std_lib_map, module_name) do - nil -> - module_name - actual_module_name -> - actual_module_name - end - end - - def is_module_loaded?(pid, module) when is_atom(module) do - Agent.get(pid, fn(state) -> - (module in state.loaded_modules) - end) - end - - def is_module_loaded?(pid, {:__aliases__, _, _} = module) do - - is_module_loaded?(pid, Utils.quoted_to_name(module)) - end - - def get_module(pid, module) when is_atom(module) do - do_get_module(pid, module) - end - - def get_module(pid, {:__aliases__, _, _} = name) do - do_get_module(pid, Utils.quoted_to_name(name)) - end - - def get_module(pid, module_name_list) when is_list(module_name_list) do - do_get_module(pid, Utils.quoted_to_name({:__aliases__, [], module_name_list})) - end - - defp do_get_module(pid, name) do - Agent.get(pid, fn(state) -> - Keyword.get(state.modules, do_get_module_name(name, state)) - end) - end - - def add_module_reference(pid, module_name, module_ref) do - Agent.update(pid, fn(state) -> - case Keyword.get(state.modules, do_get_module_name(module_ref, state)) do - nil -> - state - module -> - module_references = Keyword.update(state.module_references, module.name, [module_name], fn(x) -> Enum.uniq(x ++ [module_name]) end) - %{ state | module_references: module_references } - end - end) - end - - def list_module_references(pid) do - Agent.get(pid, fn(state) -> - state.module_references - end) - end - - def list_modules(pid) do - Agent.get(pid, fn(state) -> - Keyword.values(state.modules) - end) - end - - def list_module_names(pid) do - Agent.get(pid, fn(state) -> - Keyword.keys(state.modules) - end) - end - - def stop(pid) do - Agent.stop(pid) - end -end diff --git a/lib/elixir_script/translator/unsupported_error.ex b/lib/elixir_script/translator/unsupported_error.ex deleted file mode 100644 index 34bb1b6d..00000000 --- a/lib/elixir_script/translator/unsupported_error.ex +++ /dev/null @@ -1,8 +0,0 @@ -defmodule ElixirScript.Translator.UnsupportedError do - defexception [:message] - - def exception(value) do - msg = "Currently unsupported #{inspect value}" - %ElixirScript.Translator.UnsupportedError{message: msg} - end -end diff --git a/lib/elixir_script/translator/utils.ex b/lib/elixir_script/translator/utils.ex deleted file mode 100644 index e0611980..00000000 --- a/lib/elixir_script/translator/utils.ex +++ /dev/null @@ -1,65 +0,0 @@ -defmodule ElixirScript.Translator.Utils do - @moduledoc false - - def quoted_to_name(the_alias) do - {name, _} = Code.eval_quoted(the_alias) - name - end - - def name_to_quoted(name) when is_list(name) do - { :__aliases__, [], name } - end - - def name_to_quoted(name) do - name = name - |> Module.split - |> Enum.map(fn x -> String.to_atom(x) end) - - { :__aliases__, [], name } - end - - def name_to_js_name(name) do - { :__aliases__, _, name } = name_to_quoted(name) - Enum.join([:Elixir] ++ name, "$") - end - - def name_to_js_file_name(name) do - { :__aliases__, _, name } = name_to_quoted(name) - Enum.join([:Elixir] ++ name, ".") - end - - def make_local_file_path(module_app_name, file_name, env) do - root = ElixirScript.Translator.State.get(env.state).compiler_opts.root - app_name = if is_binary(module_app_name), do: module_app_name, else: to_string(module_app_name) - - case root do - nil -> - Path.join(["..", app_name, file_name]) - root -> - Path.join([root, app_name, file_name]) - end - end - - def make_local_file_path(file_name, env) do - root = ElixirScript.Translator.State.get(env.state).compiler_opts.root - - case root do - nil -> - Path.join([".", file_name]) - root -> - Path.join([root, file_name]) - end - end - - def make_local_file_path(module_app_name, file_name, root, _) do - app_name = to_string(module_app_name) - - case root do - nil -> - Path.join(["..", app_name, file_name]) - root -> - Path.join([root, app_name, file_name]) - end - end - -end diff --git a/lib/mix/tasks/compile.elixir_script.ex b/lib/mix/tasks/compile.elixir_script.ex index 0abf7e9c..a7926b79 100644 --- a/lib/mix/tasks/compile.elixir_script.ex +++ b/lib/mix/tasks/compile.elixir_script.ex @@ -49,7 +49,7 @@ defmodule Mix.Tasks.Compile.ElixirScript do defp do_compile(elixirscript_base, app) do {input, opts} = get_compiler_params() - ElixirScript.compiler.compile(input, opts) + ElixirScript.Compiler.compile(input, opts) end def clean do diff --git a/priv/std_lib/agent.ex b/priv/std_lib/agent.ex deleted file mode 100644 index 6b2559de..00000000 --- a/priv/std_lib/agent.ex +++ /dev/null @@ -1,54 +0,0 @@ -defmodule ElixirScript.Agent do - @moduledoc false - require JS - - def start(fun, options \\ []) do - pid = JS.new Bootstrap.Core.PID, [] - - name = if Elixir.Keyword.has_key?(options, :name) do - Elixir.Keyword.get(options, :name) - else - nil - end - - ElixirScript.Store.create(pid, fun.(), name) - { :ok, pid } - end - - def start_link(fun, options \\ []) do - pid = JS.new Bootstrap.Core.PID, [] - - name = if Elixir.Keyword.has_key?(options, :name) do - Elixir.Keyword.get(options, :name) - else - nil - end - - ElixirScript.Store.create(pid, fun.(), name) - { :ok, pid } - end - - def stop(agent) do - ElixirScript.Store.remove(agent) - :ok - end - - def update(agent, fun) do - current_state = ElixirScript.Store.read(agent) - ElixirScript.Store.update(agent, fun.(current_state)) - :ok - end - - def get(agent, fun) do - current_state = ElixirScript.Store.read(agent) - fun.(current_state) - end - - def get_and_update(agent, fun) do - current_state = ElixirScript.Store.read(agent) - {val, new_state} = fun.(current_state) - ElixirScript.Store.update(agent, new_state) - val - end - -end diff --git a/priv/std_lib/atom.ex b/priv/std_lib/atom.ex deleted file mode 100644 index 786ded55..00000000 --- a/priv/std_lib/atom.ex +++ /dev/null @@ -1,13 +0,0 @@ -defmodule ElixirScript.Atom do - @moduledoc false - import Kernel, except: [to_string: 1] - - def to_char_list(atom) do - to_string(atom).split("") - end - - def to_string(atom) do - JS.Symbol.keyFor(atom) - end - -end diff --git a/priv/std_lib/base.ex b/priv/std_lib/base.ex deleted file mode 100644 index 27fcdee9..00000000 --- a/priv/std_lib/base.ex +++ /dev/null @@ -1,30 +0,0 @@ -defmodule ElixirScript.Base do - @moduledoc false - - def encode64(data) do - ElixirScript.Bootstrap.Functions.b64EncodeUnicode(data) - end - - defp can_decode64(data) do - try do - JS.atob(data) - true - rescue - _ -> - false - end - end - - def decode64(data) do - if can_decode64(data) do - {:ok, decode64!(data) } - else - :error - end - end - - def decode64!(data) do - JS.atob(data) - end - -end diff --git a/priv/std_lib/bitwise.ex b/priv/std_lib/bitwise.ex deleted file mode 100644 index bc92799e..00000000 --- a/priv/std_lib/bitwise.ex +++ /dev/null @@ -1,74 +0,0 @@ -defmodule ElixirScript.Bitwise do - @moduledoc false - defmacro bnot(expr) do - quote do - JS.__bnot__(unquote(expr)) - end - end - - defmacro ~~~(expr) do - quote do - JS.__bnot__(unquote(expr)) - end - end - - defmacro band(left, right) do - quote do - JS.__band__(unquote(left), unquote(right)) - end - end - - defmacro left &&& right do - quote do - JS.__band__(unquote(left), unquote(right)) - end - end - - defmacro bor(left, right) do - quote do - JS.__bor__(unquote(left), unquote(right)) - end - end - - defmacro left ||| right do - quote do - JS.__bor__(unquote(left), unquote(right)) - end - end - - defmacro bxor(left, right) do - quote do - JS.__bxor__(unquote(left), unquote(right)) - end - end - - defmacro left ^^^ right do - quote do - JS.__bxor__(unquote(left), unquote(right)) - end - end - - defmacro bsl(left, right) do - quote do - JS.__bsl__(unquote(left), unquote(right)) - end - end - - defmacro left <<< right do - quote do - JS.__bsl__(unquote(left), unquote(right)) - end - end - - defmacro bsr(left, right) do - quote do - JS.__bsr__(unquote(left), unquote(right)) - end - end - - defmacro left >>> right do - quote do - JS.__bsr__(unquote(left), unquote(right)) - end - end -end diff --git a/priv/std_lib/bootstrap/functions.ex b/priv/std_lib/bootstrap/functions.ex deleted file mode 100644 index e8e0fe93..00000000 --- a/priv/std_lib/bootstrap/functions.ex +++ /dev/null @@ -1,70 +0,0 @@ -defmodule ElixirScript.Bootstrap.Functions do - - def contains(left, []) do - false - end - - def contains(left, [right]) do - case right do - ^left -> - true - _ -> - false - end - end - - def contains(left, [h|t]) do - case h do - ^left -> - true - _ -> - contains(left, t) - end - end - - def get_object_keys(obj) do - JS.Object.keys(obj).concat(JS.Object.getOwnPropertySymbols(obj)) - end - - def is_valid_character(codepoint) do - try do - JS.String.fromCodePoint(codepoint) != nil - rescue - _ -> - false - end - end - - def b64EncodeUnicode(str) do - regex = Regex.compile!("%([0-9A-F]{2})", "g") - - JS.btoa( - JS.encodeURIComponent(str).replace(regex, fn (match, p1, _, _) -> - JS.String.fromCharCode("0x#{p1}") - end) - ) - end - - def reverse(list) do - list.concat([]).reverse() - end - - def class_to_obj(map) do - JS.Object.assign(JS.new(JS.Object, []), map) - |> JS.Object.freeze - end - -def delete_property_from_map(map, property) do - new_map = JS.Object.assign(JS.Object.create(map.constructor.prototype), map) - JS.delete(new_map[property]) - - JS.Object.freeze(new_map) -end - -def add_property_to_map(map, property, value) do - JS.Object.assign(JS.new(JS.Object, []), map) - |> JS.update(property, value) - |> JS.Object.freeze -end - -end diff --git a/priv/std_lib/collectable.ex b/priv/std_lib/collectable.ex deleted file mode 100644 index 6950b962..00000000 --- a/priv/std_lib/collectable.ex +++ /dev/null @@ -1,34 +0,0 @@ -defprotocol ElixirScript.Collectable do - @moduledoc false - def into(collectable) -end - -defimpl ElixirScript.Collectable, for: List do - def into(original) do - {[], fn - list, {:cont, x} -> list ++ [x] - list, :done -> original ++ list - _, :halt -> :ok - end} - end -end - -defimpl ElixirScript.Collectable, for: BitString do - def into(original) do - {original, fn - acc, {:cont, x} when is_bitstring(x) -> <> - acc, :done -> acc - _, :halt -> :ok - end} - end -end - -defimpl ElixirScript.Collectable, for: Map do - def into(original) do - {original, fn - map, {:cont, {k, v}} -> Map.put(map, k, v) - map, :done -> map - _, :halt -> :ok - end} - end -end \ No newline at end of file diff --git a/priv/std_lib/enum.ex b/priv/std_lib/enum.ex deleted file mode 100644 index fded4e3f..00000000 --- a/priv/std_lib/enum.ex +++ /dev/null @@ -1,358 +0,0 @@ -defmodule ElixirScript.Enum do - - def all?(enumerable, fun \\ fn(x) -> x end) do - {_, acc} = Enumerable.reduce(enumerable, {:cont, true}, fn(item, _) -> - if fun.(item) do - {:cont, true} - else - {:halt, false} - end - end) - - acc - end - - def any?(enumerable, fun \\ fn(x) -> x end) do - {_, acc} = Enumerable.reduce(enumerable, {:cont, true}, fn(item, _) -> - if fun.(item) do - {:halt, true} - else - {:cont, false} - end - end) - - acc - end - - def at(enumerable, n, default \\ nil) do - index = if n < 0 do - {_, count} = Enumerable.count(enumerable) - count + n - else - n - end - - result = Enumerable.reduce(enumerable, {:cont, 0}, fn(item, acc) -> - if index == acc do - {:halt, item} - else - {:cont, acc + 1} - end - end) - - case result do - {:done, _} -> - default - {:halted, item} -> - item - end - end - - def concat([]) do - [] - end - - def concat([enumerable]) do - enumerable - end - - def concat([h, t]) do - h.concat(t) - end - - def concat([h | t]) do - h.concat(concat(t)) - end - - def concat(h, t) do - h.concat(t) - end - - def count(enumerable) do - {:ok, num} = Enumerable.count(enumerable) - num - end - - def count(enumerable, fun) do - {_, acc} = Enumerable.reduce(enumerable, {:cont, 0}, fn(item, acc) -> - if fun.(item) do - {:cont, acc + 1} - else - {:cont, acc} - end - end) - - acc - end - - def reduce(enumerable, fun) do - {_, result} = Enumerable.reduce(enumerable, {:cont, nil}, fn - item, nil -> - {:cont, {:acc, item}} - item, {:acc, acc} -> - {:cont, {:acc, fun.(item, acc)}} - end) - - result - end - - def reduce(enumerable, acc, fun) do - {_, result} = Enumerable.reduce(enumerable, {:cont, acc}, fn - item, acc -> - {:cont, fun.(item, acc)} - end) - - result - end - - - def map(enumerable, fun) do - reduce(enumerable, [], fn(x, acc) -> - acc ++ fun.(x) - end) - end - - def map_reduce(enumerable, acc, fun) do - reduce(enumerable, {[], acc}, fn(x, {m, acc}) -> - {v, new_acc} = fun.(x, acc) - {m ++ [v], new_acc} - end) - end - - def each(enumerable, fun) do - map(enumerable, fun) - :ok - end - - def empty?(enumerable) do - {:ok, count} = Enumerable.count(enumerable) - count == 0 - end - - def fetch(enumerable, index) do - index = if index < 0 do - {_, count} = Enumerable.count(enumerable) - count + index - else - index - end - - result = Enumerable.reduce(enumerable, {:cont, 0}, fn(item, acc) -> - if index == acc do - {:halt, {:ok, item}} - else - {:cont, acc + 1} - end - end) - - case result do - {:done, _} -> - :error - {:halted, item} -> - item - end - end - - def fetch!(enumerable, index) do - case fetch(enumerable, index) do - {:ok, item} -> - item - :error -> - raise Enum.OutOfBoundsError - end - end - - def filter(enumerable, fun) do - reduce(enumerable, [], fn(x, acc) -> - if fun.(x) do - acc ++ [x] - else - acc - end - end) - end - - def filter_map(enumerable, filter, mapper) do - reduce(enumerable, [], fn(x, acc) -> - if filter.(x) do - acc ++ [mapper.(x)] - else - acc - end - end) - end - - def find(enumerable, default \\ nil, fun) do - {_, result} = Enumerable.reduce(enumerable, {:cont, default}, fn(item, acc) -> - if fun.(item) do - {:halt, item} - else - {:cont, default} - end - end) - - result - end - - def into(enumerable, collectable) do - {init, fun} = Collectable.into(collectable) - reduce(enumerable, init, fn x, acc -> - fun.(acc, {:cont, x}) - end) - end - - def into(enumerable, collectable, transform) do - {init, fun} = Collectable.into(collectable) - reduce(enumerable, init, fn x, acc -> - fun.(acc, {:cont, transform.(x)}) - end) - end - - def member?(enumerable, value) do - {_, result} = Enumerable.reduce(enumerable, {:cont, false}, fn(item, acc) -> - if item == value do - {:halt, true} - else - {:cont, false} - end - end) - - result - end - - def drop(enumerable, count) when count < 0 do - enumerable - |> reverse - |> drop(abs(count)) - |> reverse - end - - def drop(enumerable, count) do - {_, {result, _}} = Enumerable.reduce(enumerable, {:cont, {[], 0}}, fn - (item, {taken, drop_count}) -> - if drop_count < count do - {:cont, {[], drop_count + 1 }} - else - {:cont, {taken ++ [item], drop_count}} - end - end) - - result - end - - def drop_every(enumerable, nth) do - {_, {result, _count}} = Enumerable.reduce(enumerable, {:cont, {[], 0}}, fn - (item, {taken, count}) -> - if rem(count, nth) == 0 do - {:cont, {taken, count + 1}} - else - {:cont, {taken ++ [item], count + 1}} - end - end) - - result - end - - def drop_while(enumerable, fun) do - {_, result} = Enumerable.reduce(enumerable, {:cont, :dropping}, fn - (item, :dropping) -> - if fun.(item) do - {:cont, :dropping} - else - {:cont, [item]} - end - - (item, taken) -> - {:cont, taken ++ [item]} - end) - - case result do - :dropping -> - [] - :done -> - [] - _ -> - result - end - end - - def empty?(enumerable) do - {:ok, count} = Enumerable.count(enumerable) - count == 0 - end - - def take(enumerable, count) do - if Enumerable.count(enumerable) < count do - enumerable - else - {_, result} = Enumerable.reduce(enumerable, {:cont, {[], 0}}, fn - (item, {taken, taken_count}) -> - if taken_count == count do - {:halt, taken} - else - {:cont, {taken ++ [item], taken_count + 1}} - end - end) - - result - end - end - - def take_every(enumerable, nth) do - {_, {result, _count}} = Enumerable.reduce(enumerable, {:cont, {[], 0}}, fn - (item, {taken, count}) -> - if rem(count, nth) == 0 do - {:cont, {taken ++ [item], count + 1}} - else - {:cont, {taken, count + 1}} - end - end) - - result - end - - def take_while(enumerable, fun) do - {_, result} = Enumerable.reduce(enumerable, {:cont, []}, fn - (item, taken) -> - if fun.(item) do - {:cont, {taken ++ [item]}} - else - {:halt, taken} - end - end) - - result - end - - - def to_list(enumerable) when is_list(enumerable) do - enumerable - end - - def to_list(enumerable) do - map(enumerable, fn x -> x end) - end - - def reverse(enumerable) when is_list(enumerable) do - enumerable.concat([]).reverse() - end - - def reverse(enumerable) do - reduce(enumerable, [], fn(item, acc) -> - [item] ++ acc - end) - end - - def reverse(enumerable, tail) when is_list(enumerable) do - enumerable.concat([]).reverse() ++ tail - end - - def reverse(enumerable, tail) do - result = reduce(enumerable, [], fn(item, acc) -> - [item] ++ acc - end) - - result ++ tail - end - -end \ No newline at end of file diff --git a/priv/std_lib/enum/out_of_bounds_error.ex b/priv/std_lib/enum/out_of_bounds_error.ex deleted file mode 100644 index e8ffb4b2..00000000 --- a/priv/std_lib/enum/out_of_bounds_error.ex +++ /dev/null @@ -1,3 +0,0 @@ -defmodule ElixirScript.Enum.OutOfBoundsError do - defexception message: "out of bounds error" -end \ No newline at end of file diff --git a/priv/std_lib/enumerable.ex b/priv/std_lib/enumerable.ex deleted file mode 100644 index b9ff8e7a..00000000 --- a/priv/std_lib/enumerable.ex +++ /dev/null @@ -1,38 +0,0 @@ -defprotocol ElixirScript.Enumerable do - @moduledoc false - def reduce(enumerable, acc, fun) - def member?(enumerable, element) - def count(enumerable) -end - -defimpl ElixirScript.Enumerable, for: List do - def count(list), - do: {:ok, list.length } - - def member?(list, value), - do: {:ok, value in list } - - def reduce(list, acc, fun) do - Bootstrap.Core.Functions.iterator_to_reducer(list, acc, fun) - end -end - -defimpl ElixirScript.Enumerable, for: Map do - def count(map) do - {:ok, map.length} - end - - def member?(map, {key, value}) do - {:ok, Map.get(map, key) == value } - end - - def member?(_, _) do - {:ok, false} - end - - def reduce(map, acc, fun) do - map - |> Map.to_list - |> Bootstrap.Core.Functions.iterator_to_reducer(acc, fun) - end -end diff --git a/priv/std_lib/exceptions.ex b/priv/std_lib/exceptions.ex deleted file mode 100644 index 4f723003..00000000 --- a/priv/std_lib/exceptions.ex +++ /dev/null @@ -1,7 +0,0 @@ -defmodule ElixirScript.ArgumentError do - defexception message: "argument error" -end - -defmodule ElixirScript.RuntimeError do - defexception message: "runtime error" -end \ No newline at end of file diff --git a/priv/std_lib/integer.ex b/priv/std_lib/integer.ex deleted file mode 100644 index 3a5bb41d..00000000 --- a/priv/std_lib/integer.ex +++ /dev/null @@ -1,29 +0,0 @@ -defmodule ElixirScript.Integer do - @moduledoc false - def is_even(number) do - rem(number, 2) == 0 - end - - def is_odd(number) do - rem(number, 2) != 0 - end - - def to_char_list(number, base \\ 10) do - number.toString(base).split('') - end - - def parse(bin, base \\ 10) do - result = JS.parseInt(bin, base) - - if JS.isNaN(result) do - :error - else - case bin.indexOf(".") do - index_of_dot when index_of_dot < 0 -> - {result, ""} - index_of_dot -> - {result, bin.substring(index_of_dot)} - end - end - end -end diff --git a/priv/std_lib/io.ex b/priv/std_lib/io.ex deleted file mode 100644 index 0444da1d..00000000 --- a/priv/std_lib/io.ex +++ /dev/null @@ -1,22 +0,0 @@ -defmodule ElixirScript.IO do - - def inspect(item, opts \\ []) do - JS.console.log(item) - item - end - - def puts(device \\ :stdio, item) when is_binary(item) do - case device do - :stdio -> - JS.console.log(item) - :stderr -> - JS.console.warn(item) - end - end - - def warn(message) when is_binary(message) do - JS.console.warn("warning: #{message}") - JS.console.trace() - end - -end diff --git a/priv/std_lib/js.ex b/priv/std_lib/js.ex deleted file mode 100644 index 3e3db5ac..00000000 --- a/priv/std_lib/js.ex +++ /dev/null @@ -1,108 +0,0 @@ -defmodule JS do - @moduledoc """ - This module defines macros and functions which implement - JavaScript functionality that may not translate easily to - Elixir. For instance, creating a new object, or updating - an existing one. - """ - - @doc """ - Creates new JavaScript objects. - - ex: - JS.new User, ["first_name", "last_name"] - """ - defmacro new(module, params) - - @doc """ - Updates an existing JavaScript object. - - ex: - JS.update elem, %{"width" => 100} - """ - defmacro update(object, map) - - @doc """ - Updates an existing JavaScript object. - - ex: - JS.update elem, "width", 100 - """ - defmacro update(object, key, value) - - @doc """ - Returns the type of the given value - """ - defmacro typeof(value) - - @doc """ - Determines if value is an instance of type. - """ - defmacro instanceof(value, type) - - @doc """ - Throws the term given - """ - defmacro throw(term) - - @doc """ - Returns a reference to the global JavaScript object. - - In browsers this would be window or self. - In node this would be the global object. - """ - def global() do - Bootstrap.Core.global() - end - - @doc """ - Defines a generator. This is compiled into a generator function in JavaScript. - defgen and defgenp are currently the only ways to use process in Elixirscript right now. - """ - defmacro defgen(call, expr \\ nil) do - quote do - def unquote(call), unquote(expr) - end - end - - @doc """ - Defines a private generator. This is compiled into a generator function in JavaScript. - """ - defmacro defgenp(call, expr \\ nil) do - quote do - defp unquote(call), unquote(expr) - end - end - - @doc """ - Determines if term is a generator - """ - def is_generator(term) do - term.constructor.name === "GeneratorFunction" - end - - @doc """ - Yields the current generator function - """ - defmacro yield() - - @doc """ - Yields the current generator function with the given term - """ - defmacro yield(term) - - @doc """ - Yields control to the given generator - """ - defmacro yield_to(gen) - - @doc """ - Creates a breakpoint for JavaScript debuggers to stop at - """ - defmacro debugger() - - @doc """ - The current JavaScript context - """ - defmacro this() -end diff --git a/priv/std_lib/kernel.ex b/priv/std_lib/kernel.ex deleted file mode 100644 index 83978563..00000000 --- a/priv/std_lib/kernel.ex +++ /dev/null @@ -1,209 +0,0 @@ -defmodule ElixirScript.Kernel do - @moduledoc false - import Kernel, only: [defmodule: 2, def: 1, def: 2, defp: 2, - defmacro: 1, defmacro: 2, defmacrop: 2, ||: 2, !: 1, - ++: 2, in: 2, &&: 2, ===: 2, @: 1, sigil_r: 2] - require JS - - - defmacro if(condition, clauses) do - build_if(condition, clauses) - end - - defp build_if(condition, do: do_clause) do - build_if(condition, do: do_clause, else: nil) - end - - defp build_if(condition, do: do_clause, else: else_clause) do - quote do - case unquote(condition) do - x when x in [false, nil] -> - unquote(else_clause) - _ -> - unquote(do_clause) - end - end - end - - defmacro unless(condition, clauses) do - build_unless(condition, clauses) - end - - defp build_unless(condition, do: do_clause) do - build_unless(condition, do: do_clause, else: nil) - end - - defp build_unless(condition, do: do_clause, else: else_clause) do - quote do - if(unquote(condition), do: unquote(else_clause), else: unquote(do_clause)) - end - end - - def abs(number) do - JS.Math.abs(number) - end - - def apply(fun, args) do - fun.apply(fun, args) - end - - def apply(module, fun, args) do - module[Atom.to_string(fun)].apply(module[Atom.to_string(fun)], args) - end - - def binary_part(binary, start, len) do - binary.substring(start, len) - end - - def hd(list) do - list[0] - end - - def tl(list) do - list.slice(1) - end - - def is_atom(term) do - JS.typeof(term) === "symbol" - end - - def is_binary(term) do - JS.typeof(term) === "string" - end - - def is_bitstring(term) do - is_binary(term) || JS.instanceof(term, Bootstrap.Core.BitString) - end - - def is_boolean(term) do - JS.typeof(term) === "boolean" || JS.instanceof(term, Boolean) - end - - def is_float(term) do - is_number(term) && !JS.Number.isInteger(term) - end - - def is_function(term) do - is_function(term, 0) - end - - def is_function(term, _) do - JS.typeof(term) === "function" || JS.instanceof(term, Function) - end - - def is_integer(term) do - JS.Number.isInteger(term) - end - - def is_list(term) do - JS.Array.isArray(term) - end - - def is_number(term) do - JS.typeof(term) === "number" || JS.instanceof(term, Number) - end - - def is_pid(term) do - JS.instanceof(term, Bootstrap.Core.PID) - end - - def is_tuple(term) do - JS.instanceof(term, Bootstrap.Core.Tuple) - end - - def is_map(term) do - JS.typeof(term) === "object" || JS.instanceof(term, Object) - end - - def is_port(_) do - false - end - - def is_reference(_) do - false - end - - def length(term) do - term.length - end - - def map_size(term) do - JS.Object.keys(term).length - end - - def max(first, second) do - JS.Math.max(first, second) - end - - def min(first, second) do - JS.Math.min(first, second) - end - - def round(number) do - JS.Math.round(number) - end - - def trunc(number) do - JS.Math.floor(number) - end - - def tuple_size(tuple) do - tuple.count() - end - - def elem(tuple, index) do - tuple.get(index) - end - - def is_nil(term) do - term === nil - end - - defmacro sigil_r({:<<>>, _meta, [string]}, options) do - str_options = List.to_string(options) - quote do - Regex.compile!(unquote(string), unquote(str_options)) - end - end - - defmacro match?(pattern, expr) do - quote do - case unquote(expr) do - unquote(pattern) -> - true - _ -> - false - end - end - end - - defmacro to_string(arg) when Kernel.is_binary(arg) do - arg - end - - defmacro to_string(arg) do - quote do - String.Chars.to_string(unquote(arg)) - end - end - - defmacro left |> {fun, context, params} do - {fun, context, [left] ++ params } - end - - defmacro left in right do - quote do - ElixirScript.Bootstrap.Functions.contains(unquote(left), unquote(right)) - end - end - - defmacro first .. last do - quote do - %ElixirScript.Range{ first: unquote(first), last: unquote(last) } - end - end - - def throw(term) do - JS.throw(term) - end -end diff --git a/priv/std_lib/keyword.ex b/priv/std_lib/keyword.ex deleted file mode 100644 index 2c91ec9f..00000000 --- a/priv/std_lib/keyword.ex +++ /dev/null @@ -1,46 +0,0 @@ -defmodule ElixirScript.Keyword do - @moduledoc false - - def new() do - [] - end - - def has_key?(kw, key) do - do_has_key?(kw, key) - end - - defp do_has_key?([], _) do - false - end - - defp do_has_key?(kw, key) do - case hd(kw) do - {the_key, _} when the_key == key -> - true - _ -> - do_has_key?(tl(kw), key) - end - end - - def get(kw, key) do - get(kw, key, nil) - end - - def get(kw, key, default_value) do - case has_key?(kw, key) do - true -> - do_get(kw, key) - false -> - default_value - end - end - - defp do_get(kw, key) do - case hd(kw) do - { kw_key, value } when kw_key == key -> - value - _ -> - do_get(tl(kw), key) - end - end -end diff --git a/priv/std_lib/list.ex b/priv/std_lib/list.ex deleted file mode 100644 index 156475f7..00000000 --- a/priv/std_lib/list.ex +++ /dev/null @@ -1,265 +0,0 @@ -defmodule ElixirScript.List do - @moduledoc false - require JS - - def duplicate(data, size) do - do_duplicate(data, size, []) - end - - defp do_duplicate(_, 0, list) do - list - end - - defp do_duplicate(data, size, list) do - do_duplicate(data, size - 1, list ++ [data]) - end - - def to_tuple(list) do - JS.new(Bootstrap.Core.Tuple, list) - end - - def wrap(list) when is_list(list), do: list - def wrap(nil), do: [] - def wrap(term), do: [term] - - def append(list, term) do - concat(list, [term]) - end - - def prepend(list, term) do - concat([term], list) - end - - def concat(list_a, list_b) do - list_a.concat(list_b) - end - - def first(list) do - list[0] - end - - def last(list) do - list[length(list) - 1] - end - - def delete(list, item) do - do_delete(list, item, 0, []) - end - - defp do_delete(list, item, current_index, new_list) do - if current_index == length(list) do - new_list - else - updated = case list[current_index] do - ^item -> - new_list - _ -> - new_list ++ [list[current_index]] - end - - do_delete(list, item, current_index + 1, updated) - end - end - - def delete_at(list, index) do - do_delete_at(list, index, 0, []) - end - - defp do_delete_at(list, index, current_index, new_list) do - if current_index == length(list) do - new_list - else - updated = case current_index == index do - true -> - new_list - _ -> - new_list ++ [list[current_index]] - end - - do_delete_at(list, index, current_index + 1, updated) - end - end - - def insert_at(list, index, value) do - do_insert_at(list, index, value, 0, []) - end - - defp do_insert_at(list, index, value, current_index, new_list) do - if current_index == length(list) do - new_list - else - updated = case current_index == index do - true -> - new_list ++ [value, list[current_index]] - _ -> - new_list ++ [list[current_index]] - end - - do_insert_at(list, index, value, current_index + 1, updated) - end - end - - def replace_at(list, index, value) do - do_replace_at(list, index, value, 0, []) - end - - defp do_replace_at(list, index, value, current_index, new_list) do - if current_index == length(list) do - new_list - else - updated = case current_index == index do - true -> - new_list ++ [value] - _ -> - new_list ++ [list[current_index]] - end - - do_replace_at(list, index, value, current_index + 1, updated) - end - end - - - def update_at(list, index, func) do - do_update_at(list, index, func, 0, []) - end - - defp do_update_at(list, index, func, current_index, new_list) do - if current_index == length(list) do - new_list - else - updated = case current_index == index do - true -> - new_list ++ [func.(list[current_index])] - _ -> - new_list ++ [list[current_index]] - end - - do_update_at(list, index, func, current_index + 1, updated) - end - end - - - def foldl(list, acc, func) do - do_foldl(list, acc, func, []) - end - - def foldr(list, acc, func) do - do_foldl(list.concat([]).reverse(), acc, func, []) - end - - defp do_foldl([], acc, _, new_list) do - { acc, new_list } - end - - defp do_foldl(list, acc, func, new_list) do - { acc, value } = func.(hd(list), acc) - do_foldl(tl(list), acc, func, new_list ++ [value]) - end - - def flatten(list, tail \\ []) do - do_flatten(list, []) ++ tail - end - - defp do_flatten([], flattened_list) do - flattened_list - end - - defp do_flatten(list, flattened_list) do - updated = case hd(list) do - l when is_list(l) -> - flattened_list ++ do_flatten(l, []) - item -> - flattened_list ++ [item] - end - - do_flatten(tl(list), updated) - end - - - def keydelete(list, key, position) do - do_keydelete(list, key, position, []) - end - - defp do_keydelete([], _, _, new_list) do - new_list - end - - defp do_keydelete(list, key, position, new_list) do - current_value = hd(list) - - updated = if elem(current_value, position) == key do - new_list - else - new_list ++ [current_value] - end - - do_keydelete(tl(list), key, position, updated) - end - - def keyfind(list, key, position) do - do_keyfind(list, key, position, nil) - end - - def keyfind(list, key, position, default) do - do_keyfind(list, key, position, default) - end - - defp do_keyfind([], _, _, default) do - default - end - - defp do_keyfind(list, key, position, default) do - current_value = hd(list) - - if elem(current_value, position) == key do - current_value - else - do_keyfind(tl(list), key, position, default) - end - end - - def keymember?(list, key, position) do - keyfind(list, key, position) != nil - end - - def keyreplace(list, key, position, new_tuple) do - do_keyreplace(list, key, position, [], new_tuple) - end - - defp do_keyreplace([], _, _, new_list, _) do - new_list - end - - defp do_keyreplace(list, key, position, new_list, new_tuple) do - current_value = hd(list) - - updated = if elem(current_value, position) == key do - new_list ++ [new_tuple] - else - new_list ++ [current_value] - end - - do_keyreplace(tl(list), key, position, updated, new_tuple) - end - - def zip([]) do - [] - end - - def zip(list_of_lists) when is_list(list_of_lists) do - lengths = Enum.map(list_of_lists, fn(list) -> length(list) end) - length = apply(JS.Math, :min, lengths) - do_zip(list_of_lists, 0, length, []) - end - - defp do_zip(list_of_lists, index, length, acc) when index == length do - acc - end - - defp do_zip(list_of_lists, index, length, acc) do - values = Enum.map(list_of_lists, fn(list) -> Enum.at(list, index) end) - item = JS.new(Bootstrap.Core.Tuple, values) - - do_zip(list_of_lists, index + 1, length, acc ++ [item]) - end -end diff --git a/priv/std_lib/macro/env.ex b/priv/std_lib/macro/env.ex deleted file mode 100644 index 1528e2c8..00000000 --- a/priv/std_lib/macro/env.ex +++ /dev/null @@ -1,37 +0,0 @@ -defmodule ElixirScript.Macro.Env do - @moduledoc false - - @type t :: %ElixirScript.Macro.Env{ - module: atom, - file: binary, - line: non_neg_integer, - function: { atom, non_neg_integer } | nil, - context: :match | :guard | :generator | nil, - aliases: [{atom, atom}], - requires: [atom], - functions: [{atom, [{ atom, non_neg_integer }]}], - macros: [{atom, [{ atom, non_neg_integer }]}], - macro_aliases: [{atom, {integer, atom}}], - context_modules: [atom], - vars: [{atom, atom | non_neg_integer}], - export_vars: [{atom, atom | non_neg_integer}] | nil, - lexical_tracker: nil - } - - defstruct [ - module: nil, - file: nil, - line: 0, - function: nil, - context: nil, - aliases: [], - requires: [], - functions: [], - macros: [], - macro_aliases: [], - context_modules: [], - vars: [], - export_vars: nil, - lexical_tracker: nil - ] -end diff --git a/priv/std_lib/map.ex b/priv/std_lib/map.ex deleted file mode 100644 index b8e48707..00000000 --- a/priv/std_lib/map.ex +++ /dev/null @@ -1,204 +0,0 @@ -defmodule ElixirScript.Map do - @moduledoc false - - def new() do - %{} - end - - def keys(map) do - ElixirScript.Bootstrap.Functions.get_object_keys(map) - end - - def size(map) do - keys(map).length - end - - def to_list(map) do - do_to_list(map, []) - end - - def do_to_list(map, list) do - case size(map) do - 0 -> - list - _ -> - key = hd(keys(map)) - value = map[key] - do_to_list(Map.delete(map, key), list ++ [{key, value}]) - end - end - - def values(map) do - JS.Object.values(map) - end - - def from_struct(struct) do - struct - |> ElixirScript.Bootstrap.Functions.class_to_obj - |> delete(:__struct__) - end - - def delete(map, key) do - map - |> ElixirScript.Bootstrap.Functions.delete_property_from_map(key) - end - - def equal?(map1, map2) do - map1 === map2 - end - - def fetch!(map, key) do - case key in keys(map) do - true -> - map[key] - false -> - raise "#{key} not found in map" - end - end - - def fetch(map, key) do - case key in keys(map) do - true -> - { :ok, map[key] } - false -> - :error - end - end - - def has_key?(map, key) do - key in keys(map) - end - - def merge(map1, map2) do - JS.Object.assign(%{}, map1, map2) - |> JS.Object.freeze() - end - - def split(map, keys) do - do_split(map, keys, { %{}, %{} }) - end - - defp do_split(_, [], split_tuple) do - split_tuple - end - - defp do_split(map, keys, { key_map, non_key_map }) do - key = hd(keys) - - new_split_tuple = case key in keys(map) do - true -> - { Map.put(key_map, key, map[key]), non_key_map } - false -> - { key_map, Map.put(non_key_map, key, map[key]) } - end - - do_split(map, tl(keys), new_split_tuple) - end - - def take(map, keys) do - {key_map, _} = split(map, keys) - key_map - end - - def drop(map, keys) do - {_, non_key_map} = split(map, keys) - non_key_map - end - - def put_new(map, key, value) do - case key in keys(map) do - true -> - map - false -> - Map.put(map, key, value) - end - end - - def put_new_lazy(map, key, func) do - case key in keys(map) do - true -> - map - false -> - Map.put(map, key, func.()) - end - end - - def put(map, key, value) do - ElixirScript.Bootstrap.Functions.add_property_to_map(map, key, value) - end - - def get(map, key) do - get(map, key, nil) - end - - def get(map, key, default_value) do - case key in keys(map) do - true -> - map[key] - false -> - default_value - end - end - - def get_lazy(map, key, func) do - case key in keys(map) do - true -> - func.(map[key]) - false -> - func.() - end - end - - def get_and_update(map, key, func) do - case key in keys(map) do - true -> - { nil, map } - false -> - new_value = func.(map[key]) - { new_value, Map.put(map, key, new_value) } - end - end - - def pop(map, key) do - pop(map, key, nil) - end - - def pop(map, key, default_value) do - case key in keys(map) do - true -> - { map[key], Map.delete(map, key) } - false -> - { default_value, map } - end - end - - def pop_lazy(map, key, func) do - case key in keys(map) do - true -> - { func.(map[key]), Map.delete(map, key) } - false -> - { func.(), map } - end - end - - - def update!(map, key, func) do - case key in keys(map) do - true -> - Map.put(map, key, func.(map[key])) - false -> - raise "#{key} not found in map" - end - end - - - def update(map, key, initial, func) do - case key in keys(map) do - true -> - Map.put(map, key, func.(map[key])) - false -> - Map.put(map, key, initial) - end - end - -end diff --git a/priv/std_lib/map_set.ex b/priv/std_lib/map_set.ex deleted file mode 100644 index a22fe57b..00000000 --- a/priv/std_lib/map_set.ex +++ /dev/null @@ -1,100 +0,0 @@ -defmodule ElixirScript.MapSet do - @moduledoc false - defstruct set: [] - - def new() do - %MapSet{} - end - - def size(set) do - length(set.set) - end - - def to_list(set) do - set.set - end - - def delete(set, term) do - %{ set | set: Elixir.List.remove(set.set, term) } - end - - def put(set, term) do - case member?(set, term) do - false -> - %{ set | set: set.set ++ term } - true -> - set - end - end - - def member?(set, term) do - set.set.indexOf(term) >= 0 - end - - def equal?(set1, set2) do - set1 === set2 - end - - def difference(set1, set2) do - do_difference(to_list(set1), set2, new()) - end - - def do_difference([], _, difference_set) do - difference_set - end - - def do_difference(set1_list, set2, difference_set) do - term = hd(set1_list) - case member?(set2, term) do - true -> - do_difference(tl(set1_list), set2, difference_set) - false -> - do_difference(tl(set1_list), set2, %{ difference_set | set: difference_set.set ++ [term]}) - end - end - - def intersection(set1, set2) do - do_intersection(to_list(set1), set2, new()) - end - - def do_intersection([], _, intersection_set) do - intersection_set - end - - def do_intersection(set1_list, set2, intersection_set) do - term = hd(set1_list) - case member?(set2, term) do - false -> - do_intersection(tl(set1_list), set2, intersection_set) - true -> - do_intersection(tl(set1_list), set2, %{ intersection_set | set: intersection_set.set ++ [term]}) - end - end - - def union(set1, set2) do - %{ set1 | set: set1.set ++ set2.set} - end - - def disjoint?(set1, set2) do - size(intersection(set1, set2)) == 0 - end - - def subset?(set1, set2) do - do_subset?(to_list(set1), set2) - end - - def do_subset?([], _) do - true - end - - def do_subset?(set1_list, set2) do - term = hd(set1_list) - case member?(set2, term) do - false -> - false - true -> - do_subset?(tl(set1_list), set2) - end - end - -end diff --git a/priv/std_lib/module.ex b/priv/std_lib/module.ex deleted file mode 100644 index f1454a5d..00000000 --- a/priv/std_lib/module.ex +++ /dev/null @@ -1,9 +0,0 @@ -defmodule ElixirScript.Module do - @moduledoc false - - defstruct name: nil, - functions: Keyword.new, private_functions: Keyword.new, - body: nil, js_imports: [], module_refs: [], type: :module, - impls: Map.new, impl_type: nil, app_name: nil - -end diff --git a/priv/std_lib/range.ex b/priv/std_lib/range.ex deleted file mode 100644 index 7f53b13e..00000000 --- a/priv/std_lib/range.ex +++ /dev/null @@ -1,12 +0,0 @@ -defmodule ElixirScript.Range do - @moduledoc false - defstruct first: nil, last: nil - - def new(first, last) do - %Range{first: first, last: last} - end - - def range?(%Range{}), do: true - def range?(_), do: false - -end diff --git a/priv/std_lib/regex.ex b/priv/std_lib/regex.ex deleted file mode 100644 index e395a5d9..00000000 --- a/priv/std_lib/regex.ex +++ /dev/null @@ -1,71 +0,0 @@ -defmodule ElixirScript.Regex do - @moduledoc false - require JS - - def compile(source, options \\ "") do - try do - {:ok, JS.new(JS.RegExp, [source, options])} - rescue - x -> - {:error, x.message} - end - end - - def compile!(source, options \\ "") do - JS.new(JS.RegExp, [source, options]) - end - - def regex?(term) do - JS.instanceof(term, JS.RegExp) - end - - def match?(regex, string) do - reg = if regex?(regex), do: regex, else: compile!(source(regex), opts(regex)) - reg.test(string) - end - - def source(regex) do - regex.source - end - - def opts(regex) do - regex.opts - end - - def run(regex, string, options \\ []) do - regex.exec(string) - end - - def scan(regex, string, options \\ []) do - reg = make_global(regex) - do_scan(reg, string, options, []) - end - - def replace(regex, string, replacement, options \\ []) do - reg = if Keyword.get(options, :global, true) do - make_global(regex) - else - regex - end - - string.replace(reg, replacement) - end - - defp do_scan(regex, string, options, results) do - case run(regex, string, options) do - nil -> - results - match -> - do_scan(regex, string, options, results ++ match) - end - end - - defp make_global(regex) do - if String.contains?(opts(regex), "g") do - regex - else - JS.new(JS.RegExp, [ source(regex), opts(regex) <> "g" ]) - end - end - -end diff --git a/priv/std_lib/store.ex b/priv/std_lib/store.ex deleted file mode 100644 index 70634248..00000000 --- a/priv/std_lib/store.ex +++ /dev/null @@ -1,45 +0,0 @@ -defmodule ElixirScript.Store do - - defp get_key(key) do - - real_key = case JS.__elixirscript_names__.has(key) do - true -> - JS.__elixirscript_names__.get(key) - false -> - key - end - - - case JS.__elixirscript_store__.has(real_key) do - true -> - real_key - false -> - JS.throw JS.new(JS.Error, ["Key Not Found"]) - end - end - - def create(key, value, name \\ nil) do - if name != nil do - JS.__elixirscript_names__.set(name, key) - end - - JS.__elixirscript_store__.set(key, value) - end - - def update(key, value) do - real_key = get_key(key) - JS.__elixirscript_store__.set(real_key, value) - end - - def read(key) do - real_key = get_key(key) - JS.__elixirscript_store__.get(real_key) - end - - def remove(key) do - real_key = get_key(key) - JS.__elixirscript_store__.delete(real_key) - end - - -end diff --git a/priv/std_lib/string/chars.ex b/priv/std_lib/string/chars.ex deleted file mode 100644 index ae5d0227..00000000 --- a/priv/std_lib/string/chars.ex +++ /dev/null @@ -1,48 +0,0 @@ -defprotocol ElixirScript.String.Chars do - @moduledoc false - def to_string(item) -end - -defimpl ElixirScript.String.Chars, for: Atom do - def to_string(nil) do - "" - end - - def to_string(atom) do - Atom.to_string(atom) - end -end - -defimpl ElixirScript.String.Chars, for: BitString do - def to_string(thing) when is_binary(thing) do - thing - end - - def to_string(thing) do - thing.toString() - end -end - -defimpl ElixirScript.String.Chars, for: List do - def to_string(list) do - list.toString() - end -end - -defimpl ElixirScript.String.Chars, for: Tuple do - def to_string(tuple) do - tuple.toString() - end -end - -defimpl ElixirScript.String.Chars, for: Integer do - def to_string(integer) do - integer.toString() - end -end - -defimpl ElixirScript.String.Chars, for: Float do - def to_string(float) do - float.toString() - end -end diff --git a/priv/std_lib/tuple.ex b/priv/std_lib/tuple.ex deleted file mode 100644 index 6751dfa6..00000000 --- a/priv/std_lib/tuple.ex +++ /dev/null @@ -1,63 +0,0 @@ -defmodule ElixirScript.Tuple do - @moduledoc false - require JS - - def duplicate(data, size) do - JS.new(Bootstrap.Core.Tuple, do_duplicate(data, size, [])) - end - - defp do_duplicate(_, 0, list) do - list - end - - defp do_duplicate(data, size, list) do - do_duplicate(data, size - 1, list ++ [data]) - end - - def to_list(tuple) do - tuple.values - end - - def insert_at(tuple, index, value) do - JS.new(Bootstrap.Core.Tuple, do_insert_at(tuple, index, value, 0, [])) - end - - defp do_insert_at(tuple, index, value, current_index, list) do - if current_index == length(tuple) do - list - else - new_list = case index == current_index do - true -> - list ++ [value, tuple.get(current_index)] - false -> - list ++ [tuple.get(current_index)] - end - - do_insert_at(tuple, index, value, current_index + 1, new_list) - end - end - - def delete_at(tuple, index) do - JS.new(Bootstrap.Core.Tuple, do_delete_at(tuple, index, 0, [])) - end - - defp do_delete_at(tuple, index, current_index, list) do - if current_index == length(tuple) do - list - else - new_list = case index == current_index do - true -> - list - false -> - list ++ [tuple.get(current_index)] - end - - do_delete_at(tuple, index, current_index + 1, new_list) - end - end - - def append(tuple, value) do - JS.new(Bootstrap.Core.Tuple, to_list(tuple) ++ [value]) - end - -end diff --git a/rollup.config.js b/rollup.config.js index c06836ac..9fe0ae32 100644 --- a/rollup.config.js +++ b/rollup.config.js @@ -10,7 +10,10 @@ export default { babel({ babelrc: false, }), - //babili({}), + babili({ + keepFnName: true, + keepClassName: true, + }), ], targets: [{ dest: 'priv/build/iife/Elixir.Bootstrap.js', format: 'iife' }], }; diff --git a/src/javascript/lib/core/erlang_compat/erlang.js b/src/javascript/lib/core/erlang_compat/erlang.js index eb3f78c6..3ca28bf6 100644 --- a/src/javascript/lib/core/erlang_compat/erlang.js +++ b/src/javascript/lib/core/erlang_compat/erlang.js @@ -6,9 +6,25 @@ function atom_to_binary(atom, encoding = Symbol.for('utf8')) { throw new Error(`unsupported encoding ${encoding}`); } + if (atom.__MODULE__) { + return Symbol.keyFor(atom.__MODULE__); + } + return Symbol.keyFor(atom); } +function binary_to_atom(binary, encoding = Symbol.for('utf8')) { + if (encoding !== Symbol.for('utf8')) { + throw new Error(`unsupported encoding ${encoding}`); + } + + return Symbol.for(binary); +} + +function binary_to_existing_atom(binary, encoding = Symbol.for('utf8')) { + return binary_to_atom(binary, encoding); +} + function list_concatenation(list1, list2) { return list1.concat(list2); } @@ -124,7 +140,9 @@ function bxor(left, right) { } function is_atom(value) { - return value instanceof Symbol || value.__MODULE__ === true; + return ( + typeof value === 'symbol' || value instanceof Symbol || value.__MODULE__ + ); } function is_bitstring(value) { @@ -132,15 +150,19 @@ function is_bitstring(value) { } function is_boolean(value) { - return value instanceof Boolean; + return typeof value === 'boolean' || value instanceof Boolean; +} + +function is_number(value) { + return typeof value === 'number' || value instanceof Number; } function is_float(value) { - return value instanceof Number && !Number.isInteger(value); + return is_number(value) && !Number.isInteger(value); } function is_function(value) { - return value instanceof Function; + return typeof value === 'function' || value instanceof Function; } function is_integer(value) { @@ -152,11 +174,7 @@ function is_list(value) { } function is_map(value) { - return value instanceof Object; -} - -function is_number(value) { - return value instanceof Number; + return typeof value === 'object' || value instanceof Object; } function is_pid(value) { @@ -176,11 +194,13 @@ function is_tuple(value) { } function is_binary(value) { - return value instanceof String; + return typeof value === 'string' || value instanceof String; } export default { atom_to_binary, + binary_to_atom, + binary_to_existing_atom, list_concatenation, list_subtraction, plus, diff --git a/test/cli_test.exs b/test/cli_test.exs deleted file mode 100644 index 05244867..00000000 --- a/test/cli_test.exs +++ /dev/null @@ -1,8 +0,0 @@ -defmodule ElixirScript.CLI.Test do - use ExUnit.Case - - test "parse_args -js-module includes js module" do - {_, args} = ElixirScript.CLI.parse_args(["Example", "--js-module", "React:react"]) - assert args == [js_module: "React:react"] - end -end diff --git a/test/passes/create_js_modules_test.exs b/test/passes/create_js_modules_test.exs deleted file mode 100644 index 23b4edc3..00000000 --- a/test/passes/create_js_modules_test.exs +++ /dev/null @@ -1,30 +0,0 @@ -defmodule ElixirScript.Passes.CreateJSModules.Test do - use ExUnit.Case - - import ElixirScript.TestHelper - - alias ElixirScript.Passes.CreateJSModules - alias ESTree.Tools.Generator - - test "start" do - ex_ast = quote do: CreateJSModules.start - js = """ - Elixir.start = function(app, args) { - app.__load(Elixir).start(Symbol.for('normal'), args) - } - """ - - assert_translation(ex_ast, js) - end - - test "load" do - ex_ast = quote do: CreateJSModules.load - js = """ - Elixir.load = function(module) { - return module.__load(Elixir); - } - """ - - assert_translation(ex_ast, js) - end -end diff --git a/test/passes/handle_output_test.exs b/test/passes/handle_output_test.exs deleted file mode 100644 index 8691a6be..00000000 --- a/test/passes/handle_output_test.exs +++ /dev/null @@ -1,21 +0,0 @@ -defmodule ElixirScript.Passes.HandleOutput.Test do - use ExUnit.Case - alias ElixirScript.Passes.HandleOutput - - test "get_js_path output: nil" do - assert HandleOutput.get_js_path(nil) == "Elixir.App.js" - end - - test "get_js_path output: stdout" do - assert HandleOutput.get_js_path(:stdout) == "Elixir.App.js" - end - - test "get_js_path output is directory" do - assert HandleOutput.get_js_path("/path/to/file/") == "/path/to/file/Elixir.App.js" - assert HandleOutput.get_js_path("/path/to/file") == "/path/to/file/Elixir.App.js" - end - - test "get_js_path output ends in js" do - assert HandleOutput.get_js_path("/path/to/file/myfile.js") == "/path/to/file/myfile.js" - end -end \ No newline at end of file diff --git a/test/next/passes/translate/form_test.exs b/test/passes/translate/form_test.exs similarity index 98% rename from test/next/passes/translate/form_test.exs rename to test/passes/translate/form_test.exs index 5d8dc95c..50dcd93f 100644 --- a/test/next/passes/translate/form_test.exs +++ b/test/passes/translate/form_test.exs @@ -1,7 +1,7 @@ defmodule ElixirScript.Translate.Forms.Test do use ExUnit.Case alias ElixirScript.Translate.Form - alias ElixirScript.Translator.Identifier + alias ElixirScript.Translate.Identifier alias ESTree.Tools.Builder, as: J diff --git a/test/next/passes/translate/forms/map_test.exs b/test/passes/translate/forms/map_test.exs similarity index 100% rename from test/next/passes/translate/forms/map_test.exs rename to test/passes/translate/forms/map_test.exs diff --git a/test/next/passes/translate/forms/receive_test.exs b/test/passes/translate/forms/receive_test.exs similarity index 100% rename from test/next/passes/translate/forms/receive_test.exs rename to test/passes/translate/forms/receive_test.exs diff --git a/test/next/passes/translate/forms/remote_test.exs b/test/passes/translate/forms/remote_test.exs similarity index 100% rename from test/next/passes/translate/forms/remote_test.exs rename to test/passes/translate/forms/remote_test.exs diff --git a/test/prelude/js_test.exs b/test/prelude/js_test.exs deleted file mode 100644 index 3cff3835..00000000 --- a/test/prelude/js_test.exs +++ /dev/null @@ -1,52 +0,0 @@ -defmodule ElixirScript.Lib.JS.Test do - use ExUnit.Case - import ElixirScript.TestHelper - - test "translate new" do - ex_ast = quote do - require JS - - def execute() do - JS.new A.B, [1, 2, 3] - end - end - - js_code = """ - new A.B(1, 2, 3) - """ - - assert_translation(ex_ast, js_code) - - ex_ast = quote do - require JS - - def execute() do - JS.new A, [1, 2, 3] - end - end - - js_code = """ - new A(1, 2, 3) - """ - - assert_translation(ex_ast, js_code) - end - - test "translate update" do - ex_ast = quote do - require JS - - def execute() do - JS.update A, %{"b" => [1, 2, 3]} - end - end - - js_code = """ - Object.assign(A, Object.freeze({ - b: Object.freeze([1, 2, 3]) - })) - """ - - assert_translation(ex_ast, js_code) - end -end diff --git a/test/prelude/kernel_test.exs b/test/prelude/kernel_test.exs deleted file mode 100644 index e134c61e..00000000 --- a/test/prelude/kernel_test.exs +++ /dev/null @@ -1,44 +0,0 @@ -defmodule ElixirScript.Lib.Elixir.Kernel.Test do - use ExUnit.Case - import ElixirScript.TestHelper - - test "translate range" do - ex_ast = quote do - 1..4 - end - - js_code = """ - - Elixir.ElixirScript.Range.__load(Elixir).__struct__(Object.freeze({ - [Symbol.for('first')]: 1, - [Symbol.for('last')]: 4 - })) - """ - - assert_translation(ex_ast, js_code) - end - - test "translate sigil_r" do - ex_ast = quote do - ~r/foo/ - end - - js_code = """ - Elixir.ElixirScript.Regex.__load(Elixir).compile__emark__('foo', '') - """ - - assert_translation(ex_ast, js_code) - end - - test "translate sigil_r with options" do - ex_ast = quote do - ~r/foo/i - end - - js_code = """ - Elixir.ElixirScript.Regex.__load(Elixir).compile__emark__('foo', 'i') - """ - - assert_translation(ex_ast, js_code) - end -end diff --git a/test/support/main.ex b/test/support/main.ex index a18d3d90..ec70a46a 100644 --- a/test/support/main.ex +++ b/test/support/main.ex @@ -1,5 +1,8 @@ defmodule Main do def start(:normal, [callback]) do callback.("started") + + JS.console.log String.valid?("a") + JS.console.log String.valid?(1) end end diff --git a/test/test_helper.exs b/test/test_helper.exs index f23b9de7..30fac768 100644 --- a/test/test_helper.exs +++ b/test/test_helper.exs @@ -1,87 +1,3 @@ exclude = if Node.alive?, do: [], else: [skip: true] ExUnit.start(exclude: exclude) - -defmodule ElixirScript.Math do - defmacro squared(x) do - quote do - unquote(x) * unquote(x) - end - end -end - -defmodule ElixirScript.Using do - defmacro __using__(_) do - quote do - def sandwich() do - end - end - end -end - -defmodule ElixirScript.TestHelper do - use ExUnit.Case - - def make_custom_env do - use ElixirScript - require ElixirScript.Math - require ElixirScript.Using - __ENV__ - end - - def ex_ast_to_js(ex_ast, format) do - ElixirScript.compile_quoted(ex_ast, %{ env: make_custom_env(), import_standard_libs: false, format: format }) - end - - def strip_spaces(js) do - js |> String.replace(~r/\s+/, "") - end - - def assert_translation(ex_ast, js_code) do - assert_translation(ex_ast, js_code, :es) - end - - def assert_translation(ex_ast, js_code, format) do - converted_code = ex_ast_to_js(ex_ast, format) - - assert converted_code |> strip_spaces =~ strip_spaces(js_code), """ - **Code Does Not Match ** - - ***Expected*** - #{js_code} - - ***Actual*** - #{converted_code} - """ - end - - def assert_js_matches(expected_js_code, actual_js_code) do - assert strip_spaces(hd(List.wrap(actual_js_code))) =~ strip_spaces(expected_js_code), """ - **Code Does Not Match ** - - ***Expected*** - #{expected_js_code} - - ***Actual*** - #{actual_js_code} - """ - end - - def refute_translation(ex_ast, js_code) do - refute_translation(ex_ast, js_code, :es) - end - - def refute_translation(ex_ast, js_code, format) do - converted_code = ex_ast_to_js(ex_ast, format) - - refute converted_code |> strip_spaces =~ strip_spaces(js_code), """ - **Code Does Not Match ** - - ***Expected*** - #{js_code} - - ***Actual*** - #{converted_code} - """ - end -end diff --git a/test/translator/access_test.exs b/test/translator/access_test.exs deleted file mode 100644 index 194c24d7..00000000 --- a/test/translator/access_test.exs +++ /dev/null @@ -1,14 +0,0 @@ -defmodule ElixirScript.Translator.Access.Test do - use ExUnit.Case - import ElixirScript.TestHelper - - test "translate access" do - ex_ast = quote do - a = [] - a[:b] - end - js_code = "a[Symbol.for('b')]" - - assert_translation(ex_ast, js_code) - end -end diff --git a/test/translator/atom_test.exs b/test/translator/atom_test.exs deleted file mode 100644 index 90edfc9d..00000000 --- a/test/translator/atom_test.exs +++ /dev/null @@ -1,14 +0,0 @@ -defmodule ElixirScript.Translator.Atom.Test do - use ExUnit.Case - import ElixirScript.TestHelper - - test "translate atom" do - ex_ast = quote do: :atom - assert_translation(ex_ast, "Symbol.for('atom')") - end - - test "Call Atom module" do - ex_ast = quote do: Atom.to_string(:atom) - assert_translation(ex_ast, "Elixir.ElixirScript.Atom.__load(Elixir).to_string(Symbol.for('atom'))") - end -end diff --git a/test/translator/bitstring_test.exs b/test/translator/bitstring_test.exs deleted file mode 100644 index 2faef0e2..00000000 --- a/test/translator/bitstring_test.exs +++ /dev/null @@ -1,95 +0,0 @@ -defmodule ElixirScript.Translator.Bitstring.Test do - use ExUnit.Case - import ElixirScript.TestHelper - - test "translate bitstring" do - ex_ast = quote do: <<1, 2, 3>> - assert_translation(ex_ast, "new Bootstrap.Core.BitString(Bootstrap.Core.BitString.integer(1), Bootstrap.Core.BitString.integer(2), Bootstrap.Core.BitString.integer(3))") - - ex_ast = quote do: <<1, "foo">> - assert_translation(ex_ast, "new Bootstrap.Core.BitString(Bootstrap.Core.BitString.integer(1), Bootstrap.Core.BitString.binary('foo'))") - - ex_ast = quote do: <<1, "foo" :: binary>> - assert_translation(ex_ast, "new Bootstrap.Core.BitString(Bootstrap.Core.BitString.integer(1), Bootstrap.Core.BitString.binary('foo'))") - - ex_ast = quote do: <<1, "foo" :: utf8, "bar" :: utf32>> - assert_translation(ex_ast, "new Bootstrap.Core.BitString(Bootstrap.Core.BitString.integer(1), Bootstrap.Core.BitString.utf8('foo'), Bootstrap.Core.BitString.utf32('bar'))") - - ex_ast = quote do - rest = "oo" - <<102 :: integer-native, rest :: binary>> - end - assert_translation(ex_ast, "new Bootstrap.Core.BitString(Bootstrap.Core.BitString.native(Bootstrap.Core.BitString.integer(102)), Bootstrap.Core.BitString.binary(rest))") - - ex_ast = quote do - rest = "oo" - <<102 :: unsigned-big-integer, rest :: binary>> - end - assert_translation(ex_ast, "new Bootstrap.Core.BitString(Bootstrap.Core.BitString.integer(Bootstrap.Core.BitString.big(Bootstrap.Core.BitString.unsigned(102))), Bootstrap.Core.BitString.binary(rest))") - - ex_ast = quote do - rest = 100 - <<102, rest :: size(16)>> - end - - assert_translation(ex_ast, "new Bootstrap.Core.BitString(Bootstrap.Core.BitString.integer(102), Bootstrap.Core.BitString.size(rest, 16))") - - ex_ast = quote do - rest = 100 - <<102, rest :: size(16)-unit(4)>> - end - - assert_translation(ex_ast, "new Bootstrap.Core.BitString(Bootstrap.Core.BitString.integer(102), Bootstrap.Core.BitString.unit(Bootstrap.Core.BitString.size(rest, 16), 4))") - - ex_ast = quote do - rest = 100 - <<102, rest :: 16 * 4>> - end - - assert_translation(ex_ast, "new Bootstrap.Core.BitString(Bootstrap.Core.BitString.integer(102), Bootstrap.Core.BitString.unit(Bootstrap.Core.BitString.size(rest, 16), 4))") - - ex_ast = quote do - rest = 100 - <<102, rest :: 16>> - end - - assert_translation(ex_ast, "new Bootstrap.Core.BitString(Bootstrap.Core.BitString.integer(102), Bootstrap.Core.BitString.size(rest, 16))") - - ex_ast = quote do: << 1, <<2>> >> - assert_translation(ex_ast, "new Bootstrap.Core.BitString(Bootstrap.Core.BitString.integer(1), new Bootstrap.Core.BitString(Bootstrap.Core.BitString.integer(2)))") - end - - test "translate pattern matching bitstring" do - ex_ast = quote do: <> = <<"Frank the Walrus">> - js_code = """ - let [name,species] = Bootstrap.Core.Patterns.match(Bootstrap.Core.Patterns.bitStringMatch(Bootstrap.Core.BitString.size(Bootstrap.Core.BitString.binary({ - 'value': Bootstrap.Core.Patterns.variable() - }),5),Bootstrap.Core.BitString.binary(' the '),Bootstrap.Core.BitString.binary({ - 'value': Bootstrap.Core.Patterns.variable() - })),'Frank the Walrus'); - """ - - assert_translation(ex_ast, js_code) - - - ex_ast = quote do: <> = <<-100>> - js_code = """ - let [int] = Bootstrap.Core.Patterns.match(Bootstrap.Core.Patterns.bitStringMatch(Bootstrap.Core.BitString.integer({ - 'value': Bootstrap.Core.Patterns.variable() - })),new Bootstrap.Core.BitString(Bootstrap.Core.BitString.binary(-100))); - """ - - assert_translation(ex_ast, js_code) - - - ex_ast = quote do: <<-100::signed, _rest::binary>> = <<-100, "foo">> - js_code = """ - let [_rest] = Bootstrap.Core.Patterns.match(Bootstrap.Core.Patterns.bitStringMatch(Bootstrap.Core.BitString.signed(-100),Bootstrap.Core.BitString.binary({ - 'value': Bootstrap.Core.Patterns.variable() - })),new Bootstrap.Core.BitString(Bootstrap.Core.BitString.binary(-100),Bootstrap.Core.BitString.binary('foo'))); - """ - - assert_translation(ex_ast, js_code) - end - -end diff --git a/test/translator/bitwise_test.exs b/test/translator/bitwise_test.exs deleted file mode 100644 index 0f9f6a57..00000000 --- a/test/translator/bitwise_test.exs +++ /dev/null @@ -1,15 +0,0 @@ -defmodule ElixirScript.Translator.Bitwise.Test do - use ExUnit.Case - import ElixirScript.TestHelper - - test "bitwise when imported" do - ex_ast = quote do - import Bitwise - 1 &&& 2 - end - - js_code = "1 & 2" - - assert_translation(ex_ast, js_code) - end -end diff --git a/test/translator/bug_test.exs b/test/translator/bug_test.exs deleted file mode 100644 index f4474eb1..00000000 --- a/test/translator/bug_test.exs +++ /dev/null @@ -1,161 +0,0 @@ -defmodule ElixirScript.Translator.Bug.Test do - use ExUnit.Case - import ElixirScript.TestHelper - - test "Translate function with 0 arguments" do - ex_ast = quote do - def test do - :atom - end - end - - js_code = """ - const test = Bootstrap.Core.Patterns.defmatch(Bootstrap.Core.Patterns.clause([],function(){ - return Symbol.for('atom'); - })); - """ - - assert_translation(ex_ast, js_code) - end - - test "Translate react element" do - ex_ast = quote do - def execute() do - React.createElement( - React.Text, - %{"style" => ""}, - "Welcome to React Native!" - ) - end - end - - js_code = """ - React.createElement(React.Text,Object.freeze({ - style: '' - }),'Welcome to React Native!') - """ - - assert_translation(ex_ast, js_code) - - end - - test "replace !" do - ex_ast = quote do - def execute(data, i) do - Enum.fetch!(data, i) - end - end - - js_code = """ - Elixir.ElixirScript.Enum.__load(Elixir).fetch__emark__(data, i) - """ - - assert_translation(ex_ast, js_code) - end - - test "chain calls correctly" do - ex_ast = quote do - def execute() do - :this.getRawCanvas().getContext("2d") - end - end - - js_code = """ - Bootstrap.Core.Functions.call_property(this, 'getRawCanvas').getContext('2d') - """ - - assert_translation(ex_ast, js_code) - - - ex_ast = quote do - def execute(one) do - :this.getRawCanvas(one).get("fg").getContext("2d") - end - end - - js_code = """ - this.getRawCanvas(one).get('fg').getContext('2d') - """ - - assert_translation(ex_ast, js_code) - end - - test "correctly call multi-module functions" do - ex_ast = quote do - def getDispatcher() do - DeLorean.Flux.createDispatcher(%{ - startPainting: fn() -> :this.dispatch("startPainting") end, - stopPainting: fn() -> :this.dispatch("stopPainting") end, - addPoint: fn(data) -> :this.dispatch("addPoint", data) end, - getStores: fn() -> %{ graphic: GraphicStore } end - }) - end - end - - - js_code = """ - const getDispatcher = Bootstrap.Core.Patterns.defmatch(Bootstrap.Core.Patterns.clause([],function() { - return DeLorean.Flux.createDispatcher(Object.freeze({ - [Symbol.for('startPainting')]: Bootstrap.Core.Patterns.defmatch(Bootstrap.Core.Patterns.clause([],function() { - return this.dispatch('startPainting'); - })), [Symbol.for('stopPainting')]: Bootstrap.Core.Patterns.defmatch(Bootstrap.Core.Patterns.clause([],function() { - return this.dispatch('stopPainting'); - })), [Symbol.for('addPoint')]: Bootstrap.Core.Patterns.defmatch(Bootstrap.Core.Patterns.clause([Bootstrap.Core.Patterns.variable()],function(data) { - return this.dispatch('addPoint',data); - })), [Symbol.for('getStores')]: Bootstrap.Core.Patterns.defmatch(Bootstrap.Core.Patterns.clause([],function() { - return Object.freeze({ - [Symbol.for('graphic')]: GraphicStore - }); - })) - })); - })); - """ - - assert_translation(ex_ast, js_code) - end - - - test "test array returns correctly" do - ex_ast = quote do - def my_func(x) do - [x.a, x.b] - end - end - - js_code = """ - const my_func = Bootstrap.Core.Patterns.defmatch(Bootstrap.Core.Patterns.clause([Bootstrap.Core.Patterns.variable()],function(x){ - return Object.freeze([Bootstrap.Core.Functions.call_property(x,'a'), Bootstrap.Core.Functions.call_property(x,'b')]); - })); - """ - - assert_translation(ex_ast, js_code) - end - - test "Elixir.Enum.member__qmark__ does not show up in translation" do - ex_ast = quote do - Enum.member?([1, 2, 3], 1) - end - - js_code = """ - Elixir.Enum.member__qmark__ - """ - - refute_translation(ex_ast, js_code) - end - - test "pipe translates correctly" do - ex_ast = quote do - def execute() do - :document.getElementById("main") |> JS.update(%{"innerHTML" => @html}) - end - end - - js_code = """ - Object.assign(document.getElementById('main'), Object.freeze({ - innerHTML: html - })) - """ - - assert_translation(ex_ast, js_code) - end -end diff --git a/test/translator/capture_test.exs b/test/translator/capture_test.exs deleted file mode 100644 index 892321ac..00000000 --- a/test/translator/capture_test.exs +++ /dev/null @@ -1,131 +0,0 @@ -defmodule ElixirScript.Translator.Capture.Test do - use ExUnit.Case - import ElixirScript.TestHelper - - test "translate capture operator with Module, function, and arity" do - ex_ast = quote do - fun = &Elixir.Kernel.is_atom/1 - end - - js_code = """ - let [fun] = Bootstrap.Core.Patterns.match(Bootstrap.Core.Patterns.variable(), Elixir.ElixirScript.Kernel.__load(Elixir).is_atom); - """ - - assert_translation(ex_ast, js_code) - - end - - test "translate capture operator with function, and parameters" do - - ex_ast = quote do - fun = &is_atom(&1) - end - - js_code = """ - let [fun] = Bootstrap.Core.Patterns.match(Bootstrap.Core.Patterns.variable(),Bootstrap.Core.Patterns.defmatch(Bootstrap.Core.Patterns.clause([Bootstrap.Core.Patterns.variable()],function(__1) { - return Elixir.ElixirScript.Kernel.__load(Elixir).is_atom(__1); - }))); - """ - - assert_translation(ex_ast, js_code) - - - end - - test "translate capture operator with function, and arity" do - - ex_ast = quote do - fun = &is_atom/1 - end - - js_code = """ - let [fun] = Bootstrap.Core.Patterns.match(Bootstrap.Core.Patterns.variable(),is_atom); - """ - - assert_translation(ex_ast, js_code) - - end - - test "translate capture operator with anonymous function" do - - ex_ast = quote do - fun = &(&1 * 2) - end - - js_code = """ - let [fun] = Bootstrap.Core.Patterns.match(Bootstrap.Core.Patterns.variable(),Bootstrap.Core.Patterns.defmatch(Bootstrap.Core.Patterns.clause([Bootstrap.Core.Patterns.variable()],function(__1) { - return __1 * 2; - }))); - """ - - assert_translation(ex_ast, js_code) - - end - - test "translate capture operator with anonymous function tuple" do - - ex_ast = quote do - fun = &{&1, &2} - end - - js_code = """ - let [fun] = Bootstrap.Core.Patterns.match(Bootstrap.Core.Patterns.variable(),Bootstrap.Core.Patterns.defmatch(Bootstrap.Core.Patterns.clause([Bootstrap.Core.Patterns.variable(), Bootstrap.Core.Patterns.variable()],function(__1,__2) { - return new Bootstrap.Core.Tuple(__1,__2); - }))); - """ - - assert_translation(ex_ast, js_code) - - ex_ast = quote do - fun = &{&1, &2, &3} - end - - js_code = """ - let [fun] = Bootstrap.Core.Patterns.match(Bootstrap.Core.Patterns.variable(),Bootstrap.Core.Patterns.defmatch(Bootstrap.Core.Patterns.clause([Bootstrap.Core.Patterns.variable(), Bootstrap.Core.Patterns.variable(), Bootstrap.Core.Patterns.variable()],function(__1,__2,__3) { - return new Bootstrap.Core.Tuple(__1,__2,__3); - }))); - """ - - assert_translation(ex_ast, js_code) - - - end - - test "translate capture operator with anonymous functions as parameters" do - - ex_ast = quote do - def process(a) do - end - - def execute() do - Enum.map([], &process(&1)) - end - end - - js_code = """ - Elixir.ElixirScript.Enum.__load(Elixir).map(Object.freeze([]),Bootstrap.Core.Patterns.defmatch(Bootstrap.Core.Patterns.clause([Bootstrap.Core.Patterns.variable()],function(__1) { - return process(__1); - }))) - """ - - assert_translation(ex_ast, js_code) - - - ex_ast = quote do - def process_event(a) do - end - - def execute() do - Elem.keypress(&process_event(&1)) - end - end - - js_code = """ - Elem.keypress(Bootstrap.Core.Patterns.defmatch(Bootstrap.Core.Patterns.clause([Bootstrap.Core.Patterns.variable()],function(__1) { - return process_event(__1); - }))) - """ - - assert_translation(ex_ast, js_code) - end -end diff --git a/test/translator/case_test.exs b/test/translator/case_test.exs deleted file mode 100644 index 4a38b333..00000000 --- a/test/translator/case_test.exs +++ /dev/null @@ -1,211 +0,0 @@ -defmodule ElixirScript.Translator.Case.Test do - use ExUnit.Case - import ElixirScript.TestHelper - - test "translate case" do - - ex_ast = quote do - def execute() do - data = :ok - case data do - :ok -> 1 - :error -> nil - end - end - end - - js_code = """ - Bootstrap.Core.Patterns.defmatch(Bootstrap.Core.Patterns.clause([Symbol.for('ok')],function() { - return 1; - }),Bootstrap.Core.Patterns.clause([Symbol.for('error')],function() { - return null; - })).call(this,data) - """ - - assert_translation(ex_ast, js_code) - - ex_ast = quote do - data = true - case data do - false -> value = 13 - true -> true - end - end - - js_code = """ - Bootstrap.Core.Patterns.defmatch(Bootstrap.Core.Patterns.clause([false],function() { - let [value] = Bootstrap.Core.Patterns.match(Bootstrap.Core.Patterns.variable(),13); - return value; - }),Bootstrap.Core.Patterns.clause([true],function() { - return true; - })).call(this,data) - """ - - assert_translation(ex_ast, js_code) - - - - ex_ast = quote do - data = :ok - case data do - false -> value = 13 - _ -> true - end - end - - js_code = """ - Bootstrap.Core.Patterns.defmatch(Bootstrap.Core.Patterns.clause([false],function() { - let [value] = Bootstrap.Core.Patterns.match(Bootstrap.Core.Patterns.variable(),13); - return value; - }),Bootstrap.Core.Patterns.clause([Bootstrap.Core.Patterns.variable()],function(__ignored__) { - return true; - })).call(this,data) - """ - - assert_translation(ex_ast, js_code) - end - - test "translate case with guard" do - ex_ast = quote do - data = :ok - case data do - number when number in [1,2,3,4] -> - value = 13 - _ -> - true - end - end - - js_code = """ - Bootstrap.Core.Patterns.defmatch(Bootstrap.Core.Patterns.clause([Bootstrap.Core.Patterns.variable()],function(number) { - let [value] = Bootstrap.Core.Patterns.match(Bootstrap.Core.Patterns.variable(),13); - return value; - },function(number) { - return Elixir.ElixirScript.Bootstrap.Functions.__load(Elixir).contains(number,Object.freeze([1, 2, 3, 4])); - }),Bootstrap.Core.Patterns.clause([Bootstrap.Core.Patterns.variable()],function(__ignored__) { - return true; - })).call(this,data) - """ - - assert_translation(ex_ast, js_code) - end - - test "translate case with multiple guards" do - ex_ast = quote do - data = :ok - case data do - number when number in [1,2,3,4] when number in [4, 3, 2, 1] -> - value = 13 - _ -> - true - end - end - - js_code = """ - Bootstrap.Core.Patterns.defmatch(Bootstrap.Core.Patterns.clause([Bootstrap.Core.Patterns.variable()],function(number) { - let [value] = Bootstrap.Core.Patterns.match(Bootstrap.Core.Patterns.variable(),13); - return value; - },function(number) { - return Elixir.ElixirScript.Bootstrap.Functions.__load(Elixir).contains(number,Object.freeze([1, 2, 3, 4])) || Elixir.ElixirScript.Bootstrap.Functions.__load(Elixir).contains(number,Object.freeze([4, 3, 2, 1])); - }),Bootstrap.Core.Patterns.clause([Bootstrap.Core.Patterns.variable()],function(__ignored__) { - return true; - })).call(this,data) - """ - - assert_translation(ex_ast, js_code) - end - - test "translate case with multiple statements in body" do - ex_ast = quote do - def execute() do - data = :ok - case data do - :ok -> - :console.info("info") - Todo.add(data) - :error -> - nil - end - end - end - - js_code = """ - Bootstrap.Core.Patterns.defmatch(Bootstrap.Core.Patterns.clause([Symbol.for('ok')],function() { - console.info('info'); - return Todo.add(data); - }),Bootstrap.Core.Patterns.clause([Symbol.for('error')],function() { - return null; - })).call(this,data) - """ - - assert_translation(ex_ast, js_code) - end - - test "translate case with destructing" do - ex_ast = quote do - def execute() do - data = :ok - case data do - { one, two } -> - :console.info(one) - :error -> - nil - end - end - end - - js_code = """ -Bootstrap.Core.Patterns.defmatch(Bootstrap.Core.Patterns.clause([new Bootstrap.Core.Tuple(Bootstrap.Core.Patterns.variable(), Bootstrap.Core.Patterns.variable())], function(one, two) { - return console.info(one); - }), Bootstrap.Core.Patterns.clause([Symbol.for('error')], function() { - return null; - })).call(this, data); - """ - - assert_translation(ex_ast, js_code) - end - - test "translate case with nested destructing" do - ex_ast = quote do - def execute() do - data = :error - case data do - { {one, two} , three } -> - :console.info(one) - :error -> - nil - end - end - end - - js_code = """ -Bootstrap.Core.Patterns.defmatch(Bootstrap.Core.Patterns.clause([new Bootstrap.Core.Tuple(new Bootstrap.Core.Tuple(Bootstrap.Core.Patterns.variable(), Bootstrap.Core.Patterns.variable()), Bootstrap.Core.Patterns.variable())], function(one, two, three) { - return console.info(one); - }), Bootstrap.Core.Patterns.clause([Symbol.for('error')], function() { - return null; - })).call(this, data) - """ - - assert_translation(ex_ast, js_code) - - ex_ast = quote do - data = :error - case data do - { one, {two, three} } -> - :console.info(one) - :error -> - nil - end - end - - js_code = """ -Bootstrap.Core.Patterns.defmatch(Bootstrap.Core.Patterns.clause([new Bootstrap.Core.Tuple(Bootstrap.Core.Patterns.variable(), new Bootstrap.Core.Tuple(Bootstrap.Core.Patterns.variable(), Bootstrap.Core.Patterns.variable()))], function(one, two, three) { - return console.info(one); - }), Bootstrap.Core.Patterns.clause([Symbol.for('error')], function() { - return null; - })).call(this, data) - """ - - assert_translation(ex_ast, js_code) - end -end diff --git a/test/translator/commonjs_test.exs b/test/translator/commonjs_test.exs deleted file mode 100644 index 187a9cdd..00000000 --- a/test/translator/commonjs_test.exs +++ /dev/null @@ -1,22 +0,0 @@ -defmodule ElixirScript.Translator.CommonJS.Test do - use ExUnit.Case - import ElixirScript.TestHelper - - test "translate module to commonjs" do - ex_ast = quote do - defmodule Elephant do - @ul "#todo-list" - - def something() do - @ul - end - end - end - - js_code = """ - module.exports = Elixir - """ - - assert_translation(ex_ast, js_code, :common) - end -end diff --git a/test/translator/cond_test.exs b/test/translator/cond_test.exs deleted file mode 100644 index 8b5f605d..00000000 --- a/test/translator/cond_test.exs +++ /dev/null @@ -1,58 +0,0 @@ -defmodule ElixirScript.Translator.Cond.Test do - use ExUnit.Case - import ElixirScript.TestHelper - - test "translate cond" do - ex_ast = quote do - cond do - 1 + 1 == 1 -> - "This will never match" - 2 * 2 != 4 -> - "Nor this" - true -> - "This will" - end - end - - js_code = """ - Bootstrap.Core.SpecialForms.cond(Object.freeze([1 + 1 == 1, function() { - return 'This will never match'; - }]),Object.freeze([2 * 2 != 4, function() { - return 'Nor this'; - }]),Object.freeze([true, function() { - return 'This will'; - }])) - """ - - assert_translation(ex_ast, js_code) - - ex_ast = quote do - cond do - 1 + 1 == 1 -> - a = 1 - "This will never match" - 2 * 2 != 4 -> - a = 2 - "Nor this" - true -> - a = 3 - "This will" - end - end - - js_code = """ - Bootstrap.Core.SpecialForms.cond(Object.freeze([1 + 1 == 1, function() { - let [a] = Bootstrap.Core.Patterns.match(Bootstrap.Core.Patterns.variable(),1); - return 'This will never match'; - }]),Object.freeze([2 * 2 != 4, function() { - let [a] = Bootstrap.Core.Patterns.match(Bootstrap.Core.Patterns.variable(),2); - return 'Nor this'; - }]),Object.freeze([true, function() { - let [a] = Bootstrap.Core.Patterns.match(Bootstrap.Core.Patterns.variable(),3); - return 'This will'; - }])) - """ - - assert_translation(ex_ast, js_code) - end -end diff --git a/test/translator/defdelegate_test.exs b/test/translator/defdelegate_test.exs deleted file mode 100644 index 52ef6266..00000000 --- a/test/translator/defdelegate_test.exs +++ /dev/null @@ -1,28 +0,0 @@ -defmodule ElixirScript.Translator.Defdelegate.Test do - use ExUnit.Case - import ElixirScript.TestHelper - - test "translate defdelegate" do - ex_ast = quote do: defdelegate reverse(list), to: :lists - - js_code = """ - const reverse = function(list) { - return Elixir.ElixirScript.Bootstrap.Functions.__load(Elixir).reverse(list); - }; - """ - - assert_translation(ex_ast, js_code) - end - - test "translate defdelegate as another name" do - ex_ast = quote do: defdelegate other_reverse(list), to: :lists, as: :reverse - - js_code = """ - const other_reverse = function(list) { - return Elixir.ElixirScript.Bootstrap.Functions.__load(Elixir).reverse(list); - }; - """ - - assert_translation(ex_ast, js_code) - end -end diff --git a/test/translator/defmodule_test.exs b/test/translator/defmodule_test.exs deleted file mode 100644 index 8719b2a9..00000000 --- a/test/translator/defmodule_test.exs +++ /dev/null @@ -1,176 +0,0 @@ -defmodule ElixirScript.Translator.Defmodule.Test do - use ExUnit.Case - import ElixirScript.TestHelper - - test "translate empty module" do - ex_ast = quote do - defmodule Elephant do - end - end - - js_code = """ - const __exports = { - __info__ - }; - """ - - assert_translation(ex_ast, js_code) - end - - test "translate defmodules" do - ex_ast = quote do - defmodule Elephant do - require JS - @ul "#todo-list" - - def something() do - @ul - end - - JS.defgenp something_else() do - end - end - end - - js_code = """ - const something = Bootstrap.Core.Patterns.defmatch(Bootstrap.Core.Patterns.clause([], function() { - return ul; - })); - - const __info__ = function(kind) { - return Bootstrap.Core.Patterns.defmatch(Bootstrap.Core.Patterns.clause([Symbol.for('functions')], function() { - return Object.freeze([new Bootstrap.Core.Tuple(Symbol.for('something'), 0)]); - }), Bootstrap.Core.Patterns.clause([Symbol.for('macros')], function() { - return Object.freeze([]); - }), Bootstrap.Core.Patterns.clause([Symbol.for('module')], function() { - return Symbol.for('Elixir.Elephant'); - })).call(this, kind); - }; - - const ul = '#todo-list'; - - const something_else = Bootstrap.Core.Patterns.defmatchgen(Bootstrap.Core.Patterns.clause([], function*() { - return null; - })); - """ - - assert_translation(ex_ast, js_code) - end - - test "translate modules with inner modules" do - ex_ast = quote do - defmodule Animals do - - defmodule Elephant do - defstruct [trunk: true] - end - - def something() do - %Animals.Elephant{} - end - - defp something_else() do - end - - end - end - - js_code = """ - const __struct__ = function(values = {}) { - const allowed_keys = [Symbol.for('trunk')] - - const value_keys = Object.keys(values) - - const every_call_result = value_keys.every(function(key) { - return allowed_keys.includes(key); - }) - - if (every_call_result) { - return Object.assign({}, { - [Symbol.for('__struct__')]: Symbol.for('Elixir.Animals.Elephant'), - [Symbol.for('trunk')]: true - }, values); - } else { - throw 'Unallowed key found'; - } - }; - """ - - assert_translation(ex_ast, js_code) - end - - - test "translate modules with inner module that has inner module" do - ex_ast = quote do - defmodule Animals do - - defmodule Elephant do - defstruct trunk: true - - defmodule Bear do - defstruct trunk: true - end - end - - - def something() do - %Animals.Elephant{} - end - - defp something_else() do - end - - end - end - - js_code = """ - const __struct__ = function(values = {}) { - const allowed_keys = [Symbol.for('trunk')] - - const value_keys = Object.keys(values) - - const every_call_result = value_keys.every(function(key) { - return allowed_keys.includes(key); - }) - - if (every_call_result) { - return Object.assign({}, { - [Symbol.for('__struct__')]: Symbol.for('Elixir.Animals.Elephant.Bear'), - [Symbol.for('trunk')]: true - }, values); - } else { - throw 'Unallowed key found'; - } - }; - """ - - assert_translation(ex_ast, js_code) - end - - test "Pull out module references and make them into imports if modules listed" do - ex_ast = quote do - defmodule Lions.Tigers.Bears do - def oh_my() do - end - end - - defmodule Lions.Tigers do - def oh_my() do - end - - Lions.Tigers.Bears.oh_my() - end - - defmodule Animals do - Lions.Tigers.oh_my() - end - end - - js_code = """ - Elixir.Lions.Tigers.Bears.__load(Elixir).oh_my() - """ - - assert_translation(ex_ast, js_code) - end - -end diff --git a/test/translator/for_test.exs b/test/translator/for_test.exs deleted file mode 100644 index 60fda4e7..00000000 --- a/test/translator/for_test.exs +++ /dev/null @@ -1,202 +0,0 @@ -defmodule ElixirScript.Translator.For.Test do - use ExUnit.Case - import ElixirScript.TestHelper - - test "translate simple for" do - ex_ast = quote do - for n <- [1, 2, 3, 4], do: n * 2 - end - - js_code = """ - Bootstrap.Core.SpecialForms._for(Bootstrap.Core.Patterns.clause([Bootstrap.Core.Patterns.variable()], function(n) { - return n * 2; - }, function() { - return true; - }), [Bootstrap.Core.Patterns.list_generator(Bootstrap.Core.Patterns.variable(), Object.freeze([1, 2, 3, 4]))], Elixir.ElixirScript.Collectable.__load(Elixir), Object.freeze([])) - """ - - assert_translation(ex_ast, js_code) - end - - test "translate simple for with into" do - ex_ast = quote do - for n <- [1, 2, 3, 4], into: [], do: n * 2 - end - - js_code = """ - Bootstrap.Core.SpecialForms._for( - Bootstrap.Core.Patterns.clause( - [Bootstrap.Core.Patterns.variable()], - function(n) { - return n * 2; - }, - function() { - return true; - } - ), - [ - Bootstrap.Core.Patterns.list_generator( - Bootstrap.Core.Patterns.variable(), - Object.freeze([1, 2, 3, 4]) - ) - ], - Elixir.ElixirScript.Collectable.__load(Elixir), - Object.freeze([]) - ) - """ - - assert_translation(ex_ast, js_code) - end - - test "translate multiple generator for" do - ex_ast = quote do - for x <- [1, 2], y <- [2, 3], do: x*y - end - - js_code = """ - Bootstrap.Core.SpecialForms._for( - Bootstrap.Core.Patterns.clause( - [Bootstrap.Core.Patterns.variable(), Bootstrap.Core.Patterns.variable()], - function(x, y) { - return x * y; - }, - function() { - return true; - } - ), - [ - Bootstrap.Core.Patterns.list_generator( - Bootstrap.Core.Patterns.variable(), - Object.freeze([1, 2]) - ), - Bootstrap.Core.Patterns.list_generator( - Bootstrap.Core.Patterns.variable(), - Object.freeze([2, 3]) - ) - ], - Elixir.ElixirScript.Collectable.__load(Elixir), - Object.freeze([]) - ) - """ - - assert_translation(ex_ast, js_code) - end - - test "translate multiple generator for, assignment, and do block" do - ex_ast = quote do - r = for x <- [1, 2], y <- [2, 3] do - x*y - end - end - - js_code = """ - let [r] = Bootstrap.Core.Patterns.match( - Bootstrap.Core.Patterns.variable(), - Bootstrap.Core.SpecialForms._for( - Bootstrap.Core.Patterns.clause( - [Bootstrap.Core.Patterns.variable(), Bootstrap.Core.Patterns.variable()], - function(x, y) { - return x * y; - }, - function() { - return true; - } - ), - [ - Bootstrap.Core.Patterns.list_generator( - Bootstrap.Core.Patterns.variable(), - Object.freeze([1, 2]) - ), - Bootstrap.Core.Patterns.list_generator( - Bootstrap.Core.Patterns.variable(), - Object.freeze([2, 3]) - ) - ], - Elixir.ElixirScript.Collectable.__load(Elixir), - Object.freeze([]) - ) - ); - """ - - assert_translation(ex_ast, js_code) - end - - test "translate for with filter" do - ex_ast = quote do - for n <- [1, 2, 3, 4, 5, 6], rem(n, 2) == 0, do: n - end - - js_code = """ - Bootstrap.Core.SpecialForms._for( - Bootstrap.Core.Patterns.clause( - [Bootstrap.Core.Patterns.variable()], - function(n) { - return n; - }, - function(n) { - return n % 2 == 0; - } - ), - [ - Bootstrap.Core.Patterns.list_generator( - Bootstrap.Core.Patterns.variable(), - Object.freeze([1, 2, 3, 4, 5, 6]) - ) - ], - Elixir.ElixirScript.Collectable.__load(Elixir), - Object.freeze([]) - ) - """ - - assert_translation(ex_ast, js_code) - end - - test "translate for with pattern matched input" do - ex_ast = quote do - for {:user, name} <- [user: "john", admin: "john", user: "meg"] do - Elixir.String.upcase(name) - end - end - - js_code = """ - Bootstrap.Core.SpecialForms._for(Bootstrap.Core.Patterns.clause([new Bootstrap.Core.Tuple(Symbol.for('user'), Bootstrap.Core.Patterns.variable())], function(name) { - return Elixir.ElixirScript.String.__load(Elixir).upcase(name); - }, function() { - return true; - }), [Bootstrap.Core.Patterns.list_generator(new Bootstrap.Core.Tuple(Symbol.for('user'), Bootstrap.Core.Patterns.variable()), Object.freeze([new Bootstrap.Core.Tuple(Symbol.for('user'), 'john'), new Bootstrap.Core.Tuple(Symbol.for('admin'), 'john'), new Bootstrap.Core.Tuple(Symbol.for('user'), 'meg')]))], Elixir.ElixirScript.Collectable.__load(Elixir), Object.freeze([])) - """ - - assert_translation(ex_ast, js_code) - end - - test "translate for with bitstring" do - ex_ast = quote do - pixels = <<1, 2, 3, 4, 5, 6>> - for <> do - {r, g, b} - end - end - - js_code = """ - Bootstrap.Core.SpecialForms._for(Bootstrap.Core.Patterns.clause([Bootstrap.Core.Patterns.bitStringMatch(Bootstrap.Core.BitString.size({ - 'value': Bootstrap.Core.Patterns.variable() - }, 8), Bootstrap.Core.BitString.size({ - 'value': Bootstrap.Core.Patterns.variable() - }, 8), Bootstrap.Core.BitString.size({ - 'value': Bootstrap.Core.Patterns.variable() - }, 8))], function(r, g, b) { - return new Bootstrap.Core.Tuple(r, g, b); - }, function() { - return true; - }), [Bootstrap.Core.Patterns.bitstring_generator(Bootstrap.Core.Patterns.bitStringMatch(Bootstrap.Core.BitString.size({ - 'value': Bootstrap.Core.Patterns.variable() - }, 8), Bootstrap.Core.BitString.size({ - 'value': Bootstrap.Core.Patterns.variable() - }, 8), Bootstrap.Core.BitString.size({ - 'value': Bootstrap.Core.Patterns.variable() - }, 8)), pixels)], Elixir.ElixirScript.Collectable.__load(Elixir), Object.freeze([])) - """ - - assert_translation(ex_ast, js_code) - end -end diff --git a/test/translator/function_test.exs b/test/translator/function_test.exs deleted file mode 100644 index eb9e145e..00000000 --- a/test/translator/function_test.exs +++ /dev/null @@ -1,815 +0,0 @@ -defmodule ElixirScript.Translator.Function.Test do - use ExUnit.Case - import ElixirScript.TestHelper - - test "translate functions" do - ex_ast = quote do - def test1() do - end - end - - js_code = """ - const test1 = Bootstrap.Core.Patterns.defmatch(Bootstrap.Core.Patterns.clause([],function() { - return null; - })); - """ - - assert_translation(ex_ast, js_code) - - ex_ast = quote do - def test1(alpha, beta) do - end - end - - js_code = """ - const test1 = Bootstrap.Core.Patterns.defmatch(Bootstrap.Core.Patterns.clause([Bootstrap.Core.Patterns.variable(), Bootstrap.Core.Patterns.variable()],function(alpha,beta) { - return null; - })); - """ - - assert_translation(ex_ast, js_code) - - ex_ast = quote do - def test1(alpha, beta) do - a = alpha - end - end - - js_code = """ - const test1 = Bootstrap.Core.Patterns.defmatch(Bootstrap.Core.Patterns.clause([Bootstrap.Core.Patterns.variable(), Bootstrap.Core.Patterns.variable()],function(alpha,beta) { - let [a] = Bootstrap.Core.Patterns.match(Bootstrap.Core.Patterns.variable(),alpha); - return a; - })); - """ - - assert_translation(ex_ast, js_code) - - ex_ast = quote do - def test1(alpha, beta) do - if 1 == 1 do - 1 - else - 2 - end - end - end - - js_code = """ - const test1 = Bootstrap.Core.Patterns.defmatch(Bootstrap.Core.Patterns.clause([Bootstrap.Core.Patterns.variable(), Bootstrap.Core.Patterns.variable()],function(alpha,beta) { - return Bootstrap.Core.Patterns.defmatch(Bootstrap.Core.Patterns.clause([Bootstrap.Core.Patterns.variable()],function(x) { - return 2; - },function(x) { - return x === null || x === false; - }),Bootstrap.Core.Patterns.clause([Bootstrap.Core.Patterns.variable()],function(__ignored__) { - return 1; - })).call(this,1 == 1); - })); - """ - - assert_translation(ex_ast, js_code) - - ex_ast = quote do - def test1(alpha, beta) do - if 1 == 1 do - if 2 == 2 do - 4 - else - a = 1 - end - else - 2 - end - end - end - - js_code = """ - const test1 = Bootstrap.Core.Patterns.defmatch(Bootstrap.Core.Patterns.clause([Bootstrap.Core.Patterns.variable(), Bootstrap.Core.Patterns.variable()], function(alpha, beta) { - return Bootstrap.Core.Patterns.defmatch(Bootstrap.Core.Patterns.clause([Bootstrap.Core.Patterns.variable()], function(x) { - return 2; - }, function(x) { - return x === null || x === false; - }), Bootstrap.Core.Patterns.clause([Bootstrap.Core.Patterns.variable()], function(__ignored__) { - return Bootstrap.Core.Patterns.defmatch(Bootstrap.Core.Patterns.clause([Bootstrap.Core.Patterns.variable()], function(x) { - let [a] = Bootstrap.Core.Patterns.match(Bootstrap.Core.Patterns.variable(), 1); - - return a; - }, function(x) { - return x === null || x === false; - }), Bootstrap.Core.Patterns.clause([Bootstrap.Core.Patterns.variable()], function(__ignored__1) { - return 4; - })).call(this, 2 == 2); - })).call(this, 1 == 1); - })); - """ - - assert_translation(ex_ast, js_code) - - ex_ast = quote do - def test1(alpha, beta) do - {a, b} = {1, 2} - end - end - - js_code = """ - const test1 = Bootstrap.Core.Patterns.defmatch(Bootstrap.Core.Patterns.clause([Bootstrap.Core.Patterns.variable(), Bootstrap.Core.Patterns.variable()], function(alpha, beta) { - let [a, b] = Bootstrap.Core.Patterns.match(new Bootstrap.Core.Tuple(Bootstrap.Core.Patterns.variable(), Bootstrap.Core.Patterns.variable()), new Bootstrap.Core.Tuple(1, 2)); - - let _ref = new Bootstrap.Core.Tuple(a, b); - - return _ref; - })); - """ - - assert_translation(ex_ast, js_code) - end - - test "translate function calls" do - ex_ast = quote do - defmodule Taco do - def test1() do - end - end - - - Taco.test1() - end - - js_code = "Elixir.Taco.__load(Elixir).test1()" - - assert_translation(ex_ast, js_code) - - ex_ast = quote do - defmodule Taco do - def test1(a, b) do - end - end - - Taco.test1(3, 2) - end - - js_code = "Elixir.Taco.__load(Elixir).test1(3,2)" - - assert_translation(ex_ast, js_code) - - ex_ast = quote do - defmodule Taco do - def test1(a, b) do - end - - def test2(a) do - end - end - - Taco.test1(Taco.test2(1), 2) - end - - js_code = "Elixir.Taco.__load(Elixir).test1(Elixir.Taco.__load(Elixir).test2(1), 2)" - - assert_translation(ex_ast, js_code) - end - - - test "translate anonymous functions" do - ex_ast = quote do - list = [] - Enum.map(list, fn(x) -> x * 2 end) - end - - js_code = """ - Elixir.ElixirScript.Enum.__load(Elixir).map(list,Bootstrap.Core.Patterns.defmatch(Bootstrap.Core.Patterns.clause([Bootstrap.Core.Patterns.variable()],function(x) { - return x * 2; - }))) - """ - - assert_translation(ex_ast, js_code) - end - - test "translate function arity" do - ex_ast = quote do - defmodule Example do - - defp example() do - end - - defp example(oneArg) do - end - - defp example(oneArg, twoArg) do - end - - defp example(oneArg, twoArg, redArg) do - end - - defp example(oneArg, twoArg, redArg, blueArg) do - end - end - end - - js_code = """ - const example = Bootstrap.Core.Patterns.defmatch(Bootstrap.Core.Patterns.clause([],function() { - return null; - }),Bootstrap.Core.Patterns.clause([Bootstrap.Core.Patterns.variable()],function(oneArg) { - return null; - }),Bootstrap.Core.Patterns.clause([Bootstrap.Core.Patterns.variable(), Bootstrap.Core.Patterns.variable()],function(oneArg,twoArg) { - return null; - }),Bootstrap.Core.Patterns.clause([Bootstrap.Core.Patterns.variable(), Bootstrap.Core.Patterns.variable(), Bootstrap.Core.Patterns.variable()],function(oneArg,twoArg,redArg) { - return null; - }),Bootstrap.Core.Patterns.clause([Bootstrap.Core.Patterns.variable(), Bootstrap.Core.Patterns.variable(), Bootstrap.Core.Patterns.variable(), Bootstrap.Core.Patterns.variable()],function(oneArg,twoArg,redArg,blueArg) { - return null; - })); - """ - assert_translation(ex_ast, js_code) - - - ex_ast = quote do - defmodule Example do - def example() do - end - - def example(oneArg) do - end - - def example(oneArg, twoArg) do - end - - def example(oneArg, twoArg, redArg) do - end - - def example(oneArg, twoArg, redArg, blueArg) do - end - end - end - - js_code = """ - const example = Bootstrap.Core.Patterns.defmatch(Bootstrap.Core.Patterns.clause([],function() { - return null; - }),Bootstrap.Core.Patterns.clause([Bootstrap.Core.Patterns.variable()],function(oneArg) { - return null; - }),Bootstrap.Core.Patterns.clause([Bootstrap.Core.Patterns.variable(), Bootstrap.Core.Patterns.variable()],function(oneArg,twoArg) { - return null; - }),Bootstrap.Core.Patterns.clause([Bootstrap.Core.Patterns.variable(), Bootstrap.Core.Patterns.variable(), Bootstrap.Core.Patterns.variable()],function(oneArg,twoArg,redArg) { - return null; - }),Bootstrap.Core.Patterns.clause([Bootstrap.Core.Patterns.variable(), Bootstrap.Core.Patterns.variable(), Bootstrap.Core.Patterns.variable(), Bootstrap.Core.Patterns.variable()],function(oneArg,twoArg,redArg,blueArg) { - return null; - })); - """ - assert_translation(ex_ast, js_code) - - - ex_ast = quote do - defmodule Example do - def example(oneArg) do - end - end - end - - js_code = """ - const example = Bootstrap.Core.Patterns.defmatch(Bootstrap.Core.Patterns.clause([Bootstrap.Core.Patterns.variable()],function(oneArg) { - return null; - })); - """ - assert_translation(ex_ast, js_code) - - end - - test "test Elixir.Kernel function" do - ex_ast = quote do - is_atom(:atom) - end - - js_code = "Elixir.ElixirScript.Kernel.__load(Elixir).is_atom(Symbol.for('atom'))" - - assert_translation(ex_ast, js_code) - end - - test "guards" do - ex_ast = quote do - def something(one) when is_number(one) do - end - end - - - js_code = """ - const something = Bootstrap.Core.Patterns.defmatch(Bootstrap.Core.Patterns.clause([Bootstrap.Core.Patterns.variable()],function(one) { - return null; - },function(one) { - return Elixir.ElixirScript.Kernel.__load(Elixir).is_number(one); - })); - """ - - assert_translation(ex_ast, js_code) - - - ex_ast = quote do - def something(one) when is_number(one) or is_atom(one) do - end - end - - - js_code = """ - const something = Bootstrap.Core.Patterns.defmatch(Bootstrap.Core.Patterns.clause([Bootstrap.Core.Patterns.variable()],function(one) { - return null; - },function(one) { - return Elixir.ElixirScript.Kernel.__load(Elixir).is_number(one) || Elixir.ElixirScript.Kernel.__load(Elixir).is_atom(one); - })); - """ - - assert_translation(ex_ast, js_code) - - ex_ast = quote do - defp something(one) when is_number(one) or is_atom(one) do - end - end - - - js_code = """ - const something = Bootstrap.Core.Patterns.defmatch(Bootstrap.Core.Patterns.clause([Bootstrap.Core.Patterns.variable()],function(one) { - return null; - },function(one) { - return Elixir.ElixirScript.Kernel.__load(Elixir).is_number(one) || Elixir.ElixirScript.Kernel.__load(Elixir).is_atom(one); - })); - """ - - assert_translation(ex_ast, js_code) - - ex_ast = quote do - defp something(one, two) when one in [1, 2, 3] do - end - end - - - js_code = """ - const something = Bootstrap.Core.Patterns.defmatch(Bootstrap.Core.Patterns.clause([Bootstrap.Core.Patterns.variable(), Bootstrap.Core.Patterns.variable()],function(one,two) { - return null; - },function(one,two) { - return Elixir.ElixirScript.Bootstrap.Functions.__load(Elixir).contains(one,Object.freeze([1, 2, 3])); - })); - """ - - assert_translation(ex_ast, js_code) - - ex_ast = quote do - defmodule Example do - def something(one) when one in [1, 2, 3] do - end - - def something(one) when is_number(one) or is_atom(one) do - end - end - end - - js_code = """ - const something = Bootstrap.Core.Patterns.defmatch(Bootstrap.Core.Patterns.clause([Bootstrap.Core.Patterns.variable()],function(one) { - return null; - },function(one) { - return Elixir.ElixirScript.Bootstrap.Functions.__load(Elixir).contains(one,Object.freeze([1, 2, 3])); - }),Bootstrap.Core.Patterns.clause([Bootstrap.Core.Patterns.variable()],function(one) { - return null; - },function(one) { - return Elixir.ElixirScript.Kernel.__load(Elixir).is_number(one) || Elixir.ElixirScript.Kernel.__load(Elixir).is_atom(one); - })); - """ - assert_translation(ex_ast, js_code) - - end - - test "pattern match function with literal" do - ex_ast = quote do - def something(1) do - end - end - - - js_code = """ - const something = Bootstrap.Core.Patterns.defmatch(Bootstrap.Core.Patterns.clause([1],function() { - return null; - })); - """ - - assert_translation(ex_ast, js_code) - end - - test "pattern match function with list" do - ex_ast = quote do - def something([apple | fruits]) do - end - end - - - js_code = """ - const something = Bootstrap.Core.Patterns.defmatch(Bootstrap.Core.Patterns.clause([Bootstrap.Core.Patterns.headTail(Bootstrap.Core.Patterns.variable(),Bootstrap.Core.Patterns.variable())],function(apple,fruits) { - return null; - })); - """ - - assert_translation(ex_ast, js_code) - end - - test "pattern match function with multiple items in list" do - ex_ast = quote do - def something([apple, pear, banana]) do - end - end - - - js_code = """ - const something = Bootstrap.Core.Patterns.defmatch(Bootstrap.Core.Patterns.clause([Object.freeze([Bootstrap.Core.Patterns.variable(), Bootstrap.Core.Patterns.variable(), Bootstrap.Core.Patterns.variable()])],function(apple,pear,banana) { - return null; - })); - """ - - assert_translation(ex_ast, js_code) - end - - test "pattern match function with tuple" do - ex_ast = quote do - def something({ apple , fruits }) do - end - end - - - js_code = """ - const something = Bootstrap.Core.Patterns.defmatch(Bootstrap.Core.Patterns.clause([new Bootstrap.Core.Tuple(Bootstrap.Core.Patterns.variable(), Bootstrap.Core.Patterns.variable())], function(apple, fruits) { - return null; - })); - """ - - assert_translation(ex_ast, js_code) - end - - test "pattern match function with struct" do - ex_ast = quote do - defmodule AStruct do - defstruct [] - end - - def something(%AStruct{}) do - end - end - - - js_code = """ - const something = Bootstrap.Core.Patterns.defmatch(Bootstrap.Core.Patterns.clause([{ - [Symbol.for('__struct__')]: Symbol.for('Elixir.AStruct') - }], function() { - return null; - })); - """ - - assert_translation(ex_ast, js_code) - end - - test "pattern match function with struct reference" do - ex_ast = quote do - defmodule AStruct do - defstruct [] - end - - def something(%AStruct{} = a) do - end - - end - - js_code = """ - const something = Bootstrap.Core.Patterns.defmatch(Bootstrap.Core.Patterns.clause([Bootstrap.Core.Patterns.capture({ - [Symbol.for('__struct__')]: Symbol.for('Elixir.AStruct') - })], function(a) { - return null; - })); - """ - assert_translation(ex_ast, js_code) - end - - test "pattern match function with map reference" do - ex_ast = quote do - def something(%{ which: 13 } = a) do - end - end - - js_code = """ - const something = Bootstrap.Core.Patterns.defmatch(Bootstrap.Core.Patterns.clause([Bootstrap.Core.Patterns.capture({ - [Symbol.for('which')]: 13 - })],function(a) { - return null; - })); - """ - - assert_translation(ex_ast, js_code) - end - - test "pattern match function with struct decontructed" do - ex_ast = quote do - defmodule AStruct do - defstruct [:key, :key1] - end - - def something(%AStruct{key: value, key1: 2}) do - end - end - - - js_code = """ - const something = Bootstrap.Core.Patterns.defmatch(Bootstrap.Core.Patterns.clause([{ - [Symbol.for('__struct__')]: Symbol.for('Elixir.AStruct'), - [Symbol.for('key')]: Bootstrap.Core.Patterns.variable(), - [Symbol.for('key1')]: 2 - }], function(value) { - return null; - })); - """ - - assert_translation(ex_ast, js_code) - - ex_ast = quote do - defmodule AStruct do - defstruct [:key, :key1] - end - - def something(%AStruct{key: value, key1: 2}) when is_number(value) do - end - end - - - js_code = """ - const something = Bootstrap.Core.Patterns.defmatch(Bootstrap.Core.Patterns.clause([{ - [Symbol.for('__struct__')]: Symbol.for('Elixir.AStruct'), - [Symbol.for('key')]: Bootstrap.Core.Patterns.variable(), - [Symbol.for('key1')]: 2 - }], function(value) { - return null; - }, function(value) { - return Elixir.ElixirScript.Kernel.__load(Elixir).is_number(value); - })); - """ - - assert_translation(ex_ast, js_code) - end - - test "pattern match function with binary part" do - ex_ast = quote do - def something("Bearer " <> token) do - end - end - - - js_code = """ - const something = Bootstrap.Core.Patterns.defmatch(Bootstrap.Core.Patterns.clause([Bootstrap.Core.Patterns.startsWith('Bearer ')],function(token) { - return null; - })); - """ - - assert_translation(ex_ast, js_code) - - ex_ast = quote do - def something("Bearer " <> token, hotel) do - end - end - - - js_code = """ - const something = Bootstrap.Core.Patterns.defmatch(Bootstrap.Core.Patterns.clause([Bootstrap.Core.Patterns.startsWith('Bearer '), Bootstrap.Core.Patterns.variable()],function(token,hotel) { - return null; - })); - """ - - assert_translation(ex_ast, js_code) - - ex_ast = quote do - def something("Bearer " <> token, hotel, 1) do - end - end - - - js_code = """ - const something = Bootstrap.Core.Patterns.defmatch(Bootstrap.Core.Patterns.clause([Bootstrap.Core.Patterns.startsWith('Bearer '), Bootstrap.Core.Patterns.variable(), 1],function(token,hotel) { - return null; - })); - """ - - assert_translation(ex_ast, js_code) - end - - test "combine pattern matched functions of same arity" do - ex_ast = quote do - defmodule Example do - def something(1) do - end - - def something(2) do - end - - def something(one) when is_binary(one) do - end - - def something(one) do - end - end - - end - - - js_code = """ - const something = Bootstrap.Core.Patterns.defmatch(Bootstrap.Core.Patterns.clause([1],function() { - return null; - }),Bootstrap.Core.Patterns.clause([2],function() { - return null; - }),Bootstrap.Core.Patterns.clause([Bootstrap.Core.Patterns.variable()],function(one) { - return null; - },function(one) { - return Elixir.ElixirScript.Kernel.__load(Elixir).is_binary(one); - }),Bootstrap.Core.Patterns.clause([Bootstrap.Core.Patterns.variable()],function(one) { - return null; - })); - """ - - assert_translation(ex_ast, js_code) - - end - - test "translate varible declaration correctly" do - ex_ast = quote do - def test1(alpha, beta) do - a = 1 - a = 2 - end - end - - js_code = """ - const test1 = Bootstrap.Core.Patterns.defmatch(Bootstrap.Core.Patterns.clause([Bootstrap.Core.Patterns.variable(), Bootstrap.Core.Patterns.variable()],function(alpha,beta) { - let [a] = Bootstrap.Core.Patterns.match(Bootstrap.Core.Patterns.variable(),1); - let [a1] = Bootstrap.Core.Patterns.match(Bootstrap.Core.Patterns.variable(),2); - return a1; - })); - """ - - assert_translation(ex_ast, js_code) - - ex_ast = quote do - def test1(alpha, beta) do - a = 1 - a = a - a = 2 - end - end - - js_code = """ - const test1 = Bootstrap.Core.Patterns.defmatch(Bootstrap.Core.Patterns.clause([Bootstrap.Core.Patterns.variable(), Bootstrap.Core.Patterns.variable()],function(alpha,beta) { - let [a] = Bootstrap.Core.Patterns.match(Bootstrap.Core.Patterns.variable(),1); - let [a1] = Bootstrap.Core.Patterns.match(Bootstrap.Core.Patterns.variable(),a); - let [a2] = Bootstrap.Core.Patterns.match(Bootstrap.Core.Patterns.variable(),2); - return a2; - })); - """ - - assert_translation(ex_ast, js_code) - - ex_ast = quote do - def test1(alpha, beta) do - a = 1 - [a, b, c] = [a, 2, 3] - end - end - - js_code = """ - const test1 = Bootstrap.Core.Patterns.defmatch(Bootstrap.Core.Patterns.clause([Bootstrap.Core.Patterns.variable(), Bootstrap.Core.Patterns.variable()],function(alpha,beta) { - let [a] = Bootstrap.Core.Patterns.match(Bootstrap.Core.Patterns.variable(),1); - let [a1,b,c] = Bootstrap.Core.Patterns.match(Object.freeze([Bootstrap.Core.Patterns.variable(), Bootstrap.Core.Patterns.variable(), Bootstrap.Core.Patterns.variable()]),Object.freeze([a, 2, 3])); - let _ref = Object.freeze([a1, b, c]); - return _ref; - })); - """ - - assert_translation(ex_ast, js_code) - end - - test "translate function variables with ? or !" do - ex_ast = quote do - def test1(alpha?, beta!) do - a? = 1 - b! = 2 - end - end - - js_code = """ - const test1 = Bootstrap.Core.Patterns.defmatch(Bootstrap.Core.Patterns.clause([Bootstrap.Core.Patterns.variable(), Bootstrap.Core.Patterns.variable()],function(alpha__qmark__,beta__emark__) { - let [a__qmark__] = Bootstrap.Core.Patterns.match(Bootstrap.Core.Patterns.variable(),1); - let [b__emark__] = Bootstrap.Core.Patterns.match(Bootstrap.Core.Patterns.variable(),2); - return b__emark__; - })); - """ - - assert_translation(ex_ast, js_code) - end - - test "translate function params with defaults" do - ex_ast = quote do - def test1(alpha, beta \\ 0) do - end - end - - js_code = """ - const test1 = Bootstrap.Core.Patterns.defmatch(Bootstrap.Core.Patterns.clause([Bootstrap.Core.Patterns.variable(), Bootstrap.Core.Patterns.variable(0)],function(alpha,beta) { - return null; - })); - """ - - assert_translation(ex_ast, js_code) - - ex_ast = quote do - def test1(alpha \\ fn x -> x end) do - end - end - - js_code = """ - const test1 = Bootstrap.Core.Patterns.defmatch(Bootstrap.Core.Patterns.clause([Bootstrap.Core.Patterns.variable(Bootstrap.Core.Patterns.defmatch(Bootstrap.Core.Patterns.clause([Bootstrap.Core.Patterns.variable()],function(x) { - return x; - })))], - function(alpha) { - return null; - })); - """ - - assert_translation(ex_ast, js_code) - end - - test "def with catch" do - ex_ast = quote do - defp func(param) do - if true do - nil - else - :error - end - catch - :invalid -> :error - end - end - - js_code = """ - const func = Bootstrap.Core.Patterns.defmatch(Bootstrap.Core.Patterns.clause([Bootstrap.Core.Patterns.variable()], - function(param) { - return Bootstrap.Core.SpecialForms._try(function() { - return Bootstrap.Core.Patterns.defmatch(Bootstrap.Core.Patterns.clause([Bootstrap.Core.Patterns.variable()], function(x) { - return Symbol.for('error'); - }, - function(x) { - return x === null || x === false; - }), - Bootstrap.Core.Patterns.clause([Bootstrap.Core.Patterns.variable()], function(__ignored__) { - return null; - })).call(this, true); - }, - null, - Bootstrap.Core.Patterns.defmatch(Bootstrap.Core.Patterns.clause([Symbol.for('invalid')], function() { - return Symbol.for('error'); - })), - null, - null - ); - })); - """ - - assert_translation(ex_ast, js_code) - end - - - test "translate anonymous function with variable bound" do - ex_ast = quote do - key = "test" - fn ^key -> :ok end - end - - js_code = """ - let [key] = Bootstrap.Core.Patterns.match(Bootstrap.Core.Patterns.variable(),'test'); - - Bootstrap.Core.Patterns.defmatch( - Bootstrap.Core.Patterns.clause( - [Bootstrap.Core.Patterns.bound(key)], - function() { - return Symbol.for('ok'); - } - ) - ) - """ - - assert_translation(ex_ast, js_code) - end - - test "multiple when guards" do - ex_ast = quote do - def something(one) when is_number(one) when is_atom(one) do - end - end - - - js_code = """ - const something = Bootstrap.Core.Patterns.defmatch(Bootstrap.Core.Patterns.clause([Bootstrap.Core.Patterns.variable()],function(one) { - return null; - },function(one) { - return Elixir.ElixirScript.Kernel.__load(Elixir).is_number(one) || Elixir.ElixirScript.Kernel.__load(Elixir).is_atom(one); - })); - """ - - assert_translation(ex_ast, js_code) - end -end diff --git a/test/translator/js_test.exs b/test/translator/js_test.exs deleted file mode 100644 index 7dde65f2..00000000 --- a/test/translator/js_test.exs +++ /dev/null @@ -1,55 +0,0 @@ -defmodule ElixirScript.Translator.JS.Test do - use ExUnit.Case - import ElixirScript.TestHelper - - - test "translate global function calls" do - ex_ast = quote do: JS.alert("hi") - js_code = "Bootstrap.Core.global.alert('hi')" - - assert_translation(ex_ast, js_code) - - ex_ast = quote do: JS.back() - js_code = "Bootstrap.Core.Functions.call_property(Bootstrap.Core.global, 'back')" - - assert_translation(ex_ast, js_code) - end - - test "translate global properties" do - ex_ast = quote do: JS.length - js_code = "Bootstrap.Core.Functions.call_property(Bootstrap.Core.global, 'length')" - - assert_translation(ex_ast, js_code) - end - - test "translate global module" do - ex_ast = quote do: JS.String.toString() - js_code = "Bootstrap.Core.Functions.call_property(Bootstrap.Core.global.String, 'toString')" - - assert_translation(ex_ast, js_code) - - ex_ast = quote do: JS.String.raw("hi") - js_code = "Bootstrap.Core.global.String.raw('hi')" - - assert_translation(ex_ast, js_code) - - ex_ast = quote do: JS.Something.Other.raw("hi") - js_code = "Bootstrap.Core.global.Something.Other.raw('hi')" - - assert_translation(ex_ast, js_code) - end - - test "translate global lowercase" do - ex_ast = quote do: JS.console.log("hi") - js_code = "Bootstrap.Core.Functions.call_property(Bootstrap.Core.global, 'console').log('hi')" - - assert_translation(ex_ast, js_code) - - ex_ast = quote do: JS.window.length - js_code = "Bootstrap.Core.Functions.call_property(Bootstrap.Core.Functions.call_property(Bootstrap.Core.global, 'window'), 'length')" - - assert_translation(ex_ast, js_code) - end - - -end diff --git a/test/translator/kernel_test.exs b/test/translator/kernel_test.exs deleted file mode 100644 index 2438c7f3..00000000 --- a/test/translator/kernel_test.exs +++ /dev/null @@ -1,89 +0,0 @@ -defmodule ElixirScript.Translator.Kernel.Test do - use ExUnit.Case - import ElixirScript.TestHelper - - test "raise with bitstring" do - ex_ast = quote do - def execute() do - list = [] - raise ArgumentError, "cannot convert list to string. The list must contain only integers, strings or nested such lists; got: #{inspect list}" - end - end - - js_code = """ - throw Elixir.ElixirScript.ArgumentError.__load(Elixir).__struct__(Object.freeze({ - [Symbol.for('message')]: 'cannot convert list to string. The list must contain only integers, strings or nested such lists; got: ' + Elixir.ElixirScript.String.Chars.__load(Elixir).to_string(inspect(list)) - })); - """ - - assert_translation(ex_ast, js_code) - end - - test "raise with string" do - ex_ast = quote do - def execute() do - raise ArgumentError, "cannot convert list to string. The list must contain only integers, strings or nested such lists; got" - end - end - - js_code = """ - throw Elixir.ElixirScript.ArgumentError.__load(Elixir).__struct__(Object.freeze({ - [Symbol.for('message')]: 'cannot convert list to string. The list must contain only integers, strings or nested such lists; got' - })); - """ - - assert_translation(ex_ast, js_code) - end - - test "max" do - ex_ast = quote do - max(1, 2) - end - - js_code = """ - Elixir.ElixirScript.Kernel.__load(Elixir).max(1, 2) - """ - - assert_translation(ex_ast, js_code) - - end - - test "apply/3" do - ex_ast = quote do - apply(Enum, :reverse, [[1, 2, 3]]) - end - - js_code = """ - Elixir.ElixirScript.Kernel.__load(Elixir).apply(Elixir.ElixirScript.Enum, Symbol.for('reverse'), Object.freeze([Object.freeze([1, 2, 3])])) - """ - - assert_translation(ex_ast, js_code) - - end - - test "hd" do - ex_ast = quote do - hd([1, 2, 3]) - end - - js_code = """ - Elixir.ElixirScript.Kernel.__load(Elixir).hd(Object.freeze([1, 2, 3])) - """ - - assert_translation(ex_ast, js_code) - - end - - test "tl" do - ex_ast = quote do - tl([1, 2, 3]) - end - - js_code = """ - Elixir.ElixirScript.Kernel.__load(Elixir).tl(Object.freeze([1, 2, 3])) - """ - - assert_translation(ex_ast, js_code) - - end -end diff --git a/test/translator/list_test.exs b/test/translator/list_test.exs deleted file mode 100644 index 39384bfe..00000000 --- a/test/translator/list_test.exs +++ /dev/null @@ -1,70 +0,0 @@ -defmodule ElixirScript.Translator.List.Test do - use ExUnit.Case - import ElixirScript.TestHelper - - test "translate list" do - ex_ast = quote do: [1, 2, 3] - js_code = "Object.freeze([1, 2, 3])" - - assert_translation(ex_ast, js_code) - - ex_ast = quote do: ["a", "b", "c"] - js_code = "Object.freeze(['a', 'b', 'c'])" - - assert_translation(ex_ast, js_code) - - ex_ast = quote do: [:a, :b, :c] - js_code = "Object.freeze([Symbol.for('a'), Symbol.for('b'), Symbol.for('c')])" - - assert_translation(ex_ast, js_code) - - ex_ast = quote do: [:a, 2, "c"] - js_code = "Object.freeze([Symbol.for('a'), 2, 'c'])" - - assert_translation(ex_ast, js_code) - end - - test "concatenate lists" do - ex_ast = quote do: [1, 2, 3] ++ [4, 5, 6] - js_code = "Object.freeze([1, 2, 3]).concat(Object.freeze([4, 5, 6]))" - - assert_translation(ex_ast, js_code) - - ex_ast = quote do - list = [] - list ++ [4, 5, 6] - end - js_code = "list.concat(Object.freeze([4, 5, 6]))" - - assert_translation(ex_ast, js_code) - end - - test "prepend element" do - ex_ast = quote do - x = 1 - list = [] - [x | list] - end - - js_code = "Object.freeze([x]).concat(list)" - - assert_translation(ex_ast, js_code) - end - - test "prepend element in function" do - ex_ast = quote do - x = 1 - list = [] - - fn (_) -> [x|list] end - end - - js_code = """ - Bootstrap.Core.Patterns.defmatch(Bootstrap.Core.Patterns.clause([Bootstrap.Core.Patterns.variable()],function(__ignored__){ - return Object.freeze([x]).concat(list); - })) - """ - - assert_translation(ex_ast, js_code) - end -end diff --git a/test/translator/map_test.exs b/test/translator/map_test.exs deleted file mode 100644 index 8c49fcb6..00000000 --- a/test/translator/map_test.exs +++ /dev/null @@ -1,87 +0,0 @@ -defmodule ElixirScript.Translator.Map.Test do - use ExUnit.Case - import ElixirScript.TestHelper - - test "translate empty map" do - ex_ast = quote do: %{} - js_code = "Object.freeze({})" - - assert_translation(ex_ast, js_code) - end - - test "translate map with elements" do - ex_ast = quote do: %{one: "one", two: "two"} - js_code = "Object.freeze({[Symbol.for('one')]: 'one', [Symbol.for('two')]: 'two'})" - - assert_translation(ex_ast, js_code) - end - - test "translate map within map" do - ex_ast = quote do: %{one: "one", two: %{three: "three"}} - js_code = """ - Object.freeze({ - [Symbol.for('one')]: 'one', - [Symbol.for('two')]: Object.freeze({ - [Symbol.for('three')]: 'three' - }) - }) - """ - - assert_translation(ex_ast, js_code) - end - - test "translate map with string keys" do - ex_ast = quote do: %{"one" => "one", "two" => "two"} - js_code = """ - Object.freeze({ - one: 'one', two: 'two' - }) - """ - - assert_translation(ex_ast, js_code) - end - - - test "translate map update" do - ex_ast = quote do - map = %{value: 2} - %{ map | value: 1 } - end - - js_code = """ - Object.freeze(Object.assign({}, map, Object.freeze({ - [Symbol.for('value')]: 1 - }))) - """ - - assert_translation(ex_ast, js_code) - end - - test "translate variable key" do - ex_ast = quote do - key = 1 - value = 2 - %{key => value} - end - - js_code = "Object.freeze({ [key]: value })" - assert_translation(ex_ast, js_code) - end - - test "translate bound map key" do - ex_ast = quote do - key = 1 - value = 2 - %{^key => value} = %{key => value} - end - js_code = """ - let [value1] = Bootstrap.Core.Patterns.match({ - [key]: Bootstrap.Core.Patterns.variable() - }, Object.freeze({ - [key]: value - })); - """ - assert_translation(ex_ast, js_code) - end - -end diff --git a/test/translator/match_test.exs b/test/translator/match_test.exs deleted file mode 100644 index 639738f6..00000000 --- a/test/translator/match_test.exs +++ /dev/null @@ -1,84 +0,0 @@ -defmodule ElixirScript.Translator.Match.Test do - use ExUnit.Case - import ElixirScript.TestHelper - - test "translate simple match" do - ex_ast = quote do: a = 1 - js_code = "let [a] = Bootstrap.Core.Patterns.match(Bootstrap.Core.Patterns.variable(), 1);" - - assert_translation(ex_ast, js_code) - - ex_ast = quote do: a = :atom - js_code = "let [a] = Bootstrap.Core.Patterns.match(Bootstrap.Core.Patterns.variable(), Symbol.for('atom'));" - - assert_translation(ex_ast, js_code) - end - - test "translate tuple match" do - ex_ast = quote do - {a, b} = {1, 2} - end - js_code = """ - let [a, b] = Bootstrap.Core.Patterns.match( - new Bootstrap.Core.Tuple( - Bootstrap.Core.Patterns.variable(), - Bootstrap.Core.Patterns.variable() - ), - new Bootstrap.Core.Tuple(1, 2) - ); - """ - - assert_translation(ex_ast, js_code) - - ex_ast = quote do: {a, _, c} = {1, 2, 3} - js_code = """ - let [a, __ignored__, c] = Bootstrap.Core.Patterns.match(new Bootstrap.Core.Tuple(Bootstrap.Core.Patterns.variable(), Bootstrap.Core.Patterns.variable(), Bootstrap.Core.Patterns.variable()), new Bootstrap.Core.Tuple(1, 2, 3)); - """ - - assert_translation(ex_ast, js_code) - - - ex_ast = quote do - a = 1 - {^a, _, c} = {1, 2, 3} - end - js_code = """ - let [, __ignored__, c] = Bootstrap.Core.Patterns.match(new Bootstrap.Core.Tuple(Bootstrap.Core.Patterns.bound(a), Bootstrap.Core.Patterns.variable(), Bootstrap.Core.Patterns.variable()), new Bootstrap.Core.Tuple(1, 2, 3)); - """ - - assert_translation(ex_ast, js_code) - end - - test "translate bound match" do - ex_ast = quote do - a = 1 - ^a = 1 - end - - js_code = """ - let [] = Bootstrap.Core.Patterns.match(Bootstrap.Core.Patterns.bound(a),1); - """ - - assert_translation(ex_ast, js_code) - end - - test "translate list match" do - ex_ast = quote do: [a, b] = [1, 2] - js_code = """ - let [a,b] = Bootstrap.Core.Patterns.match(Object.freeze([Bootstrap.Core.Patterns.variable(), Bootstrap.Core.Patterns.variable()]),Object.freeze([1, 2])); - let _ref = Object.freeze([a, b]); - """ - - assert_translation(ex_ast, js_code) - end - - test "translate head/tail match" do - ex_ast = quote do: [a | b] = [1, 2, 3, 4] - js_code = """ - let [a,b] = Bootstrap.Core.Patterns.match(Bootstrap.Core.Patterns.headTail(Bootstrap.Core.Patterns.variable(),Bootstrap.Core.Patterns.variable()),Object.freeze([1, 2, 3, 4])); - let _ref = Object.freeze([a, b]); - """ - - assert_translation(ex_ast, js_code) - end -end diff --git a/test/translator/nil_test.exs b/test/translator/nil_test.exs deleted file mode 100644 index 4c77bed1..00000000 --- a/test/translator/nil_test.exs +++ /dev/null @@ -1,9 +0,0 @@ -defmodule ElixirScript.Translator.Nil.Test do - use ExUnit.Case - import ElixirScript.TestHelper - - test "translate nil" do - ex_ast = quote do: nil - assert_translation(ex_ast, "null") - end -end diff --git a/test/translator/number_test.exs b/test/translator/number_test.exs deleted file mode 100644 index 6d2fe4f4..00000000 --- a/test/translator/number_test.exs +++ /dev/null @@ -1,18 +0,0 @@ -defmodule ElixirScript.Translator.Number.Test do - use ExUnit.Case - import ElixirScript.TestHelper - - test "translate numbers" do - ex_ast = quote do: 1 - assert_translation(ex_ast, "1") - - ex_ast = quote do: 1_000 - assert_translation(ex_ast, "1000") - - ex_ast = quote do: 1.1 - assert_translation(ex_ast, "1.1") - - ex_ast = quote do: -1.1 - assert_translation(ex_ast, "-1.1") - end -end diff --git a/test/translator/pattern_matching_test.exs b/test/translator/pattern_matching_test.exs deleted file mode 100644 index 75598bc6..00000000 --- a/test/translator/pattern_matching_test.exs +++ /dev/null @@ -1,257 +0,0 @@ -defmodule ElixirScript.Translator.PatternMatching.Test do - use ExUnit.Case - alias ElixirScript.Translator - alias ElixirScript.Translator.Primitive - alias ElixirScript.Translator.PatternMatching - alias ElixirScript.Translator.Map - alias ESTree.Tools.Builder, as: JS - alias ElixirScript.Translator.State - - setup do - {:ok, pid} = State.start_link(%{env: __ENV__}, []) - - State.set_module_data(pid, [{ - ElixirScript.Kernel, - %{app: :elixir, name: ElixirScript.Kernel, ast: {}, functions: []} - }]) - - scope = ElixirScript.Translator.LexicalScope.module_scope( - ElixirScript.Temp, - "temp.ex", - __ENV__, - pid, - %{ format: :es, module_formatter: ElixirScript.ModuleSystems.ES } - ) - - {:ok, [scope: scope]} - end - - test "match wildcard", %{scope: scope} do - params = [{:_, [], Test}] - result = PatternMatching.build_match(params, scope) - expected_result = {[PatternMatching.parameter()], [JS.identifier(:__ignored__)]} - - assert result == expected_result - end - - test "match one identifier param", %{scope: scope} do - params = [{:a, [], Test}] - result = PatternMatching.build_match(params, scope ) - expected_result = {[PatternMatching.parameter], [JS.identifier("a")]} - - assert result == expected_result - end - - test "match multiple identifier params", %{scope: scope} do - params = [{:a, [], Test}, {:b, [], Test}, {:c, [], Test}] - result = PatternMatching.build_match(params, scope ) - expected_result = { - List.duplicate(PatternMatching.parameter, 3), - [JS.identifier("a"), JS.identifier("b"), JS.identifier("c")] - } - - assert result == expected_result - end - - test "match head and tail param", %{scope: scope} do - params = [[{:|, [], [{:head, [], Elixir}, {:tail, [], Elixir}]}]] - result = PatternMatching.build_match(params, scope ) - expected_result = { - [PatternMatching.head_tail(PatternMatching.parameter, PatternMatching.parameter)], - [JS.identifier("head"), JS.identifier("tail")] - } - - assert result == expected_result - end - - test "match prefix param", %{scope: scope} do - params = [{:<>, [context: Elixir, import: Elixir.Kernel], ["Bearer ", {:token, [], Elixir}]}] - result = PatternMatching.build_match(params, scope ) - expected_result = { - [PatternMatching.starts_with("Bearer ")], - [JS.identifier("token")] - } - - assert result == expected_result - end - - test "match list", %{scope: scope} do - params = [[{:a, [], Elixir}, {:b, [], Elixir}, {:c, [], Elixir}]] - result = PatternMatching.build_match(params, scope ) - expected_result = { - [Primitive.make_list_no_translate(List.duplicate(PatternMatching.parameter, 3))], - [JS.identifier("a"), JS.identifier("b"), JS.identifier("c")] - } - - assert result == expected_result - end - - test "match list with a literal", %{scope: scope} do - params = [[1, {:b, [], Elixir}, {:c, [], Elixir}]] - result = PatternMatching.build_match(params, scope ) - expected_result = { - [Primitive.make_list_no_translate([JS.literal(1), PatternMatching.parameter, PatternMatching.parameter])], - [JS.identifier("b"), JS.identifier("c")] - } - - assert result == expected_result - end - - test "match number", %{scope: scope} do - params = [1] - result = PatternMatching.build_match(params, scope ) - expected_result = { - [JS.literal(1)], - [] - } - - assert result == expected_result - end - - test "match struct pattern", %{scope: scope} do - params = [{:%, [], [{:__aliases__, [alias: false], [:Hello]}, {:%{}, [], []}]}] - result = PatternMatching.build_match(params, scope ) - expected_result = { - [JS.object_expression([ - JS.property(Primitive.make_atom(:__struct__), - Primitive.make_atom(Hello), - :init, false, false, true), - ])], - [] - } - - assert result == expected_result - end - - test "match struct pattern with property", %{scope: scope} do - params = [{:%, [], [{:__aliases__, [alias: false], [:Hello]}, {:%{}, [], [key: 1]}]}] - result = PatternMatching.build_match(params, scope ) - expected_result = { - [JS.object_expression([ - JS.property(Primitive.make_atom(:__struct__), - Primitive.make_atom(Hello), - :init, false, false, true), - Map.make_property(Translator.translate!(:key, scope ), Translator.translate!(1, scope)) - ])], - [] - } - - assert result == expected_result - end - - test "match struct pattern with property param", %{scope: scope} do - params = [{:%, [], [{:__aliases__, [alias: false], [:Hello]}, {:%{}, [], [key: {:key, [], Elixir}]}]}] - result = PatternMatching.build_match(params, scope ) - expected_result = { - [JS.object_expression([ - JS.property(Primitive.make_atom(:__struct__), - Primitive.make_atom(Hello), - :init, false, false, true), - Map.make_property(Translator.translate!(:key, scope ), PatternMatching.parameter()) - ])], - [JS.identifier("key")] - } - - assert result == expected_result - end - - test "capture parameter when assigning it", %{scope: scope} do - params = [{:=, [], [1, {:a, [], Elixir}]}] - result = PatternMatching.build_match(params, scope ) - expected_result = { - [PatternMatching.capture(JS.literal(1))], - [JS.identifier("a")] - } - - assert result == expected_result - - - params = [{:=, [], [{:a, [], Elixir}, 1]}] - result = PatternMatching.build_match(params, scope ) - expected_result = { - [PatternMatching.capture(JS.literal(1))], - [JS.identifier("a")] - } - - assert result == expected_result - - - params = [{:=, [], [{:%, [], [{:__aliases__, [alias: false], [:AStruct]}, {:%{}, [], []}]}, {:a, [], ElixirScript.Translator.Function.Test}]}] - result = PatternMatching.build_match(params, scope ) - expected_result = { - [PatternMatching.capture(JS.object_expression([ - JS.property(Primitive.make_atom(:__struct__), - Primitive.make_atom(AStruct), - :init, false, false, true), - ]))], - [JS.identifier("a")] - } - - assert result == expected_result - end - - test "match and assign list", %{scope: scope} do - params = [{:=, [], [[{:a, [], Elixir}, {:b, [], Elixir}, {:c, [], Elixir}], {:d, [], Elixir}]}] - result = PatternMatching.build_match(params, scope ) - expected_result = { - [PatternMatching.capture(Primitive.make_list_no_translate([PatternMatching.parameter, PatternMatching.parameter, PatternMatching.parameter]))], - [JS.identifier("a"), JS.identifier("b"), JS.identifier("c"), JS.identifier("d")] - } - - assert result == expected_result - end - - test "match on tuple", %{scope: scope} do - params = [{:{}, [], [1, {:b, [], Elixir}, 3]}] - result = PatternMatching.build_match(params, scope ) - expected_result = { - [JS.new_expression( - Primitive.tuple_class(), - [JS.literal(1), PatternMatching.parameter, JS.literal(3)] - )], - [JS.identifier("b")] - } - - assert result == expected_result - - params = [{1, {:b, [], Elixir}}] - result = PatternMatching.build_match(params, scope ) - expected_result = { - [JS.new_expression( - Primitive.tuple_class(), - [JS.literal(1), PatternMatching.parameter] - )], - [JS.identifier("b")] - } - - assert result == expected_result - end - - test "match on map", %{scope: scope} do - params = [{:%{}, [], [which: 13]}] - result = PatternMatching.build_match(params, scope ) - - expected_result = { - [JS.object_expression([ - Map.make_property(Translator.translate!(:which, scope ), JS.literal(13)) - ])], - [] - } - - assert result == expected_result - end - - - test "match on bound value", %{scope: scope} do - params = [{:^, [], [{:a, [], Elixir}]}] - result = PatternMatching.build_match(params, scope ) - - expected_result = { - [PatternMatching.bound(JS.identifier("a"))], - [nil] - } - - assert result == expected_result - end - -end diff --git a/test/translator/quote_test.exs b/test/translator/quote_test.exs deleted file mode 100644 index 2728ea69..00000000 --- a/test/translator/quote_test.exs +++ /dev/null @@ -1,142 +0,0 @@ -defmodule ElixirScript.Translator.Quote.Test do - use ExUnit.Case - import ElixirScript.TestHelper - - test "quote number" do - ex_ast = quote do - quote do: 1 - end - - js_code = "1" - - assert_translation(ex_ast, js_code) - end - - test "quote atom" do - ex_ast = quote do - quote do: :time - end - - js_code = "Symbol.for('time')" - - assert_translation(ex_ast, js_code) - end - - - test "quote 2 element tuple" do - ex_ast = quote do - quote do: {1, 2} - end - - js_code = "new Bootstrap.Core.Tuple(1, 2)" - - assert_translation(ex_ast, js_code) - end - - - test "quote 3 element tuple" do - ex_ast = quote do - quote do: {1, 2, 3} - end - - js_code = "new Bootstrap.Core.Tuple(Symbol.for('{}'), Object.freeze([]), Object.freeze([1, 2, 3]))" - - assert_translation(ex_ast, js_code) - end - - - test "quote function call" do - ex_ast = quote do - quote do: test(1) - end - - js_code = """ - new Bootstrap.Core.Tuple( - Symbol.for('test'), - Object.freeze([new Bootstrap.Core.Tuple(Symbol.for('context'),Symbol.for('Elixir.ElixirScript.Translator.Quote.Test')), new Bootstrap.Core.Tuple(Symbol.for('import'),Symbol.for('Elixir.ExUnit.Case'))]),Object.freeze([1]) - ) - """ - - assert_translation(ex_ast, js_code) - end - - - test "quote function with variable" do - ex_ast = quote do - quote do: test(x) - end - - js_code = """ - new Bootstrap.Core.Tuple( - Symbol.for('test'), - Object.freeze([new Bootstrap.Core.Tuple(Symbol.for('context'), Symbol.for('Elixir.ElixirScript.Translator.Quote.Test')), new Bootstrap.Core.Tuple(Symbol.for('import'),Symbol.for('Elixir.ExUnit.Case'))]),Object.freeze([new Bootstrap.Core.Tuple(Symbol.for('x'),Object.freeze([]),Symbol.for('Elixir.ElixirScript.Translator.Quote.Test'))])) - """ - - assert_translation(ex_ast, js_code) - end - - - test "quote function call with unquote" do - ex_ast = quote do - x = 1 - quote do: test(unquote(x)) - end - - js_code = """ - new Bootstrap.Core.Tuple( - Symbol.for('test'), - Object.freeze([new Bootstrap.Core.Tuple(Symbol.for('context'),Symbol.for('Elixir.ElixirScript.Translator.Quote.Test')), new Bootstrap.Core.Tuple(Symbol.for('import'),Symbol.for('Elixir.ExUnit.Case'))]),Object.freeze([x]) - ) - """ - - assert_translation(ex_ast, js_code) - end - - - test "quote function call with unquote_slicing" do - ex_ast = quote do - quote do: sum(1, unquote_splicing([1, 2, 3]), 5) - end - - js_code = """ - new Bootstrap.Core.Tuple(Symbol.for('sum'), Object.freeze([]), Bootstrap.Enum.concat(Object.freeze([1]), Object.freeze([1, 2, 3]), Object.freeze([5]))) - """ - - assert_translation(ex_ast, js_code) - end - - test "bind_quoted" do - ex_ast = quote do - x = 1 - quote bind_quoted: [x: x] do - x * x - end - end - - js_code = """ - new Bootstrap.Core.Tuple( - Symbol.for('*'), - Object.freeze([new Bootstrap.Core.Tuple(Symbol.for('context'), Symbol.for('Elixir.ElixirScript.Translator.Quote.Test')), new Bootstrap.Core.Tuple(Symbol.for('import'),Symbol.for('Elixir.ElixirScript.Kernel'))]),Object.freeze([x, x]) - ) - """ - - assert_translation(ex_ast, js_code) - end - - test "quote with context option" do - ex_ast = quote do - quote context: Elixir do - test(1) - end - end - - js_code = """ - new Bootstrap.Core.Tuple( - Symbol.for('test'), - Object.freeze([new Bootstrap.Core.Tuple(Symbol.for('context'),Symbol.for('Elixir')), new Bootstrap.Core.Tuple(Symbol.for('import'),Symbol.for('Elixir.ExUnit.Case'))]),Object.freeze([1]) - ) - """ - - assert_translation(ex_ast, js_code) - end -end diff --git a/test/translator/string_test.exs b/test/translator/string_test.exs deleted file mode 100644 index 3eb79606..00000000 --- a/test/translator/string_test.exs +++ /dev/null @@ -1,43 +0,0 @@ -defmodule ElixirScript.Translator.String.Test do - use ExUnit.Case - import ElixirScript.TestHelper - - test "translate string" do - ex_ast = quote do: "Hello" - assert_translation(ex_ast, "'Hello'") - end - - test "translate multiline string" do - ex_ast = quote do: """ - Hello - This is another line - """ - assert_translation(ex_ast, "'Hello\\nThis is another line\\n'") - end - - test "translate string concatenation" do - ex_ast = quote do: "Hello" <> "World" - assert_translation(ex_ast, "'Hello' + 'World'") - end - - test "translate string interpolation" do - ex_ast = quote do: "Hello #{"world"}" - assert_translation(ex_ast, "'Hello ' + Elixir.ElixirScript.String.Chars.__load(Elixir).to_string('world')") - - ex_ast = quote do: "Hello #{length([])}" - assert_translation(ex_ast, "'Hello ' + Elixir.ElixirScript.String.Chars.__load(Elixir).to_string(Elixir.ElixirScript.Kernel.__load(Elixir).length(Object.freeze([])))") - end - - test "translate multiline string interpolation" do - ex_ast = quote do: """ - Hello #{length([])} - """ - assert_translation(ex_ast, "'Hello ' + (Elixir.ElixirScript.String.Chars.__load(Elixir).to_string(Elixir.ElixirScript.Kernel.__load(Elixir).length(Object.freeze([]))) + '\\n')") - - ex_ast = quote do: """ - Hello #{length([])} - How are you, #{length([])}? - """ - assert_translation(ex_ast, "'Hello ' + (Elixir.ElixirScript.String.Chars.__load(Elixir).to_string(Elixir.ElixirScript.Kernel.__load(Elixir).length(Object.freeze([]))) + ('\\nHow are you, ' + (Elixir.ElixirScript.String.Chars.__load(Elixir).to_string(Elixir.ElixirScript.Kernel.__load(Elixir).length(Object.freeze([]))) + '?\\n')))") - end -end diff --git a/test/translator/struct_test.exs b/test/translator/struct_test.exs deleted file mode 100644 index b562a050..00000000 --- a/test/translator/struct_test.exs +++ /dev/null @@ -1,233 +0,0 @@ -defmodule ElixirScript.Translator.Struct.Test do - use ExUnit.Case - import ElixirScript.TestHelper - - test "translate struct with default values" do - ex_ast = quote do - defmodule User do - defstruct name: "john", age: 27 - end - end - - js_code = """ - const __struct__ = function(values = {}) { - const allowed_keys = [Symbol.for('name'), Symbol.for('age')] - - const value_keys = Object.keys(values) - - const every_call_result = value_keys.every(function(key) { - return allowed_keys.includes(key); - }) - - if (every_call_result) { - return Object.assign({}, { - [Symbol.for('__struct__')]: Symbol.for('Elixir.User'), - [Symbol.for('name')]: 'john', - [Symbol.for('age')]: 27 - }, values); - } else { - throw 'Unallowed key found'; - } - }; - """ - - assert_translation(ex_ast, js_code) - end - - test "translate struct without default values" do - - ex_ast = quote do - defmodule User do - defstruct [:name, :age] - end - end - - js_code = """ - const __struct__ = function(values = {}) { - const allowed_keys = [Symbol.for('name'), Symbol.for('age')] - - const value_keys = Object.keys(values) - - const every_call_result = value_keys.every(function(key) { - return allowed_keys.includes(key); - }) - - if (every_call_result) { - return Object.assign({}, { - [Symbol.for('__struct__')]: Symbol.for('Elixir.User'), - [Symbol.for('name')]: null, - [Symbol.for('age')]: null - }, values); - } else { - throw 'Unallowed key found'; - } - }; - """ - - assert_translation(ex_ast, js_code) - - end - - test "translate struct creation" do - ex_ast = quote do - defmodule User do - defstruct [:name, :age] - end - - user = %User{} - end - - js_code = """ - Elixir.User.__load(Elixir).__struct__(Object.freeze({}) - """ - - assert_translation(ex_ast, js_code) - - ex_ast = quote do - defmodule User do - defstruct [:name, :age] - end - - user = %User{name: "John"} - end - - js_code = """ - Elixir.User.__load(Elixir).__struct__(Object.freeze({[Symbol.for('name')]: 'John'}) - """ - - assert_translation(ex_ast, js_code) - end - - test "translate struct update" do - ex_ast = quote do - map = %{key: nil} - user = %{ map | key: 1 } - end - - js_code = """ - let [user] = Bootstrap.Core.Patterns.match(Bootstrap.Core.Patterns.variable(), Object.freeze(Object.assign({}, map, Object.freeze({ - [Symbol.for('key')]: 1 - })))); - """ - - assert_translation(ex_ast, js_code) - - - ex_ast = quote do - map = %{key: nil, key1: nil} - user = %{ map | key: 1, key1: 11 } - end - - js_code = """ - let [user] = Bootstrap.Core.Patterns.match(Bootstrap.Core.Patterns.variable(), Object.freeze(Object.assign({}, map, Object.freeze({ - [Symbol.for('key')]: 1, - [Symbol.for('key1')]: 11 - })))); - """ - - assert_translation(ex_ast, js_code) - end - - test "translate defexception" do - ex_ast = quote do - defmodule MyAppError do - defexception message: "This is a message" - end - end - - js_code = """ - const __struct__ = function(values = {}) { - const allowed_keys = [Symbol.for('message'), Symbol.for('__exception__')] - - const value_keys = Object.keys(values) - - const every_call_result = value_keys.every(function(key) { - return allowed_keys.includes(key); - }) - - if (every_call_result) { - return Object.assign({}, { - [Symbol.for('__struct__')]: Symbol.for('Elixir.MyAppError'), - [Symbol.for('message')]: 'This is a message', - [Symbol.for('__exception__')]: true - }, values); - } else { - throw 'Unallowed key found'; - } - }; - """ - - assert_translation(ex_ast, js_code) - - ex_ast = quote do - defmodule MyAppError do - defexception [:message] - end - end - - js_code = """ - const __struct__ = function(values = {}) { - const allowed_keys = [Symbol.for('message'), Symbol.for('__exception__')] - - const value_keys = Object.keys(values) - - const every_call_result = value_keys.every(function(key) { - return allowed_keys.includes(key); - }) - - if (every_call_result) { - return Object.assign({}, { - [Symbol.for('__struct__')]: Symbol.for('Elixir.MyAppError'), - [Symbol.for('message')]: null, - [Symbol.for('__exception__')]: true - }, values); - } else { - throw 'Unallowed key found'; - } - }; - """ - - assert_translation(ex_ast, js_code) - - end - - test "translate raise exception" do - ex_ast = quote do - defmodule MyAppError do - defexception [:message] - - def do_it() do - raise MyAppError, message: "did not get what was expected" - end - - end - end - - js_code = """ - throw Elixir.MyAppError.__load(Elixir).__struct__(Object.freeze({ - [Symbol.for('message')]: 'did not get what was expected' - })); - """ - - assert_translation(ex_ast, js_code) - - - ex_ast = quote do - def do_it() do - raise "did not get what was expected" - end - - end - - js_code = """ - throw { - [Symbol.for('__struct__')]: Symbol.for('RuntimeError'), - [Symbol.for('__exception__')]: true, - [Symbol.for('message')]: 'did not get what was expected' - }; - """ - - assert_translation(ex_ast, js_code) - - end -end diff --git a/test/translator/try_test.exs b/test/translator/try_test.exs deleted file mode 100644 index f8728b61..00000000 --- a/test/translator/try_test.exs +++ /dev/null @@ -1,231 +0,0 @@ -defmodule ElixirScript.Translator.Try.Test do - use ExUnit.Case - import ElixirScript.TestHelper - - test "translate with a rescue with one match" do - ex_ast = quote do - try do - 1 - rescue - ArgumentError -> - IO.puts "Invalid argument given" - end - end - - js_code = """ - Bootstrap.Core.SpecialForms._try(function() { - return 1; - }, Bootstrap.Core.Patterns.defmatch(Bootstrap.Core.Patterns.clause([{ - [Symbol.for('__struct__')]: Symbol.for('Elixir.ElixirScript.ArgumentError') - }], function() { - return Elixir.ElixirScript.IO.__load(Elixir).puts('Invalid argument given'); - })), null, null, null) - """ - - assert_translation(ex_ast, js_code) - end - - test "translate with a rescue with a list match" do - ex_ast = quote do - - try do - 1 - rescue - [ArgumentError] -> - IO.puts "Invalid argument given" - end - end - - js_code = """ - Bootstrap.Core.SpecialForms._try(function() { - return 1; - }, Bootstrap.Core.Patterns.defmatch(Bootstrap.Core.Patterns.clause([{ - [Symbol.for('__struct__')]: Symbol.for('Elixir.ElixirScript.ArgumentError') - }], function() { - return Elixir.ElixirScript.IO.__load(Elixir).puts('Invalid argument given'); - })), null, null, null) - """ - - assert_translation(ex_ast, js_code) - end - - test "translate with a rescue with an in guard" do - ex_ast = quote do - - try do - 1 - rescue - x in [ArgumentError] -> - IO.puts "Invalid argument given" - end - end - - js_code = """ - Bootstrap.Core.SpecialForms._try(function() { - return 1; - },Bootstrap.Core.Patterns.defmatch(Bootstrap.Core.Patterns.clause([Bootstrap.Core.Patterns.variable()],function(x) { - return Elixir.ElixirScript.IO.__load(Elixir).puts('Invalid argument given'); - },function(x) { - return Elixir.ElixirScript.Bootstrap.Functions.__load(Elixir).contains(x, Object.freeze([Elixir.ElixirScript.ArgumentError.__load(Elixir).__struct__(Object.freeze({}))])); - })),null,null,null) - """ - - assert_translation(ex_ast, js_code) - end - - test "translate with a rescue with an identifier" do - ex_ast = quote do - - try do - 1 - rescue - x -> - IO.puts "Invalid argument given" - end - end - - js_code = """ - Bootstrap.Core.SpecialForms._try(function() { - return 1; - },Bootstrap.Core.Patterns.defmatch(Bootstrap.Core.Patterns.clause([Bootstrap.Core.Patterns.variable()],function(x) { - return Elixir.ElixirScript.IO.__load(Elixir).puts('Invalid argument given'); - })),null,null,null) - """ - - assert_translation(ex_ast, js_code) - end - - - test "translate with a rescue with multiple patterns" do - ex_ast = quote do - - try do - 1 - rescue - [ArgumentError] -> - IO.puts "ArgumentError" - x -> - IO.puts "x" - end - end - - js_code = """ - Bootstrap.Core.SpecialForms._try(function() { - return 1; - }, Bootstrap.Core.Patterns.defmatch(Bootstrap.Core.Patterns.clause([{ - [Symbol.for('__struct__')]: Symbol.for('Elixir.ElixirScript.ArgumentError') - }], function() { - return Elixir.ElixirScript.IO.__load(Elixir).puts('ArgumentError'); - }), Bootstrap.Core.Patterns.clause([Bootstrap.Core.Patterns.variable()], function(x) { - return Elixir.ElixirScript.IO.__load(Elixir).puts('x'); - })), null, null, null) - """ - - assert_translation(ex_ast, js_code) - end - - test "translate with a rescue and after clause" do - ex_ast = quote do - - try do - 1 - rescue - ArgumentError -> - IO.puts "Invalid argument given" - after - IO.puts "This is printed regardless if it failed or succeed" - end - end - - js_code = """ - Bootstrap.Core.SpecialForms._try(function() { - return 1; - }, Bootstrap.Core.Patterns.defmatch(Bootstrap.Core.Patterns.clause([{ - [Symbol.for('__struct__')]: Symbol.for('Elixir.ElixirScript.ArgumentError') - }], function() { - return Elixir.ElixirScript.IO.__load(Elixir).puts('Invalid argument given'); - })), null, null, function() { - return Elixir.ElixirScript.IO.__load(Elixir).puts('This is printed regardless if it failed or succeed'); - }) - """ - - assert_translation(ex_ast, js_code) - end - - test "translate with an after clause" do - ex_ast = quote do - - try do - 1 - after - IO.puts "This is printed regardless if it failed or succeed" - end - end - - js_code = """ - Bootstrap.Core.SpecialForms._try(function() { - return 1; - },null,null,null,function() { - return Elixir.ElixirScript.IO.__load(Elixir).puts('This is printed regardless if it failed or succeed'); - }) - """ - - assert_translation(ex_ast, js_code) - end - - test "translate else" do - ex_ast = quote do - x = 1 - try do - 1 / x - else - y when y < 1 and y > -1 -> - :small - _ -> - :large - end - end - - js_code = """ - Bootstrap.Core.SpecialForms._try(function() { - return 1 / x; - }, null, null, Bootstrap.Core.Patterns.defmatch(Bootstrap.Core.Patterns.clause([Bootstrap.Core.Patterns.variable()], function(y) { - return Symbol.for('small'); - }, function(y) { - return y < 1 && y > -1; - }), Bootstrap.Core.Patterns.clause([Bootstrap.Core.Patterns.variable()], function(__ignored__) { - return Symbol.for('large'); - })), null) - """ - - assert_translation(ex_ast, js_code) - end - - test "translate catch" do - ex_ast = quote do - try do - 1 - rescue - ArgumentError -> - IO.puts "Invalid argument given" - catch - :throw, :Error -> - IO.puts "caught error" - end - end - - js_code = """ - Bootstrap.Core.SpecialForms._try(function() { - return 1; - }, Bootstrap.Core.Patterns.defmatch(Bootstrap.Core.Patterns.clause([{ - [Symbol.for('__struct__')]: Symbol.for('Elixir.ElixirScript.ArgumentError') - }], function() { - return Elixir.ElixirScript.IO.__load(Elixir).puts('Invalid argument given'); - })), Bootstrap.Core.Patterns.defmatch(Bootstrap.Core.Patterns.clause([Symbol.for('throw'), Symbol.for('Error')], function() { - return Elixir.ElixirScript.IO.__load(Elixir).puts('caught error'); - })), null, null) - """ - - assert_translation(ex_ast, js_code) - end -end diff --git a/test/translator/tuple_test.exs b/test/translator/tuple_test.exs deleted file mode 100644 index 189c1de9..00000000 --- a/test/translator/tuple_test.exs +++ /dev/null @@ -1,35 +0,0 @@ -defmodule ElixirScript.Translator.Tuple.Test do - use ExUnit.Case - import ElixirScript.TestHelper - - test "translate 2 item tuple" do - ex_ast = quote do: {1, 2} - js_code = "new Bootstrap.Core.Tuple(1, 2)" - - assert_translation(ex_ast, js_code) - end - - test "translate multiple item tuple" do - ex_ast = quote do: {1, 2, 3, 4, 5} - js_code = "new Bootstrap.Core.Tuple(1, 2, 3, 4, 5)" - - assert_translation(ex_ast, js_code) - end - - test "translate tuples of different typed items" do - ex_ast = quote do: {"a", "b", "c"} - js_code = "new Bootstrap.Core.Tuple('a', 'b', 'c')" - - assert_translation(ex_ast, js_code) - - ex_ast = quote do: {:a, :b, :c} - js_code = "new Bootstrap.Core.Tuple(Symbol.for('a'), Symbol.for('b'), Symbol.for('c'))" - - assert_translation(ex_ast, js_code) - - ex_ast = quote do: {:a, 2, "c"} - js_code = "new Bootstrap.Core.Tuple(Symbol.for('a'), 2, 'c')" - - assert_translation(ex_ast, js_code) - end -end diff --git a/test/translator/umd_test.exs b/test/translator/umd_test.exs deleted file mode 100644 index 0acd353a..00000000 --- a/test/translator/umd_test.exs +++ /dev/null @@ -1,29 +0,0 @@ -defmodule ElixirScript.Translator.UMD.Test do - use ExUnit.Case - import ElixirScript.TestHelper - - test "translate module to umd" do - ex_ast = quote do - defmodule Elephant do - @ul "#todo-list" - - def something() do - @ul - end - end - end - - js_code = """ - (function(root, factory) { - if (typeof define === 'function' && define.amd) { - define([], factory) - } else if (typeof exports === 'object') { - module.exports = factory() - } else { - root.Elixir = factory() - } - """ - - assert_translation(ex_ast, js_code, :umd) - end -end \ No newline at end of file diff --git a/test/translator/with_test.exs b/test/translator/with_test.exs deleted file mode 100644 index 58c44375..00000000 --- a/test/translator/with_test.exs +++ /dev/null @@ -1,75 +0,0 @@ -defmodule ElixirScript.Translator.With.Test do - use ExUnit.Case - import ElixirScript.TestHelper - - test "translate with" do - ex_ast = quote do - opts = %{} - with {:ok, width} <- Map.fetch(opts, :width), - {:ok, height} <- Map.fetch(opts, :height), - do: {:ok, width * height} - end - - js_code = """ - Bootstrap.Core.SpecialForms._with([new Bootstrap.Core.Tuple(Symbol.for('ok'), Bootstrap.Core.Patterns.variable()), function() { - return Elixir.ElixirScript.Map.__load(Elixir).fetch(opts, Symbol.for('width')); - }], [new Bootstrap.Core.Tuple(Symbol.for('ok'), Bootstrap.Core.Patterns.variable()), function(width) { - return Elixir.ElixirScript.Map.__load(Elixir).fetch(opts, Symbol.for('height')); - }], function(width, height) { - return new Bootstrap.Core.Tuple(Symbol.for('ok'), width * height); - }) - """ - - assert_translation(ex_ast, js_code) - end - - test "translate with with bare expression" do - ex_ast = quote do - opts = %{} - with {:ok, width} <- Map.fetch(opts, :width), - double_width = width * 2, - {:ok, height} <- Map.fetch(opts, :height), - do: {:ok, double_width * height} - end - - js_code = """ - Bootstrap.Core.SpecialForms._with([new Bootstrap.Core.Tuple(Symbol.for('ok'), Bootstrap.Core.Patterns.variable()), function() { - return Elixir.ElixirScript.Map.__load(Elixir).fetch(opts, Symbol.for('width')); - }], [Bootstrap.Core.Patterns.variable(), function(width) { - return width * 2; - }], [new Bootstrap.Core.Tuple(Symbol.for('ok'), Bootstrap.Core.Patterns.variable()), function(width, double_width) { - return Elixir.ElixirScript.Map.__load(Elixir).fetch(opts, Symbol.for('height')); - }], function(width, double_width, height) { - return new Bootstrap.Core.Tuple(Symbol.for('ok'), double_width * height); - }) - """ - - assert_translation(ex_ast, js_code) - end - - test "translate with with else" do - ex_ast = quote do - opts = %{} - with {:ok, width} <- Map.fetch(opts, :width), - {:ok, height} <- Map.fetch(opts, :height) do - {:ok, width * height} - else - :error -> {:error, :wrong_data} - end - end - - js_code = """ - Bootstrap.Core.SpecialForms._with([new Bootstrap.Core.Tuple(Symbol.for('ok'), Bootstrap.Core.Patterns.variable()), function() { - return Elixir.ElixirScript.Map.__load(Elixir).fetch(opts, Symbol.for('width')); - }], [new Bootstrap.Core.Tuple(Symbol.for('ok'), Bootstrap.Core.Patterns.variable()), function(width) { - return Elixir.ElixirScript.Map.__load(Elixir).fetch(opts, Symbol.for('height')); - }], function(width, height) { - return new Bootstrap.Core.Tuple(Symbol.for('ok'), width * height); - }, Bootstrap.Core.Patterns.defmatch(Bootstrap.Core.Patterns.clause([Symbol.for('error')], function() { - return new Bootstrap.Core.Tuple(Symbol.for('error'), Symbol.for('wrong_data')); - }))) - """ - - assert_translation(ex_ast, js_code) - end -end From 6ff7c750ac03b18db8644b9ee24afd197fcf5c47 Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Sun, 25 Jun 2017 19:52:04 -0500 Subject: [PATCH 133/418] Add more tests --- .gitignore | 1 + lib/elixir_script.ex | 1 + lib/elixir_script/cli.ex | 8 +-- lib/elixir_script/compiler.ex | 4 +- lib/elixir_script/module_systems/common.ex | 4 +- lib/elixir_script/module_systems/es.ex | 4 -- lib/elixir_script/module_systems/namespace.ex | 17 ------ lib/elixir_script/module_systems/umd.ex | 4 -- lib/elixir_script/passes/find_used_modules.ex | 2 +- lib/elixir_script/passes/output.ex | 16 +++-- lib/elixir_script/passes/translate/clause.ex | 2 +- lib/elixir_script/passes/translate/form.ex | 7 ++- .../passes/translate/forms/bitstring.ex | 2 +- .../passes/translate/forms/for.ex | 7 ++- .../passes/translate/forms/map.ex | 1 + .../passes/translate/forms/match.ex | 4 +- .../passes/translate/forms/pattern.ex | 2 +- .../translate/forms/pattern/patterns.ex | 2 + .../passes/translate/forms/remote.ex | 8 +-- .../passes/translate/forms/try.ex | 3 +- .../passes/translate/function.ex | 9 ++- lib/elixir_script/passes/translate/module.ex | 4 +- .../passes/translate/protocol.ex | 4 +- lib/elixir_script/state.ex | 7 ++- lib/elixir_script/watcher.ex | 4 +- lib/mix/tasks/compile.elixir_script.ex | 10 ++- mix.exs | 61 +++---------------- mix.lock | 21 ++++--- test/beam_test.exs | 16 ++++- test/cli_test.exs | 8 +++ test/compiler_test.exs | 49 +++++++++++++++ test/support/user.ex | 17 ------ 32 files changed, 155 insertions(+), 154 deletions(-) create mode 100644 test/cli_test.exs create mode 100644 test/compiler_test.exs delete mode 100644 test/support/user.ex diff --git a/.gitignore b/.gitignore index 9a234b19..ee4d5234 100644 --- a/.gitignore +++ b/.gitignore @@ -22,3 +22,4 @@ stdlib_state.bin .nyc_output test/app/build .vscode +cover diff --git a/lib/elixir_script.ex b/lib/elixir_script.ex index d92c6861..d69317d6 100644 --- a/lib/elixir_script.ex +++ b/lib/elixir_script.ex @@ -1,2 +1,3 @@ defmodule ElixirScript do + @moduledoc false end diff --git a/lib/elixir_script/cli.ex b/lib/elixir_script/cli.ex index ab8af630..9bd4daea 100644 --- a/lib/elixir_script/cli.ex +++ b/lib/elixir_script/cli.ex @@ -19,12 +19,6 @@ defmodule ElixirScript.CLI do f: :format ] - def main(argv) do - argv - |> parse_args - |> process - end - def parse_args(args) do { options, input, errors } = OptionParser.parse(args, switches: @switches, aliases: @aliases) @@ -43,7 +37,7 @@ defmodule ElixirScript.CLI do end - def help_message() do + defp help_message() do """ usage: elixirscript [options] the entry module of your application diff --git a/lib/elixir_script/compiler.ex b/lib/elixir_script/compiler.ex index faf38459..5dc1195d 100644 --- a/lib/elixir_script/compiler.ex +++ b/lib/elixir_script/compiler.ex @@ -28,9 +28,11 @@ defmodule ElixirScript.Compiler do IO.puts "Building Output" modules = ElixirScript.State.list_modules(pid) - ElixirScript.Output.execute(modules, pid) + result = ElixirScript.Output.execute(modules, pid) ElixirScript.State.stop(pid) + + result end defp build_compiler_options(opts, entry_modules) do diff --git a/lib/elixir_script/module_systems/common.ex b/lib/elixir_script/module_systems/common.ex index f5c01065..f4c00837 100644 --- a/lib/elixir_script/module_systems/common.ex +++ b/lib/elixir_script/module_systems/common.ex @@ -2,8 +2,7 @@ defmodule ElixirScript.ModuleSystems.Common do @moduledoc false alias ESTree.Tools.Builder, as: JS alias ElixirScript.Translator - alias ElixirScript.Translator.State - alias ElixirScript.Translator.Utils + alias ElixirScript.Translator.{State, Utils} def build(imports, js_imports, body, exports) do module_imports = Enum.map(imports, fn {module, path} -> import_module(module, path) end) @@ -11,7 +10,6 @@ defmodule ElixirScript.ModuleSystems.Common do imports = js_imports |> Enum.map(fn {module, path} -> import_module(module, path) - {module, path, _} -> import_module(module, path) end) imports = Enum.uniq(imports ++ module_imports) diff --git a/lib/elixir_script/module_systems/es.ex b/lib/elixir_script/module_systems/es.ex index 81f5bd4c..3e92049c 100644 --- a/lib/elixir_script/module_systems/es.ex +++ b/lib/elixir_script/module_systems/es.ex @@ -1,9 +1,6 @@ defmodule ElixirScript.ModuleSystems.ES do @moduledoc false alias ESTree.Tools.Builder, as: JS - alias ElixirScript.Translator - alias ElixirScript.Translator.State - alias ElixirScript.Translator.Utils def build(imports, js_imports, body, exports) do module_imports = Enum.map(imports, fn {module, path} -> import_module(module, path) end) @@ -11,7 +8,6 @@ defmodule ElixirScript.ModuleSystems.ES do imports = js_imports |> Enum.map(fn {module, path} -> import_module(module, path) - {module, path, default: true} -> import_module(module, path) {module, path, default: false} -> import_namespace_module(module, path) end) diff --git a/lib/elixir_script/module_systems/namespace.ex b/lib/elixir_script/module_systems/namespace.ex index 92caa561..200ae0c3 100644 --- a/lib/elixir_script/module_systems/namespace.ex +++ b/lib/elixir_script/module_systems/namespace.ex @@ -1,9 +1,6 @@ defmodule ElixirScript.ModuleSystems.Namespace do @moduledoc false alias ESTree.Tools.Builder, as: JS - alias ElixirScript.Translator - alias ElixirScript.Translator.State - alias ElixirScript.Translator.Utils alias ElixirScript.Translate.Identifier def build(module_name, body, exports, env) do @@ -15,20 +12,6 @@ defmodule ElixirScript.ModuleSystems.Namespace do Identifier.make_namespace_members(members) end - def import_module(module_name) do - name = ["Elixir" | Module.split(module_name) ] |> Enum.join("$") - - declarator = JS.variable_declarator( - JS.identifier(name), - JS.call_expression( - module_name_function_call(module_name, "__load"), - [JS.identifier("Elixir")] - ) - ) - - JS.variable_declaration([declarator], :const) - end - defp build_namespace() do JS.member_expression( JS.identifier("Bootstrap"), diff --git a/lib/elixir_script/module_systems/umd.ex b/lib/elixir_script/module_systems/umd.ex index c0f0d7a6..4aefe6d3 100644 --- a/lib/elixir_script/module_systems/umd.ex +++ b/lib/elixir_script/module_systems/umd.ex @@ -1,9 +1,6 @@ defmodule ElixirScript.ModuleSystems.UMD do @moduledoc false alias ESTree.Tools.Builder, as: JS - alias ElixirScript.Translator - alias ElixirScript.Translator.State - alias ElixirScript.Translator.Utils def build(imports, js_imports, body, exports) do module_imports = Enum.map(imports, fn {module, path} -> import_module(module, path) end) @@ -11,7 +8,6 @@ defmodule ElixirScript.ModuleSystems.UMD do imports = js_imports |> Enum.map(fn {module, path} -> import_module(module, path) - {module, path, _} -> import_module(module, path) end) imports = Enum.uniq(imports ++ module_imports) diff --git a/lib/elixir_script/passes/find_used_modules.ex b/lib/elixir_script/passes/find_used_modules.ex index bbb70cfd..fcdadbc0 100644 --- a/lib/elixir_script/passes/find_used_modules.ex +++ b/lib/elixir_script/passes/find_used_modules.ex @@ -21,7 +21,7 @@ defmodule ElixirScript.FindUsedModules do {:ok, module, implementations} -> walk_protocol(module, implementations, pid) {:error, error} -> - raise "An error occurred while compiling #{inspect module}: #{error}" + raise ElixirScript.CompileError, "An error occurred while compiling #{inspect module}: #{error}" end end diff --git a/lib/elixir_script/passes/output.ex b/lib/elixir_script/passes/output.ex index 9b175f90..f5804cc8 100644 --- a/lib/elixir_script/passes/output.ex +++ b/lib/elixir_script/passes/output.ex @@ -63,12 +63,7 @@ defmodule ElixirScript.Output do end defp output(code, path) do - file_name = case Path.extname(path) do - ".js" -> - path - _ -> - Path.join([path, @generated_name]) - end + file_name = get_output_file_name(path) if !File.exists?(Path.dirname(file_name)) do File.mkdir_p!(Path.dirname(file_name)) @@ -76,4 +71,13 @@ defmodule ElixirScript.Output do File.write!(file_name, code) end + + def get_output_file_name(path) do + case Path.extname(path) do + ".js" -> + path + _ -> + Path.join([path, @generated_name]) + end + end end \ No newline at end of file diff --git a/lib/elixir_script/passes/translate/clause.ex b/lib/elixir_script/passes/translate/clause.ex index 1816ab34..79512ab0 100644 --- a/lib/elixir_script/passes/translate/clause.ex +++ b/lib/elixir_script/passes/translate/clause.ex @@ -84,7 +84,7 @@ defmodule ElixirScript.Translate.Clause do return_statement = case declaration do %ESTree.ArrayPattern{elements: elements} -> - if(length(elements) == 1) do + if length(elements) == 1 do J.return_statement(hd(declaration.elements)) else J.return_statement(J.array_expression(declaration.elements)) diff --git a/lib/elixir_script/passes/translate/form.ex b/lib/elixir_script/passes/translate/form.ex index f530e8cb..662ee8be 100644 --- a/lib/elixir_script/passes/translate/form.ex +++ b/lib/elixir_script/passes/translate/form.ex @@ -2,8 +2,7 @@ defmodule ElixirScript.Translate.Form do alias ESTree.Tools.Builder, as: J alias ElixirScript.Translate.Forms.{Bitstring, Match, Try, For, Receive, Remote, Pattern} alias ElixirScript.Translate.Functions.{Erlang, Lists, Maps} - alias ElixirScript.Translate.Identifier - alias ElixirScript.Translate.Clause + alias ElixirScript.Translate.{Identifier, Clause} require Logger @moduledoc """ @@ -180,7 +179,9 @@ defmodule ElixirScript.Translate.Form do def compile({:receive, context, [blocks]}, state) do line = Keyword.get(context, :line, 1) {function, arity} = Map.get(state, :function) - Logger.warn "receive not supported, Module: #{inspect state.module}, Function: #{function}, Line: #{line}" + Logger.warn fn() -> + "receive not supported, Module: #{inspect state.module}, Function: #{function}, Line: #{line}" + end Receive.compile(blocks, state) end diff --git a/lib/elixir_script/passes/translate/forms/bitstring.ex b/lib/elixir_script/passes/translate/forms/bitstring.ex index dfe5f495..0221e82c 100644 --- a/lib/elixir_script/passes/translate/forms/bitstring.ex +++ b/lib/elixir_script/passes/translate/forms/bitstring.ex @@ -120,7 +120,7 @@ defmodule ElixirScript.Translate.Forms.Bitstring do end def make_interpolated_string(elements, state) do - translated_elements = Enum.map(elements, fn(x)-> + translated_elements = Enum.map(elements, fn(x) -> case x do elem when is_binary(elem) -> Form.compile!(elem, state) diff --git a/lib/elixir_script/passes/translate/forms/for.ex b/lib/elixir_script/passes/translate/forms/for.ex index 8e67424d..063fbe39 100644 --- a/lib/elixir_script/passes/translate/forms/for.ex +++ b/lib/elixir_script/passes/translate/forms/for.ex @@ -1,8 +1,9 @@ defmodule ElixirScript.Translate.Forms.For do + @moduledoc false + alias ESTree.Tools.Builder, as: JS - alias ElixirScript.Translate.Form - alias ElixirScript.Translate.Clause - alias ElixirScript.Translate.Forms.{Pattern} + alias ElixirScript.Translate.{Form, Clause} + alias ElixirScript.Translate.Forms.Pattern def compile({:for, _, generators}, state) do args = handle_args(generators, state) diff --git a/lib/elixir_script/passes/translate/forms/map.ex b/lib/elixir_script/passes/translate/forms/map.ex index 49480138..5bc27ba6 100644 --- a/lib/elixir_script/passes/translate/forms/map.ex +++ b/lib/elixir_script/passes/translate/forms/map.ex @@ -1,4 +1,5 @@ defmodule ElixirScript.Translate.Forms.Map do + @moduledoc false alias ESTree.Tools.Builder, as: J alias ElixirScript.Translate.Form diff --git a/lib/elixir_script/passes/translate/forms/match.ex b/lib/elixir_script/passes/translate/forms/match.ex index 6a2a8613..2ef9037c 100644 --- a/lib/elixir_script/passes/translate/forms/match.ex +++ b/lib/elixir_script/passes/translate/forms/match.ex @@ -1,7 +1,9 @@ defmodule ElixirScript.Translate.Forms.Match do + @moduledoc false + alias ESTree.Tools.Builder, as: J alias ElixirScript.Translate.Form - alias ElixirScript.Translate.Forms.{Pattern} + alias ElixirScript.Translate.Forms.Pattern def compile({:=, _, [left, right]}, state) do { right_ast, state } = Form.compile(right, state) diff --git a/lib/elixir_script/passes/translate/forms/pattern.ex b/lib/elixir_script/passes/translate/forms/pattern.ex index 89587f5f..a96f589f 100644 --- a/lib/elixir_script/passes/translate/forms/pattern.ex +++ b/lib/elixir_script/passes/translate/forms/pattern.ex @@ -2,7 +2,7 @@ defmodule ElixirScript.Translate.Forms.Pattern do alias ElixirScript.Translate.Forms.Pattern.Patterns, as: PM alias ESTree.Tools.Builder, as: J alias ElixirScript.Translate.Form - alias ElixirScript.Translate.Forms.{Bitstring} + alias ElixirScript.Translate.Forms.Bitstring @moduledoc """ Handles all pattern matching translations diff --git a/lib/elixir_script/passes/translate/forms/pattern/patterns.ex b/lib/elixir_script/passes/translate/forms/pattern/patterns.ex index d914080f..bb8401a3 100644 --- a/lib/elixir_script/passes/translate/forms/pattern/patterns.ex +++ b/lib/elixir_script/passes/translate/forms/pattern/patterns.ex @@ -1,4 +1,6 @@ defmodule ElixirScript.Translate.Forms.Pattern.Patterns do + @moduledoc false + alias ESTree.Tools.Builder, as: J @patterns J.member_expression( diff --git a/lib/elixir_script/passes/translate/forms/remote.ex b/lib/elixir_script/passes/translate/forms/remote.ex index 6d4a751a..b6c8c192 100644 --- a/lib/elixir_script/passes/translate/forms/remote.ex +++ b/lib/elixir_script/passes/translate/forms/remote.ex @@ -2,8 +2,7 @@ defmodule ElixirScript.Translate.Forms.Remote do @moduledoc false alias ESTree.Tools.Builder, as: J - alias ElixirScript.Translate.Form - alias ElixirScript.Translate.Identifier + alias ElixirScript.Translate.{Form, Identifier} @erlang_modules [ :erlang, @@ -126,10 +125,9 @@ defmodule ElixirScript.Translate.Forms.Remote do end def compile({:., _, [module, function]}, state) do - function_name = cond do - ElixirScript.Translate.Module.is_js_module(module, state) -> + function_name = if ElixirScript.Translate.Module.is_js_module(module, state) do ElixirScript.Translate.Identifier.make_extern_function_name(function) - true -> + else ElixirScript.Translate.Identifier.make_function_name(function) end diff --git a/lib/elixir_script/passes/translate/forms/try.ex b/lib/elixir_script/passes/translate/forms/try.ex index 2729e39f..b7c0f225 100644 --- a/lib/elixir_script/passes/translate/forms/try.ex +++ b/lib/elixir_script/passes/translate/forms/try.ex @@ -1,8 +1,7 @@ defmodule ElixirScript.Translate.Forms.Try do @moduledoc false alias ESTree.Tools.Builder, as: JS - alias ElixirScript.Translate.Clause - alias ElixirScript.Translate.{Form, Function} + alias ElixirScript.Translate.{Form, Function, Clause} def compile(blocks, state) do try_block = Keyword.get(blocks, :do) diff --git a/lib/elixir_script/passes/translate/function.ex b/lib/elixir_script/passes/translate/function.ex index ba6e1fc1..23e13f20 100644 --- a/lib/elixir_script/passes/translate/function.ex +++ b/lib/elixir_script/passes/translate/function.ex @@ -1,8 +1,7 @@ defmodule ElixirScript.Translate.Function do alias ESTree.Tools.Builder, as: J - alias ElixirScript.Translate.Clause + alias ElixirScript.Translate.{Clause, Form} alias ElixirScript.Translate.Forms.Pattern - alias ElixirScript.Translate.Form @moduledoc """ Translates the given Elixir function AST into the @@ -115,10 +114,10 @@ defmodule ElixirScript.Translate.Function do end defp compile_clause({ _, args, guards, body}, state) do - state = if !Map.has_key?(state, :vars) do - Map.put(state, :vars, %{}) - else + state = if Map.has_key?(state, :vars) do state + else + Map.put(state, :vars, %{}) end {patterns, params, state} = Pattern.compile(args, state) diff --git a/lib/elixir_script/passes/translate/module.ex b/lib/elixir_script/passes/translate/module.ex index 9f716f80..c46dc80e 100644 --- a/lib/elixir_script/passes/translate/module.ex +++ b/lib/elixir_script/passes/translate/module.ex @@ -1,9 +1,7 @@ defmodule ElixirScript.Translate.Module do @moduledoc false alias ESTree.Tools.Builder, as: J - alias ElixirScript.Translate.Function - alias ElixirScript.Translate.Form - alias ElixirScript.Translate.Identifier + alias ElixirScript.Translate.{Function, Form, Identifier} alias ElixirScript.State, as: ModuleState @doc """ diff --git a/lib/elixir_script/passes/translate/protocol.ex b/lib/elixir_script/passes/translate/protocol.ex index baaed852..0a02a17e 100644 --- a/lib/elixir_script/passes/translate/protocol.ex +++ b/lib/elixir_script/passes/translate/protocol.ex @@ -1,9 +1,7 @@ defmodule ElixirScript.Translate.Protocol do @moduledoc false alias ESTree.Tools.Builder, as: J - alias ElixirScript.Translate.Function - alias ElixirScript.Translate.Form - alias ElixirScript.Translate.Identifier + alias ElixirScript.Translate.{Function, Form, Identifier} alias ElixirScript.State, as: ModuleState diff --git a/lib/elixir_script/state.ex b/lib/elixir_script/state.ex index b199e9e8..b65c7189 100644 --- a/lib/elixir_script/state.ex +++ b/lib/elixir_script/state.ex @@ -60,8 +60,11 @@ defmodule ElixirScript.State do def get_javascript_modules(pid) do Agent.get(pid, fn(state) -> Map.get(state.compiler_opts, :js_modules, []) - |> Enum.map(fn({module_name, _path}) -> - module_name + |> Enum.map(fn + {module_name, _path} -> + module_name + {module_name, _path, _opts} -> + module_name end) end) end diff --git a/lib/elixir_script/watcher.ex b/lib/elixir_script/watcher.ex index 5f6de96c..7f1e6e1d 100644 --- a/lib/elixir_script/watcher.ex +++ b/lib/elixir_script/watcher.ex @@ -23,7 +23,9 @@ defmodule ElixirScript.Watcher do try do if input_changed?(to_string(path), state) do - Logger.debug "Event: #{inspect event} Path: #{path}" + Logger.debug fn() -> + "Event: #{inspect event} Path: #{path}" + end ElixirScript.Compiler.compile(state[:input], state[:options]) end rescue diff --git a/lib/mix/tasks/compile.elixir_script.ex b/lib/mix/tasks/compile.elixir_script.ex index a7926b79..eec94c8d 100644 --- a/lib/mix/tasks/compile.elixir_script.ex +++ b/lib/mix/tasks/compile.elixir_script.ex @@ -53,7 +53,15 @@ defmodule Mix.Tasks.Compile.ElixirScript do end def clean do - #TODO: Figure out how to clean + {input, opts} = get_compiler_params() + + case opts[:output] do + path when is_binary(path) -> + file_name = ElixirScript.Output.get_output_file_name(path) + File.rm!(file_name) + _ -> + nil + end :ok end diff --git a/mix.exs b/mix.exs index 83839435..8bd543b2 100644 --- a/mix.exs +++ b/mix.exs @@ -7,7 +7,6 @@ defmodule ElixirScript.Mixfile do version: "0.29.0-dev", elixir: "~> 1.5-dev", elixirc_paths: elixirc_paths(Mix.env), - escript: escript_config(), deps: deps(), description: description(), package: package(), @@ -15,7 +14,7 @@ defmodule ElixirScript.Mixfile do aliases: aliases(), test_coverage: [tool: ExCoveralls], docs: [ - extras: ["GettingStarted.md", "FAQ.md", "Supported.md", "JavaScriptInterop.md"] + extras: ["GettingStarted.md", "JavaScriptInterop.md"] ] ] end @@ -29,19 +28,15 @@ defmodule ElixirScript.Mixfile do defp deps do [ {:estree, "~> 2.6"}, - {:fs, "~> 2.12"}, - {:ex_doc, "~> 0.15", only: :dev}, - {:excoveralls, "~> 0.6", only: :test}, - {:credo, "~> 0.7", only: [:dev, :test]} + {:fs, "~> 3.4"}, + {:ex_doc, "~> 0.16", only: :dev}, + {:excoveralls, "~> 0.7", only: :test}, + {:credo, "~> 0.8", only: [:dev, :test]} ] end - defp elixirc_paths(:test), do: ["lib", "priv/std_lib", "test/support"] - defp elixirc_paths(_), do: ["lib", "priv/std_lib"] - - defp escript_config do - [main_module: ElixirScript.CLI, name: "elixirscript"] - end + defp elixirc_paths(:test), do: ["lib", "test/support"] + defp elixirc_paths(_), do: ["lib"] defp description do """ @@ -62,48 +57,12 @@ defmodule ElixirScript.Mixfile do end defp aliases do - [dist: &dist/1, - install: &install/1] - end - - def dist(_) do - Mix.Task.run "app.start" - - dist_folder = "dist" - folder_name = "#{dist_folder}/elixirscript" - archive_file_name = "#{dist_folder}/elixirscript.tar.gz" - - Mix.Tasks.Escript.Build.run([]) - - if File.exists?(dist_folder) do - File.rm_rf(dist_folder) - end - - System.cmd("npm", ["run", "build"]) - - File.mkdir_p(folder_name <> "/bin") - File.cp!("elixirscript", "#{folder_name}/bin/elixirscript") - if File.exists?("priv/.DS_Store") do - File.rm!("priv/.DS_Store") - end - File.cp_r!("priv/", "#{folder_name}") - File.cp!("LICENSE", "#{folder_name}/LICENSE") - - System.cmd("tar", ["czf", archive_file_name, folder_name]) - - File.rm_rf(folder_name) + [build_js: &build_js/1] end - def install(_) do + def build_js(_) do Mix.Task.run "app.start" - - System.cmd("tar", ["-zxvf", "dist/elixirscript.tar.gz"]) - - File.rm_rf!("/usr/local/elixirscript") - - System.cmd("mv", ["dist/elixirscript", "/usr/local/elixirscript"]) - - IO.puts("installed at /usr/local/elixirscript") + System.cmd("yarn", ["build"]) end end diff --git a/mix.lock b/mix.lock index 353e11a0..9de5d64f 100644 --- a/mix.lock +++ b/mix.lock @@ -1,15 +1,16 @@ %{"bunt": {:hex, :bunt, "0.2.0", "951c6e801e8b1d2cbe58ebbd3e616a869061ddadcc4863d0a2182541acae9a38", [:mix], [], "hexpm"}, - "certifi": {:hex, :certifi, "1.0.0", "1c787a85b1855ba354f0b8920392c19aa1d06b0ee1362f9141279620a5be2039", [:rebar3], [], "hexpm"}, - "credo": {:hex, :credo, "0.7.3", "9827ab04002186af1aec014a811839a06f72aaae6cd5eed3919b248c8767dbf3", [:mix], [{:bunt, "~> 0.2.0", [hex: :bunt, repo: "hexpm", optional: false]}], "hexpm"}, - "earmark": {:hex, :earmark, "1.2.0", "bf1ce17aea43ab62f6943b97bd6e3dc032ce45d4f787504e3adf738e54b42f3a", [:mix], [], "hexpm"}, + "certifi": {:hex, :certifi, "1.2.1", "c3904f192bd5284e5b13f20db3ceac9626e14eeacfbb492e19583cf0e37b22be", [:rebar3], [], "hexpm"}, + "credo": {:hex, :credo, "0.8.1", "137efcc99b4bc507c958ba9b5dff70149e971250813cbe7d4537ec7e36997402", [:mix], [{:bunt, "~> 0.2.0", [hex: :bunt, repo: "hexpm", optional: false]}], "hexpm"}, + "earmark": {:hex, :earmark, "1.2.2", "f718159d6b65068e8daeef709ccddae5f7fdc770707d82e7d126f584cd925b74", [:mix], [], "hexpm"}, "estree": {:hex, :estree, "2.6.0", "86a301b0c355fa55c19e7ef9dceb1b1e983c6df526a2b7846818a38c258fc3fb", [:mix], [], "hexpm"}, - "ex_doc": {:hex, :ex_doc, "0.15.1", "d5f9d588fd802152516fccfdb96d6073753f77314fcfee892b15b6724ca0d596", [:mix], [{:earmark, "~> 1.1", [hex: :earmark, repo: "hexpm", optional: false]}], "hexpm"}, - "excoveralls": {:hex, :excoveralls, "0.6.3", "894bf9254890a4aac1d1165da08145a72700ff42d8cb6ce8195a584cb2a4b374", [:mix], [{:exjsx, "~> 3.0", [hex: :exjsx, repo: "hexpm", optional: false]}, {:hackney, ">= 0.12.0", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm"}, - "exjsx": {:hex, :exjsx, "3.2.1", "1bc5bf1e4fd249104178f0885030bcd75a4526f4d2a1e976f4b428d347614f0f", [:mix], [{:jsx, "~> 2.8.0", [hex: :jsx, repo: "hexpm", optional: false]}], "hexpm"}, - "fs": {:hex, :fs, "2.12.0", "ad631efacc9a5683c8eaa1b274e24fa64a1b8eb30747e9595b93bec7e492e25e", [:rebar3], [], "hexpm"}, - "hackney": {:hex, :hackney, "1.7.1", "e238c52c5df3c3b16ce613d3a51c7220a784d734879b1e231c9babd433ac1cb4", [:rebar3], [{:certifi, "1.0.0", [hex: :certifi, repo: "hexpm", optional: false]}, {:idna, "4.0.0", [hex: :idna, repo: "hexpm", optional: false]}, {:metrics, "1.0.1", [hex: :metrics, repo: "hexpm", optional: false]}, {:mimerl, "1.0.2", [hex: :mimerl, repo: "hexpm", optional: false]}, {:ssl_verify_fun, "1.1.1", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}], "hexpm"}, - "idna": {:hex, :idna, "4.0.0", "10aaa9f79d0b12cf0def53038547855b91144f1bfcc0ec73494f38bb7b9c4961", [:rebar3], [], "hexpm"}, + "ex_doc": {:hex, :ex_doc, "0.16.1", "b4b8a23602b4ce0e9a5a960a81260d1f7b29635b9652c67e95b0c2f7ccee5e81", [:mix], [{:earmark, "~> 1.1", [hex: :earmark, repo: "hexpm", optional: false]}], "hexpm"}, + "excoveralls": {:hex, :excoveralls, "0.7.0", "05cb3332c2b0f799df3ab90eb7df1ae5a147c86776e91792848a12b7ed87242f", [:mix], [{:exjsx, ">= 3.0.0", [hex: :exjsx, repo: "hexpm", optional: false]}, {:hackney, ">= 0.12.0", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm"}, + "exjsx": {:hex, :exjsx, "4.0.0", "60548841e0212df401e38e63c0078ec57b33e7ea49b032c796ccad8cde794b5c", [:mix], [{:jsx, "~> 2.8.0", [hex: :jsx, repo: "hexpm", optional: false]}], "hexpm"}, + "fs": {:hex, :fs, "3.4.0", "6d18575c250b415b3cad559e6f97a4c822516c7bc2c10bfbb2493a8f230f5132", [:rebar3], [], "hexpm"}, + "hackney": {:hex, :hackney, "1.8.6", "21a725db3569b3fb11a6af17d5c5f654052ce9624219f1317e8639183de4a423", [:rebar3], [{:certifi, "1.2.1", [hex: :certifi, repo: "hexpm", optional: false]}, {:idna, "5.0.2", [hex: :idna, repo: "hexpm", optional: false]}, {:metrics, "1.0.1", [hex: :metrics, repo: "hexpm", optional: false]}, {:mimerl, "1.0.2", [hex: :mimerl, repo: "hexpm", optional: false]}, {:ssl_verify_fun, "1.1.1", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}], "hexpm"}, + "idna": {:hex, :idna, "5.0.2", "ac203208ada855d95dc591a764b6e87259cb0e2a364218f215ad662daa8cd6b4", [:rebar3], [{:unicode_util_compat, "0.2.0", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm"}, "jsx": {:hex, :jsx, "2.8.2", "7acc7d785b5abe8a6e9adbde926a24e481f29956dd8b4df49e3e4e7bcc92a018", [:mix, :rebar3], [], "hexpm"}, "metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [:rebar3], [], "hexpm"}, "mimerl": {:hex, :mimerl, "1.0.2", "993f9b0e084083405ed8252b99460c4f0563e41729ab42d9074fd5e52439be88", [:rebar3], [], "hexpm"}, - "ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.1", "28a4d65b7f59893bc2c7de786dec1e1555bd742d336043fe644ae956c3497fbe", [:make, :rebar], [], "hexpm"}} + "ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.1", "28a4d65b7f59893bc2c7de786dec1e1555bd742d336043fe644ae956c3497fbe", [:make, :rebar], [], "hexpm"}, + "unicode_util_compat": {:hex, :unicode_util_compat, "0.2.0", "dbbccf6781821b1c0701845eaf966c9b6d83d7c3bfc65ca2b78b88b8678bfa35", [:rebar3], [], "hexpm"}} diff --git a/test/beam_test.exs b/test/beam_test.exs index bfcbb798..43c45880 100644 --- a/test/beam_test.exs +++ b/test/beam_test.exs @@ -2,6 +2,20 @@ defmodule ElixirScript.Beam.Test do use ExUnit.Case test "can get ast from beam" do - assert {:ok, map} = ElixirScript.Beam.debug_info(Atom) + assert {:ok, _} = ElixirScript.Beam.debug_info(Atom) + end + + test "errors when not found" do + assert {:error, _} = ElixirScript.Beam.debug_info(Some.Module) + end + + test "can get ast from beam that is protocol" do + assert {:ok, Enumerable, _} = ElixirScript.Beam.debug_info(Enumerable) + end + + test "replaces String with ElixirScript.String" do + assert {:ok, map} = ElixirScript.Beam.debug_info(String) + assert {:ok, map2} = ElixirScript.Beam.debug_info(ElixirScript.String) + assert map.definitions == map2.definitions end end diff --git a/test/cli_test.exs b/test/cli_test.exs new file mode 100644 index 00000000..2826670d --- /dev/null +++ b/test/cli_test.exs @@ -0,0 +1,8 @@ +defmodule ElixirScript.CLI.Test do + use ExUnit.Case + + test "parse_args" do + {_, args} = ElixirScript.CLI.parse_args(["Atom", "--format", "umd"]) + assert args == [format: "umd"] + end +end \ No newline at end of file diff --git a/test/compiler_test.exs b/test/compiler_test.exs new file mode 100644 index 00000000..c154e67c --- /dev/null +++ b/test/compiler_test.exs @@ -0,0 +1,49 @@ +defmodule ElixirScript.Compiler.Test do + use ExUnit.Case + + test "Can compile one entry module" do + result = ElixirScript.Compiler.compile(Version) + assert is_binary(result) + end + + test "Can compile multiple entry modules" do + result = ElixirScript.Compiler.compile([Atom, String]) + assert is_binary(result) + end + + test "Error on unknown module" do + assert_raise ElixirScript.CompileError, fn -> + ElixirScript.Compiler.compile(SomeModule) + end + end + + test "Output format: es" do + result = ElixirScript.Compiler.compile(Atom, [format: :es, js_modules: [{React, "react"}, {ReactDOM, "react-dom", default: false}]]) + assert result =~ "export default Elixir" + end + + test "Output format: umd" do + result = ElixirScript.Compiler.compile(Atom, [format: :umd, js_modules: [{React, "react"}]]) + assert result =~ "factory" + end + + test "Output format: common" do + result = ElixirScript.Compiler.compile(Atom, [format: :common, js_modules: [{React, "react"}]]) + assert result =~ "module.exports = Elixir" + end + + test "Output file with default name" do + path = System.tmp_dir() + + result = ElixirScript.Compiler.compile(Atom, [output: path]) + assert File.exists?(Path.join([path, "Elixir.App.js"])) + end + + test "Output file with custom name" do + path = System.tmp_dir() + path = Path.join([path, "myfile.js"]) + + result = ElixirScript.Compiler.compile(Atom, [output: path]) + assert File.exists?(path) + end +end \ No newline at end of file diff --git a/test/support/user.ex b/test/support/user.ex deleted file mode 100644 index 2781433d..00000000 --- a/test/support/user.ex +++ /dev/null @@ -1,17 +0,0 @@ -defmodule User do - defstruct [:first, :last] - - def throw_something() do - raise ArgumentError - end -end - -defimpl String.Chars, for: User do - def to_string(nil) do - "" - end - - def to_string(user) do - user.first <> user.last - end -end \ No newline at end of file From bac9b99153516d253835013d4844204e8f3485a5 Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Sun, 25 Jun 2017 21:07:14 -0500 Subject: [PATCH 134/418] More CLI tests. Add JS tests --- .../translate/forms/pattern/patterns.ex | 19 ---- .../passes/translate/identifier.ex | 10 -- test/cli_test.exs | 31 ++++++ test/passes/translate/forms/js_test.exs | 105 ++++++++++++++++++ 4 files changed, 136 insertions(+), 29 deletions(-) create mode 100644 test/passes/translate/forms/js_test.exs diff --git a/lib/elixir_script/passes/translate/forms/pattern/patterns.ex b/lib/elixir_script/passes/translate/forms/pattern/patterns.ex index bb8401a3..70154334 100644 --- a/lib/elixir_script/passes/translate/forms/pattern/patterns.ex +++ b/lib/elixir_script/passes/translate/forms/pattern/patterns.ex @@ -11,11 +11,6 @@ defmodule ElixirScript.Translate.Forms.Pattern.Patterns do J.identifier("Patterns") ) - @wildcard J.member_expression( - @patterns, - J.identifier(:wildcard) - ) - @parameter J.member_expression( @patterns, J.identifier(:variable) @@ -51,13 +46,6 @@ defmodule ElixirScript.Translate.Forms.Pattern.Patterns do J.identifier(:bitStringMatch) ) - def wildcard() do - J.call_expression( - @wildcard, - [] - ) - end - def parameter() do J.call_expression( @parameter, @@ -65,13 +53,6 @@ defmodule ElixirScript.Translate.Forms.Pattern.Patterns do ) end - def parameter(default_value) do - J.call_expression( - @parameter, - [default_value] - ) - end - def head_tail(headParameter, tailParameter) do J.call_expression( @head_tail, diff --git a/lib/elixir_script/passes/translate/identifier.ex b/lib/elixir_script/passes/translate/identifier.ex index 5c95e03a..b5c287dd 100644 --- a/lib/elixir_script/passes/translate/identifier.ex +++ b/lib/elixir_script/passes/translate/identifier.ex @@ -35,20 +35,12 @@ defmodule ElixirScript.Translate.Identifier do :yield ] - def make_identifier([ast]) do - make_identifier(ast) - end - def make_identifier(ast) do ast |> filter_name |> J.identifier end - defp filter_name(name) when is_tuple(name) do - name - end - defp filter_name(reserved_word) when reserved_word in @js_reserved_words do "__#{Atom.to_string(reserved_word)}__" end @@ -71,8 +63,6 @@ defmodule ElixirScript.Translate.Identifier do case module_name do m when is_list(m) -> m - m when is_binary(m) -> - String.split(m, ".") m when is_atom(m) -> Module.split(m) end diff --git a/test/cli_test.exs b/test/cli_test.exs index 2826670d..53589cc9 100644 --- a/test/cli_test.exs +++ b/test/cli_test.exs @@ -1,8 +1,39 @@ defmodule ElixirScript.CLI.Test do use ExUnit.Case + import ExUnit.CaptureIO test "parse_args" do {_, args} = ElixirScript.CLI.parse_args(["Atom", "--format", "umd"]) assert args == [format: "umd"] end + + test "process help" do + assert capture_io(fn -> + ElixirScript.CLI.process(:help) + end) =~ "usage: elixirscript [options]" + end + + test "process version" do + assert capture_io(fn -> + ElixirScript.CLI.process(:version) + end) =~ Mix.Project.config()[:version] + end + + test "process unknown" do + assert capture_io(fn -> + ElixirScript.CLI.process({"", [unknown: ""]}) + end) =~ "usage: elixirscript [options]" + end + + test "process input" do + assert capture_io(fn -> + ElixirScript.CLI.process({["Atom"], []}) + end) =~ "export default Elixir" + end + + test "process js modules" do + assert capture_io(fn -> + ElixirScript.CLI.process({["Atom"], [js_module: "React:react"]}) + end) =~ "import React from 'react'" + end end \ No newline at end of file diff --git a/test/passes/translate/forms/js_test.exs b/test/passes/translate/forms/js_test.exs new file mode 100644 index 00000000..c6d7c121 --- /dev/null +++ b/test/passes/translate/forms/js_test.exs @@ -0,0 +1,105 @@ +defmodule ElixirScript.Translate.Forms.JS.Test do + use ExUnit.Case + alias ElixirScript.Translate.Form + alias ESTree.Tools.Builder, as: J + + setup_all do + {:ok, pid} = ElixirScript.State.start_link(%{}) + + state = %{ + pid: pid, + vars: %{} + } + + [state: state] + end + + test "debugger" do + ast = {{:., [], [JS, :debugger]}, [], []} + state = %{function: {:each, nil}, module: Enum, vars: %{:_ => 0, "entry" => 0, "enumerable" => 0, "fun" => 0}} + + {js_ast, _} = Form.compile(ast, state) + assert js_ast == J.debugger_statement() + end + + test "this" do + ast = {{:., [], [JS, :this]}, [], []} + state = %{function: {:each, nil}, module: Enum, vars: %{:_ => 0, "entry" => 0, "enumerable" => 0, "fun" => 0}} + + {js_ast, _} = Form.compile(ast, state) + assert js_ast == J.this_expression() + end + + test "new" do + ast = {{:., [], [JS, :new]}, [], [BLT, ["bacon", "lettuce", "tomato"]]} + state = %{function: {:each, nil}, module: Enum, vars: %{:_ => 0, "entry" => 0, "enumerable" => 0, "fun" => 0}} + + {js_ast, _} = Form.compile(ast, state) + assert js_ast == J.new_expression( + J.identifier("BLT"), + [ + J.literal("bacon"), + J.literal("lettuce"), + J.literal("tomato") + ] + ) + end + + + test "throw" do + ast = {{:., [], [JS, :throw]}, [], [1]} + state = %{function: {:each, nil}, module: Enum, vars: %{:_ => 0, "entry" => 0, "enumerable" => 0, "fun" => 0}} + + {js_ast, _} = Form.compile(ast, state) + assert js_ast == J.throw_statement(J.literal(1)) + end + + test "import" do + ast = {{:., [], [JS, :import]}, [], ["react"]} + state = %{function: {:each, nil}, module: Enum, vars: %{:_ => 0, "entry" => 0, "enumerable" => 0, "fun" => 0}} + + {js_ast, _} = Form.compile(ast, state) + assert js_ast == J.call_expression( + J.identifier("import"), + [J.literal("react")] + ) + end + + test "global function or property" do + ast = {{:., [], [JS, :self]}, [], []} + state = %{function: {:each, nil}, module: Enum, vars: %{:_ => 0, "entry" => 0, "enumerable" => 0, "fun" => 0}} + + {js_ast, _} = Form.compile(ast, state) + assert js_ast == J.call_expression( + ElixirScript.Translate.Forms.JS.call_property(), + [ + ElixirScript.Translate.Forms.JS.global(), + J.literal("self") + ] + ) + end + + test "global function with params" do + ast = {{:., [], [JS, :self]}, [], ["something"]} + state = %{function: {:each, nil}, module: Enum, vars: %{:_ => 0, "entry" => 0, "enumerable" => 0, "fun" => 0}} + + {js_ast, _} = Form.compile(ast, state) + assert js_ast == J.call_expression( + J.identifier(:self), + [J.literal("something")] + ) + end + + test "JavaScript module call", %{state: state} do + ast = {{:., [], [JS.Object, :keys]}, [], [{:obj, [], nil}]} + + {js_ast, _} = Form.compile(ast, state) + assert js_ast == J.call_expression( + J.member_expression( + J.identifier("Object"), + J.identifier("keys") + ), + [J.identifier("obj")] + ) + end +end \ No newline at end of file From 72323bf42b56b071f090b1a0f008d0284c37b92c Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Sun, 25 Jun 2017 21:09:40 -0500 Subject: [PATCH 135/418] Show cover information in travis tests --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 3333d660..859e3269 100644 --- a/.travis.yml +++ b/.travis.yml @@ -16,7 +16,7 @@ script: - mix deps.get - mix compile - yarn build - - mix test + - mix test --cover - yarn test - yarn test-app notifications: From 98c68911cff32b8ed9162ae2bfe8e90a482a7075 Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Mon, 26 Jun 2017 19:52:35 -0500 Subject: [PATCH 136/418] Try to update elixir version in travis.yml and use otp 20 --- .travis.yml | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/.travis.yml b/.travis.yml index 859e3269..ce075d5f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,7 +1,5 @@ sudo: false -language: elixir -elixir: - - 1.5.0-rc.0 +language: erlang otp_release: - 20.0 env: @@ -10,13 +8,16 @@ install: - rm -rf ~/.nvm && git clone https://github.com/creationix/nvm.git ~/.nvm && (cd ~/.nvm && git checkout `git describe --abbrev=0 --tags`) && source ~/.nvm/nvm.sh && nvm install $TRAVIS_NODE_VERSION - npm install -g yarn - yarn -script: - - mix local.hex --force +before_script: + - wget https://repo.hex.pm/builds/elixir/v1.5.0-rc.0-otp-20.zip + - unzip -d elixir v1.5.0-rc.0-otp-20.zip + - export PATH=$(pwd)/elixir/bin:${PATH} - mix local.rebar --force + - mix local.hex --force - mix deps.get - - mix compile +script: - yarn build - - mix test --cover + - mix test - yarn test - yarn test-app notifications: From ed4dbcc67894950d067f6382a60d1b978c3d23b8 Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Tue, 27 Jun 2017 21:29:24 -0500 Subject: [PATCH 137/418] Add all lists functions used in List module --- .../lib/core/erlang_compat/lists.js | 145 ++++++++++++++++++ .../tests/core/erlang_compat/lists_spec.js | 22 +++ 2 files changed, 167 insertions(+) diff --git a/src/javascript/lib/core/erlang_compat/lists.js b/src/javascript/lib/core/erlang_compat/lists.js index a926fab9..c9e4eacc 100644 --- a/src/javascript/lib/core/erlang_compat/lists.js +++ b/src/javascript/lib/core/erlang_compat/lists.js @@ -1,4 +1,5 @@ // http://erlang.org/doc/man/lists.html +import ErlangTypes from 'erlang-types'; function reverse(list) { return [...list].reverse(); @@ -10,7 +11,151 @@ function foreach(fun, list) { return Symbol.for('ok'); } +function duplicate(n, elem) { + const list = []; + + while (list.length < n) { + list.push(elem); + } + + return list; +} + +function flatten(deepList, tail = []) { + const val = deepList.reduce((acc, value) => { + if (Array.isArray(value)) { + return acc.concat(flatten(value)); + } + + return acc.concat(value); + }, []); + + return val.concat(tail); +} + +function foldl(fun, acc0, list) { + return list.reduce((acc, value) => { + return fun(value, acc); + }, acc0); +} + +function foldr(fun, acc0, list) { + return foldl(fun, acc0, reverse(list)); +} + +function keyfind(key, n, tupleList) { + for (const tuple of tupleList) { + if (tuple.get(n) === key) { + return tuple; + } + } + + return false; +} + +function keymember(key, n, tupleList) { + if (keyfind(key, n, tupleList) === false) { + return false; + } + + return true; +} + +function keyreplace(key, n, tupleList, newTuple) { + const newTupleList = [...tupleList]; + + for (let index = 0; index < newTupleList.length; index++) { + if (newTupleList[index].get(n) === key) { + newTupleList[index] = newTuple; + return newTupleList; + } + } + + return newTupleList; +} + +function keysort(n, tupleList) { + const newTupleList = [...tupleList]; + + return newTupleList.sort((a, b) => { + if (a.get(n) < b.get(n)) { + return -1; + } else if (a.get(n) > b.get(n)) { + return 1; + } + + return 0; + }); +} + +function keystore(key, n, tupleList, newTuple) { + const newTupleList = [...tupleList]; + + for (let index = 0; index < newTupleList.length; index++) { + if (newTupleList[index].get(n) === key) { + newTupleList[index] = newTuple; + return newTupleList; + } + } + + return newTupleList.concat(newTuple); +} + +function keydelete(key, n, tupleList) { + const newTupleList = []; + let deleted = false; + + for (let index = 0; index < tupleList.length; index++) { + if (deleted === false && tupleList[index].get(n) === key) { + deleted = true; + } else { + newTupleList.push(tupleList[index]); + } + } + + return newTupleList; +} + +function keytake(key, n, tupleList) { + const result = keyfind(key, n, tupleList); + + if (result !== false) { + return new ErlangTypes.Tuple( + result.get(n), + result, + keydelete(key, n, tupleList) + ); + } + + return false; +} + +function mapfoldl(fun, acc0, list1) { + const listResult = []; + let accResult = acc0; + + for (const item of list1) { + const tuple = fun(item, accResult); + listResult.push(tuple.get(0)); + accResult = tuple.get(1); + } + + return new ErlangTypes.Tuple(listResult, accResult); +} + export default { reverse, foreach, + duplicate, + flatten, + foldl, + foldr, + keydelete, + keyfind, + keymember, + keyreplace, + keysort, + keystore, + keytake, + mapfoldl, }; diff --git a/src/javascript/tests/core/erlang_compat/lists_spec.js b/src/javascript/tests/core/erlang_compat/lists_spec.js index 4e3fbb4e..491abd15 100644 --- a/src/javascript/tests/core/erlang_compat/lists_spec.js +++ b/src/javascript/tests/core/erlang_compat/lists_spec.js @@ -4,3 +4,25 @@ import Core from '../../../lib/core'; test('reverse', t => { t.deepEqual(Core.lists.reverse([1, 2, 3]), [3, 2, 1]); }); + +test('duplicate', t => { + t.deepEqual(Core.lists.duplicate(0, 1), []); + t.deepEqual(Core.lists.duplicate(1, 1), [1]); + t.deepEqual(Core.lists.duplicate(2, 1), [1, 1]); +}); + +test('flatten', t => { + t.deepEqual(Core.lists.flatten([1, 2, 3]), [1, 2, 3]); + t.deepEqual(Core.lists.flatten([1, [[2], 3]]), [1, 2, 3]); +}); + +test('foldl', t => { + t.deepEqual(Core.lists.foldl((v, acc) => acc + v, 0, [1, 2, 3]), 6); +}); + +test('foldr', t => { + t.deepEqual( + Core.lists.foldr((v, acc) => acc + v.toString(), '', [1, 2, 3]), + '321' + ); +}); From e009885941795a9c39a1f793358b15d492c1da15 Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Tue, 27 Jun 2017 21:33:35 -0500 Subject: [PATCH 138/418] Add map function to lists module --- src/javascript/lib/core/erlang_compat/lists.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/javascript/lib/core/erlang_compat/lists.js b/src/javascript/lib/core/erlang_compat/lists.js index c9e4eacc..1c9a3974 100644 --- a/src/javascript/lib/core/erlang_compat/lists.js +++ b/src/javascript/lib/core/erlang_compat/lists.js @@ -143,6 +143,10 @@ function mapfoldl(fun, acc0, list1) { return new ErlangTypes.Tuple(listResult, accResult); } +function map(fun, list) { + return list.map(value => fun(value)); +} + export default { reverse, foreach, @@ -158,4 +162,5 @@ export default { keystore, keytake, mapfoldl, + map, }; From 2a4808fc169fb6f36e36f23b0e1e8aaa3c91a077 Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Wed, 28 Jun 2017 20:42:58 -0500 Subject: [PATCH 139/418] Add more lists functions --- .../lib/core/erlang_compat/lists.js | 80 +++++++++++++++++++ 1 file changed, 80 insertions(+) diff --git a/src/javascript/lib/core/erlang_compat/lists.js b/src/javascript/lib/core/erlang_compat/lists.js index 1c9a3974..d2de47b5 100644 --- a/src/javascript/lib/core/erlang_compat/lists.js +++ b/src/javascript/lib/core/erlang_compat/lists.js @@ -143,10 +143,83 @@ function mapfoldl(fun, acc0, list1) { return new ErlangTypes.Tuple(listResult, accResult); } +function concat(things) { + return things.map(v => v.toString()).join(); +} + function map(fun, list) { return list.map(value => fun(value)); } +function filter(pred, list1) { + return list1.filter(x => pred(x)); +} + +function filtermap(fun, list1) { + const list2 = []; + + for (const item of list1) { + const value = fun(item); + + if (value === true) { + list2.push(item); + } else if (value instanceof ErlangTypes.Tuple && value.get(0) === true) { + list2.push(value.get(1)); + } + } + + return list2; +} + +function member(elem, list) { + for (const item of list) { + if (item === elem) { + return true; + } + } + + return false; +} + +function all(pred, list) { + for (const item of list) { + if (pred(item) === false) { + return false; + } + } + + return true; +} + +function any(pred, list) { + for (const item of list) { + if (pred(item) === true) { + return true; + } + } + + return false; +} + +function splitwith(pred, list) { + let switchToList2 = false; + const list1 = []; + const list2 = []; + + for (const item of list) { + if (switchToList2 === true) { + list2.push(item); + } else if (pred(item) === true) { + list1.push(item); + } else { + switchToList2 = true; + list2.push(item); + } + } + + return new ErlangTypes.Tuple(list1, list2); +} + export default { reverse, foreach, @@ -162,5 +235,12 @@ export default { keystore, keytake, mapfoldl, + concat, map, + filter, + filtermap, + member, + all, + any, + splitwith, }; From 82f57f4af7ffa9fa62add04b29d54350189860b0 Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Wed, 28 Jun 2017 20:48:50 -0500 Subject: [PATCH 140/418] Add lists.sort --- .../lib/core/erlang_compat/lists.js | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/src/javascript/lib/core/erlang_compat/lists.js b/src/javascript/lib/core/erlang_compat/lists.js index d2de47b5..52db1b08 100644 --- a/src/javascript/lib/core/erlang_compat/lists.js +++ b/src/javascript/lib/core/erlang_compat/lists.js @@ -220,6 +220,26 @@ function splitwith(pred, list) { return new ErlangTypes.Tuple(list1, list2); } +function sort(...args) { + if (args.length === 1) { + const list2 = [...args[0]]; + return list2.sort(); + } + + const fun = args[0]; + const list2 = [...args[1]]; + + return list2.sort((a, b) => { + const result = fun(a, b); + + if (result === true) { + return -1; + } + + return 1; + }); +} + export default { reverse, foreach, @@ -243,4 +263,5 @@ export default { all, any, splitwith, + sort, }; From a4edc213aabba8429db42c57a4f81d32eff8f82d Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Thu, 29 Jun 2017 02:50:34 -0500 Subject: [PATCH 141/418] Add maps functions found in Map module --- src/javascript/lib/core/erlang_compat/maps.js | 135 +++++++++++++++++- 1 file changed, 134 insertions(+), 1 deletion(-) diff --git a/src/javascript/lib/core/erlang_compat/maps.js b/src/javascript/lib/core/erlang_compat/maps.js index fdda87d3..c29c795e 100644 --- a/src/javascript/lib/core/erlang_compat/maps.js +++ b/src/javascript/lib/core/erlang_compat/maps.js @@ -1,12 +1,14 @@ // http://erlang.org/doc/man/maps.html import ErlangTypes from 'erlang-types'; +import erlang from './erlang'; const OK = Symbol.for('ok'); const ERROR = Symbol.for('error'); const BADMAP = Symbol.for('badmap'); +const BADKEY = Symbol.for('badkey'); function find(key, map) { - if (map instanceof Object === false) { + if (erlang.is_map(map) === false) { return new ErlangTypes.Tuple(BADMAP, map); } @@ -29,7 +31,138 @@ function fold(fun, init, map) { return acc; } +function remove(key, map1) { + if (erlang.is_map(map1) === false) { + return new ErlangTypes.Tuple(BADMAP, map1); + } + + const map2 = { ...map1 }; + + delete map2[key]; + + return map2; +} + +function to_list(map) { + if (erlang.is_map(map) === false) { + return new ErlangTypes.Tuple(BADMAP, map); + } + + return Object.entries(map).map(entry => { + return ErlangTypes.Tuple(...entry); + }); +} + +function from_list(list) { + return list.reduce((acc, item) => { + const [key, value] = item; + acc[key] = value; + + return acc; + }, {}); +} + +function keys(map) { + if (erlang.is_map(map) === false) { + return new ErlangTypes.Tuple(BADMAP, map); + } + + return Object.keys(map); +} + +function values(map) { + if (erlang.is_map(map) === false) { + return new ErlangTypes.Tuple(BADMAP, map); + } + + return Object.values(map); +} + +function is_key(key, map) { + return map.hasOwnProperty(key); +} + +function put(key, value, map1) { + if (erlang.is_map(map1) === false) { + return new ErlangTypes.Tuple(BADMAP, map1); + } + + const map2 = { ...map1, [key]: value }; + + return map2; +} + +function merge(map1, map2) { + if (erlang.is_map(map1) === false) { + return new ErlangTypes.Tuple(BADMAP, map1); + } + + if (erlang.is_map(map2) === false) { + return new ErlangTypes.Tuple(BADMAP, map2); + } + + return { ...map1, ...map2 }; +} + +function update(key, value, map1) { + if (erlang.is_map(map1) === false) { + return new ErlangTypes.Tuple(BADMAP, map1); + } + + if (is_key(key) === false) { + return new ErlangTypes.Tuple(BADKEY, key); + } + + return { ...map1, [key]: value }; +} + +function get(...args) { + const key = args[0]; + const map = args[1]; + + if (erlang.is_map(map) === false) { + return new ErlangTypes.Tuple(BADMAP, map); + } + + if (is_key(key)) { + return map[key]; + } + + if (args.length === 3) { + return args[2]; + } + + return new ErlangTypes.Tuple(BADKEY, key); +} + +function take(key, map1) { + if (erlang.is_map(map1) === false) { + return new ErlangTypes.Tuple(BADMAP, map1); + } + + if (!is_key(key)) { + return ERROR; + } + + const value = map1[key]; + const map2 = { ...map1 }; + delete map2[key]; + + return new ErlangTypes.Tuple(value, map2); +} + export default { find, fold, + remove, + to_list, + from_list, + keys, + values, + is_key, + put, + merge, + update, + get, + take, }; From 863df936c2bcbae067e19ede6ddf48c9e6d41c80 Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Thu, 29 Jun 2017 03:01:26 -0500 Subject: [PATCH 142/418] Remove spread operator calls with Object.assign --- src/javascript/lib/core/erlang_compat/maps.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/javascript/lib/core/erlang_compat/maps.js b/src/javascript/lib/core/erlang_compat/maps.js index c29c795e..7319dbf3 100644 --- a/src/javascript/lib/core/erlang_compat/maps.js +++ b/src/javascript/lib/core/erlang_compat/maps.js @@ -36,7 +36,7 @@ function remove(key, map1) { return new ErlangTypes.Tuple(BADMAP, map1); } - const map2 = { ...map1 }; + const map2 = Object.assign({}, map1); delete map2[key]; @@ -87,7 +87,7 @@ function put(key, value, map1) { return new ErlangTypes.Tuple(BADMAP, map1); } - const map2 = { ...map1, [key]: value }; + const map2 = Object.assign({}, map1, { [key]: value }); return map2; } @@ -101,7 +101,7 @@ function merge(map1, map2) { return new ErlangTypes.Tuple(BADMAP, map2); } - return { ...map1, ...map2 }; + return Object.assign({}, map1, map2); } function update(key, value, map1) { @@ -113,7 +113,7 @@ function update(key, value, map1) { return new ErlangTypes.Tuple(BADKEY, key); } - return { ...map1, [key]: value }; + return Object.assign({}, map1, { [key]: value }); } function get(...args) { @@ -145,7 +145,7 @@ function take(key, map1) { } const value = map1[key]; - const map2 = { ...map1 }; + const map2 = Object.assign({}, map1); delete map2[key]; return new ErlangTypes.Tuple(value, map2); From d9874df6516825e228474b5230f47ef9d43342c3 Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Fri, 30 Jun 2017 06:04:23 -0500 Subject: [PATCH 143/418] Fix index off by one issues. Add tuple functions --- .../lib/core/erlang_compat/erlang.js | 55 +++++++++++++++++++ .../lib/core/erlang_compat/lists.js | 14 ++--- 2 files changed, 62 insertions(+), 7 deletions(-) diff --git a/src/javascript/lib/core/erlang_compat/erlang.js b/src/javascript/lib/core/erlang_compat/erlang.js index 3ca28bf6..8eee209e 100644 --- a/src/javascript/lib/core/erlang_compat/erlang.js +++ b/src/javascript/lib/core/erlang_compat/erlang.js @@ -197,6 +197,54 @@ function is_binary(value) { return typeof value === 'string' || value instanceof String; } +function element(n, tuple) { + return tuple.get(n - 1); +} + +function setelement(index, tuple1, value) { + const tupleData = [...tuple1.data]; + + tupleData[index - 1] = value; + + return new ErlangTypes.Tuple(...tupleData); +} + +function make_tuple(arity, initialValue) { + const list = []; + + for (let i = 0; i < arity; i++) { + list.push(initialValue); + } + + return new ErlangTypes.Tuple(...list); +} + +function insert_element(index, tuple, term) { + const list = [...tuple.data]; + list.splice(index - 1, 0, term); + + return new ErlangTypes.Tuple(...list); +} + +function append_element(tuple, term) { + const list = [...tuple.data]; + list.push(term); + + return new ErlangTypes.Tuple(...list); +} + +function delete_element(index, tuple) { + const list = [...tuple.data]; + list.splice(index - 1, 1); + + return new ErlangTypes.Tuple(...list); +} + +function tuple_to_list(tuple) { + const list = [...tuple.data]; + return list; +} + export default { atom_to_binary, binary_to_atom, @@ -239,4 +287,11 @@ export default { is_tuple, is_atom, is_binary, + element, + setelement, + make_tuple, + insert_element, + append_element, + delete_element, + tuple_to_list, }; diff --git a/src/javascript/lib/core/erlang_compat/lists.js b/src/javascript/lib/core/erlang_compat/lists.js index 52db1b08..b06cc30d 100644 --- a/src/javascript/lib/core/erlang_compat/lists.js +++ b/src/javascript/lib/core/erlang_compat/lists.js @@ -45,7 +45,7 @@ function foldr(fun, acc0, list) { function keyfind(key, n, tupleList) { for (const tuple of tupleList) { - if (tuple.get(n) === key) { + if (tuple.get(n - 1) === key) { return tuple; } } @@ -65,7 +65,7 @@ function keyreplace(key, n, tupleList, newTuple) { const newTupleList = [...tupleList]; for (let index = 0; index < newTupleList.length; index++) { - if (newTupleList[index].get(n) === key) { + if (newTupleList[index].get(n - 1) === key) { newTupleList[index] = newTuple; return newTupleList; } @@ -78,9 +78,9 @@ function keysort(n, tupleList) { const newTupleList = [...tupleList]; return newTupleList.sort((a, b) => { - if (a.get(n) < b.get(n)) { + if (a.get(n - 1) < b.get(n - 1)) { return -1; - } else if (a.get(n) > b.get(n)) { + } else if (a.get(n - 1) > b.get(n - 1)) { return 1; } @@ -92,7 +92,7 @@ function keystore(key, n, tupleList, newTuple) { const newTupleList = [...tupleList]; for (let index = 0; index < newTupleList.length; index++) { - if (newTupleList[index].get(n) === key) { + if (newTupleList[index].get(n - 1) === key) { newTupleList[index] = newTuple; return newTupleList; } @@ -106,7 +106,7 @@ function keydelete(key, n, tupleList) { let deleted = false; for (let index = 0; index < tupleList.length; index++) { - if (deleted === false && tupleList[index].get(n) === key) { + if (deleted === false && tupleList[index].get(n - 1) === key) { deleted = true; } else { newTupleList.push(tupleList[index]); @@ -121,7 +121,7 @@ function keytake(key, n, tupleList) { if (result !== false) { return new ErlangTypes.Tuple( - result.get(n), + result.get(n - 1), result, keydelete(key, n, tupleList) ); From 739208aa2602d2aafb52b11b804f2cfb11ad1b3d Mon Sep 17 00:00:00 2001 From: Craig Spaeth Date: Sat, 1 Jul 2017 13:16:55 -0400 Subject: [PATCH 144/418] Use spread operator to fix cond function --- src/javascript/lib/core/special_forms.js | 2 +- src/javascript/tests/cond.spec.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/javascript/lib/core/special_forms.js b/src/javascript/lib/core/special_forms.js index b093fee6..fbb830cd 100644 --- a/src/javascript/lib/core/special_forms.js +++ b/src/javascript/lib/core/special_forms.js @@ -4,7 +4,7 @@ function _case(condition, clauses) { return Core.Patterns.defmatch(...clauses)(condition); } -function cond(clauses) { +function cond(...clauses) { for (const clause of clauses) { if (clause[0]) { return clause[1](); diff --git a/src/javascript/tests/cond.spec.js b/src/javascript/tests/cond.spec.js index c5d66aed..6d1d87e8 100644 --- a/src/javascript/tests/cond.spec.js +++ b/src/javascript/tests/cond.spec.js @@ -10,7 +10,7 @@ test('cond', t => { [true, () => 'This will'], ]; - const result = SpecialForms.cond(clauses); + const result = SpecialForms.cond(...clauses); t.is(result, 'This will'); }); From 9e8dc4203e76bd537f0c3cbbccc4eb2a5df8b769 Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Sat, 1 Jul 2017 17:00:33 -0500 Subject: [PATCH 145/418] Update confusing comment. Fix some warnings in Module --- lib/elixir_script/passes/translate/module.ex | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/lib/elixir_script/passes/translate/module.ex b/lib/elixir_script/passes/translate/module.ex index c46dc80e..b6184ac2 100644 --- a/lib/elixir_script/passes/translate/module.ex +++ b/lib/elixir_script/passes/translate/module.ex @@ -1,7 +1,7 @@ defmodule ElixirScript.Translate.Module do @moduledoc false alias ESTree.Tools.Builder, as: J - alias ElixirScript.Translate.{Function, Form, Identifier} + alias ElixirScript.Translate.Function alias ElixirScript.State, as: ModuleState @doc """ @@ -28,7 +28,7 @@ defmodule ElixirScript.Translate.Module do module: module, pid: pid } - + # Filter so that we only have the # Used functions to compile reachable_defs = Enum.filter(defs, fn @@ -52,8 +52,7 @@ defmodule ElixirScript.Translate.Module do combined_defs = combine_defs(used_defs) exports = make_exports(module, combined_defs) - # Don't skip compilation and output of modules that don't have - # any public functions + # If there are no public exports, skip compilation case exports do %ESTree.ObjectExpression{ properties: [] } -> nil @@ -85,7 +84,7 @@ defmodule ElixirScript.Translate.Module do defp make_exports(module, reachable_defs) do exports = Enum.reduce(reachable_defs, [], fn - {{name, arity}, :def, _, _}, list -> + {{name, _arity}, :def, _, _}, list -> function_name = ElixirScript.Translate.Identifier.make_identifier(name) list ++ [J.property(function_name, function_name, :init, true)] _, list -> From c9ef9084eb7d42c0e779c2864ae6b0b1c6fc9da1 Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Sat, 1 Jul 2017 17:05:04 -0500 Subject: [PATCH 146/418] Update README.md --- README.md | 48 ++++++++++++++---------------------------------- 1 file changed, 14 insertions(+), 34 deletions(-) diff --git a/README.md b/README.md index a3a106c0..5f78b35d 100644 --- a/README.md +++ b/README.md @@ -14,47 +14,27 @@ Usage Please check the [Getting Started Guide](GettingStarted.md) for usage -FAQ, Limitations -======== - -Please check the [FAQ](FAQ.md) - - Development =========== -Clone the repo - - git clone git@github.com:bryanjos/elixirscript.git - -Get dependencies +```bash +# Clone the repo +git clone git@github.com:bryanjos/elixirscript.git - mix deps.get - yarn +#Get dependencies +mix deps.get +yarn -Create Elixir.Bootstrap.js - - yarn build - -Compile - - mix compile - -Test - - mix test - yarn test - +# Create Elixir.Bootstrap.js +yarn build -Build -============= - MIX_ENV=prod mix do clean, compile, dist +# Compile +mix compile -This will build a tarball in the dist folder. -By default the escript built will look into the folder above it for the -core JavaScript files needed for ElixirScript. To change the location, -update the `lib_path` config variable in the `:elixir_script` config block -to the path to look in and then do a clean build. +# Test +mix test +yarn test +``` Communication ======== From c655d9951d8a6602873e58c2be03ca54f13ea7fc Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Sat, 1 Jul 2017 17:21:19 -0500 Subject: [PATCH 147/418] Fix a bunch of lints --- lib/elixir_script/beam.ex | 6 +-- lib/elixir_script/cli.ex | 10 ++--- lib/elixir_script/compiler.ex | 4 +- lib/elixir_script/lib/string.ex | 3 -- lib/elixir_script/module_systems/common.ex | 2 +- lib/elixir_script/module_systems/namespace.ex | 6 +-- lib/elixir_script/module_systems/umd.ex | 6 ++- .../passes/find_used_functions.ex | 14 +++---- lib/elixir_script/passes/find_used_modules.ex | 18 ++++----- lib/elixir_script/passes/output.ex | 8 ++-- lib/elixir_script/passes/output/js_module.ex | 2 +- lib/elixir_script/passes/translate/form.ex | 4 +- .../passes/translate/forms/js.ex | 2 +- .../passes/translate/forms/map.ex | 2 +- .../passes/translate/forms/pattern.ex | 4 +- .../translate/forms/pattern/patterns.ex | 2 +- .../passes/translate/forms/receive.ex | 2 +- .../passes/translate/forms/remote.ex | 38 +++++++++---------- .../passes/translate/function.ex | 18 ++++++--- .../passes/translate/identifier.ex | 2 +- lib/elixir_script/passes/translate/module.ex | 8 ++-- .../passes/translate/protocol.ex | 2 +- lib/elixir_script/state.ex | 6 +-- lib/mix/tasks/compile.elixir_script.ex | 2 +- lib/mix/tasks/elixirscript.watch.ex | 4 +- 25 files changed, 90 insertions(+), 85 deletions(-) diff --git a/lib/elixir_script/beam.ex b/lib/elixir_script/beam.ex index f9611c5a..a5a3aa46 100644 --- a/lib/elixir_script/beam.ex +++ b/lib/elixir_script/beam.ex @@ -8,8 +8,8 @@ defmodule ElixirScript.Beam do all the protocol implementations """ @spec debug_info(atom) :: {:ok | :error, map | binary} - def debug_info(module) - + def debug_info(module) + #Replacing String module with our ElixirScript's version def debug_info(String) do case debug_info(ElixirScript.String) do @@ -19,7 +19,7 @@ defmodule ElixirScript.Beam do e end end - + def debug_info(module) when is_atom(module) do #TODO: Get modified date from _beam_path to check for cached version? with {_, beam, _beam_path} <- :code.get_object_code(module), diff --git a/lib/elixir_script/cli.ex b/lib/elixir_script/cli.ex index 9bd4daea..9fc992ba 100644 --- a/lib/elixir_script/cli.ex +++ b/lib/elixir_script/cli.ex @@ -5,17 +5,17 @@ defmodule ElixirScript.CLI do @switches [ output: :string, - help: :boolean, + help: :boolean, version: :boolean, - watch: :boolean, - format: :string, + watch: :boolean, + format: :string, js_module: [:string, :keep] ] @aliases [ o: :output, - h: :help, - v: :version, + h: :help, + v: :version, f: :format ] diff --git a/lib/elixir_script/compiler.ex b/lib/elixir_script/compiler.ex index 5dc1195d..79fe7238 100644 --- a/lib/elixir_script/compiler.ex +++ b/lib/elixir_script/compiler.ex @@ -21,7 +21,7 @@ defmodule ElixirScript.Compiler do IO.puts "Finding used functions" ElixirScript.FindUsedFunctions.execute(entry_modules, pid) - + IO.puts "Compiling" modules = ElixirScript.State.list_modules(pid) ElixirScript.Translate.execute(modules, pid) @@ -29,7 +29,7 @@ defmodule ElixirScript.Compiler do IO.puts "Building Output" modules = ElixirScript.State.list_modules(pid) result = ElixirScript.Output.execute(modules, pid) - + ElixirScript.State.stop(pid) result diff --git a/lib/elixir_script/lib/string.ex b/lib/elixir_script/lib/string.ex index 6ace3e43..1ad3d9bf 100644 --- a/lib/elixir_script/lib/string.ex +++ b/lib/elixir_script/lib/string.ex @@ -137,7 +137,6 @@ defmodule ElixirScript.String do end end - def ends_with?(str, suffix) when is_binary(suffix) do str.endsWith(suffix) end @@ -163,7 +162,6 @@ defmodule ElixirScript.String do str.repeat(n) end - def contains?(str, s) when is_binary(s) do str.indexOf(s) > -1 end @@ -185,7 +183,6 @@ defmodule ElixirScript.String do end end - def codepoints(str) do do_codepoints(str, []) end diff --git a/lib/elixir_script/module_systems/common.ex b/lib/elixir_script/module_systems/common.ex index f4c00837..9554e687 100644 --- a/lib/elixir_script/module_systems/common.ex +++ b/lib/elixir_script/module_systems/common.ex @@ -19,7 +19,7 @@ defmodule ElixirScript.ModuleSystems.Common do end defp import_module(module_name, from) do - js_module_name = ElixirScript.Translate.Identifier.make_namespace_members(module_name) + js_module_name = ElixirScript.Translate.Identifier.make_namespace_members(module_name) do_import_module(js_module_name, from) end diff --git a/lib/elixir_script/module_systems/namespace.ex b/lib/elixir_script/module_systems/namespace.ex index 200ae0c3..4a4cf96d 100644 --- a/lib/elixir_script/module_systems/namespace.ex +++ b/lib/elixir_script/module_systems/namespace.ex @@ -22,7 +22,7 @@ defmodule ElixirScript.ModuleSystems.Namespace do JS.identifier(:build_namespace) ) ) - ) + ) end defp make_namespace_body(module_name, body, exports) do @@ -35,7 +35,7 @@ defmodule ElixirScript.ModuleSystems.Namespace do exports = if is_nil(exports) do JS.object_expression([]) - else + else exports end @@ -44,7 +44,7 @@ defmodule ElixirScript.ModuleSystems.Namespace do exports ) - declaration = JS.variable_declaration([declarator], :const) + declaration = JS.variable_declaration([declarator], :const) assign = JS.assignment_expression( :=, diff --git a/lib/elixir_script/module_systems/umd.ex b/lib/elixir_script/module_systems/umd.ex index 4aefe6d3..e9894c24 100644 --- a/lib/elixir_script/module_systems/umd.ex +++ b/lib/elixir_script/module_systems/umd.ex @@ -3,7 +3,9 @@ defmodule ElixirScript.ModuleSystems.UMD do alias ESTree.Tools.Builder, as: JS def build(imports, js_imports, body, exports) do - module_imports = Enum.map(imports, fn {module, path} -> import_module(module, path) end) + module_imports = Enum.map(imports, fn + {module, path} -> import_module(module, path) + end) imports = js_imports |> Enum.map(fn @@ -17,7 +19,7 @@ defmodule ElixirScript.ModuleSystems.UMD do end defp import_module(module_name, from) do - js_module_name = ElixirScript.Translate.Identifier.make_namespace_members(module_name) + js_module_name = ElixirScript.Translate.Identifier.make_namespace_members(module_name) {js_module_name, JS.literal(from)} end diff --git a/lib/elixir_script/passes/find_used_functions.ex b/lib/elixir_script/passes/find_used_functions.ex index e656a580..af659000 100644 --- a/lib/elixir_script/passes/find_used_functions.ex +++ b/lib/elixir_script/passes/find_used_functions.ex @@ -1,6 +1,6 @@ defmodule ElixirScript.FindUsedFunctions do @moduledoc false - alias ElixirScript.State, as: ModuleState + alias ElixirScript.State, as: ModuleState @doc """ Takes a list of entry modules and finds modules they use along with @@ -25,12 +25,12 @@ defmodule ElixirScript.FindUsedFunctions do defp walk_module(module, pid) do %{ - attributes: _attrs, + attributes: _attrs, compile_opts: _compile_opts, definitions: defs, file: _file, - line: _line, - module: ^module, + line: _line, + module: ^module, unreachable: unreachable } = ModuleState.get_module(pid, module) @@ -48,7 +48,7 @@ defmodule ElixirScript.FindUsedFunctions do Enum.each(reachable_defs, fn({name, _type, _, _clauses}) -> ModuleState.add_used(state.pid, module, name) end) - + Enum.each(reachable_defs, &walk(&1, state)) end @@ -171,7 +171,7 @@ defmodule ElixirScript.FindUsedFunctions do defp walk({:receive, _context, blocks}, state) do do_block = Keyword.get(blocks, :do) - after_block = Keyword.get(blocks, :after, nil) + after_block = Keyword.get(blocks, :after, nil) walk_block(do_block, state) @@ -234,7 +234,7 @@ defmodule ElixirScript.FindUsedFunctions do ElixirScript.Translate.Module.is_elixir_module(module) -> walk_module(module, function, length(params), state.pid) true -> - nil + nil end walk(params, state) diff --git a/lib/elixir_script/passes/find_used_modules.ex b/lib/elixir_script/passes/find_used_modules.ex index fcdadbc0..5c7cd5d7 100644 --- a/lib/elixir_script/passes/find_used_modules.ex +++ b/lib/elixir_script/passes/find_used_modules.ex @@ -1,6 +1,6 @@ defmodule ElixirScript.FindUsedModules do @moduledoc false - alias ElixirScript.State, as: ModuleState + alias ElixirScript.State, as: ModuleState @doc """ Takes a list of entry modules and finds modules they use. @@ -27,12 +27,12 @@ defmodule ElixirScript.FindUsedModules do defp walk_module(module, info, pid) do %{ - attributes: _attrs, + attributes: _attrs, compile_opts: _compile_opts, definitions: defs, file: _file, - line: _line, - module: ^module, + line: _line, + module: ^module, unreachable: unreachable } = info @@ -65,9 +65,9 @@ defmodule ElixirScript.FindUsedModules do functions = Enum.map(first_implementation_functions, fn { name, _, _, _} -> name end) ModuleState.put_module(pid, module, %{protocol: true, impls: impls, functions: functions}) - + Enum.each(implementations, fn {impl, info} -> - walk_module(impl, info, pid) + walk_module(impl, info, pid) end) end @@ -180,7 +180,7 @@ defmodule ElixirScript.FindUsedModules do defp walk({:receive, _context, blocks}, state) do do_block = Keyword.get(blocks, :do) - after_block = Keyword.get(blocks, :after, nil) + after_block = Keyword.get(blocks, :after, nil) walk_block(do_block, state) @@ -246,7 +246,7 @@ defmodule ElixirScript.FindUsedModules do end true -> walk(module, state) - walk(function, state) + walk(function, state) end end @@ -255,7 +255,7 @@ defmodule ElixirScript.FindUsedModules do end defp walk({function, _, params}, state) when is_list(params) do - walk(function, state) + walk(function, state) walk(params, state) end diff --git a/lib/elixir_script/passes/output.ex b/lib/elixir_script/passes/output.ex index f5804cc8..f4c1cb4a 100644 --- a/lib/elixir_script/passes/output.ex +++ b/lib/elixir_script/passes/output.ex @@ -11,8 +11,8 @@ defmodule ElixirScript.Output do @spec execute([atom], pid) :: nil def execute(modules, pid) do modules = Enum.filter_map(modules, fn {_, info} -> Map.has_key?(info, :js_ast) end, - fn {_module, info} -> - info.js_ast + fn {_module, info} -> + info.js_ast end ) @@ -58,7 +58,7 @@ defmodule ElixirScript.Output do code end - defp output(code, :stdout) do + defp output(code, :stdout) do IO.puts(code) end @@ -78,6 +78,6 @@ defmodule ElixirScript.Output do path _ -> Path.join([path, @generated_name]) - end + end end end \ No newline at end of file diff --git a/lib/elixir_script/passes/output/js_module.ex b/lib/elixir_script/passes/output/js_module.ex index c0aa3346..8be907ca 100644 --- a/lib/elixir_script/passes/output/js_module.ex +++ b/lib/elixir_script/passes/output/js_module.ex @@ -111,7 +111,7 @@ defmodule ElixirScript.Output.JSModule do J.call_expression( J.member_expression( J.identifier("Symbol"), - J.identifier("for") + J.identifier("for") ), [J.literal(ref.name)] ), diff --git a/lib/elixir_script/passes/translate/form.ex b/lib/elixir_script/passes/translate/form.ex index 662ee8be..f03f6b84 100644 --- a/lib/elixir_script/passes/translate/form.ex +++ b/lib/elixir_script/passes/translate/form.ex @@ -144,10 +144,10 @@ defmodule ElixirScript.Translate.Form do def compile({:cond, _, [[do: clauses]]}, state) do processed_clauses = Enum.map(clauses, fn({:->, _, [clause, clause_body]}) -> { translated_body, state } = ElixirScript.Translate.Function.compile_block(clause_body, state) - + translated_body = translated_body |> Clause.return_last_statement - + translated_body = J.arrow_function_expression([], [], J.block_statement(translated_body)) { translated_clause, _ } = compile(hd(clause), state) diff --git a/lib/elixir_script/passes/translate/forms/js.ex b/lib/elixir_script/passes/translate/forms/js.ex index 49da8f7b..9cf77604 100644 --- a/lib/elixir_script/passes/translate/forms/js.ex +++ b/lib/elixir_script/passes/translate/forms/js.ex @@ -91,4 +91,4 @@ defmodule ElixirScript.Translate.Forms.JS do {ast, state} end -end \ No newline at end of file +end diff --git a/lib/elixir_script/passes/translate/forms/map.ex b/lib/elixir_script/passes/translate/forms/map.ex index 5bc27ba6..28518a92 100644 --- a/lib/elixir_script/passes/translate/forms/map.ex +++ b/lib/elixir_script/passes/translate/forms/map.ex @@ -15,7 +15,7 @@ defmodule ElixirScript.Translate.Forms.Map do [ J.object_expression([]), map, - data + data ] ) diff --git a/lib/elixir_script/passes/translate/forms/pattern.ex b/lib/elixir_script/passes/translate/forms/pattern.ex index a96f589f..93b7c6fb 100644 --- a/lib/elixir_script/passes/translate/forms/pattern.ex +++ b/lib/elixir_script/passes/translate/forms/pattern.ex @@ -19,7 +19,7 @@ defmodule ElixirScript.Translate.Forms.Pattern do x, { patterns, params } -> {pattern, param} = process_pattern(x, state) { patterns ++ List.wrap(pattern), params ++ List.wrap(param) } - end) + end) end defp update_env({ patterns, params }, state) do @@ -102,7 +102,7 @@ defmodule ElixirScript.Translate.Forms.Pattern do { tail_patterns, tail_params } = process_pattern(tail, state) params = head_params ++ tail_params - { [PM.head_tail(hd(head_patterns), hd(tail_patterns))], params } + { [PM.head_tail(hd(head_patterns), hd(tail_patterns))], params } end defp process_pattern({{:., _, [:erlang, :++]}, context, [head, tail]}, state) do diff --git a/lib/elixir_script/passes/translate/forms/pattern/patterns.ex b/lib/elixir_script/passes/translate/forms/pattern/patterns.ex index 70154334..21f313f5 100644 --- a/lib/elixir_script/passes/translate/forms/pattern/patterns.ex +++ b/lib/elixir_script/passes/translate/forms/pattern/patterns.ex @@ -2,7 +2,7 @@ defmodule ElixirScript.Translate.Forms.Pattern.Patterns do @moduledoc false alias ESTree.Tools.Builder, as: J - + @patterns J.member_expression( J.member_expression( J.identifier("Bootstrap"), diff --git a/lib/elixir_script/passes/translate/forms/receive.ex b/lib/elixir_script/passes/translate/forms/receive.ex index 6a51bf24..a23897e5 100644 --- a/lib/elixir_script/passes/translate/forms/receive.ex +++ b/lib/elixir_script/passes/translate/forms/receive.ex @@ -28,4 +28,4 @@ defmodule ElixirScript.Translate.Forms.Receive do { ast, state } end -end \ No newline at end of file +end diff --git a/lib/elixir_script/passes/translate/forms/remote.ex b/lib/elixir_script/passes/translate/forms/remote.ex index b6c8c192..213f9a00 100644 --- a/lib/elixir_script/passes/translate/forms/remote.ex +++ b/lib/elixir_script/passes/translate/forms/remote.ex @@ -27,67 +27,67 @@ defmodule ElixirScript.Translate.Forms.Remote do def compile({:., _, [:erlang, :+]}, state) do ast = erlang_compat_function("erlang", "plus") - { ast, state } + { ast, state } end def compile({:., _, [:erlang, :-]}, state) do ast = erlang_compat_function("erlang", "minus") - { ast, state } + { ast, state } end def compile({:., _, [:erlang, :*]}, state) do ast = erlang_compat_function("erlang", "multiply") - { ast, state } + { ast, state } end def compile({:., _, [:erlang, :/]}, state) do ast = erlang_compat_function("erlang", "div") - { ast, state } + { ast, state } end def compile({:., _, [:erlang, :==]}, state) do ast = erlang_compat_function("erlang", "equal") - { ast, state } + { ast, state } end def compile({:., _, [:erlang, :>]}, state) do ast = erlang_compat_function("erlang", "greaterThan") - { ast, state } + { ast, state } end def compile({:., _, [:erlang, :>=]}, state) do ast = erlang_compat_function("erlang", "greaterThanOrEqualTo") - { ast, state } + { ast, state } end def compile({:., _, [:erlang, :"/="]}, state) do ast = erlang_compat_function("erlang", "doesNotEqual") - { ast, state } + { ast, state } end def compile({:., _, [:erlang, :"<"]}, state) do ast = erlang_compat_function("erlang", "lessThan") - { ast, state } + { ast, state } end def compile({:., _, [:erlang, :"=<"]}, state) do ast = erlang_compat_function("erlang", "lessThanOrEqualTo") - { ast, state } + { ast, state } end def compile({:., _, [:erlang, :"=:="]}, state) do ast = erlang_compat_function("erlang", "strictlyEqual") - { ast, state } + { ast, state } end def compile({:., _, [:erlang, :"=/="]}, state) do ast = erlang_compat_function("erlang", "doesNotStrictlyEqual") - { ast, state } + { ast, state } end def compile({:., _, [:erlang, function]}, state) when function in [:andalso, :and] do ast = erlang_compat_function("erlang", "and") - { ast, state } + { ast, state } end def compile({:., _, [:erlang, function]}, state) when function in [:orelse, :or] do @@ -97,12 +97,12 @@ defmodule ElixirScript.Translate.Forms.Remote do def compile({:., _, [:erlang, :++]}, state) do ast = erlang_compat_function("erlang", "list_concatenation") - { ast, state } + { ast, state } end def compile({:., _, [:erlang, :--]}, state) do ast = erlang_compat_function("erlang", "list_substraction") - { ast, state } + { ast, state } end def compile({:., _, [module, function]}, state) when module in @erlang_modules do @@ -123,12 +123,12 @@ defmodule ElixirScript.Translate.Forms.Remote do def compile({:., _, [function_name]}, state) do Form.compile(function_name, state) end - + def compile({:., _, [module, function]}, state) do function_name = if ElixirScript.Translate.Module.is_js_module(module, state) do ElixirScript.Translate.Identifier.make_extern_function_name(function) else - ElixirScript.Translate.Identifier.make_function_name(function) + ElixirScript.Translate.Identifier.make_function_name(function) end ast = J.member_expression( @@ -179,7 +179,7 @@ defmodule ElixirScript.Translate.Forms.Remote do ["JS" | rest] -> Identifier.make_namespace_members(rest) x -> - Identifier.make_namespace_members(x) + Identifier.make_namespace_members(x) end end @@ -193,6 +193,6 @@ defmodule ElixirScript.Translate.Forms.Remote do J.identifier(module) ), ElixirScript.Translate.Identifier.make_function_name(function) - ) + ) end end \ No newline at end of file diff --git a/lib/elixir_script/passes/translate/function.ex b/lib/elixir_script/passes/translate/function.ex index 23e13f20..a31a93fc 100644 --- a/lib/elixir_script/passes/translate/function.ex +++ b/lib/elixir_script/passes/translate/function.ex @@ -27,9 +27,12 @@ defmodule ElixirScript.Translate.Function do J.identifier("null") ) - arg_matches_declaration = J.variable_declaration([arg_matches_declarator], :let) + arg_matches_declaration = J.variable_declaration( + [arg_matches_declarator], + :let + ) - function_dec = J.arrow_function_expression( + function_dec = J.arrow_function_expression( [J.rest_element(J.identifier("__function_args__"))], [], J.block_statement([ @@ -59,10 +62,13 @@ defmodule ElixirScript.Translate.Function do J.identifier("null") ) - arg_matches_declaration = J.variable_declaration([arg_matches_declarator], :let) + arg_matches_declaration = J.variable_declaration( + [arg_matches_declarator], + :let + ) function_dec = J.function_declaration( - ElixirScript.Translate.Identifier.make_function_name(name), + ElixirScript.Translate.Identifier.make_function_name(name), [J.rest_element(J.identifier("__function_args__"))], [], J.block_statement([ @@ -105,7 +111,7 @@ defmodule ElixirScript.Translate.Function do ) end) |> Enum.reverse - |> Enum.reduce(nil, fn + |> Enum.reduce(nil, fn if_ast, nil -> if_ast if_ast, ast -> @@ -136,7 +142,7 @@ defmodule ElixirScript.Translate.Function do Form.compile!(body, state) end - body = body + body = body |> Clause.return_last_statement declarator = J.variable_declarator( diff --git a/lib/elixir_script/passes/translate/identifier.ex b/lib/elixir_script/passes/translate/identifier.ex index b5c287dd..e91c02d2 100644 --- a/lib/elixir_script/passes/translate/identifier.ex +++ b/lib/elixir_script/passes/translate/identifier.ex @@ -76,7 +76,7 @@ defmodule ElixirScript.Translate.Identifier do end def make_extern_function_name(name) do - J.identifier("#{name}") + J.identifier("#{name}") end end diff --git a/lib/elixir_script/passes/translate/module.ex b/lib/elixir_script/passes/translate/module.ex index b6184ac2..310b455d 100644 --- a/lib/elixir_script/passes/translate/module.ex +++ b/lib/elixir_script/passes/translate/module.ex @@ -14,12 +14,12 @@ defmodule ElixirScript.Translate.Module do def compile(module, info, pid) do %{ - attributes: attrs, + attributes: attrs, compile_opts: _compile_opts, definitions: defs, file: _file, - line: _line, - module: ^module, + line: _line, + module: ^module, unreachable: unreachable, used: used } = info @@ -58,7 +58,7 @@ defmodule ElixirScript.Translate.Module do nil _ -> { compiled_functions, _ } = Enum.map_reduce(combined_defs, state, &Function.compile(&1, &2)) - + js_ast = ElixirScript.ModuleSystems.Namespace.build( module, compiled_functions, diff --git a/lib/elixir_script/passes/translate/protocol.ex b/lib/elixir_script/passes/translate/protocol.ex index 0a02a17e..8dc5deaa 100644 --- a/lib/elixir_script/passes/translate/protocol.ex +++ b/lib/elixir_script/passes/translate/protocol.ex @@ -45,7 +45,7 @@ defmodule ElixirScript.Translate.Protocol do nil ) - ModuleState.put_module(pid, module, Map.put(info, :js_ast, hd(js_ast))) + ModuleState.put_module(pid, module, Map.put(info, :js_ast, hd(js_ast))) end defp build_implementations(impls, pid) do diff --git a/lib/elixir_script/state.ex b/lib/elixir_script/state.ex index b65c7189..f7e82449 100644 --- a/lib/elixir_script/state.ex +++ b/lib/elixir_script/state.ex @@ -6,7 +6,7 @@ defmodule ElixirScript.State do def start_link(compiler_opts) do Agent.start_link(fn -> %{ - compiler_opts: compiler_opts, + compiler_opts: compiler_opts, modules: Keyword.new, refs: [] } @@ -46,7 +46,7 @@ defmodule ElixirScript.State do def add_used(pid, module, {_function, _arity} = func) do Agent.update(pid, fn(state) -> module_info = Keyword.get(state.modules, module) - + used = Map.get(module_info, :used, []) used = used ++ [func] @@ -72,6 +72,6 @@ defmodule ElixirScript.State do def list_modules(pid) do Agent.get(pid, fn(state) -> state.modules - end) + end) end end \ No newline at end of file diff --git a/lib/mix/tasks/compile.elixir_script.ex b/lib/mix/tasks/compile.elixir_script.ex index eec94c8d..85a8871b 100644 --- a/lib/mix/tasks/compile.elixir_script.ex +++ b/lib/mix/tasks/compile.elixir_script.ex @@ -73,7 +73,7 @@ defmodule Mix.Tasks.Compile.ElixirScript do output: Keyword.get(elixirscript_config, :output), format: Keyword.get(elixirscript_config, :format), js_modules: Keyword.get(elixirscript_config, :js_modules, []) - ] + ] {input, opts} end diff --git a/lib/mix/tasks/elixirscript.watch.ex b/lib/mix/tasks/elixirscript.watch.ex index 5235d700..a2d654ef 100644 --- a/lib/mix/tasks/elixirscript.watch.ex +++ b/lib/mix/tasks/elixirscript.watch.ex @@ -23,10 +23,10 @@ defmodule Mix.Tasks.Elixirscript.Watch do def run(_) do Mix.Task.run "app.start" - {input, opts} = Mix.Tasks.Compile.ElixirScript.get_compiler_params() + {input, opts} = Mix.Tasks.Compile.ElixirScript.get_compiler_params() {:ok, _} = ElixirScript.Watcher.start_link( - input, + input, opts ) From 634cc0510e2d8ecf6f3688eafe90a3ed4e8176f3 Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Sat, 1 Jul 2017 22:42:04 -0500 Subject: [PATCH 148/418] Add erlang functions used in Kernel --- .../passes/translate/function.ex | 34 ++++---- .../lib/core/erlang_compat/erlang.js | 79 +++++++++++++++++++ 2 files changed, 96 insertions(+), 17 deletions(-) diff --git a/lib/elixir_script/passes/translate/function.ex b/lib/elixir_script/passes/translate/function.ex index a31a93fc..e98200b2 100644 --- a/lib/elixir_script/passes/translate/function.ex +++ b/lib/elixir_script/passes/translate/function.ex @@ -68,23 +68,23 @@ defmodule ElixirScript.Translate.Function do ) function_dec = J.function_declaration( - ElixirScript.Translate.Identifier.make_function_name(name), - [J.rest_element(J.identifier("__function_args__"))], - [], - J.block_statement([ - arg_matches_declaration, - clauses, - J.throw_statement( - J.new_expression( - J.member_expression( - patterns_ast(), - J.identifier("MatchError") - ), - [J.identifier("__function_args__")] - ) - ) - ]) - ) + ElixirScript.Translate.Identifier.make_function_name(name), + [J.rest_element(J.identifier("__function_args__"))], + [], + J.block_statement([ + arg_matches_declaration, + clauses, + J.throw_statement( + J.new_expression( + J.member_expression( + patterns_ast(), + J.identifier("MatchError") + ), + [J.identifier("__function_args__")] + ) + ) + ]) + ) { function_dec, state } end diff --git a/src/javascript/lib/core/erlang_compat/erlang.js b/src/javascript/lib/core/erlang_compat/erlang.js index 8eee209e..0fd5a647 100644 --- a/src/javascript/lib/core/erlang_compat/erlang.js +++ b/src/javascript/lib/core/erlang_compat/erlang.js @@ -245,6 +245,70 @@ function tuple_to_list(tuple) { return list; } +function abs(number) { + return Math.abs(number); +} + +function apply(...args) { + if (args.length === 2) { + return args[0].apply(this, ...args[1]); + } + + return args[0][atom_to_binary(args[1])].apply(this, ...args[2]); +} + +function binary_part(binary, start, length) { + return binary.substring(start, start + length); +} + +function bit_size(bitstring) { + return bitstring.bit_size; +} + +function byte_size(bitstring) { + return bitstring.byte_size; +} + +function hd(list) { + return list[0]; +} + +function length(list) { + return list.length; +} + +function make_ref() { + return new ErlangTypes.Reference(); +} + +function map_size(map) { + return Object.keys(map).length; +} + +function max(first, second) { + return Math.max(first, second); +} + +function min(first, second) { + return Math.min(first, second); +} + +function round(number) { + return Math.round(number); +} + +function tl(list) { + return list.slice(1); +} + +function trunc(number) { + return Math.trunc(number); +} + +function tuple_size(tuple) { + return tuple.length; +} + export default { atom_to_binary, binary_to_atom, @@ -294,4 +358,19 @@ export default { append_element, delete_element, tuple_to_list, + abs, + apply, + binary_part, + bit_size, + byte_size, + hd, + length, + make_ref, + map_size, + max, + min, + round, + tl, + trunc, + tuple_size }; From cc32253e64ff18128262c0e63639b0c36a48ad0c Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Sun, 2 Jul 2017 20:34:42 -0500 Subject: [PATCH 149/418] Fix some lints. Fixed implementations of some map functions --- .../passes/translate/forms/pattern.ex | 7 ++-- src/javascript/lib/core/erlang_compat/maps.js | 34 +++++++++++++++---- test/support/main.ex | 3 +- 3 files changed, 33 insertions(+), 11 deletions(-) diff --git a/lib/elixir_script/passes/translate/forms/pattern.ex b/lib/elixir_script/passes/translate/forms/pattern.ex index 93b7c6fb..134b8ca8 100644 --- a/lib/elixir_script/passes/translate/forms/pattern.ex +++ b/lib/elixir_script/passes/translate/forms/pattern.ex @@ -4,10 +4,12 @@ defmodule ElixirScript.Translate.Forms.Pattern do alias ElixirScript.Translate.Form alias ElixirScript.Translate.Forms.Bitstring - @moduledoc """ + @moduledoc false + + @doc """ Handles all pattern matching translations """ - + @spec compile(list(), map()) :: { list(), list(), map() } def compile(patterns, state) do patterns |> do_compile(state) @@ -40,6 +42,7 @@ defmodule ElixirScript.Translate.Forms.Pattern do { patterns, params, state } end + @spec get_variable_name(atom(), map()) :: atom() def get_variable_name(function, state) do number = Map.get(state.vars, function) String.to_atom("#{function}#{number}") diff --git a/src/javascript/lib/core/erlang_compat/maps.js b/src/javascript/lib/core/erlang_compat/maps.js index 7319dbf3..6178eba7 100644 --- a/src/javascript/lib/core/erlang_compat/maps.js +++ b/src/javascript/lib/core/erlang_compat/maps.js @@ -24,7 +24,7 @@ function find(key, map) { function fold(fun, init, map) { let acc = init; - for (const [key, value] of Object.entries(map)) { + for (const [key, value] of to_list(map)) { acc = fun(key, value, acc); } @@ -48,9 +48,13 @@ function to_list(map) { return new ErlangTypes.Tuple(BADMAP, map); } - return Object.entries(map).map(entry => { - return ErlangTypes.Tuple(...entry); - }); + const list = []; + + for (const key of keys(map)) { + list.push(new ErlangTypes.Tuple(key, map[key])); + } + + return list; } function from_list(list) { @@ -67,7 +71,17 @@ function keys(map) { return new ErlangTypes.Tuple(BADMAP, map); } - return Object.keys(map); + const keys = []; + + for (const key of Object.getOwnPropertySymbols(map)) { + keys.push(key); + } + + for (const key of Object.getOwnPropertyNames(map)) { + keys.push(key); + } + + return keys; } function values(map) { @@ -75,7 +89,13 @@ function values(map) { return new ErlangTypes.Tuple(BADMAP, map); } - return Object.values(map); + const theValues = []; + + for (const key of keys(map)) { + theValues.push(map[key]); + } + + return theValues; } function is_key(key, map) { @@ -164,5 +184,5 @@ export default { merge, update, get, - take, + take }; diff --git a/test/support/main.ex b/test/support/main.ex index ec70a46a..64562538 100644 --- a/test/support/main.ex +++ b/test/support/main.ex @@ -2,7 +2,6 @@ defmodule Main do def start(:normal, [callback]) do callback.("started") - JS.console.log String.valid?("a") - JS.console.log String.valid?(1) + Enum.each(1..3, fn x -> JS.console.log(x) end) end end From 71356dc3d82a75b7c426b4915c423416c5e1adc6 Mon Sep 17 00:00:00 2001 From: Artsy Date: Mon, 3 Jul 2017 18:09:46 -0400 Subject: [PATCH 150/418] Fixed compilation of functions that return array values --- lib/elixir_script/passes/translate/function.ex | 2 +- test/passes/translate/form_test.exs | 13 +++++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/lib/elixir_script/passes/translate/function.ex b/lib/elixir_script/passes/translate/function.ex index e98200b2..0c74fdd8 100644 --- a/lib/elixir_script/passes/translate/function.ex +++ b/lib/elixir_script/passes/translate/function.ex @@ -137,7 +137,7 @@ defmodule ElixirScript.Translate.Function do List.flatten(list) b when is_list(b) -> {list, _} = Enum.map_reduce(b, state, &Form.compile(&1, &2)) - List.flatten(list) + J.array_expression(list) _ -> Form.compile!(body, state) end diff --git a/test/passes/translate/form_test.exs b/test/passes/translate/form_test.exs index 50dcd93f..f7106473 100644 --- a/test/passes/translate/form_test.exs +++ b/test/passes/translate/form_test.exs @@ -118,4 +118,17 @@ defmodule ElixirScript.Translate.Forms.Test do ) end + test "function returning an array" do + ast = {:fn, [], [{:foo, [], [], [1, 2, 3]}]} + state = %{} + + {js_ast, _} = Form.compile(ast, state) + return_statement = Enum.at(Enum.at(js_ast.body.body, 1).consequent.body, 1) + + assert return_statement.argument == J.array_expression([ + J.literal(1), + J.literal(2), + J.literal(3) + ]) + end end \ No newline at end of file From 20f893dd61ff2d9e5a438a9fc9b85133c1900e59 Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Tue, 4 Jul 2017 15:47:53 -0500 Subject: [PATCH 151/418] Remove a bunch of warnings --- lib/elixir_script/cli.ex | 4 ++-- lib/elixir_script/module_systems/common.ex | 2 -- lib/elixir_script/module_systems/namespace.ex | 6 +++--- .../passes/find_used_functions.ex | 2 +- lib/elixir_script/passes/find_used_modules.ex | 4 ++-- lib/elixir_script/passes/output.ex | 5 +++-- lib/elixir_script/passes/output/js_module.ex | 6 +++--- lib/elixir_script/passes/translate.ex | 3 --- lib/elixir_script/passes/translate/form.ex | 9 ++++----- .../passes/translate/forms/bitstring.ex | 4 ++-- .../passes/translate/forms/for.ex | 4 ++-- lib/elixir_script/passes/translate/forms/js.ex | 2 +- .../passes/translate/forms/match.ex | 4 ++-- .../passes/translate/forms/remote.ex | 2 +- .../passes/translate/forms/try.ex | 4 ++-- lib/elixir_script/passes/translate/function.ex | 18 ++---------------- lib/elixir_script/passes/translate/module.ex | 3 +-- lib/elixir_script/passes/translate/protocol.ex | 11 +++++------ lib/elixir_script/watcher.ex | 4 ++-- lib/mix/tasks/compile.elixir_script.ex | 13 +++---------- 20 files changed, 41 insertions(+), 69 deletions(-) diff --git a/lib/elixir_script/cli.ex b/lib/elixir_script/cli.ex index 9fc992ba..fd27b355 100644 --- a/lib/elixir_script/cli.ex +++ b/lib/elixir_script/cli.ex @@ -54,7 +54,7 @@ defmodule ElixirScript.CLI do end def process(:help) do - IO.write help_message + IO.write help_message() end def process(:version) do @@ -101,7 +101,7 @@ defmodule ElixirScript.CLI do end defp handle_input(input) do - input = input + input |> Enum.map(fn(x) -> String.split(x, [" ", ","], trim: true) end) |> List.flatten |> Enum.map(fn(x) -> Module.concat([x]) end) diff --git a/lib/elixir_script/module_systems/common.ex b/lib/elixir_script/module_systems/common.ex index 9554e687..3236f92b 100644 --- a/lib/elixir_script/module_systems/common.ex +++ b/lib/elixir_script/module_systems/common.ex @@ -1,8 +1,6 @@ defmodule ElixirScript.ModuleSystems.Common do @moduledoc false alias ESTree.Tools.Builder, as: JS - alias ElixirScript.Translator - alias ElixirScript.Translator.{State, Utils} def build(imports, js_imports, body, exports) do module_imports = Enum.map(imports, fn {module, path} -> import_module(module, path) end) diff --git a/lib/elixir_script/module_systems/namespace.ex b/lib/elixir_script/module_systems/namespace.ex index 4a4cf96d..08e7aa4b 100644 --- a/lib/elixir_script/module_systems/namespace.ex +++ b/lib/elixir_script/module_systems/namespace.ex @@ -3,7 +3,7 @@ defmodule ElixirScript.ModuleSystems.Namespace do alias ESTree.Tools.Builder, as: JS alias ElixirScript.Translate.Identifier - def build(module_name, body, exports, env) do + def build(module_name, body, exports) do List.wrap(make_namespace_body(module_name, body, exports)) end @@ -28,7 +28,7 @@ defmodule ElixirScript.ModuleSystems.Namespace do defp make_namespace_body(module_name, body, exports) do values = module_name_function_call(module_name, "__exports") - _if = JS.if_statement( + js_if = JS.if_statement( values, JS.return_statement(values) ) @@ -62,7 +62,7 @@ defmodule ElixirScript.ModuleSystems.Namespace do JS.identifier("__load") ) - func_body = JS.block_statement([_if] ++ body ++ [declaration, assign] ++ exports) + func_body = JS.block_statement([js_if] ++ body ++ [declaration, assign] ++ exports) func = JS.function_expression([JS.identifier("Elixir")], [], func_body) JS.assignment_expression( diff --git a/lib/elixir_script/passes/find_used_functions.ex b/lib/elixir_script/passes/find_used_functions.ex index af659000..30d2919f 100644 --- a/lib/elixir_script/passes/find_used_functions.ex +++ b/lib/elixir_script/passes/find_used_functions.ex @@ -98,7 +98,7 @@ defmodule ElixirScript.FindUsedFunctions do walk(tail, state) end - defp walk({:::, _, _}, state) do + defp walk({:::, _, _}, _) do nil end diff --git a/lib/elixir_script/passes/find_used_modules.ex b/lib/elixir_script/passes/find_used_modules.ex index 5c7cd5d7..1a8bddf2 100644 --- a/lib/elixir_script/passes/find_used_modules.ex +++ b/lib/elixir_script/passes/find_used_modules.ex @@ -95,7 +95,7 @@ defmodule ElixirScript.FindUsedModules do walk(tail, state) end - defp walk({:::, _, _}, state) do + defp walk({:::, _, _}, _) do nil end @@ -232,7 +232,7 @@ defmodule ElixirScript.FindUsedModules do walk({function, [], params}, state) end - defp walk({:., _, [JS, _]}, state) do + defp walk({:., _, [JS, _]}, _) do nil end diff --git a/lib/elixir_script/passes/output.ex b/lib/elixir_script/passes/output.ex index f4c1cb4a..14872ba0 100644 --- a/lib/elixir_script/passes/output.ex +++ b/lib/elixir_script/passes/output.ex @@ -10,8 +10,9 @@ defmodule ElixirScript.Output do """ @spec execute([atom], pid) :: nil def execute(modules, pid) do - modules = Enum.filter_map(modules, fn {_, info} -> Map.has_key?(info, :js_ast) end, - fn {_module, info} -> + modules = modules + |> Enum.filter(fn {_, info} -> Map.has_key?(info, :js_ast) end) + |> Enum.map(fn {_module, info} -> info.js_ast end ) diff --git a/lib/elixir_script/passes/output/js_module.ex b/lib/elixir_script/passes/output/js_module.ex index 8be907ca..75eb960f 100644 --- a/lib/elixir_script/passes/output/js_module.ex +++ b/lib/elixir_script/passes/output/js_module.ex @@ -12,14 +12,14 @@ defmodule ElixirScript.Output.JSModule do elixir = J.variable_declaration([declarator], :const) table_additions = Enum.map(opts.js_modules, fn - {module, path} -> add_import_to_table(module) - {module, path, _} -> add_import_to_table(module) + {module, _} -> add_import_to_table(module) + {module, _, _} -> add_import_to_table(module) end) ast = opts.module_formatter.build( [], opts.js_modules, - [elixir, create_atom_table(), start, load] ++ table_additions ++ body, + [elixir, create_atom_table(), start(), load()] ++ table_additions ++ body, J.identifier("Elixir") ) diff --git a/lib/elixir_script/passes/translate.ex b/lib/elixir_script/passes/translate.ex index 8341a30a..11f89339 100644 --- a/lib/elixir_script/passes/translate.ex +++ b/lib/elixir_script/passes/translate.ex @@ -1,9 +1,6 @@ defmodule ElixirScript.Translate do @moduledoc false - alias ElixirScript.State, as: ModuleState - alias ESTree.Tools.{Builder, Generator} - @doc """ Takes a list of modules and translates their ast into JavaScript AST. The modules are the ones collected from diff --git a/lib/elixir_script/passes/translate/form.ex b/lib/elixir_script/passes/translate/form.ex index f03f6b84..dd1395fb 100644 --- a/lib/elixir_script/passes/translate/form.ex +++ b/lib/elixir_script/passes/translate/form.ex @@ -1,8 +1,7 @@ defmodule ElixirScript.Translate.Form do alias ESTree.Tools.Builder, as: J alias ElixirScript.Translate.Forms.{Bitstring, Match, Try, For, Receive, Remote, Pattern} - alias ElixirScript.Translate.Functions.{Erlang, Lists, Maps} - alias ElixirScript.Translate.{Identifier, Clause} + alias ElixirScript.Translate.Clause require Logger @moduledoc """ @@ -178,7 +177,7 @@ defmodule ElixirScript.Translate.Form do def compile({:receive, context, [blocks]}, state) do line = Keyword.get(context, :line, 1) - {function, arity} = Map.get(state, :function) + {function, _arity} = Map.get(state, :function) Logger.warn fn() -> "receive not supported, Module: #{inspect state.module}, Function: #{function}, Line: #{line}" end @@ -201,7 +200,7 @@ defmodule ElixirScript.Translate.Form do Remote.compile(ast, state) end - def compile({:super, context, params}, state) when is_list(params) do + def compile({:super, _, params}, state) when is_list(params) do {function_name, _} = Map.get(state, :function) {var_decs, params} = compile_params(params, state) @@ -259,7 +258,7 @@ defmodule ElixirScript.Translate.Form do end end - def compile({var, _, _} = ast, state) do + def compile({var, _, _}, state) do var = Pattern.get_variable_name(to_string(var), state) { ElixirScript.Translate.Identifier.make_identifier(var), state } end diff --git a/lib/elixir_script/passes/translate/forms/bitstring.ex b/lib/elixir_script/passes/translate/forms/bitstring.ex index 0221e82c..751af14f 100644 --- a/lib/elixir_script/passes/translate/forms/bitstring.ex +++ b/lib/elixir_script/passes/translate/forms/bitstring.ex @@ -98,7 +98,7 @@ defmodule ElixirScript.Translate.Forms.Bitstring do defp do_compile_element({type, ast}) do JS.call_expression( JS.member_expression( - bitstring_class, + bitstring_class(), JS.identifier(type) ), [ @@ -110,7 +110,7 @@ defmodule ElixirScript.Translate.Forms.Bitstring do defp do_compile_element({type, ast, params}) when is_list(params) do JS.call_expression( JS.member_expression( - bitstring_class, + bitstring_class(), JS.identifier(type) ), [ diff --git a/lib/elixir_script/passes/translate/forms/for.ex b/lib/elixir_script/passes/translate/forms/for.ex index 063fbe39..a04733cd 100644 --- a/lib/elixir_script/passes/translate/forms/for.ex +++ b/lib/elixir_script/passes/translate/forms/for.ex @@ -51,7 +51,7 @@ defmodule ElixirScript.Translate.Forms.For do {ast, state} end - defp handle_args(nil, module_state) do + defp handle_args(nil, _) do %{generators: [], args: [], filter: nil, fun: nil, into: nil, patterns: []} end @@ -123,7 +123,7 @@ defmodule ElixirScript.Translate.Forms.For do defp create_function_expression(ast, state, module_state) do - { ast, module_state } = Enum.map_reduce(List.wrap(ast), module_state, fn x, acc_state -> + { ast, _ } = Enum.map_reduce(List.wrap(ast), module_state, fn x, acc_state -> Form.compile(x, acc_state) end) diff --git a/lib/elixir_script/passes/translate/forms/js.ex b/lib/elixir_script/passes/translate/forms/js.ex index 9cf77604..bb49deb3 100644 --- a/lib/elixir_script/passes/translate/forms/js.ex +++ b/lib/elixir_script/passes/translate/forms/js.ex @@ -42,7 +42,7 @@ defmodule ElixirScript.Translate.Forms.JS do params = case params do p when is_list(p) -> Enum.map(params, &Form.compile!(&1, state)) - p -> + _ -> [J.rest_element(Form.compile!(params, state))] end diff --git a/lib/elixir_script/passes/translate/forms/match.ex b/lib/elixir_script/passes/translate/forms/match.ex index 2ef9037c..1f31bf75 100644 --- a/lib/elixir_script/passes/translate/forms/match.ex +++ b/lib/elixir_script/passes/translate/forms/match.ex @@ -38,7 +38,7 @@ defmodule ElixirScript.Translate.Forms.Match do js_ast = case left do list when is_list(list) -> - make_list_ref(array_pattern, params, state) + make_list_ref(array_pattern, params) { _, _ } -> make_tuple_ref(array_pattern, params) {:{}, _, _ } -> @@ -58,7 +58,7 @@ defmodule ElixirScript.Translate.Forms.Match do end - defp make_list_ref(array_pattern, params, state) do + defp make_list_ref(array_pattern, params) do {ref, params} = make_params(params) ref_declarator = J.variable_declarator(ref, J.array_expression(params)) diff --git a/lib/elixir_script/passes/translate/forms/remote.ex b/lib/elixir_script/passes/translate/forms/remote.ex index 213f9a00..66740877 100644 --- a/lib/elixir_script/passes/translate/forms/remote.ex +++ b/lib/elixir_script/passes/translate/forms/remote.ex @@ -166,7 +166,7 @@ defmodule ElixirScript.Translate.Forms.Remote do Form.compile!(module, state) end - defp process_js_module_name(module, state) do + defp process_js_module_name(module, _) do case Module.split(module) do ["JS"] -> J.member_expression( diff --git a/lib/elixir_script/passes/translate/forms/try.ex b/lib/elixir_script/passes/translate/forms/try.ex index b7c0f225..0df1df1f 100644 --- a/lib/elixir_script/passes/translate/forms/try.ex +++ b/lib/elixir_script/passes/translate/forms/try.ex @@ -64,7 +64,7 @@ defmodule ElixirScript.Translate.Forms.Try do defp process_rescue_block(rescue_block, state) do processed_clauses = Enum.map(rescue_block, fn - {:->, _, [ [{:in, _, [param, names]} = pattern], body]} -> + {:->, _, [ [{:in, _, [param, names]}], body]} -> {ast, _} = Clause.compile({[], [param], [{{:., [], [Enum, :member?]}, [], [param, names]}], body}, state) ast {:->, _, [ [param], body]} -> @@ -91,7 +91,7 @@ defmodule ElixirScript.Translate.Forms.Try do end defp prepare_function_body(body, state) do - {ast, state} = Function.compile_block(body, state) + {ast, _} = Function.compile_block(body, state) Clause.return_last_statement(ast) end diff --git a/lib/elixir_script/passes/translate/function.ex b/lib/elixir_script/passes/translate/function.ex index 0c74fdd8..148fe2ad 100644 --- a/lib/elixir_script/passes/translate/function.ex +++ b/lib/elixir_script/passes/translate/function.ex @@ -92,7 +92,7 @@ defmodule ElixirScript.Translate.Function do defp compile_clauses(clauses, state) do clauses |> Enum.map(&compile_clause(&1, state)) - |> Enum.map(fn {patterns, params, guards, body} -> + |> Enum.map(fn {patterns, _params, guards, body} -> match_or_default_call = J.call_expression( J.member_expression( patterns_ast(), @@ -129,18 +129,7 @@ defmodule ElixirScript.Translate.Function do {patterns, params, state} = Pattern.compile(args, state) guard = Clause.compile_guard(params, guards, state) - body = case body do - nil -> - J.identifier("null") - {:__block__, _, block_body} -> - {list, _} = Enum.map_reduce(block_body, state, &Form.compile(&1, &2)) - List.flatten(list) - b when is_list(b) -> - {list, _} = Enum.map_reduce(b, state, &Form.compile(&1, &2)) - J.array_expression(list) - _ -> - Form.compile!(body, state) - end + {body, _state} = compile_block(body, state) body = body |> Clause.return_last_statement @@ -174,9 +163,6 @@ defmodule ElixirScript.Translate.Function do {:__block__, _, block_body} -> {list, _} = Enum.map_reduce(block_body, state, &Form.compile(&1, &2)) List.flatten(list) - b when is_list(b) -> - {list, _} = Enum.map_reduce(b, state, &Form.compile(&1, &2)) - List.flatten(list) _ -> Form.compile!(block, state) end diff --git a/lib/elixir_script/passes/translate/module.ex b/lib/elixir_script/passes/translate/module.ex index 310b455d..54ca1c7e 100644 --- a/lib/elixir_script/passes/translate/module.ex +++ b/lib/elixir_script/passes/translate/module.ex @@ -62,8 +62,7 @@ defmodule ElixirScript.Translate.Module do js_ast = ElixirScript.ModuleSystems.Namespace.build( module, compiled_functions, - exports, - nil + exports ) ModuleState.put_module(pid, module, Map.put(info, :js_ast, hd(js_ast))) diff --git a/lib/elixir_script/passes/translate/protocol.ex b/lib/elixir_script/passes/translate/protocol.ex index 8dc5deaa..d487a391 100644 --- a/lib/elixir_script/passes/translate/protocol.ex +++ b/lib/elixir_script/passes/translate/protocol.ex @@ -1,7 +1,7 @@ defmodule ElixirScript.Translate.Protocol do @moduledoc false alias ESTree.Tools.Builder, as: J - alias ElixirScript.Translate.{Function, Form, Identifier} + alias ElixirScript.Translate.{Function, Identifier} alias ElixirScript.State, as: ModuleState @@ -34,21 +34,20 @@ defmodule ElixirScript.Translate.Protocol do declaration = J.variable_declaration([declarator], :const) - body = build_implementations(impls, pid) + body = build_implementations(impls) body = [declaration] ++ body js_ast = ElixirScript.ModuleSystems.Namespace.build( module, body, - J.identifier("protocol"), - nil + J.identifier("protocol") ) ModuleState.put_module(pid, module, Map.put(info, :js_ast, hd(js_ast))) end - defp build_implementations(impls, pid) do + defp build_implementations(impls) do Enum.map(impls, fn({impl, impl_for}) -> members = ["Elixir"] ++ Module.split(impl) ++ ["__load"] @@ -165,7 +164,7 @@ defmodule ElixirScript.Translate.Protocol do case Module.split(module) do ["JS" | rest] -> Identifier.make_namespace_members(rest) - split_module -> + _ -> J.call_expression( J.member_expression( J.identifier("Symbol"), diff --git a/lib/elixir_script/watcher.ex b/lib/elixir_script/watcher.ex index 7f1e6e1d..00584d08 100644 --- a/lib/elixir_script/watcher.ex +++ b/lib/elixir_script/watcher.ex @@ -22,7 +22,7 @@ defmodule ElixirScript.Watcher do def handle_info({_pid, {:fs, :file_event}, {path, event}}, state) do try do - if input_changed?(to_string(path), state) do + if input_changed?(to_string(path)) do Logger.debug fn() -> "Event: #{inspect event} Path: #{path}" end @@ -36,7 +36,7 @@ defmodule ElixirScript.Watcher do {:noreply, state} end - defp input_changed?(path, state) do + defp input_changed?(path) do case Path.extname(path) do ".beam" -> true diff --git a/lib/mix/tasks/compile.elixir_script.ex b/lib/mix/tasks/compile.elixir_script.ex index 85a8871b..b01abbcb 100644 --- a/lib/mix/tasks/compile.elixir_script.ex +++ b/lib/mix/tasks/compile.elixir_script.ex @@ -37,23 +37,17 @@ defmodule Mix.Tasks.Compile.ElixirScript do @spec run(any()) :: :ok def run(_) do - elixirscript_base = Path.join([Mix.Project.build_path, "elixirscript"]) - do_compile(elixirscript_base, Mix.Project.config[:app]) + do_compile() :ok end - defp do_compile(_, nil) do - raise ElixirScript.CompileError, message: "Unable to find mix project app name" - end - - defp do_compile(elixirscript_base, app) do - + defp do_compile() do {input, opts} = get_compiler_params() ElixirScript.Compiler.compile(input, opts) end def clean do - {input, opts} = get_compiler_params() + {_, opts} = get_compiler_params() case opts[:output] do path when is_binary(path) -> @@ -78,7 +72,6 @@ defmodule Mix.Tasks.Compile.ElixirScript do {input, opts} end - defp get_elixirscript_config() do config = Mix.Project.config exjs_config = cond do From 128218eb33e85177ef81511bcb716db077c6227c Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Tue, 4 Jul 2017 16:34:25 -0500 Subject: [PATCH 152/418] Add string interpolation --- .../passes/find_used_functions.ex | 4 +-- lib/elixir_script/passes/find_used_modules.ex | 4 +-- lib/elixir_script/passes/translate/form.ex | 19 ++++++++++-- .../passes/translate/forms/bitstring.ex | 13 ++++++-- .../passes/translate/forms/bitstring_test.exs | 30 +++++++++++++++++++ 5 files changed, 62 insertions(+), 8 deletions(-) create mode 100644 test/passes/translate/forms/bitstring_test.exs diff --git a/lib/elixir_script/passes/find_used_functions.ex b/lib/elixir_script/passes/find_used_functions.ex index 30d2919f..234805e0 100644 --- a/lib/elixir_script/passes/find_used_functions.ex +++ b/lib/elixir_script/passes/find_used_functions.ex @@ -98,8 +98,8 @@ defmodule ElixirScript.FindUsedFunctions do walk(tail, state) end - defp walk({:::, _, _}, _) do - nil + defp walk({:::, _, [target, _type]}, state) do + walk(target, state) end defp walk(form, state) when is_list(form) do diff --git a/lib/elixir_script/passes/find_used_modules.ex b/lib/elixir_script/passes/find_used_modules.ex index 1a8bddf2..5823ec65 100644 --- a/lib/elixir_script/passes/find_used_modules.ex +++ b/lib/elixir_script/passes/find_used_modules.ex @@ -95,8 +95,8 @@ defmodule ElixirScript.FindUsedModules do walk(tail, state) end - defp walk({:::, _, _}, _) do - nil + defp walk({:::, _, [target, _type]}, state) do + walk(target, state) end defp walk(form, state) when is_list(form) do diff --git a/lib/elixir_script/passes/translate/form.ex b/lib/elixir_script/passes/translate/form.ex index dd1395fb..314fa624 100644 --- a/lib/elixir_script/passes/translate/form.ex +++ b/lib/elixir_script/passes/translate/form.ex @@ -90,8 +90,23 @@ defmodule ElixirScript.Translate.Form do ElixirScript.Translate.Forms.Map.compile(map, state) end - def compile({:<<>>, _, _} = bitstring, state) do - Bitstring.compile(bitstring, state) + def compile({:<<>>, _, elements} = bitstring, state) do + is_interpolated_string = Enum.all?(elements, fn(x) -> + case x do + b when is_binary(b) -> + true + {:::, _, [_target, {:binary, _, _}]} -> + true + _ -> + false + end + end) + + if is_interpolated_string do + Bitstring.make_interpolated_string(elements, state) + else + Bitstring.compile(bitstring, state) + end end def compile({:=, _, [_, _]} = match, state) do diff --git a/lib/elixir_script/passes/translate/forms/bitstring.ex b/lib/elixir_script/passes/translate/forms/bitstring.ex index 751af14f..1490f74f 100644 --- a/lib/elixir_script/passes/translate/forms/bitstring.ex +++ b/lib/elixir_script/passes/translate/forms/bitstring.ex @@ -129,10 +129,19 @@ defmodule ElixirScript.Translate.Forms.Bitstring do end end) - { do_make_interpolated_string(tl(translated_elements), hd(translated_elements)) } + result = case translated_elements do + [] -> + JS.literal('') + [element] -> + do_make_interpolated_string([], hd(translated_elements)) + elements -> + do_make_interpolated_string(tl(elements), hd(elements)) + end + + {result, state} end - defp do_make_interpolated_string([], ast, _) do + defp do_make_interpolated_string([], ast) do ast end diff --git a/test/passes/translate/forms/bitstring_test.exs b/test/passes/translate/forms/bitstring_test.exs new file mode 100644 index 00000000..73e0e0fa --- /dev/null +++ b/test/passes/translate/forms/bitstring_test.exs @@ -0,0 +1,30 @@ +defmodule ElixirScript.Translate.Forms.Bitstring.Test do + use ExUnit.Case + alias ElixirScript.Translate.Form + alias ESTree.Tools.Builder, as: J + + setup_all do + {:ok, pid} = ElixirScript.State.start_link(%{}) + + state = %{ + pid: pid, + vars: %{} + } + + [state: state] + end + + test "string interpolation", %{state: state} do + ast = {:<<>>, [line: 5], + [{:::, [], ["Hello, ", {:binary, [], []}]}, + {:::, [line: 5], + [{{:., [line: 5], [String.Chars, :to_string]}, [line: 5], + [{:name, [line: 5], nil}]}, {:binary, [], []}]}]} + + {js_ast, _} = Form.compile(ast, state) + assert js_ast.type == "BinaryExpression" + assert js_ast.left == J.literal("Hello, ") + assert js_ast.right.type == "CallExpression" + end + +end \ No newline at end of file From cbdb1f3938c4041f4aab26294b2b72e64d0db2d8 Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Tue, 4 Jul 2017 17:16:26 -0500 Subject: [PATCH 153/418] Update tailored dependency --- package.json | 2 +- yarn.lock | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/package.json b/package.json index 23da045b..a7d6ce42 100644 --- a/package.json +++ b/package.json @@ -23,7 +23,7 @@ "license": "MIT", "dependencies": { "erlang-types": "^1.0.1", - "tailored": "^2.4.6" + "tailored": "^2.4.7" }, "devDependencies": { "ava": "^0.19.1", diff --git a/yarn.lock b/yarn.lock index 7ceffecc..b3274706 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3771,9 +3771,9 @@ table@^3.7.8: slice-ansi "0.0.4" string-width "^2.0.0" -tailored@^2.4.6: - version "2.4.6" - resolved "https://registry.yarnpkg.com/tailored/-/tailored-2.4.6.tgz#1425d01bfc0e69ae0f8edb7030f82d6f0239d00f" +tailored@^2.4.7: + version "2.4.7" + resolved "https://registry.yarnpkg.com/tailored/-/tailored-2.4.7.tgz#1d90846b4885631be00cfd8bc9f56b0dec1686bf" dependencies: erlang-types "^1.0.0" From b57c2b137f643bfb6243ba6b5cc10132daec7463 Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Wed, 5 Jul 2017 21:18:07 -0500 Subject: [PATCH 154/418] Updated from testing --- lib/elixir_script/beam.ex | 10 ++++ lib/elixir_script/lib/agent.ex | 53 +++++++++++++++++++ lib/elixir_script/lib/store.ex | 43 +++++++++++++++ .../passes/find_used_functions.ex | 7 +-- lib/elixir_script/passes/find_used_modules.ex | 5 ++ lib/elixir_script/passes/translate/form.ex | 9 ++++ .../passes/translate/forms/js.ex | 7 +++ .../passes/translate/forms/pattern.ex | 15 ++++++ package.json | 2 +- rollup.config.js | 14 ++--- .../lib/core/erlang_compat/erlang.js | 10 ++-- .../lib/core/erlang_compat/lists.js | 2 +- src/javascript/lib/core/erlang_compat/maps.js | 2 +- src/javascript/lib/core/functions.js | 6 +-- test/support/main.ex | 6 ++- yarn.lock | 6 +-- 16 files changed, 172 insertions(+), 25 deletions(-) create mode 100644 lib/elixir_script/lib/agent.ex create mode 100644 lib/elixir_script/lib/store.ex diff --git a/lib/elixir_script/beam.ex b/lib/elixir_script/beam.ex index a5a3aa46..d8cb7213 100644 --- a/lib/elixir_script/beam.ex +++ b/lib/elixir_script/beam.ex @@ -20,6 +20,16 @@ defmodule ElixirScript.Beam do end end + #Replacing Agent module with our ElixirScript's version + def debug_info(Agent) do + case debug_info(ElixirScript.Agent) do + {:ok, info} -> + {:ok, Map.put(info, :module, Agent)} + e -> + e + end + end + def debug_info(module) when is_atom(module) do #TODO: Get modified date from _beam_path to check for cached version? with {_, beam, _beam_path} <- :code.get_object_code(module), diff --git a/lib/elixir_script/lib/agent.ex b/lib/elixir_script/lib/agent.ex new file mode 100644 index 00000000..8ae7b1eb --- /dev/null +++ b/lib/elixir_script/lib/agent.ex @@ -0,0 +1,53 @@ +defmodule ElixirScript.Agent do + @moduledoc false + + def start(fun, options \\ []) do + pid = JS.new JS.Bootstrap.Core.PID, [] + + name = if Keyword.has_key?(options, :name) do + Keyword.get(options, :name) + else + nil + end + + ElixirScript.Store.create(pid, fun.(), name) + { :ok, pid } + end + + def start_link(fun, options \\ []) do + pid = JS.new JS.Bootstrap.Core.PID, [] + + name = if Keyword.has_key?(options, :name) do + Keyword.get(options, :name) + else + nil + end + + ElixirScript.Store.create(pid, fun.(), name) + { :ok, pid } + end + + def stop(agent) do + ElixirScript.Store.remove(agent) + :ok + end + + def update(agent, fun) do + current_state = ElixirScript.Store.read(agent) + ElixirScript.Store.update(agent, fun.(current_state)) + :ok + end + + def get(agent, fun) do + current_state = ElixirScript.Store.read(agent) + fun.(current_state) + end + + def get_and_update(agent, fun) do + current_state = ElixirScript.Store.read(agent) + {val, new_state} = fun.(current_state) + ElixirScript.Store.update(agent, new_state) + val + end + +end \ No newline at end of file diff --git a/lib/elixir_script/lib/store.ex b/lib/elixir_script/lib/store.ex new file mode 100644 index 00000000..ad5b777c --- /dev/null +++ b/lib/elixir_script/lib/store.ex @@ -0,0 +1,43 @@ +defmodule ElixirScript.Store do + + defp get_key(key) do + real_key = case JS.__elixirscript_names__.has(key) do + true -> + JS.__elixirscript_names__.get(key) + false -> + key + end + + case JS.__elixirscript_store__.has(real_key) do + true -> + real_key + false -> + JS.throw JS.new(JS.Error, ["Key Not Found"]) + end + end + + def create(key, value, name \\ nil) do + if name != nil do + JS.__elixirscript_names__.set(name, key) + end + + JS.__elixirscript_store__.set(key, value) + end + + def update(key, value) do + real_key = get_key(key) + JS.__elixirscript_store__.set(real_key, value) + end + + def read(key) do + real_key = get_key(key) + JS.__elixirscript_store__.get(real_key) + end + + def remove(key) do + real_key = get_key(key) + JS.__elixirscript_store__.delete(real_key) + end + + +end \ No newline at end of file diff --git a/lib/elixir_script/passes/find_used_functions.ex b/lib/elixir_script/passes/find_used_functions.ex index 234805e0..50177616 100644 --- a/lib/elixir_script/passes/find_used_functions.ex +++ b/lib/elixir_script/passes/find_used_functions.ex @@ -36,7 +36,8 @@ defmodule ElixirScript.FindUsedFunctions do reachable_defs = Enum.filter(defs, fn { _, type, _, _} when type in [:defmacro, :defmacrop] -> false - { name, _, _, _} -> not(name in unreachable) + { name, _, _, _} -> + not(name in unreachable) _ -> true end) @@ -128,8 +129,8 @@ defmodule ElixirScript.FindUsedFunctions do end defp walk({:%, _, [module, params]}, state) do - ModuleState.add_used(state.pid, module, {:__struct__, 0}) - ModuleState.add_used(state.pid, module, {:__struct__, 1}) + walk_module(module, :__struct__, 0, state.pid) + walk_module(module, :__struct__, 1, state.pid) walk(params, state) end diff --git a/lib/elixir_script/passes/find_used_modules.ex b/lib/elixir_script/passes/find_used_modules.ex index 5823ec65..ccd94136 100644 --- a/lib/elixir_script/passes/find_used_modules.ex +++ b/lib/elixir_script/passes/find_used_modules.ex @@ -232,6 +232,11 @@ defmodule ElixirScript.FindUsedModules do walk({function, [], params}, state) end + defp walk({{:., _, [module, function]} = ast, _, params}, state) do + walk(ast, state) + walk(params, state) + end + defp walk({:., _, [JS, _]}, _) do nil end diff --git a/lib/elixir_script/passes/translate/form.ex b/lib/elixir_script/passes/translate/form.ex index 314fa624..385156da 100644 --- a/lib/elixir_script/passes/translate/form.ex +++ b/lib/elixir_script/passes/translate/form.ex @@ -207,6 +207,15 @@ defmodule ElixirScript.Translate.Form do ElixirScript.Translate.Function.compile(ast, state) end + def compile({{:., _, [{_, _, nil} = var, func_or_prop]}, _, []}, state) do + ast = J.call_expression( + ElixirScript.Translate.Forms.JS.call_property(), + [compile!(var, state), J.literal(to_string(func_or_prop))] + ) + + {ast, state} + end + def compile({{:., _, [JS, _]}, _, _} = ast, state) do ElixirScript.Translate.Forms.JS.compile(ast, state) end diff --git a/lib/elixir_script/passes/translate/forms/js.ex b/lib/elixir_script/passes/translate/forms/js.ex index bb49deb3..80c8cca9 100644 --- a/lib/elixir_script/passes/translate/forms/js.ex +++ b/lib/elixir_script/passes/translate/forms/js.ex @@ -39,6 +39,13 @@ defmodule ElixirScript.Translate.Forms.JS do def compile({{:., _, [JS, :new]}, _, [module, params]}, state) do members = Module.split(module) + members = case members do + ["JS" | rest] -> + rest + x -> + x + end + params = case params do p when is_list(p) -> Enum.map(params, &Form.compile!(&1, state)) diff --git a/lib/elixir_script/passes/translate/forms/pattern.ex b/lib/elixir_script/passes/translate/forms/pattern.ex index 134b8ca8..a721295b 100644 --- a/lib/elixir_script/passes/translate/forms/pattern.ex +++ b/lib/elixir_script/passes/translate/forms/pattern.ex @@ -118,6 +118,21 @@ defmodule ElixirScript.Translate.Forms.Pattern do defp process_pattern({:%{}, _, props}, state) do properties = Enum.map(props, fn + {:__module__struct__, {_, _, nil} = var } -> + {pattern, params} = process_pattern(var, state) + + a = J.object_expression([%ESTree.Property{ + key: J.identifier("__MODULE__"), + value: hd(List.wrap(pattern)) + }]) + + property = ElixirScript.Translate.Forms.Map.make_property( + Form.compile!(:__struct__, state), + a + ) + + { property, params } + {:__module__struct__, module} -> a = J.object_expression([%ESTree.Property{ key: J.identifier("__MODULE__"), diff --git a/package.json b/package.json index a7d6ce42..cb87365b 100644 --- a/package.json +++ b/package.json @@ -23,7 +23,7 @@ "license": "MIT", "dependencies": { "erlang-types": "^1.0.1", - "tailored": "^2.4.7" + "tailored": "^2.4.8" }, "devDependencies": { "ava": "^0.19.1", diff --git a/rollup.config.js b/rollup.config.js index 9fe0ae32..70fa4aef 100644 --- a/rollup.config.js +++ b/rollup.config.js @@ -8,12 +8,12 @@ export default { plugins: [ nodeResolve({ jsnext: true }), babel({ - babelrc: false, - }), - babili({ - keepFnName: true, - keepClassName: true, - }), + babelrc: false + }) + //babili({ + // keepFnName: true, + // keepClassName: true, + //}), ], - targets: [{ dest: 'priv/build/iife/Elixir.Bootstrap.js', format: 'iife' }], + targets: [{ dest: 'priv/build/iife/Elixir.Bootstrap.js', format: 'iife' }] }; diff --git a/src/javascript/lib/core/erlang_compat/erlang.js b/src/javascript/lib/core/erlang_compat/erlang.js index 0fd5a647..aefbf7b7 100644 --- a/src/javascript/lib/core/erlang_compat/erlang.js +++ b/src/javascript/lib/core/erlang_compat/erlang.js @@ -202,7 +202,7 @@ function element(n, tuple) { } function setelement(index, tuple1, value) { - const tupleData = [...tuple1.data]; + const tupleData = [...tuple1.values]; tupleData[index - 1] = value; @@ -220,28 +220,28 @@ function make_tuple(arity, initialValue) { } function insert_element(index, tuple, term) { - const list = [...tuple.data]; + const list = [...tuple.values]; list.splice(index - 1, 0, term); return new ErlangTypes.Tuple(...list); } function append_element(tuple, term) { - const list = [...tuple.data]; + const list = [...tuple.values]; list.push(term); return new ErlangTypes.Tuple(...list); } function delete_element(index, tuple) { - const list = [...tuple.data]; + const list = [...tuple.values]; list.splice(index - 1, 1); return new ErlangTypes.Tuple(...list); } function tuple_to_list(tuple) { - const list = [...tuple.data]; + const list = [...tuple.values]; return list; } diff --git a/src/javascript/lib/core/erlang_compat/lists.js b/src/javascript/lib/core/erlang_compat/lists.js index b06cc30d..9e9daf43 100644 --- a/src/javascript/lib/core/erlang_compat/lists.js +++ b/src/javascript/lib/core/erlang_compat/lists.js @@ -263,5 +263,5 @@ export default { all, any, splitwith, - sort, + sort }; diff --git a/src/javascript/lib/core/erlang_compat/maps.js b/src/javascript/lib/core/erlang_compat/maps.js index 6178eba7..142a031f 100644 --- a/src/javascript/lib/core/erlang_compat/maps.js +++ b/src/javascript/lib/core/erlang_compat/maps.js @@ -129,7 +129,7 @@ function update(key, value, map1) { return new ErlangTypes.Tuple(BADMAP, map1); } - if (is_key(key) === false) { + if (is_key(key, map1) === false) { return new ErlangTypes.Tuple(BADKEY, key); } diff --git a/src/javascript/lib/core/functions.js b/src/javascript/lib/core/functions.js index 423f323a..d315dab9 100644 --- a/src/javascript/lib/core/functions.js +++ b/src/javascript/lib/core/functions.js @@ -24,7 +24,7 @@ function iterator_to_reducer(iterable, acc, fun) { function call_property(item, property) { if (!property) { - if (item instanceof Function) { + if (item instanceof Function || typeof item === 'function') { return item(); } @@ -54,7 +54,7 @@ function call_property(item, property) { throw new Error(`Property ${property} not found in ${item}`); } - if (item[prop] instanceof Function) { + if (item[prop] instanceof Function || typeof item[prop] === 'function') { return item[prop](); } return item[prop]; @@ -96,5 +96,5 @@ export default { defprotocol, defimpl, build_namespace, - iterator_to_reducer, + iterator_to_reducer }; diff --git a/test/support/main.ex b/test/support/main.ex index 64562538..ef0460e0 100644 --- a/test/support/main.ex +++ b/test/support/main.ex @@ -2,6 +2,10 @@ defmodule Main do def start(:normal, [callback]) do callback.("started") - Enum.each(1..3, fn x -> JS.console.log(x) end) + JS.fetch("/api/todo").then(fn(response) -> + response.json() + end).catch(fn(err) -> + :console.debug(err) + end) end end diff --git a/yarn.lock b/yarn.lock index b3274706..731d3082 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3771,9 +3771,9 @@ table@^3.7.8: slice-ansi "0.0.4" string-width "^2.0.0" -tailored@^2.4.7: - version "2.4.7" - resolved "https://registry.yarnpkg.com/tailored/-/tailored-2.4.7.tgz#1d90846b4885631be00cfd8bc9f56b0dec1686bf" +tailored@^2.4.8: + version "2.4.8" + resolved "https://registry.yarnpkg.com/tailored/-/tailored-2.4.8.tgz#adef8f95aa621068d5735f970ceb458d689e6de5" dependencies: erlang-types "^1.0.0" From 57cdb747d34185a2d2d5855100b9fc90c7133322 Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Sat, 8 Jul 2017 04:38:14 -0500 Subject: [PATCH 155/418] Updated tailored dep --- package.json | 2 +- yarn.lock | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/package.json b/package.json index cb87365b..bb34b229 100644 --- a/package.json +++ b/package.json @@ -23,7 +23,7 @@ "license": "MIT", "dependencies": { "erlang-types": "^1.0.1", - "tailored": "^2.4.8" + "tailored": "^2.4.9" }, "devDependencies": { "ava": "^0.19.1", diff --git a/yarn.lock b/yarn.lock index 731d3082..241ad9e7 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3771,9 +3771,9 @@ table@^3.7.8: slice-ansi "0.0.4" string-width "^2.0.0" -tailored@^2.4.8: - version "2.4.8" - resolved "https://registry.yarnpkg.com/tailored/-/tailored-2.4.8.tgz#adef8f95aa621068d5735f970ceb458d689e6de5" +tailored@^2.4.9: + version "2.4.9" + resolved "https://registry.yarnpkg.com/tailored/-/tailored-2.4.9.tgz#b06ea7e8eab054860062b076e7e1d0e33e0fa983" dependencies: erlang-types "^1.0.0" From 15d467cc2a0d630961698a62079a56cb20c60547 Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Sat, 8 Jul 2017 04:40:18 -0500 Subject: [PATCH 156/418] Revert changes main.ex --- test/support/main.ex | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/test/support/main.ex b/test/support/main.ex index ef0460e0..64562538 100644 --- a/test/support/main.ex +++ b/test/support/main.ex @@ -2,10 +2,6 @@ defmodule Main do def start(:normal, [callback]) do callback.("started") - JS.fetch("/api/todo").then(fn(response) -> - response.json() - end).catch(fn(err) -> - :console.debug(err) - end) + Enum.each(1..3, fn x -> JS.console.log(x) end) end end From c07fce0bae35d0a3092a86f9a38dd09aa8d640bd Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Sat, 8 Jul 2017 04:42:38 -0500 Subject: [PATCH 157/418] Uncomment minification options --- rollup.config.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/rollup.config.js b/rollup.config.js index 70fa4aef..a69d9169 100644 --- a/rollup.config.js +++ b/rollup.config.js @@ -9,11 +9,11 @@ export default { nodeResolve({ jsnext: true }), babel({ babelrc: false + }), + babili({ + keepFnName: true, + keepClassName: true }) - //babili({ - // keepFnName: true, - // keepClassName: true, - //}), ], targets: [{ dest: 'priv/build/iife/Elixir.Bootstrap.js', format: 'iife' }] }; From 579dbcbebcdc88eb815575d77d91a8bd3f116dea Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Mon, 10 Jul 2017 08:38:11 -0500 Subject: [PATCH 158/418] Add FFI for javascript interop --- lib/elixir_script/ffi.ex | 15 ++++++ lib/elixir_script/lib/agent.ex | 20 ++++---- lib/elixir_script/lib/store.ex | 45 +++--------------- lib/elixir_script/passes/output.ex | 6 +-- lib/elixir_script/passes/output/js_module.ex | 6 +-- .../passes/translate/forms/remote.ex | 15 +----- lib/elixir_script/passes/translate/module.ex | 10 ++-- lib/elixir_script/state.ex | 36 ++++++++++++-- src/javascript/lib/core.js | 4 +- src/javascript/lib/core/store.js | 47 +++++++++++++++++++ test/support/json.ex | 6 +++ test/support/main.ex | 2 + 12 files changed, 135 insertions(+), 77 deletions(-) create mode 100644 lib/elixir_script/ffi.ex create mode 100644 src/javascript/lib/core/store.js create mode 100644 test/support/json.ex diff --git a/lib/elixir_script/ffi.ex b/lib/elixir_script/ffi.ex new file mode 100644 index 00000000..ff14b80b --- /dev/null +++ b/lib/elixir_script/ffi.ex @@ -0,0 +1,15 @@ +defmodule ElixirScript.FFI do + defmacro __using__(opts) do + quote do + import ElixirScript.FFI + Module.register_attribute __MODULE__, :__foreign_info__, persist: true + @__foreign_info__ %{path: unquote(Keyword.get(opts, :path, nil))} + end + end + + defmacro foreign({name, _, args}) do + quote do + def unquote(name)(unquote_splicing(args)), do: nil + end + end +end \ No newline at end of file diff --git a/lib/elixir_script/lib/agent.ex b/lib/elixir_script/lib/agent.ex index 8ae7b1eb..cb444941 100644 --- a/lib/elixir_script/lib/agent.ex +++ b/lib/elixir_script/lib/agent.ex @@ -2,51 +2,47 @@ defmodule ElixirScript.Agent do @moduledoc false def start(fun, options \\ []) do - pid = JS.new JS.Bootstrap.Core.PID, [] - name = if Keyword.has_key?(options, :name) do Keyword.get(options, :name) else nil end - ElixirScript.Store.create(pid, fun.(), name) + pid = Bootstrap.Core.Store.create(fun.(), name) { :ok, pid } end def start_link(fun, options \\ []) do - pid = JS.new JS.Bootstrap.Core.PID, [] - name = if Keyword.has_key?(options, :name) do Keyword.get(options, :name) else nil end - ElixirScript.Store.create(pid, fun.(), name) + pid = Bootstrap.Core.Store.create(fun.(), name) { :ok, pid } end def stop(agent) do - ElixirScript.Store.remove(agent) + Bootstrap.Core.Store.remove(agent) :ok end def update(agent, fun) do - current_state = ElixirScript.Store.read(agent) - ElixirScript.Store.update(agent, fun.(current_state)) + current_state = Bootstrap.Core.Store.read(agent) + Bootstrap.Core.Store.update(agent, fun.(current_state)) :ok end def get(agent, fun) do - current_state = ElixirScript.Store.read(agent) + current_state = Bootstrap.Core.Store.read(agent) fun.(current_state) end def get_and_update(agent, fun) do - current_state = ElixirScript.Store.read(agent) + current_state = Bootstrap.Core.Store.read(agent) {val, new_state} = fun.(current_state) - ElixirScript.Store.update(agent, new_state) + Bootstrap.Core.Store.update(agent, new_state) val end diff --git a/lib/elixir_script/lib/store.ex b/lib/elixir_script/lib/store.ex index ad5b777c..dd6b4a7a 100644 --- a/lib/elixir_script/lib/store.ex +++ b/lib/elixir_script/lib/store.ex @@ -1,43 +1,12 @@ -defmodule ElixirScript.Store do +defmodule Bootstrap.Core.Store do + @moduledoc false + use ElixirScript.FFI - defp get_key(key) do - real_key = case JS.__elixirscript_names__.has(key) do - true -> - JS.__elixirscript_names__.get(key) - false -> - key - end + foreign create(value, name \\ nil) - case JS.__elixirscript_store__.has(real_key) do - true -> - real_key - false -> - JS.throw JS.new(JS.Error, ["Key Not Found"]) - end - end - - def create(key, value, name \\ nil) do - if name != nil do - JS.__elixirscript_names__.set(name, key) - end - - JS.__elixirscript_store__.set(key, value) - end - - def update(key, value) do - real_key = get_key(key) - JS.__elixirscript_store__.set(real_key, value) - end - - def read(key) do - real_key = get_key(key) - JS.__elixirscript_store__.get(real_key) - end - - def remove(key) do - real_key = get_key(key) - JS.__elixirscript_store__.delete(real_key) - end + foreign update(key, value) + foreign read(key) + foreign remove(key) end \ No newline at end of file diff --git a/lib/elixir_script/passes/output.ex b/lib/elixir_script/passes/output.ex index 14872ba0..a2d3e2fc 100644 --- a/lib/elixir_script/passes/output.ex +++ b/lib/elixir_script/passes/output.ex @@ -19,13 +19,13 @@ defmodule ElixirScript.Output do opts = ModuleState.get_compiler_opts(pid) - bundle(modules, opts) + bundle(modules, opts, ModuleState.js_modules(pid)) |> output(Map.get(opts, :output)) end - defp bundle(modules, opts) do + defp bundle(modules, opts, js_modules) do modules - |> ElixirScript.Output.JSModule.compile(opts) + |> ElixirScript.Output.JSModule.compile(opts, js_modules) |> List.wrap |> Builder.program |> prepare_js_ast diff --git a/lib/elixir_script/passes/output/js_module.ex b/lib/elixir_script/passes/output/js_module.ex index 75eb960f..79f22a83 100644 --- a/lib/elixir_script/passes/output/js_module.ex +++ b/lib/elixir_script/passes/output/js_module.ex @@ -3,7 +3,7 @@ defmodule ElixirScript.Output.JSModule do alias ESTree.Tools.Builder, as: J - def compile(body, opts) do + def compile(body, opts, js_modules) do declarator = J.variable_declarator( J.identifier("Elixir"), J.object_expression([]) @@ -11,14 +11,14 @@ defmodule ElixirScript.Output.JSModule do elixir = J.variable_declaration([declarator], :const) - table_additions = Enum.map(opts.js_modules, fn + table_additions = Enum.map(js_modules, fn {module, _} -> add_import_to_table(module) {module, _, _} -> add_import_to_table(module) end) ast = opts.module_formatter.build( [], - opts.js_modules, + js_modules, [elixir, create_atom_table(), start(), load()] ++ table_additions ++ body, J.identifier("Elixir") ) diff --git a/lib/elixir_script/passes/translate/forms/remote.ex b/lib/elixir_script/passes/translate/forms/remote.ex index 66740877..93b186cc 100644 --- a/lib/elixir_script/passes/translate/forms/remote.ex +++ b/lib/elixir_script/passes/translate/forms/remote.ex @@ -167,20 +167,7 @@ defmodule ElixirScript.Translate.Forms.Remote do end defp process_js_module_name(module, _) do - case Module.split(module) do - ["JS"] -> - J.member_expression( - J.member_expression( - J.identifier("Bootstrap"), - J.identifier("Core") - ), - J.identifier("global") - ) - ["JS" | rest] -> - Identifier.make_namespace_members(rest) - x -> - Identifier.make_namespace_members(x) - end + Identifier.make_namespace_members(module) end defp erlang_compat_function(module, function) do diff --git a/lib/elixir_script/passes/translate/module.ex b/lib/elixir_script/passes/translate/module.ex index 54ca1c7e..049bfda0 100644 --- a/lib/elixir_script/passes/translate/module.ex +++ b/lib/elixir_script/passes/translate/module.ex @@ -12,6 +12,12 @@ defmodule ElixirScript.Translate.Module do ElixirScript.Translate.Protocol.compile(module, info, pid) end + def compile(module, %{attributes: [__foreign_info__: %{path: path}]}, pid) do + ModuleState.put_javascript_module(pid, module, path) + + nil + end + def compile(module, info, pid) do %{ attributes: attrs, @@ -133,12 +139,10 @@ defmodule ElixirScript.Translate.Module do """ def is_js_module(module, state) do cond do - module in ModuleState.get_javascript_modules(state.pid) -> + module in ModuleState.list_javascript_modules(state.pid) -> true module === Elixir -> false - is_elixir_module(module) and hd(Module.split(module)) == "JS" -> - true true -> false end diff --git a/lib/elixir_script/state.ex b/lib/elixir_script/state.ex index f7e82449..464f43eb 100644 --- a/lib/elixir_script/state.ex +++ b/lib/elixir_script/state.ex @@ -8,7 +8,8 @@ defmodule ElixirScript.State do %{ compiler_opts: compiler_opts, modules: Keyword.new, - refs: [] + refs: [], + js_modules: [] } end) end @@ -57,9 +58,18 @@ defmodule ElixirScript.State do end) end - def get_javascript_modules(pid) do + def put_javascript_module(pid, module, path) do + Agent.update(pid, fn(state) -> + js_modules = Map.get(state, :js_modules, []) + js_modules = js_modules ++ [{module, path}] + + %{ state | js_modules: js_modules } + end) + end + + def list_javascript_modules(pid) do Agent.get(pid, fn(state) -> - Map.get(state.compiler_opts, :js_modules, []) + state.js_modules |> Enum.map(fn {module_name, _path} -> module_name @@ -69,6 +79,26 @@ defmodule ElixirScript.State do end) end + def js_modules(pid) do + Agent.get(pid, fn(state) -> + state.js_modules + |> Enum.filter(fn + {_, nil} -> false + _ -> true + end) + end) + end + + def list_foreign_modules(pid) do + Agent.get(pid, fn(state) -> + state.modules + |> Enum.filter(fn + (%{attributes: [__foreign_info__: _]}) -> true + (_) -> false + end) + end) + end + def list_modules(pid) do Agent.get(pid, fn(state) -> state.modules diff --git a/src/javascript/lib/core.js b/src/javascript/lib/core.js index bacfe6fe..b1c85c9e 100644 --- a/src/javascript/lib/core.js +++ b/src/javascript/lib/core.js @@ -5,6 +5,7 @@ import SpecialForms from './core/special_forms'; import erlang from './core/erlang_compat/erlang'; import maps from './core/erlang_compat/maps'; import lists from './core/erlang_compat/lists'; +import Store from './core/store'; class Integer {} class Float {} @@ -36,8 +37,9 @@ export default { Float, Functions, SpecialForms, + Store, global: globalState, erlang, maps, - lists, + lists }; diff --git a/src/javascript/lib/core/store.js b/src/javascript/lib/core/store.js new file mode 100644 index 00000000..f0ebc0ec --- /dev/null +++ b/src/javascript/lib/core/store.js @@ -0,0 +1,47 @@ +import Core from '../core'; + +function get_key(key) { + let real_key = key; + + if (__elixirscript_names__.has(key)) { + real_key = __elixirscript_names__.get(key); + } + + if (__elixirscript_store__.has(real_key)) { + return real_key; + } + + throw new Error(`Key ${real_key} not found`); +} + +function create(value, name = null) { + const key = new Core.PID(); + + if (name !== null) { + __elixirscript_names__.set(name, key); + } + + __elixirscript_store__.set(key, value); +} + +function update(key, value) { + const real_key = get_key(key); + __elixirscript_store__.set(real_key, value); +} + +function read(key) { + const real_key = get_key(key); + __elixirscript_store__.get(real_key); +} + +function remove(key) { + const real_key = get_key(key); + __elixirscript_store__.delete(real_key); +} + +export default { + create, + update, + read, + remove +}; diff --git a/test/support/json.ex b/test/support/json.ex new file mode 100644 index 00000000..a3c7e349 --- /dev/null +++ b/test/support/json.ex @@ -0,0 +1,6 @@ +defmodule JSON do + use ElixirScript.FFI + + foreign stringify(map) + foreign parse(string) +end \ No newline at end of file diff --git a/test/support/main.ex b/test/support/main.ex index 64562538..d32cd32e 100644 --- a/test/support/main.ex +++ b/test/support/main.ex @@ -2,6 +2,8 @@ defmodule Main do def start(:normal, [callback]) do callback.("started") + JSON.stringify(%{}) + Enum.each(1..3, fn x -> JS.console.log(x) end) end end From f27942b975ad8825a1b5004b1fd5bd9f61ed68c7 Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Wed, 12 Jul 2017 09:00:38 -0500 Subject: [PATCH 159/418] Updated FFI to always assume there will be a js module at an assumed path --- lib/elixir_script/ffi.ex | 10 +++++-- lib/elixir_script/module_systems/common.ex | 6 ++-- lib/elixir_script/module_systems/es.ex | 16 ++-------- lib/elixir_script/module_systems/umd.ex | 4 +-- lib/elixir_script/passes/output.ex | 6 ++++ lib/elixir_script/passes/output/js_module.ex | 29 +------------------ .../passes/translate/forms/remote.ex | 6 ++-- lib/elixir_script/passes/translate/module.ex | 4 +-- lib/elixir_script/state.ex | 22 +++++++------- test/support/json.ex | 2 +- 10 files changed, 41 insertions(+), 64 deletions(-) diff --git a/lib/elixir_script/ffi.ex b/lib/elixir_script/ffi.ex index ff14b80b..890a6913 100644 --- a/lib/elixir_script/ffi.ex +++ b/lib/elixir_script/ffi.ex @@ -1,9 +1,15 @@ defmodule ElixirScript.FFI do - defmacro __using__(opts) do + defmacro __using__(_) do + js_path = Path.join([".", Macro.underscore(__MODULE__)]) + + js_name = __MODULE__ + |> Module.split() + |> Enum.join("_") + quote do import ElixirScript.FFI Module.register_attribute __MODULE__, :__foreign_info__, persist: true - @__foreign_info__ %{path: unquote(Keyword.get(opts, :path, nil))} + @__foreign_info__ %{path: unquote(js_path), name: unquote(js_name)} end end diff --git a/lib/elixir_script/module_systems/common.ex b/lib/elixir_script/module_systems/common.ex index 3236f92b..2f4da76b 100644 --- a/lib/elixir_script/module_systems/common.ex +++ b/lib/elixir_script/module_systems/common.ex @@ -7,7 +7,7 @@ defmodule ElixirScript.ModuleSystems.Common do imports = js_imports |> Enum.map(fn - {module, path} -> import_module(module, path) + {_module, name, path} -> import_module(name, path) end) imports = Enum.uniq(imports ++ module_imports) @@ -16,8 +16,8 @@ defmodule ElixirScript.ModuleSystems.Common do imports ++ body ++ export end - defp import_module(module_name, from) do - js_module_name = ElixirScript.Translate.Identifier.make_namespace_members(module_name) + defp import_module(name, from) do + js_module_name = JS.identifier(name) do_import_module(js_module_name, from) end diff --git a/lib/elixir_script/module_systems/es.ex b/lib/elixir_script/module_systems/es.ex index 3e92049c..72cd042a 100644 --- a/lib/elixir_script/module_systems/es.ex +++ b/lib/elixir_script/module_systems/es.ex @@ -7,8 +7,7 @@ defmodule ElixirScript.ModuleSystems.ES do imports = js_imports |> Enum.map(fn - {module, path} -> import_module(module, path) - {module, path, default: false} -> import_namespace_module(module, path) + {_module, name, path} -> import_module(name, path) end) imports = Enum.uniq(imports ++ module_imports) @@ -17,19 +16,8 @@ defmodule ElixirScript.ModuleSystems.ES do imports ++ body ++ export end - defp import_namespace_module(module_name, from) do - js_module_name = ElixirScript.Translate.Identifier.make_namespace_members(module_name) - - import_specifier = JS.import_namespace_specifier( - js_module_name, - js_module_name - ) - - do_import_module([import_specifier], from) - end - defp import_module(import_name, from) do - js_module_name = ElixirScript.Translate.Identifier.make_namespace_members(import_name) + js_module_name = JS.identifier(import_name) import_specifier = JS.import_default_specifier( js_module_name diff --git a/lib/elixir_script/module_systems/umd.ex b/lib/elixir_script/module_systems/umd.ex index e9894c24..fcd30795 100644 --- a/lib/elixir_script/module_systems/umd.ex +++ b/lib/elixir_script/module_systems/umd.ex @@ -9,7 +9,7 @@ defmodule ElixirScript.ModuleSystems.UMD do imports = js_imports |> Enum.map(fn - {module, path} -> import_module(module, path) + {_module, name, path} -> import_module(name, path) end) imports = Enum.uniq(imports ++ module_imports) @@ -19,7 +19,7 @@ defmodule ElixirScript.ModuleSystems.UMD do end defp import_module(module_name, from) do - js_module_name = ElixirScript.Translate.Identifier.make_namespace_members(module_name) + js_module_name = JS.identifier(module_name) {js_module_name, JS.literal(from)} end diff --git a/lib/elixir_script/passes/output.ex b/lib/elixir_script/passes/output.ex index a2d3e2fc..26522a4b 100644 --- a/lib/elixir_script/passes/output.ex +++ b/lib/elixir_script/passes/output.ex @@ -19,6 +19,12 @@ defmodule ElixirScript.Output do opts = ModuleState.get_compiler_opts(pid) + #TODO: Combine Mix.Project.config()[:app] with Mix.Project.deps_paths() to + # get app names. + # File.exists? Path.join([:code.priv_dir(app), "src", "elixir_script"]) + # to find out if app has interop files. + # If so, copy files and directories to output folder + bundle(modules, opts, ModuleState.js_modules(pid)) |> output(Map.get(opts, :output)) end diff --git a/lib/elixir_script/passes/output/js_module.ex b/lib/elixir_script/passes/output/js_module.ex index 79f22a83..a5cea45f 100644 --- a/lib/elixir_script/passes/output/js_module.ex +++ b/lib/elixir_script/passes/output/js_module.ex @@ -11,15 +11,10 @@ defmodule ElixirScript.Output.JSModule do elixir = J.variable_declaration([declarator], :const) - table_additions = Enum.map(js_modules, fn - {module, _} -> add_import_to_table(module) - {module, _, _} -> add_import_to_table(module) - end) - ast = opts.module_formatter.build( [], js_modules, - [elixir, create_atom_table(), start(), load()] ++ table_additions ++ body, + [elixir, create_atom_table(), start(), load()] ++ body, J.identifier("Elixir") ) @@ -99,26 +94,4 @@ defmodule ElixirScript.Output.JSModule do ) end - defp add_import_to_table(module_name) do - ref = ElixirScript.Translate.Identifier.make_namespace_members(module_name) - J.assignment_expression( - :=, - J.member_expression( - J.member_expression( - J.identifier("Elixir"), - J.identifier("__table__") - ), - J.call_expression( - J.member_expression( - J.identifier("Symbol"), - J.identifier("for") - ), - [J.literal(ref.name)] - ), - true - ), - ref - ) - end - end \ No newline at end of file diff --git a/lib/elixir_script/passes/translate/forms/remote.ex b/lib/elixir_script/passes/translate/forms/remote.ex index 93b186cc..c0ea3363 100644 --- a/lib/elixir_script/passes/translate/forms/remote.ex +++ b/lib/elixir_script/passes/translate/forms/remote.ex @@ -3,6 +3,7 @@ defmodule ElixirScript.Translate.Forms.Remote do alias ESTree.Tools.Builder, as: J alias ElixirScript.Translate.{Form, Identifier} + alias ElixirScript.State, as: ModuleState @erlang_modules [ :erlang, @@ -166,8 +167,9 @@ defmodule ElixirScript.Translate.Forms.Remote do Form.compile!(module, state) end - defp process_js_module_name(module, _) do - Identifier.make_namespace_members(module) + defp process_js_module_name(module, state) do + name = ModuleState.get_js_module_name(state.pid, module) + J.identifier(name) end defp erlang_compat_function(module, function) do diff --git a/lib/elixir_script/passes/translate/module.ex b/lib/elixir_script/passes/translate/module.ex index 049bfda0..df98c5c1 100644 --- a/lib/elixir_script/passes/translate/module.ex +++ b/lib/elixir_script/passes/translate/module.ex @@ -12,8 +12,8 @@ defmodule ElixirScript.Translate.Module do ElixirScript.Translate.Protocol.compile(module, info, pid) end - def compile(module, %{attributes: [__foreign_info__: %{path: path}]}, pid) do - ModuleState.put_javascript_module(pid, module, path) + def compile(module, %{attributes: [__foreign_info__: %{path: path, name: name}]}, pid) do + ModuleState.put_javascript_module(pid, name, path) nil end diff --git a/lib/elixir_script/state.ex b/lib/elixir_script/state.ex index 464f43eb..ed47108d 100644 --- a/lib/elixir_script/state.ex +++ b/lib/elixir_script/state.ex @@ -58,10 +58,10 @@ defmodule ElixirScript.State do end) end - def put_javascript_module(pid, module, path) do + def put_javascript_module(pid, module, name, path) do Agent.update(pid, fn(state) -> js_modules = Map.get(state, :js_modules, []) - js_modules = js_modules ++ [{module, path}] + js_modules = js_modules ++ [{module, name, path}] %{ state | js_modules: js_modules } end) @@ -71,10 +71,8 @@ defmodule ElixirScript.State do Agent.get(pid, fn(state) -> state.js_modules |> Enum.map(fn - {module_name, _path} -> - module_name - {module_name, _path, _opts} -> - module_name + {module, _name, _path} -> + module end) end) end @@ -82,10 +80,14 @@ defmodule ElixirScript.State do def js_modules(pid) do Agent.get(pid, fn(state) -> state.js_modules - |> Enum.filter(fn - {_, nil} -> false - _ -> true - end) + end) + end + + def get_js_module_name(pid, module) do + Agent.get(pid, fn(state) -> + {_, name, _} = state.js_modules + |> Enum.find(fn {m, _, _} -> module == m end) + name end) end diff --git a/test/support/json.ex b/test/support/json.ex index a3c7e349..d87ff485 100644 --- a/test/support/json.ex +++ b/test/support/json.ex @@ -1,4 +1,4 @@ -defmodule JSON do +defmodule Data.JSON do use ElixirScript.FFI foreign stringify(map) From b15c487e2d29f0d3c74f7a04cb9046a2ad437ff2 Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Thu, 13 Jul 2017 21:40:44 -0500 Subject: [PATCH 160/418] Add global option to FFI. Fixed copy of js files to output path --- lib/elixir_script/cli.ex | 33 +---------- lib/elixir_script/compiler.ex | 1 - lib/elixir_script/ffi.ex | 14 ++--- lib/elixir_script/lib/store.ex | 2 +- lib/elixir_script/lib/string.ex | 6 +- lib/elixir_script/passes/find_used_modules.ex | 14 ++++- lib/elixir_script/passes/output.ex | 55 +++++++++++++++---- .../passes/translate/forms/remote.ex | 9 ++- lib/elixir_script/passes/translate/module.ex | 7 ++- lib/elixir_script/state.ex | 1 - lib/mix/tasks/compile.elixir_script.ex | 3 +- .../lib/core/erlang_compat/erlang.js | 12 +++- test/cli_test.exs | 6 -- test/passes/translate/forms/js_test.exs | 38 ------------- test/support/main.ex | 6 +- 15 files changed, 93 insertions(+), 114 deletions(-) diff --git a/lib/elixir_script/cli.ex b/lib/elixir_script/cli.ex index fd27b355..79ffcd80 100644 --- a/lib/elixir_script/cli.ex +++ b/lib/elixir_script/cli.ex @@ -8,8 +8,7 @@ defmodule ElixirScript.CLI do help: :boolean, version: :boolean, watch: :boolean, - format: :string, - js_module: [:string, :keep] + format: :string ] @aliases [ @@ -43,8 +42,6 @@ defmodule ElixirScript.CLI do the entry module of your application options: - --js-module [:] A js module used in your code. ex: React:react - Multiple can be defined -f --format [format] module format of output. options: es (default), common, umd -o --output [path] places output at the given path. Can be a directory or filename. @@ -72,13 +69,9 @@ defmodule ElixirScript.CLI do def do_process(input, options) do {watch, options} = Keyword.pop(options, :watch, false) - js_modules = Keyword.get_values(options, :js_module) - |> build_js_modules - compile_opts = [ output: Keyword.get(options, :output, :stdout), - format: String.to_atom(Keyword.get(options, :format, "es")), - js_modules: js_modules, + format: String.to_atom(Keyword.get(options, :format, "es")) ] input = handle_input(input) @@ -106,26 +99,4 @@ defmodule ElixirScript.CLI do |> List.flatten |> Enum.map(fn(x) -> Module.concat([x]) end) end - - defp build_js_modules(values) do - values - |> Enum.map(fn x -> - [identifier, path] = String.split(x, ":", trim: true) - { format_identifier(identifier), format_path(path) } - end) - end - - defp format_identifier(id) do - id - |> String.split(".") - |> Module.concat - end - - - defp format_path(path) do - path - |> String.replace("\"", "") - |> String.replace("`", "") - |> String.replace("'", "") - end end diff --git a/lib/elixir_script/compiler.ex b/lib/elixir_script/compiler.ex index 79fe7238..1c2d9c85 100644 --- a/lib/elixir_script/compiler.ex +++ b/lib/elixir_script/compiler.ex @@ -39,7 +39,6 @@ defmodule ElixirScript.Compiler do default_options = Map.new |> Map.put(:output, Keyword.get(opts, :output)) |> Map.put(:format, Keyword.get(opts, :format, :es)) - |> Map.put(:js_modules, Keyword.get(opts, :js_modules, [])) |> Map.put(:entry_modules, entry_modules) options = default_options diff --git a/lib/elixir_script/ffi.ex b/lib/elixir_script/ffi.ex index 890a6913..80114588 100644 --- a/lib/elixir_script/ffi.ex +++ b/lib/elixir_script/ffi.ex @@ -1,15 +1,13 @@ defmodule ElixirScript.FFI do - defmacro __using__(_) do - js_path = Path.join([".", Macro.underscore(__MODULE__)]) - - js_name = __MODULE__ - |> Module.split() - |> Enum.join("_") - + defmacro __using__(opts) do quote do import ElixirScript.FFI Module.register_attribute __MODULE__, :__foreign_info__, persist: true - @__foreign_info__ %{path: unquote(js_path), name: unquote(js_name)} + @__foreign_info__ %{ + path: Macro.underscore(__MODULE__), + name: Enum.join(Module.split(__MODULE__), "_"), + global: unquote(Keyword.get(opts, :global, false)) + } end end diff --git a/lib/elixir_script/lib/store.ex b/lib/elixir_script/lib/store.ex index dd6b4a7a..14447d9d 100644 --- a/lib/elixir_script/lib/store.ex +++ b/lib/elixir_script/lib/store.ex @@ -1,6 +1,6 @@ defmodule Bootstrap.Core.Store do @moduledoc false - use ElixirScript.FFI + use ElixirScript.FFI, global: true foreign create(value, name \\ nil) diff --git a/lib/elixir_script/lib/string.ex b/lib/elixir_script/lib/string.ex index 1ad3d9bf..d692f815 100644 --- a/lib/elixir_script/lib/string.ex +++ b/lib/elixir_script/lib/string.ex @@ -15,15 +15,15 @@ defmodule ElixirScript.String do end def to_float(str) do - JS.parseFloat(str) + :erlang.binary_to_float(str) end def to_integer(str) do - JS.parseInt(str, 10) + :erlang.binary_to_integer(str) end def to_integer(str, base) do - JS.parseInt(str, base) + :erlang.binary_to_integer(str, base) end def upcase(str) do diff --git a/lib/elixir_script/passes/find_used_modules.ex b/lib/elixir_script/passes/find_used_modules.ex index ccd94136..e352a935 100644 --- a/lib/elixir_script/passes/find_used_modules.ex +++ b/lib/elixir_script/passes/find_used_modules.ex @@ -25,6 +25,16 @@ defmodule ElixirScript.FindUsedModules do end end + defp walk_module(module, %{attributes: [__foreign_info__: %{path: path, name: name, global: global}]} = info, pid) do + path = if global, do: nil, else: path + name = if global, do: module, else: name + + ModuleState.put_javascript_module(pid, module, name, path) + ModuleState.put_module(pid, module, info) + + nil + end + defp walk_module(module, info, pid) do %{ attributes: _attrs, @@ -232,7 +242,7 @@ defmodule ElixirScript.FindUsedModules do walk({function, [], params}, state) end - defp walk({{:., _, [module, function]} = ast, _, params}, state) do + defp walk({{:., _, [_module, _function]} = ast, _, params}, state) do walk(ast, state) walk(params, state) end @@ -243,8 +253,6 @@ defmodule ElixirScript.FindUsedModules do defp walk({:., _, [module, function]}, state) do cond do - ElixirScript.Translate.Module.is_js_module(module, state) -> - nil ElixirScript.Translate.Module.is_elixir_module(module) -> if ModuleState.get_module(state.pid, module) == nil do execute(module, state.pid) diff --git a/lib/elixir_script/passes/output.ex b/lib/elixir_script/passes/output.ex index 26522a4b..7b6575b1 100644 --- a/lib/elixir_script/passes/output.ex +++ b/lib/elixir_script/passes/output.ex @@ -19,14 +19,18 @@ defmodule ElixirScript.Output do opts = ModuleState.get_compiler_opts(pid) - #TODO: Combine Mix.Project.config()[:app] with Mix.Project.deps_paths() to - # get app names. - # File.exists? Path.join([:code.priv_dir(app), "src", "elixir_script"]) - # to find out if app has interop files. - # If so, copy files and directories to output folder - - bundle(modules, opts, ModuleState.js_modules(pid)) - |> output(Map.get(opts, :output)) + js_modules = ModuleState.js_modules(pid) + |> Enum.filter(fn + {_module, _name, nil} -> false + _ -> true + end) + |> Enum.map(fn + {module, name, path} -> + {module, name, Path.join(".", path)} + end) + + bundle(modules, opts, js_modules) + |> output(Map.get(opts, :output), js_modules) end defp bundle(modules, opts, js_modules) do @@ -61,21 +65,27 @@ defmodule ElixirScript.Output do end end - defp output(code, nil) do + defp output(code, nil, _) do code end - defp output(code, :stdout) do + defp output(code, :stdout, _) do IO.puts(code) end - defp output(code, path) do + defp output(code, path, js_modules) do file_name = get_output_file_name(path) if !File.exists?(Path.dirname(file_name)) do File.mkdir_p!(Path.dirname(file_name)) end + apps = get_app_names() + output_dir = Path.dirname(file_name) + Enum.each(js_modules, fn({_, _, path}) -> + copy_javascript_module(apps, output_dir, path) + end) + File.write!(file_name, code) end @@ -87,4 +97,27 @@ defmodule ElixirScript.Output do Path.join([path, @generated_name]) end end + + defp get_app_names() do + Mix.Project.config()[:app] + deps = Mix.Project.deps_paths() + |> Map.keys + + [Mix.Project.config()[:app]] ++ deps + end + + defp copy_javascript_module(apps, output_dir, js_module_path) do + Enum.each(apps, fn(app) -> + full_path = Path.join([:code.priv_dir(app), "elixir_script", js_module_path]) <> ".js" + + if File.exists?(full_path) do + js_output_path = Path.join(output_dir, js_module_path) <> ".js" + if !File.exists?(Path.dirname(js_output_path)) do + File.mkdir_p!(Path.dirname(js_output_path)) + end + + File.cp(full_path, js_output_path) + end + end) + end end \ No newline at end of file diff --git a/lib/elixir_script/passes/translate/forms/remote.ex b/lib/elixir_script/passes/translate/forms/remote.ex index c0ea3363..8651e557 100644 --- a/lib/elixir_script/passes/translate/forms/remote.ex +++ b/lib/elixir_script/passes/translate/forms/remote.ex @@ -168,8 +168,13 @@ defmodule ElixirScript.Translate.Forms.Remote do end defp process_js_module_name(module, state) do - name = ModuleState.get_js_module_name(state.pid, module) - J.identifier(name) + case ModuleState.get_js_module_name(state.pid, module) do + name when is_atom(name) -> + members = Module.split(module) + Identifier.make_namespace_members(members) + name -> + J.identifier(name) + end end defp erlang_compat_function(module, function) do diff --git a/lib/elixir_script/passes/translate/module.ex b/lib/elixir_script/passes/translate/module.ex index df98c5c1..7dde8c3e 100644 --- a/lib/elixir_script/passes/translate/module.ex +++ b/lib/elixir_script/passes/translate/module.ex @@ -12,8 +12,11 @@ defmodule ElixirScript.Translate.Module do ElixirScript.Translate.Protocol.compile(module, info, pid) end - def compile(module, %{attributes: [__foreign_info__: %{path: path, name: name}]}, pid) do - ModuleState.put_javascript_module(pid, name, path) + def compile(module, %{attributes: [__foreign_info__: %{path: path, name: name, global: global}]}, pid) do + path = if global, do: nil, else: path + name = if global, do: module, else: name + + ModuleState.put_javascript_module(pid, module, name, path) nil end diff --git a/lib/elixir_script/state.ex b/lib/elixir_script/state.ex index ed47108d..50ff4cb7 100644 --- a/lib/elixir_script/state.ex +++ b/lib/elixir_script/state.ex @@ -62,7 +62,6 @@ defmodule ElixirScript.State do Agent.update(pid, fn(state) -> js_modules = Map.get(state, :js_modules, []) js_modules = js_modules ++ [{module, name, path}] - %{ state | js_modules: js_modules } end) end diff --git a/lib/mix/tasks/compile.elixir_script.ex b/lib/mix/tasks/compile.elixir_script.ex index b01abbcb..1e6067e2 100644 --- a/lib/mix/tasks/compile.elixir_script.ex +++ b/lib/mix/tasks/compile.elixir_script.ex @@ -65,8 +65,7 @@ defmodule Mix.Tasks.Compile.ElixirScript do input = Keyword.fetch!(elixirscript_config, :input) opts = [ output: Keyword.get(elixirscript_config, :output), - format: Keyword.get(elixirscript_config, :format), - js_modules: Keyword.get(elixirscript_config, :js_modules, []) + format: Keyword.get(elixirscript_config, :format) ] {input, opts} diff --git a/src/javascript/lib/core/erlang_compat/erlang.js b/src/javascript/lib/core/erlang_compat/erlang.js index aefbf7b7..5a0bc2d4 100644 --- a/src/javascript/lib/core/erlang_compat/erlang.js +++ b/src/javascript/lib/core/erlang_compat/erlang.js @@ -309,6 +309,14 @@ function tuple_size(tuple) { return tuple.length; } +function binary_to_float(str) { + return parseFloat(str); +} + +function binary_to_integer(str, base = 10) { + return parseInt(str, base); +} + export default { atom_to_binary, binary_to_atom, @@ -372,5 +380,7 @@ export default { round, tl, trunc, - tuple_size + tuple_size, + binary_to_float, + binary_to_integer }; diff --git a/test/cli_test.exs b/test/cli_test.exs index 53589cc9..b08c1d93 100644 --- a/test/cli_test.exs +++ b/test/cli_test.exs @@ -30,10 +30,4 @@ defmodule ElixirScript.CLI.Test do ElixirScript.CLI.process({["Atom"], []}) end) =~ "export default Elixir" end - - test "process js modules" do - assert capture_io(fn -> - ElixirScript.CLI.process({["Atom"], [js_module: "React:react"]}) - end) =~ "import React from 'react'" - end end \ No newline at end of file diff --git a/test/passes/translate/forms/js_test.exs b/test/passes/translate/forms/js_test.exs index c6d7c121..31bf2af3 100644 --- a/test/passes/translate/forms/js_test.exs +++ b/test/passes/translate/forms/js_test.exs @@ -64,42 +64,4 @@ defmodule ElixirScript.Translate.Forms.JS.Test do [J.literal("react")] ) end - - test "global function or property" do - ast = {{:., [], [JS, :self]}, [], []} - state = %{function: {:each, nil}, module: Enum, vars: %{:_ => 0, "entry" => 0, "enumerable" => 0, "fun" => 0}} - - {js_ast, _} = Form.compile(ast, state) - assert js_ast == J.call_expression( - ElixirScript.Translate.Forms.JS.call_property(), - [ - ElixirScript.Translate.Forms.JS.global(), - J.literal("self") - ] - ) - end - - test "global function with params" do - ast = {{:., [], [JS, :self]}, [], ["something"]} - state = %{function: {:each, nil}, module: Enum, vars: %{:_ => 0, "entry" => 0, "enumerable" => 0, "fun" => 0}} - - {js_ast, _} = Form.compile(ast, state) - assert js_ast == J.call_expression( - J.identifier(:self), - [J.literal("something")] - ) - end - - test "JavaScript module call", %{state: state} do - ast = {{:., [], [JS.Object, :keys]}, [], [{:obj, [], nil}]} - - {js_ast, _} = Form.compile(ast, state) - assert js_ast == J.call_expression( - J.member_expression( - J.identifier("Object"), - J.identifier("keys") - ), - [J.identifier("obj")] - ) - end end \ No newline at end of file diff --git a/test/support/main.ex b/test/support/main.ex index d32cd32e..99e3158b 100644 --- a/test/support/main.ex +++ b/test/support/main.ex @@ -1,9 +1,7 @@ defmodule Main do def start(:normal, [callback]) do callback.("started") - - JSON.stringify(%{}) - - Enum.each(1..3, fn x -> JS.console.log(x) end) + Agent.start(fn() -> nil end) + Data.JSON.stringify(%{}) end end From ce9d1d3fd83ca5a2250b93a5fa17ee00b872b5aa Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Thu, 13 Jul 2017 21:55:47 -0500 Subject: [PATCH 161/418] Update documentation --- CHANGELOG.md | 8 ++++++++ lib/elixir_script/ffi.ex | 4 ++++ lib/elixir_script/passes/translate/function.ex | 3 +-- 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b484b9e3..e3f5598c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,14 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/) and this project adheres to [Semantic Versioning](http://semver.org/). +## [Unreleased] + +### Added +- ElixirScript now has an FFI layer for interoperability with JavaScript. For more details, see documentation at `ElixirScript.FFI` + +### Changed +- Compiler has been completely rewritten. ElixirScript now requires Erlang 20+ and Elixir 1.5+ + ## [0.28.0] - 2017-06-11 ### Added diff --git a/lib/elixir_script/ffi.ex b/lib/elixir_script/ffi.ex index 80114588..9c8e0363 100644 --- a/lib/elixir_script/ffi.ex +++ b/lib/elixir_script/ffi.ex @@ -1,4 +1,8 @@ defmodule ElixirScript.FFI do + @moduledoc """ + The foreign function interface for interoperability with JavaScript. + """ + defmacro __using__(opts) do quote do import ElixirScript.FFI diff --git a/lib/elixir_script/passes/translate/function.ex b/lib/elixir_script/passes/translate/function.ex index 148fe2ad..ecd353cf 100644 --- a/lib/elixir_script/passes/translate/function.ex +++ b/lib/elixir_script/passes/translate/function.ex @@ -5,8 +5,7 @@ defmodule ElixirScript.Translate.Function do @moduledoc """ Translates the given Elixir function AST into the - equivalent JavaScript AST. Function names are - + equivalent JavaScript AST. """ def patterns_ast() do From f4d45872c0183254116ee7901c8c8e39ac0153cc Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Thu, 13 Jul 2017 22:26:01 -0500 Subject: [PATCH 162/418] Update documentation for FFI module --- lib/elixir_script/ffi.ex | 29 +++++++++++++++++++++++++++++ test/support/main.ex | 2 -- 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/lib/elixir_script/ffi.ex b/lib/elixir_script/ffi.ex index 9c8e0363..a8130194 100644 --- a/lib/elixir_script/ffi.ex +++ b/lib/elixir_script/ffi.ex @@ -1,6 +1,35 @@ defmodule ElixirScript.FFI do @moduledoc """ The foreign function interface for interoperability with JavaScript. + + Define foreign modules with `use ElixirScript.FFI`. + Next to define functions for the foreign module, use the `foreign` macro. + + Here is an example of a foreign module for a JSON module + + ```elixir + defmodule MyApp.JSON do + use ElixirScript.FFI + + foreign stringify(map) + foreign parse(string) + end + ``` + + Foreign modules must have an equivalent JavaScript module. + ElixirScript expects JavaScript modules to be in the `priv/elixir_script` directory. + These modules will be copied to the output directory upon compilation. + + In the example, a JavaScript file must be at `priv/elixir_script/my_app/json.js`. + It looks like this + ```javascript + export default { + stringify: JSON.stringify, + parse: JSON.parse + } + ``` + + The JavaScript module must export a default object with the foreign functions defined in the Elixir module """ defmacro __using__(opts) do diff --git a/test/support/main.ex b/test/support/main.ex index 99e3158b..a18d3d90 100644 --- a/test/support/main.ex +++ b/test/support/main.ex @@ -1,7 +1,5 @@ defmodule Main do def start(:normal, [callback]) do callback.("started") - Agent.start(fn() -> nil end) - Data.JSON.stringify(%{}) end end From 69c327451670ca596e1994db8fae242d240c99a0 Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Fri, 14 Jul 2017 20:21:57 -0500 Subject: [PATCH 163/418] Update FFI documentation --- JavascriptInterop.md | 58 +++++++++++++--------------------------- lib/elixir_script/ffi.ex | 24 +++++++++++------ 2 files changed, 35 insertions(+), 47 deletions(-) diff --git a/JavascriptInterop.md b/JavascriptInterop.md index db0c0e45..de8bf745 100644 --- a/JavascriptInterop.md +++ b/JavascriptInterop.md @@ -13,55 +13,35 @@ JS.debugger() # Getting the type of a value JS.typeof(my_value) - -# Creating a new JavaScript Map -map = JS.new(JS.Map, []) ``` -### Accessing Global Objects, Functions, and Properties - -In order to interact with JavaScript things in the global scope, append "JS" to them. The global scope corresponds to whatever the global object is in the JavaScript environment you are in. For example, in a browser this would be `window` or `self`: +### Foreign Function Interface -```elixir -# Calling alert -JS.alert("hello") +ElixirScript calls JavaScript modules through a Foreign Function Interface (FFI). A foreign module is defined by creating a new module and adding `use ElixirScript.FFI` to it. -# Calling a method on Object -JS.Object.keys(my_object) +Here is an example of a foreign module for a JSON module -# Creating a new JavaScript Date -JS.new(JS.Date, []) +```elixir +defmodule MyApp.JSON do + use ElixirScript.FFI -# Getting the outer width -JS.outerWidth + foreign stringify(map) + foreign parse(string) +end ``` -### JavaScript modules - -ElixirScript can use JavaScript modules from the supported modules systems. -In order to do so, you must tell ElixirScript about them upfront. +Foreign modules map to JavaScript files that export functions defined with the `foreign` macro. +ElixirScript expects JavaScript modules to be in the `priv/elixir_script` directory. +These modules are copied to the output directory upon compilation. -If using ElixirScript in a mix project, you can do so inside of the ElixirScript configuration keyword list +For our example, a JavaScript file must be placed at `priv/elixir_script/my_app/json.js`. -```elixir - def project do - [ - app: :my_project, - elixir_script: [ - format: :es, - js_modules: [ - {React, "react"}, - {ReactDOM, "react-dom"} - ] - ] - ] - end -``` - -Interacting with these modules works the same as interacting with an ElixirScript module - -```elixir -React.createElement(...) +It looks like this +```javascript +export default { + stringify: JSON.stringify, + parse: JSON.parse +} ``` ## JavaScript Calling ElixirScript diff --git a/lib/elixir_script/ffi.ex b/lib/elixir_script/ffi.ex index a8130194..abffc29b 100644 --- a/lib/elixir_script/ffi.ex +++ b/lib/elixir_script/ffi.ex @@ -1,9 +1,9 @@ defmodule ElixirScript.FFI do @moduledoc """ - The foreign function interface for interoperability with JavaScript. + The foreign function interface for interacting with JavaScript - Define foreign modules with `use ElixirScript.FFI`. - Next to define functions for the foreign module, use the `foreign` macro. + To define a foreign module, make a new module and add `use ElixirScript.FFI`. to it + To define foreign functions, use the `foreign` macro. Here is an example of a foreign module for a JSON module @@ -16,11 +16,12 @@ defmodule ElixirScript.FFI do end ``` - Foreign modules must have an equivalent JavaScript module. + Foreign modules map to JavaScript files that export functions defined with the `foreign` macro. ElixirScript expects JavaScript modules to be in the `priv/elixir_script` directory. - These modules will be copied to the output directory upon compilation. + These modules are copied to the output directory upon compilation. + + For our example, a JavaScript file must be placed at `priv/elixir_script/my_app/json.js`. - In the example, a JavaScript file must be at `priv/elixir_script/my_app/json.js`. It looks like this ```javascript export default { @@ -28,8 +29,6 @@ defmodule ElixirScript.FFI do parse: JSON.parse } ``` - - The JavaScript module must export a default object with the foreign functions defined in the Elixir module """ defmacro __using__(opts) do @@ -44,6 +43,15 @@ defmodule ElixirScript.FFI do end end + @doc """ + Defines a JavaScript function to be called from Elixir modules + + To define a foreign function, pass the name and arguments to `foreign` + + ```elixir + foreign my_js_function(arg1, arg2, arg3) + ``` + """ defmacro foreign({name, _, args}) do quote do def unquote(name)(unquote_splicing(args)), do: nil From f5b09cb6e047f7b9d4c1b9fa31ff65fe9deead48 Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Fri, 14 Jul 2017 20:44:43 -0500 Subject: [PATCH 164/418] Add test for FFI output. Refactor debug_info for ElixirScript replacements --- lib/elixir_script/beam.ex | 18 ++++-------------- test/compiler_test.exs | 8 +++++++- test/support/main.ex | 2 ++ 3 files changed, 13 insertions(+), 15 deletions(-) diff --git a/lib/elixir_script/beam.ex b/lib/elixir_script/beam.ex index d8cb7213..e850d837 100644 --- a/lib/elixir_script/beam.ex +++ b/lib/elixir_script/beam.ex @@ -10,21 +10,11 @@ defmodule ElixirScript.Beam do @spec debug_info(atom) :: {:ok | :error, map | binary} def debug_info(module) - #Replacing String module with our ElixirScript's version - def debug_info(String) do - case debug_info(ElixirScript.String) do + #Replace some modules with ElixirScript versions + def debug_info(module) when module in [String, Agent] do + case debug_info(Module.concat(ElixirScript, module)) do {:ok, info} -> - {:ok, Map.put(info, :module, String)} - e -> - e - end - end - - #Replacing Agent module with our ElixirScript's version - def debug_info(Agent) do - case debug_info(ElixirScript.Agent) do - {:ok, info} -> - {:ok, Map.put(info, :module, Agent)} + {:ok, Map.put(info, :module, module)} e -> e end diff --git a/test/compiler_test.exs b/test/compiler_test.exs index c154e67c..5651ec05 100644 --- a/test/compiler_test.exs +++ b/test/compiler_test.exs @@ -6,8 +6,14 @@ defmodule ElixirScript.Compiler.Test do assert is_binary(result) end + test "Use defined module with FFI module" do + result = ElixirScript.Compiler.compile(Main) + assert is_binary(result) + assert result =~ "import Data_JSON from './data/json'" + end + test "Can compile multiple entry modules" do - result = ElixirScript.Compiler.compile([Atom, String]) + result = ElixirScript.Compiler.compile([Atom, String, Agent]) assert is_binary(result) end diff --git a/test/support/main.ex b/test/support/main.ex index a18d3d90..8cdf51d8 100644 --- a/test/support/main.ex +++ b/test/support/main.ex @@ -1,5 +1,7 @@ defmodule Main do def start(:normal, [callback]) do callback.("started") + + Data.JSON.stringify(1) end end From 95efb4b1b481b754d7b76698806ebd2a04d62e42 Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Fri, 14 Jul 2017 20:47:20 -0500 Subject: [PATCH 165/418] Test FFI JavaScript file moved to output folder --- test/compiler_test.exs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/test/compiler_test.exs b/test/compiler_test.exs index 5651ec05..a2a3cce3 100644 --- a/test/compiler_test.exs +++ b/test/compiler_test.exs @@ -52,4 +52,12 @@ defmodule ElixirScript.Compiler.Test do result = ElixirScript.Compiler.compile(Atom, [output: path]) assert File.exists?(path) end + + test "Output with FFI" do + path = System.tmp_dir() + + result = ElixirScript.Compiler.compile(Main, [output: path]) + assert File.exists?(Path.join([path, "Elixir.App.js"])) + assert File.exists?(Path.join([path, "data", "json.js"])) + end end \ No newline at end of file From 43636b34351078e6de553a742a9ebafd86fefb77 Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Sat, 15 Jul 2017 07:20:56 -0500 Subject: [PATCH 166/418] Remove test json ffi module --- test/compiler_test.exs | 14 -------------- test/support/json.ex | 6 ------ test/support/main.ex | 2 -- 3 files changed, 22 deletions(-) delete mode 100644 test/support/json.ex diff --git a/test/compiler_test.exs b/test/compiler_test.exs index a2a3cce3..f41aa7bf 100644 --- a/test/compiler_test.exs +++ b/test/compiler_test.exs @@ -6,12 +6,6 @@ defmodule ElixirScript.Compiler.Test do assert is_binary(result) end - test "Use defined module with FFI module" do - result = ElixirScript.Compiler.compile(Main) - assert is_binary(result) - assert result =~ "import Data_JSON from './data/json'" - end - test "Can compile multiple entry modules" do result = ElixirScript.Compiler.compile([Atom, String, Agent]) assert is_binary(result) @@ -52,12 +46,4 @@ defmodule ElixirScript.Compiler.Test do result = ElixirScript.Compiler.compile(Atom, [output: path]) assert File.exists?(path) end - - test "Output with FFI" do - path = System.tmp_dir() - - result = ElixirScript.Compiler.compile(Main, [output: path]) - assert File.exists?(Path.join([path, "Elixir.App.js"])) - assert File.exists?(Path.join([path, "data", "json.js"])) - end end \ No newline at end of file diff --git a/test/support/json.ex b/test/support/json.ex deleted file mode 100644 index d87ff485..00000000 --- a/test/support/json.ex +++ /dev/null @@ -1,6 +0,0 @@ -defmodule Data.JSON do - use ElixirScript.FFI - - foreign stringify(map) - foreign parse(string) -end \ No newline at end of file diff --git a/test/support/main.ex b/test/support/main.ex index 8cdf51d8..a18d3d90 100644 --- a/test/support/main.ex +++ b/test/support/main.ex @@ -1,7 +1,5 @@ defmodule Main do def start(:normal, [callback]) do callback.("started") - - Data.JSON.stringify(1) end end From 729927ce28c2ad6b766eede9ff9859eeddc28319 Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Sat, 15 Jul 2017 07:41:58 -0500 Subject: [PATCH 167/418] Refactoring. Update dependencies --- lib/elixir_script/passes/translate/forms/remote.ex | 6 +----- lib/elixir_script/passes/translate/identifier.ex | 4 ---- mix.lock | 6 +++--- 3 files changed, 4 insertions(+), 12 deletions(-) diff --git a/lib/elixir_script/passes/translate/forms/remote.ex b/lib/elixir_script/passes/translate/forms/remote.ex index 8651e557..c09a065d 100644 --- a/lib/elixir_script/passes/translate/forms/remote.ex +++ b/lib/elixir_script/passes/translate/forms/remote.ex @@ -126,11 +126,7 @@ defmodule ElixirScript.Translate.Forms.Remote do end def compile({:., _, [module, function]}, state) do - function_name = if ElixirScript.Translate.Module.is_js_module(module, state) do - ElixirScript.Translate.Identifier.make_extern_function_name(function) - else - ElixirScript.Translate.Identifier.make_function_name(function) - end + function_name = ElixirScript.Translate.Identifier.make_function_name(function) ast = J.member_expression( process_module_name(module, state), diff --git a/lib/elixir_script/passes/translate/identifier.ex b/lib/elixir_script/passes/translate/identifier.ex index e91c02d2..a619f1fa 100644 --- a/lib/elixir_script/passes/translate/identifier.ex +++ b/lib/elixir_script/passes/translate/identifier.ex @@ -75,8 +75,4 @@ defmodule ElixirScript.Translate.Identifier do J.identifier(name) end - def make_extern_function_name(name) do - J.identifier("#{name}") - end - end diff --git a/mix.lock b/mix.lock index 9de5d64f..992c5f2f 100644 --- a/mix.lock +++ b/mix.lock @@ -1,10 +1,10 @@ %{"bunt": {:hex, :bunt, "0.2.0", "951c6e801e8b1d2cbe58ebbd3e616a869061ddadcc4863d0a2182541acae9a38", [:mix], [], "hexpm"}, "certifi": {:hex, :certifi, "1.2.1", "c3904f192bd5284e5b13f20db3ceac9626e14eeacfbb492e19583cf0e37b22be", [:rebar3], [], "hexpm"}, - "credo": {:hex, :credo, "0.8.1", "137efcc99b4bc507c958ba9b5dff70149e971250813cbe7d4537ec7e36997402", [:mix], [{:bunt, "~> 0.2.0", [hex: :bunt, repo: "hexpm", optional: false]}], "hexpm"}, + "credo": {:hex, :credo, "0.8.3", "efe6e9078de64cefdd25d8df7a97292e29e63f42a8988990340eaf1f40d93224", [:mix], [{:bunt, "~> 0.2.0", [hex: :bunt, repo: "hexpm", optional: false]}], "hexpm"}, "earmark": {:hex, :earmark, "1.2.2", "f718159d6b65068e8daeef709ccddae5f7fdc770707d82e7d126f584cd925b74", [:mix], [], "hexpm"}, "estree": {:hex, :estree, "2.6.0", "86a301b0c355fa55c19e7ef9dceb1b1e983c6df526a2b7846818a38c258fc3fb", [:mix], [], "hexpm"}, - "ex_doc": {:hex, :ex_doc, "0.16.1", "b4b8a23602b4ce0e9a5a960a81260d1f7b29635b9652c67e95b0c2f7ccee5e81", [:mix], [{:earmark, "~> 1.1", [hex: :earmark, repo: "hexpm", optional: false]}], "hexpm"}, - "excoveralls": {:hex, :excoveralls, "0.7.0", "05cb3332c2b0f799df3ab90eb7df1ae5a147c86776e91792848a12b7ed87242f", [:mix], [{:exjsx, ">= 3.0.0", [hex: :exjsx, repo: "hexpm", optional: false]}, {:hackney, ">= 0.12.0", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm"}, + "ex_doc": {:hex, :ex_doc, "0.16.2", "3b3e210ebcd85a7c76b4e73f85c5640c011d2a0b2f06dcdf5acdb2ae904e5084", [:mix], [{:earmark, "~> 1.1", [hex: :earmark, repo: "hexpm", optional: false]}], "hexpm"}, + "excoveralls": {:hex, :excoveralls, "0.7.1", "3dd659db19c290692b5e2c4a2365ae6d4488091a1ba58f62dcbdaa0c03da5491", [:mix], [{:exjsx, ">= 3.0.0", [hex: :exjsx, repo: "hexpm", optional: false]}, {:hackney, ">= 0.12.0", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm"}, "exjsx": {:hex, :exjsx, "4.0.0", "60548841e0212df401e38e63c0078ec57b33e7ea49b032c796ccad8cde794b5c", [:mix], [{:jsx, "~> 2.8.0", [hex: :jsx, repo: "hexpm", optional: false]}], "hexpm"}, "fs": {:hex, :fs, "3.4.0", "6d18575c250b415b3cad559e6f97a4c822516c7bc2c10bfbb2493a8f230f5132", [:rebar3], [], "hexpm"}, "hackney": {:hex, :hackney, "1.8.6", "21a725db3569b3fb11a6af17d5c5f654052ce9624219f1317e8639183de4a423", [:rebar3], [{:certifi, "1.2.1", [hex: :certifi, repo: "hexpm", optional: false]}, {:idna, "5.0.2", [hex: :idna, repo: "hexpm", optional: false]}, {:metrics, "1.0.1", [hex: :metrics, repo: "hexpm", optional: false]}, {:mimerl, "1.0.2", [hex: :mimerl, repo: "hexpm", optional: false]}, {:ssl_verify_fun, "1.1.1", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}], "hexpm"}, From caa147895af9f0bd542354427ed1b31fd5e8309d Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Sat, 15 Jul 2017 07:51:58 -0500 Subject: [PATCH 168/418] Add ffi test --- test/ffi_test.exs | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 test/ffi_test.exs diff --git a/test/ffi_test.exs b/test/ffi_test.exs new file mode 100644 index 00000000..dbbaa77d --- /dev/null +++ b/test/ffi_test.exs @@ -0,0 +1,17 @@ +defmodule ElixirScript.FFI.Test do + use ExUnit.Case + + defmodule MyTestModule do + use ElixirScript.FFI + + foreign my_test_function(arg1, arg2) + end + + test "FFI module has __foreign_info__ attribute" do + assert Keyword.has_key?(MyTestModule.__info__(:attributes), :__foreign_info__) + end + + test "FFI module makes foreign function" do + assert Keyword.has_key?(MyTestModule.__info__(:functions), :my_test_function) + end +end \ No newline at end of file From 5ea4512ccfb377923b611b483282974fc1ed81c2 Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Sat, 15 Jul 2017 23:06:49 -0500 Subject: [PATCH 169/418] Implement with special form --- .tool-versions | 4 +- .../passes/find_used_functions.ex | 25 +++++++- lib/elixir_script/passes/find_used_modules.ex | 25 +++++++- lib/elixir_script/passes/translate/form.ex | 6 +- .../passes/translate/forms/with.ex | 61 +++++++++++++++++++ package.json | 4 +- src/javascript/lib/core/special_forms.js | 2 +- src/javascript/tests/with.spec.js | 3 +- test/support/main.ex | 10 +++ 9 files changed, 130 insertions(+), 10 deletions(-) create mode 100644 lib/elixir_script/passes/translate/forms/with.ex diff --git a/.tool-versions b/.tool-versions index 1c908046..1c12341c 100644 --- a/.tool-versions +++ b/.tool-versions @@ -1,3 +1,3 @@ erlang 20.0 -elixir ref-v1.5.0-rc.0 -nodejs 8.1.0 \ No newline at end of file +elixir ref-v1.5.0-rc.1 +nodejs 8.1.0 diff --git a/lib/elixir_script/passes/find_used_functions.ex b/lib/elixir_script/passes/find_used_functions.ex index 50177616..853749ce 100644 --- a/lib/elixir_script/passes/find_used_functions.ex +++ b/lib/elixir_script/passes/find_used_functions.ex @@ -216,6 +216,29 @@ defmodule ElixirScript.FindUsedFunctions do Enum.each(clauses, &walk(&1, state)) end + defp walk({:with, _, args}, state) do + Enum.each(args, fn + {:<-, _, [left, right]} -> + walk(left, state) + walk(right, state) + + {:=, _, [left, right]} -> + walk(left, state) + walk(right, state) + + [do: expression] -> + walk_block(expression, state) + + [do: expression, else: elses] -> + walk_block(expression, state) + Enum.each(elses, fn + {:->, _, [left, right]} -> + walk(left, state) + walk(right, state) + end) + end) + end + defp walk({{:., _, [:erlang, :apply]}, _, [module, function, params]}, state) do walk({{:., [], [module, function]}, [], params}, state) end @@ -272,4 +295,4 @@ defmodule ElixirScript.FindUsedFunctions do end end -end \ No newline at end of file +end diff --git a/lib/elixir_script/passes/find_used_modules.ex b/lib/elixir_script/passes/find_used_modules.ex index e352a935..8b2f066d 100644 --- a/lib/elixir_script/passes/find_used_modules.ex +++ b/lib/elixir_script/passes/find_used_modules.ex @@ -234,6 +234,29 @@ defmodule ElixirScript.FindUsedModules do Enum.each(clauses, &walk(&1, state)) end + defp walk({:with, _, args}, state) do + Enum.each(args, fn + {:<-, _, [left, right]} -> + walk(left, state) + walk(right, state) + + {:=, _, [left, right]} -> + walk(left, state) + walk(right, state) + + [do: expression] -> + walk_block(expression, state) + + [do: expression, else: elses] -> + walk_block(expression, state) + Enum.each(elses, fn + {:->, _, [left, right]} -> + walk(left, state) + walk(right, state) + end) + end) + end + defp walk({{:., _, [:erlang, :apply]}, _, [module, function, params]}, state) do walk({{:., [], [module, function]}, [], params}, state) end @@ -289,4 +312,4 @@ defmodule ElixirScript.FindUsedModules do end end -end \ No newline at end of file +end diff --git a/lib/elixir_script/passes/translate/form.ex b/lib/elixir_script/passes/translate/form.ex index 385156da..31776b3d 100644 --- a/lib/elixir_script/passes/translate/form.ex +++ b/lib/elixir_script/passes/translate/form.ex @@ -1,6 +1,6 @@ defmodule ElixirScript.Translate.Form do alias ESTree.Tools.Builder, as: J - alias ElixirScript.Translate.Forms.{Bitstring, Match, Try, For, Receive, Remote, Pattern} + alias ElixirScript.Translate.Forms.{Bitstring, Match, Try, For, Receive, Remote, Pattern, With} alias ElixirScript.Translate.Clause require Logger @@ -203,6 +203,10 @@ defmodule ElixirScript.Translate.Form do Try.compile(blocks, state) end + def compile({:with, _, args}, state) do + With.compile(args, state) + end + def compile({:fn, _, _} = ast, state) do ElixirScript.Translate.Function.compile(ast, state) end diff --git a/lib/elixir_script/passes/translate/forms/with.ex b/lib/elixir_script/passes/translate/forms/with.ex new file mode 100644 index 00000000..ad78ce22 --- /dev/null +++ b/lib/elixir_script/passes/translate/forms/with.ex @@ -0,0 +1,61 @@ +defmodule ElixirScript.Translate.Forms.With do + @moduledoc false + alias ESTree.Tools.Builder, as: JS + alias ElixirScript.Translate.{Function, Clause} + alias ElixirScript.Translate.Forms.Pattern + + + def compile(args, module_state) do + result = Enum.reduce(args, %{ expressions: [], arguments: [], module_state: module_state }, fn + {symbol, _, [pattern, body] }, state when symbol in [:<-, :=] -> + {ast, module_state} = Function.compile_block(body, state.module_state) + body = Clause.return_last_statement(ast) + expr_function = JS.arrow_function_expression(state.arguments, [], JS.block_statement(body)) + + { patterns, params, module_state } = Pattern.compile([pattern], module_state) + + %{state | arguments: state.arguments ++ params, + expressions: state.expressions ++ [ JS.array_expression([hd(patterns), expr_function]) ], + module_state: module_state + } + + [do: expr], state -> + expr_function = process_block(expr, state.arguments, state.module_state) + + %{state | expressions: state.expressions ++ [ expr_function ] } + [do: do_expr, else: else_expr], state -> + do_function = process_block(do_expr, state.arguments, state.module_state) + + { else_function, _ } = Function.compile({:fn, [], else_expr}, state.module_state) + + %{state | expressions: state.expressions ++ [ do_function, else_function ] } + end) + + expressions = result.expressions + + js_ast = JS.call_expression( + JS.member_expression( + JS.member_expression( + JS.identifier("Bootstrap"), + JS.member_expression( + JS.identifier("Core"), + JS.identifier("SpecialForms") + ) + ), + JS.identifier("_with") + ), + expressions + ) + + { js_ast, module_state } + + end + + + defp process_block(body, arguments, module_state) do + {ast, _} = Function.compile_block(body, module_state) + + body = Clause.return_last_statement(ast) + JS.arrow_function_expression(arguments, [], JS.block_statement(body)) + end +end diff --git a/package.json b/package.json index bb34b229..882c88a0 100644 --- a/package.json +++ b/package.json @@ -41,9 +41,7 @@ "sinon": "^1.17.7" }, "ava": { - "require": [ - "babel-register" - ], + "require": ["babel-register"], "babel": { "babelrc": true } diff --git a/src/javascript/lib/core/special_forms.js b/src/javascript/lib/core/special_forms.js index fbb830cd..fe00aa6d 100644 --- a/src/javascript/lib/core/special_forms.js +++ b/src/javascript/lib/core/special_forms.js @@ -151,5 +151,5 @@ export default { _for, _try, _with, - receive, + receive }; diff --git a/src/javascript/tests/with.spec.js b/src/javascript/tests/with.spec.js index d57322d8..924c844b 100644 --- a/src/javascript/tests/with.spec.js +++ b/src/javascript/tests/with.spec.js @@ -1,5 +1,6 @@ import Core from '../lib/core'; import test from 'ava'; + const Patterns = Core.Patterns; const SpecialForms = Core.SpecialForms; const Tuple = Core.Tuple; @@ -78,7 +79,7 @@ test('with bare expression', t => { [$, width => width * 2], [ new Tuple(Symbol.for('ok'), $), - (width, double_width) => map_fetch(opts, 'height'), + (width, double_width) => map_fetch(opts, 'height') ], (width, double_width, height) => new Tuple(Symbol.for('ok'), double_width * height) diff --git a/test/support/main.ex b/test/support/main.ex index a18d3d90..94946a83 100644 --- a/test/support/main.ex +++ b/test/support/main.ex @@ -1,5 +1,15 @@ defmodule Main do def start(:normal, [callback]) do callback.("started") + + opts = %{width: 10, height: 15} + with {:ok, width} <- Map.fetch(opts, :width), + {:ok, height} <- Map.fetch(opts, :height) + do + {:ok, width * height} + else + :error -> + {:error, :wrong_data} + end end end From d2be43293d27a0172f92c5d72567811fdb2a1b44 Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Sat, 15 Jul 2017 23:11:45 -0500 Subject: [PATCH 170/418] Update travis ci config --- .travis.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index ce075d5f..e4ec9f8e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -9,8 +9,8 @@ install: - npm install -g yarn - yarn before_script: - - wget https://repo.hex.pm/builds/elixir/v1.5.0-rc.0-otp-20.zip - - unzip -d elixir v1.5.0-rc.0-otp-20.zip + - wget https://repo.hex.pm/builds/elixir/v1.5.0-rc.1-otp-20.zip + - unzip -d elixir v1.5.0-rc.1-otp-20.zip - export PATH=$(pwd)/elixir/bin:${PATH} - mix local.rebar --force - mix local.hex --force @@ -26,4 +26,4 @@ notifications: - https://webhooks.gitter.im/e/fbd8944d285c0696dc41 on_success: always # options: [always|never|change] default: always on_failure: always # options: [always|never|change] default: always - on_start: never # options: [always|never|change] default: always \ No newline at end of file + on_start: never # options: [always|never|change] default: always From 02259bd967adf2fcc34546018c495ee616c76853 Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Sat, 15 Jul 2017 23:26:41 -0500 Subject: [PATCH 171/418] Rename JS module to ElixirScript.JS --- CHANGELOG.md | 1 + JavascriptInterop.md | 14 ++++----- lib/elixir_script/lib/js.ex | 4 +-- .../passes/find_used_functions.ex | 2 +- lib/elixir_script/passes/find_used_modules.ex | 2 +- lib/elixir_script/passes/translate/form.ex | 2 +- .../passes/translate/forms/bitstring.ex | 2 +- .../passes/translate/forms/js.ex | 31 +++---------------- test/passes/translate/forms/js_test.exs | 12 +++---- 9 files changed, 25 insertions(+), 45 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e3f5598c..10cd0b98 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ### Changed - Compiler has been completely rewritten. ElixirScript now requires Erlang 20+ and Elixir 1.5+ +- `JS` module renamed to `ElixirScript.JS` ## [0.28.0] - 2017-06-11 diff --git a/JavascriptInterop.md b/JavascriptInterop.md index de8bf745..438a2781 100644 --- a/JavascriptInterop.md +++ b/JavascriptInterop.md @@ -2,17 +2,17 @@ ## ElixirScript Calling JavaScript -### JS module +### ElixirScript.JS module -The `JS` module has functions and macros that help with interacting with JavaScript. +The `ElixirScript.JS` module has functions and macros that help with interacting with JavaScript. These mostly correspond to JavaScript keywords that may be useful. ```elixir # Calling the JavaScript Debugger -JS.debugger() +ElixirScript.JS.debugger() # Getting the type of a value -JS.typeof(my_value) +ElixirScript.JS.typeof(my_value) ``` ### Foreign Function Interface @@ -53,7 +53,7 @@ export default { defmodule Main do def start(:normal, args) do - JS.console.log(args) + args end end @@ -75,7 +75,7 @@ export default { defmodule MyModule do def hi() do - JS.alert("hello") + "hello" end end ``` @@ -84,4 +84,4 @@ export default { ```javascript const MyModule = Elixir.load(Elixir.MyModule); MyModule.hi() - ``` \ No newline at end of file + ``` diff --git a/lib/elixir_script/lib/js.ex b/lib/elixir_script/lib/js.ex index 990a2110..dc584638 100644 --- a/lib/elixir_script/lib/js.ex +++ b/lib/elixir_script/lib/js.ex @@ -1,4 +1,4 @@ -defmodule JS do +defmodule ElixirScript.JS do @moduledoc """ This module defines macros and functions which implement JavaScript functionality that may not translate easily to @@ -9,7 +9,7 @@ defmodule JS do Creates new JavaScript objects. ex: - JS.new User, ["first_name", "last_name"] + ElixirScript.JS.new User, ["first_name", "last_name"] """ defmacro new(module, params) diff --git a/lib/elixir_script/passes/find_used_functions.ex b/lib/elixir_script/passes/find_used_functions.ex index 853749ce..b7ffdcf6 100644 --- a/lib/elixir_script/passes/find_used_functions.ex +++ b/lib/elixir_script/passes/find_used_functions.ex @@ -247,7 +247,7 @@ defmodule ElixirScript.FindUsedFunctions do walk({function, [], params}, state) end - defp walk({{:., _, [JS, _]}, _, params}, state) do + defp walk({{:., _, [ElixirScript.JS, _]}, _, params}, state) do walk(params, state) end diff --git a/lib/elixir_script/passes/find_used_modules.ex b/lib/elixir_script/passes/find_used_modules.ex index 8b2f066d..b7ebddc7 100644 --- a/lib/elixir_script/passes/find_used_modules.ex +++ b/lib/elixir_script/passes/find_used_modules.ex @@ -270,7 +270,7 @@ defmodule ElixirScript.FindUsedModules do walk(params, state) end - defp walk({:., _, [JS, _]}, _) do + defp walk({:., _, [ElixirScript.JS, _]}, _) do nil end diff --git a/lib/elixir_script/passes/translate/form.ex b/lib/elixir_script/passes/translate/form.ex index 31776b3d..5c843e5d 100644 --- a/lib/elixir_script/passes/translate/form.ex +++ b/lib/elixir_script/passes/translate/form.ex @@ -220,7 +220,7 @@ defmodule ElixirScript.Translate.Form do {ast, state} end - def compile({{:., _, [JS, _]}, _, _} = ast, state) do + def compile({{:., _, [ElixirScript.JS, _]}, _, _} = ast, state) do ElixirScript.Translate.Forms.JS.compile(ast, state) end diff --git a/lib/elixir_script/passes/translate/forms/bitstring.ex b/lib/elixir_script/passes/translate/forms/bitstring.ex index 1490f74f..3a2a1d5c 100644 --- a/lib/elixir_script/passes/translate/forms/bitstring.ex +++ b/lib/elixir_script/passes/translate/forms/bitstring.ex @@ -132,7 +132,7 @@ defmodule ElixirScript.Translate.Forms.Bitstring do result = case translated_elements do [] -> JS.literal('') - [element] -> + [_] -> do_make_interpolated_string([], hd(translated_elements)) elements -> do_make_interpolated_string(tl(elements), hd(elements)) diff --git a/lib/elixir_script/passes/translate/forms/js.ex b/lib/elixir_script/passes/translate/forms/js.ex index 80c8cca9..d3e74e89 100644 --- a/lib/elixir_script/passes/translate/forms/js.ex +++ b/lib/elixir_script/passes/translate/forms/js.ex @@ -26,17 +26,17 @@ defmodule ElixirScript.Translate.Forms.JS do ) end - def compile({{:., _, [JS, :debugger]}, _, _}, state) do + def compile({{:., _, [ElixirScript.JS, :debugger]}, _, _}, state) do ast = J.debugger_statement() {ast, state} end - def compile({{:., _, [JS, :this]}, _, _}, state) do + def compile({{:., _, [ElixirScript.JS, :this]}, _, _}, state) do ast = J.this_expression() {ast, state} end - def compile({{:., _, [JS, :new]}, _, [module, params]}, state) do + def compile({{:., _, [ElixirScript.JS, :new]}, _, [module, params]}, state) do members = Module.split(module) members = case members do @@ -61,7 +61,7 @@ defmodule ElixirScript.Translate.Forms.JS do {ast, state} end - def compile({{:., _, [JS, :throw]}, _, [term]}, state) do + def compile({{:., _, [ElixirScript.JS, :throw]}, _, [term]}, state) do ast = J.throw_statement( Form.compile!(term, state) ) @@ -69,7 +69,7 @@ defmodule ElixirScript.Translate.Forms.JS do {ast, state} end - def compile({{:., _, [JS, :import]}, _, [term]}, state) do + def compile({{:., _, [ElixirScript.JS, :import]}, _, [term]}, state) do ast = J.call_expression( J.identifier("import"), [Form.compile!(term, state)] @@ -77,25 +77,4 @@ defmodule ElixirScript.Translate.Forms.JS do {ast, state} end - - def compile({{:., _, [JS, function]}, _, []}, state) do - ast = J.call_expression( - call_property(), - [ - global(), - Form.compile!(to_string(function), state) - ] - ) - - {ast, state} - end - - def compile({{:., _, [JS, function]}, _, params}, state) do - ast = J.call_expression( - J.identifier(function), - Enum.map(params, &Form.compile!(&1, state)) - ) - - {ast, state} - end end diff --git a/test/passes/translate/forms/js_test.exs b/test/passes/translate/forms/js_test.exs index 31bf2af3..635c1994 100644 --- a/test/passes/translate/forms/js_test.exs +++ b/test/passes/translate/forms/js_test.exs @@ -15,7 +15,7 @@ defmodule ElixirScript.Translate.Forms.JS.Test do end test "debugger" do - ast = {{:., [], [JS, :debugger]}, [], []} + ast = {{:., [], [ElixirScript.JS, :debugger]}, [], []} state = %{function: {:each, nil}, module: Enum, vars: %{:_ => 0, "entry" => 0, "enumerable" => 0, "fun" => 0}} {js_ast, _} = Form.compile(ast, state) @@ -23,7 +23,7 @@ defmodule ElixirScript.Translate.Forms.JS.Test do end test "this" do - ast = {{:., [], [JS, :this]}, [], []} + ast = {{:., [], [ElixirScript.JS, :this]}, [], []} state = %{function: {:each, nil}, module: Enum, vars: %{:_ => 0, "entry" => 0, "enumerable" => 0, "fun" => 0}} {js_ast, _} = Form.compile(ast, state) @@ -31,7 +31,7 @@ defmodule ElixirScript.Translate.Forms.JS.Test do end test "new" do - ast = {{:., [], [JS, :new]}, [], [BLT, ["bacon", "lettuce", "tomato"]]} + ast = {{:., [], [ElixirScript.JS, :new]}, [], [BLT, ["bacon", "lettuce", "tomato"]]} state = %{function: {:each, nil}, module: Enum, vars: %{:_ => 0, "entry" => 0, "enumerable" => 0, "fun" => 0}} {js_ast, _} = Form.compile(ast, state) @@ -47,7 +47,7 @@ defmodule ElixirScript.Translate.Forms.JS.Test do test "throw" do - ast = {{:., [], [JS, :throw]}, [], [1]} + ast = {{:., [], [ElixirScript.JS, :throw]}, [], [1]} state = %{function: {:each, nil}, module: Enum, vars: %{:_ => 0, "entry" => 0, "enumerable" => 0, "fun" => 0}} {js_ast, _} = Form.compile(ast, state) @@ -55,7 +55,7 @@ defmodule ElixirScript.Translate.Forms.JS.Test do end test "import" do - ast = {{:., [], [JS, :import]}, [], ["react"]} + ast = {{:., [], [ElixirScript.JS, :import]}, [], ["react"]} state = %{function: {:each, nil}, module: Enum, vars: %{:_ => 0, "entry" => 0, "enumerable" => 0, "fun" => 0}} {js_ast, _} = Form.compile(ast, state) @@ -64,4 +64,4 @@ defmodule ElixirScript.Translate.Forms.JS.Test do [J.literal("react")] ) end -end \ No newline at end of file +end From 2425a563cb5739076aeb39763172edf062366fda Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Sat, 15 Jul 2017 23:44:57 -0500 Subject: [PATCH 172/418] Add ElixirScript.JS.mutate --- CHANGELOG.md | 2 + lib/elixir_script/lib/js.ex | 14 +++++ .../passes/translate/forms/js.ex | 41 +++++++++++---- test/passes/translate/forms/js_test.exs | 51 +++++++++++++++++++ 4 files changed, 98 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 10cd0b98..c164ace1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ### Added - ElixirScript now has an FFI layer for interoperability with JavaScript. For more details, see documentation at `ElixirScript.FFI` +- ElixirScript.JS.mutate/2 +- ElixirScript.JS.mutate/3 ### Changed - Compiler has been completely rewritten. ElixirScript now requires Erlang 20+ and Elixir 1.5+ diff --git a/lib/elixir_script/lib/js.ex b/lib/elixir_script/lib/js.ex index dc584638..2c14151c 100644 --- a/lib/elixir_script/lib/js.ex +++ b/lib/elixir_script/lib/js.ex @@ -37,4 +37,18 @@ defmodule ElixirScript.JS do The current JavaScript context """ defmacro this() + + @doc """ + Mutates an existing JavaScript object. + ex: + ElixirScript.JS.mutate elem, %{"width" => 100} + """ + defmacro update(object, map) + + @doc """ + Mutates an existing JavaScript object. + ex: + ElixirScript.JS.mutate elem, "width", 100 + """ + defmacro update(object, key, value) end diff --git a/lib/elixir_script/passes/translate/forms/js.ex b/lib/elixir_script/passes/translate/forms/js.ex index d3e74e89..c33f121e 100644 --- a/lib/elixir_script/passes/translate/forms/js.ex +++ b/lib/elixir_script/passes/translate/forms/js.ex @@ -16,16 +16,6 @@ defmodule ElixirScript.Translate.Forms.JS do ) end - def global() do - J.member_expression( - J.member_expression( - J.identifier("Bootstrap"), - J.identifier("Core") - ), - J.identifier("global") - ) - end - def compile({{:., _, [ElixirScript.JS, :debugger]}, _, _}, state) do ast = J.debugger_statement() {ast, state} @@ -77,4 +67,35 @@ defmodule ElixirScript.Translate.Forms.JS do {ast, state} end + + def compile({{:., _, [ElixirScript.JS, :mutate]}, _, [object, map]}, state) do + ast = J.call_expression( + J.member_expression( + J.identifier("Object"), + J.identifier("assign") + ), + [ + Form.compile!(object, state), + Form.compile!(map, state) + ] + ) + + {ast, state} + end + + def compile({{:., _, [ElixirScript.JS, :mutate]}, _, [object, key, value]}, state) do + ast = J.assignment_expression( + :=, + J.member_expression( + Form.compile!(object, state), + Form.compile!(key, state), + true + ), + [ + Form.compile!(value, state) + ] + ) + + {ast, state} + end end diff --git a/test/passes/translate/forms/js_test.exs b/test/passes/translate/forms/js_test.exs index 635c1994..7afd866c 100644 --- a/test/passes/translate/forms/js_test.exs +++ b/test/passes/translate/forms/js_test.exs @@ -64,4 +64,55 @@ defmodule ElixirScript.Translate.Forms.JS.Test do [J.literal("react")] ) end + + test "mutate/2" do + properties = [{"a", 1}] + map_ast = {:%{}, [], properties} + + ast = {{:., [], [ElixirScript.JS, :mutate]}, [], [{:%{}, [], []}, map_ast]} + state = %{function: {:each, nil}, module: Enum, vars: %{:_ => 0, "entry" => 0, "enumerable" => 0, "fun" => 0}} + + {js_ast, _} = Form.compile(ast, state) + assert js_ast == J.call_expression( + J.member_expression( + J.identifier("Object"), + J.identifier("assign") + ), + [ + J.object_expression([]), + J.object_expression([ + J.property( + J.identifier("a"), + J.literal(1) + ) + ]) + ] + ) + end + + test "mutate/3" do + properties = [{"a", 1}] + map_ast = {:%{}, [], properties} + + ast = {{:., [], [ElixirScript.JS, :mutate]}, [], [map_ast, "a", 2]} + state = %{function: {:each, nil}, module: Enum, vars: %{:_ => 0, "entry" => 0, "enumerable" => 0, "fun" => 0}} + + {js_ast, _} = Form.compile(ast, state) + assert js_ast == J.assignment_expression( + :=, + J.member_expression( + J.object_expression([ + J.property( + J.identifier("a"), + J.literal(1) + ) + ]), + J.literal("a"), + true + ), + [ + J.literal(2) + ] + ) + end end From cf321a5743f54c779cbf698a017bd2a3ea1bf6a4 Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Sun, 16 Jul 2017 08:46:57 -0500 Subject: [PATCH 173/418] Update tailored. Add names to variables. --- lib/elixir_script/passes/translate/forms/pattern.ex | 2 +- .../passes/translate/forms/pattern/patterns.ex | 9 ++++++++- package.json | 6 ++++-- test/support/main.ex | 10 ---------- yarn.lock | 6 +++--- 5 files changed, 16 insertions(+), 17 deletions(-) diff --git a/lib/elixir_script/passes/translate/forms/pattern.ex b/lib/elixir_script/passes/translate/forms/pattern.ex index a721295b..3c87995c 100644 --- a/lib/elixir_script/passes/translate/forms/pattern.ex +++ b/lib/elixir_script/passes/translate/forms/pattern.ex @@ -203,7 +203,7 @@ defmodule ElixirScript.Translate.Forms.Pattern do end defp process_pattern({var, _, _}, _) do - { [PM.parameter()], [ElixirScript.Translate.Identifier.make_identifier(var)] } + { [PM.parameter(J.literal(to_string(var)))], [ElixirScript.Translate.Identifier.make_identifier(var)] } end defp reduce_patterns(patterns, _) do diff --git a/lib/elixir_script/passes/translate/forms/pattern/patterns.ex b/lib/elixir_script/passes/translate/forms/pattern/patterns.ex index 21f313f5..8b9f4e54 100644 --- a/lib/elixir_script/passes/translate/forms/pattern/patterns.ex +++ b/lib/elixir_script/passes/translate/forms/pattern/patterns.ex @@ -53,6 +53,13 @@ defmodule ElixirScript.Translate.Forms.Pattern.Patterns do ) end + def parameter(name) do + J.call_expression( + @parameter, + [name] + ) + end + def head_tail(headParameter, tailParameter) do J.call_expression( @head_tail, @@ -94,4 +101,4 @@ defmodule ElixirScript.Translate.Forms.Pattern.Patterns do values ) end -end \ No newline at end of file +end diff --git a/package.json b/package.json index 882c88a0..d7d2c1a3 100644 --- a/package.json +++ b/package.json @@ -23,7 +23,7 @@ "license": "MIT", "dependencies": { "erlang-types": "^1.0.1", - "tailored": "^2.4.9" + "tailored": "^2.5.0" }, "devDependencies": { "ava": "^0.19.1", @@ -41,7 +41,9 @@ "sinon": "^1.17.7" }, "ava": { - "require": ["babel-register"], + "require": [ + "babel-register" + ], "babel": { "babelrc": true } diff --git a/test/support/main.ex b/test/support/main.ex index 94946a83..a18d3d90 100644 --- a/test/support/main.ex +++ b/test/support/main.ex @@ -1,15 +1,5 @@ defmodule Main do def start(:normal, [callback]) do callback.("started") - - opts = %{width: 10, height: 15} - with {:ok, width} <- Map.fetch(opts, :width), - {:ok, height} <- Map.fetch(opts, :height) - do - {:ok, width * height} - else - :error -> - {:error, :wrong_data} - end end end diff --git a/yarn.lock b/yarn.lock index 241ad9e7..1d33ab2c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3771,9 +3771,9 @@ table@^3.7.8: slice-ansi "0.0.4" string-width "^2.0.0" -tailored@^2.4.9: - version "2.4.9" - resolved "https://registry.yarnpkg.com/tailored/-/tailored-2.4.9.tgz#b06ea7e8eab054860062b076e7e1d0e33e0fa983" +tailored@^2.5.0: + version "2.5.0" + resolved "https://registry.yarnpkg.com/tailored/-/tailored-2.5.0.tgz#55055ea25e018951ecfc9adf39177f178fcde63e" dependencies: erlang-types "^1.0.0" From ca8c7ed212d55bf0099fafd6ac5c1f342ee19b96 Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Sun, 16 Jul 2017 10:56:05 -0500 Subject: [PATCH 174/418] Rename Bootstrap to ElixirScript --- README.md | 4 ++-- lib/elixir_script/lib/agent.ex | 18 ++++++++--------- lib/elixir_script/lib/store.ex | 4 ++-- lib/elixir_script/module_systems/namespace.ex | 4 ++-- lib/elixir_script/passes/output.ex | 4 ++-- lib/elixir_script/passes/translate/clause.ex | 2 +- lib/elixir_script/passes/translate/form.ex | 4 ++-- .../passes/translate/forms/bitstring.ex | 4 ++-- .../passes/translate/forms/for.ex | 8 ++++---- .../passes/translate/forms/js.ex | 2 +- .../passes/translate/forms/match.ex | 6 +++--- .../passes/translate/forms/pattern.ex | 2 +- .../translate/forms/pattern/patterns.ex | 2 +- .../passes/translate/forms/receive.ex | 2 +- .../passes/translate/forms/remote.ex | 6 +++--- .../passes/translate/forms/try.ex | 2 +- .../passes/translate/forms/with.ex | 2 +- .../passes/translate/function.ex | 4 ++-- .../passes/translate/protocol.ex | 20 +++++++++---------- rollup.config.js | 4 ++-- test/passes/translate/form_test.exs | 4 ++-- test/passes/translate/forms/receive_test.exs | 4 ++-- 22 files changed, 56 insertions(+), 56 deletions(-) diff --git a/README.md b/README.md index 5f78b35d..40bb0e11 100644 --- a/README.md +++ b/README.md @@ -24,8 +24,8 @@ git clone git@github.com:bryanjos/elixirscript.git #Get dependencies mix deps.get yarn - -# Create Elixir.Bootstrap.js + +# Create ElixirScript.Core.js yarn build # Compile diff --git a/lib/elixir_script/lib/agent.ex b/lib/elixir_script/lib/agent.ex index cb444941..4048350f 100644 --- a/lib/elixir_script/lib/agent.ex +++ b/lib/elixir_script/lib/agent.ex @@ -8,7 +8,7 @@ defmodule ElixirScript.Agent do nil end - pid = Bootstrap.Core.Store.create(fun.(), name) + pid = ElixirScript.Core.Store.create(fun.(), name) { :ok, pid } end @@ -19,31 +19,31 @@ defmodule ElixirScript.Agent do nil end - pid = Bootstrap.Core.Store.create(fun.(), name) + pid = ElixirScript.Core.Store.create(fun.(), name) { :ok, pid } end def stop(agent) do - Bootstrap.Core.Store.remove(agent) + ElixirScript.Core.Store.remove(agent) :ok end def update(agent, fun) do - current_state = Bootstrap.Core.Store.read(agent) - Bootstrap.Core.Store.update(agent, fun.(current_state)) + current_state = ElixirScript.Core.Store.read(agent) + ElixirScript.Core.Store.update(agent, fun.(current_state)) :ok end def get(agent, fun) do - current_state = Bootstrap.Core.Store.read(agent) + current_state = ElixirScript.Core.Store.read(agent) fun.(current_state) end def get_and_update(agent, fun) do - current_state = Bootstrap.Core.Store.read(agent) + current_state = ElixirScript.Core.Store.read(agent) {val, new_state} = fun.(current_state) - Bootstrap.Core.Store.update(agent, new_state) + ElixirScript.Core.Store.update(agent, new_state) val end -end \ No newline at end of file +end diff --git a/lib/elixir_script/lib/store.ex b/lib/elixir_script/lib/store.ex index 14447d9d..5c2efa23 100644 --- a/lib/elixir_script/lib/store.ex +++ b/lib/elixir_script/lib/store.ex @@ -1,4 +1,4 @@ -defmodule Bootstrap.Core.Store do +defmodule ElixirScript.Core.Store do @moduledoc false use ElixirScript.FFI, global: true @@ -9,4 +9,4 @@ defmodule Bootstrap.Core.Store do foreign read(key) foreign remove(key) -end \ No newline at end of file +end diff --git a/lib/elixir_script/module_systems/namespace.ex b/lib/elixir_script/module_systems/namespace.ex index 08e7aa4b..8af407ac 100644 --- a/lib/elixir_script/module_systems/namespace.ex +++ b/lib/elixir_script/module_systems/namespace.ex @@ -14,7 +14,7 @@ defmodule ElixirScript.ModuleSystems.Namespace do defp build_namespace() do JS.member_expression( - JS.identifier("Bootstrap"), + JS.identifier("ElixirScript"), JS.member_expression( JS.identifier(:Core), JS.member_expression( @@ -71,4 +71,4 @@ defmodule ElixirScript.ModuleSystems.Namespace do func ) end -end \ No newline at end of file +end diff --git a/lib/elixir_script/passes/output.ex b/lib/elixir_script/passes/output.ex index 7b6575b1..2042e718 100644 --- a/lib/elixir_script/passes/output.ex +++ b/lib/elixir_script/passes/output.ex @@ -50,7 +50,7 @@ defmodule ElixirScript.Output do defp get_bootstrap_js() do operating_path = Path.join([Mix.Project.build_path, "lib", "elixir_script", "priv"]) - path = Path.join([operating_path, "build", "iife", "Elixir.Bootstrap.js"]) + path = Path.join([operating_path, "build", "iife", "ElixirScript.Core.js"]) File.read!(path) end @@ -120,4 +120,4 @@ defmodule ElixirScript.Output do end end) end -end \ No newline at end of file +end diff --git a/lib/elixir_script/passes/translate/clause.ex b/lib/elixir_script/passes/translate/clause.ex index 79512ab0..3cebc738 100644 --- a/lib/elixir_script/passes/translate/clause.ex +++ b/lib/elixir_script/passes/translate/clause.ex @@ -9,7 +9,7 @@ defmodule ElixirScript.Translate.Clause do @patterns J.member_expression( J.member_expression( - J.identifier("Bootstrap"), + J.identifier("ElixirScript"), J.identifier("Core") ), J.identifier("Patterns") diff --git a/lib/elixir_script/passes/translate/form.ex b/lib/elixir_script/passes/translate/form.ex index 5c843e5d..c6e1ab2e 100644 --- a/lib/elixir_script/passes/translate/form.ex +++ b/lib/elixir_script/passes/translate/form.ex @@ -66,7 +66,7 @@ defmodule ElixirScript.Translate.Form do ast = J.new_expression( J.member_expression( J.member_expression( - J.identifier("Bootstrap"), + J.identifier("ElixirScript"), J.identifier("Core") ), J.identifier("Tuple") @@ -173,7 +173,7 @@ defmodule ElixirScript.Translate.Form do cond_function = J.member_expression( J.member_expression( - J.identifier("Bootstrap"), + J.identifier("ElixirScript"), J.member_expression( J.identifier("Core"), J.identifier("SpecialForms") diff --git a/lib/elixir_script/passes/translate/forms/bitstring.ex b/lib/elixir_script/passes/translate/forms/bitstring.ex index 3a2a1d5c..0db3e2ef 100644 --- a/lib/elixir_script/passes/translate/forms/bitstring.ex +++ b/lib/elixir_script/passes/translate/forms/bitstring.ex @@ -8,7 +8,7 @@ defmodule ElixirScript.Translate.Forms.Bitstring do js_ast = JS.new_expression( JS.member_expression( JS.member_expression( - JS.identifier("Bootstrap"), + JS.identifier("ElixirScript"), JS.identifier("Core") ), JS.identifier("BitString") @@ -88,7 +88,7 @@ defmodule ElixirScript.Translate.Forms.Bitstring do defp bitstring_class() do JS.member_expression( JS.member_expression( - JS.identifier("Bootstrap"), + JS.identifier("ElixirScript"), JS.identifier("Core") ), JS.identifier("BitString") diff --git a/lib/elixir_script/passes/translate/forms/for.ex b/lib/elixir_script/passes/translate/forms/for.ex index a04733cd..c7f84ce3 100644 --- a/lib/elixir_script/passes/translate/forms/for.ex +++ b/lib/elixir_script/passes/translate/forms/for.ex @@ -19,7 +19,7 @@ defmodule ElixirScript.Translate.Forms.For do JS.member_expression( JS.member_expression( JS.member_expression( - JS.identifier("Bootstrap"), + JS.identifier("ElixirScript"), JS.identifier("Core") ), JS.identifier("Patterns") @@ -37,7 +37,7 @@ defmodule ElixirScript.Translate.Forms.For do ast = JS.call_expression( JS.member_expression( JS.member_expression( - JS.identifier("Bootstrap"), + JS.identifier("ElixirScript"), JS.member_expression( JS.identifier("Core"), JS.identifier("SpecialForms") @@ -72,7 +72,7 @@ defmodule ElixirScript.Translate.Forms.For do JS.member_expression( JS.member_expression( JS.member_expression( - JS.identifier("Bootstrap"), + JS.identifier("ElixirScript"), JS.identifier("Core") ), JS.identifier("Patterns") @@ -91,7 +91,7 @@ defmodule ElixirScript.Translate.Forms.For do JS.member_expression( JS.member_expression( JS.member_expression( - JS.identifier("Bootstrap"), + JS.identifier("ElixirScript"), JS.identifier("Core") ), JS.identifier("Patterns") diff --git a/lib/elixir_script/passes/translate/forms/js.ex b/lib/elixir_script/passes/translate/forms/js.ex index c33f121e..b4c7c614 100644 --- a/lib/elixir_script/passes/translate/forms/js.ex +++ b/lib/elixir_script/passes/translate/forms/js.ex @@ -6,7 +6,7 @@ defmodule ElixirScript.Translate.Forms.JS do def call_property() do J.member_expression( J.member_expression( - J.identifier("Bootstrap"), + J.identifier("ElixirScript"), J.member_expression( J.identifier("Core"), J.identifier("Functions") diff --git a/lib/elixir_script/passes/translate/forms/match.ex b/lib/elixir_script/passes/translate/forms/match.ex index 1f31bf75..aeaac2ee 100644 --- a/lib/elixir_script/passes/translate/forms/match.ex +++ b/lib/elixir_script/passes/translate/forms/match.ex @@ -23,7 +23,7 @@ defmodule ElixirScript.Translate.Forms.Match do J.member_expression( J.member_expression( J.member_expression( - J.identifier("Bootstrap"), + J.identifier("ElixirScript"), J.identifier("Core") ), J.identifier("Patterns") @@ -72,7 +72,7 @@ defmodule ElixirScript.Translate.Forms.Match do ref, J.new_expression( J.member_expression( - J.identifier("Bootstrap"), + J.identifier("ElixirScript"), J.member_expression( J.identifier("Core"), J.identifier("Tuple") @@ -102,4 +102,4 @@ defmodule ElixirScript.Translate.Forms.Match do [array_pattern, ref_declaration] end -end \ No newline at end of file +end diff --git a/lib/elixir_script/passes/translate/forms/pattern.ex b/lib/elixir_script/passes/translate/forms/pattern.ex index 3c87995c..d52407dc 100644 --- a/lib/elixir_script/passes/translate/forms/pattern.ex +++ b/lib/elixir_script/passes/translate/forms/pattern.ex @@ -83,7 +83,7 @@ defmodule ElixirScript.Translate.Forms.Pattern do tuple = J.member_expression( J.member_expression( - J.identifier("Bootstrap"), + J.identifier("ElixirScript"), J.identifier("Core") ), J.identifier("Tuple") diff --git a/lib/elixir_script/passes/translate/forms/pattern/patterns.ex b/lib/elixir_script/passes/translate/forms/pattern/patterns.ex index 8b9f4e54..0aef2d3f 100644 --- a/lib/elixir_script/passes/translate/forms/pattern/patterns.ex +++ b/lib/elixir_script/passes/translate/forms/pattern/patterns.ex @@ -5,7 +5,7 @@ defmodule ElixirScript.Translate.Forms.Pattern.Patterns do @patterns J.member_expression( J.member_expression( - J.identifier("Bootstrap"), + J.identifier("ElixirScript"), J.identifier("Core") ), J.identifier("Patterns") diff --git a/lib/elixir_script/passes/translate/forms/receive.ex b/lib/elixir_script/passes/translate/forms/receive.ex index a23897e5..c097ffeb 100644 --- a/lib/elixir_script/passes/translate/forms/receive.ex +++ b/lib/elixir_script/passes/translate/forms/receive.ex @@ -12,7 +12,7 @@ defmodule ElixirScript.Translate.Forms.Receive do receive_function = J.member_expression( J.member_expression( - J.identifier("Bootstrap"), + J.identifier("ElixirScript"), J.member_expression( J.identifier("Core"), J.identifier("SpecialForms") diff --git a/lib/elixir_script/passes/translate/forms/remote.ex b/lib/elixir_script/passes/translate/forms/remote.ex index c09a065d..622fc3c0 100644 --- a/lib/elixir_script/passes/translate/forms/remote.ex +++ b/lib/elixir_script/passes/translate/forms/remote.ex @@ -110,7 +110,7 @@ defmodule ElixirScript.Translate.Forms.Remote do ast = J.member_expression( J.member_expression( J.member_expression( - J.identifier("Bootstrap"), + J.identifier("ElixirScript"), J.identifier("Core") ), J.identifier(module) @@ -177,7 +177,7 @@ defmodule ElixirScript.Translate.Forms.Remote do J.member_expression( J.member_expression( J.member_expression( - J.identifier("Bootstrap"), + J.identifier("ElixirScript"), J.identifier("Core") ), J.identifier(module) @@ -185,4 +185,4 @@ defmodule ElixirScript.Translate.Forms.Remote do ElixirScript.Translate.Identifier.make_function_name(function) ) end -end \ No newline at end of file +end diff --git a/lib/elixir_script/passes/translate/forms/try.ex b/lib/elixir_script/passes/translate/forms/try.ex index 0df1df1f..1d6f0754 100644 --- a/lib/elixir_script/passes/translate/forms/try.ex +++ b/lib/elixir_script/passes/translate/forms/try.ex @@ -42,7 +42,7 @@ defmodule ElixirScript.Translate.Forms.Try do js_ast = JS.call_expression( JS.member_expression( JS.member_expression( - JS.identifier("Bootstrap"), + JS.identifier("ElixirScript"), JS.member_expression( JS.identifier("Core"), JS.identifier("SpecialForms") diff --git a/lib/elixir_script/passes/translate/forms/with.ex b/lib/elixir_script/passes/translate/forms/with.ex index ad78ce22..73fe466d 100644 --- a/lib/elixir_script/passes/translate/forms/with.ex +++ b/lib/elixir_script/passes/translate/forms/with.ex @@ -36,7 +36,7 @@ defmodule ElixirScript.Translate.Forms.With do js_ast = JS.call_expression( JS.member_expression( JS.member_expression( - JS.identifier("Bootstrap"), + JS.identifier("ElixirScript"), JS.member_expression( JS.identifier("Core"), JS.identifier("SpecialForms") diff --git a/lib/elixir_script/passes/translate/function.ex b/lib/elixir_script/passes/translate/function.ex index ecd353cf..fe67824c 100644 --- a/lib/elixir_script/passes/translate/function.ex +++ b/lib/elixir_script/passes/translate/function.ex @@ -11,7 +11,7 @@ defmodule ElixirScript.Translate.Function do def patterns_ast() do J.member_expression( J.member_expression( - J.identifier("Bootstrap"), + J.identifier("ElixirScript"), J.identifier("Core") ), J.identifier("Patterns") @@ -168,4 +168,4 @@ defmodule ElixirScript.Translate.Function do {ast, state} end -end \ No newline at end of file +end diff --git a/lib/elixir_script/passes/translate/protocol.ex b/lib/elixir_script/passes/translate/protocol.ex index d487a391..e6c1747b 100644 --- a/lib/elixir_script/passes/translate/protocol.ex +++ b/lib/elixir_script/passes/translate/protocol.ex @@ -19,7 +19,7 @@ defmodule ElixirScript.Translate.Protocol do J.identifier("protocol"), J.call_expression( J.member_expression( - J.identifier("Bootstrap"), + J.identifier("ElixirScript"), J.member_expression( J.identifier(:Core), J.member_expression( @@ -58,7 +58,7 @@ defmodule ElixirScript.Translate.Protocol do J.call_expression( J.member_expression( - J.identifier("Bootstrap"), + J.identifier("ElixirScript"), J.member_expression( J.identifier(:Core), J.member_expression( @@ -79,7 +79,7 @@ defmodule ElixirScript.Translate.Protocol do defp map_to_js(Integer) do J.member_expression( J.member_expression( - J.identifier("Bootstrap"), + J.identifier("ElixirScript"), J.identifier(:Core) ), J.identifier(:Integer) @@ -89,7 +89,7 @@ defmodule ElixirScript.Translate.Protocol do defp map_to_js(Tuple) do J.member_expression( J.member_expression( - J.identifier("Bootstrap"), + J.identifier("ElixirScript"), J.identifier(:Core) ), J.identifier(:Tuple) @@ -107,7 +107,7 @@ defmodule ElixirScript.Translate.Protocol do defp map_to_js(BitString) do J.member_expression( J.member_expression( - J.identifier("Bootstrap"), + J.identifier("ElixirScript"), J.identifier(:Core) ), J.identifier(:BitString) @@ -117,7 +117,7 @@ defmodule ElixirScript.Translate.Protocol do defp map_to_js(Float) do J.member_expression( J.member_expression( - J.identifier("Bootstrap"), + J.identifier("ElixirScript"), J.identifier(:Core) ), J.identifier(:Float) @@ -131,7 +131,7 @@ defmodule ElixirScript.Translate.Protocol do defp map_to_js(PID) do J.member_expression( J.member_expression( - J.identifier("Bootstrap"), + J.identifier("ElixirScript"), J.identifier(:Core) ), J.identifier(:PID) @@ -140,14 +140,14 @@ defmodule ElixirScript.Translate.Protocol do defp map_to_js(Port) do J.member_expression( - J.identifier("Bootstrap"), + J.identifier("ElixirScript"), J.identifier(:Port) ) end defp map_to_js(Reference) do J.member_expression( - J.identifier("Bootstrap"), + J.identifier("ElixirScript"), J.identifier(:Reference) ) end @@ -174,4 +174,4 @@ defmodule ElixirScript.Translate.Protocol do ) end end -end \ No newline at end of file +end diff --git a/rollup.config.js b/rollup.config.js index a69d9169..b175860a 100644 --- a/rollup.config.js +++ b/rollup.config.js @@ -4,7 +4,7 @@ import babili from 'rollup-plugin-babili'; export default { entry: 'src/javascript/elixir.js', - moduleName: 'Bootstrap', + moduleName: 'ElixirScript', plugins: [ nodeResolve({ jsnext: true }), babel({ @@ -15,5 +15,5 @@ export default { keepClassName: true }) ], - targets: [{ dest: 'priv/build/iife/Elixir.Bootstrap.js', format: 'iife' }] + targets: [{ dest: 'priv/build/iife/ElixirScript.Core.js', format: 'iife' }] }; diff --git a/test/passes/translate/form_test.exs b/test/passes/translate/form_test.exs index f7106473..0e5a353f 100644 --- a/test/passes/translate/form_test.exs +++ b/test/passes/translate/form_test.exs @@ -79,7 +79,7 @@ defmodule ElixirScript.Translate.Forms.Test do assert js_ast == J.new_expression( J.member_expression( J.member_expression( - J.identifier("Bootstrap"), + J.identifier("ElixirScript"), J.identifier("Core") ), J.identifier("Tuple") @@ -131,4 +131,4 @@ defmodule ElixirScript.Translate.Forms.Test do J.literal(3) ]) end -end \ No newline at end of file +end diff --git a/test/passes/translate/forms/receive_test.exs b/test/passes/translate/forms/receive_test.exs index 32d55f67..5d3d1509 100644 --- a/test/passes/translate/forms/receive_test.exs +++ b/test/passes/translate/forms/receive_test.exs @@ -11,7 +11,7 @@ defmodule ElixirScript.Translate.Forms.Receive.Test do assert js_ast == J.call_expression( J.member_expression( J.member_expression( - J.identifier("Bootstrap"), + J.identifier("ElixirScript"), J.member_expression( J.identifier("Core"), J.identifier("SpecialForms") @@ -23,4 +23,4 @@ defmodule ElixirScript.Translate.Forms.Receive.Test do ) end -end \ No newline at end of file +end From 6ba4ec77db3ee6c3c5236537224cd09820850ef0 Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Sun, 16 Jul 2017 11:07:45 -0500 Subject: [PATCH 175/418] Remove warnings for FFI modules by adding underscore to args --- lib/elixir_script/ffi.ex | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/lib/elixir_script/ffi.ex b/lib/elixir_script/ffi.ex index abffc29b..3ee1ea94 100644 --- a/lib/elixir_script/ffi.ex +++ b/lib/elixir_script/ffi.ex @@ -53,8 +53,21 @@ defmodule ElixirScript.FFI do ``` """ defmacro foreign({name, _, args}) do + args = Enum.map(args, fn + {:\\, meta0, [{name, meta, atom}, value]}-> + name = String.to_atom("_" <> Atom.to_string(name)) + {:\\, meta0, [{name, meta, atom}, value]} + + {name, meta, atom} -> + name = String.to_atom("_" <> Atom.to_string(name)) + {name, meta, atom} + + other -> + other + end) + quote do def unquote(name)(unquote_splicing(args)), do: nil end end -end \ No newline at end of file +end From f3170b43b209f1ce7a18e5ad77f1f3e0a12d3d11 Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Sun, 16 Jul 2017 16:17:53 -0500 Subject: [PATCH 176/418] Checking in built js file to use in examples --- .gitignore | 1 - priv/build/iife/ElixirScript.Core.js | 6 ++++++ src/javascript/lib/core/store.js | 8 ++++---- 3 files changed, 10 insertions(+), 5 deletions(-) create mode 100644 priv/build/iife/ElixirScript.Core.js diff --git a/.gitignore b/.gitignore index ee4d5234..ba8707b5 100644 --- a/.gitignore +++ b/.gitignore @@ -16,7 +16,6 @@ index.js .tern-port test/std_lib_compile_test.exs src/elixirscript -priv/**/*.js stdlib_state.bin *.log .nyc_output diff --git a/priv/build/iife/ElixirScript.Core.js b/priv/build/iife/ElixirScript.Core.js new file mode 100644 index 00000000..42ff134f --- /dev/null +++ b/priv/build/iife/ElixirScript.Core.js @@ -0,0 +1,6 @@ +var _NumberisInteger=Number.isInteger,_StringfromCharCode=String.fromCharCode,ElixirScript=function(){'use strict';/* @flow */function namedVariableResult(E,F){return new NamedVariableResult(E,F)}/* @flow */function is_number(E){return'number'==typeof E}function is_string(E){return'string'==typeof E}function is_boolean(E){return'boolean'==typeof E}function is_symbol(E){return'symbol'==typeof E}function is_object(E){return'object'==typeof E}function is_variable(E){return E instanceof Variable}function is_null(E){return null===E}function is_array(E){return Array.isArray(E)}function is_function(E){return'[object Function]'==Object.prototype.toString.call(E)}function resolveNull(){return function(F){return is_null(F)}}function resolveWildcard(){return function(){return!0}}function resolveObject(E){let F={};const G=Object.keys(E).concat(Object.getOwnPropertySymbols(E));for(let H of G)F[H]=buildMatch(E[H]);return function(H,I){if(!is_object(H)||E.length>H.length)return!1;for(let J of G)if(!(J in H)||!F[J](H[J],I))return!1;return!0}}function getSize(E,F){return E*F/8}function arraysEqual(E,F){if(E===F)return!0;if(null==E||null==F)return!1;if(E.length!=F.length)return!1;for(var G=0;Gh.integer(G));return new h(...F)}function resolveNoMatch(){return function(){return!1}}function buildMatch(E){if(null===E)return resolveNull(E);if('undefined'==typeof E)return resolveWildcard(E);const F=E.constructor.prototype,G=k.get(F);return G?G(E):'object'==typeof E?resolveObject(E):resolveNoMatch()}function defmatchgen(...E){const F=getArityMap(E);return function*(...G){let[H,I]=findMatchingFunction(G,F);return yield*H.apply(this,I)}}function findMatchingFunction(E,F){if(F.has(E.length)){const G=F.get(E.length);let H=null,I=null;for(let J of G){let K=[];E=fillInOptionalValues(E,J.arity,J.optionals);const L=J.pattern(E,K),[M,N]=checkNamedVariables(K);if(L&&N&&J.guard.apply(this,M)){H=J.fn,I=M;break}}if(!H)throw console.error('No match for:',E),new MatchError(E);return[H,I]}throw console.error('Arity of',E.length,'not found. No match for:',E),new MatchError(E)}function getArityMap(E){let F=new Map;for(const G of E){const H=getArityRange(G);for(const I of H){let J=[];F.has(I)&&(J=F.get(I)),J.push(G),F.set(I,J)}}return F}function getArityRange(E){const F=E.arity-E.optionals.length,G=E.arity;let H=[F];for(;H[H.length-1]!=G;)H.push(H[H.length-1]+1);return H}function getOptionalValues(E){let F=[];for(let G=0;G!0,H=null){let I=[],J=buildMatch(E);const K=J(F,I),[L,M]=checkNamedVariables(I);return K&&M&&G.apply(this,L)?L:H}function run_generators(E,F){if(0==F.length)return E.map((G)=>{return Array.isArray(G)?G:[G]});const G=F.pop();let H=[];for(let I of G())for(let J of E)H.push([I].concat(J));return run_generators(H,F)}function iterator_to_reducer(E,F,G){const H=E[Symbol.iterator]();let I=H.next(),J=F;for(;!1===I.done;){if(J=G(I.value,J.get(1)),J.get(0)===Symbol.for('halt'))return new C.Tuple(Symbol.for('halted'),J.get(1));if(J.get(0)===Symbol.for('suspend'))return new C.Tuple(Symbol.for('suspended'),J.get(1),(K)=>{return iterator_to_reducer(H,K,G)});I=H.next()}return new C.Tuple(Symbol.for('done'),J.get(1))}function run_list_generators(E,F){if(0==F.length)return E.map((I)=>{return Array.isArray(I)?I:[I]});const G=F.pop(),H=[];for(const I of G())for(const J of E)H.push([I].concat(J));return run_list_generators(H,F)}// http://erlang.org/doc/man/erlang.html +function atom_to_binary(E,F=Symbol.for('utf8')){if(F!==Symbol.for('utf8'))throw new Error(`unsupported encoding ${F}`);return E.__MODULE__?Symbol.keyFor(E.__MODULE__):Symbol.keyFor(E)}function binary_to_atom(E,F=Symbol.for('utf8')){if(F!==Symbol.for('utf8'))throw new Error(`unsupported encoding ${F}`);return Symbol.for(E)}function is_number$1(E){return'number'==typeof E||E instanceof Number}function to_list(E){if(!1===q.is_map(E))return new g.Tuple(u,E);const F=[];for(const G of keys(E))F.push(new g.Tuple(G,E[G]));return F}function keys(E){if(!1===q.is_map(E))return new g.Tuple(u,E);const F=[];for(const G of Object.getOwnPropertySymbols(E))F.push(G);for(const G of Object.getOwnPropertyNames(E))F.push(G);return F}function is_key(E,F){return F.hasOwnProperty(E)}// http://erlang.org/doc/man/lists.html +function reverse(E){return[...E].reverse()}function flatten(E,F=[]){const G=E.reduce((H,I)=>{return Array.isArray(I)?H.concat(flatten(I)):H.concat(I)},[]);return G.concat(F)}function foldl(E,F,G){return G.reduce((H,I)=>{return E(I,H)},F)}function keyfind(E,F,G){for(const H of G)if(H.get(F-1)===E)return H;return!1}function keydelete(E,F,G){const H=[];let I=!1;for(let J=0;JBitString$1.integer(I));return new BitString$1(...H)}[Symbol.iterator](){return this.value[Symbol.iterator]()}toString(){var E,F='';for(E=0;E>'}process(E){let F=[];var G;for(G=0;GH?F.push(H):2048>H?F.push(192|H>>6,128|63&H):55296>H||57344<=H?F.push(224|H>>12,128|63&H>>6,128|63&H):(G++,H=65536+((1023&H)<<10|1023&E.charCodeAt(G)),F.push(240|H>>18,128|63&H>>12,128|63&H>>6,128|63&H));return F}static toUTF16Array(E){for(var H,F=[],G=0;G=H?(F.push(0),F.push(H)):(F.push(255&H>>8),F.push(255&H));return F}static toUTF32Array(E){for(var H,F=[],G=0;G=H?(F.push(0),F.push(0),F.push(0),F.push(H)):(F.push(0),F.push(0),F.push(255&H>>8),F.push(255&H));return F}//http://stackoverflow.com/questions/2003493/javascript-float-from-to-bits +static float32ToBytes(E){var F=[],G=new ArrayBuffer(4);new Float32Array(G)[0]=E;let H=new Uint32Array(G)[0];return F.push(255&H>>24),F.push(255&H>>16),F.push(255&H>>8),F.push(255&H),F}static float64ToBytes(E){var F=[],G=new ArrayBuffer(8);new Float64Array(G)[0]=E;var H=new Uint32Array(G)[0],I=new Uint32Array(G)[1];return F.push(255&I>>24),F.push(255&I>>16),F.push(255&I>>8),F.push(255&I),F.push(255&H>>24),F.push(255&H>>16),F.push(255&H>>8),F.push(255&H),F}}var g={Tuple,PID:class PID{constructor(){++c,this.id=c}toString(){return'PID#<0.'+this.id+'.0>'}},Reference:class Reference{constructor(){++d,this.id=d,this.ref=Symbol()}toString(){return'Ref#<0.0.0.'+this.id+'>'}},BitString:BitString$1};/* @flow */const h=g.BitString,k=new Map;k.set(Variable.prototype,function resolveVariable(E){return function(F,G){return null===E.name||E.name.startsWith('_')?G.push(F):G.push(namedVariableResult(E.name,F)),!0}}),k.set(Wildcard.prototype,resolveWildcard),k.set(HeadTail.prototype,function resolveHeadTail(){return function(E,F){if(!is_array(E)||2>E.length)return!1;const G=E[0],H=E.slice(1);return F.push(G),F.push(H),!0}}),k.set(StartsWith.prototype,function resolveStartsWith(E){const F=E.prefix;return function(G,H){return is_string(G)&&G.startsWith(F)&&(H.push(G.substring(F.length)),!0)}}),k.set(Capture.prototype,function resolveCapture(E){const F=buildMatch(E.value);return function(G,H){return!!F(G,H)&&(H.push(G),!0)}}),k.set(Bound.prototype,function resolveBound(E){return function(F){return typeof F==typeof E.value&&F===E.value}}),k.set(Type.prototype,function resolveType(E){return function(F,G){if(F instanceof E.type){const H=buildMatch(E.objPattern);return H(F,G)}return!1}}),k.set(BitStringMatch.prototype,function resolveBitString(E){let F=[];for(let H of E.values)if(is_variable(H.value)){let I=getSize(H.unit,H.size);fillArray(F,I)}else F=F.concat(new h(H).value);let G=E.values;return function(H,I){let J=null;if(!is_string(H)&&!(H instanceof h))return!1;J=is_string(H)?new h(h.binary(H)):H;let K=0;for(let M,L=0;LbuildMatch(G));return function(G,H){return is_array(G)&&G.length==E.length&&G.every(function(I,J){return F[J](G[J],H)})}}),k.set(String.prototype,function resolveString(E){return function(F){return is_string(F)&&F===E}}),k.set(Boolean.prototype,function resolveBoolean(E){return function(F){return is_boolean(F)&&F===E}}),k.set(Function.prototype,function resolveFunction(E){return function(F){return is_function(F)&&F===E}}),k.set(Object.prototype,resolveObject);class MatchError extends Error{constructor(E){if(super(),'symbol'==typeof E)this.message='No match for: '+E.toString();else if(Array.isArray(E)){let F=E.map((G)=>{return null===G?'null':'undefined'==typeof G?'undefined':G.toString()});this.message='No match for: '+F}else this.message='No match for: '+E;this.stack=new Error().stack,this.name=this.constructor.name}}class Clause{constructor(E,F,G=()=>!0){this.pattern=buildMatch(E),this.arity=E.length,this.optionals=getOptionalValues(E),this.fn=F,this.guard=G}}const l=Symbol();// https://github.com/airportyh/protomorphism +class Protocol{constructor(E){function createFun(F){return function(...G){const H=G[0];let I=null;if(null===H&&this.hasImplementation(Symbol('null'))?I=this.registry.get(Symbol)[F]:_NumberisInteger(H)&&this.hasImplementation(C.Integer)?I=this.registry.get(C.Integer)[F]:'number'==typeof H&&!_NumberisInteger(H)&&this.hasImplementation(C.Float)?I=this.registry.get(C.Float)[F]:'string'==typeof H&&this.hasImplementation(C.BitString)?I=this.registry.get(C.BitString)[F]:H&&H[Symbol.for('__struct__')]&&this.hasImplementation(H)?I=this.registry.get(H[Symbol.for('__struct__')].__MODULE__)[F]:null!==H&&this.hasImplementation(H)?I=this.registry.get(H.constructor)[F]:this.fallback&&(I=this.fallback[F]),null!=I){const J=I.apply(this,G);return J}throw new Error(`No implementation found for ${H}`)}}for(const F in this.registry=new Map,this.fallback=null,E)this[F]=createFun(F).bind(this)}implementation(E,F){null===E?this.fallback=F:this.registry.set(E,F)}hasImplementation(E){return E===C.Integer||E===C.Float||E===C.BitString?this.registry.has(E):E&&E[Symbol.for('__struct__')]?this.registry.has(E[Symbol.for('__struct__')].__MODULE__):this.registry.has(E.constructor)}}var q={atom_to_binary,binary_to_atom,binary_to_existing_atom:function binary_to_existing_atom(E,F=Symbol.for('utf8')){return binary_to_atom(E,F)},list_concatenation:function list_concatenation(E,F){return E.concat(F)},list_subtraction:function list_subtraction(E,F){const G=[...E];for(const H of F){const I=G.indexOf(H);-1F},greaterThanOrEqualTo:function greaterThanOrEqualTo(E,F){return E>=F},lessThan:function lessThan(E,F){return E>F},bxor:function bxor(E,F){return E^F},bnot:function bnot(E){return~E},is_bitstring:function is_bitstring$1(E){return E instanceof g.BitString},is_boolean:function is_boolean$1(E){return'boolean'==typeof E||E instanceof Boolean},is_float:function is_float(E){return is_number$1(E)&&!_NumberisInteger(E)},is_function:function is_function$1(E){return'function'==typeof E||E instanceof Function},is_integer:function is_integer(E){return _NumberisInteger(E)},is_list:function is_list(E){return Array.isArray(E)},is_map:function is_map(E){return'object'==typeof E||E instanceof Object},is_number:is_number$1,is_pid:function is_pid(E){return E instanceof g.PID},is_port:function is_port(){return!1},is_reference:function is_reference(E){return E instanceof g.Reference},is_tuple:function is_tuple(E){return E instanceof g.Tuple},is_atom:function is_atom(E){return'symbol'==typeof E||E instanceof Symbol||E.__MODULE__},is_binary:function is_binary(E){return'string'==typeof E||E instanceof String},element:function element(E,F){return F.get(E-1)},setelement:function setelement(E,F,G){const H=[...F.values];return H[E-1]=G,new g.Tuple(...H)},make_tuple:function make_tuple(E,F){const G=[];for(let H=0;H!0){let H=[],I=buildMatch(E);const J=I(F,H),[K,L]=checkNamedVariables(H);if(J&&L&&G.apply(this,K))return K;throw console.error('No match for:',F),new MatchError(F)},MatchError,variable:function variable(E=null,F=Symbol.for('tailored.no_value')){return new Variable(E,F)},wildcard:function wildcard(){return new Wildcard},startsWith:function startsWith(E){return new StartsWith(E)},capture:function capture(E){return new Capture(E)},headTail:function headTail(){return new HeadTail},type:function type(E,F={}){return new Type(E,F)},bound:function bound(E){return new Bound(E)},Clause,clause:function clause(E,F,G=()=>!0){return new Clause(E,F,G)},bitStringMatch:function bitStringMatch(...E){return new BitStringMatch(...E)},match_or_default,defmatchgen,list_comprehension:function list_comprehension(E,F){const G=run_generators(F.pop()(),F);let H=[];for(let I of G)E.guard.apply(this,I)&&H.push(E.fn.apply(this,I));return H},list_generator:function list_generator(E,F){return function(){let G=[];for(let H of F){const I=match_or_default(E,H,()=>!0,l);if(I!=l){const[J]=I;G.push(J)}}return G}},bitstring_generator:function bitstring_generator(E,F){return function(){let G=[],H=F.slice(0,E.byte_size()),I=1;for(;H.byte_size==E.byte_size();){const J=match_or_default(E,H,()=>!0,l);J!=l&&G.push(J),H=F.slice(E.byte_size()*I,E.byte_size()*(I+1)),I++}return G}},bitstring_comprehension:function bitstring_comprehension(E,F){const G=run_generators(F.pop()(),F);let H=[];for(let I of G)E.guard.apply(this,I)&&H.push(E.fn.apply(this,I));return H=H.map((I)=>g.BitString.integer(I)),new g.BitString(...H)},defmatchGen:function defmatchGen(...E){return defmatchgen(...E)},defmatchAsync:function defmatchAsync(...E){const F=getArityMap(E);return async function(...G){if(F.has(G.length)){const H=F.get(G.length);let I=null,J=null;for(let K of H){let L=[];G=fillInOptionalValues(G,K.arity,K.optionals);const M=K.pattern(G,L),[N,O]=checkNamedVariables(L);if(M&&O&&(await K.guard.apply(this,L))){I=K.fn,J=L;break}}if(!I)throw console.error('No match for:',G),new MatchError(G);return I.apply(this,J)}throw console.error('Arity of',G.length,'not found. No match for:',G),new MatchError(G)}}},Integer:class Integer{},Float:class Float{},Functions:{call_property:function call_property(E,F){if(!F)return E instanceof Function||'function'==typeof E?E():E;let G=null;if('number'==typeof E||'symbol'==typeof E||'boolean'==typeof E||'string'==typeof E?void 0===E[F]?void 0!==E[Symbol.for(F)]&&(G=Symbol.for(F)):G=F:F in E?G=F:Symbol.for(F)in E&&(G=Symbol.for(F)),null===G)throw new Error(`Property ${F} not found in ${E}`);return E[G]instanceof Function||'function'==typeof E[G]?E[G]():E[G]},defprotocol:function defprotocol(E){return new Protocol(E)},defimpl:function defimpl(E,F,G){E.implementation(F,G)},build_namespace:function build_namespace(E,F){let G=F.split('.');const H=E;let I=E;'Elixir'===G[0]&&(G=G.slice(1));for(const J of G)'undefined'==typeof I[J]&&(I[J]={}),I=I[J];return H.__table__=E.__table__||{},H.__table__[Symbol.for(F)]=I,I},iterator_to_reducer},SpecialForms:{_case:function _case(E,F){return C.Patterns.defmatch(...F)(E)},cond:function cond(...E){for(const F of E)if(F[0])return F[1]();throw new Error},_for:function _for(E,F,G,H=[]){let[I,J]=G.into(H);const K=run_list_generators(F.pop()(),F);for(const L of K)E.guard.apply(this,L)&&(I=J(I,new C.Tuple(Symbol.for('cont'),E.fn.apply(this,L))));return J(I,Symbol.for('done'))},_try:function _try(E,F,G,H,I){let J=null;try{J=E()}catch(K){let L=null;if(F)try{return L=F(K),L}catch(M){if(M instanceof C.Patterns.MatchError)throw M}if(G)try{return L=G(K),L}catch(M){if(M instanceof C.Patterns.MatchError)throw M}throw K}finally{I&&I()}if(H)try{return H(J)}catch(K){if(K instanceof C.Patterns.MatchError)throw new Error('No Match Found in Else');throw K}else return J},_with:function _with(...E){let F=[],G=null,H=null;'function'==typeof E[E.length-2]?[G,H]=E.splice(-2):G=E.pop();for(let I=0;I{const[H,I]=G;return F[H]=I,F},{})},keys,values:function values$1(E){if(!1===q.is_map(E))return new g.Tuple(u,E);const F=[];for(const G of keys(E))F.push(E[G]);return F},is_key,put:function put(E,F,G){if(!1===q.is_map(G))return new g.Tuple(u,G);const H=Object.assign({},G,{[E]:F});return H},merge:function merge(E,F){return!1===q.is_map(E)?new g.Tuple(u,E):!1===q.is_map(F)?new g.Tuple(u,F):Object.assign({},E,F)},update:function update(E,F,G){return!1===q.is_map(G)?new g.Tuple(u,G):!1===is_key(E,G)?new g.Tuple(w,E):Object.assign({},G,{[E]:F})},get:function get(...E){const F=E[0],G=E[1];return!1===q.is_map(G)?new g.Tuple(u,G):is_key(F)?G[F]:3===E.length?E[2]:new g.Tuple(w,F)},take:function take(E,F){if(!1===q.is_map(F))return new g.Tuple(u,F);if(!is_key(E))return t;const G=F[E],H=Object.assign({},F);return delete H[E],new g.Tuple(G,H)}},lists:{reverse,foreach:function foreach(E,F){return F.forEach((G)=>E(G)),Symbol.for('ok')},duplicate:function duplicate(E,F){const G=[];for(;G.length{return H.get(E-1)I.get(E-1)?1:0})},keystore:function keystore(E,F,G,H){const I=[...G];for(let J=0;JF.toString()).join()},map:function map(E,F){return F.map((G)=>E(G))},filter:function filter(E,F){return F.filter((G)=>E(G))},filtermap:function filtermap(E,F){const G=[];for(const H of F){const I=E(H);!0===I?G.push(H):I instanceof g.Tuple&&!0===I.get(0)&&G.push(I.get(1))}return G},member:function member(E,F){for(const G of F)if(G===E)return!0;return!1},all:function all(E,F){for(const G of F)if(!1===E(G))return!1;return!0},any:function any(E,F){for(const G of F)if(!0===E(G))return!0;return!1},splitwith:function splitwith(E,F){let G=!1;const H=[],I=[];for(const J of F)!0==G?I.push(J):!0===E(J)?H.push(J):(G=!0,I.push(J));return new g.Tuple(H,I)},sort:function sort(...E){if(1===E.length){const H=[...E[0]];return H.sort()}const F=E[0],G=[...E[1]];return G.sort((H,I)=>{const J=F(H,I);return!0===J?-1:1})}}};return{Core:C}}(); diff --git a/src/javascript/lib/core/store.js b/src/javascript/lib/core/store.js index f0ebc0ec..5dc364d8 100644 --- a/src/javascript/lib/core/store.js +++ b/src/javascript/lib/core/store.js @@ -21,22 +21,22 @@ function create(value, name = null) { __elixirscript_names__.set(name, key); } - __elixirscript_store__.set(key, value); + return __elixirscript_store__.set(key, value); } function update(key, value) { const real_key = get_key(key); - __elixirscript_store__.set(real_key, value); + return __elixirscript_store__.set(real_key, value); } function read(key) { const real_key = get_key(key); - __elixirscript_store__.get(real_key); + return __elixirscript_store__.get(real_key); } function remove(key) { const real_key = get_key(key); - __elixirscript_store__.delete(real_key); + return __elixirscript_store__.delete(real_key); } export default { From b3277f8c01f20e9c2c00557a55af8b08f10f3857 Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Sun, 16 Jul 2017 16:47:27 -0500 Subject: [PATCH 177/418] Update super implementation --- lib/elixir_script/passes/translate/form.ex | 2 +- test/passes/translate/form_test.exs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/elixir_script/passes/translate/form.ex b/lib/elixir_script/passes/translate/form.ex index c6e1ab2e..70e2af99 100644 --- a/lib/elixir_script/passes/translate/form.ex +++ b/lib/elixir_script/passes/translate/form.ex @@ -228,7 +228,7 @@ defmodule ElixirScript.Translate.Form do Remote.compile(ast, state) end - def compile({:super, _, params}, state) when is_list(params) do + def compile({:super, _, [_ | params]}, state) when is_list(params) do {function_name, _} = Map.get(state, :function) {var_decs, params} = compile_params(params, state) diff --git a/test/passes/translate/form_test.exs b/test/passes/translate/form_test.exs index 0e5a353f..ea154950 100644 --- a/test/passes/translate/form_test.exs +++ b/test/passes/translate/form_test.exs @@ -97,8 +97,8 @@ defmodule ElixirScript.Translate.Forms.Test do end test "super" do - ast = {:super, [], [1]} - state = %{function: {:my_function, nil}} + ast = {:super, [], [{:def, :my_function}, 1]} + state = %{function: {:my_function, nil}, vars: %{}} {js_ast, _} = Form.compile(ast, state) assert js_ast == J.call_expression( From c27de808312c47f2d425458165873c06abb41896 Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Mon, 17 Jul 2017 20:17:11 -0500 Subject: [PATCH 178/418] Update node dependencies --- package.json | 20 +- priv/build/iife/ElixirScript.Core.js | 12 +- yarn.lock | 1073 ++++++++++++-------------- 3 files changed, 516 insertions(+), 589 deletions(-) diff --git a/package.json b/package.json index d7d2c1a3..8e013597 100644 --- a/package.json +++ b/package.json @@ -23,22 +23,22 @@ "license": "MIT", "dependencies": { "erlang-types": "^1.0.1", - "tailored": "^2.5.0" + "tailored": "^2.6.0" }, "devDependencies": { - "ava": "^0.19.1", + "ava": "^0.21.0", "babel-core": "^6.24.0", - "babel-preset-env": "^1.3.2", + "babel-preset-env": "^1.6.0", "babel-register": "^6.24.0", - "eslint": "^3.15.0", + "eslint": "^4.2.0", "eslint-config-airbnb-base": "^11.1.0", - "eslint-plugin-import": "^2.2.0", - "nyc": "^10.3.2", - "rollup": "^0.41.6", + "eslint-plugin-import": "^2.7.0", + "nyc": "^11.0.3", + "rollup": "^0.45.2", "rollup-plugin-babel": "^2.7.1", - "rollup-plugin-babili": "^2.0.0", - "rollup-plugin-node-resolve": "^2.0.0", - "sinon": "^1.17.7" + "rollup-plugin-babili": "^3.1.0", + "rollup-plugin-node-resolve": "^3.0.0", + "sinon": "^2.3.8" }, "ava": { "require": [ diff --git a/priv/build/iife/ElixirScript.Core.js b/priv/build/iife/ElixirScript.Core.js index 42ff134f..a6c133c6 100644 --- a/priv/build/iife/ElixirScript.Core.js +++ b/priv/build/iife/ElixirScript.Core.js @@ -1,6 +1,6 @@ -var _NumberisInteger=Number.isInteger,_StringfromCharCode=String.fromCharCode,ElixirScript=function(){'use strict';/* @flow */function namedVariableResult(E,F){return new NamedVariableResult(E,F)}/* @flow */function is_number(E){return'number'==typeof E}function is_string(E){return'string'==typeof E}function is_boolean(E){return'boolean'==typeof E}function is_symbol(E){return'symbol'==typeof E}function is_object(E){return'object'==typeof E}function is_variable(E){return E instanceof Variable}function is_null(E){return null===E}function is_array(E){return Array.isArray(E)}function is_function(E){return'[object Function]'==Object.prototype.toString.call(E)}function resolveNull(){return function(F){return is_null(F)}}function resolveWildcard(){return function(){return!0}}function resolveObject(E){let F={};const G=Object.keys(E).concat(Object.getOwnPropertySymbols(E));for(let H of G)F[H]=buildMatch(E[H]);return function(H,I){if(!is_object(H)||E.length>H.length)return!1;for(let J of G)if(!(J in H)||!F[J](H[J],I))return!1;return!0}}function getSize(E,F){return E*F/8}function arraysEqual(E,F){if(E===F)return!0;if(null==E||null==F)return!1;if(E.length!=F.length)return!1;for(var G=0;Gh.integer(G));return new h(...F)}function resolveNoMatch(){return function(){return!1}}function buildMatch(E){if(null===E)return resolveNull(E);if('undefined'==typeof E)return resolveWildcard(E);const F=E.constructor.prototype,G=k.get(F);return G?G(E):'object'==typeof E?resolveObject(E):resolveNoMatch()}function defmatchgen(...E){const F=getArityMap(E);return function*(...G){let[H,I]=findMatchingFunction(G,F);return yield*H.apply(this,I)}}function findMatchingFunction(E,F){if(F.has(E.length)){const G=F.get(E.length);let H=null,I=null;for(let J of G){let K=[];E=fillInOptionalValues(E,J.arity,J.optionals);const L=J.pattern(E,K),[M,N]=checkNamedVariables(K);if(L&&N&&J.guard.apply(this,M)){H=J.fn,I=M;break}}if(!H)throw console.error('No match for:',E),new MatchError(E);return[H,I]}throw console.error('Arity of',E.length,'not found. No match for:',E),new MatchError(E)}function getArityMap(E){let F=new Map;for(const G of E){const H=getArityRange(G);for(const I of H){let J=[];F.has(I)&&(J=F.get(I)),J.push(G),F.set(I,J)}}return F}function getArityRange(E){const F=E.arity-E.optionals.length,G=E.arity;let H=[F];for(;H[H.length-1]!=G;)H.push(H[H.length-1]+1);return H}function getOptionalValues(E){let F=[];for(let G=0;G!0,H=null){let I=[],J=buildMatch(E);const K=J(F,I),[L,M]=checkNamedVariables(I);return K&&M&&G.apply(this,L)?L:H}function run_generators(E,F){if(0==F.length)return E.map((G)=>{return Array.isArray(G)?G:[G]});const G=F.pop();let H=[];for(let I of G())for(let J of E)H.push([I].concat(J));return run_generators(H,F)}function iterator_to_reducer(E,F,G){const H=E[Symbol.iterator]();let I=H.next(),J=F;for(;!1===I.done;){if(J=G(I.value,J.get(1)),J.get(0)===Symbol.for('halt'))return new C.Tuple(Symbol.for('halted'),J.get(1));if(J.get(0)===Symbol.for('suspend'))return new C.Tuple(Symbol.for('suspended'),J.get(1),(K)=>{return iterator_to_reducer(H,K,G)});I=H.next()}return new C.Tuple(Symbol.for('done'),J.get(1))}function run_list_generators(E,F){if(0==F.length)return E.map((I)=>{return Array.isArray(I)?I:[I]});const G=F.pop(),H=[];for(const I of G())for(const J of E)H.push([I].concat(J));return run_list_generators(H,F)}// http://erlang.org/doc/man/erlang.html -function atom_to_binary(E,F=Symbol.for('utf8')){if(F!==Symbol.for('utf8'))throw new Error(`unsupported encoding ${F}`);return E.__MODULE__?Symbol.keyFor(E.__MODULE__):Symbol.keyFor(E)}function binary_to_atom(E,F=Symbol.for('utf8')){if(F!==Symbol.for('utf8'))throw new Error(`unsupported encoding ${F}`);return Symbol.for(E)}function is_number$1(E){return'number'==typeof E||E instanceof Number}function to_list(E){if(!1===q.is_map(E))return new g.Tuple(u,E);const F=[];for(const G of keys(E))F.push(new g.Tuple(G,E[G]));return F}function keys(E){if(!1===q.is_map(E))return new g.Tuple(u,E);const F=[];for(const G of Object.getOwnPropertySymbols(E))F.push(G);for(const G of Object.getOwnPropertyNames(E))F.push(G);return F}function is_key(E,F){return F.hasOwnProperty(E)}// http://erlang.org/doc/man/lists.html -function reverse(E){return[...E].reverse()}function flatten(E,F=[]){const G=E.reduce((H,I)=>{return Array.isArray(I)?H.concat(flatten(I)):H.concat(I)},[]);return G.concat(F)}function foldl(E,F,G){return G.reduce((H,I)=>{return E(I,H)},F)}function keyfind(E,F,G){for(const H of G)if(H.get(F-1)===E)return H;return!1}function keydelete(E,F,G){const H=[];let I=!1;for(let J=0;JBitString$1.integer(I));return new BitString$1(...H)}[Symbol.iterator](){return this.value[Symbol.iterator]()}toString(){var E,F='';for(E=0;E>'}process(E){let F=[];var G;for(G=0;GH?F.push(H):2048>H?F.push(192|H>>6,128|63&H):55296>H||57344<=H?F.push(224|H>>12,128|63&H>>6,128|63&H):(G++,H=65536+((1023&H)<<10|1023&E.charCodeAt(G)),F.push(240|H>>18,128|63&H>>12,128|63&H>>6,128|63&H));return F}static toUTF16Array(E){for(var H,F=[],G=0;G=H?(F.push(0),F.push(H)):(F.push(255&H>>8),F.push(255&H));return F}static toUTF32Array(E){for(var H,F=[],G=0;G=H?(F.push(0),F.push(0),F.push(0),F.push(H)):(F.push(0),F.push(0),F.push(255&H>>8),F.push(255&H));return F}//http://stackoverflow.com/questions/2003493/javascript-float-from-to-bits -static float32ToBytes(E){var F=[],G=new ArrayBuffer(4);new Float32Array(G)[0]=E;let H=new Uint32Array(G)[0];return F.push(255&H>>24),F.push(255&H>>16),F.push(255&H>>8),F.push(255&H),F}static float64ToBytes(E){var F=[],G=new ArrayBuffer(8);new Float64Array(G)[0]=E;var H=new Uint32Array(G)[0],I=new Uint32Array(G)[1];return F.push(255&I>>24),F.push(255&I>>16),F.push(255&I>>8),F.push(255&I),F.push(255&H>>24),F.push(255&H>>16),F.push(255&H>>8),F.push(255&H),F}}var g={Tuple,PID:class PID{constructor(){++c,this.id=c}toString(){return'PID#<0.'+this.id+'.0>'}},Reference:class Reference{constructor(){++d,this.id=d,this.ref=Symbol()}toString(){return'Ref#<0.0.0.'+this.id+'>'}},BitString:BitString$1};/* @flow */const h=g.BitString,k=new Map;k.set(Variable.prototype,function resolveVariable(E){return function(F,G){return null===E.name||E.name.startsWith('_')?G.push(F):G.push(namedVariableResult(E.name,F)),!0}}),k.set(Wildcard.prototype,resolveWildcard),k.set(HeadTail.prototype,function resolveHeadTail(){return function(E,F){if(!is_array(E)||2>E.length)return!1;const G=E[0],H=E.slice(1);return F.push(G),F.push(H),!0}}),k.set(StartsWith.prototype,function resolveStartsWith(E){const F=E.prefix;return function(G,H){return is_string(G)&&G.startsWith(F)&&(H.push(G.substring(F.length)),!0)}}),k.set(Capture.prototype,function resolveCapture(E){const F=buildMatch(E.value);return function(G,H){return!!F(G,H)&&(H.push(G),!0)}}),k.set(Bound.prototype,function resolveBound(E){return function(F){return typeof F==typeof E.value&&F===E.value}}),k.set(Type.prototype,function resolveType(E){return function(F,G){if(F instanceof E.type){const H=buildMatch(E.objPattern);return H(F,G)}return!1}}),k.set(BitStringMatch.prototype,function resolveBitString(E){let F=[];for(let H of E.values)if(is_variable(H.value)){let I=getSize(H.unit,H.size);fillArray(F,I)}else F=F.concat(new h(H).value);let G=E.values;return function(H,I){let J=null;if(!is_string(H)&&!(H instanceof h))return!1;J=is_string(H)?new h(h.binary(H)):H;let K=0;for(let M,L=0;LbuildMatch(G));return function(G,H){return is_array(G)&&G.length==E.length&&G.every(function(I,J){return F[J](G[J],H)})}}),k.set(String.prototype,function resolveString(E){return function(F){return is_string(F)&&F===E}}),k.set(Boolean.prototype,function resolveBoolean(E){return function(F){return is_boolean(F)&&F===E}}),k.set(Function.prototype,function resolveFunction(E){return function(F){return is_function(F)&&F===E}}),k.set(Object.prototype,resolveObject);class MatchError extends Error{constructor(E){if(super(),'symbol'==typeof E)this.message='No match for: '+E.toString();else if(Array.isArray(E)){let F=E.map((G)=>{return null===G?'null':'undefined'==typeof G?'undefined':G.toString()});this.message='No match for: '+F}else this.message='No match for: '+E;this.stack=new Error().stack,this.name=this.constructor.name}}class Clause{constructor(E,F,G=()=>!0){this.pattern=buildMatch(E),this.arity=E.length,this.optionals=getOptionalValues(E),this.fn=F,this.guard=G}}const l=Symbol();// https://github.com/airportyh/protomorphism -class Protocol{constructor(E){function createFun(F){return function(...G){const H=G[0];let I=null;if(null===H&&this.hasImplementation(Symbol('null'))?I=this.registry.get(Symbol)[F]:_NumberisInteger(H)&&this.hasImplementation(C.Integer)?I=this.registry.get(C.Integer)[F]:'number'==typeof H&&!_NumberisInteger(H)&&this.hasImplementation(C.Float)?I=this.registry.get(C.Float)[F]:'string'==typeof H&&this.hasImplementation(C.BitString)?I=this.registry.get(C.BitString)[F]:H&&H[Symbol.for('__struct__')]&&this.hasImplementation(H)?I=this.registry.get(H[Symbol.for('__struct__')].__MODULE__)[F]:null!==H&&this.hasImplementation(H)?I=this.registry.get(H.constructor)[F]:this.fallback&&(I=this.fallback[F]),null!=I){const J=I.apply(this,G);return J}throw new Error(`No implementation found for ${H}`)}}for(const F in this.registry=new Map,this.fallback=null,E)this[F]=createFun(F).bind(this)}implementation(E,F){null===E?this.fallback=F:this.registry.set(E,F)}hasImplementation(E){return E===C.Integer||E===C.Float||E===C.BitString?this.registry.has(E):E&&E[Symbol.for('__struct__')]?this.registry.has(E[Symbol.for('__struct__')].__MODULE__):this.registry.has(E.constructor)}}var q={atom_to_binary,binary_to_atom,binary_to_existing_atom:function binary_to_existing_atom(E,F=Symbol.for('utf8')){return binary_to_atom(E,F)},list_concatenation:function list_concatenation(E,F){return E.concat(F)},list_subtraction:function list_subtraction(E,F){const G=[...E];for(const H of F){const I=G.indexOf(H);-1F},greaterThanOrEqualTo:function greaterThanOrEqualTo(E,F){return E>=F},lessThan:function lessThan(E,F){return E>F},bxor:function bxor(E,F){return E^F},bnot:function bnot(E){return~E},is_bitstring:function is_bitstring$1(E){return E instanceof g.BitString},is_boolean:function is_boolean$1(E){return'boolean'==typeof E||E instanceof Boolean},is_float:function is_float(E){return is_number$1(E)&&!_NumberisInteger(E)},is_function:function is_function$1(E){return'function'==typeof E||E instanceof Function},is_integer:function is_integer(E){return _NumberisInteger(E)},is_list:function is_list(E){return Array.isArray(E)},is_map:function is_map(E){return'object'==typeof E||E instanceof Object},is_number:is_number$1,is_pid:function is_pid(E){return E instanceof g.PID},is_port:function is_port(){return!1},is_reference:function is_reference(E){return E instanceof g.Reference},is_tuple:function is_tuple(E){return E instanceof g.Tuple},is_atom:function is_atom(E){return'symbol'==typeof E||E instanceof Symbol||E.__MODULE__},is_binary:function is_binary(E){return'string'==typeof E||E instanceof String},element:function element(E,F){return F.get(E-1)},setelement:function setelement(E,F,G){const H=[...F.values];return H[E-1]=G,new g.Tuple(...H)},make_tuple:function make_tuple(E,F){const G=[];for(let H=0;H!0){let H=[],I=buildMatch(E);const J=I(F,H),[K,L]=checkNamedVariables(H);if(J&&L&&G.apply(this,K))return K;throw console.error('No match for:',F),new MatchError(F)},MatchError,variable:function variable(E=null,F=Symbol.for('tailored.no_value')){return new Variable(E,F)},wildcard:function wildcard(){return new Wildcard},startsWith:function startsWith(E){return new StartsWith(E)},capture:function capture(E){return new Capture(E)},headTail:function headTail(){return new HeadTail},type:function type(E,F={}){return new Type(E,F)},bound:function bound(E){return new Bound(E)},Clause,clause:function clause(E,F,G=()=>!0){return new Clause(E,F,G)},bitStringMatch:function bitStringMatch(...E){return new BitStringMatch(...E)},match_or_default,defmatchgen,list_comprehension:function list_comprehension(E,F){const G=run_generators(F.pop()(),F);let H=[];for(let I of G)E.guard.apply(this,I)&&H.push(E.fn.apply(this,I));return H},list_generator:function list_generator(E,F){return function(){let G=[];for(let H of F){const I=match_or_default(E,H,()=>!0,l);if(I!=l){const[J]=I;G.push(J)}}return G}},bitstring_generator:function bitstring_generator(E,F){return function(){let G=[],H=F.slice(0,E.byte_size()),I=1;for(;H.byte_size==E.byte_size();){const J=match_or_default(E,H,()=>!0,l);J!=l&&G.push(J),H=F.slice(E.byte_size()*I,E.byte_size()*(I+1)),I++}return G}},bitstring_comprehension:function bitstring_comprehension(E,F){const G=run_generators(F.pop()(),F);let H=[];for(let I of G)E.guard.apply(this,I)&&H.push(E.fn.apply(this,I));return H=H.map((I)=>g.BitString.integer(I)),new g.BitString(...H)},defmatchGen:function defmatchGen(...E){return defmatchgen(...E)},defmatchAsync:function defmatchAsync(...E){const F=getArityMap(E);return async function(...G){if(F.has(G.length)){const H=F.get(G.length);let I=null,J=null;for(let K of H){let L=[];G=fillInOptionalValues(G,K.arity,K.optionals);const M=K.pattern(G,L),[N,O]=checkNamedVariables(L);if(M&&O&&(await K.guard.apply(this,L))){I=K.fn,J=L;break}}if(!I)throw console.error('No match for:',G),new MatchError(G);return I.apply(this,J)}throw console.error('Arity of',G.length,'not found. No match for:',G),new MatchError(G)}}},Integer:class Integer{},Float:class Float{},Functions:{call_property:function call_property(E,F){if(!F)return E instanceof Function||'function'==typeof E?E():E;let G=null;if('number'==typeof E||'symbol'==typeof E||'boolean'==typeof E||'string'==typeof E?void 0===E[F]?void 0!==E[Symbol.for(F)]&&(G=Symbol.for(F)):G=F:F in E?G=F:Symbol.for(F)in E&&(G=Symbol.for(F)),null===G)throw new Error(`Property ${F} not found in ${E}`);return E[G]instanceof Function||'function'==typeof E[G]?E[G]():E[G]},defprotocol:function defprotocol(E){return new Protocol(E)},defimpl:function defimpl(E,F,G){E.implementation(F,G)},build_namespace:function build_namespace(E,F){let G=F.split('.');const H=E;let I=E;'Elixir'===G[0]&&(G=G.slice(1));for(const J of G)'undefined'==typeof I[J]&&(I[J]={}),I=I[J];return H.__table__=E.__table__||{},H.__table__[Symbol.for(F)]=I,I},iterator_to_reducer},SpecialForms:{_case:function _case(E,F){return C.Patterns.defmatch(...F)(E)},cond:function cond(...E){for(const F of E)if(F[0])return F[1]();throw new Error},_for:function _for(E,F,G,H=[]){let[I,J]=G.into(H);const K=run_list_generators(F.pop()(),F);for(const L of K)E.guard.apply(this,L)&&(I=J(I,new C.Tuple(Symbol.for('cont'),E.fn.apply(this,L))));return J(I,Symbol.for('done'))},_try:function _try(E,F,G,H,I){let J=null;try{J=E()}catch(K){let L=null;if(F)try{return L=F(K),L}catch(M){if(M instanceof C.Patterns.MatchError)throw M}if(G)try{return L=G(K),L}catch(M){if(M instanceof C.Patterns.MatchError)throw M}throw K}finally{I&&I()}if(H)try{return H(J)}catch(K){if(K instanceof C.Patterns.MatchError)throw new Error('No Match Found in Else');throw K}else return J},_with:function _with(...E){let F=[],G=null,H=null;'function'==typeof E[E.length-2]?[G,H]=E.splice(-2):G=E.pop();for(let I=0;I{const[H,I]=G;return F[H]=I,F},{})},keys,values:function values$1(E){if(!1===q.is_map(E))return new g.Tuple(u,E);const F=[];for(const G of keys(E))F.push(E[G]);return F},is_key,put:function put(E,F,G){if(!1===q.is_map(G))return new g.Tuple(u,G);const H=Object.assign({},G,{[E]:F});return H},merge:function merge(E,F){return!1===q.is_map(E)?new g.Tuple(u,E):!1===q.is_map(F)?new g.Tuple(u,F):Object.assign({},E,F)},update:function update(E,F,G){return!1===q.is_map(G)?new g.Tuple(u,G):!1===is_key(E,G)?new g.Tuple(w,E):Object.assign({},G,{[E]:F})},get:function get(...E){const F=E[0],G=E[1];return!1===q.is_map(G)?new g.Tuple(u,G):is_key(F)?G[F]:3===E.length?E[2]:new g.Tuple(w,F)},take:function take(E,F){if(!1===q.is_map(F))return new g.Tuple(u,F);if(!is_key(E))return t;const G=F[E],H=Object.assign({},F);return delete H[E],new g.Tuple(G,H)}},lists:{reverse,foreach:function foreach(E,F){return F.forEach((G)=>E(G)),Symbol.for('ok')},duplicate:function duplicate(E,F){const G=[];for(;G.length{return H.get(E-1)I.get(E-1)?1:0})},keystore:function keystore(E,F,G,H){const I=[...G];for(let J=0;JF.toString()).join()},map:function map(E,F){return F.map((G)=>E(G))},filter:function filter(E,F){return F.filter((G)=>E(G))},filtermap:function filtermap(E,F){const G=[];for(const H of F){const I=E(H);!0===I?G.push(H):I instanceof g.Tuple&&!0===I.get(0)&&G.push(I.get(1))}return G},member:function member(E,F){for(const G of F)if(G===E)return!0;return!1},all:function all(E,F){for(const G of F)if(!1===E(G))return!1;return!0},any:function any(E,F){for(const G of F)if(!0===E(G))return!0;return!1},splitwith:function splitwith(E,F){let G=!1;const H=[],I=[];for(const J of F)!0==G?I.push(J):!0===E(J)?H.push(J):(G=!0,I.push(J));return new g.Tuple(H,I)},sort:function sort(...E){if(1===E.length){const H=[...E[0]];return H.sort()}const F=E[0],G=[...E[1]];return G.sort((H,I)=>{const J=F(H,I);return!0===J?-1:1})}}};return{Core:C}}(); +var ElixirScript=function(){'use strict';/* @flow */function namedVariableResult(a,b){return new NamedVariableResult(a,b)}/* @flow */function is_number(a){return'number'==typeof a}function is_string(a){return'string'==typeof a}function is_boolean(a){return'boolean'==typeof a}function is_symbol(a){return'symbol'==typeof a}function is_object(a){return'object'==typeof a}function is_variable(a){return a instanceof Variable}function is_null(a){return null===a}function is_array(a){return Array.isArray(a)}function is_function(a){return'[object Function]'==Object.prototype.toString.call(a)}function is_map(a){return a instanceof Map}function resolveNull(){return function(a){return is_null(a)}}function resolveWildcard(){return function(){return!0}}function resolveObject(a){let b={};const c=Object.keys(a).concat(Object.getOwnPropertySymbols(a));for(let d of c)b[d]=buildMatch(a[d]);return function(d,e){if(!is_object(d)||a.length>d.length)return!1;for(let a of c)if(!(a in d)||!b[a](d[a],e))return!1;return!0}}function getSize(a,b){return a*b/8}function arraysEqual(c,a){if(c===a)return!0;if(null==c||null==a)return!1;if(c.length!=a.length)return!1;for(var b=0;be.integer(a));return new e(...b)}function resolveNoMatch(){return function(){return!1}}function buildMatch(a){if(null===a)return resolveNull(a);if('undefined'==typeof a)return resolveWildcard(a);const b=a.constructor.prototype,c=f.get(b);return c?c(a):'object'==typeof a?resolveObject(a):resolveNoMatch()}function defmatchgen(...a){const b=getArityMap(a);return function*(...a){let[c,d]=findMatchingFunction(a,b);return yield*c.apply(this,d)}}function findMatchingFunction(a,b){if(b.has(a.length)){const c=b.get(a.length);let d=null,e=null;for(let b of c){let c=[];a=fillInOptionalValues(a,b.arity,b.optionals);const f=b.pattern(a,c),[g,h]=checkNamedVariables(c);if(f&&h&&b.guard.apply(this,g)){d=b.fn,e=g;break}}if(!d)throw console.error('No match for:',a),new MatchError(a);return[d,e]}throw console.error('Arity of',a.length,'not found. No match for:',a),new MatchError(a)}function getArityMap(a){let b=new Map;for(const c of a){const a=getArityRange(c);for(const d of a){let a=[];b.has(d)&&(a=b.get(d)),a.push(c),b.set(d,a)}}return b}function getArityRange(a){const b=a.arity-a.optionals.length,c=a.arity;let d=[b];for(;d[d.length-1]!=c;)d.push(d[d.length-1]+1);return d}function getOptionalValues(a){let b=[];for(let c=0;c!0,d=null){let e=[],f=buildMatch(a);const g=f(b,e),[h,i]=checkNamedVariables(e);return g&&i&&c.apply(this,h)?h:d}function run_generators(a,b){if(0==b.length)return a.map((a)=>{return Array.isArray(a)?a:[a]});const c=b.pop();let d=[];for(let e of c())for(let b of a)d.push([e].concat(b));return run_generators(d,b)}function iterator_to_reducer(a,b,c){const d=a[Symbol.iterator]();let e=d.next(),f=b;for(;!1===e.done;){if(f=c(e.value,f.get(1)),f.get(0)===Symbol.for('halt'))return new n.Tuple(Symbol.for('halted'),f.get(1));if(f.get(0)===Symbol.for('suspend'))return new n.Tuple(Symbol.for('suspended'),f.get(1),(a)=>{return iterator_to_reducer(d,a,c)});e=d.next()}return new n.Tuple(Symbol.for('done'),f.get(1))}function run_list_generators(a,b){if(0==b.length)return a.map((a)=>{return Array.isArray(a)?a:[a]});const c=b.pop(),d=[];for(const e of c())for(const b of a)d.push([e].concat(b));return run_list_generators(d,b)}// http://erlang.org/doc/man/erlang.html +function atom_to_binary(a,b=Symbol.for('utf8')){if(b!==Symbol.for('utf8'))throw new Error(`unsupported encoding ${b}`);return a.__MODULE__?Symbol.keyFor(a.__MODULE__):Symbol.keyFor(a)}function binary_to_atom(a,b=Symbol.for('utf8')){if(b!==Symbol.for('utf8'))throw new Error(`unsupported encoding ${b}`);return Symbol.for(a)}function is_number$1(a){return'number'==typeof a||a instanceof Number}function to_list(a){if(!1===h.is_map(a))return new d.Tuple(k,a);const b=[];for(const c of keys(a))b.push(new d.Tuple(c,a[c]));return b}function keys(a){if(!1===h.is_map(a))return new d.Tuple(k,a);const b=[];for(const c of Object.getOwnPropertySymbols(a))b.push(c);for(const c of Object.getOwnPropertyNames(a))b.push(c);return b}function is_key(a,b){return b.hasOwnProperty(a)}// http://erlang.org/doc/man/lists.html +function reverse(a){return[...a]}function flatten(a,b=[]){const c=a.reduce((a,b)=>{return Array.isArray(b)?a.concat(flatten(b)):a.concat(b)},[]);return c.concat(b)}function foldl(a,b,c){return c.reduce((b,c)=>{return a(c,b)},b)}function keyfind(a,b,c){for(const d of c)if(d.get(b-1)===a)return d;return!1}function keydelete(a,b,c){const d=[];let e=!1;for(let f=0;fBitString$1.integer(a));return new BitString$1(...d)}[Symbol.iterator](){return this.value[Symbol.iterator]()}toString(){var a,b='';for(a=0;a>'}process(a){let b=[];var c;for(c=0;cb?c.push(b):2048>b?c.push(192|b>>6,128|63&b):55296>b||57344<=b?c.push(224|b>>12,128|63&b>>6,128|63&b):(d++,b=65536+((1023&b)<<10|1023&a.charCodeAt(d)),c.push(240|b>>18,128|63&b>>12,128|63&b>>6,128|63&b));return c}static toUTF16Array(a){for(var b,c=[],d=0;d=b?(c.push(0),c.push(b)):(c.push(255&b>>8),c.push(255&b));return c}static toUTF32Array(a){for(var b,c=[],d=0;d=b?(c.push(0),c.push(0),c.push(0),c.push(b)):(c.push(0),c.push(0),c.push(255&b>>8),c.push(255&b));return c}//http://stackoverflow.com/questions/2003493/javascript-float-from-to-bits +static float32ToBytes(a){var b=[],c=new ArrayBuffer(4);new Float32Array(c)[0]=a;let d=new Uint32Array(c)[0];return b.push(255&d>>24),b.push(255&d>>16),b.push(255&d>>8),b.push(255&d),b}static float64ToBytes(a){var b=[],c=new ArrayBuffer(8);new Float64Array(c)[0]=a;var d=new Uint32Array(c)[0],e=new Uint32Array(c)[1];return b.push(255&e>>24),b.push(255&e>>16),b.push(255&e>>8),b.push(255&e),b.push(255&d>>24),b.push(255&d>>16),b.push(255&d>>8),b.push(255&d),b}}var d={Tuple,PID:class PID{constructor(){++b,this.id=b}toString(){return'PID#<0.'+this.id+'.0>'}},Reference:class Reference{constructor(){++c,this.id=c,this.ref=Symbol()}toString(){return'Ref#<0.0.0.'+this.id+'>'}},BitString:BitString$1};/* @flow */const e=d.BitString,f=new Map;f.set(Variable.prototype,function resolveVariable(a){return function(b,c){return null===a.name||a.name.startsWith('_')?c.push(b):c.push(namedVariableResult(a.name,b)),!0}}),f.set(Wildcard.prototype,resolveWildcard),f.set(HeadTail.prototype,function resolveHeadTail(){return function(a,b){if(!is_array(a)||2>a.length)return!1;const c=a[0],d=a.slice(1);return b.push(c),b.push(d),!0}}),f.set(StartsWith.prototype,function resolveStartsWith(a){const b=a.prefix;return function(a,c){return is_string(a)&&a.startsWith(b)&&(c.push(a.substring(b.length)),!0)}}),f.set(Capture.prototype,function resolveCapture(a){const b=buildMatch(a.value);return function(a,c){return!!b(a,c)&&(c.push(a),!0)}}),f.set(Bound.prototype,function resolveBound(a){return function(b){return typeof b==typeof a.value&&b===a.value}}),f.set(Type.prototype,function resolveType(a){return function(b,c){if(b instanceof a.type){const d=buildMatch(a.objPattern);return d(b,c)}return!1}}),f.set(BitStringMatch.prototype,function resolveBitString(a){let b=[];for(let c of a.values)if(is_variable(c.value)){let a=getSize(c.unit,c.size);fillArray(b,a)}else b=b.concat(new e(c).value);let c=a.values;return function(a,d){var f=String.fromCharCode;let g=null;if(!is_string(a)&&!(a instanceof e))return!1;g=is_string(a)?new e(e.binary(a)):a;let h=0;for(let e,j=0;jd.size)return!1;for(let a of c)if(!d.has(a)||!b.get(a)(d.get(a),e))return!1;return!0}}),f.set(Array.prototype,function resolveArray(a){const b=a.map((a)=>buildMatch(a));return function(c,d){return is_array(c)&&c.length==a.length&&c.every(function(a,e){return b[e](c[e],d)})}}),f.set(String.prototype,function resolveString(a){return function(b){return is_string(b)&&b===a}}),f.set(Boolean.prototype,function resolveBoolean(a){return function(b){return is_boolean(b)&&b===a}}),f.set(Function.prototype,function resolveFunction(a){return function(b){return is_function(b)&&b===a}}),f.set(Object.prototype,resolveObject);class MatchError extends Error{constructor(a){if(super(),'symbol'==typeof a)this.message='No match for: '+a.toString();else if(Array.isArray(a)){let b=a.map((a)=>{return null===a?'null':'undefined'==typeof a?'undefined':a.toString()});this.message='No match for: '+b}else this.message='No match for: '+a;this.stack=new Error().stack,this.name=this.constructor.name}}class Clause{constructor(a,b,c=()=>!0){this.pattern=buildMatch(a),this.arity=a.length,this.optionals=getOptionalValues(a),this.fn=b,this.guard=c}}const g=Symbol();// https://github.com/airportyh/protomorphism +class Protocol{constructor(b){function createFun(b){return function(...c){const d=c[0];let e=null;if(null===d&&this.hasImplementation(Symbol('null'))?e=this.registry.get(Symbol)[b]:a(d)&&this.hasImplementation(n.Integer)?e=this.registry.get(n.Integer)[b]:'number'==typeof d&&!a(d)&&this.hasImplementation(n.Float)?e=this.registry.get(n.Float)[b]:'string'==typeof d&&this.hasImplementation(n.BitString)?e=this.registry.get(n.BitString)[b]:d&&d[Symbol.for('__struct__')]&&this.hasImplementation(d)?e=this.registry.get(d[Symbol.for('__struct__')].__MODULE__)[b]:null!==d&&this.hasImplementation(d)?e=this.registry.get(d.constructor)[b]:this.fallback&&(e=this.fallback[b]),null!=e){const a=e.apply(this,c);return a}throw new Error(`No implementation found for ${d}`)}}for(const a in this.registry=new Map,this.fallback=null,b)this[a]=createFun(a).bind(this)}implementation(a,b){null===a?this.fallback=b:this.registry.set(a,b)}hasImplementation(a){if(a===n.Integer||a===n.Float||a===n.BitString)return this.registry.has(a);return a&&a[Symbol.for('__struct__')]?this.registry.has(a[Symbol.for('__struct__')].__MODULE__):this.registry.has(a.constructor)}}var h={atom_to_binary,binary_to_atom,binary_to_existing_atom:function binary_to_existing_atom(a,b=Symbol.for('utf8')){return binary_to_atom(a,b)},list_concatenation:function list_concatenation(a,b){return a.concat(b)},list_subtraction:function list_subtraction(a,b){const c=[...a];for(const d of b){const a=c.indexOf(d);-1b},greaterThanOrEqualTo:function greaterThanOrEqualTo(a,b){return a>=b},lessThan:function lessThan(a,b){return a>b},bxor:function bxor(a,b){return a^b},bnot:function bnot(a){return~a},is_bitstring:function is_bitstring$1(a){return a instanceof d.BitString},is_boolean:function is_boolean$1(a){return'boolean'==typeof a||a instanceof Boolean},is_float:function is_float(b){return is_number$1(b)&&!a(b)},is_function:function is_function$1(a){return'function'==typeof a||a instanceof Function},is_integer:function is_integer(b){return a(b)},is_list:function is_list(a){return Array.isArray(a)},is_map:function is_map$1(a){return'object'==typeof a||a instanceof Object},is_number:is_number$1,is_pid:function is_pid(a){return a instanceof d.PID},is_port:function is_port(){return!1},is_reference:function is_reference(a){return a instanceof d.Reference},is_tuple:function is_tuple(a){return a instanceof d.Tuple},is_atom:function is_atom(a){return'symbol'==typeof a||a instanceof Symbol||a.__MODULE__},is_binary:function is_binary(a){return'string'==typeof a||a instanceof String},element:function element(a,b){return b.get(a-1)},setelement:function setelement(a,b,c){const e=[...b.values];return e[a-1]=c,new d.Tuple(...e)},make_tuple:function make_tuple(a,b){const c=[];for(let d=0;d!0){let d=[],e=buildMatch(a);const f=e(b,d),[g,h]=checkNamedVariables(d);if(f&&h&&c.apply(this,g))return g;throw console.error('No match for:',b),new MatchError(b)},MatchError,variable:function variable(a=null,b=Symbol.for('tailored.no_value')){return new Variable(a,b)},wildcard:function wildcard(){return new Wildcard},startsWith:function startsWith(a){return new StartsWith(a)},capture:function capture(a){return new Capture(a)},headTail:function headTail(){return new HeadTail},type:function a(a,b={}){return new Type(a,b)},bound:function bound(a){return new Bound(a)},Clause,clause:function clause(a,b,c=()=>!0){return new Clause(a,b,c)},bitStringMatch:function bitStringMatch(...a){return new BitStringMatch(...a)},match_or_default,defmatchgen,list_comprehension:function list_comprehension(a,b){const c=run_generators(b.pop()(),b);let d=[];for(let e of c)a.guard.apply(this,e)&&d.push(a.fn.apply(this,e));return d},list_generator:function list_generator(a,b){return function(){let c=[];for(let d of b){const b=match_or_default(a,d,()=>!0,g);if(b!=g){const[a]=b;c.push(a)}}return c}},bitstring_generator:function bitstring_generator(a,b){return function(){let c=[],d=b.slice(0,a.byte_size()),e=1;for(;d.byte_size==a.byte_size();){const f=match_or_default(a,d,()=>!0,g);if(f!=g){c.push(f)}d=b.slice(a.byte_size()*e,a.byte_size()*(e+1)),e++}return c}},bitstring_comprehension:function bitstring_comprehension(a,b){const c=run_generators(b.pop()(),b);let e=[];for(let d of c)a.guard.apply(this,d)&&e.push(a.fn.apply(this,d));return e=e.map((a)=>d.BitString.integer(a)),new d.BitString(...e)},defmatchGen:function defmatchGen(...a){return defmatchgen(...a)},defmatchAsync:function defmatchAsync(...a){const b=getArityMap(a);return async function(...a){if(b.has(a.length)){const c=b.get(a.length);let d=null,e=null;for(let b of c){let c=[];a=fillInOptionalValues(a,b.arity,b.optionals);const f=b.pattern(a,c),[g,h]=checkNamedVariables(c);if(f&&h&&(await b.guard.apply(this,c))){d=b.fn,e=c;break}}if(!d)throw console.error('No match for:',a),new MatchError(a);return d.apply(this,e)}throw console.error('Arity of',a.length,'not found. No match for:',a),new MatchError(a)}}},Integer:class Integer{},Float:class Float{},Functions:{call_property:function call_property(a,b){if(!b)return a instanceof Function||'function'==typeof a?a():a;let c=null;if('number'==typeof a||'symbol'==typeof a||'boolean'==typeof a||'string'==typeof a?void 0===a[b]?void 0!==a[Symbol.for(b)]&&(c=Symbol.for(b)):c=b:b in a?c=b:Symbol.for(b)in a&&(c=Symbol.for(b)),null===c)throw new Error(`Property ${b} not found in ${a}`);return a[c]instanceof Function||'function'==typeof a[c]?a[c]():a[c]},defprotocol:function defprotocol(a){return new Protocol(a)},defimpl:function defimpl(a,b,c){a.implementation(b,c)},build_namespace:function build_namespace(a,b){let c=b.split('.');const d=a;let e=a;'Elixir'===c[0]&&(c=c.slice(1));for(const d of c)'undefined'==typeof e[d]&&(e[d]={}),e=e[d];return d.__table__=a.__table__||{},d.__table__[Symbol.for(b)]=e,e},iterator_to_reducer},SpecialForms:{_case:function _case(a,b){return n.Patterns.defmatch(...b)(a)},cond:function cond(...a){for(const b of a)if(b[0])return b[1]();throw new Error},_for:function _for(a,b,c,d=[]){let[e,f]=c.into(d);const g=run_list_generators(b.pop()(),b);for(const h of g)a.guard.apply(this,h)&&(e=f(e,new n.Tuple(Symbol.for('cont'),a.fn.apply(this,h))));return f(e,Symbol.for('done'))},_try:function _try(a,b,c,d,e){let f=null;try{f=a()}catch(a){let d=null;if(b)try{return d=b(a),d}catch(a){if(a instanceof n.Patterns.MatchError)throw a}if(c)try{return d=c(a),d}catch(a){if(a instanceof n.Patterns.MatchError)throw a}throw a}finally{e&&e()}if(d)try{return d(f)}catch(a){if(a instanceof n.Patterns.MatchError)throw new Error('No Match Found in Else');throw a}else return f},_with:function _with(...a){let b=[],c=null,d=null;'function'==typeof a[a.length-2]?[c,d]=a.splice(-2):c=a.pop();for(let c=0;c{const[c,d]=b;return a[c]=d,a},{})},keys,values:function values$1(a){if(!1===h.is_map(a))return new d.Tuple(k,a);const b=[];for(const c of keys(a))b.push(a[c]);return b},is_key,put:function put(a,b,c){if(!1===h.is_map(c))return new d.Tuple(k,c);const e=Object.assign({},c,{[a]:b});return e},merge:function merge(a,b){return!1===h.is_map(a)?new d.Tuple(k,a):!1===h.is_map(b)?new d.Tuple(k,b):Object.assign({},a,b)},update:function update(a,b,c){return!1===h.is_map(c)?new d.Tuple(k,c):!1===is_key(a,c)?new d.Tuple(l,a):Object.assign({},c,{[a]:b})},get:function get(...a){const b=a[0],c=a[1];return!1===h.is_map(c)?new d.Tuple(k,c):is_key(b)?c[b]:3===a.length?a[2]:new d.Tuple(l,b)},take:function take(a,b){if(!1===h.is_map(b))return new d.Tuple(k,b);if(!is_key(a))return j;const c=b[a],e=Object.assign({},b);return delete e[a],new d.Tuple(c,e)}},lists:{reverse,foreach:function foreach(a,b){return b.forEach((b)=>a(b)),Symbol.for('ok')},duplicate:function duplicate(a,b){const c=[];for(;c.length{if(d.get(c-1)a.get(c-1)?1:0})},keystore:function keystore(a,b,c,d){const e=[...c];for(let f=0;fa.toString()).join()},map:function map(a,b){return b.map((b)=>a(b))},filter:function filter(a,b){return b.filter((b)=>a(b))},filtermap:function filtermap(a,b){const c=[];for(const e of b){const b=a(e);!0===b?c.push(e):b instanceof d.Tuple&&!0===b.get(0)&&c.push(b.get(1))}return c},member:function member(a,b){for(const c of b)if(c===a)return!0;return!1},all:function all(a,b){for(const c of b)if(!1===a(c))return!1;return!0},any:function any(a,b){for(const c of b)if(!0===a(c))return!0;return!1},splitwith:function splitwith(a,b){let c=!1;const e=[],f=[];for(const d of b)!0==c?f.push(d):!0===a(d)?e.push(d):(c=!0,f.push(d));return new d.Tuple(e,f)},sort:function sort(...a){if(1===a.length){const b=[...a[0]];return b.sort()}const c=a[0],b=[...a[1]];return b.sort((d,a)=>{const b=c(d,a);return!0===b?-1:1})}}};return{Core:n}}(); diff --git a/yarn.lock b/yarn.lock index 1d33ab2c..4c47311a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6,7 +6,7 @@ version "2.0.0" resolved "https://registry.yarnpkg.com/@ava/babel-plugin-throws-helper/-/babel-plugin-throws-helper-2.0.0.tgz#2fc1fe3c211a71071a4eca7b8f7af5842cd1ae7c" -"@ava/babel-preset-stage-4@^1.0.0": +"@ava/babel-preset-stage-4@^1.1.0": version "1.1.0" resolved "https://registry.yarnpkg.com/@ava/babel-preset-stage-4/-/babel-preset-stage-4-1.1.0.tgz#ae60be881a0babf7d35f52aba770d1f6194f76bd" dependencies: @@ -30,17 +30,24 @@ "@ava/babel-plugin-throws-helper" "^2.0.0" babel-plugin-espower "^2.3.2" -"@ava/pretty-format@^1.1.0": - version "1.1.0" - resolved "https://registry.yarnpkg.com/@ava/pretty-format/-/pretty-format-1.1.0.tgz#d0a57d25eb9aeab9643bdd1a030642b91c123e28" +"@ava/write-file-atomic@^2.2.0": + version "2.2.0" + resolved "https://registry.yarnpkg.com/@ava/write-file-atomic/-/write-file-atomic-2.2.0.tgz#d625046f3495f1f5e372135f473909684b429247" dependencies: - ansi-styles "^2.2.1" - esutils "^2.0.2" + graceful-fs "^4.1.11" + imurmurhash "^0.1.4" + slide "^1.1.5" "@comandeer/babel-plugin-banner@^1.0.0": version "1.0.0" resolved "https://registry.yarnpkg.com/@comandeer/babel-plugin-banner/-/babel-plugin-banner-1.0.0.tgz#40bcce0bbee084b5b02545a33635d053c248356f" +"@concordance/react@^1.0.0": + version "1.0.0" + resolved "https://registry.yarnpkg.com/@concordance/react/-/react-1.0.0.tgz#fcf3cad020e5121bfd1c61d05bc3516aac25f734" + dependencies: + arrify "^1.0.1" + abbrev@1: version "1.1.0" resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.0.tgz#d0554c2256636e2f56e7c2e5ad183f859428d81f" @@ -70,6 +77,15 @@ ajv@^4.7.0, ajv@^4.9.1: co "^4.6.0" json-stable-stringify "^1.0.1" +ajv@^5.2.0: + version "5.2.2" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-5.2.2.tgz#47c68d69e86f5d953103b0074a9430dc63da5e39" + dependencies: + co "^4.6.0" + fast-deep-equal "^1.0.0" + json-schema-traverse "^0.3.0" + json-stable-stringify "^1.0.1" + align-text@^0.1.1, align-text@^0.1.3: version "0.1.4" resolved "https://registry.yarnpkg.com/align-text/-/align-text-0.1.4.tgz#0cd90a561093f35d0a99256c22b7069433fad117" @@ -88,19 +104,23 @@ ansi-align@^2.0.0: dependencies: string-width "^2.0.0" -ansi-escapes@^1.1.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-1.4.0.tgz#d3a8a83b319aa67793662b13e761c7911422306e" +ansi-escapes@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-2.0.0.tgz#5bae52be424878dd9783e8910e3fc2922e83c81b" ansi-regex@^2.0.0: version "2.1.1" resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" +ansi-regex@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998" + ansi-styles@^2.2.1: version "2.2.1" resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe" -ansi-styles@^3.0.0: +ansi-styles@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.1.0.tgz#09c202d5c917ec23188caa5c9cb9179cd9547750" dependencies: @@ -222,24 +242,26 @@ ava-init@^0.2.0: read-pkg-up "^2.0.0" write-pkg "^2.0.0" -ava@^0.19.1: - version "0.19.1" - resolved "https://registry.yarnpkg.com/ava/-/ava-0.19.1.tgz#43dd82435ad19b3980ffca2488f05daab940b273" +ava@^0.21.0: + version "0.21.0" + resolved "https://registry.yarnpkg.com/ava/-/ava-0.21.0.tgz#cd8d8ea3546f57150dea38548b9f72f8ca583d29" dependencies: - "@ava/babel-preset-stage-4" "^1.0.0" + "@ava/babel-preset-stage-4" "^1.1.0" "@ava/babel-preset-transform-test-files" "^3.0.0" - "@ava/pretty-format" "^1.1.0" + "@ava/write-file-atomic" "^2.2.0" + "@concordance/react" "^1.0.0" + ansi-escapes "^2.0.0" + ansi-styles "^3.1.0" arr-flatten "^1.0.1" array-union "^1.0.1" array-uniq "^1.0.2" arrify "^1.0.0" auto-bind "^1.1.0" ava-init "^0.2.0" - babel-code-frame "^6.16.0" babel-core "^6.17.0" bluebird "^3.0.0" caching-transform "^1.0.0" - chalk "^1.0.0" + chalk "^2.0.1" chokidar "^1.4.2" clean-stack "^1.1.1" clean-yaml-object "^0.1.0" @@ -249,59 +271,59 @@ ava@^0.19.1: co-with-promise "^4.6.0" code-excerpt "^2.1.0" common-path-prefix "^1.0.0" + concordance "^3.0.0" convert-source-map "^1.2.0" core-assert "^0.2.0" currently-unhandled "^0.4.1" debug "^2.2.0" - diff "^3.0.1" - diff-match-patch "^1.0.0" dot-prop "^4.1.0" empower-core "^0.6.1" equal-length "^1.0.0" figures "^2.0.0" - find-cache-dir "^0.1.1" + find-cache-dir "^1.0.0" fn-name "^2.0.0" get-port "^3.0.0" globby "^6.0.0" has-flag "^2.0.0" - hullabaloo-config-manager "^1.0.0" + hullabaloo-config-manager "^1.1.0" ignore-by-default "^1.0.0" + import-local "^0.1.1" indent-string "^3.0.0" is-ci "^1.0.7" is-generator-fn "^1.0.0" is-obj "^1.0.0" is-observable "^0.2.0" is-promise "^2.1.0" - jest-diff "19.0.0" - jest-snapshot "19.0.2" js-yaml "^3.8.2" last-line-stream "^1.0.0" + lodash.clonedeepwith "^4.5.0" lodash.debounce "^4.0.3" lodash.difference "^4.3.0" lodash.flatten "^4.2.0" - lodash.isequal "^4.5.0" loud-rejection "^1.2.0" - matcher "^0.1.1" + make-dir "^1.0.0" + matcher "^1.0.0" md5-hex "^2.0.0" meow "^3.7.0" - mkdirp "^0.5.1" - ms "^0.7.1" + ms "^2.0.0" multimatch "^2.1.0" observable-to-promise "^0.5.0" - option-chain "^0.1.0" + option-chain "^1.0.0" package-hash "^2.0.0" pkg-conf "^2.0.0" plur "^2.0.0" pretty-ms "^2.0.0" require-precompiled "^0.1.0" - resolve-cwd "^1.0.0" + resolve-cwd "^2.0.0" + safe-buffer "^5.1.1" slash "^1.0.0" source-map-support "^0.4.0" stack-utils "^1.0.0" - strip-ansi "^3.0.1" + strip-ansi "^4.0.0" strip-bom-buf "^1.0.0" - supports-color "^3.2.3" + supports-color "^4.0.0" time-require "^0.1.2" + trim-off-newlines "^1.0.1" unique-temp-dir "^1.0.0" update-notifier "^2.1.0" @@ -313,7 +335,7 @@ aws4@^1.2.1: version "1.6.0" resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.6.0.tgz#83ef5ca860b2b32e4a0deedee8c771b9db57471e" -babel-code-frame@^6.16.0, babel-code-frame@^6.22.0: +babel-code-frame@^6.22.0: version "6.22.0" resolved "https://registry.yarnpkg.com/babel-code-frame/-/babel-code-frame-6.22.0.tgz#027620bee567a88c32561574e7fd0801d33118e4" dependencies: @@ -384,9 +406,9 @@ babel-helper-define-map@^6.24.1: babel-types "^6.24.1" lodash "^4.2.0" -babel-helper-evaluate-path@^0.0.3: - version "0.0.3" - resolved "https://registry.yarnpkg.com/babel-helper-evaluate-path/-/babel-helper-evaluate-path-0.0.3.tgz#1d103ac9d4a59e5d431842212f151785f7ac547b" +babel-helper-evaluate-path@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/babel-helper-evaluate-path/-/babel-helper-evaluate-path-0.1.0.tgz#95d98c4ea36150483db2e7d3ec9e1954a72629cb" babel-helper-explode-assignable-expression@^6.24.1: version "6.24.1" @@ -396,9 +418,9 @@ babel-helper-explode-assignable-expression@^6.24.1: babel-traverse "^6.24.1" babel-types "^6.24.1" -babel-helper-flip-expressions@^0.0.2: - version "0.0.2" - resolved "https://registry.yarnpkg.com/babel-helper-flip-expressions/-/babel-helper-flip-expressions-0.0.2.tgz#7bab2cf61162bc92703e9b298ef512bcf77d6787" +babel-helper-flip-expressions@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/babel-helper-flip-expressions/-/babel-helper-flip-expressions-0.1.2.tgz#77f6652f9de9c42401d827bd46ebd2109e3ef18a" babel-helper-function-name@^6.24.1: version "6.24.1" @@ -428,13 +450,9 @@ babel-helper-is-nodes-equiv@^0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/babel-helper-is-nodes-equiv/-/babel-helper-is-nodes-equiv-0.0.1.tgz#34e9b300b1479ddd98ec77ea0bbe9342dfe39684" -babel-helper-is-void-0@^0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/babel-helper-is-void-0/-/babel-helper-is-void-0-0.0.1.tgz#ed74553b883e68226ae45f989a99b02c190f105a" - -babel-helper-mark-eval-scopes@^0.0.3: - version "0.0.3" - resolved "https://registry.yarnpkg.com/babel-helper-mark-eval-scopes/-/babel-helper-mark-eval-scopes-0.0.3.tgz#902f75aeb537336edc35eb9f52b6f09db7785328" +babel-helper-is-void-0@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/babel-helper-is-void-0/-/babel-helper-is-void-0-0.1.1.tgz#72f21a3abba0bef3837f9174fca731aed9a02888" babel-helper-mark-eval-scopes@^0.1.1: version "0.1.1" @@ -480,9 +498,9 @@ babel-helper-replace-supers@^6.24.1: babel-traverse "^6.24.1" babel-types "^6.24.1" -babel-helper-to-multiple-sequence-expressions@^0.0.4: - version "0.0.4" - resolved "https://registry.yarnpkg.com/babel-helper-to-multiple-sequence-expressions/-/babel-helper-to-multiple-sequence-expressions-0.0.4.tgz#d94414b386b6286fbaad77f073dea9b34324b01c" +babel-helper-to-multiple-sequence-expressions@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/babel-helper-to-multiple-sequence-expressions/-/babel-helper-to-multiple-sequence-expressions-0.1.1.tgz#5f1b832b39e4acf954e9137f0251395c71196b35" babel-helpers@^6.24.1: version "6.24.1" @@ -515,20 +533,19 @@ babel-plugin-espower@^2.3.2: espurify "^1.6.0" estraverse "^4.1.1" -babel-plugin-minify-builtins@^0.0.2: - version "0.0.2" - resolved "https://registry.yarnpkg.com/babel-plugin-minify-builtins/-/babel-plugin-minify-builtins-0.0.2.tgz#f3be6121763c0c518d5ef82067cef4b615c9498c" +babel-plugin-minify-builtins@^0.1.3: + version "0.1.3" + resolved "https://registry.yarnpkg.com/babel-plugin-minify-builtins/-/babel-plugin-minify-builtins-0.1.3.tgz#4f21a7dcb51f91a04ea71d47ff0e8e3b05fec021" dependencies: - babel-helper-evaluate-path "^0.0.3" + babel-helper-evaluate-path "^0.1.0" -babel-plugin-minify-constant-folding@^0.0.4: - version "0.0.4" - resolved "https://registry.yarnpkg.com/babel-plugin-minify-constant-folding/-/babel-plugin-minify-constant-folding-0.0.4.tgz#b6e231026a6035e88ceadd206128d7db2b5c15e6" +babel-plugin-minify-constant-folding@^0.1.3: + version "0.1.3" + resolved "https://registry.yarnpkg.com/babel-plugin-minify-constant-folding/-/babel-plugin-minify-constant-folding-0.1.3.tgz#57bd172adf8b8d74ad7c99612eb950414ebea3ca" dependencies: - babel-helper-evaluate-path "^0.0.3" - jsesc "^2.4.0" + babel-helper-evaluate-path "^0.1.0" -babel-plugin-minify-dead-code-elimination@^0.1.4: +babel-plugin-minify-dead-code-elimination@^0.1.7: version "0.1.7" resolved "https://registry.yarnpkg.com/babel-plugin-minify-dead-code-elimination/-/babel-plugin-minify-dead-code-elimination-0.1.7.tgz#774f536f347b98393a27baa717872968813c342c" dependencies: @@ -536,49 +553,49 @@ babel-plugin-minify-dead-code-elimination@^0.1.4: babel-helper-remove-or-void "^0.1.1" lodash.some "^4.6.0" -babel-plugin-minify-flip-comparisons@^0.0.2: - version "0.0.2" - resolved "https://registry.yarnpkg.com/babel-plugin-minify-flip-comparisons/-/babel-plugin-minify-flip-comparisons-0.0.2.tgz#7d0953aa5876ede6118966bda9edecc63bf346ab" +babel-plugin-minify-flip-comparisons@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/babel-plugin-minify-flip-comparisons/-/babel-plugin-minify-flip-comparisons-0.1.2.tgz#e286b40b7599b18dfea195071e4279465cfc1884" dependencies: - babel-helper-is-void-0 "^0.0.1" + babel-helper-is-void-0 "^0.1.1" -babel-plugin-minify-guarded-expressions@^0.0.4: - version "0.0.4" - resolved "https://registry.yarnpkg.com/babel-plugin-minify-guarded-expressions/-/babel-plugin-minify-guarded-expressions-0.0.4.tgz#957104a760e6a7ffd967005a7a11621bb42fd11c" +babel-plugin-minify-guarded-expressions@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/babel-plugin-minify-guarded-expressions/-/babel-plugin-minify-guarded-expressions-0.1.2.tgz#dfc3d473b0362d9605d3ce0ac1e22328c60d1007" dependencies: - babel-helper-flip-expressions "^0.0.2" + babel-helper-flip-expressions "^0.1.2" -babel-plugin-minify-infinity@^0.0.3: - version "0.0.3" - resolved "https://registry.yarnpkg.com/babel-plugin-minify-infinity/-/babel-plugin-minify-infinity-0.0.3.tgz#4cc99b61d12b434ce80ad675103335c589cba9a1" +babel-plugin-minify-infinity@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/babel-plugin-minify-infinity/-/babel-plugin-minify-infinity-0.1.2.tgz#5f1cf67ddedcba13c8a00da832542df0091a1cd4" -babel-plugin-minify-mangle-names@^0.0.8: - version "0.0.8" - resolved "https://registry.yarnpkg.com/babel-plugin-minify-mangle-names/-/babel-plugin-minify-mangle-names-0.0.8.tgz#1e2fea856dd742d5697aa26b427e41258a8c5b79" +babel-plugin-minify-mangle-names@^0.1.3: + version "0.1.3" + resolved "https://registry.yarnpkg.com/babel-plugin-minify-mangle-names/-/babel-plugin-minify-mangle-names-0.1.3.tgz#bfa24661a6794fb03833587e55828b65449e06fe" dependencies: - babel-helper-mark-eval-scopes "^0.0.3" + babel-helper-mark-eval-scopes "^0.1.1" -babel-plugin-minify-numeric-literals@^0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/babel-plugin-minify-numeric-literals/-/babel-plugin-minify-numeric-literals-0.0.1.tgz#9597e6c31154d7daf3744d0bd417c144b275bd53" +babel-plugin-minify-numeric-literals@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/babel-plugin-minify-numeric-literals/-/babel-plugin-minify-numeric-literals-0.1.1.tgz#d4b8b0c925f874714ee33ee4b26678583d7ce7fb" -babel-plugin-minify-replace@^0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/babel-plugin-minify-replace/-/babel-plugin-minify-replace-0.0.1.tgz#5d5aea7cb9899245248d1ee9ce7a2fe556a8facc" +babel-plugin-minify-replace@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/babel-plugin-minify-replace/-/babel-plugin-minify-replace-0.1.2.tgz#b90b9e71ab4d3b36325629a91beabe13b0b16ac1" -babel-plugin-minify-simplify@^0.0.8: - version "0.0.8" - resolved "https://registry.yarnpkg.com/babel-plugin-minify-simplify/-/babel-plugin-minify-simplify-0.0.8.tgz#597b23327bba4373fed1c51461a689bce9ff4979" +babel-plugin-minify-simplify@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/babel-plugin-minify-simplify/-/babel-plugin-minify-simplify-0.1.2.tgz#a968f1658fdeb2fc759e81fe331d89829df0f6b9" dependencies: - babel-helper-flip-expressions "^0.0.2" + babel-helper-flip-expressions "^0.1.2" babel-helper-is-nodes-equiv "^0.0.1" - babel-helper-to-multiple-sequence-expressions "^0.0.4" + babel-helper-to-multiple-sequence-expressions "^0.1.1" -babel-plugin-minify-type-constructors@^0.0.4: - version "0.0.4" - resolved "https://registry.yarnpkg.com/babel-plugin-minify-type-constructors/-/babel-plugin-minify-type-constructors-0.0.4.tgz#52d8b623775107523227719ade2d0b7458758b5f" +babel-plugin-minify-type-constructors@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/babel-plugin-minify-type-constructors/-/babel-plugin-minify-type-constructors-0.1.2.tgz#db53c5b76cb8e2fcd45d862f17104c78761337ee" dependencies: - babel-helper-is-void-0 "^0.0.1" + babel-helper-is-void-0 "^0.1.1" babel-plugin-syntax-async-functions@^6.8.0: version "6.13.0" @@ -776,23 +793,23 @@ babel-plugin-transform-exponentiation-operator@^6.22.0, babel-plugin-transform-e babel-plugin-syntax-exponentiation-operator "^6.8.0" babel-runtime "^6.22.0" -babel-plugin-transform-inline-consecutive-adds@^0.0.2: - version "0.0.2" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-inline-consecutive-adds/-/babel-plugin-transform-inline-consecutive-adds-0.0.2.tgz#a58fcecfc09c08fbf9373a5a3e70746c03d01fc1" +babel-plugin-transform-inline-consecutive-adds@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-inline-consecutive-adds/-/babel-plugin-transform-inline-consecutive-adds-0.1.2.tgz#5442e9f1c19c78a7899f8a4dee6fd481f61001f5" -babel-plugin-transform-member-expression-literals@^6.8.1: +babel-plugin-transform-member-expression-literals@^6.8.4: version "6.8.4" resolved "https://registry.yarnpkg.com/babel-plugin-transform-member-expression-literals/-/babel-plugin-transform-member-expression-literals-6.8.4.tgz#05679bc40596b91293401959aa1620ab1b2be437" -babel-plugin-transform-merge-sibling-variables@^6.8.2: +babel-plugin-transform-merge-sibling-variables@^6.8.5: version "6.8.5" resolved "https://registry.yarnpkg.com/babel-plugin-transform-merge-sibling-variables/-/babel-plugin-transform-merge-sibling-variables-6.8.5.tgz#03abdf107c61241913eb268ddede6d5bc541862c" -babel-plugin-transform-minify-booleans@^6.8.0: +babel-plugin-transform-minify-booleans@^6.8.2: version "6.8.2" resolved "https://registry.yarnpkg.com/babel-plugin-transform-minify-booleans/-/babel-plugin-transform-minify-booleans-6.8.2.tgz#8451579f706e702c1e1ab2756de5c8ea369cf07c" -babel-plugin-transform-property-literals@^6.8.1: +babel-plugin-transform-property-literals@^6.8.4: version "6.8.4" resolved "https://registry.yarnpkg.com/babel-plugin-transform-property-literals/-/babel-plugin-transform-property-literals-6.8.4.tgz#6ad311110b80a192a56efb5ddf4fe3ca6f7a61da" dependencies: @@ -804,23 +821,23 @@ babel-plugin-transform-regenerator@^6.22.0: dependencies: regenerator-transform "0.9.11" -babel-plugin-transform-regexp-constructors@^0.0.6: - version "0.0.6" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-regexp-constructors/-/babel-plugin-transform-regexp-constructors-0.0.6.tgz#0d92607f0d26268296980cb7c1dea5f2dd3e1e20" +babel-plugin-transform-regexp-constructors@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-regexp-constructors/-/babel-plugin-transform-regexp-constructors-0.1.1.tgz#312ab7487cc88a1c62ee25ea1b6087e89b87799c" -babel-plugin-transform-remove-console@^6.8.1: +babel-plugin-transform-remove-console@^6.8.4: version "6.8.4" resolved "https://registry.yarnpkg.com/babel-plugin-transform-remove-console/-/babel-plugin-transform-remove-console-6.8.4.tgz#41fddac19a729a4c3dd7ef2964eac07b096f9a8f" -babel-plugin-transform-remove-debugger@^6.8.1: +babel-plugin-transform-remove-debugger@^6.8.4: version "6.8.4" resolved "https://registry.yarnpkg.com/babel-plugin-transform-remove-debugger/-/babel-plugin-transform-remove-debugger-6.8.4.tgz#f85704a08adaa71b55d77005b5b94e9b9df21f6e" -babel-plugin-transform-remove-undefined@^0.0.5: - version "0.0.5" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-remove-undefined/-/babel-plugin-transform-remove-undefined-0.0.5.tgz#12ef11805e06e861dd2eb0c7cc041d2184b8f410" +babel-plugin-transform-remove-undefined@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-remove-undefined/-/babel-plugin-transform-remove-undefined-0.1.2.tgz#e1ebf51110f6b1e0665f28382ef73f95e5023652" -babel-plugin-transform-simplify-comparison-operators@^6.8.1: +babel-plugin-transform-simplify-comparison-operators@^6.8.4: version "6.8.4" resolved "https://registry.yarnpkg.com/babel-plugin-transform-simplify-comparison-operators/-/babel-plugin-transform-simplify-comparison-operators-6.8.4.tgz#2aa24a262d664c8cb3e125a306c798d7a2de08d5" @@ -831,41 +848,41 @@ babel-plugin-transform-strict-mode@^6.24.1: babel-runtime "^6.22.0" babel-types "^6.24.1" -babel-plugin-transform-undefined-to-void@^6.8.0: +babel-plugin-transform-undefined-to-void@^6.8.2: version "6.8.2" resolved "https://registry.yarnpkg.com/babel-plugin-transform-undefined-to-void/-/babel-plugin-transform-undefined-to-void-6.8.2.tgz#fe2b1d294eb05e87524eb93724dea6e2c3d66fa1" -babel-preset-babili@^0.0.12: - version "0.0.12" - resolved "https://registry.yarnpkg.com/babel-preset-babili/-/babel-preset-babili-0.0.12.tgz#74d79205d54feae6470bc84231da0b9ac9fc7de9" - dependencies: - babel-plugin-minify-builtins "^0.0.2" - babel-plugin-minify-constant-folding "^0.0.4" - babel-plugin-minify-dead-code-elimination "^0.1.4" - babel-plugin-minify-flip-comparisons "^0.0.2" - babel-plugin-minify-guarded-expressions "^0.0.4" - babel-plugin-minify-infinity "^0.0.3" - babel-plugin-minify-mangle-names "^0.0.8" - babel-plugin-minify-numeric-literals "^0.0.1" - babel-plugin-minify-replace "^0.0.1" - babel-plugin-minify-simplify "^0.0.8" - babel-plugin-minify-type-constructors "^0.0.4" - babel-plugin-transform-inline-consecutive-adds "^0.0.2" - babel-plugin-transform-member-expression-literals "^6.8.1" - babel-plugin-transform-merge-sibling-variables "^6.8.2" - babel-plugin-transform-minify-booleans "^6.8.0" - babel-plugin-transform-property-literals "^6.8.1" - babel-plugin-transform-regexp-constructors "^0.0.6" - babel-plugin-transform-remove-console "^6.8.1" - babel-plugin-transform-remove-debugger "^6.8.1" - babel-plugin-transform-remove-undefined "^0.0.5" - babel-plugin-transform-simplify-comparison-operators "^6.8.1" - babel-plugin-transform-undefined-to-void "^6.8.0" +babel-preset-babili@^0.1.2: + version "0.1.4" + resolved "https://registry.yarnpkg.com/babel-preset-babili/-/babel-preset-babili-0.1.4.tgz#ad9d6651002f5bc3f07cab300781167f54724bf2" + dependencies: + babel-plugin-minify-builtins "^0.1.3" + babel-plugin-minify-constant-folding "^0.1.3" + babel-plugin-minify-dead-code-elimination "^0.1.7" + babel-plugin-minify-flip-comparisons "^0.1.2" + babel-plugin-minify-guarded-expressions "^0.1.2" + babel-plugin-minify-infinity "^0.1.2" + babel-plugin-minify-mangle-names "^0.1.3" + babel-plugin-minify-numeric-literals "^0.1.1" + babel-plugin-minify-replace "^0.1.2" + babel-plugin-minify-simplify "^0.1.2" + babel-plugin-minify-type-constructors "^0.1.2" + babel-plugin-transform-inline-consecutive-adds "^0.1.2" + babel-plugin-transform-member-expression-literals "^6.8.4" + babel-plugin-transform-merge-sibling-variables "^6.8.5" + babel-plugin-transform-minify-booleans "^6.8.2" + babel-plugin-transform-property-literals "^6.8.4" + babel-plugin-transform-regexp-constructors "^0.1.1" + babel-plugin-transform-remove-console "^6.8.4" + babel-plugin-transform-remove-debugger "^6.8.4" + babel-plugin-transform-remove-undefined "^0.1.2" + babel-plugin-transform-simplify-comparison-operators "^6.8.4" + babel-plugin-transform-undefined-to-void "^6.8.2" lodash.isplainobject "^4.0.6" -babel-preset-env@^1.3.2: - version "1.5.2" - resolved "https://registry.yarnpkg.com/babel-preset-env/-/babel-preset-env-1.5.2.tgz#cd4ae90a6e94b709f97374b33e5f8b983556adef" +babel-preset-env@^1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/babel-preset-env/-/babel-preset-env-1.6.0.tgz#2de1c782a780a0a5d605d199c957596da43c44e4" dependencies: babel-plugin-check-es2015-constants "^6.22.0" babel-plugin-syntax-trailing-function-commas "^6.22.0" @@ -950,7 +967,7 @@ babel-types@^6.18.0, babel-types@^6.19.0, babel-types@^6.24.1, babel-types@^6.25 lodash "^4.2.0" to-fast-properties "^1.0.1" -babylon@^6.1.0, babylon@^6.13.0, babylon@^6.17.2: +babylon@^6.1.0, babylon@^6.17.2, babylon@^6.17.4: version "6.17.4" resolved "https://registry.yarnpkg.com/babylon/-/babylon-6.17.4.tgz#3e8b7402b88d22c3423e137a1577883b15ff869a" @@ -1082,7 +1099,7 @@ camelcase@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-3.0.0.tgz#32fc4b9fcdaf845fcdf7e73bb97cac2261f0ab0a" -camelcase@^4.0.0: +camelcase@^4.0.0, camelcase@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-4.1.0.tgz#d545635be1e33c542649c69173e5de6acfae34dd" @@ -1123,6 +1140,14 @@ chalk@^1.0.0, chalk@^1.1.0, chalk@^1.1.1, chalk@^1.1.3: strip-ansi "^3.0.0" supports-color "^2.0.0" +chalk@^2.0.0, chalk@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.0.1.tgz#dbec49436d2ae15f536114e76d14656cdbc0f44d" + dependencies: + ansi-styles "^3.1.0" + escape-string-regexp "^1.0.5" + supports-color "^4.0.0" + chokidar@^1.4.2: version "1.7.0" resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-1.7.0.tgz#798e689778151c8076b4b360e5edd28cda2bb468" @@ -1158,12 +1183,6 @@ cli-boxes@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/cli-boxes/-/cli-boxes-1.0.0.tgz#4fa917c3e59c94a004cd61f8ee509da651687143" -cli-cursor@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-1.0.2.tgz#64da3f7d56a54412e59794bd62dc35295e8f2987" - dependencies: - restore-cursor "^1.0.1" - cli-cursor@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-2.1.0.tgz#b35dac376479facc3e94747d41d0d0f5238ffcb5" @@ -1249,7 +1268,7 @@ concat-map@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" -concat-stream@^1.5.2: +concat-stream@^1.6.0: version "1.6.0" resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.0.tgz#0aac662fd52be78964d5532f694784e70110acf7" dependencies: @@ -1257,6 +1276,22 @@ concat-stream@^1.5.2: readable-stream "^2.2.2" typedarray "^0.0.6" +concordance@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/concordance/-/concordance-3.0.0.tgz#b2286af54405fc995fc7345b0b106d8dd073cb29" + dependencies: + date-time "^2.1.0" + esutils "^2.0.2" + fast-diff "^1.1.1" + function-name-support "^0.2.0" + js-string-escape "^1.0.1" + lodash.clonedeep "^4.5.0" + lodash.flattendeep "^4.4.0" + lodash.merge "^4.6.0" + md5-hex "^2.0.0" + semver "^5.3.0" + well-known-symbols "^1.0.0" + configstore@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/configstore/-/configstore-3.1.0.tgz#45df907073e26dfa1cf4b2d52f5b60545eaa11d1" @@ -1335,12 +1370,6 @@ currently-unhandled@^0.4.1: dependencies: array-find-index "^1.0.1" -d@1: - version "1.0.0" - resolved "https://registry.yarnpkg.com/d/-/d-1.0.0.tgz#754bb5bfe55451da69a58b94d45f4c5b0462d58f" - dependencies: - es5-ext "^0.10.9" - dashdash@^1.12.0: version "1.14.1" resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0" @@ -1351,6 +1380,12 @@ date-time@^0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/date-time/-/date-time-0.1.1.tgz#ed2f6d93d9790ce2fd66d5b5ff3edd5bbcbf3b07" +date-time@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/date-time/-/date-time-2.1.0.tgz#0286d1b4c769633b3ca13e1e62558d2dbdc2eba2" + dependencies: + time-zone "^1.0.0" + debug-log@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/debug-log/-/debug-log-1.0.1.tgz#2307632d4c04382b8df8a32f70b895046d52745f" @@ -1413,13 +1448,9 @@ detect-indent@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-5.0.0.tgz#3871cc0a6a002e8c3e5b3cf7f336264675f06b9d" -diff-match-patch@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/diff-match-patch/-/diff-match-patch-1.0.0.tgz#1cc3c83a490d67f95d91e39f6ad1f2e086b63048" - -diff@^3.0.0, diff@^3.0.1: - version "3.2.0" - resolved "https://registry.yarnpkg.com/diff/-/diff-3.2.0.tgz#c9ce393a4b7cbd0b058a725c93df299027868ff9" +diff@^3.1.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/diff/-/diff-3.3.0.tgz#056695150d7aa93237ca7e378ac3b1682b7963b9" doctrine@1.5.0: version "1.5.0" @@ -1466,7 +1497,7 @@ equal-length@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/equal-length/-/equal-length-1.0.1.tgz#21ca112d48ab24b4e1e7ffc0e5339d31fdfc274c" -erlang-types@^1.0.0, erlang-types@^1.0.1: +erlang-types@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/erlang-types/-/erlang-types-1.0.1.tgz#943a57a9324e0d0edc0273690a8c702686d9b780" @@ -1476,148 +1507,91 @@ error-ex@^1.2.0: dependencies: is-arrayish "^0.2.1" -es5-ext@^0.10.14, es5-ext@^0.10.9, es5-ext@~0.10.14: - version "0.10.23" - resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.23.tgz#7578b51be974207a5487821b56538c224e4e7b38" - dependencies: - es6-iterator "2" - es6-symbol "~3.1" - es6-error@^4.0.1, es6-error@^4.0.2: version "4.0.2" resolved "https://registry.yarnpkg.com/es6-error/-/es6-error-4.0.2.tgz#eec5c726eacef51b7f6b73c20db6e1b13b069c98" -es6-iterator@2, es6-iterator@^2.0.1, es6-iterator@~2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/es6-iterator/-/es6-iterator-2.0.1.tgz#8e319c9f0453bf575d374940a655920e59ca5512" - dependencies: - d "1" - es5-ext "^0.10.14" - es6-symbol "^3.1" - -es6-map@^0.1.3: - version "0.1.5" - resolved "https://registry.yarnpkg.com/es6-map/-/es6-map-0.1.5.tgz#9136e0503dcc06a301690f0bb14ff4e364e949f0" - dependencies: - d "1" - es5-ext "~0.10.14" - es6-iterator "~2.0.1" - es6-set "~0.1.5" - es6-symbol "~3.1.1" - event-emitter "~0.3.5" - -es6-set@~0.1.5: - version "0.1.5" - resolved "https://registry.yarnpkg.com/es6-set/-/es6-set-0.1.5.tgz#d2b3ec5d4d800ced818db538d28974db0a73ccb1" - dependencies: - d "1" - es5-ext "~0.10.14" - es6-iterator "~2.0.1" - es6-symbol "3.1.1" - event-emitter "~0.3.5" - -es6-symbol@3.1.1, es6-symbol@^3.1, es6-symbol@^3.1.1, es6-symbol@~3.1, es6-symbol@~3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/es6-symbol/-/es6-symbol-3.1.1.tgz#bf00ef4fdab6ba1b46ecb7b629b4c7ed5715cc77" - dependencies: - d "1" - es5-ext "~0.10.14" - -es6-weak-map@^2.0.1: - version "2.0.2" - resolved "https://registry.yarnpkg.com/es6-weak-map/-/es6-weak-map-2.0.2.tgz#5e3ab32251ffd1538a1f8e5ffa1357772f92d96f" - dependencies: - d "1" - es5-ext "^0.10.14" - es6-iterator "^2.0.1" - es6-symbol "^3.1.1" - escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.4, escape-string-regexp@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" -escope@^3.6.0: - version "3.6.0" - resolved "https://registry.yarnpkg.com/escope/-/escope-3.6.0.tgz#e01975e812781a163a6dadfdd80398dc64c889c3" - dependencies: - es6-map "^0.1.3" - es6-weak-map "^2.0.1" - esrecurse "^4.1.0" - estraverse "^4.1.1" - eslint-config-airbnb-base@^11.1.0: version "11.2.0" resolved "https://registry.yarnpkg.com/eslint-config-airbnb-base/-/eslint-config-airbnb-base-11.2.0.tgz#19a9dc4481a26f70904545ec040116876018f853" -eslint-import-resolver-node@^0.2.0: - version "0.2.3" - resolved "https://registry.yarnpkg.com/eslint-import-resolver-node/-/eslint-import-resolver-node-0.2.3.tgz#5add8106e8c928db2cba232bcd9efa846e3da16c" +eslint-import-resolver-node@^0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.1.tgz#4422574cde66a9a7b099938ee4d508a199e0e3cc" dependencies: - debug "^2.2.0" - object-assign "^4.0.1" - resolve "^1.1.6" + debug "^2.6.8" + resolve "^1.2.0" -eslint-module-utils@^2.0.0: +eslint-module-utils@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.1.1.tgz#abaec824177613b8a95b299639e1b6facf473449" dependencies: debug "^2.6.8" pkg-dir "^1.0.0" -eslint-plugin-import@^2.2.0: - version "2.5.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.5.0.tgz#293b5ea7910a901a05a47ccdd7546e611725406c" +eslint-plugin-import@^2.7.0: + version "2.7.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.7.0.tgz#21de33380b9efb55f5ef6d2e210ec0e07e7fa69f" dependencies: builtin-modules "^1.1.1" contains-path "^0.1.0" debug "^2.6.8" doctrine "1.5.0" - eslint-import-resolver-node "^0.2.0" - eslint-module-utils "^2.0.0" + eslint-import-resolver-node "^0.3.1" + eslint-module-utils "^2.1.1" has "^1.0.1" lodash.cond "^4.3.0" minimatch "^3.0.3" read-pkg-up "^2.0.0" -eslint@^3.15.0: - version "3.19.0" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-3.19.0.tgz#c8fc6201c7f40dd08941b87c085767386a679acc" +eslint-scope@^3.7.1: + version "3.7.1" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-3.7.1.tgz#3d63c3edfda02e06e01a452ad88caacc7cdcb6e8" dependencies: - babel-code-frame "^6.16.0" + esrecurse "^4.1.0" + estraverse "^4.1.1" + +eslint@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-4.2.0.tgz#a2b3184111b198e02e9c7f3cca625a5e01c56b3d" + dependencies: + ajv "^5.2.0" + babel-code-frame "^6.22.0" chalk "^1.1.3" - concat-stream "^1.5.2" - debug "^2.1.1" + concat-stream "^1.6.0" + debug "^2.6.8" doctrine "^2.0.0" - escope "^3.6.0" - espree "^3.4.0" + eslint-scope "^3.7.1" + espree "^3.4.3" esquery "^1.0.0" estraverse "^4.2.0" esutils "^2.0.2" file-entry-cache "^2.0.0" - glob "^7.0.3" - globals "^9.14.0" - ignore "^3.2.0" + glob "^7.1.2" + globals "^9.17.0" + ignore "^3.3.3" imurmurhash "^0.1.4" - inquirer "^0.12.0" - is-my-json-valid "^2.10.0" + inquirer "^3.0.6" is-resolvable "^1.0.0" - js-yaml "^3.5.1" - json-stable-stringify "^1.0.0" + js-yaml "^3.8.4" + json-stable-stringify "^1.0.1" levn "^0.3.0" - lodash "^4.0.0" - mkdirp "^0.5.0" + lodash "^4.17.4" + minimatch "^3.0.2" + mkdirp "^0.5.1" natural-compare "^1.4.0" optionator "^0.8.2" - path-is-inside "^1.0.1" - pluralize "^1.2.1" - progress "^1.1.8" - require-uncached "^1.0.2" - shelljs "^0.7.5" - strip-bom "^3.0.0" + path-is-inside "^1.0.2" + pluralize "^4.0.0" + progress "^2.0.0" + require-uncached "^1.0.3" strip-json-comments "~2.0.1" - table "^3.7.8" + table "^4.0.1" text-table "~0.2.0" - user-home "^2.0.0" espower-location-detector@^1.0.0: version "1.0.0" @@ -1628,7 +1602,7 @@ espower-location-detector@^1.0.0: source-map "^0.5.0" xtend "^4.0.0" -espree@^3.4.0: +espree@^3.4.3: version "3.4.3" resolved "https://registry.yarnpkg.com/espree/-/espree-3.4.3.tgz#2910b5ccd49ce893c2ffffaab4fd8b3a31b82374" dependencies: @@ -1670,13 +1644,6 @@ esutils@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.2.tgz#0abf4f1caa5bcb1f7a9d8acc6dea4faaa04bac9b" -event-emitter@~0.3.5: - version "0.3.5" - resolved "https://registry.yarnpkg.com/event-emitter/-/event-emitter-0.3.5.tgz#df8c69eef1647923c7157b9ce83840610b02cc39" - dependencies: - d "1" - es5-ext "~0.10.14" - execa@^0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/execa/-/execa-0.4.0.tgz#4eb6467a36a095fabb2970ff9d5e3fb7bce6ebc3" @@ -1700,10 +1667,6 @@ execa@^0.5.0: signal-exit "^3.0.0" strip-eof "^1.0.0" -exit-hook@^1.0.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/exit-hook/-/exit-hook-1.1.1.tgz#f05ca233b48c05d54fff07765df8507e95c02ff8" - expand-brackets@^0.1.4: version "0.1.5" resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-0.1.5.tgz#df07284e342a807cd733ac5af72411e581d1177b" @@ -1720,6 +1683,14 @@ extend@~3.0.0: version "3.0.1" resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.1.tgz#a755ea7bc1adfcc5a31ce7e762dbaadc5e636444" +external-editor@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-2.0.4.tgz#1ed9199da9cbfe2ef2f7a31b2fde8b0d12368972" + dependencies: + iconv-lite "^0.4.17" + jschardet "^1.4.2" + tmp "^0.0.31" + extglob@^0.3.1: version "0.3.2" resolved "https://registry.yarnpkg.com/extglob/-/extglob-0.3.2.tgz#2e18ff3d2f49ab2765cec9023f011daa8d8349a1" @@ -1730,17 +1701,18 @@ extsprintf@1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.0.2.tgz#e1080e0658e300b06294990cc70e1502235fd550" +fast-deep-equal@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-1.0.0.tgz#96256a3bc975595eb36d82e9929d060d893439ff" + +fast-diff@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/fast-diff/-/fast-diff-1.1.1.tgz#0aea0e4e605b6a2189f0e936d4b7fbaf1b7cfd9b" + fast-levenshtein@~2.0.4: version "2.0.6" resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" -figures@^1.3.5: - version "1.7.0" - resolved "https://registry.yarnpkg.com/figures/-/figures-1.7.0.tgz#cbe1e3affcf1cd44b80cadfed28dc793a9701d2e" - dependencies: - escape-string-regexp "^1.0.5" - object-assign "^4.1.0" - figures@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/figures/-/figures-2.0.0.tgz#3ab1a2d2a62c8bfb431a0c94cb797a2fce27c962" @@ -1776,7 +1748,15 @@ find-cache-dir@^0.1.1: mkdirp "^0.5.1" pkg-dir "^1.0.0" -find-up@^1.0.0, find-up@^1.1.2: +find-cache-dir@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-1.0.0.tgz#9288e3e9e3cc3748717d39eade17cf71fc30ee6f" + dependencies: + commondir "^1.0.1" + make-dir "^1.0.0" + pkg-dir "^2.0.0" + +find-up@^1.0.0: version "1.1.2" resolved "https://registry.yarnpkg.com/find-up/-/find-up-1.1.2.tgz#6b2e9822b1a2ce0a60ab64d610eccad53cb24d0f" dependencies: @@ -1812,7 +1792,7 @@ for-own@^0.1.4: dependencies: for-in "^1.0.1" -foreground-child@^1.3.3, foreground-child@^1.5.3: +foreground-child@^1.5.3, foreground-child@^1.5.6: version "1.5.6" resolved "https://registry.yarnpkg.com/foreground-child/-/foreground-child-1.5.6.tgz#4fd71ad2dfde96789b980a5c0a295937cb2f5ce9" dependencies: @@ -1831,11 +1811,11 @@ form-data@~2.1.1: combined-stream "^1.0.5" mime-types "^2.1.12" -formatio@1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/formatio/-/formatio-1.1.1.tgz#5ed3ccd636551097383465d996199100e86161e9" +formatio@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/formatio/-/formatio-1.2.0.tgz#f3b2167d9068c4698a8d51f4f760a39a54d818eb" dependencies: - samsam "~1.1" + samsam "1.x" fs.realpath@^1.0.0: version "1.0.0" @@ -1869,6 +1849,10 @@ function-bind@^1.0.2: version "1.1.0" resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.0.tgz#16176714c801798e4e8f2cf7f7529467bb4a5771" +function-name-support@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/function-name-support/-/function-name-support-0.2.0.tgz#55d3bfaa6eafd505a50f9bc81fdf57564a0bb071" + gauge@~2.7.3: version "2.7.4" resolved "https://registry.yarnpkg.com/gauge/-/gauge-2.7.4.tgz#2c03405c7538c39d7eb37b317022e325fb018bf7" @@ -1882,16 +1866,6 @@ gauge@~2.7.3: strip-ansi "^3.0.1" wide-align "^1.1.0" -generate-function@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/generate-function/-/generate-function-2.0.0.tgz#6858fe7c0969b7d4e9093337647ac79f60dfbe74" - -generate-object-property@^1.1.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/generate-object-property/-/generate-object-property-1.2.0.tgz#9c0e1c40308ce804f4783618b937fa88f99d50d0" - dependencies: - is-property "^1.0.0" - get-caller-file@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-1.0.2.tgz#f702e63127e7e231c160a80c1554acb70d5047e5" @@ -1934,7 +1908,7 @@ glob-parent@^2.0.0: dependencies: is-glob "^2.0.0" -glob@^7.0.0, glob@^7.0.3, glob@^7.0.5, glob@^7.0.6: +glob@^7.0.3, glob@^7.0.5, glob@^7.0.6, glob@^7.1.2: version "7.1.2" resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.2.tgz#c19c9df9a028702d678612384a6552404c636d15" dependencies: @@ -1945,7 +1919,7 @@ glob@^7.0.0, glob@^7.0.3, glob@^7.0.5, glob@^7.0.6: once "^1.3.0" path-is-absolute "^1.0.0" -globals@^9.0.0, globals@^9.14.0: +globals@^9.0.0, globals@^9.17.0: version "9.18.0" resolved "https://registry.yarnpkg.com/globals/-/globals-9.18.0.tgz#aa3896b3e69b487f17e31ed2143d69a8e30c2d8a" @@ -1986,7 +1960,7 @@ got@^6.7.1: unzip-response "^2.0.1" url-parse-lax "^1.0.0" -graceful-fs@^4.1.11, graceful-fs@^4.1.2, graceful-fs@^4.1.6: +graceful-fs@^4.1.11, graceful-fs@^4.1.2: version "4.1.11" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.11.tgz#0e8bdfe4d1ddb8854d64e04ea7c00e2a026e5658" @@ -2075,7 +2049,7 @@ http-signature@~1.1.0: jsprim "^1.2.2" sshpk "^1.7.0" -hullabaloo-config-manager@^1.0.0: +hullabaloo-config-manager@^1.1.0: version "1.1.1" resolved "https://registry.yarnpkg.com/hullabaloo-config-manager/-/hullabaloo-config-manager-1.1.1.tgz#1d9117813129ad035fd9e8477eaf066911269fe3" dependencies: @@ -2094,11 +2068,15 @@ hullabaloo-config-manager@^1.0.0: resolve-from "^3.0.0" safe-buffer "^5.0.1" +iconv-lite@^0.4.17: + version "0.4.18" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.18.tgz#23d8656b16aae6742ac29732ea8f0336a4789cf2" + ignore-by-default@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/ignore-by-default/-/ignore-by-default-1.0.1.tgz#48ca6d72f6c6a3af00a9ad4ae6876be3889e2b09" -ignore@^3.2.0: +ignore@^3.3.3: version "3.3.3" resolved "https://registry.yarnpkg.com/ignore/-/ignore-3.3.3.tgz#432352e57accd87ab3110e82d3fea0e47812156d" @@ -2106,6 +2084,13 @@ import-lazy@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/import-lazy/-/import-lazy-2.1.0.tgz#05698e3d45c88e8d7e9d92cb0584e77f096f3e43" +import-local@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/import-local/-/import-local-0.1.1.tgz#b1179572aacdc11c6a91009fb430dbcab5f668a8" + dependencies: + pkg-dir "^2.0.0" + resolve-cwd "^2.0.0" + imurmurhash@^0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" @@ -2131,36 +2116,29 @@ inherits@2, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.0, inherits@~2.0.3: version "2.0.3" resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" -inherits@2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.1.tgz#b17d08d326b4423e568eff719f91b0b1cbdf69f1" - ini@~1.3.0: version "1.3.4" resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.4.tgz#0537cb79daf59b59a1a517dff706c86ec039162e" -inquirer@^0.12.0: - version "0.12.0" - resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-0.12.0.tgz#1ef2bfd63504df0bc75785fff8c2c41df12f077e" +inquirer@^3.0.6: + version "3.2.0" + resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-3.2.0.tgz#45b44c2160c729d7578c54060b3eed94487bb42b" dependencies: - ansi-escapes "^1.1.0" - ansi-regex "^2.0.0" - chalk "^1.0.0" - cli-cursor "^1.0.1" + ansi-escapes "^2.0.0" + chalk "^2.0.0" + cli-cursor "^2.1.0" cli-width "^2.0.0" - figures "^1.3.5" + external-editor "^2.0.4" + figures "^2.0.0" lodash "^4.3.0" - readline2 "^1.0.1" - run-async "^0.1.0" - rx-lite "^3.1.2" - string-width "^1.0.1" - strip-ansi "^3.0.0" + mute-stream "0.0.7" + run-async "^2.2.0" + rx-lite "^4.0.8" + rx-lite-aggregates "^4.0.8" + string-width "^2.1.0" + strip-ansi "^4.0.0" through "^2.3.6" -interpret@^1.0.0: - version "1.0.3" - resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.0.3.tgz#cbc35c62eeee73f19ab7b10a801511401afc0f90" - invariant@^2.2.0, invariant@^2.2.2: version "2.2.2" resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.2.tgz#9e1f56ac0acdb6bf303306f338be3b204ae60360" @@ -2249,14 +2227,9 @@ is-glob@^2.0.0, is-glob@^2.0.1: dependencies: is-extglob "^1.0.0" -is-my-json-valid@^2.10.0: - version "2.16.0" - resolved "https://registry.yarnpkg.com/is-my-json-valid/-/is-my-json-valid-2.16.0.tgz#f079dd9bfdae65ee2038aae8acbc86ab109e3693" - dependencies: - generate-function "^2.0.0" - generate-object-property "^1.1.0" - jsonpointer "^4.0.0" - xtend "^4.0.0" +is-module@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-module/-/is-module-1.0.0.tgz#3258fb69f78c14d5b815d664336b4cffb6441591" is-npm@^1.0.0: version "1.0.0" @@ -2316,10 +2289,6 @@ is-promise@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/is-promise/-/is-promise-2.1.0.tgz#79a2a9ece7f096e80f36d2b2f3bc16c1ff4bf3fa" -is-property@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/is-property/-/is-property-1.0.2.tgz#57fe1c4e48474edd65b09911f26b1cd4095dda84" - is-redirect@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-redirect/-/is-redirect-1.0.0.tgz#1d03dded53bd8db0f30c26e4f95d36fc7c87dc24" @@ -2350,6 +2319,10 @@ is-utf8@^0.2.0, is-utf8@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/is-utf8/-/is-utf8-0.2.1.tgz#4b0da1442104d1b336340e80797e865cf39f7d72" +isarray@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf" + isarray@1.0.0, isarray@^1.0.0, isarray@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" @@ -2368,29 +2341,29 @@ isstream@~0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" -istanbul-lib-coverage@^1.1.0, istanbul-lib-coverage@^1.1.1: +istanbul-lib-coverage@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-1.1.1.tgz#73bfb998885299415c93d38a3e9adf784a77a9da" -istanbul-lib-hook@^1.0.6: +istanbul-lib-hook@^1.0.7: version "1.0.7" resolved "https://registry.yarnpkg.com/istanbul-lib-hook/-/istanbul-lib-hook-1.0.7.tgz#dd6607f03076578fe7d6f2a630cf143b49bacddc" dependencies: append-transform "^0.4.0" -istanbul-lib-instrument@^1.7.1: - version "1.7.2" - resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-1.7.2.tgz#6014b03d3470fb77638d5802508c255c06312e56" +istanbul-lib-instrument@^1.7.3: + version "1.7.4" + resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-1.7.4.tgz#e9fd920e4767f3d19edc765e2d6b3f5ccbd0eea8" dependencies: babel-generator "^6.18.0" babel-template "^6.16.0" babel-traverse "^6.18.0" babel-types "^6.18.0" - babylon "^6.13.0" + babylon "^6.17.4" istanbul-lib-coverage "^1.1.1" semver "^5.3.0" -istanbul-lib-report@^1.1.0: +istanbul-lib-report@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/istanbul-lib-report/-/istanbul-lib-report-1.1.1.tgz#f0e55f56655ffa34222080b7a0cd4760e1405fc9" dependencies: @@ -2399,7 +2372,7 @@ istanbul-lib-report@^1.1.0: path-parse "^1.0.5" supports-color "^3.1.2" -istanbul-lib-source-maps@^1.2.0: +istanbul-lib-source-maps@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/istanbul-lib-source-maps/-/istanbul-lib-source-maps-1.2.1.tgz#a6fe1acba8ce08eebc638e572e294d267008aa0c" dependencies: @@ -2409,82 +2382,21 @@ istanbul-lib-source-maps@^1.2.0: rimraf "^2.6.1" source-map "^0.5.3" -istanbul-reports@^1.1.0: +istanbul-reports@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-1.1.1.tgz#042be5c89e175bc3f86523caab29c014e77fee4e" dependencies: handlebars "^4.0.3" -jest-diff@19.0.0, jest-diff@^19.0.0: - version "19.0.0" - resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-19.0.0.tgz#d1563cfc56c8b60232988fbc05d4d16ed90f063c" - dependencies: - chalk "^1.1.3" - diff "^3.0.0" - jest-matcher-utils "^19.0.0" - pretty-format "^19.0.0" - -jest-file-exists@^19.0.0: - version "19.0.0" - resolved "https://registry.yarnpkg.com/jest-file-exists/-/jest-file-exists-19.0.0.tgz#cca2e587a11ec92e24cfeab3f8a94d657f3fceb8" - -jest-matcher-utils@^19.0.0: - version "19.0.0" - resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-19.0.0.tgz#5ecd9b63565d2b001f61fbf7ec4c7f537964564d" - dependencies: - chalk "^1.1.3" - pretty-format "^19.0.0" - -jest-message-util@^19.0.0: - version "19.0.0" - resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-19.0.0.tgz#721796b89c0e4d761606f9ba8cb828a3b6246416" - dependencies: - chalk "^1.1.1" - micromatch "^2.3.11" - -jest-mock@^19.0.0: - version "19.0.0" - resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-19.0.0.tgz#67038641e9607ab2ce08ec4a8cb83aabbc899d01" - -jest-snapshot@19.0.2: - version "19.0.2" - resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-19.0.2.tgz#9c1b216214f7187c38bfd5c70b1efab16b0ff50b" - dependencies: - chalk "^1.1.3" - jest-diff "^19.0.0" - jest-file-exists "^19.0.0" - jest-matcher-utils "^19.0.0" - jest-util "^19.0.2" - natural-compare "^1.4.0" - pretty-format "^19.0.0" - -jest-util@^19.0.2: - version "19.0.2" - resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-19.0.2.tgz#e0a0232a2ab9e6b2b53668bdb3534c2b5977ed41" - dependencies: - chalk "^1.1.1" - graceful-fs "^4.1.6" - jest-file-exists "^19.0.0" - jest-message-util "^19.0.0" - jest-mock "^19.0.0" - jest-validate "^19.0.2" - leven "^2.0.0" - mkdirp "^0.5.1" - -jest-validate@^19.0.2: - version "19.0.2" - resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-19.0.2.tgz#dc534df5f1278d5b63df32b14241d4dbf7244c0c" - dependencies: - chalk "^1.1.1" - jest-matcher-utils "^19.0.0" - leven "^2.0.0" - pretty-format "^19.0.0" +js-string-escape@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/js-string-escape/-/js-string-escape-1.0.1.tgz#e2625badbc0d67c7533e9edc1068c587ae4137ef" js-tokens@^3.0.0: version "3.0.1" resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.1.tgz#08e9f132484a2c45a30907e9dc4d5567b7f114d7" -js-yaml@^3.5.1, js-yaml@^3.8.2: +js-yaml@^3.8.2, js-yaml@^3.8.4: version "3.8.4" resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.8.4.tgz#520b4564f86573ba96662af85a8cafa7b4b5a6f6" dependencies: @@ -2495,23 +2407,27 @@ jsbn@~0.1.0: version "0.1.1" resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" +jschardet@^1.4.2: + version "1.5.0" + resolved "https://registry.yarnpkg.com/jschardet/-/jschardet-1.5.0.tgz#a61f310306a5a71188e1b1acd08add3cfbb08b1e" + jsesc@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-1.3.0.tgz#46c3fec8c1892b12b0833db9bc7622176dbab34b" -jsesc@^2.4.0: - version "2.5.1" - resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.1.tgz#e421a2a8e20d6b0819df28908f782526b96dd1fe" - jsesc@~0.5.0: version "0.5.0" resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-0.5.0.tgz#e7dee66e35d6fc16f710fe91d5cf69f70f08911d" +json-schema-traverse@^0.3.0: + version "0.3.1" + resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz#349a6d44c53a51de89b40805c5d5e59b417d3340" + json-schema@0.2.3: version "0.2.3" resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13" -json-stable-stringify@^1.0.0, json-stable-stringify@^1.0.1: +json-stable-stringify@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz#9a759d39c5f2ff503fd5300646ed445f88c4f9af" dependencies: @@ -2529,10 +2445,6 @@ jsonify@~0.0.0: version "0.0.0" resolved "https://registry.yarnpkg.com/jsonify/-/jsonify-0.0.0.tgz#2c74b6ee41d93ca51b7b5aaee8f503631d252a73" -jsonpointer@^4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/jsonpointer/-/jsonpointer-4.0.1.tgz#4fd92cb34e0e9db3c89c8622ecf51f9b978c6cb9" - jsprim@^1.2.2: version "1.4.0" resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.0.tgz#a3b87e40298d8c380552d8cc7628a0bb95a22918" @@ -2576,10 +2488,6 @@ lcid@^1.0.0: dependencies: invert-kv "^1.0.0" -leven@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/leven/-/leven-2.1.0.tgz#c2e7a9f772094dee9d34202ae8acce4687875580" - levn@^0.3.0, levn@~0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee" @@ -2657,13 +2565,13 @@ lodash.some@^4.6.0: version "4.6.0" resolved "https://registry.yarnpkg.com/lodash.some/-/lodash.some-4.6.0.tgz#1bb9f314ef6b8baded13b549169b2a945eb68e4d" -lodash@^4.0.0, lodash@^4.2.0, lodash@^4.3.0: +lodash@^4.0.0, lodash@^4.17.4, lodash@^4.2.0, lodash@^4.3.0: version "4.17.4" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.4.tgz#78203a4d1c328ae1d86dca6460e369b57f4055ae" -lolex@1.3.2: - version "1.3.2" - resolved "https://registry.yarnpkg.com/lolex/-/lolex-1.3.2.tgz#7c3da62ffcb30f0f5a80a2566ca24e45d8a01f31" +lolex@^1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/lolex/-/lolex-1.6.0.tgz#3a9a0283452a47d7439e72731b9e07d7386e49f6" longest@^1.0.1: version "1.0.1" @@ -2703,9 +2611,9 @@ map-obj@^1.0.0, map-obj@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/map-obj/-/map-obj-1.0.1.tgz#d933ceb9205d82bdcf4886f6742bdc2b4dea146d" -matcher@^0.1.1: - version "0.1.2" - resolved "https://registry.yarnpkg.com/matcher/-/matcher-0.1.2.tgz#ef20cbde64c24c50cc61af5b83ee0b1b8ff00101" +matcher@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/matcher/-/matcher-1.0.0.tgz#aaf0c4816eb69b92094674175625f3466b0e3e19" dependencies: escape-string-regexp "^1.0.4" @@ -2725,6 +2633,12 @@ md5-o-matic@^0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/md5-o-matic/-/md5-o-matic-0.1.1.tgz#822bccd65e117c514fab176b25945d54100a03c3" +mem@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/mem/-/mem-1.1.0.tgz#5edd52b485ca1d900fe64895505399a0dfa45f76" + dependencies: + mimic-fn "^1.0.0" + meow@^3.7.0: version "3.7.0" resolved "https://registry.yarnpkg.com/meow/-/meow-3.7.0.tgz#72cb668b425228290abbfa856892587308a801fb" @@ -2798,14 +2712,10 @@ minimist@^1.1.3, minimist@^1.2.0: dependencies: minimist "0.0.8" -ms@2.0.0: +ms@2.0.0, ms@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" -ms@^0.7.1: - version "0.7.3" - resolved "https://registry.yarnpkg.com/ms/-/ms-0.7.3.tgz#708155a5e44e33f5fd0fc53e81d0d40a91be1fff" - multimatch@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/multimatch/-/multimatch-2.1.0.tgz#9c7906a22fb4c02919e2f5f75161b4cdbd4b2a2b" @@ -2815,14 +2725,18 @@ multimatch@^2.1.0: arrify "^1.0.0" minimatch "^3.0.0" -mute-stream@0.0.5: - version "0.0.5" - resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.5.tgz#8fbfabb0a98a253d3184331f9e8deb7372fac6c0" +mute-stream@0.0.7: + version "0.0.7" + resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.7.tgz#3075ce93bc21b8fab43e1bc4da7e8115ed1e7bab" nan@^2.3.0: version "2.6.2" resolved "https://registry.yarnpkg.com/nan/-/nan-2.6.2.tgz#e4ff34e6c95fdfb5aecc08de6596f43605a7db45" +native-promise-only@^0.8.1: + version "0.8.1" + resolved "https://registry.yarnpkg.com/native-promise-only/-/native-promise-only-0.8.1.tgz#20a318c30cb45f71fe7adfbf7b21c99c1472ef11" + natural-compare@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" @@ -2888,9 +2802,9 @@ number-is-nan@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" -nyc@^10.3.2: - version "10.3.2" - resolved "https://registry.yarnpkg.com/nyc/-/nyc-10.3.2.tgz#f27f4d91f2a9db36c24f574ff5c6efff0233de46" +nyc@^11.0.3: + version "11.0.3" + resolved "https://registry.yarnpkg.com/nyc/-/nyc-11.0.3.tgz#0c28bc669a851621709bf7a08503034bee3812b6" dependencies: archy "^1.0.0" arrify "^1.0.1" @@ -2899,15 +2813,15 @@ nyc@^10.3.2: debug-log "^1.0.1" default-require-extensions "^1.0.0" find-cache-dir "^0.1.1" - find-up "^1.1.2" + find-up "^2.1.0" foreground-child "^1.5.3" glob "^7.0.6" - istanbul-lib-coverage "^1.1.0" - istanbul-lib-hook "^1.0.6" - istanbul-lib-instrument "^1.7.1" - istanbul-lib-report "^1.1.0" - istanbul-lib-source-maps "^1.2.0" - istanbul-reports "^1.1.0" + istanbul-lib-coverage "^1.1.1" + istanbul-lib-hook "^1.0.7" + istanbul-lib-instrument "^1.7.3" + istanbul-lib-report "^1.1.1" + istanbul-lib-source-maps "^1.2.1" + istanbul-reports "^1.1.1" md5-hex "^1.2.0" merge-source-map "^1.0.2" micromatch "^2.3.11" @@ -2915,9 +2829,9 @@ nyc@^10.3.2: resolve-from "^2.0.0" rimraf "^2.5.4" signal-exit "^3.0.1" - spawn-wrap "1.2.4" - test-exclude "^4.1.0" - yargs "^7.1.0" + spawn-wrap "^1.3.7" + test-exclude "^4.1.1" + yargs "^8.0.1" yargs-parser "^5.0.0" oauth-sign@~0.8.1: @@ -2948,10 +2862,6 @@ once@^1.3.0, once@^1.3.3: dependencies: wrappy "1" -onetime@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/onetime/-/onetime-1.1.0.tgz#a1f7838f8314c516f05ecefcbc4ccfe04b4ed789" - onetime@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/onetime/-/onetime-2.0.1.tgz#067428230fd67443b2794b22bba528b6867962d4" @@ -2965,11 +2875,9 @@ optimist@^0.6.1: minimist "~0.0.1" wordwrap "~0.0.2" -option-chain@^0.1.0: - version "0.1.1" - resolved "https://registry.yarnpkg.com/option-chain/-/option-chain-0.1.1.tgz#e9b811e006f1c0f54802f28295bfc8970f8dcfbd" - dependencies: - object-assign "^4.0.1" +option-chain@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/option-chain/-/option-chain-1.0.0.tgz#938d73bd4e1783f948d34023644ada23669e30f2" optionator@^0.8.2: version "0.8.2" @@ -2986,13 +2894,15 @@ os-homedir@^1.0.0, os-homedir@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3" -os-locale@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-1.4.0.tgz#20f9f17ae29ed345e8bde583b13d2009803c14d9" +os-locale@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-2.0.0.tgz#15918ded510522b81ee7ae5a309d54f639fc39a4" dependencies: + execa "^0.5.0" lcid "^1.0.0" + mem "^1.1.0" -os-tmpdir@^1.0.0, os-tmpdir@^1.0.1: +os-tmpdir@^1.0.0, os-tmpdir@^1.0.1, os-tmpdir@~1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" @@ -3078,7 +2988,7 @@ path-is-absolute@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" -path-is-inside@^1.0.1: +path-is-inside@^1.0.1, path-is-inside@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/path-is-inside/-/path-is-inside-1.0.2.tgz#365417dede44430d1c11af61027facf074bdfc53" @@ -3094,6 +3004,12 @@ path-parse@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.5.tgz#3c1adf871ea9cd6c9431b6ea2bd74a0ff055c4c1" +path-to-regexp@^1.7.0: + version "1.7.0" + resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-1.7.0.tgz#59fde0f435badacba103a84e9d3bc64e96b9937d" + dependencies: + isarray "0.0.1" + path-type@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/path-type/-/path-type-1.1.0.tgz#59c44f7ee491da704da415da5a4070ba4f8fe441" @@ -3165,9 +3081,9 @@ plur@^2.0.0: dependencies: irregular-plurals "^1.0.0" -pluralize@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/pluralize/-/pluralize-1.2.1.tgz#d1a21483fd22bb41e58a12fa3421823140897c45" +pluralize@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/pluralize/-/pluralize-4.0.0.tgz#59b708c1c0190a2f692f1c7618c446b052fd1762" prelude-ls@~1.1.2: version "1.1.2" @@ -3181,12 +3097,6 @@ preserve@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/preserve/-/preserve-0.2.0.tgz#815ed1f6ebc65926f865b310c0713bcb3315ce4b" -pretty-format@^19.0.0: - version "19.0.0" - resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-19.0.0.tgz#56530d32acb98a3fa4851c4e2b9d37b420684c84" - dependencies: - ansi-styles "^3.0.0" - pretty-ms@^0.2.1: version "0.2.2" resolved "https://registry.yarnpkg.com/pretty-ms/-/pretty-ms-0.2.2.tgz#da879a682ff33a37011046f13d627f67c73b84f6" @@ -3209,9 +3119,9 @@ process-nextick-args@~1.0.6: version "1.0.7" resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-1.0.7.tgz#150e20b756590ad3f91093f25a4f2ad8bff30ba3" -progress@^1.1.8: - version "1.1.8" - resolved "https://registry.yarnpkg.com/progress/-/progress-1.1.8.tgz#e260c78f6161cdd9b0e56cc3e0a85de17c7a57be" +progress@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.0.tgz#8a1be366bf8fc23db2bd23f10c6fe920b4389d1f" pseudomap@^1.0.2: version "1.0.2" @@ -3292,20 +3202,6 @@ readdirp@^2.0.0: readable-stream "^2.0.2" set-immediate-shim "^1.0.1" -readline2@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/readline2/-/readline2-1.0.1.tgz#41059608ffc154757b715d9989d199ffbf372e35" - dependencies: - code-point-at "^1.0.0" - is-fullwidth-code-point "^1.0.0" - mute-stream "0.0.5" - -rechoir@^0.6.2: - version "0.6.2" - resolved "https://registry.yarnpkg.com/rechoir/-/rechoir-0.6.2.tgz#85204b54dba82d5742e28c96756ef43af50e3384" - dependencies: - resolve "^1.1.6" - redent@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/redent/-/redent-1.0.0.tgz#cf916ab1fd5f1f16dfb20822dd6ec7f730c2afde" @@ -3430,18 +3326,18 @@ require-precompiled@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/require-precompiled/-/require-precompiled-0.1.0.tgz#5a1b52eb70ebed43eb982e974c85ab59571e56fa" -require-uncached@^1.0.2: +require-uncached@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/require-uncached/-/require-uncached-1.0.3.tgz#4e0d56d6c9662fd31e43011c4b95aa49955421d3" dependencies: caller-path "^0.1.0" resolve-from "^1.0.0" -resolve-cwd@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-1.0.0.tgz#4eaeea41ed040d1702457df64a42b2b07d246f9f" +resolve-cwd@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-2.0.0.tgz#00a9f7387556e27038eae232caa372a6a59b665a" dependencies: - resolve-from "^2.0.0" + resolve-from "^3.0.0" resolve-from@^1.0.0: version "1.0.1" @@ -3459,19 +3355,12 @@ resolve@1.1.7: version "1.1.7" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.1.7.tgz#203114d82ad2c5ed9e8e0411b3932875e889e97b" -resolve@^1.1.6: +resolve@^1.1.6, resolve@^1.2.0: version "1.3.3" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.3.3.tgz#655907c3469a8680dc2de3a275a8fdd69691f0e5" dependencies: path-parse "^1.0.5" -restore-cursor@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-1.0.1.tgz#34661f46886327fed2991479152252df92daa541" - dependencies: - exit-hook "^1.0.0" - onetime "^1.0.0" - restore-cursor@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-2.0.0.tgz#9f7ee287f82fd326d4fd162923d62129eee0dfaf" @@ -3500,20 +3389,21 @@ rollup-plugin-babel@^2.7.1: object-assign "^4.1.0" rollup-pluginutils "^1.5.0" -rollup-plugin-babili@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/rollup-plugin-babili/-/rollup-plugin-babili-2.0.0.tgz#3695cb851c661af5f2834836c22ca0822ff9647b" +rollup-plugin-babili@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/rollup-plugin-babili/-/rollup-plugin-babili-3.1.0.tgz#27ada043a0ed021050a712528f68ed641888b5dc" dependencies: "@comandeer/babel-plugin-banner" "^1.0.0" babel-core "^6.21.0" - babel-preset-babili "^0.0.12" + babel-preset-babili "^0.1.2" -rollup-plugin-node-resolve@^2.0.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/rollup-plugin-node-resolve/-/rollup-plugin-node-resolve-2.1.1.tgz#cbb783b0d15b02794d58915350b2f0d902b8ddc8" +rollup-plugin-node-resolve@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/rollup-plugin-node-resolve/-/rollup-plugin-node-resolve-3.0.0.tgz#8b897c4c3030d5001277b0514b25d2ca09683ee0" dependencies: browser-resolve "^1.11.0" builtin-modules "^1.1.0" + is-module "^1.0.0" resolve "^1.1.6" rollup-pluginutils@^1.5.0: @@ -3523,29 +3413,35 @@ rollup-pluginutils@^1.5.0: estree-walker "^0.2.1" minimatch "^3.0.2" -rollup@^0.41.6: - version "0.41.6" - resolved "https://registry.yarnpkg.com/rollup/-/rollup-0.41.6.tgz#e0d05497877a398c104d816d2733a718a7a94e2a" +rollup@^0.45.2: + version "0.45.2" + resolved "https://registry.yarnpkg.com/rollup/-/rollup-0.45.2.tgz#63a284c2b31234656f24e9e9717fabb6a7f0fa43" dependencies: source-map-support "^0.4.0" -run-async@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/run-async/-/run-async-0.1.0.tgz#c8ad4a5e110661e402a7d21b530e009f25f8e389" +run-async@^2.2.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/run-async/-/run-async-2.3.0.tgz#0371ab4ae0bdd720d4166d7dfda64ff7a445a6c0" dependencies: - once "^1.3.0" + is-promise "^2.1.0" + +rx-lite-aggregates@^4.0.8: + version "4.0.8" + resolved "https://registry.yarnpkg.com/rx-lite-aggregates/-/rx-lite-aggregates-4.0.8.tgz#753b87a89a11c95467c4ac1626c4efc4e05c67be" + dependencies: + rx-lite "*" -rx-lite@^3.1.2: - version "3.1.2" - resolved "https://registry.yarnpkg.com/rx-lite/-/rx-lite-3.1.2.tgz#19ce502ca572665f3b647b10939f97fd1615f102" +rx-lite@*, rx-lite@^4.0.8: + version "4.0.8" + resolved "https://registry.yarnpkg.com/rx-lite/-/rx-lite-4.0.8.tgz#0b1e11af8bc44836f04a6407e92da42467b79444" -safe-buffer@^5.0.1, safe-buffer@~5.1.0: +safe-buffer@^5.0.1, safe-buffer@^5.1.1, safe-buffer@~5.1.0: version "5.1.1" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.1.tgz#893312af69b2123def71f57889001671eeb2c853" -samsam@1.1.2, samsam@~1.1: - version "1.1.2" - resolved "https://registry.yarnpkg.com/samsam/-/samsam-1.1.2.tgz#bec11fdc83a9fda063401210e40176c3024d1567" +samsam@1.x, samsam@^1.1.3: + version "1.2.1" + resolved "https://registry.yarnpkg.com/samsam/-/samsam-1.2.1.tgz#edd39093a3184370cb859243b2bdf255e7d8ea67" semver-diff@^2.0.0: version "2.1.0" @@ -3565,30 +3461,22 @@ set-immediate-shim@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz#4b2b1b27eb808a9f8dcc481a58e5e56f599f3f61" -shelljs@^0.7.5: - version "0.7.8" - resolved "https://registry.yarnpkg.com/shelljs/-/shelljs-0.7.8.tgz#decbcf874b0d1e5fb72e14b164a9683048e9acb3" - dependencies: - glob "^7.0.0" - interpret "^1.0.0" - rechoir "^0.6.2" - -signal-exit@^2.0.0: - version "2.1.2" - resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-2.1.2.tgz#375879b1f92ebc3b334480d038dc546a6d558564" - signal-exit@^3.0.0, signal-exit@^3.0.1, signal-exit@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d" -sinon@^1.17.7: - version "1.17.7" - resolved "https://registry.yarnpkg.com/sinon/-/sinon-1.17.7.tgz#4542a4f49ba0c45c05eb2e9dd9d203e2b8efe0bf" +sinon@^2.3.8: + version "2.3.8" + resolved "https://registry.yarnpkg.com/sinon/-/sinon-2.3.8.tgz#31de06fed8fba3a671e576dd96d0a5863796f25c" dependencies: - formatio "1.1.1" - lolex "1.3.2" - samsam "1.1.2" - util ">=0.10.3 <1" + diff "^3.1.0" + formatio "1.2.0" + lolex "^1.6.0" + native-promise-only "^0.8.1" + path-to-regexp "^1.7.0" + samsam "^1.1.3" + text-encoding "0.6.4" + type-detect "^4.0.0" slash@^1.0.0: version "1.0.0" @@ -3630,15 +3518,15 @@ source-map@^0.5.0, source-map@^0.5.3, source-map@^0.5.6, source-map@~0.5.1: version "0.5.6" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.6.tgz#75ce38f52bf0733c5a7f0c118d81334a2bb5f412" -spawn-wrap@1.2.4: - version "1.2.4" - resolved "https://registry.yarnpkg.com/spawn-wrap/-/spawn-wrap-1.2.4.tgz#920eb211a769c093eebfbd5b0e7a5d2e68ab2e40" +spawn-wrap@^1.3.7: + version "1.3.8" + resolved "https://registry.yarnpkg.com/spawn-wrap/-/spawn-wrap-1.3.8.tgz#fa2a79b990cbb0bb0018dca6748d88367b19ec31" dependencies: - foreground-child "^1.3.3" + foreground-child "^1.5.6" mkdirp "^0.5.0" os-homedir "^1.0.1" rimraf "^2.3.3" - signal-exit "^2.0.0" + signal-exit "^3.0.2" which "^1.2.4" spdx-correct@~1.0.0: @@ -3692,6 +3580,13 @@ string-width@^2.0.0: is-fullwidth-code-point "^2.0.0" strip-ansi "^3.0.0" +string-width@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.0.tgz#030664561fc146c9423ec7d978fe2457437fe6d0" + dependencies: + is-fullwidth-code-point "^2.0.0" + strip-ansi "^4.0.0" + string_decoder@~1.0.0: version "1.0.3" resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.0.3.tgz#0fc67d7c141825de94282dd536bec6b9bce860ab" @@ -3708,6 +3603,12 @@ strip-ansi@^3.0.0, strip-ansi@^3.0.1: dependencies: ansi-regex "^2.0.0" +strip-ansi@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f" + dependencies: + ansi-regex "^3.0.0" + strip-ansi@~0.1.0: version "0.1.1" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-0.1.1.tgz#39e8a98d044d150660abe4a6808acf70bb7bc991" @@ -3746,12 +3647,18 @@ supports-color@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" -supports-color@^3.1.2, supports-color@^3.2.3: +supports-color@^3.1.2: version "3.2.3" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-3.2.3.tgz#65ac0504b3954171d8a64946b2ae3cbb8a5f54f6" dependencies: has-flag "^1.0.0" +supports-color@^4.0.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-4.2.0.tgz#ad986dc7eb2315d009b4d77c8169c2231a684037" + dependencies: + has-flag "^2.0.0" + symbol-observable@^0.2.2: version "0.2.4" resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-0.2.4.tgz#95a83db26186d6af7e7a18dbd9760a2f86d08f40" @@ -3760,9 +3667,9 @@ symbol-observable@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.0.4.tgz#29bf615d4aa7121bdd898b22d4b3f9bc4e2aa03d" -table@^3.7.8: - version "3.8.3" - resolved "https://registry.yarnpkg.com/table/-/table-3.8.3.tgz#2bbc542f0fda9861a755d3947fefd8b3f513855f" +table@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/table/-/table-4.0.1.tgz#a8116c133fac2c61f4a420ab6cdf5c4d61f0e435" dependencies: ajv "^4.7.0" ajv-keywords "^1.0.0" @@ -3771,11 +3678,11 @@ table@^3.7.8: slice-ansi "0.0.4" string-width "^2.0.0" -tailored@^2.5.0: - version "2.5.0" - resolved "https://registry.yarnpkg.com/tailored/-/tailored-2.5.0.tgz#55055ea25e018951ecfc9adf39177f178fcde63e" +tailored@^2.6.0: + version "2.6.0" + resolved "https://registry.yarnpkg.com/tailored/-/tailored-2.6.0.tgz#70ae98b8f8bfb25ce320290c103cbc23aae4cf2a" dependencies: - erlang-types "^1.0.0" + erlang-types "^1.0.1" tar-pack@^3.4.0: version "3.4.0" @@ -3804,7 +3711,7 @@ term-size@^0.1.0: dependencies: execa "^0.4.0" -test-exclude@^4.1.0: +test-exclude@^4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/test-exclude/-/test-exclude-4.1.1.tgz#4d84964b0966b0087ecc334a2ce002d3d9341e26" dependencies: @@ -3814,6 +3721,10 @@ test-exclude@^4.1.0: read-pkg-up "^1.0.1" require-main-filename "^1.0.1" +text-encoding@0.6.4: + version "0.6.4" + resolved "https://registry.yarnpkg.com/text-encoding/-/text-encoding-0.6.4.tgz#e399a982257a276dae428bb92845cb71bdc26d19" + text-table@^0.2.0, text-table@~0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" @@ -3838,10 +3749,20 @@ time-require@^0.1.2: pretty-ms "^0.2.1" text-table "^0.2.0" +time-zone@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/time-zone/-/time-zone-1.0.0.tgz#99c5bf55958966af6d06d83bdf3800dc82faec5d" + timed-out@^4.0.0: version "4.0.1" resolved "https://registry.yarnpkg.com/timed-out/-/timed-out-4.0.1.tgz#f32eacac5a175bea25d7fab565ab3ed8741ef56f" +tmp@^0.0.31: + version "0.0.31" + resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.31.tgz#8f38ab9438e17315e5dbd8b3657e8bfb277ae4a7" + dependencies: + os-tmpdir "~1.0.1" + to-fast-properties@^1.0.1: version "1.0.3" resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-1.0.3.tgz#b83571fa4d8c25b82e231b06e3a3055de4ca1a47" @@ -3856,6 +3777,10 @@ trim-newlines@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/trim-newlines/-/trim-newlines-1.0.0.tgz#5887966bb582a4503a41eb524f7d35011815a613" +trim-off-newlines@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/trim-off-newlines/-/trim-off-newlines-1.0.1.tgz#9f9ba9d9efa8764c387698bcbfeb2c848f11adb3" + trim-right@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/trim-right/-/trim-right-1.0.1.tgz#cb2e1203067e0c8de1f614094b9fe45704ea6003" @@ -3880,6 +3805,10 @@ type-check@~0.3.2: dependencies: prelude-ls "~1.1.2" +type-detect@^4.0.0: + version "4.0.3" + resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.3.tgz#0e3f2670b44099b0b46c284d136a7ef49c74c2ea" + typedarray@^0.0.6: version "0.0.6" resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" @@ -3942,22 +3871,10 @@ url-parse-lax@^1.0.0: dependencies: prepend-http "^1.0.1" -user-home@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/user-home/-/user-home-2.0.0.tgz#9c70bfd8169bc1dcbf48604e0f04b8b49cde9e9f" - dependencies: - os-homedir "^1.0.0" - util-deprecate@~1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" -"util@>=0.10.3 <1": - version "0.10.3" - resolved "https://registry.yarnpkg.com/util/-/util-0.10.3.tgz#7afb1afe50805246489e3db7fe0ed379336ac0f9" - dependencies: - inherits "2.0.1" - uuid@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.1.0.tgz#3dd3d3e790abc24d7b0d3a034ffababe28ebbc04" @@ -3975,9 +3892,13 @@ verror@1.3.6: dependencies: extsprintf "1.0.2" -which-module@^1.0.0: +well-known-symbols@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/which-module/-/which-module-1.0.0.tgz#bba63ca861948994ff307736089e3b96026c2a4f" + resolved "https://registry.yarnpkg.com/well-known-symbols/-/well-known-symbols-1.0.0.tgz#73c78ae81a7726a8fa598e2880801c8b16225518" + +which-module@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a" which@^1.2.4, which@^1.2.8, which@^1.2.9: version "1.2.14" @@ -4086,23 +4007,29 @@ yargs-parser@^5.0.0: dependencies: camelcase "^3.0.0" -yargs@^7.1.0: - version "7.1.0" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-7.1.0.tgz#6ba318eb16961727f5d284f8ea003e8d6154d0c8" +yargs-parser@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-7.0.0.tgz#8d0ac42f16ea55debd332caf4c4038b3e3f5dfd9" dependencies: - camelcase "^3.0.0" + camelcase "^4.1.0" + +yargs@^8.0.1: + version "8.0.2" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-8.0.2.tgz#6299a9055b1cefc969ff7e79c1d918dceb22c360" + dependencies: + camelcase "^4.1.0" cliui "^3.2.0" decamelize "^1.1.1" get-caller-file "^1.0.1" - os-locale "^1.4.0" - read-pkg-up "^1.0.1" + os-locale "^2.0.0" + read-pkg-up "^2.0.0" require-directory "^2.1.1" require-main-filename "^1.0.1" set-blocking "^2.0.0" - string-width "^1.0.2" - which-module "^1.0.0" + string-width "^2.0.0" + which-module "^2.0.0" y18n "^3.2.1" - yargs-parser "^5.0.0" + yargs-parser "^7.0.0" yargs@~3.10.0: version "3.10.0" From 2afdfb8ef194cc34b6deb481eb2e475913198e19 Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Mon, 17 Jul 2017 23:13:35 -0500 Subject: [PATCH 179/418] Translate map to JavaScript map --- .babelrc | 6 +-- .tool-versions | 2 +- .../passes/translate/forms/map.ex | 51 +++++++++--------- .../passes/translate/forms/pattern.ex | 53 ++++++++++++------- .../passes/translate/protocol.ex | 2 +- package.json | 6 +-- priv/build/iife/ElixirScript.Core.js | 8 +-- .../lib/core/erlang_compat/erlang.js | 4 +- src/javascript/lib/core/erlang_compat/maps.js | 53 +++++++------------ src/javascript/lib/core/functions.js | 22 ++++++++ src/javascript/lib/core/protocol.js | 12 ++--- test/support/main.ex | 2 + yarn.lock | 17 ++++-- 13 files changed, 135 insertions(+), 103 deletions(-) diff --git a/.babelrc b/.babelrc index 6a9be799..002b4aa0 100644 --- a/.babelrc +++ b/.babelrc @@ -1,5 +1,3 @@ { - "presets": [ - "env" - ] -} \ No newline at end of file + "presets": ["env"] +} diff --git a/.tool-versions b/.tool-versions index 1c12341c..0a498367 100644 --- a/.tool-versions +++ b/.tool-versions @@ -1,3 +1,3 @@ erlang 20.0 elixir ref-v1.5.0-rc.1 -nodejs 8.1.0 +nodejs 8.1.4 diff --git a/lib/elixir_script/passes/translate/forms/map.ex b/lib/elixir_script/passes/translate/forms/map.ex index 28518a92..5f23e0e5 100644 --- a/lib/elixir_script/passes/translate/forms/map.ex +++ b/lib/elixir_script/passes/translate/forms/map.ex @@ -5,17 +5,19 @@ defmodule ElixirScript.Translate.Forms.Map do def compile({:%{}, _, [{:|, _, [map, new_values]}]}, state) do { map, state } = Form.compile(map, state) - { data, state } = Form.compile({:%{}, [], new_values}, state) + data = Enum.map(new_values, fn {x, y} -> + J.array_expression([ + Form.compile!(x, state), + Form.compile!(y, state) + ]) + end) - ast = J.call_expression( - J.member_expression( - J.identifier("Object"), - J.identifier("assign") - ), + ast = J.new_expression( + J.identifier("Map"), [ - J.object_expression([]), - map, - data + J.array_expression( + [J.spread_element(map)] ++ data + ) ] ) @@ -23,21 +25,22 @@ defmodule ElixirScript.Translate.Forms.Map do end def compile({:%{}, _, properties}, state) do - ast = properties - |> Enum.map(fn - ({x, y}) -> - case x do - {_, _, nil } -> - {key, _} = Form.compile(x, state) - {value, _} = Form.compile(y, state) - J.property(key, value, :init, false, false, true) - _ -> - {key, _} = Form.compile(x, state) - {value, _} = Form.compile(y, state) - make_property(key, value) - end - end) - |> J.object_expression + ast = J.new_expression( + J.identifier("Map"), + [ + J.array_expression( + Enum.map(properties, fn + {x, y} -> + J.array_expression( + [ + Form.compile!(x, state), + Form.compile!(y, state) + ] + ) + end) + ) + ] + ) {ast, state} end diff --git a/lib/elixir_script/passes/translate/forms/pattern.ex b/lib/elixir_script/passes/translate/forms/pattern.ex index d52407dc..9dc2a101 100644 --- a/lib/elixir_script/passes/translate/forms/pattern.ex +++ b/lib/elixir_script/passes/translate/forms/pattern.ex @@ -122,33 +122,33 @@ defmodule ElixirScript.Translate.Forms.Pattern do {pattern, params} = process_pattern(var, state) a = J.object_expression([%ESTree.Property{ - key: J.identifier("__MODULE__"), - value: hd(List.wrap(pattern)) - }]) + key: J.identifier("__MODULE__"), + value: hd(List.wrap(pattern)) + }]) - property = ElixirScript.Translate.Forms.Map.make_property( + property = J.array_expression([ Form.compile!(:__struct__, state), a - ) + ]) { property, params } {:__module__struct__, module} -> a = J.object_expression([%ESTree.Property{ - key: J.identifier("__MODULE__"), - value: J.call_expression( - J.member_expression( - J.identifier("Symbol"), - J.identifier("for") - ), - [J.literal(to_string(module))] - ) - }]) - - property = ElixirScript.Translate.Forms.Map.make_property( + key: J.identifier("__MODULE__"), + value: J.call_expression( + J.member_expression( + J.identifier("Symbol"), + J.identifier("for") + ), + [J.literal(to_string(module))] + ) + }]) + + property = J.array_expression([ Form.compile!(:__struct__, state), a - ) + ]) { property, [] } @@ -156,9 +156,15 @@ defmodule ElixirScript.Translate.Forms.Pattern do {pattern, params} = process_pattern(value, state) property = case key do {:^, _, [the_key]} -> - J.property(Form.compile!(the_key, state), hd(List.wrap(pattern)), :init, false, false, true) + J.array_expression([ + Form.compile!(the_key, state), + hd(List.wrap(pattern)) + ]) _ -> - ElixirScript.Translate.Forms.Map.make_property(Form.compile!(key, state), hd(List.wrap(pattern))) + J.array_expression([ + Form.compile!(key, state), + hd(List.wrap(pattern)) + ]) end { property, params } @@ -168,7 +174,14 @@ defmodule ElixirScript.Translate.Forms.Pattern do { props ++ [prop], params ++ param } end) - { [J.object_expression(List.wrap(props))], params } + ast = J.new_expression( + J.identifier("Map"), + [ + J.array_expression(List.wrap(props)) + ] + ) + + { [ast], params } end defp process_pattern({:<<>>, _, elements}, state) do diff --git a/lib/elixir_script/passes/translate/protocol.ex b/lib/elixir_script/passes/translate/protocol.ex index e6c1747b..48ea1585 100644 --- a/lib/elixir_script/passes/translate/protocol.ex +++ b/lib/elixir_script/passes/translate/protocol.ex @@ -153,7 +153,7 @@ defmodule ElixirScript.Translate.Protocol do end defp map_to_js(Map) do - J.identifier(:Object) + J.identifier(:Map) end defp map_to_js(Any) do diff --git a/package.json b/package.json index 8e013597..c243103e 100644 --- a/package.json +++ b/package.json @@ -23,7 +23,7 @@ "license": "MIT", "dependencies": { "erlang-types": "^1.0.1", - "tailored": "^2.6.0" + "tailored": "^2.6.1" }, "devDependencies": { "ava": "^0.21.0", @@ -41,9 +41,7 @@ "sinon": "^2.3.8" }, "ava": { - "require": [ - "babel-register" - ], + "require": ["babel-register"], "babel": { "babelrc": true } diff --git a/priv/build/iife/ElixirScript.Core.js b/priv/build/iife/ElixirScript.Core.js index a6c133c6..45c27597 100644 --- a/priv/build/iife/ElixirScript.Core.js +++ b/priv/build/iife/ElixirScript.Core.js @@ -1,6 +1,6 @@ var ElixirScript=function(){'use strict';/* @flow */function namedVariableResult(a,b){return new NamedVariableResult(a,b)}/* @flow */function is_number(a){return'number'==typeof a}function is_string(a){return'string'==typeof a}function is_boolean(a){return'boolean'==typeof a}function is_symbol(a){return'symbol'==typeof a}function is_object(a){return'object'==typeof a}function is_variable(a){return a instanceof Variable}function is_null(a){return null===a}function is_array(a){return Array.isArray(a)}function is_function(a){return'[object Function]'==Object.prototype.toString.call(a)}function is_map(a){return a instanceof Map}function resolveNull(){return function(a){return is_null(a)}}function resolveWildcard(){return function(){return!0}}function resolveObject(a){let b={};const c=Object.keys(a).concat(Object.getOwnPropertySymbols(a));for(let d of c)b[d]=buildMatch(a[d]);return function(d,e){if(!is_object(d)||a.length>d.length)return!1;for(let a of c)if(!(a in d)||!b[a](d[a],e))return!1;return!0}}function getSize(a,b){return a*b/8}function arraysEqual(c,a){if(c===a)return!0;if(null==c||null==a)return!1;if(c.length!=a.length)return!1;for(var b=0;be.integer(a));return new e(...b)}function resolveNoMatch(){return function(){return!1}}function buildMatch(a){if(null===a)return resolveNull(a);if('undefined'==typeof a)return resolveWildcard(a);const b=a.constructor.prototype,c=f.get(b);return c?c(a):'object'==typeof a?resolveObject(a):resolveNoMatch()}function defmatchgen(...a){const b=getArityMap(a);return function*(...a){let[c,d]=findMatchingFunction(a,b);return yield*c.apply(this,d)}}function findMatchingFunction(a,b){if(b.has(a.length)){const c=b.get(a.length);let d=null,e=null;for(let b of c){let c=[];a=fillInOptionalValues(a,b.arity,b.optionals);const f=b.pattern(a,c),[g,h]=checkNamedVariables(c);if(f&&h&&b.guard.apply(this,g)){d=b.fn,e=g;break}}if(!d)throw console.error('No match for:',a),new MatchError(a);return[d,e]}throw console.error('Arity of',a.length,'not found. No match for:',a),new MatchError(a)}function getArityMap(a){let b=new Map;for(const c of a){const a=getArityRange(c);for(const d of a){let a=[];b.has(d)&&(a=b.get(d)),a.push(c),b.set(d,a)}}return b}function getArityRange(a){const b=a.arity-a.optionals.length,c=a.arity;let d=[b];for(;d[d.length-1]!=c;)d.push(d[d.length-1]+1);return d}function getOptionalValues(a){let b=[];for(let c=0;c!0,d=null){let e=[],f=buildMatch(a);const g=f(b,e),[h,i]=checkNamedVariables(e);return g&&i&&c.apply(this,h)?h:d}function run_generators(a,b){if(0==b.length)return a.map((a)=>{return Array.isArray(a)?a:[a]});const c=b.pop();let d=[];for(let e of c())for(let b of a)d.push([e].concat(b));return run_generators(d,b)}function iterator_to_reducer(a,b,c){const d=a[Symbol.iterator]();let e=d.next(),f=b;for(;!1===e.done;){if(f=c(e.value,f.get(1)),f.get(0)===Symbol.for('halt'))return new n.Tuple(Symbol.for('halted'),f.get(1));if(f.get(0)===Symbol.for('suspend'))return new n.Tuple(Symbol.for('suspended'),f.get(1),(a)=>{return iterator_to_reducer(d,a,c)});e=d.next()}return new n.Tuple(Symbol.for('done'),f.get(1))}function run_list_generators(a,b){if(0==b.length)return a.map((a)=>{return Array.isArray(a)?a:[a]});const c=b.pop(),d=[];for(const e of c())for(const b of a)d.push([e].concat(b));return run_list_generators(d,b)}// http://erlang.org/doc/man/erlang.html -function atom_to_binary(a,b=Symbol.for('utf8')){if(b!==Symbol.for('utf8'))throw new Error(`unsupported encoding ${b}`);return a.__MODULE__?Symbol.keyFor(a.__MODULE__):Symbol.keyFor(a)}function binary_to_atom(a,b=Symbol.for('utf8')){if(b!==Symbol.for('utf8'))throw new Error(`unsupported encoding ${b}`);return Symbol.for(a)}function is_number$1(a){return'number'==typeof a||a instanceof Number}function to_list(a){if(!1===h.is_map(a))return new d.Tuple(k,a);const b=[];for(const c of keys(a))b.push(new d.Tuple(c,a[c]));return b}function keys(a){if(!1===h.is_map(a))return new d.Tuple(k,a);const b=[];for(const c of Object.getOwnPropertySymbols(a))b.push(c);for(const c of Object.getOwnPropertyNames(a))b.push(c);return b}function is_key(a,b){return b.hasOwnProperty(a)}// http://erlang.org/doc/man/lists.html +function atom_to_binary(a,b=Symbol.for('utf8')){if(b!==Symbol.for('utf8'))throw new Error(`unsupported encoding ${b}`);return a.__MODULE__?Symbol.keyFor(a.__MODULE__):Symbol.keyFor(a)}function binary_to_atom(a,b=Symbol.for('utf8')){if(b!==Symbol.for('utf8'))throw new Error(`unsupported encoding ${b}`);return Symbol.for(a)}function is_number$1(a){return'number'==typeof a||a instanceof Number}function is_key(a,b){return b.has(a)}// http://erlang.org/doc/man/lists.html function reverse(a){return[...a]}function flatten(a,b=[]){const c=a.reduce((a,b)=>{return Array.isArray(b)?a.concat(flatten(b)):a.concat(b)},[]);return c.concat(b)}function foldl(a,b,c){return c.reduce((b,c)=>{return a(c,b)},b)}function keyfind(a,b,c){for(const d of c)if(d.get(b-1)===a)return d;return!1}function keydelete(a,b,c){const d=[];let e=!1;for(let f=0;fBitString$1.integer(a));return new BitString$1(...d)}[Symbol.iterator](){return this.value[Symbol.iterator]()}toString(){var a,b='';for(a=0;a>'}process(a){let b=[];var c;for(c=0;cb?c.push(b):2048>b?c.push(192|b>>6,128|63&b):55296>b||57344<=b?c.push(224|b>>12,128|63&b>>6,128|63&b):(d++,b=65536+((1023&b)<<10|1023&a.charCodeAt(d)),c.push(240|b>>18,128|63&b>>12,128|63&b>>6,128|63&b));return c}static toUTF16Array(a){for(var b,c=[],d=0;d=b?(c.push(0),c.push(b)):(c.push(255&b>>8),c.push(255&b));return c}static toUTF32Array(a){for(var b,c=[],d=0;d=b?(c.push(0),c.push(0),c.push(0),c.push(b)):(c.push(0),c.push(0),c.push(255&b>>8),c.push(255&b));return c}//http://stackoverflow.com/questions/2003493/javascript-float-from-to-bits -static float32ToBytes(a){var b=[],c=new ArrayBuffer(4);new Float32Array(c)[0]=a;let d=new Uint32Array(c)[0];return b.push(255&d>>24),b.push(255&d>>16),b.push(255&d>>8),b.push(255&d),b}static float64ToBytes(a){var b=[],c=new ArrayBuffer(8);new Float64Array(c)[0]=a;var d=new Uint32Array(c)[0],e=new Uint32Array(c)[1];return b.push(255&e>>24),b.push(255&e>>16),b.push(255&e>>8),b.push(255&e),b.push(255&d>>24),b.push(255&d>>16),b.push(255&d>>8),b.push(255&d),b}}var d={Tuple,PID:class PID{constructor(){++b,this.id=b}toString(){return'PID#<0.'+this.id+'.0>'}},Reference:class Reference{constructor(){++c,this.id=c,this.ref=Symbol()}toString(){return'Ref#<0.0.0.'+this.id+'>'}},BitString:BitString$1};/* @flow */const e=d.BitString,f=new Map;f.set(Variable.prototype,function resolveVariable(a){return function(b,c){return null===a.name||a.name.startsWith('_')?c.push(b):c.push(namedVariableResult(a.name,b)),!0}}),f.set(Wildcard.prototype,resolveWildcard),f.set(HeadTail.prototype,function resolveHeadTail(){return function(a,b){if(!is_array(a)||2>a.length)return!1;const c=a[0],d=a.slice(1);return b.push(c),b.push(d),!0}}),f.set(StartsWith.prototype,function resolveStartsWith(a){const b=a.prefix;return function(a,c){return is_string(a)&&a.startsWith(b)&&(c.push(a.substring(b.length)),!0)}}),f.set(Capture.prototype,function resolveCapture(a){const b=buildMatch(a.value);return function(a,c){return!!b(a,c)&&(c.push(a),!0)}}),f.set(Bound.prototype,function resolveBound(a){return function(b){return typeof b==typeof a.value&&b===a.value}}),f.set(Type.prototype,function resolveType(a){return function(b,c){if(b instanceof a.type){const d=buildMatch(a.objPattern);return d(b,c)}return!1}}),f.set(BitStringMatch.prototype,function resolveBitString(a){let b=[];for(let c of a.values)if(is_variable(c.value)){let a=getSize(c.unit,c.size);fillArray(b,a)}else b=b.concat(new e(c).value);let c=a.values;return function(a,d){var f=String.fromCharCode;let g=null;if(!is_string(a)&&!(a instanceof e))return!1;g=is_string(a)?new e(e.binary(a)):a;let h=0;for(let e,j=0;jd.size)return!1;for(let a of c)if(!d.has(a)||!b.get(a)(d.get(a),e))return!1;return!0}}),f.set(Array.prototype,function resolveArray(a){const b=a.map((a)=>buildMatch(a));return function(c,d){return is_array(c)&&c.length==a.length&&c.every(function(a,e){return b[e](c[e],d)})}}),f.set(String.prototype,function resolveString(a){return function(b){return is_string(b)&&b===a}}),f.set(Boolean.prototype,function resolveBoolean(a){return function(b){return is_boolean(b)&&b===a}}),f.set(Function.prototype,function resolveFunction(a){return function(b){return is_function(b)&&b===a}}),f.set(Object.prototype,resolveObject);class MatchError extends Error{constructor(a){if(super(),'symbol'==typeof a)this.message='No match for: '+a.toString();else if(Array.isArray(a)){let b=a.map((a)=>{return null===a?'null':'undefined'==typeof a?'undefined':a.toString()});this.message='No match for: '+b}else this.message='No match for: '+a;this.stack=new Error().stack,this.name=this.constructor.name}}class Clause{constructor(a,b,c=()=>!0){this.pattern=buildMatch(a),this.arity=a.length,this.optionals=getOptionalValues(a),this.fn=b,this.guard=c}}const g=Symbol();// https://github.com/airportyh/protomorphism -class Protocol{constructor(b){function createFun(b){return function(...c){const d=c[0];let e=null;if(null===d&&this.hasImplementation(Symbol('null'))?e=this.registry.get(Symbol)[b]:a(d)&&this.hasImplementation(n.Integer)?e=this.registry.get(n.Integer)[b]:'number'==typeof d&&!a(d)&&this.hasImplementation(n.Float)?e=this.registry.get(n.Float)[b]:'string'==typeof d&&this.hasImplementation(n.BitString)?e=this.registry.get(n.BitString)[b]:d&&d[Symbol.for('__struct__')]&&this.hasImplementation(d)?e=this.registry.get(d[Symbol.for('__struct__')].__MODULE__)[b]:null!==d&&this.hasImplementation(d)?e=this.registry.get(d.constructor)[b]:this.fallback&&(e=this.fallback[b]),null!=e){const a=e.apply(this,c);return a}throw new Error(`No implementation found for ${d}`)}}for(const a in this.registry=new Map,this.fallback=null,b)this[a]=createFun(a).bind(this)}implementation(a,b){null===a?this.fallback=b:this.registry.set(a,b)}hasImplementation(a){if(a===n.Integer||a===n.Float||a===n.BitString)return this.registry.has(a);return a&&a[Symbol.for('__struct__')]?this.registry.has(a[Symbol.for('__struct__')].__MODULE__):this.registry.has(a.constructor)}}var h={atom_to_binary,binary_to_atom,binary_to_existing_atom:function binary_to_existing_atom(a,b=Symbol.for('utf8')){return binary_to_atom(a,b)},list_concatenation:function list_concatenation(a,b){return a.concat(b)},list_subtraction:function list_subtraction(a,b){const c=[...a];for(const d of b){const a=c.indexOf(d);-1b},greaterThanOrEqualTo:function greaterThanOrEqualTo(a,b){return a>=b},lessThan:function lessThan(a,b){return a>b},bxor:function bxor(a,b){return a^b},bnot:function bnot(a){return~a},is_bitstring:function is_bitstring$1(a){return a instanceof d.BitString},is_boolean:function is_boolean$1(a){return'boolean'==typeof a||a instanceof Boolean},is_float:function is_float(b){return is_number$1(b)&&!a(b)},is_function:function is_function$1(a){return'function'==typeof a||a instanceof Function},is_integer:function is_integer(b){return a(b)},is_list:function is_list(a){return Array.isArray(a)},is_map:function is_map$1(a){return'object'==typeof a||a instanceof Object},is_number:is_number$1,is_pid:function is_pid(a){return a instanceof d.PID},is_port:function is_port(){return!1},is_reference:function is_reference(a){return a instanceof d.Reference},is_tuple:function is_tuple(a){return a instanceof d.Tuple},is_atom:function is_atom(a){return'symbol'==typeof a||a instanceof Symbol||a.__MODULE__},is_binary:function is_binary(a){return'string'==typeof a||a instanceof String},element:function element(a,b){return b.get(a-1)},setelement:function setelement(a,b,c){const e=[...b.values];return e[a-1]=c,new d.Tuple(...e)},make_tuple:function make_tuple(a,b){const c=[];for(let d=0;d!0){let d=[],e=buildMatch(a);const f=e(b,d),[g,h]=checkNamedVariables(d);if(f&&h&&c.apply(this,g))return g;throw console.error('No match for:',b),new MatchError(b)},MatchError,variable:function variable(a=null,b=Symbol.for('tailored.no_value')){return new Variable(a,b)},wildcard:function wildcard(){return new Wildcard},startsWith:function startsWith(a){return new StartsWith(a)},capture:function capture(a){return new Capture(a)},headTail:function headTail(){return new HeadTail},type:function a(a,b={}){return new Type(a,b)},bound:function bound(a){return new Bound(a)},Clause,clause:function clause(a,b,c=()=>!0){return new Clause(a,b,c)},bitStringMatch:function bitStringMatch(...a){return new BitStringMatch(...a)},match_or_default,defmatchgen,list_comprehension:function list_comprehension(a,b){const c=run_generators(b.pop()(),b);let d=[];for(let e of c)a.guard.apply(this,e)&&d.push(a.fn.apply(this,e));return d},list_generator:function list_generator(a,b){return function(){let c=[];for(let d of b){const b=match_or_default(a,d,()=>!0,g);if(b!=g){const[a]=b;c.push(a)}}return c}},bitstring_generator:function bitstring_generator(a,b){return function(){let c=[],d=b.slice(0,a.byte_size()),e=1;for(;d.byte_size==a.byte_size();){const f=match_or_default(a,d,()=>!0,g);if(f!=g){c.push(f)}d=b.slice(a.byte_size()*e,a.byte_size()*(e+1)),e++}return c}},bitstring_comprehension:function bitstring_comprehension(a,b){const c=run_generators(b.pop()(),b);let e=[];for(let d of c)a.guard.apply(this,d)&&e.push(a.fn.apply(this,d));return e=e.map((a)=>d.BitString.integer(a)),new d.BitString(...e)},defmatchGen:function defmatchGen(...a){return defmatchgen(...a)},defmatchAsync:function defmatchAsync(...a){const b=getArityMap(a);return async function(...a){if(b.has(a.length)){const c=b.get(a.length);let d=null,e=null;for(let b of c){let c=[];a=fillInOptionalValues(a,b.arity,b.optionals);const f=b.pattern(a,c),[g,h]=checkNamedVariables(c);if(f&&h&&(await b.guard.apply(this,c))){d=b.fn,e=c;break}}if(!d)throw console.error('No match for:',a),new MatchError(a);return d.apply(this,e)}throw console.error('Arity of',a.length,'not found. No match for:',a),new MatchError(a)}}},Integer:class Integer{},Float:class Float{},Functions:{call_property:function call_property(a,b){if(!b)return a instanceof Function||'function'==typeof a?a():a;let c=null;if('number'==typeof a||'symbol'==typeof a||'boolean'==typeof a||'string'==typeof a?void 0===a[b]?void 0!==a[Symbol.for(b)]&&(c=Symbol.for(b)):c=b:b in a?c=b:Symbol.for(b)in a&&(c=Symbol.for(b)),null===c)throw new Error(`Property ${b} not found in ${a}`);return a[c]instanceof Function||'function'==typeof a[c]?a[c]():a[c]},defprotocol:function defprotocol(a){return new Protocol(a)},defimpl:function defimpl(a,b,c){a.implementation(b,c)},build_namespace:function build_namespace(a,b){let c=b.split('.');const d=a;let e=a;'Elixir'===c[0]&&(c=c.slice(1));for(const d of c)'undefined'==typeof e[d]&&(e[d]={}),e=e[d];return d.__table__=a.__table__||{},d.__table__[Symbol.for(b)]=e,e},iterator_to_reducer},SpecialForms:{_case:function _case(a,b){return n.Patterns.defmatch(...b)(a)},cond:function cond(...a){for(const b of a)if(b[0])return b[1]();throw new Error},_for:function _for(a,b,c,d=[]){let[e,f]=c.into(d);const g=run_list_generators(b.pop()(),b);for(const h of g)a.guard.apply(this,h)&&(e=f(e,new n.Tuple(Symbol.for('cont'),a.fn.apply(this,h))));return f(e,Symbol.for('done'))},_try:function _try(a,b,c,d,e){let f=null;try{f=a()}catch(a){let d=null;if(b)try{return d=b(a),d}catch(a){if(a instanceof n.Patterns.MatchError)throw a}if(c)try{return d=c(a),d}catch(a){if(a instanceof n.Patterns.MatchError)throw a}throw a}finally{e&&e()}if(d)try{return d(f)}catch(a){if(a instanceof n.Patterns.MatchError)throw new Error('No Match Found in Else');throw a}else return f},_with:function _with(...a){let b=[],c=null,d=null;'function'==typeof a[a.length-2]?[c,d]=a.splice(-2):c=a.pop();for(let c=0;c{const[c,d]=b;return a[c]=d,a},{})},keys,values:function values$1(a){if(!1===h.is_map(a))return new d.Tuple(k,a);const b=[];for(const c of keys(a))b.push(a[c]);return b},is_key,put:function put(a,b,c){if(!1===h.is_map(c))return new d.Tuple(k,c);const e=Object.assign({},c,{[a]:b});return e},merge:function merge(a,b){return!1===h.is_map(a)?new d.Tuple(k,a):!1===h.is_map(b)?new d.Tuple(k,b):Object.assign({},a,b)},update:function update(a,b,c){return!1===h.is_map(c)?new d.Tuple(k,c):!1===is_key(a,c)?new d.Tuple(l,a):Object.assign({},c,{[a]:b})},get:function get(...a){const b=a[0],c=a[1];return!1===h.is_map(c)?new d.Tuple(k,c):is_key(b)?c[b]:3===a.length?a[2]:new d.Tuple(l,b)},take:function take(a,b){if(!1===h.is_map(b))return new d.Tuple(k,b);if(!is_key(a))return j;const c=b[a],e=Object.assign({},b);return delete e[a],new d.Tuple(c,e)}},lists:{reverse,foreach:function foreach(a,b){return b.forEach((b)=>a(b)),Symbol.for('ok')},duplicate:function duplicate(a,b){const c=[];for(;c.length{if(d.get(c-1)a.get(c-1)?1:0})},keystore:function keystore(a,b,c,d){const e=[...c];for(let f=0;fa.toString()).join()},map:function map(a,b){return b.map((b)=>a(b))},filter:function filter(a,b){return b.filter((b)=>a(b))},filtermap:function filtermap(a,b){const c=[];for(const e of b){const b=a(e);!0===b?c.push(e):b instanceof d.Tuple&&!0===b.get(0)&&c.push(b.get(1))}return c},member:function member(a,b){for(const c of b)if(c===a)return!0;return!1},all:function all(a,b){for(const c of b)if(!1===a(c))return!1;return!0},any:function any(a,b){for(const c of b)if(!0===a(c))return!0;return!1},splitwith:function splitwith(a,b){let c=!1;const e=[],f=[];for(const d of b)!0==c?f.push(d):!0===a(d)?e.push(d):(c=!0,f.push(d));return new d.Tuple(e,f)},sort:function sort(...a){if(1===a.length){const b=[...a[0]];return b.sort()}const c=a[0],b=[...a[1]];return b.sort((d,a)=>{const b=c(d,a);return!0===b?-1:1})}}};return{Core:n}}(); +static float32ToBytes(a){var b=[],c=new ArrayBuffer(4);new Float32Array(c)[0]=a;let d=new Uint32Array(c)[0];return b.push(255&d>>24),b.push(255&d>>16),b.push(255&d>>8),b.push(255&d),b}static float64ToBytes(a){var b=[],c=new ArrayBuffer(8);new Float64Array(c)[0]=a;var d=new Uint32Array(c)[0],e=new Uint32Array(c)[1];return b.push(255&e>>24),b.push(255&e>>16),b.push(255&e>>8),b.push(255&e),b.push(255&d>>24),b.push(255&d>>16),b.push(255&d>>8),b.push(255&d),b}}var d={Tuple,PID:class PID{constructor(){++b,this.id=b}toString(){return'PID#<0.'+this.id+'.0>'}},Reference:class Reference{constructor(){++c,this.id=c,this.ref=Symbol()}toString(){return'Ref#<0.0.0.'+this.id+'>'}},BitString:BitString$1};/* @flow */const e=d.BitString,f=new Map;f.set(Variable.prototype,function resolveVariable(a){return function(b,c){return null===a.name||a.name.startsWith('_')?c.push(b):c.push(namedVariableResult(a.name,b)),!0}}),f.set(Wildcard.prototype,resolveWildcard),f.set(HeadTail.prototype,function resolveHeadTail(){return function(a,b){if(!is_array(a)||2>a.length)return!1;const c=a[0],d=a.slice(1);return b.push(c),b.push(d),!0}}),f.set(StartsWith.prototype,function resolveStartsWith(a){const b=a.prefix;return function(a,c){return is_string(a)&&a.startsWith(b)&&(c.push(a.substring(b.length)),!0)}}),f.set(Capture.prototype,function resolveCapture(a){const b=buildMatch(a.value);return function(a,c){return!!b(a,c)&&(c.push(a),!0)}}),f.set(Bound.prototype,function resolveBound(a){return function(b){return typeof b==typeof a.value&&b===a.value}}),f.set(Type.prototype,function resolveType(a){return function(b,c){if(b instanceof a.type){const d=buildMatch(a.objPattern);return d(b,c)}return!1}}),f.set(BitStringMatch.prototype,function resolveBitString(a){let b=[];for(let c of a.values)if(is_variable(c.value)){let a=getSize(c.unit,c.size);fillArray(b,a)}else b=b.concat(new e(c).value);let c=a.values;return function(a,d){var f=String.fromCharCode;let g=null;if(!is_string(a)&&!(a instanceof e))return!1;g=is_string(a)?new e(e.binary(a)):a;let h=0;for(let e,j=0;jd.size)return!1;for(let a of c)if(!d.has(a)||!b.get(a)(d.get(a),e))return!1;return!0}}),f.set(Array.prototype,function resolveArray(a){const b=a.map((a)=>buildMatch(a));return function(c,d){return is_array(c)&&c.length==a.length&&c.every(function(a,e){return b[e](c[e],d)})}}),f.set(String.prototype,function resolveString(a){return function(b){return is_string(b)&&b===a}}),f.set(Boolean.prototype,function resolveBoolean(a){return function(b){return is_boolean(b)&&b===a}}),f.set(Function.prototype,function resolveFunction(a){return function(b){return is_function(b)&&b===a}}),f.set(Object.prototype,resolveObject);class MatchError extends Error{constructor(a){if(super(),'symbol'==typeof a)this.message='No match for: '+a.toString();else if(Array.isArray(a)){let b=a.map((a)=>{return null===a?'null':'undefined'==typeof a?'undefined':a.toString()});this.message='No match for: '+b}else this.message='No match for: '+a;this.stack=new Error().stack,this.name=this.constructor.name}}class Clause{constructor(a,b,c=()=>!0){this.pattern=buildMatch(a),this.arity=a.length,this.optionals=getOptionalValues(a),this.fn=b,this.guard=c}}const g=Symbol();// https://github.com/airportyh/protomorphism +class Protocol{constructor(b){function createFun(b){return function(...c){const d=c[0];let e=null;if(null===d&&this.hasImplementation(Symbol('null'))?e=this.registry.get(Symbol)[b]:a(d)&&this.hasImplementation(n.Integer)?e=this.registry.get(n.Integer)[b]:'number'==typeof d&&!a(d)&&this.hasImplementation(n.Float)?e=this.registry.get(n.Float)[b]:'string'==typeof d&&this.hasImplementation(n.BitString)?e=this.registry.get(n.BitString)[b]:d&&d.has(Symbol.for('__struct__'))&&this.hasImplementation(d)?e=this.registry.get(d.get(Symbol.for('__struct__')).__MODULE__)[b]:null!==d&&this.hasImplementation(d)?e=this.registry.get(d.constructor)[b]:this.fallback&&(e=this.fallback[b]),null!=e){const a=e.apply(this,c);return a}throw new Error(`No implementation found for ${d}`)}}for(const a in this.registry=new Map,this.fallback=null,b)this[a]=createFun(a).bind(this)}implementation(a,b){null===a?this.fallback=b:this.registry.set(a,b)}hasImplementation(a){if(a===n.Integer||a===n.Float||a===n.BitString)return this.registry.has(a);return a&&a.has(Symbol.for('__struct__'))?this.registry.has(a.get(Symbol.for('__struct__')).__MODULE__):this.registry.has(a.constructor)}}var h={atom_to_binary,binary_to_atom,binary_to_existing_atom:function binary_to_existing_atom(a,b=Symbol.for('utf8')){return binary_to_atom(a,b)},list_concatenation:function list_concatenation(a,b){return a.concat(b)},list_subtraction:function list_subtraction(a,b){const c=[...a];for(const d of b){const a=c.indexOf(d);-1b},greaterThanOrEqualTo:function greaterThanOrEqualTo(a,b){return a>=b},lessThan:function lessThan(a,b){return a>b},bxor:function bxor(a,b){return a^b},bnot:function bnot(a){return~a},is_bitstring:function is_bitstring$1(a){return a instanceof d.BitString},is_boolean:function is_boolean$1(a){return'boolean'==typeof a||a instanceof Boolean},is_float:function is_float(b){return is_number$1(b)&&!a(b)},is_function:function is_function$1(a){return'function'==typeof a||a instanceof Function},is_integer:function is_integer(b){return a(b)},is_list:function is_list(a){return Array.isArray(a)},is_map:function is_map$1(a){return a instanceof Map},is_number:is_number$1,is_pid:function is_pid(a){return a instanceof d.PID},is_port:function is_port(){return!1},is_reference:function is_reference(a){return a instanceof d.Reference},is_tuple:function is_tuple(a){return a instanceof d.Tuple},is_atom:function is_atom(a){return'symbol'==typeof a||a instanceof Symbol||a.__MODULE__},is_binary:function is_binary(a){return'string'==typeof a||a instanceof String},element:function element(a,b){return b.get(a-1)},setelement:function setelement(a,b,c){const e=[...b.values];return e[a-1]=c,new d.Tuple(...e)},make_tuple:function make_tuple(a,b){const c=[];for(let d=0;d!0){let d=[],e=buildMatch(a);const f=e(b,d),[g,h]=checkNamedVariables(d);if(f&&h&&c.apply(this,g))return g;throw console.error('No match for:',b),new MatchError(b)},MatchError,variable:function variable(a=null,b=Symbol.for('tailored.no_value')){return new Variable(a,b)},wildcard:function wildcard(){return new Wildcard},startsWith:function startsWith(a){return new StartsWith(a)},capture:function capture(a){return new Capture(a)},headTail:function headTail(){return new HeadTail},type:function a(a,b={}){return new Type(a,b)},bound:function bound(a){return new Bound(a)},Clause,clause:function clause(a,b,c=()=>!0){return new Clause(a,b,c)},bitStringMatch:function bitStringMatch(...a){return new BitStringMatch(...a)},match_or_default,defmatchgen,list_comprehension:function list_comprehension(a,b){const c=run_generators(b.pop()(),b);let d=[];for(let e of c)a.guard.apply(this,e)&&d.push(a.fn.apply(this,e));return d},list_generator:function list_generator(a,b){return function(){let c=[];for(let d of b){const b=match_or_default(a,d,()=>!0,g);if(b!=g){const[a]=b;c.push(a)}}return c}},bitstring_generator:function bitstring_generator(a,b){return function(){let c=[],d=b.slice(0,a.byte_size()),e=1;for(;d.byte_size==a.byte_size();){const f=match_or_default(a,d,()=>!0,g);if(f!=g){c.push(f)}d=b.slice(a.byte_size()*e,a.byte_size()*(e+1)),e++}return c}},bitstring_comprehension:function bitstring_comprehension(a,b){const c=run_generators(b.pop()(),b);let e=[];for(let d of c)a.guard.apply(this,d)&&e.push(a.fn.apply(this,d));return e=e.map((a)=>d.BitString.integer(a)),new d.BitString(...e)},defmatchGen:function defmatchGen(...a){return defmatchgen(...a)},defmatchAsync:function defmatchAsync(...a){const b=getArityMap(a);return async function(...a){if(b.has(a.length)){const c=b.get(a.length);let d=null,e=null;for(let b of c){let c=[];a=fillInOptionalValues(a,b.arity,b.optionals);const f=b.pattern(a,c),[g,h]=checkNamedVariables(c);if(f&&h&&(await b.guard.apply(this,c))){d=b.fn,e=c;break}}if(!d)throw console.error('No match for:',a),new MatchError(a);return d.apply(this,e)}throw console.error('Arity of',a.length,'not found. No match for:',a),new MatchError(a)}}},Integer:class Integer{},Float:class Float{},Functions:{call_property:function call_property(a,b){if(!b)return a instanceof Function||'function'==typeof a?a():a;if(a instanceof Map){let c=null;if(a.has(b)?c=b:a.has(Symbol.for(b))&&(c=Symbol.for(b)),null===c)throw new Error(`Property ${b} not found in ${a}`);return a.get(c)instanceof Function||'function'==typeof a.get(c)?a.get(c)():a.get(c)}let c=null;if('number'==typeof a||'symbol'==typeof a||'boolean'==typeof a||'string'==typeof a?void 0===a[b]?void 0!==a[Symbol.for(b)]&&(c=Symbol.for(b)):c=b:b in a?c=b:Symbol.for(b)in a&&(c=Symbol.for(b)),null===c)throw new Error(`Property ${b} not found in ${a}`);return a[c]instanceof Function||'function'==typeof a[c]?a[c]():a[c]},defprotocol:function defprotocol(a){return new Protocol(a)},defimpl:function defimpl(a,b,c){a.implementation(b,c)},build_namespace:function build_namespace(a,b){let c=b.split('.');const d=a;let e=a;'Elixir'===c[0]&&(c=c.slice(1));for(const d of c)'undefined'==typeof e[d]&&(e[d]={}),e=e[d];return d.__table__=a.__table__||{},d.__table__[Symbol.for(b)]=e,e},iterator_to_reducer},SpecialForms:{_case:function _case(a,b){return n.Patterns.defmatch(...b)(a)},cond:function cond(...a){for(const b of a)if(b[0])return b[1]();throw new Error},_for:function _for(a,b,c,d=[]){let[e,f]=c.into(d);const g=run_list_generators(b.pop()(),b);for(const h of g)a.guard.apply(this,h)&&(e=f(e,new n.Tuple(Symbol.for('cont'),a.fn.apply(this,h))));return f(e,Symbol.for('done'))},_try:function _try(a,b,c,d,e){let f=null;try{f=a()}catch(a){let d=null;if(b)try{return d=b(a),d}catch(a){if(a instanceof n.Patterns.MatchError)throw a}if(c)try{return d=c(a),d}catch(a){if(a instanceof n.Patterns.MatchError)throw a}throw a}finally{e&&e()}if(d)try{return d(f)}catch(a){if(a instanceof n.Patterns.MatchError)throw new Error('No Match Found in Else');throw a}else return f},_with:function _with(...a){let b=[],c=null,d=null;'function'==typeof a[a.length-2]?[c,d]=a.splice(-2):c=a.pop();for(let c=0;c{const[c,d]=b;return a.set(c,d),a},new Map)},keys:function keys(a){return!1===h.is_map(a)?new d.Tuple(k,a):Array.from(a.keys())},values:function values$1(a){return!1===h.is_map(a)?new d.Tuple(k,a):Array.from(a.values())},is_key,put:function put(a,b,c){if(!1===h.is_map(c))return new d.Tuple(k,c);const e=new Map(c);return e.set(a,b),e},merge:function merge(a,b){return!1===h.is_map(a)?new d.Tuple(k,a):!1===h.is_map(b)?new d.Tuple(k,b):new Map([...a,...b])},update:function update(a,b,c){return!1===h.is_map(c)?new d.Tuple(k,c):!1===is_key(a,c)?new d.Tuple(l,a):new Map([...c,[a,b]])},get:function get(...a){const b=a[0],c=a[1];return!1===h.is_map(c)?new d.Tuple(k,c):is_key(b)?c.get(b):3===a.length?a[2]:new d.Tuple(l,b)},take:function take(a,b){if(!1===h.is_map(b))return new d.Tuple(k,b);if(!is_key(a))return j;const c=b.get(a),e=new Map(b);return e.delete(a),new d.Tuple(c,e)}},lists:{reverse,foreach:function foreach(a,b){return b.forEach((b)=>a(b)),Symbol.for('ok')},duplicate:function duplicate(a,b){const c=[];for(;c.length{if(d.get(c-1)a.get(c-1)?1:0})},keystore:function keystore(a,b,c,d){const e=[...c];for(let f=0;fa.toString()).join()},map:function map(a,b){return b.map((b)=>a(b))},filter:function filter(a,b){return b.filter((b)=>a(b))},filtermap:function filtermap(a,b){const c=[];for(const e of b){const b=a(e);!0===b?c.push(e):b instanceof d.Tuple&&!0===b.get(0)&&c.push(b.get(1))}return c},member:function member(a,b){for(const c of b)if(c===a)return!0;return!1},all:function all(a,b){for(const c of b)if(!1===a(c))return!1;return!0},any:function any(a,b){for(const c of b)if(!0===a(c))return!0;return!1},splitwith:function splitwith(a,b){let c=!1;const e=[],f=[];for(const d of b)!0==c?f.push(d):!0===a(d)?e.push(d):(c=!0,f.push(d));return new d.Tuple(e,f)},sort:function sort(...a){if(1===a.length){const b=[...a[0]];return b.sort()}const c=a[0],b=[...a[1]];return b.sort((d,a)=>{const b=c(d,a);return!0===b?-1:1})}}};return{Core:n}}(); diff --git a/src/javascript/lib/core/erlang_compat/erlang.js b/src/javascript/lib/core/erlang_compat/erlang.js index 5a0bc2d4..338c3a2b 100644 --- a/src/javascript/lib/core/erlang_compat/erlang.js +++ b/src/javascript/lib/core/erlang_compat/erlang.js @@ -174,7 +174,7 @@ function is_list(value) { } function is_map(value) { - return typeof value === 'object' || value instanceof Object; + return value instanceof Map; } function is_pid(value) { @@ -282,7 +282,7 @@ function make_ref() { } function map_size(map) { - return Object.keys(map).length; + return map.size; } function max(first, second) { diff --git a/src/javascript/lib/core/erlang_compat/maps.js b/src/javascript/lib/core/erlang_compat/maps.js index 142a031f..9f0686c3 100644 --- a/src/javascript/lib/core/erlang_compat/maps.js +++ b/src/javascript/lib/core/erlang_compat/maps.js @@ -12,7 +12,7 @@ function find(key, map) { return new ErlangTypes.Tuple(BADMAP, map); } - const value = map[key]; + const value = map.get(key); if (typeof value !== 'undefined') { return new ErlangTypes.Tuple(OK, value); @@ -24,7 +24,7 @@ function find(key, map) { function fold(fun, init, map) { let acc = init; - for (const [key, value] of to_list(map)) { + for (const [key, value] of map.entries()) { acc = fun(key, value, acc); } @@ -36,9 +36,9 @@ function remove(key, map1) { return new ErlangTypes.Tuple(BADMAP, map1); } - const map2 = Object.assign({}, map1); + const map2 = new Map(map1); - delete map2[key]; + map2.delete(key); return map2; } @@ -50,8 +50,8 @@ function to_list(map) { const list = []; - for (const key of keys(map)) { - list.push(new ErlangTypes.Tuple(key, map[key])); + for (const [key, value] of map.entries()) { + list.push(new ErlangTypes.Tuple(key, value)); } return list; @@ -60,10 +60,10 @@ function to_list(map) { function from_list(list) { return list.reduce((acc, item) => { const [key, value] = item; - acc[key] = value; + acc.set(key, value); return acc; - }, {}); + }, new Map()); } function keys(map) { @@ -71,17 +71,7 @@ function keys(map) { return new ErlangTypes.Tuple(BADMAP, map); } - const keys = []; - - for (const key of Object.getOwnPropertySymbols(map)) { - keys.push(key); - } - - for (const key of Object.getOwnPropertyNames(map)) { - keys.push(key); - } - - return keys; + return Array.from(map.keys()); } function values(map) { @@ -89,17 +79,11 @@ function values(map) { return new ErlangTypes.Tuple(BADMAP, map); } - const theValues = []; - - for (const key of keys(map)) { - theValues.push(map[key]); - } - - return theValues; + return Array.from(map.values()); } function is_key(key, map) { - return map.hasOwnProperty(key); + return map.has(key); } function put(key, value, map1) { @@ -107,7 +91,8 @@ function put(key, value, map1) { return new ErlangTypes.Tuple(BADMAP, map1); } - const map2 = Object.assign({}, map1, { [key]: value }); + const map2 = new Map(map1); + map2.set(key, value); return map2; } @@ -121,7 +106,7 @@ function merge(map1, map2) { return new ErlangTypes.Tuple(BADMAP, map2); } - return Object.assign({}, map1, map2); + return new Map([...map1, ...map2]); } function update(key, value, map1) { @@ -133,7 +118,7 @@ function update(key, value, map1) { return new ErlangTypes.Tuple(BADKEY, key); } - return Object.assign({}, map1, { [key]: value }); + return new Map([...map1, [key, value]]); } function get(...args) { @@ -145,7 +130,7 @@ function get(...args) { } if (is_key(key)) { - return map[key]; + return map.get(key); } if (args.length === 3) { @@ -164,9 +149,9 @@ function take(key, map1) { return ERROR; } - const value = map1[key]; - const map2 = Object.assign({}, map1); - delete map2[key]; + const value = map1.get(key); + const map2 = new Map(map1); + map2.delete(key); return new ErlangTypes.Tuple(value, map2); } diff --git a/src/javascript/lib/core/functions.js b/src/javascript/lib/core/functions.js index d315dab9..97a18379 100644 --- a/src/javascript/lib/core/functions.js +++ b/src/javascript/lib/core/functions.js @@ -31,6 +31,28 @@ function call_property(item, property) { return item; } + if (item instanceof Map) { + let prop = null; + + if (item.has(property)) { + prop = property; + } else if (item.has(Symbol.for(property))) { + prop = Symbol.for(property); + } + + if (prop === null) { + throw new Error(`Property ${property} not found in ${item}`); + } + + if ( + item.get(prop) instanceof Function || + typeof item.get(prop) === 'function' + ) { + return item.get(prop)(); + } + return item.get(prop); + } + let prop = null; if ( diff --git a/src/javascript/lib/core/protocol.js b/src/javascript/lib/core/protocol.js index 5ae04ddf..ac292a81 100644 --- a/src/javascript/lib/core/protocol.js +++ b/src/javascript/lib/core/protocol.js @@ -31,12 +31,12 @@ class Protocol { fun = this.registry.get(Core.BitString)[funName]; } else if ( thing && - thing[Symbol.for('__struct__')] && + thing.has(Symbol.for('__struct__')) && this.hasImplementation(thing) ) { - fun = this.registry.get(thing[Symbol.for('__struct__')].__MODULE__)[ - funName - ]; + fun = this.registry.get( + thing.get(Symbol.for('__struct__')).__MODULE__ + )[funName]; } else if (thing !== null && this.hasImplementation(thing)) { fun = this.registry.get(thing.constructor)[funName]; } else if (this.fallback) { @@ -72,8 +72,8 @@ class Protocol { thing === Core.BitString ) { return this.registry.has(thing); - } else if (thing && thing[Symbol.for('__struct__')]) { - return this.registry.has(thing[Symbol.for('__struct__')].__MODULE__); + } else if (thing && thing.has(Symbol.for('__struct__'))) { + return this.registry.has(thing.get(Symbol.for('__struct__')).__MODULE__); } return this.registry.has(thing.constructor); diff --git a/test/support/main.ex b/test/support/main.ex index a18d3d90..a2260e63 100644 --- a/test/support/main.ex +++ b/test/support/main.ex @@ -1,5 +1,7 @@ defmodule Main do def start(:normal, [callback]) do callback.("started") + + Enum.map(1..5, fn(x) -> x * 2 end) end end diff --git a/yarn.lock b/yarn.lock index 4c47311a..0c91a8ec 100644 --- a/yarn.lock +++ b/yarn.lock @@ -605,6 +605,10 @@ babel-plugin-syntax-exponentiation-operator@^6.8.0: version "6.13.0" resolved "https://registry.yarnpkg.com/babel-plugin-syntax-exponentiation-operator/-/babel-plugin-syntax-exponentiation-operator-6.13.0.tgz#9ee7e8337290da95288201a6a57f4170317830de" +babel-plugin-syntax-object-rest-spread@^6.8.0: + version "6.13.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-object-rest-spread/-/babel-plugin-syntax-object-rest-spread-6.13.0.tgz#fd6536f2bce13836ffa3a5458c4903a597bb3bf5" + babel-plugin-syntax-trailing-function-commas@^6.20.0, babel-plugin-syntax-trailing-function-commas@^6.22.0: version "6.22.0" resolved "https://registry.yarnpkg.com/babel-plugin-syntax-trailing-function-commas/-/babel-plugin-syntax-trailing-function-commas-6.22.0.tgz#ba0360937f8d06e40180a43fe0d5616fff532cf3" @@ -809,6 +813,13 @@ babel-plugin-transform-minify-booleans@^6.8.2: version "6.8.2" resolved "https://registry.yarnpkg.com/babel-plugin-transform-minify-booleans/-/babel-plugin-transform-minify-booleans-6.8.2.tgz#8451579f706e702c1e1ab2756de5c8ea369cf07c" +babel-plugin-transform-object-rest-spread@^6.23.0: + version "6.23.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-object-rest-spread/-/babel-plugin-transform-object-rest-spread-6.23.0.tgz#875d6bc9be761c58a2ae3feee5dc4895d8c7f921" + dependencies: + babel-plugin-syntax-object-rest-spread "^6.8.0" + babel-runtime "^6.22.0" + babel-plugin-transform-property-literals@^6.8.4: version "6.8.4" resolved "https://registry.yarnpkg.com/babel-plugin-transform-property-literals/-/babel-plugin-transform-property-literals-6.8.4.tgz#6ad311110b80a192a56efb5ddf4fe3ca6f7a61da" @@ -3678,9 +3689,9 @@ table@^4.0.1: slice-ansi "0.0.4" string-width "^2.0.0" -tailored@^2.6.0: - version "2.6.0" - resolved "https://registry.yarnpkg.com/tailored/-/tailored-2.6.0.tgz#70ae98b8f8bfb25ce320290c103cbc23aae4cf2a" +tailored@^2.6.1: + version "2.6.1" + resolved "https://registry.yarnpkg.com/tailored/-/tailored-2.6.1.tgz#afac1114f4622eceba11d87fcc35b42a658ded84" dependencies: erlang-types "^1.0.1" From 049d1b4444102652ae0c7e3372e798221189ba19 Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Wed, 19 Jul 2017 20:24:48 -0500 Subject: [PATCH 180/418] Remove mutate/2 Fix broken tests --- CHANGELOG.md | 1 - lib/elixir_script/lib/js.ex | 9 +-- test/passes/translate/forms/js_test.exs | 34 +-------- test/passes/translate/forms/map_test.exs | 87 +++++++++++++----------- 4 files changed, 52 insertions(+), 79 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c164ace1..fb472034 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,7 +8,6 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ### Added - ElixirScript now has an FFI layer for interoperability with JavaScript. For more details, see documentation at `ElixirScript.FFI` -- ElixirScript.JS.mutate/2 - ElixirScript.JS.mutate/3 ### Changed diff --git a/lib/elixir_script/lib/js.ex b/lib/elixir_script/lib/js.ex index 2c14151c..44f55f5a 100644 --- a/lib/elixir_script/lib/js.ex +++ b/lib/elixir_script/lib/js.ex @@ -38,17 +38,10 @@ defmodule ElixirScript.JS do """ defmacro this() - @doc """ - Mutates an existing JavaScript object. - ex: - ElixirScript.JS.mutate elem, %{"width" => 100} - """ - defmacro update(object, map) - @doc """ Mutates an existing JavaScript object. ex: ElixirScript.JS.mutate elem, "width", 100 """ - defmacro update(object, key, value) + defmacro mutate(object, key, value) end diff --git a/test/passes/translate/forms/js_test.exs b/test/passes/translate/forms/js_test.exs index 7afd866c..d9f556cd 100644 --- a/test/passes/translate/forms/js_test.exs +++ b/test/passes/translate/forms/js_test.exs @@ -65,48 +65,18 @@ defmodule ElixirScript.Translate.Forms.JS.Test do ) end - test "mutate/2" do - properties = [{"a", 1}] - map_ast = {:%{}, [], properties} - - ast = {{:., [], [ElixirScript.JS, :mutate]}, [], [{:%{}, [], []}, map_ast]} - state = %{function: {:each, nil}, module: Enum, vars: %{:_ => 0, "entry" => 0, "enumerable" => 0, "fun" => 0}} - - {js_ast, _} = Form.compile(ast, state) - assert js_ast == J.call_expression( - J.member_expression( - J.identifier("Object"), - J.identifier("assign") - ), - [ - J.object_expression([]), - J.object_expression([ - J.property( - J.identifier("a"), - J.literal(1) - ) - ]) - ] - ) - end - test "mutate/3" do properties = [{"a", 1}] map_ast = {:%{}, [], properties} - ast = {{:., [], [ElixirScript.JS, :mutate]}, [], [map_ast, "a", 2]} + ast = {{:., [], [ElixirScript.JS, :mutate]}, [], [{:entry, [], nil}, "a", 2]} state = %{function: {:each, nil}, module: Enum, vars: %{:_ => 0, "entry" => 0, "enumerable" => 0, "fun" => 0}} {js_ast, _} = Form.compile(ast, state) assert js_ast == J.assignment_expression( :=, J.member_expression( - J.object_expression([ - J.property( - J.identifier("a"), - J.literal(1) - ) - ]), + J.identifier("entry0"), J.literal("a"), true ), diff --git a/test/passes/translate/forms/map_test.exs b/test/passes/translate/forms/map_test.exs index ad826766..a94b454a 100644 --- a/test/passes/translate/forms/map_test.exs +++ b/test/passes/translate/forms/map_test.exs @@ -9,19 +9,23 @@ defmodule ElixirScript.Translate.Forms.Map.Test do state = %{} {js_ast, _} = Form.compile(ast, state) - assert js_ast == J.object_expression([ - J.property( - J.call_expression( - J.member_expression( - J.identifier("Symbol"), - J.identifier("for") - ), - [J.literal(:a)] - ), - J.literal(1), - :init, false, false, true - ) - ]) + assert js_ast == J.new_expression( + J.identifier("Map"), + [ + J.array_expression([ + J.array_expression([ + J.call_expression( + J.member_expression( + J.identifier("Symbol"), + J.identifier("for") + ), + [J.literal(:a)] + ), + J.literal(1), + ]) + ]) + ] + ) end test "map with string key" do @@ -30,12 +34,17 @@ defmodule ElixirScript.Translate.Forms.Map.Test do state = %{} {js_ast, _} = Form.compile(ast, state) - assert js_ast == J.object_expression([ - J.property( - J.identifier("a"), - J.literal(1) - ) - ]) + assert js_ast == J.new_expression( + J.identifier("Map"), + [ + J.array_expression([ + J.array_expression([ + J.literal("a"), + J.literal(1), + ]) + ]) + ] + ) end @@ -47,28 +56,30 @@ defmodule ElixirScript.Translate.Forms.Map.Test do ast = {:%{}, [], [{:|, [], [map_ast, new_values]}]} + map_ast = J.new_expression( + J.identifier("Map"), + [ + J.array_expression([ + J.array_expression([ + J.literal("a"), + J.literal(1), + ]) + ]) + ] + ) + {js_ast, _} = Form.compile(ast, state) - assert js_ast == J.call_expression( - J.member_expression( - J.identifier("Object"), - J.identifier("assign") - ), + assert js_ast == J.new_expression( + J.identifier("Map"), [ - J.object_expression([]), - J.object_expression([ - J.property( - J.identifier("a"), - J.literal(1) - ) - ]), - J.object_expression([ - J.property( - J.identifier("a"), - J.literal(2) - ) - ]) + J.array_expression( + [J.spread_element(map_ast)] ++ [J.array_expression([ + J.literal("a"), + J.literal(2) + ])] + ) ] ) end -end \ No newline at end of file +end From cf00817fff9e288b67151c69cb15078ba7d55590 Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Thu, 20 Jul 2017 19:53:51 -0500 Subject: [PATCH 181/418] Add ElixirScript.JS.map_to_object/1 --- lib/elixir_script/lib/js.ex | 10 ++++++++++ .../passes/translate/forms/js.ex | 20 ++++++++++++++++++- priv/build/iife/ElixirScript.Core.js | 4 ++-- src/javascript/lib/core/functions.js | 17 +++++++++++++++- 4 files changed, 47 insertions(+), 4 deletions(-) diff --git a/lib/elixir_script/lib/js.ex b/lib/elixir_script/lib/js.ex index 44f55f5a..8e255cfc 100644 --- a/lib/elixir_script/lib/js.ex +++ b/lib/elixir_script/lib/js.ex @@ -44,4 +44,14 @@ defmodule ElixirScript.JS do ElixirScript.JS.mutate elem, "width", 100 """ defmacro mutate(object, key, value) + + + @doc """ + Takes the given map and returns an object + Throws an error if any key is not a + number, binary, or atom + ex: + ElixirScript.JS.map_to_object(%{my: "map"}) + """ + defmacro map_to_object(object) end diff --git a/lib/elixir_script/passes/translate/forms/js.ex b/lib/elixir_script/passes/translate/forms/js.ex index b4c7c614..a55f0899 100644 --- a/lib/elixir_script/passes/translate/forms/js.ex +++ b/lib/elixir_script/passes/translate/forms/js.ex @@ -91,8 +91,26 @@ defmodule ElixirScript.Translate.Forms.JS do Form.compile!(key, state), true ), + Form.compile!(value, state) + ) + + {ast, state} + end + + def compile({{:., _, [ElixirScript.JS, :map_to_object]}, _, [object]}, state) do + ast = J.call_expression( + J.member_expression( + J.member_expression( + J.identifier("ElixirScript"), + J.member_expression( + J.identifier("Core"), + J.identifier("Functions") + ) + ), + J.identifier("map_to_object") + ), [ - Form.compile!(value, state) + Form.compile!(object, state) ] ) diff --git a/priv/build/iife/ElixirScript.Core.js b/priv/build/iife/ElixirScript.Core.js index 45c27597..42035b8b 100644 --- a/priv/build/iife/ElixirScript.Core.js +++ b/priv/build/iife/ElixirScript.Core.js @@ -1,6 +1,6 @@ -var ElixirScript=function(){'use strict';/* @flow */function namedVariableResult(a,b){return new NamedVariableResult(a,b)}/* @flow */function is_number(a){return'number'==typeof a}function is_string(a){return'string'==typeof a}function is_boolean(a){return'boolean'==typeof a}function is_symbol(a){return'symbol'==typeof a}function is_object(a){return'object'==typeof a}function is_variable(a){return a instanceof Variable}function is_null(a){return null===a}function is_array(a){return Array.isArray(a)}function is_function(a){return'[object Function]'==Object.prototype.toString.call(a)}function is_map(a){return a instanceof Map}function resolveNull(){return function(a){return is_null(a)}}function resolveWildcard(){return function(){return!0}}function resolveObject(a){let b={};const c=Object.keys(a).concat(Object.getOwnPropertySymbols(a));for(let d of c)b[d]=buildMatch(a[d]);return function(d,e){if(!is_object(d)||a.length>d.length)return!1;for(let a of c)if(!(a in d)||!b[a](d[a],e))return!1;return!0}}function getSize(a,b){return a*b/8}function arraysEqual(c,a){if(c===a)return!0;if(null==c||null==a)return!1;if(c.length!=a.length)return!1;for(var b=0;be.integer(a));return new e(...b)}function resolveNoMatch(){return function(){return!1}}function buildMatch(a){if(null===a)return resolveNull(a);if('undefined'==typeof a)return resolveWildcard(a);const b=a.constructor.prototype,c=f.get(b);return c?c(a):'object'==typeof a?resolveObject(a):resolveNoMatch()}function defmatchgen(...a){const b=getArityMap(a);return function*(...a){let[c,d]=findMatchingFunction(a,b);return yield*c.apply(this,d)}}function findMatchingFunction(a,b){if(b.has(a.length)){const c=b.get(a.length);let d=null,e=null;for(let b of c){let c=[];a=fillInOptionalValues(a,b.arity,b.optionals);const f=b.pattern(a,c),[g,h]=checkNamedVariables(c);if(f&&h&&b.guard.apply(this,g)){d=b.fn,e=g;break}}if(!d)throw console.error('No match for:',a),new MatchError(a);return[d,e]}throw console.error('Arity of',a.length,'not found. No match for:',a),new MatchError(a)}function getArityMap(a){let b=new Map;for(const c of a){const a=getArityRange(c);for(const d of a){let a=[];b.has(d)&&(a=b.get(d)),a.push(c),b.set(d,a)}}return b}function getArityRange(a){const b=a.arity-a.optionals.length,c=a.arity;let d=[b];for(;d[d.length-1]!=c;)d.push(d[d.length-1]+1);return d}function getOptionalValues(a){let b=[];for(let c=0;c!0,d=null){let e=[],f=buildMatch(a);const g=f(b,e),[h,i]=checkNamedVariables(e);return g&&i&&c.apply(this,h)?h:d}function run_generators(a,b){if(0==b.length)return a.map((a)=>{return Array.isArray(a)?a:[a]});const c=b.pop();let d=[];for(let e of c())for(let b of a)d.push([e].concat(b));return run_generators(d,b)}function iterator_to_reducer(a,b,c){const d=a[Symbol.iterator]();let e=d.next(),f=b;for(;!1===e.done;){if(f=c(e.value,f.get(1)),f.get(0)===Symbol.for('halt'))return new n.Tuple(Symbol.for('halted'),f.get(1));if(f.get(0)===Symbol.for('suspend'))return new n.Tuple(Symbol.for('suspended'),f.get(1),(a)=>{return iterator_to_reducer(d,a,c)});e=d.next()}return new n.Tuple(Symbol.for('done'),f.get(1))}function run_list_generators(a,b){if(0==b.length)return a.map((a)=>{return Array.isArray(a)?a:[a]});const c=b.pop(),d=[];for(const e of c())for(const b of a)d.push([e].concat(b));return run_list_generators(d,b)}// http://erlang.org/doc/man/erlang.html +var ElixirScript=function(){'use strict';/* @flow */function namedVariableResult(a,b){return new NamedVariableResult(a,b)}/* @flow */function is_number(a){return'number'==typeof a}function is_string(a){return'string'==typeof a}function is_boolean(a){return'boolean'==typeof a}function is_symbol(a){return'symbol'==typeof a}function is_object(a){return'object'==typeof a}function is_variable(a){return a instanceof Variable}function is_null(a){return null===a}function is_array(a){return Array.isArray(a)}function is_function(a){return'[object Function]'==Object.prototype.toString.call(a)}function is_map(a){return a instanceof Map}function resolveNull(){return function(a){return is_null(a)}}function resolveWildcard(){return function(){return!0}}function resolveObject(a){let b={};const c=Object.keys(a).concat(Object.getOwnPropertySymbols(a));for(let d of c)b[d]=buildMatch(a[d]);return function(d,e){if(!is_object(d)||a.length>d.length)return!1;for(let a of c)if(!(a in d)||!b[a](d[a],e))return!1;return!0}}function getSize(a,b){return a*b/8}function arraysEqual(c,a){if(c===a)return!0;if(null==c||null==a)return!1;if(c.length!=a.length)return!1;for(var b=0;be.integer(a));return new e(...b)}function resolveNoMatch(){return function(){return!1}}function buildMatch(a){if(null===a)return resolveNull(a);if('undefined'==typeof a)return resolveWildcard(a);const b=a.constructor.prototype,c=f.get(b);return c?c(a):'object'==typeof a?resolveObject(a):resolveNoMatch()}function defmatchgen(...a){const b=getArityMap(a);return function*(...a){let[c,d]=findMatchingFunction(a,b);return yield*c.apply(this,d)}}function findMatchingFunction(a,b){if(b.has(a.length)){const c=b.get(a.length);let d=null,e=null;for(let b of c){let c=[];a=fillInOptionalValues(a,b.arity,b.optionals);const f=b.pattern(a,c),[g,h]=checkNamedVariables(c);if(f&&h&&b.guard.apply(this,g)){d=b.fn,e=g;break}}if(!d)throw console.error('No match for:',a),new MatchError(a);return[d,e]}throw console.error('Arity of',a.length,'not found. No match for:',a),new MatchError(a)}function getArityMap(a){let b=new Map;for(const c of a){const a=getArityRange(c);for(const d of a){let a=[];b.has(d)&&(a=b.get(d)),a.push(c),b.set(d,a)}}return b}function getArityRange(a){const b=a.arity-a.optionals.length,c=a.arity;let d=[b];for(;d[d.length-1]!=c;)d.push(d[d.length-1]+1);return d}function getOptionalValues(a){let b=[];for(let c=0;c!0,d=null){let e=[],f=buildMatch(a);const g=f(b,e),[h,i]=checkNamedVariables(e);return g&&i&&c.apply(this,h)?h:d}function run_generators(a,b){if(0==b.length)return a.map((a)=>{return Array.isArray(a)?a:[a]});const c=b.pop();let d=[];for(let e of c())for(let b of a)d.push([e].concat(b));return run_generators(d,b)}function iterator_to_reducer(a,b,c){const d=a[Symbol.iterator]();let e=d.next(),f=b;for(;!1===e.done;){if(f=c(e.value,f.get(1)),f.get(0)===Symbol.for('halt'))return new n.Tuple(Symbol.for('halted'),f.get(1));if(f.get(0)===Symbol.for('suspend'))return new n.Tuple(Symbol.for('suspended'),f.get(1),(a)=>{return iterator_to_reducer(d,a,c)});e=d.next()}return new n.Tuple(Symbol.for('done'),f.get(1))}function map_to_object(a){const b={};for(const[c,d]of a.entries())b[c]=d instanceof Map?map_to_object(d):d;return b}function run_list_generators(a,b){if(0==b.length)return a.map((a)=>{return Array.isArray(a)?a:[a]});const c=b.pop(),d=[];for(const e of c())for(const b of a)d.push([e].concat(b));return run_list_generators(d,b)}// http://erlang.org/doc/man/erlang.html function atom_to_binary(a,b=Symbol.for('utf8')){if(b!==Symbol.for('utf8'))throw new Error(`unsupported encoding ${b}`);return a.__MODULE__?Symbol.keyFor(a.__MODULE__):Symbol.keyFor(a)}function binary_to_atom(a,b=Symbol.for('utf8')){if(b!==Symbol.for('utf8'))throw new Error(`unsupported encoding ${b}`);return Symbol.for(a)}function is_number$1(a){return'number'==typeof a||a instanceof Number}function is_key(a,b){return b.has(a)}// http://erlang.org/doc/man/lists.html function reverse(a){return[...a]}function flatten(a,b=[]){const c=a.reduce((a,b)=>{return Array.isArray(b)?a.concat(flatten(b)):a.concat(b)},[]);return c.concat(b)}function foldl(a,b,c){return c.reduce((b,c)=>{return a(c,b)},b)}function keyfind(a,b,c){for(const d of c)if(d.get(b-1)===a)return d;return!1}function keydelete(a,b,c){const d=[];let e=!1;for(let f=0;fBitString$1.integer(a));return new BitString$1(...d)}[Symbol.iterator](){return this.value[Symbol.iterator]()}toString(){var a,b='';for(a=0;a>'}process(a){let b=[];var c;for(c=0;cb?c.push(b):2048>b?c.push(192|b>>6,128|63&b):55296>b||57344<=b?c.push(224|b>>12,128|63&b>>6,128|63&b):(d++,b=65536+((1023&b)<<10|1023&a.charCodeAt(d)),c.push(240|b>>18,128|63&b>>12,128|63&b>>6,128|63&b));return c}static toUTF16Array(a){for(var b,c=[],d=0;d=b?(c.push(0),c.push(b)):(c.push(255&b>>8),c.push(255&b));return c}static toUTF32Array(a){for(var b,c=[],d=0;d=b?(c.push(0),c.push(0),c.push(0),c.push(b)):(c.push(0),c.push(0),c.push(255&b>>8),c.push(255&b));return c}//http://stackoverflow.com/questions/2003493/javascript-float-from-to-bits static float32ToBytes(a){var b=[],c=new ArrayBuffer(4);new Float32Array(c)[0]=a;let d=new Uint32Array(c)[0];return b.push(255&d>>24),b.push(255&d>>16),b.push(255&d>>8),b.push(255&d),b}static float64ToBytes(a){var b=[],c=new ArrayBuffer(8);new Float64Array(c)[0]=a;var d=new Uint32Array(c)[0],e=new Uint32Array(c)[1];return b.push(255&e>>24),b.push(255&e>>16),b.push(255&e>>8),b.push(255&e),b.push(255&d>>24),b.push(255&d>>16),b.push(255&d>>8),b.push(255&d),b}}var d={Tuple,PID:class PID{constructor(){++b,this.id=b}toString(){return'PID#<0.'+this.id+'.0>'}},Reference:class Reference{constructor(){++c,this.id=c,this.ref=Symbol()}toString(){return'Ref#<0.0.0.'+this.id+'>'}},BitString:BitString$1};/* @flow */const e=d.BitString,f=new Map;f.set(Variable.prototype,function resolveVariable(a){return function(b,c){return null===a.name||a.name.startsWith('_')?c.push(b):c.push(namedVariableResult(a.name,b)),!0}}),f.set(Wildcard.prototype,resolveWildcard),f.set(HeadTail.prototype,function resolveHeadTail(){return function(a,b){if(!is_array(a)||2>a.length)return!1;const c=a[0],d=a.slice(1);return b.push(c),b.push(d),!0}}),f.set(StartsWith.prototype,function resolveStartsWith(a){const b=a.prefix;return function(a,c){return is_string(a)&&a.startsWith(b)&&(c.push(a.substring(b.length)),!0)}}),f.set(Capture.prototype,function resolveCapture(a){const b=buildMatch(a.value);return function(a,c){return!!b(a,c)&&(c.push(a),!0)}}),f.set(Bound.prototype,function resolveBound(a){return function(b){return typeof b==typeof a.value&&b===a.value}}),f.set(Type.prototype,function resolveType(a){return function(b,c){if(b instanceof a.type){const d=buildMatch(a.objPattern);return d(b,c)}return!1}}),f.set(BitStringMatch.prototype,function resolveBitString(a){let b=[];for(let c of a.values)if(is_variable(c.value)){let a=getSize(c.unit,c.size);fillArray(b,a)}else b=b.concat(new e(c).value);let c=a.values;return function(a,d){var f=String.fromCharCode;let g=null;if(!is_string(a)&&!(a instanceof e))return!1;g=is_string(a)?new e(e.binary(a)):a;let h=0;for(let e,j=0;jd.size)return!1;for(let a of c)if(!d.has(a)||!b.get(a)(d.get(a),e))return!1;return!0}}),f.set(Array.prototype,function resolveArray(a){const b=a.map((a)=>buildMatch(a));return function(c,d){return is_array(c)&&c.length==a.length&&c.every(function(a,e){return b[e](c[e],d)})}}),f.set(String.prototype,function resolveString(a){return function(b){return is_string(b)&&b===a}}),f.set(Boolean.prototype,function resolveBoolean(a){return function(b){return is_boolean(b)&&b===a}}),f.set(Function.prototype,function resolveFunction(a){return function(b){return is_function(b)&&b===a}}),f.set(Object.prototype,resolveObject);class MatchError extends Error{constructor(a){if(super(),'symbol'==typeof a)this.message='No match for: '+a.toString();else if(Array.isArray(a)){let b=a.map((a)=>{return null===a?'null':'undefined'==typeof a?'undefined':a.toString()});this.message='No match for: '+b}else this.message='No match for: '+a;this.stack=new Error().stack,this.name=this.constructor.name}}class Clause{constructor(a,b,c=()=>!0){this.pattern=buildMatch(a),this.arity=a.length,this.optionals=getOptionalValues(a),this.fn=b,this.guard=c}}const g=Symbol();// https://github.com/airportyh/protomorphism class Protocol{constructor(b){function createFun(b){return function(...c){const d=c[0];let e=null;if(null===d&&this.hasImplementation(Symbol('null'))?e=this.registry.get(Symbol)[b]:a(d)&&this.hasImplementation(n.Integer)?e=this.registry.get(n.Integer)[b]:'number'==typeof d&&!a(d)&&this.hasImplementation(n.Float)?e=this.registry.get(n.Float)[b]:'string'==typeof d&&this.hasImplementation(n.BitString)?e=this.registry.get(n.BitString)[b]:d&&d.has(Symbol.for('__struct__'))&&this.hasImplementation(d)?e=this.registry.get(d.get(Symbol.for('__struct__')).__MODULE__)[b]:null!==d&&this.hasImplementation(d)?e=this.registry.get(d.constructor)[b]:this.fallback&&(e=this.fallback[b]),null!=e){const a=e.apply(this,c);return a}throw new Error(`No implementation found for ${d}`)}}for(const a in this.registry=new Map,this.fallback=null,b)this[a]=createFun(a).bind(this)}implementation(a,b){null===a?this.fallback=b:this.registry.set(a,b)}hasImplementation(a){if(a===n.Integer||a===n.Float||a===n.BitString)return this.registry.has(a);return a&&a.has(Symbol.for('__struct__'))?this.registry.has(a.get(Symbol.for('__struct__')).__MODULE__):this.registry.has(a.constructor)}}var h={atom_to_binary,binary_to_atom,binary_to_existing_atom:function binary_to_existing_atom(a,b=Symbol.for('utf8')){return binary_to_atom(a,b)},list_concatenation:function list_concatenation(a,b){return a.concat(b)},list_subtraction:function list_subtraction(a,b){const c=[...a];for(const d of b){const a=c.indexOf(d);-1b},greaterThanOrEqualTo:function greaterThanOrEqualTo(a,b){return a>=b},lessThan:function lessThan(a,b){return a>b},bxor:function bxor(a,b){return a^b},bnot:function bnot(a){return~a},is_bitstring:function is_bitstring$1(a){return a instanceof d.BitString},is_boolean:function is_boolean$1(a){return'boolean'==typeof a||a instanceof Boolean},is_float:function is_float(b){return is_number$1(b)&&!a(b)},is_function:function is_function$1(a){return'function'==typeof a||a instanceof Function},is_integer:function is_integer(b){return a(b)},is_list:function is_list(a){return Array.isArray(a)},is_map:function is_map$1(a){return a instanceof Map},is_number:is_number$1,is_pid:function is_pid(a){return a instanceof d.PID},is_port:function is_port(){return!1},is_reference:function is_reference(a){return a instanceof d.Reference},is_tuple:function is_tuple(a){return a instanceof d.Tuple},is_atom:function is_atom(a){return'symbol'==typeof a||a instanceof Symbol||a.__MODULE__},is_binary:function is_binary(a){return'string'==typeof a||a instanceof String},element:function element(a,b){return b.get(a-1)},setelement:function setelement(a,b,c){const e=[...b.values];return e[a-1]=c,new d.Tuple(...e)},make_tuple:function make_tuple(a,b){const c=[];for(let d=0;d!0){let d=[],e=buildMatch(a);const f=e(b,d),[g,h]=checkNamedVariables(d);if(f&&h&&c.apply(this,g))return g;throw console.error('No match for:',b),new MatchError(b)},MatchError,variable:function variable(a=null,b=Symbol.for('tailored.no_value')){return new Variable(a,b)},wildcard:function wildcard(){return new Wildcard},startsWith:function startsWith(a){return new StartsWith(a)},capture:function capture(a){return new Capture(a)},headTail:function headTail(){return new HeadTail},type:function a(a,b={}){return new Type(a,b)},bound:function bound(a){return new Bound(a)},Clause,clause:function clause(a,b,c=()=>!0){return new Clause(a,b,c)},bitStringMatch:function bitStringMatch(...a){return new BitStringMatch(...a)},match_or_default,defmatchgen,list_comprehension:function list_comprehension(a,b){const c=run_generators(b.pop()(),b);let d=[];for(let e of c)a.guard.apply(this,e)&&d.push(a.fn.apply(this,e));return d},list_generator:function list_generator(a,b){return function(){let c=[];for(let d of b){const b=match_or_default(a,d,()=>!0,g);if(b!=g){const[a]=b;c.push(a)}}return c}},bitstring_generator:function bitstring_generator(a,b){return function(){let c=[],d=b.slice(0,a.byte_size()),e=1;for(;d.byte_size==a.byte_size();){const f=match_or_default(a,d,()=>!0,g);if(f!=g){c.push(f)}d=b.slice(a.byte_size()*e,a.byte_size()*(e+1)),e++}return c}},bitstring_comprehension:function bitstring_comprehension(a,b){const c=run_generators(b.pop()(),b);let e=[];for(let d of c)a.guard.apply(this,d)&&e.push(a.fn.apply(this,d));return e=e.map((a)=>d.BitString.integer(a)),new d.BitString(...e)},defmatchGen:function defmatchGen(...a){return defmatchgen(...a)},defmatchAsync:function defmatchAsync(...a){const b=getArityMap(a);return async function(...a){if(b.has(a.length)){const c=b.get(a.length);let d=null,e=null;for(let b of c){let c=[];a=fillInOptionalValues(a,b.arity,b.optionals);const f=b.pattern(a,c),[g,h]=checkNamedVariables(c);if(f&&h&&(await b.guard.apply(this,c))){d=b.fn,e=c;break}}if(!d)throw console.error('No match for:',a),new MatchError(a);return d.apply(this,e)}throw console.error('Arity of',a.length,'not found. No match for:',a),new MatchError(a)}}},Integer:class Integer{},Float:class Float{},Functions:{call_property:function call_property(a,b){if(!b)return a instanceof Function||'function'==typeof a?a():a;if(a instanceof Map){let c=null;if(a.has(b)?c=b:a.has(Symbol.for(b))&&(c=Symbol.for(b)),null===c)throw new Error(`Property ${b} not found in ${a}`);return a.get(c)instanceof Function||'function'==typeof a.get(c)?a.get(c)():a.get(c)}let c=null;if('number'==typeof a||'symbol'==typeof a||'boolean'==typeof a||'string'==typeof a?void 0===a[b]?void 0!==a[Symbol.for(b)]&&(c=Symbol.for(b)):c=b:b in a?c=b:Symbol.for(b)in a&&(c=Symbol.for(b)),null===c)throw new Error(`Property ${b} not found in ${a}`);return a[c]instanceof Function||'function'==typeof a[c]?a[c]():a[c]},defprotocol:function defprotocol(a){return new Protocol(a)},defimpl:function defimpl(a,b,c){a.implementation(b,c)},build_namespace:function build_namespace(a,b){let c=b.split('.');const d=a;let e=a;'Elixir'===c[0]&&(c=c.slice(1));for(const d of c)'undefined'==typeof e[d]&&(e[d]={}),e=e[d];return d.__table__=a.__table__||{},d.__table__[Symbol.for(b)]=e,e},iterator_to_reducer},SpecialForms:{_case:function _case(a,b){return n.Patterns.defmatch(...b)(a)},cond:function cond(...a){for(const b of a)if(b[0])return b[1]();throw new Error},_for:function _for(a,b,c,d=[]){let[e,f]=c.into(d);const g=run_list_generators(b.pop()(),b);for(const h of g)a.guard.apply(this,h)&&(e=f(e,new n.Tuple(Symbol.for('cont'),a.fn.apply(this,h))));return f(e,Symbol.for('done'))},_try:function _try(a,b,c,d,e){let f=null;try{f=a()}catch(a){let d=null;if(b)try{return d=b(a),d}catch(a){if(a instanceof n.Patterns.MatchError)throw a}if(c)try{return d=c(a),d}catch(a){if(a instanceof n.Patterns.MatchError)throw a}throw a}finally{e&&e()}if(d)try{return d(f)}catch(a){if(a instanceof n.Patterns.MatchError)throw new Error('No Match Found in Else');throw a}else return f},_with:function _with(...a){let b=[],c=null,d=null;'function'==typeof a[a.length-2]?[c,d]=a.splice(-2):c=a.pop();for(let c=0;c{const[c,d]=b;return a.set(c,d),a},new Map)},keys:function keys(a){return!1===h.is_map(a)?new d.Tuple(k,a):Array.from(a.keys())},values:function values$1(a){return!1===h.is_map(a)?new d.Tuple(k,a):Array.from(a.values())},is_key,put:function put(a,b,c){if(!1===h.is_map(c))return new d.Tuple(k,c);const e=new Map(c);return e.set(a,b),e},merge:function merge(a,b){return!1===h.is_map(a)?new d.Tuple(k,a):!1===h.is_map(b)?new d.Tuple(k,b):new Map([...a,...b])},update:function update(a,b,c){return!1===h.is_map(c)?new d.Tuple(k,c):!1===is_key(a,c)?new d.Tuple(l,a):new Map([...c,[a,b]])},get:function get(...a){const b=a[0],c=a[1];return!1===h.is_map(c)?new d.Tuple(k,c):is_key(b)?c.get(b):3===a.length?a[2]:new d.Tuple(l,b)},take:function take(a,b){if(!1===h.is_map(b))return new d.Tuple(k,b);if(!is_key(a))return j;const c=b.get(a),e=new Map(b);return e.delete(a),new d.Tuple(c,e)}},lists:{reverse,foreach:function foreach(a,b){return b.forEach((b)=>a(b)),Symbol.for('ok')},duplicate:function duplicate(a,b){const c=[];for(;c.length{if(d.get(c-1)a.get(c-1)?1:0})},keystore:function keystore(a,b,c,d){const e=[...c];for(let f=0;fa.toString()).join()},map:function map(a,b){return b.map((b)=>a(b))},filter:function filter(a,b){return b.filter((b)=>a(b))},filtermap:function filtermap(a,b){const c=[];for(const e of b){const b=a(e);!0===b?c.push(e):b instanceof d.Tuple&&!0===b.get(0)&&c.push(b.get(1))}return c},member:function member(a,b){for(const c of b)if(c===a)return!0;return!1},all:function all(a,b){for(const c of b)if(!1===a(c))return!1;return!0},any:function any(a,b){for(const c of b)if(!0===a(c))return!0;return!1},splitwith:function splitwith(a,b){let c=!1;const e=[],f=[];for(const d of b)!0==c?f.push(d):!0===a(d)?e.push(d):(c=!0,f.push(d));return new d.Tuple(e,f)},sort:function sort(...a){if(1===a.length){const b=[...a[0]];return b.sort()}const c=a[0],b=[...a[1]];return b.sort((d,a)=>{const b=c(d,a);return!0===b?-1:1})}}};return{Core:n}}(); +const i=Symbol.for('ok'),j=Symbol.for('error'),k=Symbol.for('badmap'),l=Symbol.for('badkey');const m=function get_global(){return'undefined'==typeof self?'undefined'==typeof window?'undefined'==typeof global?(console.warn('No global state found'),null):global:window:self}();m.__elixirscript_store__=new Map,m.__elixirscript_names__=new Map;var n={Tuple:d.Tuple,PID:d.PID,BitString:d.BitString,Patterns:{defmatch:function defmatch(...a){const b=getArityMap(a);return function(...a){let[c,d]=findMatchingFunction(a,b);return c.apply(this,d)}},match:function match(a,b,c=()=>!0){let d=[],e=buildMatch(a);const f=e(b,d),[g,h]=checkNamedVariables(d);if(f&&h&&c.apply(this,g))return g;throw console.error('No match for:',b),new MatchError(b)},MatchError,variable:function variable(a=null,b=Symbol.for('tailored.no_value')){return new Variable(a,b)},wildcard:function wildcard(){return new Wildcard},startsWith:function startsWith(a){return new StartsWith(a)},capture:function capture(a){return new Capture(a)},headTail:function headTail(){return new HeadTail},type:function a(a,b={}){return new Type(a,b)},bound:function bound(a){return new Bound(a)},Clause,clause:function clause(a,b,c=()=>!0){return new Clause(a,b,c)},bitStringMatch:function bitStringMatch(...a){return new BitStringMatch(...a)},match_or_default,defmatchgen,list_comprehension:function list_comprehension(a,b){const c=run_generators(b.pop()(),b);let d=[];for(let e of c)a.guard.apply(this,e)&&d.push(a.fn.apply(this,e));return d},list_generator:function list_generator(a,b){return function(){let c=[];for(let d of b){const b=match_or_default(a,d,()=>!0,g);if(b!=g){const[a]=b;c.push(a)}}return c}},bitstring_generator:function bitstring_generator(a,b){return function(){let c=[],d=b.slice(0,a.byte_size()),e=1;for(;d.byte_size==a.byte_size();){const f=match_or_default(a,d,()=>!0,g);if(f!=g){c.push(f)}d=b.slice(a.byte_size()*e,a.byte_size()*(e+1)),e++}return c}},bitstring_comprehension:function bitstring_comprehension(a,b){const c=run_generators(b.pop()(),b);let e=[];for(let d of c)a.guard.apply(this,d)&&e.push(a.fn.apply(this,d));return e=e.map((a)=>d.BitString.integer(a)),new d.BitString(...e)},defmatchGen:function defmatchGen(...a){return defmatchgen(...a)},defmatchAsync:function defmatchAsync(...a){const b=getArityMap(a);return async function(...a){if(b.has(a.length)){const c=b.get(a.length);let d=null,e=null;for(let b of c){let c=[];a=fillInOptionalValues(a,b.arity,b.optionals);const f=b.pattern(a,c),[g,h]=checkNamedVariables(c);if(f&&h&&(await b.guard.apply(this,c))){d=b.fn,e=c;break}}if(!d)throw console.error('No match for:',a),new MatchError(a);return d.apply(this,e)}throw console.error('Arity of',a.length,'not found. No match for:',a),new MatchError(a)}}},Integer:class Integer{},Float:class Float{},Functions:{call_property:function call_property(a,b){if(!b)return a instanceof Function||'function'==typeof a?a():a;if(a instanceof Map){let c=null;if(a.has(b)?c=b:a.has(Symbol.for(b))&&(c=Symbol.for(b)),null===c)throw new Error(`Property ${b} not found in ${a}`);return a.get(c)instanceof Function||'function'==typeof a.get(c)?a.get(c)():a.get(c)}let c=null;if('number'==typeof a||'symbol'==typeof a||'boolean'==typeof a||'string'==typeof a?void 0===a[b]?void 0!==a[Symbol.for(b)]&&(c=Symbol.for(b)):c=b:b in a?c=b:Symbol.for(b)in a&&(c=Symbol.for(b)),null===c)throw new Error(`Property ${b} not found in ${a}`);return a[c]instanceof Function||'function'==typeof a[c]?a[c]():a[c]},defprotocol:function defprotocol(a){return new Protocol(a)},defimpl:function defimpl(a,b,c){a.implementation(b,c)},build_namespace:function build_namespace(a,b){let c=b.split('.');const d=a;let e=a;'Elixir'===c[0]&&(c=c.slice(1));for(const d of c)'undefined'==typeof e[d]&&(e[d]={}),e=e[d];return d.__table__=a.__table__||{},d.__table__[Symbol.for(b)]=e,e},iterator_to_reducer,map_to_object},SpecialForms:{_case:function _case(a,b){return n.Patterns.defmatch(...b)(a)},cond:function cond(...a){for(const b of a)if(b[0])return b[1]();throw new Error},_for:function _for(a,b,c,d=[]){let[e,f]=c.into(d);const g=run_list_generators(b.pop()(),b);for(const h of g)a.guard.apply(this,h)&&(e=f(e,new n.Tuple(Symbol.for('cont'),a.fn.apply(this,h))));return f(e,Symbol.for('done'))},_try:function _try(a,b,c,d,e){let f=null;try{f=a()}catch(a){let d=null;if(b)try{return d=b(a),d}catch(a){if(a instanceof n.Patterns.MatchError)throw a}if(c)try{return d=c(a),d}catch(a){if(a instanceof n.Patterns.MatchError)throw a}throw a}finally{e&&e()}if(d)try{return d(f)}catch(a){if(a instanceof n.Patterns.MatchError)throw new Error('No Match Found in Else');throw a}else return f},_with:function _with(...a){let b=[],c=null,d=null;'function'==typeof a[a.length-2]?[c,d]=a.splice(-2):c=a.pop();for(let c=0;c{const[c,d]=b;return a.set(c,d),a},new Map)},keys:function keys(a){return!1===h.is_map(a)?new d.Tuple(k,a):Array.from(a.keys())},values:function values$1(a){return!1===h.is_map(a)?new d.Tuple(k,a):Array.from(a.values())},is_key,put:function put(a,b,c){if(!1===h.is_map(c))return new d.Tuple(k,c);const e=new Map(c);return e.set(a,b),e},merge:function merge(a,b){return!1===h.is_map(a)?new d.Tuple(k,a):!1===h.is_map(b)?new d.Tuple(k,b):new Map([...a,...b])},update:function update(a,b,c){return!1===h.is_map(c)?new d.Tuple(k,c):!1===is_key(a,c)?new d.Tuple(l,a):new Map([...c,[a,b]])},get:function get(...a){const b=a[0],c=a[1];return!1===h.is_map(c)?new d.Tuple(k,c):is_key(b)?c.get(b):3===a.length?a[2]:new d.Tuple(l,b)},take:function take(a,b){if(!1===h.is_map(b))return new d.Tuple(k,b);if(!is_key(a))return j;const c=b.get(a),e=new Map(b);return e.delete(a),new d.Tuple(c,e)}},lists:{reverse,foreach:function foreach(a,b){return b.forEach((b)=>a(b)),Symbol.for('ok')},duplicate:function duplicate(a,b){const c=[];for(;c.length{if(d.get(c-1)a.get(c-1)?1:0})},keystore:function keystore(a,b,c,d){const e=[...c];for(let f=0;fa.toString()).join()},map:function map(a,b){return b.map((b)=>a(b))},filter:function filter(a,b){return b.filter((b)=>a(b))},filtermap:function filtermap(a,b){const c=[];for(const e of b){const b=a(e);!0===b?c.push(e):b instanceof d.Tuple&&!0===b.get(0)&&c.push(b.get(1))}return c},member:function member(a,b){for(const c of b)if(c===a)return!0;return!1},all:function all(a,b){for(const c of b)if(!1===a(c))return!1;return!0},any:function any(a,b){for(const c of b)if(!0===a(c))return!0;return!1},splitwith:function splitwith(a,b){let c=!1;const e=[],f=[];for(const d of b)!0==c?f.push(d):!0===a(d)?e.push(d):(c=!0,f.push(d));return new d.Tuple(e,f)},sort:function sort(...a){if(1===a.length){const b=[...a[0]];return b.sort()}const c=a[0],b=[...a[1]];return b.sort((d,a)=>{const b=c(d,a);return!0===b?-1:1})}}};return{Core:n}}(); diff --git a/src/javascript/lib/core/functions.js b/src/javascript/lib/core/functions.js index 97a18379..4fdabcac 100644 --- a/src/javascript/lib/core/functions.js +++ b/src/javascript/lib/core/functions.js @@ -113,10 +113,25 @@ function build_namespace(ns, ns_string) { return parent; } +function map_to_object(map) { + const object = {}; + + for (const [key, value] of map.entries()) { + if (value instanceof Map) { + object[key] = map_to_object(value); + } else { + object[key] = value; + } + } + + return object; +} + export default { call_property, defprotocol, defimpl, build_namespace, - iterator_to_reducer + iterator_to_reducer, + map_to_object }; From f7c8ac87d7469d182e2efb0e63488de735dd49a0 Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Thu, 20 Jul 2017 19:54:41 -0500 Subject: [PATCH 182/418] Add ElixirScript.JS.map_to_object/1 --- CHANGELOG.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index fb472034..38eb4911 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,7 +8,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ### Added - ElixirScript now has an FFI layer for interoperability with JavaScript. For more details, see documentation at `ElixirScript.FFI` -- ElixirScript.JS.mutate/3 +- `ElixirScript.JS.mutate/3` +- `ElixirScript.JS.map_to_object/1` ### Changed - Compiler has been completely rewritten. ElixirScript now requires Erlang 20+ and Elixir 1.5+ From 6b9d3b11854fdb1bcf19dd93c3c90946db427c5f Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Thu, 20 Jul 2017 21:54:51 -0500 Subject: [PATCH 183/418] Revert changes to main.ex. Add map_to_object/1 test --- test/passes/translate/forms/js_test.exs | 25 +++++++++++++++++++++---- test/support/main.ex | 2 -- 2 files changed, 21 insertions(+), 6 deletions(-) diff --git a/test/passes/translate/forms/js_test.exs b/test/passes/translate/forms/js_test.exs index d9f556cd..60571603 100644 --- a/test/passes/translate/forms/js_test.exs +++ b/test/passes/translate/forms/js_test.exs @@ -66,9 +66,6 @@ defmodule ElixirScript.Translate.Forms.JS.Test do end test "mutate/3" do - properties = [{"a", 1}] - map_ast = {:%{}, [], properties} - ast = {{:., [], [ElixirScript.JS, :mutate]}, [], [{:entry, [], nil}, "a", 2]} state = %{function: {:each, nil}, module: Enum, vars: %{:_ => 0, "entry" => 0, "enumerable" => 0, "fun" => 0}} @@ -80,8 +77,28 @@ defmodule ElixirScript.Translate.Forms.JS.Test do J.literal("a"), true ), + J.literal(2) + ) + end + + test "map_to_object/1" do + ast = {{:., [], [ElixirScript.JS, :map_to_object]}, [], [{:entry, [], nil}]} + state = %{function: {:each, nil}, module: Enum, vars: %{:_ => 0, "entry" => 0, "enumerable" => 0, "fun" => 0}} + + {js_ast, _} = Form.compile(ast, state) + assert js_ast == J.call_expression( + J.member_expression( + J.member_expression( + J.identifier("ElixirScript"), + J.member_expression( + J.identifier("Core"), + J.identifier("Functions") + ) + ), + J.identifier("map_to_object") + ), [ - J.literal(2) + J.identifier("entry0") ] ) end diff --git a/test/support/main.ex b/test/support/main.ex index a2260e63..a18d3d90 100644 --- a/test/support/main.ex +++ b/test/support/main.ex @@ -1,7 +1,5 @@ defmodule Main do def start(:normal, [callback]) do callback.("started") - - Enum.map(1..5, fn(x) -> x * 2 end) end end From 673e6c0c3d965dcff5b657522bb339ca8ba42b89 Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Thu, 20 Jul 2017 22:01:39 -0500 Subject: [PATCH 184/418] Fix broken maps tests --- src/javascript/tests/core/erlang_compat/maps_spec.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/javascript/tests/core/erlang_compat/maps_spec.js b/src/javascript/tests/core/erlang_compat/maps_spec.js index 805c7172..ddb69aa9 100644 --- a/src/javascript/tests/core/erlang_compat/maps_spec.js +++ b/src/javascript/tests/core/erlang_compat/maps_spec.js @@ -2,7 +2,7 @@ import test from 'ava'; import Core from '../../../lib/core'; test('find', t => { - let myMap = {}; + let myMap = new Map(); let result = Core.maps.find('t', myMap); t.is(result, Symbol.for('error')); @@ -10,13 +10,13 @@ test('find', t => { result = Core.maps.find('t', myMap); t.deepEqual(result.values, [Symbol.for('badmap'), myMap]); - myMap = { t: 'b' }; + myMap = new Map([['t', 'b']]); result = Core.maps.find('t', myMap); t.deepEqual(result.values, [Symbol.for('ok'), 'b']); }); test('fold', t => { - const myMap = { a: 1, b: 2 }; + const myMap = new Map([['a', 1], ['b', 2]]); const result = Core.maps.fold((k, v, acc) => acc + v, 0, myMap); t.is(result, 3); }); From 48f1e3e675eb54a5da8e1d40f1edac131b5c1f93 Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Thu, 20 Jul 2017 22:21:18 -0500 Subject: [PATCH 185/418] Update to Elixir 1.5-rc.2 and nodejs 8.2.0 --- .tool-versions | 4 ++-- .travis.yml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.tool-versions b/.tool-versions index 0a498367..8dbeeb38 100644 --- a/.tool-versions +++ b/.tool-versions @@ -1,3 +1,3 @@ erlang 20.0 -elixir ref-v1.5.0-rc.1 -nodejs 8.1.4 +elixir ref-v1.5.0-rc.2 +nodejs 8.2.0 diff --git a/.travis.yml b/.travis.yml index e4ec9f8e..ed00c03d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -9,8 +9,8 @@ install: - npm install -g yarn - yarn before_script: - - wget https://repo.hex.pm/builds/elixir/v1.5.0-rc.1-otp-20.zip - - unzip -d elixir v1.5.0-rc.1-otp-20.zip + - wget https://repo.hex.pm/builds/elixir/v1.5.0-rc.2-otp-20.zip + - unzip -d elixir v1.5.0-rc.2-otp-20.zip - export PATH=$(pwd)/elixir/bin:${PATH} - mix local.rebar --force - mix local.hex --force From 18d75af4d99e67e5bc6f137ffdca2cd8d54e3253 Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Thu, 20 Jul 2017 22:51:14 -0500 Subject: [PATCH 186/418] Add erlang.process_info shim and erlang_compat.elixir_errors.warn --- priv/build/iife/ElixirScript.Core.js | 2564 ++++++++++++++++- src/javascript/lib/core.js | 4 +- .../lib/core/erlang_compat/elixir_errors.js | 10 + .../lib/core/erlang_compat/erlang.js | 15 +- 4 files changed, 2585 insertions(+), 8 deletions(-) create mode 100644 src/javascript/lib/core/erlang_compat/elixir_errors.js diff --git a/priv/build/iife/ElixirScript.Core.js b/priv/build/iife/ElixirScript.Core.js index 42035b8b..2ffba822 100644 --- a/priv/build/iife/ElixirScript.Core.js +++ b/priv/build/iife/ElixirScript.Core.js @@ -1,6 +1,2558 @@ -var ElixirScript=function(){'use strict';/* @flow */function namedVariableResult(a,b){return new NamedVariableResult(a,b)}/* @flow */function is_number(a){return'number'==typeof a}function is_string(a){return'string'==typeof a}function is_boolean(a){return'boolean'==typeof a}function is_symbol(a){return'symbol'==typeof a}function is_object(a){return'object'==typeof a}function is_variable(a){return a instanceof Variable}function is_null(a){return null===a}function is_array(a){return Array.isArray(a)}function is_function(a){return'[object Function]'==Object.prototype.toString.call(a)}function is_map(a){return a instanceof Map}function resolveNull(){return function(a){return is_null(a)}}function resolveWildcard(){return function(){return!0}}function resolveObject(a){let b={};const c=Object.keys(a).concat(Object.getOwnPropertySymbols(a));for(let d of c)b[d]=buildMatch(a[d]);return function(d,e){if(!is_object(d)||a.length>d.length)return!1;for(let a of c)if(!(a in d)||!b[a](d[a],e))return!1;return!0}}function getSize(a,b){return a*b/8}function arraysEqual(c,a){if(c===a)return!0;if(null==c||null==a)return!1;if(c.length!=a.length)return!1;for(var b=0;be.integer(a));return new e(...b)}function resolveNoMatch(){return function(){return!1}}function buildMatch(a){if(null===a)return resolveNull(a);if('undefined'==typeof a)return resolveWildcard(a);const b=a.constructor.prototype,c=f.get(b);return c?c(a):'object'==typeof a?resolveObject(a):resolveNoMatch()}function defmatchgen(...a){const b=getArityMap(a);return function*(...a){let[c,d]=findMatchingFunction(a,b);return yield*c.apply(this,d)}}function findMatchingFunction(a,b){if(b.has(a.length)){const c=b.get(a.length);let d=null,e=null;for(let b of c){let c=[];a=fillInOptionalValues(a,b.arity,b.optionals);const f=b.pattern(a,c),[g,h]=checkNamedVariables(c);if(f&&h&&b.guard.apply(this,g)){d=b.fn,e=g;break}}if(!d)throw console.error('No match for:',a),new MatchError(a);return[d,e]}throw console.error('Arity of',a.length,'not found. No match for:',a),new MatchError(a)}function getArityMap(a){let b=new Map;for(const c of a){const a=getArityRange(c);for(const d of a){let a=[];b.has(d)&&(a=b.get(d)),a.push(c),b.set(d,a)}}return b}function getArityRange(a){const b=a.arity-a.optionals.length,c=a.arity;let d=[b];for(;d[d.length-1]!=c;)d.push(d[d.length-1]+1);return d}function getOptionalValues(a){let b=[];for(let c=0;c!0,d=null){let e=[],f=buildMatch(a);const g=f(b,e),[h,i]=checkNamedVariables(e);return g&&i&&c.apply(this,h)?h:d}function run_generators(a,b){if(0==b.length)return a.map((a)=>{return Array.isArray(a)?a:[a]});const c=b.pop();let d=[];for(let e of c())for(let b of a)d.push([e].concat(b));return run_generators(d,b)}function iterator_to_reducer(a,b,c){const d=a[Symbol.iterator]();let e=d.next(),f=b;for(;!1===e.done;){if(f=c(e.value,f.get(1)),f.get(0)===Symbol.for('halt'))return new n.Tuple(Symbol.for('halted'),f.get(1));if(f.get(0)===Symbol.for('suspend'))return new n.Tuple(Symbol.for('suspended'),f.get(1),(a)=>{return iterator_to_reducer(d,a,c)});e=d.next()}return new n.Tuple(Symbol.for('done'),f.get(1))}function map_to_object(a){const b={};for(const[c,d]of a.entries())b[c]=d instanceof Map?map_to_object(d):d;return b}function run_list_generators(a,b){if(0==b.length)return a.map((a)=>{return Array.isArray(a)?a:[a]});const c=b.pop(),d=[];for(const e of c())for(const b of a)d.push([e].concat(b));return run_list_generators(d,b)}// http://erlang.org/doc/man/erlang.html -function atom_to_binary(a,b=Symbol.for('utf8')){if(b!==Symbol.for('utf8'))throw new Error(`unsupported encoding ${b}`);return a.__MODULE__?Symbol.keyFor(a.__MODULE__):Symbol.keyFor(a)}function binary_to_atom(a,b=Symbol.for('utf8')){if(b!==Symbol.for('utf8'))throw new Error(`unsupported encoding ${b}`);return Symbol.for(a)}function is_number$1(a){return'number'==typeof a||a instanceof Number}function is_key(a,b){return b.has(a)}// http://erlang.org/doc/man/lists.html -function reverse(a){return[...a]}function flatten(a,b=[]){const c=a.reduce((a,b)=>{return Array.isArray(b)?a.concat(flatten(b)):a.concat(b)},[]);return c.concat(b)}function foldl(a,b,c){return c.reduce((b,c)=>{return a(c,b)},b)}function keyfind(a,b,c){for(const d of c)if(d.get(b-1)===a)return d;return!1}function keydelete(a,b,c){const d=[];let e=!1;for(let f=0;fBitString$1.integer(a));return new BitString$1(...d)}[Symbol.iterator](){return this.value[Symbol.iterator]()}toString(){var a,b='';for(a=0;a>'}process(a){let b=[];var c;for(c=0;cb?c.push(b):2048>b?c.push(192|b>>6,128|63&b):55296>b||57344<=b?c.push(224|b>>12,128|63&b>>6,128|63&b):(d++,b=65536+((1023&b)<<10|1023&a.charCodeAt(d)),c.push(240|b>>18,128|63&b>>12,128|63&b>>6,128|63&b));return c}static toUTF16Array(a){for(var b,c=[],d=0;d=b?(c.push(0),c.push(b)):(c.push(255&b>>8),c.push(255&b));return c}static toUTF32Array(a){for(var b,c=[],d=0;d=b?(c.push(0),c.push(0),c.push(0),c.push(b)):(c.push(0),c.push(0),c.push(255&b>>8),c.push(255&b));return c}//http://stackoverflow.com/questions/2003493/javascript-float-from-to-bits -static float32ToBytes(a){var b=[],c=new ArrayBuffer(4);new Float32Array(c)[0]=a;let d=new Uint32Array(c)[0];return b.push(255&d>>24),b.push(255&d>>16),b.push(255&d>>8),b.push(255&d),b}static float64ToBytes(a){var b=[],c=new ArrayBuffer(8);new Float64Array(c)[0]=a;var d=new Uint32Array(c)[0],e=new Uint32Array(c)[1];return b.push(255&e>>24),b.push(255&e>>16),b.push(255&e>>8),b.push(255&e),b.push(255&d>>24),b.push(255&d>>16),b.push(255&d>>8),b.push(255&d),b}}var d={Tuple,PID:class PID{constructor(){++b,this.id=b}toString(){return'PID#<0.'+this.id+'.0>'}},Reference:class Reference{constructor(){++c,this.id=c,this.ref=Symbol()}toString(){return'Ref#<0.0.0.'+this.id+'>'}},BitString:BitString$1};/* @flow */const e=d.BitString,f=new Map;f.set(Variable.prototype,function resolveVariable(a){return function(b,c){return null===a.name||a.name.startsWith('_')?c.push(b):c.push(namedVariableResult(a.name,b)),!0}}),f.set(Wildcard.prototype,resolveWildcard),f.set(HeadTail.prototype,function resolveHeadTail(){return function(a,b){if(!is_array(a)||2>a.length)return!1;const c=a[0],d=a.slice(1);return b.push(c),b.push(d),!0}}),f.set(StartsWith.prototype,function resolveStartsWith(a){const b=a.prefix;return function(a,c){return is_string(a)&&a.startsWith(b)&&(c.push(a.substring(b.length)),!0)}}),f.set(Capture.prototype,function resolveCapture(a){const b=buildMatch(a.value);return function(a,c){return!!b(a,c)&&(c.push(a),!0)}}),f.set(Bound.prototype,function resolveBound(a){return function(b){return typeof b==typeof a.value&&b===a.value}}),f.set(Type.prototype,function resolveType(a){return function(b,c){if(b instanceof a.type){const d=buildMatch(a.objPattern);return d(b,c)}return!1}}),f.set(BitStringMatch.prototype,function resolveBitString(a){let b=[];for(let c of a.values)if(is_variable(c.value)){let a=getSize(c.unit,c.size);fillArray(b,a)}else b=b.concat(new e(c).value);let c=a.values;return function(a,d){var f=String.fromCharCode;let g=null;if(!is_string(a)&&!(a instanceof e))return!1;g=is_string(a)?new e(e.binary(a)):a;let h=0;for(let e,j=0;jd.size)return!1;for(let a of c)if(!d.has(a)||!b.get(a)(d.get(a),e))return!1;return!0}}),f.set(Array.prototype,function resolveArray(a){const b=a.map((a)=>buildMatch(a));return function(c,d){return is_array(c)&&c.length==a.length&&c.every(function(a,e){return b[e](c[e],d)})}}),f.set(String.prototype,function resolveString(a){return function(b){return is_string(b)&&b===a}}),f.set(Boolean.prototype,function resolveBoolean(a){return function(b){return is_boolean(b)&&b===a}}),f.set(Function.prototype,function resolveFunction(a){return function(b){return is_function(b)&&b===a}}),f.set(Object.prototype,resolveObject);class MatchError extends Error{constructor(a){if(super(),'symbol'==typeof a)this.message='No match for: '+a.toString();else if(Array.isArray(a)){let b=a.map((a)=>{return null===a?'null':'undefined'==typeof a?'undefined':a.toString()});this.message='No match for: '+b}else this.message='No match for: '+a;this.stack=new Error().stack,this.name=this.constructor.name}}class Clause{constructor(a,b,c=()=>!0){this.pattern=buildMatch(a),this.arity=a.length,this.optionals=getOptionalValues(a),this.fn=b,this.guard=c}}const g=Symbol();// https://github.com/airportyh/protomorphism -class Protocol{constructor(b){function createFun(b){return function(...c){const d=c[0];let e=null;if(null===d&&this.hasImplementation(Symbol('null'))?e=this.registry.get(Symbol)[b]:a(d)&&this.hasImplementation(n.Integer)?e=this.registry.get(n.Integer)[b]:'number'==typeof d&&!a(d)&&this.hasImplementation(n.Float)?e=this.registry.get(n.Float)[b]:'string'==typeof d&&this.hasImplementation(n.BitString)?e=this.registry.get(n.BitString)[b]:d&&d.has(Symbol.for('__struct__'))&&this.hasImplementation(d)?e=this.registry.get(d.get(Symbol.for('__struct__')).__MODULE__)[b]:null!==d&&this.hasImplementation(d)?e=this.registry.get(d.constructor)[b]:this.fallback&&(e=this.fallback[b]),null!=e){const a=e.apply(this,c);return a}throw new Error(`No implementation found for ${d}`)}}for(const a in this.registry=new Map,this.fallback=null,b)this[a]=createFun(a).bind(this)}implementation(a,b){null===a?this.fallback=b:this.registry.set(a,b)}hasImplementation(a){if(a===n.Integer||a===n.Float||a===n.BitString)return this.registry.has(a);return a&&a.has(Symbol.for('__struct__'))?this.registry.has(a.get(Symbol.for('__struct__')).__MODULE__):this.registry.has(a.constructor)}}var h={atom_to_binary,binary_to_atom,binary_to_existing_atom:function binary_to_existing_atom(a,b=Symbol.for('utf8')){return binary_to_atom(a,b)},list_concatenation:function list_concatenation(a,b){return a.concat(b)},list_subtraction:function list_subtraction(a,b){const c=[...a];for(const d of b){const a=c.indexOf(d);-1b},greaterThanOrEqualTo:function greaterThanOrEqualTo(a,b){return a>=b},lessThan:function lessThan(a,b){return a>b},bxor:function bxor(a,b){return a^b},bnot:function bnot(a){return~a},is_bitstring:function is_bitstring$1(a){return a instanceof d.BitString},is_boolean:function is_boolean$1(a){return'boolean'==typeof a||a instanceof Boolean},is_float:function is_float(b){return is_number$1(b)&&!a(b)},is_function:function is_function$1(a){return'function'==typeof a||a instanceof Function},is_integer:function is_integer(b){return a(b)},is_list:function is_list(a){return Array.isArray(a)},is_map:function is_map$1(a){return a instanceof Map},is_number:is_number$1,is_pid:function is_pid(a){return a instanceof d.PID},is_port:function is_port(){return!1},is_reference:function is_reference(a){return a instanceof d.Reference},is_tuple:function is_tuple(a){return a instanceof d.Tuple},is_atom:function is_atom(a){return'symbol'==typeof a||a instanceof Symbol||a.__MODULE__},is_binary:function is_binary(a){return'string'==typeof a||a instanceof String},element:function element(a,b){return b.get(a-1)},setelement:function setelement(a,b,c){const e=[...b.values];return e[a-1]=c,new d.Tuple(...e)},make_tuple:function make_tuple(a,b){const c=[];for(let d=0;d!0){let d=[],e=buildMatch(a);const f=e(b,d),[g,h]=checkNamedVariables(d);if(f&&h&&c.apply(this,g))return g;throw console.error('No match for:',b),new MatchError(b)},MatchError,variable:function variable(a=null,b=Symbol.for('tailored.no_value')){return new Variable(a,b)},wildcard:function wildcard(){return new Wildcard},startsWith:function startsWith(a){return new StartsWith(a)},capture:function capture(a){return new Capture(a)},headTail:function headTail(){return new HeadTail},type:function a(a,b={}){return new Type(a,b)},bound:function bound(a){return new Bound(a)},Clause,clause:function clause(a,b,c=()=>!0){return new Clause(a,b,c)},bitStringMatch:function bitStringMatch(...a){return new BitStringMatch(...a)},match_or_default,defmatchgen,list_comprehension:function list_comprehension(a,b){const c=run_generators(b.pop()(),b);let d=[];for(let e of c)a.guard.apply(this,e)&&d.push(a.fn.apply(this,e));return d},list_generator:function list_generator(a,b){return function(){let c=[];for(let d of b){const b=match_or_default(a,d,()=>!0,g);if(b!=g){const[a]=b;c.push(a)}}return c}},bitstring_generator:function bitstring_generator(a,b){return function(){let c=[],d=b.slice(0,a.byte_size()),e=1;for(;d.byte_size==a.byte_size();){const f=match_or_default(a,d,()=>!0,g);if(f!=g){c.push(f)}d=b.slice(a.byte_size()*e,a.byte_size()*(e+1)),e++}return c}},bitstring_comprehension:function bitstring_comprehension(a,b){const c=run_generators(b.pop()(),b);let e=[];for(let d of c)a.guard.apply(this,d)&&e.push(a.fn.apply(this,d));return e=e.map((a)=>d.BitString.integer(a)),new d.BitString(...e)},defmatchGen:function defmatchGen(...a){return defmatchgen(...a)},defmatchAsync:function defmatchAsync(...a){const b=getArityMap(a);return async function(...a){if(b.has(a.length)){const c=b.get(a.length);let d=null,e=null;for(let b of c){let c=[];a=fillInOptionalValues(a,b.arity,b.optionals);const f=b.pattern(a,c),[g,h]=checkNamedVariables(c);if(f&&h&&(await b.guard.apply(this,c))){d=b.fn,e=c;break}}if(!d)throw console.error('No match for:',a),new MatchError(a);return d.apply(this,e)}throw console.error('Arity of',a.length,'not found. No match for:',a),new MatchError(a)}}},Integer:class Integer{},Float:class Float{},Functions:{call_property:function call_property(a,b){if(!b)return a instanceof Function||'function'==typeof a?a():a;if(a instanceof Map){let c=null;if(a.has(b)?c=b:a.has(Symbol.for(b))&&(c=Symbol.for(b)),null===c)throw new Error(`Property ${b} not found in ${a}`);return a.get(c)instanceof Function||'function'==typeof a.get(c)?a.get(c)():a.get(c)}let c=null;if('number'==typeof a||'symbol'==typeof a||'boolean'==typeof a||'string'==typeof a?void 0===a[b]?void 0!==a[Symbol.for(b)]&&(c=Symbol.for(b)):c=b:b in a?c=b:Symbol.for(b)in a&&(c=Symbol.for(b)),null===c)throw new Error(`Property ${b} not found in ${a}`);return a[c]instanceof Function||'function'==typeof a[c]?a[c]():a[c]},defprotocol:function defprotocol(a){return new Protocol(a)},defimpl:function defimpl(a,b,c){a.implementation(b,c)},build_namespace:function build_namespace(a,b){let c=b.split('.');const d=a;let e=a;'Elixir'===c[0]&&(c=c.slice(1));for(const d of c)'undefined'==typeof e[d]&&(e[d]={}),e=e[d];return d.__table__=a.__table__||{},d.__table__[Symbol.for(b)]=e,e},iterator_to_reducer,map_to_object},SpecialForms:{_case:function _case(a,b){return n.Patterns.defmatch(...b)(a)},cond:function cond(...a){for(const b of a)if(b[0])return b[1]();throw new Error},_for:function _for(a,b,c,d=[]){let[e,f]=c.into(d);const g=run_list_generators(b.pop()(),b);for(const h of g)a.guard.apply(this,h)&&(e=f(e,new n.Tuple(Symbol.for('cont'),a.fn.apply(this,h))));return f(e,Symbol.for('done'))},_try:function _try(a,b,c,d,e){let f=null;try{f=a()}catch(a){let d=null;if(b)try{return d=b(a),d}catch(a){if(a instanceof n.Patterns.MatchError)throw a}if(c)try{return d=c(a),d}catch(a){if(a instanceof n.Patterns.MatchError)throw a}throw a}finally{e&&e()}if(d)try{return d(f)}catch(a){if(a instanceof n.Patterns.MatchError)throw new Error('No Match Found in Else');throw a}else return f},_with:function _with(...a){let b=[],c=null,d=null;'function'==typeof a[a.length-2]?[c,d]=a.splice(-2):c=a.pop();for(let c=0;c{const[c,d]=b;return a.set(c,d),a},new Map)},keys:function keys(a){return!1===h.is_map(a)?new d.Tuple(k,a):Array.from(a.keys())},values:function values$1(a){return!1===h.is_map(a)?new d.Tuple(k,a):Array.from(a.values())},is_key,put:function put(a,b,c){if(!1===h.is_map(c))return new d.Tuple(k,c);const e=new Map(c);return e.set(a,b),e},merge:function merge(a,b){return!1===h.is_map(a)?new d.Tuple(k,a):!1===h.is_map(b)?new d.Tuple(k,b):new Map([...a,...b])},update:function update(a,b,c){return!1===h.is_map(c)?new d.Tuple(k,c):!1===is_key(a,c)?new d.Tuple(l,a):new Map([...c,[a,b]])},get:function get(...a){const b=a[0],c=a[1];return!1===h.is_map(c)?new d.Tuple(k,c):is_key(b)?c.get(b):3===a.length?a[2]:new d.Tuple(l,b)},take:function take(a,b){if(!1===h.is_map(b))return new d.Tuple(k,b);if(!is_key(a))return j;const c=b.get(a),e=new Map(b);return e.delete(a),new d.Tuple(c,e)}},lists:{reverse,foreach:function foreach(a,b){return b.forEach((b)=>a(b)),Symbol.for('ok')},duplicate:function duplicate(a,b){const c=[];for(;c.length{if(d.get(c-1)a.get(c-1)?1:0})},keystore:function keystore(a,b,c,d){const e=[...c];for(let f=0;fa.toString()).join()},map:function map(a,b){return b.map((b)=>a(b))},filter:function filter(a,b){return b.filter((b)=>a(b))},filtermap:function filtermap(a,b){const c=[];for(const e of b){const b=a(e);!0===b?c.push(e):b instanceof d.Tuple&&!0===b.get(0)&&c.push(b.get(1))}return c},member:function member(a,b){for(const c of b)if(c===a)return!0;return!1},all:function all(a,b){for(const c of b)if(!1===a(c))return!1;return!0},any:function any(a,b){for(const c of b)if(!0===a(c))return!0;return!1},splitwith:function splitwith(a,b){let c=!1;const e=[],f=[];for(const d of b)!0==c?f.push(d):!0===a(d)?e.push(d):(c=!0,f.push(d));return new d.Tuple(e,f)},sort:function sort(...a){if(1===a.length){const b=[...a[0]];return b.sort()}const c=a[0],b=[...a[1]];return b.sort((d,a)=>{const b=c(d,a);return!0===b?-1:1})}}};return{Core:n}}(); +var ElixirScript = (function () { +'use strict'; + +/* @flow */ + +class Variable { + constructor(name = null, default_value = Symbol.for('tailored.no_value')) { + this.name = name; + this.default_value = default_value; + } +} + +class Wildcard { + constructor() {} +} + +class StartsWith { + constructor(prefix) { + this.prefix = prefix; + } +} + +class Capture { + constructor(value) { + this.value = value; + } +} + +class HeadTail { + constructor() {} +} + +class Type { + constructor(type, objPattern = {}) { + this.type = type; + this.objPattern = objPattern; + } +} + +class Bound { + constructor(value) { + this.value = value; + } +} + +class BitStringMatch { + constructor(...values) { + this.values = values; + } + + length() { + return values.length; + } + + bit_size() { + return this.byte_size() * 8; + } + + byte_size() { + let s = 0; + + for (let val of this.values) { + s = s + val.unit * val.size / 8; + } + + return s; + } + + getValue(index) { + return this.values(index); + } + + getSizeOfValue(index) { + let val = this.getValue(index); + return val.unit * val.size; + } + + getTypeOfValue(index) { + return this.getValue(index).type; + } +} + +class NamedVariableResult { + constructor(name, value) { + this.name = name; + this.value = value; + } +} + +function variable(name = null, default_value = Symbol.for('tailored.no_value')) { + return new Variable(name, default_value); +} + +function wildcard() { + return new Wildcard(); +} + +function startsWith(prefix) { + return new StartsWith(prefix); +} + +function capture(value) { + return new Capture(value); +} + +function headTail() { + return new HeadTail(); +} + +function type(type, objPattern = {}) { + return new Type(type, objPattern); +} + +function bound(value) { + return new Bound(value); +} + +function bitStringMatch(...values) { + return new BitStringMatch(...values); +} + +function namedVariableResult(name, value) { + return new NamedVariableResult(name, value); +} + +/* @flow */ + +function is_number(value) { + return typeof value === 'number'; +} + +function is_string(value) { + return typeof value === 'string'; +} + +function is_boolean(value) { + return typeof value === 'boolean'; +} + +function is_symbol(value) { + return typeof value === 'symbol'; +} + +function is_object(value) { + return typeof value === 'object'; +} + +function is_variable(value) { + return value instanceof Variable; +} + +function is_null(value) { + return value === null; +} + +function is_array(value) { + return Array.isArray(value); +} + +function is_function(value) { + return Object.prototype.toString.call(value) == '[object Function]'; +} + +function is_map(value) { + return value instanceof Map; +} + +class Tuple { + constructor(...args) { + this.values = Object.freeze(args); + this.length = this.values.length; + } + + get(index) { + return this.values[index]; + } + + count() { + return this.values.length; + } + + [Symbol.iterator]() { + return this.values[Symbol.iterator](); + } + + toString() { + let i, + s = ''; + for (i = 0; i < this.values.length; i++) { + if (s !== '') { + s += ', '; + } + + const stringToAppend = this.values[i] ? this.values[i].toString() : ''; + + s += stringToAppend; + } + + return '{' + s + '}'; + } + + put_elem(index, elem) { + if (index === this.length) { + let new_values = this.values.concat([elem]); + return new Tuple(...new_values); + } + + let new_values = this.values.concat([]); + new_values.splice(index, 0, elem); + return new Tuple(...new_values); + } + + remove_elem(index) { + let new_values = this.values.concat([]); + new_values.splice(index, 1); + return new Tuple(...new_values); + } +} + +let process_counter = -1; + +class PID { + constructor() { + process_counter = process_counter + 1; + this.id = process_counter; + } + + toString() { + return 'PID#<0.' + this.id + '.0>'; + } +} + +let ref_counter = -1; + +class Reference { + constructor() { + ref_counter = ref_counter + 1; + this.id = ref_counter; + this.ref = Symbol(); + } + + toString() { + return 'Ref#<0.0.0.' + this.id + '>'; + } +} + +class BitString$1 { + constructor(...args) { + this.value = Object.freeze(this.process(args)); + this.length = this.value.length; + this.bit_size = this.length * 8; + this.byte_size = this.length; + } + + get(index) { + return this.value[index]; + } + + count() { + return this.value.length; + } + + slice(start, end = null) { + let s = this.value.slice(start, end); + let ms = s.map(elem => BitString$1.integer(elem)); + return new BitString$1(...ms); + } + + [Symbol.iterator]() { + return this.value[Symbol.iterator](); + } + + toString() { + var i, + s = ''; + for (i = 0; i < this.count(); i++) { + if (s !== '') { + s += ', '; + } + s += this.get(i).toString(); + } + + return '<<' + s + '>>'; + } + + process(bitStringParts) { + let processed_values = []; + + var i; + for (i = 0; i < bitStringParts.length; i++) { + let processed_value = this['process_' + bitStringParts[i].type](bitStringParts[i]); + + for (let attr of bitStringParts[i].attributes) { + processed_value = this['process_' + attr](processed_value); + } + + processed_values = processed_values.concat(processed_value); + } + + return processed_values; + } + + process_integer(value) { + return value.value; + } + + process_float(value) { + if (value.size === 64) { + return BitString$1.float64ToBytes(value.value); + } else if (value.size === 32) { + return BitString$1.float32ToBytes(value.value); + } + + throw new Error('Invalid size for float'); + } + + process_bitstring(value) { + return value.value.value; + } + + process_binary(value) { + return BitString$1.toUTF8Array(value.value); + } + + process_utf8(value) { + return BitString$1.toUTF8Array(value.value); + } + + process_utf16(value) { + return BitString$1.toUTF16Array(value.value); + } + + process_utf32(value) { + return BitString$1.toUTF32Array(value.value); + } + + process_signed(value) { + return new Uint8Array([value])[0]; + } + + process_unsigned(value) { + return value; + } + + process_native(value) { + return value; + } + + process_big(value) { + return value; + } + + process_little(value) { + return value.reverse(); + } + + process_size(value) { + return value; + } + + process_unit(value) { + return value; + } + + static integer(value) { + return BitString$1.wrap(value, { type: 'integer', unit: 1, size: 8 }); + } + + static float(value) { + return BitString$1.wrap(value, { type: 'float', unit: 1, size: 64 }); + } + + static bitstring(value) { + return BitString$1.wrap(value, { + type: 'bitstring', + unit: 1, + size: value.bit_size + }); + } + + static bits(value) { + return BitString$1.bitstring(value); + } + + static binary(value) { + return BitString$1.wrap(value, { + type: 'binary', + unit: 8, + size: value.length + }); + } + + static bytes(value) { + return BitString$1.binary(value); + } + + static utf8(value) { + return BitString$1.wrap(value, { type: 'utf8', unit: 1, size: value.length }); + } + + static utf16(value) { + return BitString$1.wrap(value, { + type: 'utf16', + unit: 1, + size: value.length * 2 + }); + } + + static utf32(value) { + return BitString$1.wrap(value, { + type: 'utf32', + unit: 1, + size: value.length * 4 + }); + } + + static signed(value) { + return BitString$1.wrap(value, {}, 'signed'); + } + + static unsigned(value) { + return BitString$1.wrap(value, {}, 'unsigned'); + } + + static native(value) { + return BitString$1.wrap(value, {}, 'native'); + } + + static big(value) { + return BitString$1.wrap(value, {}, 'big'); + } + + static little(value) { + return BitString$1.wrap(value, {}, 'little'); + } + + static size(value, count) { + return BitString$1.wrap(value, { size: count }); + } + + static unit(value, count) { + return BitString$1.wrap(value, { unit: count }); + } + + static wrap(value, opt, new_attribute = null) { + let the_value = value; + + if (!(value instanceof Object)) { + the_value = { value: value, attributes: [] }; + } + + the_value = Object.assign(the_value, opt); + + if (new_attribute) { + the_value.attributes.push(new_attribute); + } + + return the_value; + } + + static toUTF8Array(str) { + var utf8 = []; + for (var i = 0; i < str.length; i++) { + var charcode = str.charCodeAt(i); + if (charcode < 0x80) { + utf8.push(charcode); + } else if (charcode < 0x800) { + utf8.push(0xc0 | charcode >> 6, 0x80 | charcode & 0x3f); + } else if (charcode < 0xd800 || charcode >= 0xe000) { + utf8.push(0xe0 | charcode >> 12, 0x80 | charcode >> 6 & 0x3f, 0x80 | charcode & 0x3f); + } else { + // surrogate pair + i++; + // UTF-16 encodes 0x10000-0x10FFFF by + // subtracting 0x10000 and splitting the + // 20 bits of 0x0-0xFFFFF into two halves + charcode = 0x10000 + ((charcode & 0x3ff) << 10 | str.charCodeAt(i) & 0x3ff); + utf8.push(0xf0 | charcode >> 18, 0x80 | charcode >> 12 & 0x3f, 0x80 | charcode >> 6 & 0x3f, 0x80 | charcode & 0x3f); + } + } + return utf8; + } + + static toUTF16Array(str) { + var utf16 = []; + for (var i = 0; i < str.length; i++) { + var codePoint = str.codePointAt(i); + + if (codePoint <= 255) { + utf16.push(0); + utf16.push(codePoint); + } else { + utf16.push(codePoint >> 8 & 0xff); + utf16.push(codePoint & 0xff); + } + } + return utf16; + } + + static toUTF32Array(str) { + var utf32 = []; + for (var i = 0; i < str.length; i++) { + var codePoint = str.codePointAt(i); + + if (codePoint <= 255) { + utf32.push(0); + utf32.push(0); + utf32.push(0); + utf32.push(codePoint); + } else { + utf32.push(0); + utf32.push(0); + utf32.push(codePoint >> 8 & 0xff); + utf32.push(codePoint & 0xff); + } + } + return utf32; + } + + //http://stackoverflow.com/questions/2003493/javascript-float-from-to-bits + static float32ToBytes(f) { + var bytes = []; + + var buf = new ArrayBuffer(4); + new Float32Array(buf)[0] = f; + + let intVersion = new Uint32Array(buf)[0]; + + bytes.push(intVersion >> 24 & 0xff); + bytes.push(intVersion >> 16 & 0xff); + bytes.push(intVersion >> 8 & 0xff); + bytes.push(intVersion & 0xff); + + return bytes; + } + + static float64ToBytes(f) { + var bytes = []; + + var buf = new ArrayBuffer(8); + new Float64Array(buf)[0] = f; + + var intVersion1 = new Uint32Array(buf)[0]; + var intVersion2 = new Uint32Array(buf)[1]; + + bytes.push(intVersion2 >> 24 & 0xff); + bytes.push(intVersion2 >> 16 & 0xff); + bytes.push(intVersion2 >> 8 & 0xff); + bytes.push(intVersion2 & 0xff); + + bytes.push(intVersion1 >> 24 & 0xff); + bytes.push(intVersion1 >> 16 & 0xff); + bytes.push(intVersion1 >> 8 & 0xff); + bytes.push(intVersion1 & 0xff); + + return bytes; + } +} + +var ErlangTypes = { + Tuple, + PID, + Reference, + BitString: BitString$1 +}; + +/* @flow */ + +const BitString = ErlangTypes.BitString; + +function resolveSymbol(pattern) { + return function (value) { + return is_symbol(value) && value === pattern; + }; +} + +function resolveString(pattern) { + return function (value) { + return is_string(value) && value === pattern; + }; +} + +function resolveNumber(pattern) { + return function (value) { + return is_number(value) && value === pattern; + }; +} + +function resolveBoolean(pattern) { + return function (value) { + return is_boolean(value) && value === pattern; + }; +} + +function resolveFunction(pattern) { + return function (value) { + return is_function(value) && value === pattern; + }; +} + +function resolveNull(pattern) { + return function (value) { + return is_null(value); + }; +} + +function resolveBound(pattern) { + return function (value, args) { + if (typeof value === typeof pattern.value && value === pattern.value) { + return true; + } + + return false; + }; +} + +function resolveWildcard() { + return function () { + return true; + }; +} + +function resolveVariable(pattern) { + return function (value, args) { + if (pattern.name === null || pattern.name.startsWith('_')) { + args.push(value); + } else { + args.push(namedVariableResult(pattern.name, value)); + } + + return true; + }; +} + +function resolveHeadTail() { + return function (value, args) { + if (!is_array(value) || value.length < 2) { + return false; + } + + const head = value[0]; + const tail = value.slice(1); + + args.push(head); + args.push(tail); + + return true; + }; +} + +function resolveCapture(pattern) { + const matches = buildMatch(pattern.value); + + return function (value, args) { + if (matches(value, args)) { + args.push(value); + return true; + } + + return false; + }; +} + +function resolveStartsWith(pattern) { + const prefix = pattern.prefix; + + return function (value, args) { + if (is_string(value) && value.startsWith(prefix)) { + args.push(value.substring(prefix.length)); + return true; + } + + return false; + }; +} + +function resolveType(pattern) { + return function (value, args) { + if (value instanceof pattern.type) { + const matches = buildMatch(pattern.objPattern); + return matches(value, args); + } + + return false; + }; +} + +function resolveArray(pattern) { + const matches = pattern.map(x => buildMatch(x)); + + return function (value, args) { + if (!is_array(value) || value.length != pattern.length) { + return false; + } + + return value.every(function (v, i) { + return matches[i](value[i], args); + }); + }; +} + +function resolveMap(pattern) { + let matches = new Map(); + + const keys = Array.from(pattern.keys()); + + for (let key of keys) { + matches.set(key, buildMatch(pattern.get(key))); + } + + return function (value, args) { + if (!is_map(value) || pattern.size > value.size) { + return false; + } + + for (let key of keys) { + if (!value.has(key) || !matches.get(key)(value.get(key), args)) { + return false; + } + } + + return true; + }; +} + +function resolveObject(pattern) { + let matches = {}; + + const keys = Object.keys(pattern).concat(Object.getOwnPropertySymbols(pattern)); + + for (let key of keys) { + matches[key] = buildMatch(pattern[key]); + } + + return function (value, args) { + if (!is_object(value) || pattern.length > value.length) { + return false; + } + + for (let key of keys) { + if (!(key in value) || !matches[key](value[key], args)) { + return false; + } + } + + return true; + }; +} + +function resolveBitString(pattern) { + let patternBitString = []; + + for (let bitstringMatchPart of pattern.values) { + if (is_variable(bitstringMatchPart.value)) { + let size = getSize(bitstringMatchPart.unit, bitstringMatchPart.size); + fillArray(patternBitString, size); + } else { + patternBitString = patternBitString.concat(new BitString(bitstringMatchPart).value); + } + } + + let patternValues = pattern.values; + + return function (value, args) { + let bsValue = null; + + if (!is_string(value) && !(value instanceof BitString)) { + return false; + } + + if (is_string(value)) { + bsValue = new BitString(BitString.binary(value)); + } else { + bsValue = value; + } + + let beginningIndex = 0; + + for (let i = 0; i < patternValues.length; i++) { + let bitstringMatchPart = patternValues[i]; + + if (is_variable(bitstringMatchPart.value) && bitstringMatchPart.type == 'binary' && bitstringMatchPart.size === undefined && i < patternValues.length - 1) { + throw new Error('a binary field without size is only allowed at the end of a binary pattern'); + } + + let size = 0; + let bsValueArrayPart = []; + let patternBitStringArrayPart = []; + size = getSize(bitstringMatchPart.unit, bitstringMatchPart.size); + + if (i === patternValues.length - 1) { + bsValueArrayPart = bsValue.value.slice(beginningIndex); + patternBitStringArrayPart = patternBitString.slice(beginningIndex); + } else { + bsValueArrayPart = bsValue.value.slice(beginningIndex, beginningIndex + size); + patternBitStringArrayPart = patternBitString.slice(beginningIndex, beginningIndex + size); + } + + if (is_variable(bitstringMatchPart.value)) { + switch (bitstringMatchPart.type) { + case 'integer': + if (bitstringMatchPart.attributes && bitstringMatchPart.attributes.indexOf('signed') != -1) { + args.push(new Int8Array([bsValueArrayPart[0]])[0]); + } else { + args.push(new Uint8Array([bsValueArrayPart[0]])[0]); + } + break; + + case 'float': + if (size === 64) { + args.push(Float64Array.from(bsValueArrayPart)[0]); + } else if (size === 32) { + args.push(Float32Array.from(bsValueArrayPart)[0]); + } else { + return false; + } + break; + + case 'bitstring': + args.push(createBitString(bsValueArrayPart)); + break; + + case 'binary': + args.push(String.fromCharCode.apply(null, new Uint8Array(bsValueArrayPart))); + break; + + case 'utf8': + args.push(String.fromCharCode.apply(null, new Uint8Array(bsValueArrayPart))); + break; + + case 'utf16': + args.push(String.fromCharCode.apply(null, new Uint16Array(bsValueArrayPart))); + break; + + case 'utf32': + args.push(String.fromCharCode.apply(null, new Uint32Array(bsValueArrayPart))); + break; + + default: + return false; + } + } else if (!arraysEqual(bsValueArrayPart, patternBitStringArrayPart)) { + return false; + } + + beginningIndex = beginningIndex + size; + } + + return true; + }; +} + +function getSize(unit, size) { + return unit * size / 8; +} + +function arraysEqual(a, b) { + if (a === b) return true; + if (a == null || b == null) return false; + if (a.length != b.length) return false; + + for (var i = 0; i < a.length; ++i) { + if (a[i] !== b[i]) return false; + } + + return true; +} + +function fillArray(arr, num) { + for (let i = 0; i < num; i++) { + arr.push(0); + } +} + +function createBitString(arr) { + let integerParts = arr.map(elem => BitString.integer(elem)); + return new BitString(...integerParts); +} + +function resolveNoMatch() { + return function () { + return false; + }; +} + +const patternMap = new Map(); +patternMap.set(Variable.prototype, resolveVariable); +patternMap.set(Wildcard.prototype, resolveWildcard); +patternMap.set(HeadTail.prototype, resolveHeadTail); +patternMap.set(StartsWith.prototype, resolveStartsWith); +patternMap.set(Capture.prototype, resolveCapture); +patternMap.set(Bound.prototype, resolveBound); +patternMap.set(Type.prototype, resolveType); +patternMap.set(BitStringMatch.prototype, resolveBitString); +patternMap.set(Number.prototype, resolveNumber); +patternMap.set(Symbol.prototype, resolveSymbol); +patternMap.set(Map.prototype, resolveMap); +patternMap.set(Array.prototype, resolveArray); +patternMap.set(String.prototype, resolveString); +patternMap.set(Boolean.prototype, resolveBoolean); +patternMap.set(Function.prototype, resolveFunction); +patternMap.set(Object.prototype, resolveObject); + +function buildMatch(pattern) { + if (pattern === null) { + return resolveNull(pattern); + } + + if (typeof pattern === 'undefined') { + return resolveWildcard(pattern); + } + + const type$$1 = pattern.constructor.prototype; + const resolver = patternMap.get(type$$1); + + if (resolver) { + return resolver(pattern); + } + + if (typeof pattern === 'object') { + return resolveObject(pattern); + } + + return resolveNoMatch(); +} + +class MatchError extends Error { + constructor(arg) { + super(); + + if (typeof arg === 'symbol') { + this.message = 'No match for: ' + arg.toString(); + } else if (Array.isArray(arg)) { + let mappedValues = arg.map(x => { + if (x === null) { + return 'null'; + } else if (typeof x === 'undefined') { + return 'undefined'; + } + + return x.toString(); + }); + + this.message = 'No match for: ' + mappedValues; + } else { + this.message = 'No match for: ' + arg; + } + + this.stack = new Error().stack; + this.name = this.constructor.name; + } +} + +class Clause { + constructor(pattern, fn, guard = () => true) { + this.pattern = buildMatch(pattern); + this.arity = pattern.length; + this.optionals = getOptionalValues(pattern); + this.fn = fn; + this.guard = guard; + } +} + +function clause(pattern, fn, guard = () => true) { + return new Clause(pattern, fn, guard); +} + + + +function defmatch(...clauses) { + const arities = getArityMap(clauses); + + return function (...args) { + let [funcToCall, params] = findMatchingFunction(args, arities); + return funcToCall.apply(this, params); + }; +} + +function defmatchgen(...clauses) { + const arities = getArityMap(clauses); + + return function* (...args) { + let [funcToCall, params] = findMatchingFunction(args, arities); + return yield* funcToCall.apply(this, params); + }; +} + +function defmatchGen(...args) { + return defmatchgen(...args); +} + +function defmatchAsync(...clauses) { + const arities = getArityMap(clauses); + + return async function (...args) { + if (arities.has(args.length)) { + const arityClauses = arities.get(args.length); + + let funcToCall = null; + let params = null; + for (let processedClause of arityClauses) { + let result = []; + args = fillInOptionalValues(args, processedClause.arity, processedClause.optionals); + + const doesMatch = processedClause.pattern(args, result); + const [filteredResult, allNamesMatch] = checkNamedVariables(result); + + if (doesMatch && allNamesMatch && (await processedClause.guard.apply(this, result))) { + funcToCall = processedClause.fn; + params = result; + break; + } + } + + if (!funcToCall) { + console.error('No match for:', args); + throw new MatchError(args); + } + + return funcToCall.apply(this, params); + } else { + console.error('Arity of', args.length, 'not found. No match for:', args); + throw new MatchError(args); + } + }; +} + +function findMatchingFunction(args, arities) { + if (arities.has(args.length)) { + const arityClauses = arities.get(args.length); + + let funcToCall = null; + let params = null; + for (let processedClause of arityClauses) { + let result = []; + args = fillInOptionalValues(args, processedClause.arity, processedClause.optionals); + + const doesMatch = processedClause.pattern(args, result); + const [filteredResult, allNamesMatch] = checkNamedVariables(result); + + if (doesMatch && allNamesMatch && processedClause.guard.apply(this, filteredResult)) { + funcToCall = processedClause.fn; + params = filteredResult; + break; + } + } + + if (!funcToCall) { + console.error('No match for:', args); + throw new MatchError(args); + } + + return [funcToCall, params]; + } else { + console.error('Arity of', args.length, 'not found. No match for:', args); + throw new MatchError(args); + } +} + +function getArityMap(clauses) { + let map = new Map(); + + for (const clause of clauses) { + const range = getArityRange(clause); + + for (const arity of range) { + let arityClauses = []; + + if (map.has(arity)) { + arityClauses = map.get(arity); + } + + arityClauses.push(clause); + map.set(arity, arityClauses); + } + } + + return map; +} + +function getArityRange(clause) { + const min = clause.arity - clause.optionals.length; + const max = clause.arity; + + let range = [min]; + + while (range[range.length - 1] != max) { + range.push(range[range.length - 1] + 1); + } + + return range; +} + +function getOptionalValues(pattern) { + let optionals = []; + + for (let i = 0; i < pattern.length; i++) { + if (pattern[i] instanceof Variable && pattern[i].default_value != Symbol.for('tailored.no_value')) { + optionals.push([i, pattern[i].default_value]); + } + } + + return optionals; +} + +function fillInOptionalValues(args, arity, optionals) { + if (args.length === arity || optionals.length === 0) { + return args; + } + + if (args.length + optionals.length < arity) { + return args; + } + + let numberOfOptionalsToFill = arity - args.length; + let optionalsToRemove = optionals.length - numberOfOptionalsToFill; + + let optionalsToUse = optionals.slice(optionalsToRemove); + + for (let [index, value] of optionalsToUse) { + args.splice(index, 0, value); + if (args.length === arity) { + break; + } + } + + return args; +} + +function match(pattern, expr, guard = () => true) { + let result = []; + let processedPattern = buildMatch(pattern); + const doesMatch = processedPattern(expr, result); + const [filteredResult, allNamesMatch] = checkNamedVariables(result); + + if (doesMatch && allNamesMatch && guard.apply(this, filteredResult)) { + return filteredResult; + } else { + console.error('No match for:', expr); + throw new MatchError(expr); + } +} + +function checkNamedVariables(results) { + const namesMap = {}; + const filteredResults = []; + + for (let i = 0; i < results.length; i++) { + const current = results[i]; + if (current instanceof NamedVariableResult) { + if (namesMap[current.name] && namesMap[current.name] !== current.value) { + return [results, false]; + } else if (namesMap[current.name] && namesMap[current.name] === current.value) { + filteredResults.push(current.value); + } else { + namesMap[current.name] = current.value; + filteredResults.push(current.value); + } + } else { + filteredResults.push(current); + } + } + + return [filteredResults, true]; +} + +function match_or_default(pattern, expr, guard = () => true, default_value = null) { + let result = []; + let processedPattern = buildMatch(pattern); + const doesMatch = processedPattern(expr, result); + const [filteredResult, allNamesMatch] = checkNamedVariables(result); + + if (doesMatch && allNamesMatch && guard.apply(this, filteredResult)) { + return filteredResult; + } else { + return default_value; + } +} + +const NO_MATCH = Symbol(); + +function bitstring_generator(pattern, bitstring) { + return function () { + let returnResult = []; + let bsSlice = bitstring.slice(0, pattern.byte_size()); + let i = 1; + + while (bsSlice.byte_size == pattern.byte_size()) { + const result = match_or_default(pattern, bsSlice, () => true, NO_MATCH); + + if (result != NO_MATCH) { + const [value] = result; + returnResult.push(result); + } + + bsSlice = bitstring.slice(pattern.byte_size() * i, pattern.byte_size() * (i + 1)); + + i++; + } + + return returnResult; + }; +} + +function list_generator(pattern, list) { + return function () { + let returnResult = []; + for (let i of list) { + const result = match_or_default(pattern, i, () => true, NO_MATCH); + if (result != NO_MATCH) { + const [value] = result; + returnResult.push(value); + } + } + + return returnResult; + }; +} + +function list_comprehension(expression, generators) { + const generatedValues = run_generators(generators.pop()(), generators); + + let result = []; + + for (let value of generatedValues) { + if (expression.guard.apply(this, value)) { + result.push(expression.fn.apply(this, value)); + } + } + + return result; +} + +function run_generators(generator, generators) { + if (generators.length == 0) { + return generator.map(x => { + if (Array.isArray(x)) { + return x; + } else { + return [x]; + } + }); + } else { + const list = generators.pop(); + + let next_gen = []; + for (let j of list()) { + for (let i of generator) { + next_gen.push([j].concat(i)); + } + } + + return run_generators(next_gen, generators); + } +} + +function bitstring_comprehension(expression, generators) { + const generatedValues = run_generators(generators.pop()(), generators); + + let result = []; + + for (let value of generatedValues) { + if (expression.guard.apply(this, value)) { + result.push(expression.fn.apply(this, value)); + } + } + + result = result.map(x => ErlangTypes.BitString.integer(x)); + return new ErlangTypes.BitString(...result); +} + +var Patterns = { + defmatch, + match, + MatchError, + variable, + wildcard, + startsWith, + capture, + headTail, + type, + bound, + Clause, + clause, + bitStringMatch, + match_or_default, + defmatchgen, + list_comprehension, + list_generator, + bitstring_generator, + bitstring_comprehension, + defmatchGen, + defmatchAsync +}; + +// https://github.com/airportyh/protomorphism +class Protocol { + constructor(spec) { + this.registry = new Map(); + this.fallback = null; + + function createFun(funName) { + return function (...args) { + const thing = args[0]; + let fun = null; + + if (thing === null && this.hasImplementation(Symbol('null'))) { + fun = this.registry.get(Symbol)[funName]; + } else if (Number.isInteger(thing) && this.hasImplementation(Core.Integer)) { + fun = this.registry.get(Core.Integer)[funName]; + } else if (typeof thing === 'number' && !Number.isInteger(thing) && this.hasImplementation(Core.Float)) { + fun = this.registry.get(Core.Float)[funName]; + } else if (typeof thing === 'string' && this.hasImplementation(Core.BitString)) { + fun = this.registry.get(Core.BitString)[funName]; + } else if (thing && thing.has(Symbol.for('__struct__')) && this.hasImplementation(thing)) { + fun = this.registry.get(thing.get(Symbol.for('__struct__')).__MODULE__)[funName]; + } else if (thing !== null && this.hasImplementation(thing)) { + fun = this.registry.get(thing.constructor)[funName]; + } else if (this.fallback) { + fun = this.fallback[funName]; + } + + if (fun != null) { + const retval = fun.apply(this, args); + return retval; + } + + throw new Error(`No implementation found for ${thing}`); + }; + } + + for (const funName in spec) { + this[funName] = createFun(funName).bind(this); + } + } + + implementation(type, implementation) { + if (type === null) { + this.fallback = implementation; + } else { + this.registry.set(type, implementation); + } + } + + hasImplementation(thing) { + if (thing === Core.Integer || thing === Core.Float || thing === Core.BitString) { + return this.registry.has(thing); + } else if (thing && thing.has(Symbol.for('__struct__'))) { + return this.registry.has(thing.get(Symbol.for('__struct__')).__MODULE__); + } + + return this.registry.has(thing.constructor); + } +} + +function iterator_to_reducer(iterable, acc, fun) { + const iterator = iterable[Symbol.iterator](); + let x = iterator.next(); + let _acc = acc; + + while (x.done === false) { + _acc = fun(x.value, _acc.get(1)); + if (_acc.get(0) === Symbol.for('halt')) { + return new Core.Tuple(Symbol.for('halted'), _acc.get(1)); + } else if (_acc.get(0) === Symbol.for('suspend')) { + return new Core.Tuple(Symbol.for('suspended'), _acc.get(1), new_acc => { + return iterator_to_reducer(iterator, new_acc, fun); + }); + } + + x = iterator.next(); + } + + return new Core.Tuple(Symbol.for('done'), _acc.get(1)); +} + +function call_property(item, property) { + if (!property) { + if (item instanceof Function || typeof item === 'function') { + return item(); + } + + return item; + } + + if (item instanceof Map) { + let prop = null; + + if (item.has(property)) { + prop = property; + } else if (item.has(Symbol.for(property))) { + prop = Symbol.for(property); + } + + if (prop === null) { + throw new Error(`Property ${property} not found in ${item}`); + } + + if (item.get(prop) instanceof Function || typeof item.get(prop) === 'function') { + return item.get(prop)(); + } + return item.get(prop); + } + + let prop = null; + + if (typeof item === 'number' || typeof item === 'symbol' || typeof item === 'boolean' || typeof item === 'string') { + if (item[property] !== undefined) { + prop = property; + } else if (item[Symbol.for(property)] !== undefined) { + prop = Symbol.for(property); + } + } else if (property in item) { + prop = property; + } else if (Symbol.for(property) in item) { + prop = Symbol.for(property); + } + + if (prop === null) { + throw new Error(`Property ${property} not found in ${item}`); + } + + if (item[prop] instanceof Function || typeof item[prop] === 'function') { + return item[prop](); + } + return item[prop]; +} + +function defprotocol(spec) { + return new Protocol(spec); +} + +function defimpl(protocol, type, impl) { + protocol.implementation(type, impl); +} + +function build_namespace(ns, ns_string) { + let parts = ns_string.split('.'); + const root = ns; + let parent = ns; + + if (parts[0] === 'Elixir') { + parts = parts.slice(1); + } + + for (const part of parts) { + if (typeof parent[part] === 'undefined') { + parent[part] = {}; + } + + parent = parent[part]; + } + + root.__table__ = ns.__table__ || {}; + root.__table__[Symbol.for(ns_string)] = parent; + + return parent; +} + +function map_to_object(map) { + const object = {}; + + for (const [key, value] of map.entries()) { + if (value instanceof Map) { + object[key] = map_to_object(value); + } else { + object[key] = value; + } + } + + return object; +} + +var Functions = { + call_property, + defprotocol, + defimpl, + build_namespace, + iterator_to_reducer, + map_to_object +}; + +function _case(condition, clauses) { + return Core.Patterns.defmatch(...clauses)(condition); +} + +function cond(...clauses) { + for (const clause of clauses) { + if (clause[0]) { + return clause[1](); + } + } + + throw new Error(); +} + +function _for(expression, generators, collectable_protocol, into = []) { + let [result, fun] = collectable_protocol.into(into); + + const generatedValues = run_list_generators(generators.pop()(), generators); + + for (const value of generatedValues) { + if (expression.guard.apply(this, value)) { + result = fun(result, new Core.Tuple(Symbol.for('cont'), expression.fn.apply(this, value))); + } + } + + return fun(result, Symbol.for('done')); +} + +function run_list_generators(generator, generators) { + if (generators.length == 0) { + return generator.map(x => { + if (Array.isArray(x)) { + return x; + } + return [x]; + }); + } + const list = generators.pop(); + + const next_gen = []; + for (const j of list()) { + for (const i of generator) { + next_gen.push([j].concat(i)); + } + } + + return run_list_generators(next_gen, generators); +} + +function _try(do_fun, rescue_function, catch_fun, else_function, after_function) { + let result = null; + + try { + result = do_fun(); + } catch (e) { + let ex_result = null; + + if (rescue_function) { + try { + ex_result = rescue_function(e); + return ex_result; + } catch (ex) { + if (ex instanceof Core.Patterns.MatchError) { + throw ex; + } + } + } + + if (catch_fun) { + try { + ex_result = catch_fun(e); + return ex_result; + } catch (ex) { + if (ex instanceof Core.Patterns.MatchError) { + throw ex; + } + } + } + + throw e; + } finally { + if (after_function) { + after_function(); + } + } + + if (else_function) { + try { + return else_function(result); + } catch (ex) { + if (ex instanceof Core.Patterns.MatchError) { + throw new Error('No Match Found in Else'); + } + + throw ex; + } + } else { + return result; + } +} + +function _with(...args) { + let argsToPass = []; + let successFunction = null; + let elseFunction = null; + + if (typeof args[args.length - 2] === 'function') { + [successFunction, elseFunction] = args.splice(-2); + } else { + successFunction = args.pop(); + } + + for (let i = 0; i < args.length; i++) { + const [pattern, func] = args[i]; + + const result = func(...argsToPass); + + const patternResult = Core.Patterns.match_or_default(pattern, result); + + if (patternResult == null) { + if (elseFunction) { + return elseFunction.call(null, result); + } + return result; + } + + argsToPass = argsToPass.concat(patternResult); + } + + return successFunction(...argsToPass); +} + +function receive(clauses, after) { + console.warn('Receive not supported'); +} + +var SpecialForms = { + _case, + cond, + _for, + _try, + _with, + receive +}; + +// http://erlang.org/doc/man/erlang.html +function atom_to_binary(atom, encoding = Symbol.for('utf8')) { + if (encoding !== Symbol.for('utf8')) { + throw new Error(`unsupported encoding ${encoding}`); + } + + if (atom.__MODULE__) { + return Symbol.keyFor(atom.__MODULE__); + } + + return Symbol.keyFor(atom); +} + +function binary_to_atom(binary, encoding = Symbol.for('utf8')) { + if (encoding !== Symbol.for('utf8')) { + throw new Error(`unsupported encoding ${encoding}`); + } + + return Symbol.for(binary); +} + +function binary_to_existing_atom(binary, encoding = Symbol.for('utf8')) { + return binary_to_atom(binary, encoding); +} + +function list_concatenation(list1, list2) { + return list1.concat(list2); +} + +function list_subtraction(list1, list2) { + const list = [...list1]; + + for (const item of list2) { + const index = list.indexOf(item); + + if (index > -1) { + list.splice(index, 1); + } + } + + return list; +} + +function plus(left, right) { + if (!right) { + return +left; + } + + return left + right; +} + +function minus(left, right) { + if (!right) { + return -left; + } + + return left - right; +} + +function multiply(left, right) { + return left * right; +} + +function div(left, right) { + return left / right; +} + +function equal(left, right) { + return left == right; +} + +function doesNotEqual(left, right) { + return left != right; +} + +function greaterThan(left, right) { + return left > right; +} + +function greaterThanOrEqualTo(left, right) { + return left >= right; +} + +function lessThan(left, right) { + return left < right; +} + +function lessThanOrEqualTo(left, right) { + return left <= right; +} + +function strictlyEqual(left, right) { + return left === right; +} + +function doesNotStrictlyEqual(left, right) { + return left !== right; +} + +function and(left, right) { + return left && right; +} + +function or(left, right) { + return left || right; +} + +function not(x) { + return !x; +} + +function rem(left, right) { + return left % right; +} + +function band(left, right) { + return left & right; +} + +function bor(left, right) { + return left | right; +} + +function bnot(x) { + return ~x; +} + +function bsl(left, right) { + return left << right; +} + +function bsr(left, right) { + return left >> right; +} + +function bxor(left, right) { + return left ^ right; +} + +function is_atom(value) { + return typeof value === 'symbol' || value instanceof Symbol || value.__MODULE__; +} + +function is_bitstring$1(value) { + return value instanceof ErlangTypes.BitString; +} + +function is_boolean$1(value) { + return typeof value === 'boolean' || value instanceof Boolean; +} + +function is_number$1(value) { + return typeof value === 'number' || value instanceof Number; +} + +function is_float(value) { + return is_number$1(value) && !Number.isInteger(value); +} + +function is_function$1(value) { + return typeof value === 'function' || value instanceof Function; +} + +function is_integer(value) { + return Number.isInteger(value); +} + +function is_list(value) { + return Array.isArray(value); +} + +function is_map$1(value) { + return value instanceof Map; +} + +function is_pid(value) { + return value instanceof ErlangTypes.PID; +} + +function is_port() { + return false; +} + +function is_reference(value) { + return value instanceof ErlangTypes.Reference; +} + +function is_tuple(value) { + return value instanceof ErlangTypes.Tuple; +} + +function is_binary(value) { + return typeof value === 'string' || value instanceof String; +} + +function element(n, tuple) { + return tuple.get(n - 1); +} + +function setelement(index, tuple1, value) { + const tupleData = [...tuple1.values]; + + tupleData[index - 1] = value; + + return new ErlangTypes.Tuple(...tupleData); +} + +function make_tuple(arity, initialValue) { + const list = []; + + for (let i = 0; i < arity; i++) { + list.push(initialValue); + } + + return new ErlangTypes.Tuple(...list); +} + +function insert_element(index, tuple, term) { + const list = [...tuple.values]; + list.splice(index - 1, 0, term); + + return new ErlangTypes.Tuple(...list); +} + +function append_element(tuple, term) { + const list = [...tuple.values]; + list.push(term); + + return new ErlangTypes.Tuple(...list); +} + +function delete_element(index, tuple) { + const list = [...tuple.values]; + list.splice(index - 1, 1); + + return new ErlangTypes.Tuple(...list); +} + +function tuple_to_list(tuple) { + const list = [...tuple.values]; + return list; +} + +function abs(number) { + return Math.abs(number); +} + +function apply(...args) { + if (args.length === 2) { + return args[0].apply(this, ...args[1]); + } + + return args[0][atom_to_binary(args[1])].apply(this, ...args[2]); +} + +function binary_part(binary, start, length) { + return binary.substring(start, start + length); +} + +function bit_size(bitstring) { + return bitstring.bit_size; +} + +function byte_size(bitstring) { + return bitstring.byte_size; +} + +function hd(list) { + return list[0]; +} + +function length(list) { + return list.length; +} + +function make_ref() { + return new ErlangTypes.Reference(); +} + +function map_size(map) { + return map.size; +} + +function max(first, second) { + return Math.max(first, second); +} + +function min(first, second) { + return Math.min(first, second); +} + +function round(number) { + return Math.round(number); +} + +function tl(list) { + return list.slice(1); +} + +function trunc(number) { + return Math.trunc(number); +} + +function tuple_size(tuple) { + return tuple.length; +} + +function binary_to_float(str) { + return parseFloat(str); +} + +function binary_to_integer(str, base = 10) { + return parseInt(str, base); +} + +function process_info(pid, item) { + if (item) { + if (item === Symbol.for('current_stacktrace')) { + return new ErlangTypes.Tuple(item, []); + } + + return new ErlangTypes.Tuple(item, null); + } + + return []; +} + +var erlang = { + atom_to_binary, + binary_to_atom, + binary_to_existing_atom, + list_concatenation, + list_subtraction, + plus, + minus, + multiply, + div, + equal, + greaterThan, + greaterThanOrEqualTo, + lessThan, + lessThanOrEqualTo, + doesNotEqual, + strictlyEqual, + doesNotStrictlyEqual, + and, + or, + not, + rem, + band, + bor, + bsl, + bsr, + bxor, + bnot, + is_bitstring: is_bitstring$1, + is_boolean: is_boolean$1, + is_float, + is_function: is_function$1, + is_integer, + is_list, + is_map: is_map$1, + is_number: is_number$1, + is_pid, + is_port, + is_reference, + is_tuple, + is_atom, + is_binary, + element, + setelement, + make_tuple, + insert_element, + append_element, + delete_element, + tuple_to_list, + abs, + apply, + binary_part, + bit_size, + byte_size, + hd, + length, + make_ref, + map_size, + max, + min, + round, + tl, + trunc, + tuple_size, + binary_to_float, + binary_to_integer, + process_info +}; + +// http://erlang.org/doc/man/maps.html +const OK = Symbol.for('ok'); +const ERROR = Symbol.for('error'); +const BADMAP = Symbol.for('badmap'); +const BADKEY = Symbol.for('badkey'); + +function find(key, map) { + if (erlang.is_map(map) === false) { + return new ErlangTypes.Tuple(BADMAP, map); + } + + const value = map.get(key); + + if (typeof value !== 'undefined') { + return new ErlangTypes.Tuple(OK, value); + } + + return ERROR; +} + +function fold(fun, init, map) { + let acc = init; + + for (const [key, value] of map.entries()) { + acc = fun(key, value, acc); + } + + return acc; +} + +function remove(key, map1) { + if (erlang.is_map(map1) === false) { + return new ErlangTypes.Tuple(BADMAP, map1); + } + + const map2 = new Map(map1); + + map2.delete(key); + + return map2; +} + +function to_list(map) { + if (erlang.is_map(map) === false) { + return new ErlangTypes.Tuple(BADMAP, map); + } + + const list = []; + + for (const [key, value] of map.entries()) { + list.push(new ErlangTypes.Tuple(key, value)); + } + + return list; +} + +function from_list(list) { + return list.reduce((acc, item) => { + const [key, value] = item; + acc.set(key, value); + + return acc; + }, new Map()); +} + +function keys(map) { + if (erlang.is_map(map) === false) { + return new ErlangTypes.Tuple(BADMAP, map); + } + + return Array.from(map.keys()); +} + +function values$1(map) { + if (erlang.is_map(map) === false) { + return new ErlangTypes.Tuple(BADMAP, map); + } + + return Array.from(map.values()); +} + +function is_key(key, map) { + return map.has(key); +} + +function put(key, value, map1) { + if (erlang.is_map(map1) === false) { + return new ErlangTypes.Tuple(BADMAP, map1); + } + + const map2 = new Map(map1); + map2.set(key, value); + + return map2; +} + +function merge(map1, map2) { + if (erlang.is_map(map1) === false) { + return new ErlangTypes.Tuple(BADMAP, map1); + } + + if (erlang.is_map(map2) === false) { + return new ErlangTypes.Tuple(BADMAP, map2); + } + + return new Map([...map1, ...map2]); +} + +function update(key, value, map1) { + if (erlang.is_map(map1) === false) { + return new ErlangTypes.Tuple(BADMAP, map1); + } + + if (is_key(key, map1) === false) { + return new ErlangTypes.Tuple(BADKEY, key); + } + + return new Map([...map1, [key, value]]); +} + +function get(...args) { + const key = args[0]; + const map = args[1]; + + if (erlang.is_map(map) === false) { + return new ErlangTypes.Tuple(BADMAP, map); + } + + if (is_key(key)) { + return map.get(key); + } + + if (args.length === 3) { + return args[2]; + } + + return new ErlangTypes.Tuple(BADKEY, key); +} + +function take(key, map1) { + if (erlang.is_map(map1) === false) { + return new ErlangTypes.Tuple(BADMAP, map1); + } + + if (!is_key(key)) { + return ERROR; + } + + const value = map1.get(key); + const map2 = new Map(map1); + map2.delete(key); + + return new ErlangTypes.Tuple(value, map2); +} + +var maps = { + find, + fold, + remove, + to_list, + from_list, + keys, + values: values$1, + is_key, + put, + merge, + update, + get, + take +}; + +// http://erlang.org/doc/man/lists.html +function reverse(list) { + return [...list].reverse(); +} + +function foreach(fun, list) { + list.forEach(x => fun(x)); + + return Symbol.for('ok'); +} + +function duplicate(n, elem) { + const list = []; + + while (list.length < n) { + list.push(elem); + } + + return list; +} + +function flatten(deepList, tail = []) { + const val = deepList.reduce((acc, value) => { + if (Array.isArray(value)) { + return acc.concat(flatten(value)); + } + + return acc.concat(value); + }, []); + + return val.concat(tail); +} + +function foldl(fun, acc0, list) { + return list.reduce((acc, value) => { + return fun(value, acc); + }, acc0); +} + +function foldr(fun, acc0, list) { + return foldl(fun, acc0, reverse(list)); +} + +function keyfind(key, n, tupleList) { + for (const tuple of tupleList) { + if (tuple.get(n - 1) === key) { + return tuple; + } + } + + return false; +} + +function keymember(key, n, tupleList) { + if (keyfind(key, n, tupleList) === false) { + return false; + } + + return true; +} + +function keyreplace(key, n, tupleList, newTuple) { + const newTupleList = [...tupleList]; + + for (let index = 0; index < newTupleList.length; index++) { + if (newTupleList[index].get(n - 1) === key) { + newTupleList[index] = newTuple; + return newTupleList; + } + } + + return newTupleList; +} + +function keysort(n, tupleList) { + const newTupleList = [...tupleList]; + + return newTupleList.sort((a, b) => { + if (a.get(n - 1) < b.get(n - 1)) { + return -1; + } else if (a.get(n - 1) > b.get(n - 1)) { + return 1; + } + + return 0; + }); +} + +function keystore(key, n, tupleList, newTuple) { + const newTupleList = [...tupleList]; + + for (let index = 0; index < newTupleList.length; index++) { + if (newTupleList[index].get(n - 1) === key) { + newTupleList[index] = newTuple; + return newTupleList; + } + } + + return newTupleList.concat(newTuple); +} + +function keydelete(key, n, tupleList) { + const newTupleList = []; + let deleted = false; + + for (let index = 0; index < tupleList.length; index++) { + if (deleted === false && tupleList[index].get(n - 1) === key) { + deleted = true; + } else { + newTupleList.push(tupleList[index]); + } + } + + return newTupleList; +} + +function keytake(key, n, tupleList) { + const result = keyfind(key, n, tupleList); + + if (result !== false) { + return new ErlangTypes.Tuple(result.get(n - 1), result, keydelete(key, n, tupleList)); + } + + return false; +} + +function mapfoldl(fun, acc0, list1) { + const listResult = []; + let accResult = acc0; + + for (const item of list1) { + const tuple = fun(item, accResult); + listResult.push(tuple.get(0)); + accResult = tuple.get(1); + } + + return new ErlangTypes.Tuple(listResult, accResult); +} + +function concat(things) { + return things.map(v => v.toString()).join(); +} + +function map(fun, list) { + return list.map(value => fun(value)); +} + +function filter(pred, list1) { + return list1.filter(x => pred(x)); +} + +function filtermap(fun, list1) { + const list2 = []; + + for (const item of list1) { + const value = fun(item); + + if (value === true) { + list2.push(item); + } else if (value instanceof ErlangTypes.Tuple && value.get(0) === true) { + list2.push(value.get(1)); + } + } + + return list2; +} + +function member(elem, list) { + for (const item of list) { + if (item === elem) { + return true; + } + } + + return false; +} + +function all(pred, list) { + for (const item of list) { + if (pred(item) === false) { + return false; + } + } + + return true; +} + +function any(pred, list) { + for (const item of list) { + if (pred(item) === true) { + return true; + } + } + + return false; +} + +function splitwith(pred, list) { + let switchToList2 = false; + const list1 = []; + const list2 = []; + + for (const item of list) { + if (switchToList2 === true) { + list2.push(item); + } else if (pred(item) === true) { + list1.push(item); + } else { + switchToList2 = true; + list2.push(item); + } + } + + return new ErlangTypes.Tuple(list1, list2); +} + +function sort(...args) { + if (args.length === 1) { + const list2 = [...args[0]]; + return list2.sort(); + } + + const fun = args[0]; + const list2 = [...args[1]]; + + return list2.sort((a, b) => { + const result = fun(a, b); + + if (result === true) { + return -1; + } + + return 1; + }); +} + +var lists = { + reverse, + foreach, + duplicate, + flatten, + foldl, + foldr, + keydelete, + keyfind, + keymember, + keyreplace, + keysort, + keystore, + keytake, + mapfoldl, + concat, + map, + filter, + filtermap, + member, + all, + any, + splitwith, + sort +}; + +function warn(message) { + const messageString = message.join(''); + console.warn(`warning ${messageString}`); + + return Symbol.for('ok'); +} + +var elixir_errors = { + warn +}; + +function get_key(key) { + let real_key = key; + + if (__elixirscript_names__.has(key)) { + real_key = __elixirscript_names__.get(key); + } + + if (__elixirscript_store__.has(real_key)) { + return real_key; + } + + throw new Error(`Key ${real_key} not found`); +} + +function create(value, name = null) { + const key = new Core.PID(); + + if (name !== null) { + __elixirscript_names__.set(name, key); + } + + return __elixirscript_store__.set(key, value); +} + +function update$1(key, value) { + const real_key = get_key(key); + return __elixirscript_store__.set(real_key, value); +} + +function read(key) { + const real_key = get_key(key); + return __elixirscript_store__.get(real_key); +} + +function remove$1(key) { + const real_key = get_key(key); + return __elixirscript_store__.delete(real_key); +} + +var Store = { + create, + update: update$1, + read, + remove: remove$1 +}; + +class Integer {} +class Float {} + +function get_global() { + if (typeof self !== 'undefined') { + return self; + } else if (typeof window !== 'undefined') { + return window; + } else if (typeof global !== 'undefined') { + return global; + } + + console.warn('No global state found'); + return null; +} + +const globalState = get_global(); + +globalState.__elixirscript_store__ = new Map(); +globalState.__elixirscript_names__ = new Map(); + +var Core = { + Tuple: ErlangTypes.Tuple, + PID: ErlangTypes.PID, + BitString: ErlangTypes.BitString, + Patterns, + Integer, + Float, + Functions, + SpecialForms, + Store, + global: globalState, + erlang, + maps, + lists, + elixir_errors +}; + +var elixir = { + Core +}; + +return elixir; + +}()); diff --git a/src/javascript/lib/core.js b/src/javascript/lib/core.js index b1c85c9e..f0e5277f 100644 --- a/src/javascript/lib/core.js +++ b/src/javascript/lib/core.js @@ -5,6 +5,7 @@ import SpecialForms from './core/special_forms'; import erlang from './core/erlang_compat/erlang'; import maps from './core/erlang_compat/maps'; import lists from './core/erlang_compat/lists'; +import elixir_errors from './core/erlang_compat/elixir_errors'; import Store from './core/store'; class Integer {} @@ -41,5 +42,6 @@ export default { global: globalState, erlang, maps, - lists + lists, + elixir_errors }; diff --git a/src/javascript/lib/core/erlang_compat/elixir_errors.js b/src/javascript/lib/core/erlang_compat/elixir_errors.js new file mode 100644 index 00000000..67efd473 --- /dev/null +++ b/src/javascript/lib/core/erlang_compat/elixir_errors.js @@ -0,0 +1,10 @@ +function warn(message) { + const messageString = message.join(''); + console.warn(`warning: ${messageString}`); + + return Symbol.for('ok'); +} + +export default { + warn +}; diff --git a/src/javascript/lib/core/erlang_compat/erlang.js b/src/javascript/lib/core/erlang_compat/erlang.js index 338c3a2b..670d9047 100644 --- a/src/javascript/lib/core/erlang_compat/erlang.js +++ b/src/javascript/lib/core/erlang_compat/erlang.js @@ -317,6 +317,18 @@ function binary_to_integer(str, base = 10) { return parseInt(str, base); } +function process_info(pid, item) { + if (item) { + if (item === Symbol.for('current_stacktrace')) { + return new ErlangTypes.Tuple(item, []); + } + + return new ErlangTypes.Tuple(item, null); + } + + return []; +} + export default { atom_to_binary, binary_to_atom, @@ -382,5 +394,6 @@ export default { trunc, tuple_size, binary_to_float, - binary_to_integer + binary_to_integer, + process_info }; From dc01dc76ea23afa43e5b63d6b2e275a21596a6c9 Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Thu, 20 Jul 2017 22:52:43 -0500 Subject: [PATCH 187/418] minify ElixirScript.Core.js --- priv/build/iife/ElixirScript.Core.js | 2564 +------------------------- 1 file changed, 6 insertions(+), 2558 deletions(-) diff --git a/priv/build/iife/ElixirScript.Core.js b/priv/build/iife/ElixirScript.Core.js index 2ffba822..f97d3ed7 100644 --- a/priv/build/iife/ElixirScript.Core.js +++ b/priv/build/iife/ElixirScript.Core.js @@ -1,2558 +1,6 @@ -var ElixirScript = (function () { -'use strict'; - -/* @flow */ - -class Variable { - constructor(name = null, default_value = Symbol.for('tailored.no_value')) { - this.name = name; - this.default_value = default_value; - } -} - -class Wildcard { - constructor() {} -} - -class StartsWith { - constructor(prefix) { - this.prefix = prefix; - } -} - -class Capture { - constructor(value) { - this.value = value; - } -} - -class HeadTail { - constructor() {} -} - -class Type { - constructor(type, objPattern = {}) { - this.type = type; - this.objPattern = objPattern; - } -} - -class Bound { - constructor(value) { - this.value = value; - } -} - -class BitStringMatch { - constructor(...values) { - this.values = values; - } - - length() { - return values.length; - } - - bit_size() { - return this.byte_size() * 8; - } - - byte_size() { - let s = 0; - - for (let val of this.values) { - s = s + val.unit * val.size / 8; - } - - return s; - } - - getValue(index) { - return this.values(index); - } - - getSizeOfValue(index) { - let val = this.getValue(index); - return val.unit * val.size; - } - - getTypeOfValue(index) { - return this.getValue(index).type; - } -} - -class NamedVariableResult { - constructor(name, value) { - this.name = name; - this.value = value; - } -} - -function variable(name = null, default_value = Symbol.for('tailored.no_value')) { - return new Variable(name, default_value); -} - -function wildcard() { - return new Wildcard(); -} - -function startsWith(prefix) { - return new StartsWith(prefix); -} - -function capture(value) { - return new Capture(value); -} - -function headTail() { - return new HeadTail(); -} - -function type(type, objPattern = {}) { - return new Type(type, objPattern); -} - -function bound(value) { - return new Bound(value); -} - -function bitStringMatch(...values) { - return new BitStringMatch(...values); -} - -function namedVariableResult(name, value) { - return new NamedVariableResult(name, value); -} - -/* @flow */ - -function is_number(value) { - return typeof value === 'number'; -} - -function is_string(value) { - return typeof value === 'string'; -} - -function is_boolean(value) { - return typeof value === 'boolean'; -} - -function is_symbol(value) { - return typeof value === 'symbol'; -} - -function is_object(value) { - return typeof value === 'object'; -} - -function is_variable(value) { - return value instanceof Variable; -} - -function is_null(value) { - return value === null; -} - -function is_array(value) { - return Array.isArray(value); -} - -function is_function(value) { - return Object.prototype.toString.call(value) == '[object Function]'; -} - -function is_map(value) { - return value instanceof Map; -} - -class Tuple { - constructor(...args) { - this.values = Object.freeze(args); - this.length = this.values.length; - } - - get(index) { - return this.values[index]; - } - - count() { - return this.values.length; - } - - [Symbol.iterator]() { - return this.values[Symbol.iterator](); - } - - toString() { - let i, - s = ''; - for (i = 0; i < this.values.length; i++) { - if (s !== '') { - s += ', '; - } - - const stringToAppend = this.values[i] ? this.values[i].toString() : ''; - - s += stringToAppend; - } - - return '{' + s + '}'; - } - - put_elem(index, elem) { - if (index === this.length) { - let new_values = this.values.concat([elem]); - return new Tuple(...new_values); - } - - let new_values = this.values.concat([]); - new_values.splice(index, 0, elem); - return new Tuple(...new_values); - } - - remove_elem(index) { - let new_values = this.values.concat([]); - new_values.splice(index, 1); - return new Tuple(...new_values); - } -} - -let process_counter = -1; - -class PID { - constructor() { - process_counter = process_counter + 1; - this.id = process_counter; - } - - toString() { - return 'PID#<0.' + this.id + '.0>'; - } -} - -let ref_counter = -1; - -class Reference { - constructor() { - ref_counter = ref_counter + 1; - this.id = ref_counter; - this.ref = Symbol(); - } - - toString() { - return 'Ref#<0.0.0.' + this.id + '>'; - } -} - -class BitString$1 { - constructor(...args) { - this.value = Object.freeze(this.process(args)); - this.length = this.value.length; - this.bit_size = this.length * 8; - this.byte_size = this.length; - } - - get(index) { - return this.value[index]; - } - - count() { - return this.value.length; - } - - slice(start, end = null) { - let s = this.value.slice(start, end); - let ms = s.map(elem => BitString$1.integer(elem)); - return new BitString$1(...ms); - } - - [Symbol.iterator]() { - return this.value[Symbol.iterator](); - } - - toString() { - var i, - s = ''; - for (i = 0; i < this.count(); i++) { - if (s !== '') { - s += ', '; - } - s += this.get(i).toString(); - } - - return '<<' + s + '>>'; - } - - process(bitStringParts) { - let processed_values = []; - - var i; - for (i = 0; i < bitStringParts.length; i++) { - let processed_value = this['process_' + bitStringParts[i].type](bitStringParts[i]); - - for (let attr of bitStringParts[i].attributes) { - processed_value = this['process_' + attr](processed_value); - } - - processed_values = processed_values.concat(processed_value); - } - - return processed_values; - } - - process_integer(value) { - return value.value; - } - - process_float(value) { - if (value.size === 64) { - return BitString$1.float64ToBytes(value.value); - } else if (value.size === 32) { - return BitString$1.float32ToBytes(value.value); - } - - throw new Error('Invalid size for float'); - } - - process_bitstring(value) { - return value.value.value; - } - - process_binary(value) { - return BitString$1.toUTF8Array(value.value); - } - - process_utf8(value) { - return BitString$1.toUTF8Array(value.value); - } - - process_utf16(value) { - return BitString$1.toUTF16Array(value.value); - } - - process_utf32(value) { - return BitString$1.toUTF32Array(value.value); - } - - process_signed(value) { - return new Uint8Array([value])[0]; - } - - process_unsigned(value) { - return value; - } - - process_native(value) { - return value; - } - - process_big(value) { - return value; - } - - process_little(value) { - return value.reverse(); - } - - process_size(value) { - return value; - } - - process_unit(value) { - return value; - } - - static integer(value) { - return BitString$1.wrap(value, { type: 'integer', unit: 1, size: 8 }); - } - - static float(value) { - return BitString$1.wrap(value, { type: 'float', unit: 1, size: 64 }); - } - - static bitstring(value) { - return BitString$1.wrap(value, { - type: 'bitstring', - unit: 1, - size: value.bit_size - }); - } - - static bits(value) { - return BitString$1.bitstring(value); - } - - static binary(value) { - return BitString$1.wrap(value, { - type: 'binary', - unit: 8, - size: value.length - }); - } - - static bytes(value) { - return BitString$1.binary(value); - } - - static utf8(value) { - return BitString$1.wrap(value, { type: 'utf8', unit: 1, size: value.length }); - } - - static utf16(value) { - return BitString$1.wrap(value, { - type: 'utf16', - unit: 1, - size: value.length * 2 - }); - } - - static utf32(value) { - return BitString$1.wrap(value, { - type: 'utf32', - unit: 1, - size: value.length * 4 - }); - } - - static signed(value) { - return BitString$1.wrap(value, {}, 'signed'); - } - - static unsigned(value) { - return BitString$1.wrap(value, {}, 'unsigned'); - } - - static native(value) { - return BitString$1.wrap(value, {}, 'native'); - } - - static big(value) { - return BitString$1.wrap(value, {}, 'big'); - } - - static little(value) { - return BitString$1.wrap(value, {}, 'little'); - } - - static size(value, count) { - return BitString$1.wrap(value, { size: count }); - } - - static unit(value, count) { - return BitString$1.wrap(value, { unit: count }); - } - - static wrap(value, opt, new_attribute = null) { - let the_value = value; - - if (!(value instanceof Object)) { - the_value = { value: value, attributes: [] }; - } - - the_value = Object.assign(the_value, opt); - - if (new_attribute) { - the_value.attributes.push(new_attribute); - } - - return the_value; - } - - static toUTF8Array(str) { - var utf8 = []; - for (var i = 0; i < str.length; i++) { - var charcode = str.charCodeAt(i); - if (charcode < 0x80) { - utf8.push(charcode); - } else if (charcode < 0x800) { - utf8.push(0xc0 | charcode >> 6, 0x80 | charcode & 0x3f); - } else if (charcode < 0xd800 || charcode >= 0xe000) { - utf8.push(0xe0 | charcode >> 12, 0x80 | charcode >> 6 & 0x3f, 0x80 | charcode & 0x3f); - } else { - // surrogate pair - i++; - // UTF-16 encodes 0x10000-0x10FFFF by - // subtracting 0x10000 and splitting the - // 20 bits of 0x0-0xFFFFF into two halves - charcode = 0x10000 + ((charcode & 0x3ff) << 10 | str.charCodeAt(i) & 0x3ff); - utf8.push(0xf0 | charcode >> 18, 0x80 | charcode >> 12 & 0x3f, 0x80 | charcode >> 6 & 0x3f, 0x80 | charcode & 0x3f); - } - } - return utf8; - } - - static toUTF16Array(str) { - var utf16 = []; - for (var i = 0; i < str.length; i++) { - var codePoint = str.codePointAt(i); - - if (codePoint <= 255) { - utf16.push(0); - utf16.push(codePoint); - } else { - utf16.push(codePoint >> 8 & 0xff); - utf16.push(codePoint & 0xff); - } - } - return utf16; - } - - static toUTF32Array(str) { - var utf32 = []; - for (var i = 0; i < str.length; i++) { - var codePoint = str.codePointAt(i); - - if (codePoint <= 255) { - utf32.push(0); - utf32.push(0); - utf32.push(0); - utf32.push(codePoint); - } else { - utf32.push(0); - utf32.push(0); - utf32.push(codePoint >> 8 & 0xff); - utf32.push(codePoint & 0xff); - } - } - return utf32; - } - - //http://stackoverflow.com/questions/2003493/javascript-float-from-to-bits - static float32ToBytes(f) { - var bytes = []; - - var buf = new ArrayBuffer(4); - new Float32Array(buf)[0] = f; - - let intVersion = new Uint32Array(buf)[0]; - - bytes.push(intVersion >> 24 & 0xff); - bytes.push(intVersion >> 16 & 0xff); - bytes.push(intVersion >> 8 & 0xff); - bytes.push(intVersion & 0xff); - - return bytes; - } - - static float64ToBytes(f) { - var bytes = []; - - var buf = new ArrayBuffer(8); - new Float64Array(buf)[0] = f; - - var intVersion1 = new Uint32Array(buf)[0]; - var intVersion2 = new Uint32Array(buf)[1]; - - bytes.push(intVersion2 >> 24 & 0xff); - bytes.push(intVersion2 >> 16 & 0xff); - bytes.push(intVersion2 >> 8 & 0xff); - bytes.push(intVersion2 & 0xff); - - bytes.push(intVersion1 >> 24 & 0xff); - bytes.push(intVersion1 >> 16 & 0xff); - bytes.push(intVersion1 >> 8 & 0xff); - bytes.push(intVersion1 & 0xff); - - return bytes; - } -} - -var ErlangTypes = { - Tuple, - PID, - Reference, - BitString: BitString$1 -}; - -/* @flow */ - -const BitString = ErlangTypes.BitString; - -function resolveSymbol(pattern) { - return function (value) { - return is_symbol(value) && value === pattern; - }; -} - -function resolveString(pattern) { - return function (value) { - return is_string(value) && value === pattern; - }; -} - -function resolveNumber(pattern) { - return function (value) { - return is_number(value) && value === pattern; - }; -} - -function resolveBoolean(pattern) { - return function (value) { - return is_boolean(value) && value === pattern; - }; -} - -function resolveFunction(pattern) { - return function (value) { - return is_function(value) && value === pattern; - }; -} - -function resolveNull(pattern) { - return function (value) { - return is_null(value); - }; -} - -function resolveBound(pattern) { - return function (value, args) { - if (typeof value === typeof pattern.value && value === pattern.value) { - return true; - } - - return false; - }; -} - -function resolveWildcard() { - return function () { - return true; - }; -} - -function resolveVariable(pattern) { - return function (value, args) { - if (pattern.name === null || pattern.name.startsWith('_')) { - args.push(value); - } else { - args.push(namedVariableResult(pattern.name, value)); - } - - return true; - }; -} - -function resolveHeadTail() { - return function (value, args) { - if (!is_array(value) || value.length < 2) { - return false; - } - - const head = value[0]; - const tail = value.slice(1); - - args.push(head); - args.push(tail); - - return true; - }; -} - -function resolveCapture(pattern) { - const matches = buildMatch(pattern.value); - - return function (value, args) { - if (matches(value, args)) { - args.push(value); - return true; - } - - return false; - }; -} - -function resolveStartsWith(pattern) { - const prefix = pattern.prefix; - - return function (value, args) { - if (is_string(value) && value.startsWith(prefix)) { - args.push(value.substring(prefix.length)); - return true; - } - - return false; - }; -} - -function resolveType(pattern) { - return function (value, args) { - if (value instanceof pattern.type) { - const matches = buildMatch(pattern.objPattern); - return matches(value, args); - } - - return false; - }; -} - -function resolveArray(pattern) { - const matches = pattern.map(x => buildMatch(x)); - - return function (value, args) { - if (!is_array(value) || value.length != pattern.length) { - return false; - } - - return value.every(function (v, i) { - return matches[i](value[i], args); - }); - }; -} - -function resolveMap(pattern) { - let matches = new Map(); - - const keys = Array.from(pattern.keys()); - - for (let key of keys) { - matches.set(key, buildMatch(pattern.get(key))); - } - - return function (value, args) { - if (!is_map(value) || pattern.size > value.size) { - return false; - } - - for (let key of keys) { - if (!value.has(key) || !matches.get(key)(value.get(key), args)) { - return false; - } - } - - return true; - }; -} - -function resolveObject(pattern) { - let matches = {}; - - const keys = Object.keys(pattern).concat(Object.getOwnPropertySymbols(pattern)); - - for (let key of keys) { - matches[key] = buildMatch(pattern[key]); - } - - return function (value, args) { - if (!is_object(value) || pattern.length > value.length) { - return false; - } - - for (let key of keys) { - if (!(key in value) || !matches[key](value[key], args)) { - return false; - } - } - - return true; - }; -} - -function resolveBitString(pattern) { - let patternBitString = []; - - for (let bitstringMatchPart of pattern.values) { - if (is_variable(bitstringMatchPart.value)) { - let size = getSize(bitstringMatchPart.unit, bitstringMatchPart.size); - fillArray(patternBitString, size); - } else { - patternBitString = patternBitString.concat(new BitString(bitstringMatchPart).value); - } - } - - let patternValues = pattern.values; - - return function (value, args) { - let bsValue = null; - - if (!is_string(value) && !(value instanceof BitString)) { - return false; - } - - if (is_string(value)) { - bsValue = new BitString(BitString.binary(value)); - } else { - bsValue = value; - } - - let beginningIndex = 0; - - for (let i = 0; i < patternValues.length; i++) { - let bitstringMatchPart = patternValues[i]; - - if (is_variable(bitstringMatchPart.value) && bitstringMatchPart.type == 'binary' && bitstringMatchPart.size === undefined && i < patternValues.length - 1) { - throw new Error('a binary field without size is only allowed at the end of a binary pattern'); - } - - let size = 0; - let bsValueArrayPart = []; - let patternBitStringArrayPart = []; - size = getSize(bitstringMatchPart.unit, bitstringMatchPart.size); - - if (i === patternValues.length - 1) { - bsValueArrayPart = bsValue.value.slice(beginningIndex); - patternBitStringArrayPart = patternBitString.slice(beginningIndex); - } else { - bsValueArrayPart = bsValue.value.slice(beginningIndex, beginningIndex + size); - patternBitStringArrayPart = patternBitString.slice(beginningIndex, beginningIndex + size); - } - - if (is_variable(bitstringMatchPart.value)) { - switch (bitstringMatchPart.type) { - case 'integer': - if (bitstringMatchPart.attributes && bitstringMatchPart.attributes.indexOf('signed') != -1) { - args.push(new Int8Array([bsValueArrayPart[0]])[0]); - } else { - args.push(new Uint8Array([bsValueArrayPart[0]])[0]); - } - break; - - case 'float': - if (size === 64) { - args.push(Float64Array.from(bsValueArrayPart)[0]); - } else if (size === 32) { - args.push(Float32Array.from(bsValueArrayPart)[0]); - } else { - return false; - } - break; - - case 'bitstring': - args.push(createBitString(bsValueArrayPart)); - break; - - case 'binary': - args.push(String.fromCharCode.apply(null, new Uint8Array(bsValueArrayPart))); - break; - - case 'utf8': - args.push(String.fromCharCode.apply(null, new Uint8Array(bsValueArrayPart))); - break; - - case 'utf16': - args.push(String.fromCharCode.apply(null, new Uint16Array(bsValueArrayPart))); - break; - - case 'utf32': - args.push(String.fromCharCode.apply(null, new Uint32Array(bsValueArrayPart))); - break; - - default: - return false; - } - } else if (!arraysEqual(bsValueArrayPart, patternBitStringArrayPart)) { - return false; - } - - beginningIndex = beginningIndex + size; - } - - return true; - }; -} - -function getSize(unit, size) { - return unit * size / 8; -} - -function arraysEqual(a, b) { - if (a === b) return true; - if (a == null || b == null) return false; - if (a.length != b.length) return false; - - for (var i = 0; i < a.length; ++i) { - if (a[i] !== b[i]) return false; - } - - return true; -} - -function fillArray(arr, num) { - for (let i = 0; i < num; i++) { - arr.push(0); - } -} - -function createBitString(arr) { - let integerParts = arr.map(elem => BitString.integer(elem)); - return new BitString(...integerParts); -} - -function resolveNoMatch() { - return function () { - return false; - }; -} - -const patternMap = new Map(); -patternMap.set(Variable.prototype, resolveVariable); -patternMap.set(Wildcard.prototype, resolveWildcard); -patternMap.set(HeadTail.prototype, resolveHeadTail); -patternMap.set(StartsWith.prototype, resolveStartsWith); -patternMap.set(Capture.prototype, resolveCapture); -patternMap.set(Bound.prototype, resolveBound); -patternMap.set(Type.prototype, resolveType); -patternMap.set(BitStringMatch.prototype, resolveBitString); -patternMap.set(Number.prototype, resolveNumber); -patternMap.set(Symbol.prototype, resolveSymbol); -patternMap.set(Map.prototype, resolveMap); -patternMap.set(Array.prototype, resolveArray); -patternMap.set(String.prototype, resolveString); -patternMap.set(Boolean.prototype, resolveBoolean); -patternMap.set(Function.prototype, resolveFunction); -patternMap.set(Object.prototype, resolveObject); - -function buildMatch(pattern) { - if (pattern === null) { - return resolveNull(pattern); - } - - if (typeof pattern === 'undefined') { - return resolveWildcard(pattern); - } - - const type$$1 = pattern.constructor.prototype; - const resolver = patternMap.get(type$$1); - - if (resolver) { - return resolver(pattern); - } - - if (typeof pattern === 'object') { - return resolveObject(pattern); - } - - return resolveNoMatch(); -} - -class MatchError extends Error { - constructor(arg) { - super(); - - if (typeof arg === 'symbol') { - this.message = 'No match for: ' + arg.toString(); - } else if (Array.isArray(arg)) { - let mappedValues = arg.map(x => { - if (x === null) { - return 'null'; - } else if (typeof x === 'undefined') { - return 'undefined'; - } - - return x.toString(); - }); - - this.message = 'No match for: ' + mappedValues; - } else { - this.message = 'No match for: ' + arg; - } - - this.stack = new Error().stack; - this.name = this.constructor.name; - } -} - -class Clause { - constructor(pattern, fn, guard = () => true) { - this.pattern = buildMatch(pattern); - this.arity = pattern.length; - this.optionals = getOptionalValues(pattern); - this.fn = fn; - this.guard = guard; - } -} - -function clause(pattern, fn, guard = () => true) { - return new Clause(pattern, fn, guard); -} - - - -function defmatch(...clauses) { - const arities = getArityMap(clauses); - - return function (...args) { - let [funcToCall, params] = findMatchingFunction(args, arities); - return funcToCall.apply(this, params); - }; -} - -function defmatchgen(...clauses) { - const arities = getArityMap(clauses); - - return function* (...args) { - let [funcToCall, params] = findMatchingFunction(args, arities); - return yield* funcToCall.apply(this, params); - }; -} - -function defmatchGen(...args) { - return defmatchgen(...args); -} - -function defmatchAsync(...clauses) { - const arities = getArityMap(clauses); - - return async function (...args) { - if (arities.has(args.length)) { - const arityClauses = arities.get(args.length); - - let funcToCall = null; - let params = null; - for (let processedClause of arityClauses) { - let result = []; - args = fillInOptionalValues(args, processedClause.arity, processedClause.optionals); - - const doesMatch = processedClause.pattern(args, result); - const [filteredResult, allNamesMatch] = checkNamedVariables(result); - - if (doesMatch && allNamesMatch && (await processedClause.guard.apply(this, result))) { - funcToCall = processedClause.fn; - params = result; - break; - } - } - - if (!funcToCall) { - console.error('No match for:', args); - throw new MatchError(args); - } - - return funcToCall.apply(this, params); - } else { - console.error('Arity of', args.length, 'not found. No match for:', args); - throw new MatchError(args); - } - }; -} - -function findMatchingFunction(args, arities) { - if (arities.has(args.length)) { - const arityClauses = arities.get(args.length); - - let funcToCall = null; - let params = null; - for (let processedClause of arityClauses) { - let result = []; - args = fillInOptionalValues(args, processedClause.arity, processedClause.optionals); - - const doesMatch = processedClause.pattern(args, result); - const [filteredResult, allNamesMatch] = checkNamedVariables(result); - - if (doesMatch && allNamesMatch && processedClause.guard.apply(this, filteredResult)) { - funcToCall = processedClause.fn; - params = filteredResult; - break; - } - } - - if (!funcToCall) { - console.error('No match for:', args); - throw new MatchError(args); - } - - return [funcToCall, params]; - } else { - console.error('Arity of', args.length, 'not found. No match for:', args); - throw new MatchError(args); - } -} - -function getArityMap(clauses) { - let map = new Map(); - - for (const clause of clauses) { - const range = getArityRange(clause); - - for (const arity of range) { - let arityClauses = []; - - if (map.has(arity)) { - arityClauses = map.get(arity); - } - - arityClauses.push(clause); - map.set(arity, arityClauses); - } - } - - return map; -} - -function getArityRange(clause) { - const min = clause.arity - clause.optionals.length; - const max = clause.arity; - - let range = [min]; - - while (range[range.length - 1] != max) { - range.push(range[range.length - 1] + 1); - } - - return range; -} - -function getOptionalValues(pattern) { - let optionals = []; - - for (let i = 0; i < pattern.length; i++) { - if (pattern[i] instanceof Variable && pattern[i].default_value != Symbol.for('tailored.no_value')) { - optionals.push([i, pattern[i].default_value]); - } - } - - return optionals; -} - -function fillInOptionalValues(args, arity, optionals) { - if (args.length === arity || optionals.length === 0) { - return args; - } - - if (args.length + optionals.length < arity) { - return args; - } - - let numberOfOptionalsToFill = arity - args.length; - let optionalsToRemove = optionals.length - numberOfOptionalsToFill; - - let optionalsToUse = optionals.slice(optionalsToRemove); - - for (let [index, value] of optionalsToUse) { - args.splice(index, 0, value); - if (args.length === arity) { - break; - } - } - - return args; -} - -function match(pattern, expr, guard = () => true) { - let result = []; - let processedPattern = buildMatch(pattern); - const doesMatch = processedPattern(expr, result); - const [filteredResult, allNamesMatch] = checkNamedVariables(result); - - if (doesMatch && allNamesMatch && guard.apply(this, filteredResult)) { - return filteredResult; - } else { - console.error('No match for:', expr); - throw new MatchError(expr); - } -} - -function checkNamedVariables(results) { - const namesMap = {}; - const filteredResults = []; - - for (let i = 0; i < results.length; i++) { - const current = results[i]; - if (current instanceof NamedVariableResult) { - if (namesMap[current.name] && namesMap[current.name] !== current.value) { - return [results, false]; - } else if (namesMap[current.name] && namesMap[current.name] === current.value) { - filteredResults.push(current.value); - } else { - namesMap[current.name] = current.value; - filteredResults.push(current.value); - } - } else { - filteredResults.push(current); - } - } - - return [filteredResults, true]; -} - -function match_or_default(pattern, expr, guard = () => true, default_value = null) { - let result = []; - let processedPattern = buildMatch(pattern); - const doesMatch = processedPattern(expr, result); - const [filteredResult, allNamesMatch] = checkNamedVariables(result); - - if (doesMatch && allNamesMatch && guard.apply(this, filteredResult)) { - return filteredResult; - } else { - return default_value; - } -} - -const NO_MATCH = Symbol(); - -function bitstring_generator(pattern, bitstring) { - return function () { - let returnResult = []; - let bsSlice = bitstring.slice(0, pattern.byte_size()); - let i = 1; - - while (bsSlice.byte_size == pattern.byte_size()) { - const result = match_or_default(pattern, bsSlice, () => true, NO_MATCH); - - if (result != NO_MATCH) { - const [value] = result; - returnResult.push(result); - } - - bsSlice = bitstring.slice(pattern.byte_size() * i, pattern.byte_size() * (i + 1)); - - i++; - } - - return returnResult; - }; -} - -function list_generator(pattern, list) { - return function () { - let returnResult = []; - for (let i of list) { - const result = match_or_default(pattern, i, () => true, NO_MATCH); - if (result != NO_MATCH) { - const [value] = result; - returnResult.push(value); - } - } - - return returnResult; - }; -} - -function list_comprehension(expression, generators) { - const generatedValues = run_generators(generators.pop()(), generators); - - let result = []; - - for (let value of generatedValues) { - if (expression.guard.apply(this, value)) { - result.push(expression.fn.apply(this, value)); - } - } - - return result; -} - -function run_generators(generator, generators) { - if (generators.length == 0) { - return generator.map(x => { - if (Array.isArray(x)) { - return x; - } else { - return [x]; - } - }); - } else { - const list = generators.pop(); - - let next_gen = []; - for (let j of list()) { - for (let i of generator) { - next_gen.push([j].concat(i)); - } - } - - return run_generators(next_gen, generators); - } -} - -function bitstring_comprehension(expression, generators) { - const generatedValues = run_generators(generators.pop()(), generators); - - let result = []; - - for (let value of generatedValues) { - if (expression.guard.apply(this, value)) { - result.push(expression.fn.apply(this, value)); - } - } - - result = result.map(x => ErlangTypes.BitString.integer(x)); - return new ErlangTypes.BitString(...result); -} - -var Patterns = { - defmatch, - match, - MatchError, - variable, - wildcard, - startsWith, - capture, - headTail, - type, - bound, - Clause, - clause, - bitStringMatch, - match_or_default, - defmatchgen, - list_comprehension, - list_generator, - bitstring_generator, - bitstring_comprehension, - defmatchGen, - defmatchAsync -}; - -// https://github.com/airportyh/protomorphism -class Protocol { - constructor(spec) { - this.registry = new Map(); - this.fallback = null; - - function createFun(funName) { - return function (...args) { - const thing = args[0]; - let fun = null; - - if (thing === null && this.hasImplementation(Symbol('null'))) { - fun = this.registry.get(Symbol)[funName]; - } else if (Number.isInteger(thing) && this.hasImplementation(Core.Integer)) { - fun = this.registry.get(Core.Integer)[funName]; - } else if (typeof thing === 'number' && !Number.isInteger(thing) && this.hasImplementation(Core.Float)) { - fun = this.registry.get(Core.Float)[funName]; - } else if (typeof thing === 'string' && this.hasImplementation(Core.BitString)) { - fun = this.registry.get(Core.BitString)[funName]; - } else if (thing && thing.has(Symbol.for('__struct__')) && this.hasImplementation(thing)) { - fun = this.registry.get(thing.get(Symbol.for('__struct__')).__MODULE__)[funName]; - } else if (thing !== null && this.hasImplementation(thing)) { - fun = this.registry.get(thing.constructor)[funName]; - } else if (this.fallback) { - fun = this.fallback[funName]; - } - - if (fun != null) { - const retval = fun.apply(this, args); - return retval; - } - - throw new Error(`No implementation found for ${thing}`); - }; - } - - for (const funName in spec) { - this[funName] = createFun(funName).bind(this); - } - } - - implementation(type, implementation) { - if (type === null) { - this.fallback = implementation; - } else { - this.registry.set(type, implementation); - } - } - - hasImplementation(thing) { - if (thing === Core.Integer || thing === Core.Float || thing === Core.BitString) { - return this.registry.has(thing); - } else if (thing && thing.has(Symbol.for('__struct__'))) { - return this.registry.has(thing.get(Symbol.for('__struct__')).__MODULE__); - } - - return this.registry.has(thing.constructor); - } -} - -function iterator_to_reducer(iterable, acc, fun) { - const iterator = iterable[Symbol.iterator](); - let x = iterator.next(); - let _acc = acc; - - while (x.done === false) { - _acc = fun(x.value, _acc.get(1)); - if (_acc.get(0) === Symbol.for('halt')) { - return new Core.Tuple(Symbol.for('halted'), _acc.get(1)); - } else if (_acc.get(0) === Symbol.for('suspend')) { - return new Core.Tuple(Symbol.for('suspended'), _acc.get(1), new_acc => { - return iterator_to_reducer(iterator, new_acc, fun); - }); - } - - x = iterator.next(); - } - - return new Core.Tuple(Symbol.for('done'), _acc.get(1)); -} - -function call_property(item, property) { - if (!property) { - if (item instanceof Function || typeof item === 'function') { - return item(); - } - - return item; - } - - if (item instanceof Map) { - let prop = null; - - if (item.has(property)) { - prop = property; - } else if (item.has(Symbol.for(property))) { - prop = Symbol.for(property); - } - - if (prop === null) { - throw new Error(`Property ${property} not found in ${item}`); - } - - if (item.get(prop) instanceof Function || typeof item.get(prop) === 'function') { - return item.get(prop)(); - } - return item.get(prop); - } - - let prop = null; - - if (typeof item === 'number' || typeof item === 'symbol' || typeof item === 'boolean' || typeof item === 'string') { - if (item[property] !== undefined) { - prop = property; - } else if (item[Symbol.for(property)] !== undefined) { - prop = Symbol.for(property); - } - } else if (property in item) { - prop = property; - } else if (Symbol.for(property) in item) { - prop = Symbol.for(property); - } - - if (prop === null) { - throw new Error(`Property ${property} not found in ${item}`); - } - - if (item[prop] instanceof Function || typeof item[prop] === 'function') { - return item[prop](); - } - return item[prop]; -} - -function defprotocol(spec) { - return new Protocol(spec); -} - -function defimpl(protocol, type, impl) { - protocol.implementation(type, impl); -} - -function build_namespace(ns, ns_string) { - let parts = ns_string.split('.'); - const root = ns; - let parent = ns; - - if (parts[0] === 'Elixir') { - parts = parts.slice(1); - } - - for (const part of parts) { - if (typeof parent[part] === 'undefined') { - parent[part] = {}; - } - - parent = parent[part]; - } - - root.__table__ = ns.__table__ || {}; - root.__table__[Symbol.for(ns_string)] = parent; - - return parent; -} - -function map_to_object(map) { - const object = {}; - - for (const [key, value] of map.entries()) { - if (value instanceof Map) { - object[key] = map_to_object(value); - } else { - object[key] = value; - } - } - - return object; -} - -var Functions = { - call_property, - defprotocol, - defimpl, - build_namespace, - iterator_to_reducer, - map_to_object -}; - -function _case(condition, clauses) { - return Core.Patterns.defmatch(...clauses)(condition); -} - -function cond(...clauses) { - for (const clause of clauses) { - if (clause[0]) { - return clause[1](); - } - } - - throw new Error(); -} - -function _for(expression, generators, collectable_protocol, into = []) { - let [result, fun] = collectable_protocol.into(into); - - const generatedValues = run_list_generators(generators.pop()(), generators); - - for (const value of generatedValues) { - if (expression.guard.apply(this, value)) { - result = fun(result, new Core.Tuple(Symbol.for('cont'), expression.fn.apply(this, value))); - } - } - - return fun(result, Symbol.for('done')); -} - -function run_list_generators(generator, generators) { - if (generators.length == 0) { - return generator.map(x => { - if (Array.isArray(x)) { - return x; - } - return [x]; - }); - } - const list = generators.pop(); - - const next_gen = []; - for (const j of list()) { - for (const i of generator) { - next_gen.push([j].concat(i)); - } - } - - return run_list_generators(next_gen, generators); -} - -function _try(do_fun, rescue_function, catch_fun, else_function, after_function) { - let result = null; - - try { - result = do_fun(); - } catch (e) { - let ex_result = null; - - if (rescue_function) { - try { - ex_result = rescue_function(e); - return ex_result; - } catch (ex) { - if (ex instanceof Core.Patterns.MatchError) { - throw ex; - } - } - } - - if (catch_fun) { - try { - ex_result = catch_fun(e); - return ex_result; - } catch (ex) { - if (ex instanceof Core.Patterns.MatchError) { - throw ex; - } - } - } - - throw e; - } finally { - if (after_function) { - after_function(); - } - } - - if (else_function) { - try { - return else_function(result); - } catch (ex) { - if (ex instanceof Core.Patterns.MatchError) { - throw new Error('No Match Found in Else'); - } - - throw ex; - } - } else { - return result; - } -} - -function _with(...args) { - let argsToPass = []; - let successFunction = null; - let elseFunction = null; - - if (typeof args[args.length - 2] === 'function') { - [successFunction, elseFunction] = args.splice(-2); - } else { - successFunction = args.pop(); - } - - for (let i = 0; i < args.length; i++) { - const [pattern, func] = args[i]; - - const result = func(...argsToPass); - - const patternResult = Core.Patterns.match_or_default(pattern, result); - - if (patternResult == null) { - if (elseFunction) { - return elseFunction.call(null, result); - } - return result; - } - - argsToPass = argsToPass.concat(patternResult); - } - - return successFunction(...argsToPass); -} - -function receive(clauses, after) { - console.warn('Receive not supported'); -} - -var SpecialForms = { - _case, - cond, - _for, - _try, - _with, - receive -}; - -// http://erlang.org/doc/man/erlang.html -function atom_to_binary(atom, encoding = Symbol.for('utf8')) { - if (encoding !== Symbol.for('utf8')) { - throw new Error(`unsupported encoding ${encoding}`); - } - - if (atom.__MODULE__) { - return Symbol.keyFor(atom.__MODULE__); - } - - return Symbol.keyFor(atom); -} - -function binary_to_atom(binary, encoding = Symbol.for('utf8')) { - if (encoding !== Symbol.for('utf8')) { - throw new Error(`unsupported encoding ${encoding}`); - } - - return Symbol.for(binary); -} - -function binary_to_existing_atom(binary, encoding = Symbol.for('utf8')) { - return binary_to_atom(binary, encoding); -} - -function list_concatenation(list1, list2) { - return list1.concat(list2); -} - -function list_subtraction(list1, list2) { - const list = [...list1]; - - for (const item of list2) { - const index = list.indexOf(item); - - if (index > -1) { - list.splice(index, 1); - } - } - - return list; -} - -function plus(left, right) { - if (!right) { - return +left; - } - - return left + right; -} - -function minus(left, right) { - if (!right) { - return -left; - } - - return left - right; -} - -function multiply(left, right) { - return left * right; -} - -function div(left, right) { - return left / right; -} - -function equal(left, right) { - return left == right; -} - -function doesNotEqual(left, right) { - return left != right; -} - -function greaterThan(left, right) { - return left > right; -} - -function greaterThanOrEqualTo(left, right) { - return left >= right; -} - -function lessThan(left, right) { - return left < right; -} - -function lessThanOrEqualTo(left, right) { - return left <= right; -} - -function strictlyEqual(left, right) { - return left === right; -} - -function doesNotStrictlyEqual(left, right) { - return left !== right; -} - -function and(left, right) { - return left && right; -} - -function or(left, right) { - return left || right; -} - -function not(x) { - return !x; -} - -function rem(left, right) { - return left % right; -} - -function band(left, right) { - return left & right; -} - -function bor(left, right) { - return left | right; -} - -function bnot(x) { - return ~x; -} - -function bsl(left, right) { - return left << right; -} - -function bsr(left, right) { - return left >> right; -} - -function bxor(left, right) { - return left ^ right; -} - -function is_atom(value) { - return typeof value === 'symbol' || value instanceof Symbol || value.__MODULE__; -} - -function is_bitstring$1(value) { - return value instanceof ErlangTypes.BitString; -} - -function is_boolean$1(value) { - return typeof value === 'boolean' || value instanceof Boolean; -} - -function is_number$1(value) { - return typeof value === 'number' || value instanceof Number; -} - -function is_float(value) { - return is_number$1(value) && !Number.isInteger(value); -} - -function is_function$1(value) { - return typeof value === 'function' || value instanceof Function; -} - -function is_integer(value) { - return Number.isInteger(value); -} - -function is_list(value) { - return Array.isArray(value); -} - -function is_map$1(value) { - return value instanceof Map; -} - -function is_pid(value) { - return value instanceof ErlangTypes.PID; -} - -function is_port() { - return false; -} - -function is_reference(value) { - return value instanceof ErlangTypes.Reference; -} - -function is_tuple(value) { - return value instanceof ErlangTypes.Tuple; -} - -function is_binary(value) { - return typeof value === 'string' || value instanceof String; -} - -function element(n, tuple) { - return tuple.get(n - 1); -} - -function setelement(index, tuple1, value) { - const tupleData = [...tuple1.values]; - - tupleData[index - 1] = value; - - return new ErlangTypes.Tuple(...tupleData); -} - -function make_tuple(arity, initialValue) { - const list = []; - - for (let i = 0; i < arity; i++) { - list.push(initialValue); - } - - return new ErlangTypes.Tuple(...list); -} - -function insert_element(index, tuple, term) { - const list = [...tuple.values]; - list.splice(index - 1, 0, term); - - return new ErlangTypes.Tuple(...list); -} - -function append_element(tuple, term) { - const list = [...tuple.values]; - list.push(term); - - return new ErlangTypes.Tuple(...list); -} - -function delete_element(index, tuple) { - const list = [...tuple.values]; - list.splice(index - 1, 1); - - return new ErlangTypes.Tuple(...list); -} - -function tuple_to_list(tuple) { - const list = [...tuple.values]; - return list; -} - -function abs(number) { - return Math.abs(number); -} - -function apply(...args) { - if (args.length === 2) { - return args[0].apply(this, ...args[1]); - } - - return args[0][atom_to_binary(args[1])].apply(this, ...args[2]); -} - -function binary_part(binary, start, length) { - return binary.substring(start, start + length); -} - -function bit_size(bitstring) { - return bitstring.bit_size; -} - -function byte_size(bitstring) { - return bitstring.byte_size; -} - -function hd(list) { - return list[0]; -} - -function length(list) { - return list.length; -} - -function make_ref() { - return new ErlangTypes.Reference(); -} - -function map_size(map) { - return map.size; -} - -function max(first, second) { - return Math.max(first, second); -} - -function min(first, second) { - return Math.min(first, second); -} - -function round(number) { - return Math.round(number); -} - -function tl(list) { - return list.slice(1); -} - -function trunc(number) { - return Math.trunc(number); -} - -function tuple_size(tuple) { - return tuple.length; -} - -function binary_to_float(str) { - return parseFloat(str); -} - -function binary_to_integer(str, base = 10) { - return parseInt(str, base); -} - -function process_info(pid, item) { - if (item) { - if (item === Symbol.for('current_stacktrace')) { - return new ErlangTypes.Tuple(item, []); - } - - return new ErlangTypes.Tuple(item, null); - } - - return []; -} - -var erlang = { - atom_to_binary, - binary_to_atom, - binary_to_existing_atom, - list_concatenation, - list_subtraction, - plus, - minus, - multiply, - div, - equal, - greaterThan, - greaterThanOrEqualTo, - lessThan, - lessThanOrEqualTo, - doesNotEqual, - strictlyEqual, - doesNotStrictlyEqual, - and, - or, - not, - rem, - band, - bor, - bsl, - bsr, - bxor, - bnot, - is_bitstring: is_bitstring$1, - is_boolean: is_boolean$1, - is_float, - is_function: is_function$1, - is_integer, - is_list, - is_map: is_map$1, - is_number: is_number$1, - is_pid, - is_port, - is_reference, - is_tuple, - is_atom, - is_binary, - element, - setelement, - make_tuple, - insert_element, - append_element, - delete_element, - tuple_to_list, - abs, - apply, - binary_part, - bit_size, - byte_size, - hd, - length, - make_ref, - map_size, - max, - min, - round, - tl, - trunc, - tuple_size, - binary_to_float, - binary_to_integer, - process_info -}; - -// http://erlang.org/doc/man/maps.html -const OK = Symbol.for('ok'); -const ERROR = Symbol.for('error'); -const BADMAP = Symbol.for('badmap'); -const BADKEY = Symbol.for('badkey'); - -function find(key, map) { - if (erlang.is_map(map) === false) { - return new ErlangTypes.Tuple(BADMAP, map); - } - - const value = map.get(key); - - if (typeof value !== 'undefined') { - return new ErlangTypes.Tuple(OK, value); - } - - return ERROR; -} - -function fold(fun, init, map) { - let acc = init; - - for (const [key, value] of map.entries()) { - acc = fun(key, value, acc); - } - - return acc; -} - -function remove(key, map1) { - if (erlang.is_map(map1) === false) { - return new ErlangTypes.Tuple(BADMAP, map1); - } - - const map2 = new Map(map1); - - map2.delete(key); - - return map2; -} - -function to_list(map) { - if (erlang.is_map(map) === false) { - return new ErlangTypes.Tuple(BADMAP, map); - } - - const list = []; - - for (const [key, value] of map.entries()) { - list.push(new ErlangTypes.Tuple(key, value)); - } - - return list; -} - -function from_list(list) { - return list.reduce((acc, item) => { - const [key, value] = item; - acc.set(key, value); - - return acc; - }, new Map()); -} - -function keys(map) { - if (erlang.is_map(map) === false) { - return new ErlangTypes.Tuple(BADMAP, map); - } - - return Array.from(map.keys()); -} - -function values$1(map) { - if (erlang.is_map(map) === false) { - return new ErlangTypes.Tuple(BADMAP, map); - } - - return Array.from(map.values()); -} - -function is_key(key, map) { - return map.has(key); -} - -function put(key, value, map1) { - if (erlang.is_map(map1) === false) { - return new ErlangTypes.Tuple(BADMAP, map1); - } - - const map2 = new Map(map1); - map2.set(key, value); - - return map2; -} - -function merge(map1, map2) { - if (erlang.is_map(map1) === false) { - return new ErlangTypes.Tuple(BADMAP, map1); - } - - if (erlang.is_map(map2) === false) { - return new ErlangTypes.Tuple(BADMAP, map2); - } - - return new Map([...map1, ...map2]); -} - -function update(key, value, map1) { - if (erlang.is_map(map1) === false) { - return new ErlangTypes.Tuple(BADMAP, map1); - } - - if (is_key(key, map1) === false) { - return new ErlangTypes.Tuple(BADKEY, key); - } - - return new Map([...map1, [key, value]]); -} - -function get(...args) { - const key = args[0]; - const map = args[1]; - - if (erlang.is_map(map) === false) { - return new ErlangTypes.Tuple(BADMAP, map); - } - - if (is_key(key)) { - return map.get(key); - } - - if (args.length === 3) { - return args[2]; - } - - return new ErlangTypes.Tuple(BADKEY, key); -} - -function take(key, map1) { - if (erlang.is_map(map1) === false) { - return new ErlangTypes.Tuple(BADMAP, map1); - } - - if (!is_key(key)) { - return ERROR; - } - - const value = map1.get(key); - const map2 = new Map(map1); - map2.delete(key); - - return new ErlangTypes.Tuple(value, map2); -} - -var maps = { - find, - fold, - remove, - to_list, - from_list, - keys, - values: values$1, - is_key, - put, - merge, - update, - get, - take -}; - -// http://erlang.org/doc/man/lists.html -function reverse(list) { - return [...list].reverse(); -} - -function foreach(fun, list) { - list.forEach(x => fun(x)); - - return Symbol.for('ok'); -} - -function duplicate(n, elem) { - const list = []; - - while (list.length < n) { - list.push(elem); - } - - return list; -} - -function flatten(deepList, tail = []) { - const val = deepList.reduce((acc, value) => { - if (Array.isArray(value)) { - return acc.concat(flatten(value)); - } - - return acc.concat(value); - }, []); - - return val.concat(tail); -} - -function foldl(fun, acc0, list) { - return list.reduce((acc, value) => { - return fun(value, acc); - }, acc0); -} - -function foldr(fun, acc0, list) { - return foldl(fun, acc0, reverse(list)); -} - -function keyfind(key, n, tupleList) { - for (const tuple of tupleList) { - if (tuple.get(n - 1) === key) { - return tuple; - } - } - - return false; -} - -function keymember(key, n, tupleList) { - if (keyfind(key, n, tupleList) === false) { - return false; - } - - return true; -} - -function keyreplace(key, n, tupleList, newTuple) { - const newTupleList = [...tupleList]; - - for (let index = 0; index < newTupleList.length; index++) { - if (newTupleList[index].get(n - 1) === key) { - newTupleList[index] = newTuple; - return newTupleList; - } - } - - return newTupleList; -} - -function keysort(n, tupleList) { - const newTupleList = [...tupleList]; - - return newTupleList.sort((a, b) => { - if (a.get(n - 1) < b.get(n - 1)) { - return -1; - } else if (a.get(n - 1) > b.get(n - 1)) { - return 1; - } - - return 0; - }); -} - -function keystore(key, n, tupleList, newTuple) { - const newTupleList = [...tupleList]; - - for (let index = 0; index < newTupleList.length; index++) { - if (newTupleList[index].get(n - 1) === key) { - newTupleList[index] = newTuple; - return newTupleList; - } - } - - return newTupleList.concat(newTuple); -} - -function keydelete(key, n, tupleList) { - const newTupleList = []; - let deleted = false; - - for (let index = 0; index < tupleList.length; index++) { - if (deleted === false && tupleList[index].get(n - 1) === key) { - deleted = true; - } else { - newTupleList.push(tupleList[index]); - } - } - - return newTupleList; -} - -function keytake(key, n, tupleList) { - const result = keyfind(key, n, tupleList); - - if (result !== false) { - return new ErlangTypes.Tuple(result.get(n - 1), result, keydelete(key, n, tupleList)); - } - - return false; -} - -function mapfoldl(fun, acc0, list1) { - const listResult = []; - let accResult = acc0; - - for (const item of list1) { - const tuple = fun(item, accResult); - listResult.push(tuple.get(0)); - accResult = tuple.get(1); - } - - return new ErlangTypes.Tuple(listResult, accResult); -} - -function concat(things) { - return things.map(v => v.toString()).join(); -} - -function map(fun, list) { - return list.map(value => fun(value)); -} - -function filter(pred, list1) { - return list1.filter(x => pred(x)); -} - -function filtermap(fun, list1) { - const list2 = []; - - for (const item of list1) { - const value = fun(item); - - if (value === true) { - list2.push(item); - } else if (value instanceof ErlangTypes.Tuple && value.get(0) === true) { - list2.push(value.get(1)); - } - } - - return list2; -} - -function member(elem, list) { - for (const item of list) { - if (item === elem) { - return true; - } - } - - return false; -} - -function all(pred, list) { - for (const item of list) { - if (pred(item) === false) { - return false; - } - } - - return true; -} - -function any(pred, list) { - for (const item of list) { - if (pred(item) === true) { - return true; - } - } - - return false; -} - -function splitwith(pred, list) { - let switchToList2 = false; - const list1 = []; - const list2 = []; - - for (const item of list) { - if (switchToList2 === true) { - list2.push(item); - } else if (pred(item) === true) { - list1.push(item); - } else { - switchToList2 = true; - list2.push(item); - } - } - - return new ErlangTypes.Tuple(list1, list2); -} - -function sort(...args) { - if (args.length === 1) { - const list2 = [...args[0]]; - return list2.sort(); - } - - const fun = args[0]; - const list2 = [...args[1]]; - - return list2.sort((a, b) => { - const result = fun(a, b); - - if (result === true) { - return -1; - } - - return 1; - }); -} - -var lists = { - reverse, - foreach, - duplicate, - flatten, - foldl, - foldr, - keydelete, - keyfind, - keymember, - keyreplace, - keysort, - keystore, - keytake, - mapfoldl, - concat, - map, - filter, - filtermap, - member, - all, - any, - splitwith, - sort -}; - -function warn(message) { - const messageString = message.join(''); - console.warn(`warning ${messageString}`); - - return Symbol.for('ok'); -} - -var elixir_errors = { - warn -}; - -function get_key(key) { - let real_key = key; - - if (__elixirscript_names__.has(key)) { - real_key = __elixirscript_names__.get(key); - } - - if (__elixirscript_store__.has(real_key)) { - return real_key; - } - - throw new Error(`Key ${real_key} not found`); -} - -function create(value, name = null) { - const key = new Core.PID(); - - if (name !== null) { - __elixirscript_names__.set(name, key); - } - - return __elixirscript_store__.set(key, value); -} - -function update$1(key, value) { - const real_key = get_key(key); - return __elixirscript_store__.set(real_key, value); -} - -function read(key) { - const real_key = get_key(key); - return __elixirscript_store__.get(real_key); -} - -function remove$1(key) { - const real_key = get_key(key); - return __elixirscript_store__.delete(real_key); -} - -var Store = { - create, - update: update$1, - read, - remove: remove$1 -}; - -class Integer {} -class Float {} - -function get_global() { - if (typeof self !== 'undefined') { - return self; - } else if (typeof window !== 'undefined') { - return window; - } else if (typeof global !== 'undefined') { - return global; - } - - console.warn('No global state found'); - return null; -} - -const globalState = get_global(); - -globalState.__elixirscript_store__ = new Map(); -globalState.__elixirscript_names__ = new Map(); - -var Core = { - Tuple: ErlangTypes.Tuple, - PID: ErlangTypes.PID, - BitString: ErlangTypes.BitString, - Patterns, - Integer, - Float, - Functions, - SpecialForms, - Store, - global: globalState, - erlang, - maps, - lists, - elixir_errors -}; - -var elixir = { - Core -}; - -return elixir; - -}()); +var ElixirScript=function(){'use strict';/* @flow */function namedVariableResult(a,b){return new NamedVariableResult(a,b)}/* @flow */function is_number(a){return'number'==typeof a}function is_string(a){return'string'==typeof a}function is_boolean(a){return'boolean'==typeof a}function is_symbol(a){return'symbol'==typeof a}function is_object(a){return'object'==typeof a}function is_variable(a){return a instanceof Variable}function is_null(a){return null===a}function is_array(a){return Array.isArray(a)}function is_function(a){return'[object Function]'==Object.prototype.toString.call(a)}function is_map(a){return a instanceof Map}function resolveNull(){return function(a){return is_null(a)}}function resolveWildcard(){return function(){return!0}}function resolveObject(a){let b={};const c=Object.keys(a).concat(Object.getOwnPropertySymbols(a));for(let d of c)b[d]=buildMatch(a[d]);return function(d,e){if(!is_object(d)||a.length>d.length)return!1;for(let a of c)if(!(a in d)||!b[a](d[a],e))return!1;return!0}}function getSize(a,b){return a*b/8}function arraysEqual(c,a){if(c===a)return!0;if(null==c||null==a)return!1;if(c.length!=a.length)return!1;for(var b=0;be.integer(a));return new e(...b)}function resolveNoMatch(){return function(){return!1}}function buildMatch(a){if(null===a)return resolveNull(a);if('undefined'==typeof a)return resolveWildcard(a);const b=a.constructor.prototype,c=f.get(b);return c?c(a):'object'==typeof a?resolveObject(a):resolveNoMatch()}function defmatchgen(...a){const b=getArityMap(a);return function*(...a){let[c,d]=findMatchingFunction(a,b);return yield*c.apply(this,d)}}function findMatchingFunction(a,b){if(b.has(a.length)){const c=b.get(a.length);let d=null,e=null;for(let b of c){let c=[];a=fillInOptionalValues(a,b.arity,b.optionals);const f=b.pattern(a,c),[g,h]=checkNamedVariables(c);if(f&&h&&b.guard.apply(this,g)){d=b.fn,e=g;break}}if(!d)throw console.error('No match for:',a),new MatchError(a);return[d,e]}throw console.error('Arity of',a.length,'not found. No match for:',a),new MatchError(a)}function getArityMap(a){let b=new Map;for(const c of a){const a=getArityRange(c);for(const d of a){let a=[];b.has(d)&&(a=b.get(d)),a.push(c),b.set(d,a)}}return b}function getArityRange(a){const b=a.arity-a.optionals.length,c=a.arity;let d=[b];for(;d[d.length-1]!=c;)d.push(d[d.length-1]+1);return d}function getOptionalValues(a){let b=[];for(let c=0;c!0,d=null){let e=[],f=buildMatch(a);const g=f(b,e),[h,i]=checkNamedVariables(e);return g&&i&&c.apply(this,h)?h:d}function run_generators(a,b){if(0==b.length)return a.map((a)=>{return Array.isArray(a)?a:[a]});const c=b.pop();let d=[];for(let e of c())for(let b of a)d.push([e].concat(b));return run_generators(d,b)}function iterator_to_reducer(a,b,c){const d=a[Symbol.iterator]();let e=d.next(),f=b;for(;!1===e.done;){if(f=c(e.value,f.get(1)),f.get(0)===Symbol.for('halt'))return new n.Tuple(Symbol.for('halted'),f.get(1));if(f.get(0)===Symbol.for('suspend'))return new n.Tuple(Symbol.for('suspended'),f.get(1),(a)=>{return iterator_to_reducer(d,a,c)});e=d.next()}return new n.Tuple(Symbol.for('done'),f.get(1))}function map_to_object(a){const b={};for(const[c,d]of a.entries())b[c]=d instanceof Map?map_to_object(d):d;return b}function run_list_generators(a,b){if(0==b.length)return a.map((a)=>{return Array.isArray(a)?a:[a]});const c=b.pop(),d=[];for(const e of c())for(const b of a)d.push([e].concat(b));return run_list_generators(d,b)}// http://erlang.org/doc/man/erlang.html +function atom_to_binary(a,b=Symbol.for('utf8')){if(b!==Symbol.for('utf8'))throw new Error(`unsupported encoding ${b}`);return a.__MODULE__?Symbol.keyFor(a.__MODULE__):Symbol.keyFor(a)}function binary_to_atom(a,b=Symbol.for('utf8')){if(b!==Symbol.for('utf8'))throw new Error(`unsupported encoding ${b}`);return Symbol.for(a)}function is_number$1(a){return'number'==typeof a||a instanceof Number}function is_key(a,b){return b.has(a)}// http://erlang.org/doc/man/lists.html +function reverse(a){return[...a]}function flatten(a,b=[]){const c=a.reduce((a,b)=>{return Array.isArray(b)?a.concat(flatten(b)):a.concat(b)},[]);return c.concat(b)}function foldl(a,b,c){return c.reduce((b,c)=>{return a(c,b)},b)}function keyfind(a,b,c){for(const d of c)if(d.get(b-1)===a)return d;return!1}function keydelete(a,b,c){const d=[];let e=!1;for(let f=0;fBitString$1.integer(a));return new BitString$1(...d)}[Symbol.iterator](){return this.value[Symbol.iterator]()}toString(){var a,b='';for(a=0;a>'}process(a){let b=[];var c;for(c=0;cb?c.push(b):2048>b?c.push(192|b>>6,128|63&b):55296>b||57344<=b?c.push(224|b>>12,128|63&b>>6,128|63&b):(d++,b=65536+((1023&b)<<10|1023&a.charCodeAt(d)),c.push(240|b>>18,128|63&b>>12,128|63&b>>6,128|63&b));return c}static toUTF16Array(a){for(var b,c=[],d=0;d=b?(c.push(0),c.push(b)):(c.push(255&b>>8),c.push(255&b));return c}static toUTF32Array(a){for(var b,c=[],d=0;d=b?(c.push(0),c.push(0),c.push(0),c.push(b)):(c.push(0),c.push(0),c.push(255&b>>8),c.push(255&b));return c}//http://stackoverflow.com/questions/2003493/javascript-float-from-to-bits +static float32ToBytes(a){var b=[],c=new ArrayBuffer(4);new Float32Array(c)[0]=a;let d=new Uint32Array(c)[0];return b.push(255&d>>24),b.push(255&d>>16),b.push(255&d>>8),b.push(255&d),b}static float64ToBytes(a){var b=[],c=new ArrayBuffer(8);new Float64Array(c)[0]=a;var d=new Uint32Array(c)[0],e=new Uint32Array(c)[1];return b.push(255&e>>24),b.push(255&e>>16),b.push(255&e>>8),b.push(255&e),b.push(255&d>>24),b.push(255&d>>16),b.push(255&d>>8),b.push(255&d),b}}var d={Tuple,PID:class PID{constructor(){++b,this.id=b}toString(){return'PID#<0.'+this.id+'.0>'}},Reference:class Reference{constructor(){++c,this.id=c,this.ref=Symbol()}toString(){return'Ref#<0.0.0.'+this.id+'>'}},BitString:BitString$1};/* @flow */const e=d.BitString,f=new Map;f.set(Variable.prototype,function resolveVariable(a){return function(b,c){return null===a.name||a.name.startsWith('_')?c.push(b):c.push(namedVariableResult(a.name,b)),!0}}),f.set(Wildcard.prototype,resolveWildcard),f.set(HeadTail.prototype,function resolveHeadTail(){return function(a,b){if(!is_array(a)||2>a.length)return!1;const c=a[0],d=a.slice(1);return b.push(c),b.push(d),!0}}),f.set(StartsWith.prototype,function resolveStartsWith(a){const b=a.prefix;return function(a,c){return is_string(a)&&a.startsWith(b)&&(c.push(a.substring(b.length)),!0)}}),f.set(Capture.prototype,function resolveCapture(a){const b=buildMatch(a.value);return function(a,c){return!!b(a,c)&&(c.push(a),!0)}}),f.set(Bound.prototype,function resolveBound(a){return function(b){return typeof b==typeof a.value&&b===a.value}}),f.set(Type.prototype,function resolveType(a){return function(b,c){if(b instanceof a.type){const d=buildMatch(a.objPattern);return d(b,c)}return!1}}),f.set(BitStringMatch.prototype,function resolveBitString(a){let b=[];for(let c of a.values)if(is_variable(c.value)){let a=getSize(c.unit,c.size);fillArray(b,a)}else b=b.concat(new e(c).value);let c=a.values;return function(a,d){var f=String.fromCharCode;let g=null;if(!is_string(a)&&!(a instanceof e))return!1;g=is_string(a)?new e(e.binary(a)):a;let h=0;for(let e,j=0;jd.size)return!1;for(let a of c)if(!d.has(a)||!b.get(a)(d.get(a),e))return!1;return!0}}),f.set(Array.prototype,function resolveArray(a){const b=a.map((a)=>buildMatch(a));return function(c,d){return is_array(c)&&c.length==a.length&&c.every(function(a,e){return b[e](c[e],d)})}}),f.set(String.prototype,function resolveString(a){return function(b){return is_string(b)&&b===a}}),f.set(Boolean.prototype,function resolveBoolean(a){return function(b){return is_boolean(b)&&b===a}}),f.set(Function.prototype,function resolveFunction(a){return function(b){return is_function(b)&&b===a}}),f.set(Object.prototype,resolveObject);class MatchError extends Error{constructor(a){if(super(),'symbol'==typeof a)this.message='No match for: '+a.toString();else if(Array.isArray(a)){let b=a.map((a)=>{return null===a?'null':'undefined'==typeof a?'undefined':a.toString()});this.message='No match for: '+b}else this.message='No match for: '+a;this.stack=new Error().stack,this.name=this.constructor.name}}class Clause{constructor(a,b,c=()=>!0){this.pattern=buildMatch(a),this.arity=a.length,this.optionals=getOptionalValues(a),this.fn=b,this.guard=c}}const g=Symbol();// https://github.com/airportyh/protomorphism +class Protocol{constructor(b){function createFun(b){return function(...c){const d=c[0];let e=null;if(null===d&&this.hasImplementation(Symbol('null'))?e=this.registry.get(Symbol)[b]:a(d)&&this.hasImplementation(n.Integer)?e=this.registry.get(n.Integer)[b]:'number'==typeof d&&!a(d)&&this.hasImplementation(n.Float)?e=this.registry.get(n.Float)[b]:'string'==typeof d&&this.hasImplementation(n.BitString)?e=this.registry.get(n.BitString)[b]:d&&d.has(Symbol.for('__struct__'))&&this.hasImplementation(d)?e=this.registry.get(d.get(Symbol.for('__struct__')).__MODULE__)[b]:null!==d&&this.hasImplementation(d)?e=this.registry.get(d.constructor)[b]:this.fallback&&(e=this.fallback[b]),null!=e){const a=e.apply(this,c);return a}throw new Error(`No implementation found for ${d}`)}}for(const a in this.registry=new Map,this.fallback=null,b)this[a]=createFun(a).bind(this)}implementation(a,b){null===a?this.fallback=b:this.registry.set(a,b)}hasImplementation(a){if(a===n.Integer||a===n.Float||a===n.BitString)return this.registry.has(a);return a&&a.has(Symbol.for('__struct__'))?this.registry.has(a.get(Symbol.for('__struct__')).__MODULE__):this.registry.has(a.constructor)}}var h={atom_to_binary,binary_to_atom,binary_to_existing_atom:function binary_to_existing_atom(a,b=Symbol.for('utf8')){return binary_to_atom(a,b)},list_concatenation:function list_concatenation(a,b){return a.concat(b)},list_subtraction:function list_subtraction(a,b){const c=[...a];for(const d of b){const a=c.indexOf(d);-1b},greaterThanOrEqualTo:function greaterThanOrEqualTo(a,b){return a>=b},lessThan:function lessThan(a,b){return a>b},bxor:function bxor(a,b){return a^b},bnot:function bnot(a){return~a},is_bitstring:function is_bitstring$1(a){return a instanceof d.BitString},is_boolean:function is_boolean$1(a){return'boolean'==typeof a||a instanceof Boolean},is_float:function is_float(b){return is_number$1(b)&&!a(b)},is_function:function is_function$1(a){return'function'==typeof a||a instanceof Function},is_integer:function is_integer(b){return a(b)},is_list:function is_list(a){return Array.isArray(a)},is_map:function is_map$1(a){return a instanceof Map},is_number:is_number$1,is_pid:function is_pid(a){return a instanceof d.PID},is_port:function is_port(){return!1},is_reference:function is_reference(a){return a instanceof d.Reference},is_tuple:function is_tuple(a){return a instanceof d.Tuple},is_atom:function is_atom(a){return'symbol'==typeof a||a instanceof Symbol||a.__MODULE__},is_binary:function is_binary(a){return'string'==typeof a||a instanceof String},element:function element(a,b){return b.get(a-1)},setelement:function setelement(a,b,c){const e=[...b.values];return e[a-1]=c,new d.Tuple(...e)},make_tuple:function make_tuple(a,b){const c=[];for(let d=0;d!0){let d=[],e=buildMatch(a);const f=e(b,d),[g,h]=checkNamedVariables(d);if(f&&h&&c.apply(this,g))return g;throw console.error('No match for:',b),new MatchError(b)},MatchError,variable:function variable(a=null,b=Symbol.for('tailored.no_value')){return new Variable(a,b)},wildcard:function wildcard(){return new Wildcard},startsWith:function startsWith(a){return new StartsWith(a)},capture:function capture(a){return new Capture(a)},headTail:function headTail(){return new HeadTail},type:function a(a,b={}){return new Type(a,b)},bound:function bound(a){return new Bound(a)},Clause,clause:function clause(a,b,c=()=>!0){return new Clause(a,b,c)},bitStringMatch:function bitStringMatch(...a){return new BitStringMatch(...a)},match_or_default,defmatchgen,list_comprehension:function list_comprehension(a,b){const c=run_generators(b.pop()(),b);let d=[];for(let e of c)a.guard.apply(this,e)&&d.push(a.fn.apply(this,e));return d},list_generator:function list_generator(a,b){return function(){let c=[];for(let d of b){const b=match_or_default(a,d,()=>!0,g);if(b!=g){const[a]=b;c.push(a)}}return c}},bitstring_generator:function bitstring_generator(a,b){return function(){let c=[],d=b.slice(0,a.byte_size()),e=1;for(;d.byte_size==a.byte_size();){const f=match_or_default(a,d,()=>!0,g);if(f!=g){c.push(f)}d=b.slice(a.byte_size()*e,a.byte_size()*(e+1)),e++}return c}},bitstring_comprehension:function bitstring_comprehension(a,b){const c=run_generators(b.pop()(),b);let e=[];for(let d of c)a.guard.apply(this,d)&&e.push(a.fn.apply(this,d));return e=e.map((a)=>d.BitString.integer(a)),new d.BitString(...e)},defmatchGen:function defmatchGen(...a){return defmatchgen(...a)},defmatchAsync:function defmatchAsync(...a){const b=getArityMap(a);return async function(...a){if(b.has(a.length)){const c=b.get(a.length);let d=null,e=null;for(let b of c){let c=[];a=fillInOptionalValues(a,b.arity,b.optionals);const f=b.pattern(a,c),[g,h]=checkNamedVariables(c);if(f&&h&&(await b.guard.apply(this,c))){d=b.fn,e=c;break}}if(!d)throw console.error('No match for:',a),new MatchError(a);return d.apply(this,e)}throw console.error('Arity of',a.length,'not found. No match for:',a),new MatchError(a)}}},Integer:class Integer{},Float:class Float{},Functions:{call_property:function call_property(a,b){if(!b)return a instanceof Function||'function'==typeof a?a():a;if(a instanceof Map){let c=null;if(a.has(b)?c=b:a.has(Symbol.for(b))&&(c=Symbol.for(b)),null===c)throw new Error(`Property ${b} not found in ${a}`);return a.get(c)instanceof Function||'function'==typeof a.get(c)?a.get(c)():a.get(c)}let c=null;if('number'==typeof a||'symbol'==typeof a||'boolean'==typeof a||'string'==typeof a?void 0===a[b]?void 0!==a[Symbol.for(b)]&&(c=Symbol.for(b)):c=b:b in a?c=b:Symbol.for(b)in a&&(c=Symbol.for(b)),null===c)throw new Error(`Property ${b} not found in ${a}`);return a[c]instanceof Function||'function'==typeof a[c]?a[c]():a[c]},defprotocol:function defprotocol(a){return new Protocol(a)},defimpl:function defimpl(a,b,c){a.implementation(b,c)},build_namespace:function build_namespace(a,b){let c=b.split('.');const d=a;let e=a;'Elixir'===c[0]&&(c=c.slice(1));for(const d of c)'undefined'==typeof e[d]&&(e[d]={}),e=e[d];return d.__table__=a.__table__||{},d.__table__[Symbol.for(b)]=e,e},iterator_to_reducer,map_to_object},SpecialForms:{_case:function _case(a,b){return n.Patterns.defmatch(...b)(a)},cond:function cond(...a){for(const b of a)if(b[0])return b[1]();throw new Error},_for:function _for(a,b,c,d=[]){let[e,f]=c.into(d);const g=run_list_generators(b.pop()(),b);for(const h of g)a.guard.apply(this,h)&&(e=f(e,new n.Tuple(Symbol.for('cont'),a.fn.apply(this,h))));return f(e,Symbol.for('done'))},_try:function _try(a,b,c,d,e){let f=null;try{f=a()}catch(a){let d=null;if(b)try{return d=b(a),d}catch(a){if(a instanceof n.Patterns.MatchError)throw a}if(c)try{return d=c(a),d}catch(a){if(a instanceof n.Patterns.MatchError)throw a}throw a}finally{e&&e()}if(d)try{return d(f)}catch(a){if(a instanceof n.Patterns.MatchError)throw new Error('No Match Found in Else');throw a}else return f},_with:function _with(...a){let b=[],c=null,d=null;'function'==typeof a[a.length-2]?[c,d]=a.splice(-2):c=a.pop();for(let c=0;c{const[c,d]=b;return a.set(c,d),a},new Map)},keys:function keys(a){return!1===h.is_map(a)?new d.Tuple(k,a):Array.from(a.keys())},values:function values$1(a){return!1===h.is_map(a)?new d.Tuple(k,a):Array.from(a.values())},is_key,put:function put(a,b,c){if(!1===h.is_map(c))return new d.Tuple(k,c);const e=new Map(c);return e.set(a,b),e},merge:function merge(a,b){return!1===h.is_map(a)?new d.Tuple(k,a):!1===h.is_map(b)?new d.Tuple(k,b):new Map([...a,...b])},update:function update(a,b,c){return!1===h.is_map(c)?new d.Tuple(k,c):!1===is_key(a,c)?new d.Tuple(l,a):new Map([...c,[a,b]])},get:function get(...a){const b=a[0],c=a[1];return!1===h.is_map(c)?new d.Tuple(k,c):is_key(b)?c.get(b):3===a.length?a[2]:new d.Tuple(l,b)},take:function take(a,b){if(!1===h.is_map(b))return new d.Tuple(k,b);if(!is_key(a))return j;const c=b.get(a),e=new Map(b);return e.delete(a),new d.Tuple(c,e)}},lists:{reverse,foreach:function foreach(a,b){return b.forEach((b)=>a(b)),Symbol.for('ok')},duplicate:function duplicate(a,b){const c=[];for(;c.length{if(d.get(c-1)a.get(c-1)?1:0})},keystore:function keystore(a,b,c,d){const e=[...c];for(let f=0;fa.toString()).join()},map:function map(a,b){return b.map((b)=>a(b))},filter:function filter(a,b){return b.filter((b)=>a(b))},filtermap:function filtermap(a,b){const c=[];for(const e of b){const b=a(e);!0===b?c.push(e):b instanceof d.Tuple&&!0===b.get(0)&&c.push(b.get(1))}return c},member:function member(a,b){for(const c of b)if(c===a)return!0;return!1},all:function all(a,b){for(const c of b)if(!1===a(c))return!1;return!0},any:function any(a,b){for(const c of b)if(!0===a(c))return!0;return!1},splitwith:function splitwith(a,b){let c=!1;const e=[],f=[];for(const d of b)!0==c?f.push(d):!0===a(d)?e.push(d):(c=!0,f.push(d));return new d.Tuple(e,f)},sort:function sort(...a){if(1===a.length){const b=[...a[0]];return b.sort()}const c=a[0],b=[...a[1]];return b.sort((d,a)=>{const b=c(d,a);return!0===b?-1:1})}},elixir_errors:{warn:function warn(a){const b=a.join('');return console.warn(`warning: ${b}`),Symbol.for('ok')}}};return{Core:n}}(); From 31721a84cd9976260542b7a6dc2f76fd8db144ca Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Fri, 21 Jul 2017 07:38:24 -0500 Subject: [PATCH 188/418] Add erlang functions, iolist_to_binary and io_size --- priv/build/iife/ElixirScript.Core.js | 4 +-- .../lib/core/erlang_compat/erlang.js | 30 ++++++++++++++++++- 2 files changed, 31 insertions(+), 3 deletions(-) diff --git a/priv/build/iife/ElixirScript.Core.js b/priv/build/iife/ElixirScript.Core.js index f97d3ed7..82295b52 100644 --- a/priv/build/iife/ElixirScript.Core.js +++ b/priv/build/iife/ElixirScript.Core.js @@ -1,6 +1,6 @@ var ElixirScript=function(){'use strict';/* @flow */function namedVariableResult(a,b){return new NamedVariableResult(a,b)}/* @flow */function is_number(a){return'number'==typeof a}function is_string(a){return'string'==typeof a}function is_boolean(a){return'boolean'==typeof a}function is_symbol(a){return'symbol'==typeof a}function is_object(a){return'object'==typeof a}function is_variable(a){return a instanceof Variable}function is_null(a){return null===a}function is_array(a){return Array.isArray(a)}function is_function(a){return'[object Function]'==Object.prototype.toString.call(a)}function is_map(a){return a instanceof Map}function resolveNull(){return function(a){return is_null(a)}}function resolveWildcard(){return function(){return!0}}function resolveObject(a){let b={};const c=Object.keys(a).concat(Object.getOwnPropertySymbols(a));for(let d of c)b[d]=buildMatch(a[d]);return function(d,e){if(!is_object(d)||a.length>d.length)return!1;for(let a of c)if(!(a in d)||!b[a](d[a],e))return!1;return!0}}function getSize(a,b){return a*b/8}function arraysEqual(c,a){if(c===a)return!0;if(null==c||null==a)return!1;if(c.length!=a.length)return!1;for(var b=0;be.integer(a));return new e(...b)}function resolveNoMatch(){return function(){return!1}}function buildMatch(a){if(null===a)return resolveNull(a);if('undefined'==typeof a)return resolveWildcard(a);const b=a.constructor.prototype,c=f.get(b);return c?c(a):'object'==typeof a?resolveObject(a):resolveNoMatch()}function defmatchgen(...a){const b=getArityMap(a);return function*(...a){let[c,d]=findMatchingFunction(a,b);return yield*c.apply(this,d)}}function findMatchingFunction(a,b){if(b.has(a.length)){const c=b.get(a.length);let d=null,e=null;for(let b of c){let c=[];a=fillInOptionalValues(a,b.arity,b.optionals);const f=b.pattern(a,c),[g,h]=checkNamedVariables(c);if(f&&h&&b.guard.apply(this,g)){d=b.fn,e=g;break}}if(!d)throw console.error('No match for:',a),new MatchError(a);return[d,e]}throw console.error('Arity of',a.length,'not found. No match for:',a),new MatchError(a)}function getArityMap(a){let b=new Map;for(const c of a){const a=getArityRange(c);for(const d of a){let a=[];b.has(d)&&(a=b.get(d)),a.push(c),b.set(d,a)}}return b}function getArityRange(a){const b=a.arity-a.optionals.length,c=a.arity;let d=[b];for(;d[d.length-1]!=c;)d.push(d[d.length-1]+1);return d}function getOptionalValues(a){let b=[];for(let c=0;c!0,d=null){let e=[],f=buildMatch(a);const g=f(b,e),[h,i]=checkNamedVariables(e);return g&&i&&c.apply(this,h)?h:d}function run_generators(a,b){if(0==b.length)return a.map((a)=>{return Array.isArray(a)?a:[a]});const c=b.pop();let d=[];for(let e of c())for(let b of a)d.push([e].concat(b));return run_generators(d,b)}function iterator_to_reducer(a,b,c){const d=a[Symbol.iterator]();let e=d.next(),f=b;for(;!1===e.done;){if(f=c(e.value,f.get(1)),f.get(0)===Symbol.for('halt'))return new n.Tuple(Symbol.for('halted'),f.get(1));if(f.get(0)===Symbol.for('suspend'))return new n.Tuple(Symbol.for('suspended'),f.get(1),(a)=>{return iterator_to_reducer(d,a,c)});e=d.next()}return new n.Tuple(Symbol.for('done'),f.get(1))}function map_to_object(a){const b={};for(const[c,d]of a.entries())b[c]=d instanceof Map?map_to_object(d):d;return b}function run_list_generators(a,b){if(0==b.length)return a.map((a)=>{return Array.isArray(a)?a:[a]});const c=b.pop(),d=[];for(const e of c())for(const b of a)d.push([e].concat(b));return run_list_generators(d,b)}// http://erlang.org/doc/man/erlang.html -function atom_to_binary(a,b=Symbol.for('utf8')){if(b!==Symbol.for('utf8'))throw new Error(`unsupported encoding ${b}`);return a.__MODULE__?Symbol.keyFor(a.__MODULE__):Symbol.keyFor(a)}function binary_to_atom(a,b=Symbol.for('utf8')){if(b!==Symbol.for('utf8'))throw new Error(`unsupported encoding ${b}`);return Symbol.for(a)}function is_number$1(a){return'number'==typeof a||a instanceof Number}function is_key(a,b){return b.has(a)}// http://erlang.org/doc/man/lists.html +function atom_to_binary(a,b=Symbol.for('utf8')){if(b!==Symbol.for('utf8'))throw new Error(`unsupported encoding ${b}`);return a.__MODULE__?Symbol.keyFor(a.__MODULE__):Symbol.keyFor(a)}function binary_to_atom(a,b=Symbol.for('utf8')){if(b!==Symbol.for('utf8'))throw new Error(`unsupported encoding ${b}`);return Symbol.for(a)}function is_bitstring$1(a){return a instanceof d.BitString}function is_number$1(a){return'number'==typeof a||a instanceof Number}function is_integer(b){return a(b)}function is_binary(a){return'string'==typeof a||a instanceof String}function iolist_to_binary(a){var b=String.fromCodePoint;if(is_binary(a))return a;if(is_bitstring$1(a))return b(...a.value);const c=a.reduce((a,c)=>{if(is_integer(c))return a+b(c);return is_bitstring$1(c)?a+b(...c.value):a+iolist_to_binary(c)},'');return c}function is_key(a,b){return b.has(a)}// http://erlang.org/doc/man/lists.html function reverse(a){return[...a]}function flatten(a,b=[]){const c=a.reduce((a,b)=>{return Array.isArray(b)?a.concat(flatten(b)):a.concat(b)},[]);return c.concat(b)}function foldl(a,b,c){return c.reduce((b,c)=>{return a(c,b)},b)}function keyfind(a,b,c){for(const d of c)if(d.get(b-1)===a)return d;return!1}function keydelete(a,b,c){const d=[];let e=!1;for(let f=0;fBitString$1.integer(a));return new BitString$1(...d)}[Symbol.iterator](){return this.value[Symbol.iterator]()}toString(){var a,b='';for(a=0;a>'}process(a){let b=[];var c;for(c=0;cb?c.push(b):2048>b?c.push(192|b>>6,128|63&b):55296>b||57344<=b?c.push(224|b>>12,128|63&b>>6,128|63&b):(d++,b=65536+((1023&b)<<10|1023&a.charCodeAt(d)),c.push(240|b>>18,128|63&b>>12,128|63&b>>6,128|63&b));return c}static toUTF16Array(a){for(var b,c=[],d=0;d=b?(c.push(0),c.push(b)):(c.push(255&b>>8),c.push(255&b));return c}static toUTF32Array(a){for(var b,c=[],d=0;d=b?(c.push(0),c.push(0),c.push(0),c.push(b)):(c.push(0),c.push(0),c.push(255&b>>8),c.push(255&b));return c}//http://stackoverflow.com/questions/2003493/javascript-float-from-to-bits static float32ToBytes(a){var b=[],c=new ArrayBuffer(4);new Float32Array(c)[0]=a;let d=new Uint32Array(c)[0];return b.push(255&d>>24),b.push(255&d>>16),b.push(255&d>>8),b.push(255&d),b}static float64ToBytes(a){var b=[],c=new ArrayBuffer(8);new Float64Array(c)[0]=a;var d=new Uint32Array(c)[0],e=new Uint32Array(c)[1];return b.push(255&e>>24),b.push(255&e>>16),b.push(255&e>>8),b.push(255&e),b.push(255&d>>24),b.push(255&d>>16),b.push(255&d>>8),b.push(255&d),b}}var d={Tuple,PID:class PID{constructor(){++b,this.id=b}toString(){return'PID#<0.'+this.id+'.0>'}},Reference:class Reference{constructor(){++c,this.id=c,this.ref=Symbol()}toString(){return'Ref#<0.0.0.'+this.id+'>'}},BitString:BitString$1};/* @flow */const e=d.BitString,f=new Map;f.set(Variable.prototype,function resolveVariable(a){return function(b,c){return null===a.name||a.name.startsWith('_')?c.push(b):c.push(namedVariableResult(a.name,b)),!0}}),f.set(Wildcard.prototype,resolveWildcard),f.set(HeadTail.prototype,function resolveHeadTail(){return function(a,b){if(!is_array(a)||2>a.length)return!1;const c=a[0],d=a.slice(1);return b.push(c),b.push(d),!0}}),f.set(StartsWith.prototype,function resolveStartsWith(a){const b=a.prefix;return function(a,c){return is_string(a)&&a.startsWith(b)&&(c.push(a.substring(b.length)),!0)}}),f.set(Capture.prototype,function resolveCapture(a){const b=buildMatch(a.value);return function(a,c){return!!b(a,c)&&(c.push(a),!0)}}),f.set(Bound.prototype,function resolveBound(a){return function(b){return typeof b==typeof a.value&&b===a.value}}),f.set(Type.prototype,function resolveType(a){return function(b,c){if(b instanceof a.type){const d=buildMatch(a.objPattern);return d(b,c)}return!1}}),f.set(BitStringMatch.prototype,function resolveBitString(a){let b=[];for(let c of a.values)if(is_variable(c.value)){let a=getSize(c.unit,c.size);fillArray(b,a)}else b=b.concat(new e(c).value);let c=a.values;return function(a,d){var f=String.fromCharCode;let g=null;if(!is_string(a)&&!(a instanceof e))return!1;g=is_string(a)?new e(e.binary(a)):a;let h=0;for(let e,j=0;jd.size)return!1;for(let a of c)if(!d.has(a)||!b.get(a)(d.get(a),e))return!1;return!0}}),f.set(Array.prototype,function resolveArray(a){const b=a.map((a)=>buildMatch(a));return function(c,d){return is_array(c)&&c.length==a.length&&c.every(function(a,e){return b[e](c[e],d)})}}),f.set(String.prototype,function resolveString(a){return function(b){return is_string(b)&&b===a}}),f.set(Boolean.prototype,function resolveBoolean(a){return function(b){return is_boolean(b)&&b===a}}),f.set(Function.prototype,function resolveFunction(a){return function(b){return is_function(b)&&b===a}}),f.set(Object.prototype,resolveObject);class MatchError extends Error{constructor(a){if(super(),'symbol'==typeof a)this.message='No match for: '+a.toString();else if(Array.isArray(a)){let b=a.map((a)=>{return null===a?'null':'undefined'==typeof a?'undefined':a.toString()});this.message='No match for: '+b}else this.message='No match for: '+a;this.stack=new Error().stack,this.name=this.constructor.name}}class Clause{constructor(a,b,c=()=>!0){this.pattern=buildMatch(a),this.arity=a.length,this.optionals=getOptionalValues(a),this.fn=b,this.guard=c}}const g=Symbol();// https://github.com/airportyh/protomorphism -class Protocol{constructor(b){function createFun(b){return function(...c){const d=c[0];let e=null;if(null===d&&this.hasImplementation(Symbol('null'))?e=this.registry.get(Symbol)[b]:a(d)&&this.hasImplementation(n.Integer)?e=this.registry.get(n.Integer)[b]:'number'==typeof d&&!a(d)&&this.hasImplementation(n.Float)?e=this.registry.get(n.Float)[b]:'string'==typeof d&&this.hasImplementation(n.BitString)?e=this.registry.get(n.BitString)[b]:d&&d.has(Symbol.for('__struct__'))&&this.hasImplementation(d)?e=this.registry.get(d.get(Symbol.for('__struct__')).__MODULE__)[b]:null!==d&&this.hasImplementation(d)?e=this.registry.get(d.constructor)[b]:this.fallback&&(e=this.fallback[b]),null!=e){const a=e.apply(this,c);return a}throw new Error(`No implementation found for ${d}`)}}for(const a in this.registry=new Map,this.fallback=null,b)this[a]=createFun(a).bind(this)}implementation(a,b){null===a?this.fallback=b:this.registry.set(a,b)}hasImplementation(a){if(a===n.Integer||a===n.Float||a===n.BitString)return this.registry.has(a);return a&&a.has(Symbol.for('__struct__'))?this.registry.has(a.get(Symbol.for('__struct__')).__MODULE__):this.registry.has(a.constructor)}}var h={atom_to_binary,binary_to_atom,binary_to_existing_atom:function binary_to_existing_atom(a,b=Symbol.for('utf8')){return binary_to_atom(a,b)},list_concatenation:function list_concatenation(a,b){return a.concat(b)},list_subtraction:function list_subtraction(a,b){const c=[...a];for(const d of b){const a=c.indexOf(d);-1b},greaterThanOrEqualTo:function greaterThanOrEqualTo(a,b){return a>=b},lessThan:function lessThan(a,b){return a>b},bxor:function bxor(a,b){return a^b},bnot:function bnot(a){return~a},is_bitstring:function is_bitstring$1(a){return a instanceof d.BitString},is_boolean:function is_boolean$1(a){return'boolean'==typeof a||a instanceof Boolean},is_float:function is_float(b){return is_number$1(b)&&!a(b)},is_function:function is_function$1(a){return'function'==typeof a||a instanceof Function},is_integer:function is_integer(b){return a(b)},is_list:function is_list(a){return Array.isArray(a)},is_map:function is_map$1(a){return a instanceof Map},is_number:is_number$1,is_pid:function is_pid(a){return a instanceof d.PID},is_port:function is_port(){return!1},is_reference:function is_reference(a){return a instanceof d.Reference},is_tuple:function is_tuple(a){return a instanceof d.Tuple},is_atom:function is_atom(a){return'symbol'==typeof a||a instanceof Symbol||a.__MODULE__},is_binary:function is_binary(a){return'string'==typeof a||a instanceof String},element:function element(a,b){return b.get(a-1)},setelement:function setelement(a,b,c){const e=[...b.values];return e[a-1]=c,new d.Tuple(...e)},make_tuple:function make_tuple(a,b){const c=[];for(let d=0;db},greaterThanOrEqualTo:function greaterThanOrEqualTo(a,b){return a>=b},lessThan:function lessThan(a,b){return a>b},bxor:function bxor(a,b){return a^b},bnot:function bnot(a){return~a},is_bitstring:is_bitstring$1,is_boolean:function is_boolean$1(a){return'boolean'==typeof a||a instanceof Boolean},is_float:function is_float(b){return is_number$1(b)&&!a(b)},is_function:function is_function$1(a){return'function'==typeof a||a instanceof Function},is_integer,is_list:function is_list(a){return Array.isArray(a)},is_map:function is_map$1(a){return a instanceof Map},is_number:is_number$1,is_pid:function is_pid(a){return a instanceof d.PID},is_port:function is_port(){return!1},is_reference:function is_reference(a){return a instanceof d.Reference},is_tuple:function is_tuple(a){return a instanceof d.Tuple},is_atom:function is_atom(a){return'symbol'==typeof a||a instanceof Symbol||a.__MODULE__},is_binary,element:function element(a,b){return b.get(a-1)},setelement:function setelement(a,b,c){const e=[...b.values];return e[a-1]=c,new d.Tuple(...e)},make_tuple:function make_tuple(a,b){const c=[];for(let d=0;d!0){let d=[],e=buildMatch(a);const f=e(b,d),[g,h]=checkNamedVariables(d);if(f&&h&&c.apply(this,g))return g;throw console.error('No match for:',b),new MatchError(b)},MatchError,variable:function variable(a=null,b=Symbol.for('tailored.no_value')){return new Variable(a,b)},wildcard:function wildcard(){return new Wildcard},startsWith:function startsWith(a){return new StartsWith(a)},capture:function capture(a){return new Capture(a)},headTail:function headTail(){return new HeadTail},type:function a(a,b={}){return new Type(a,b)},bound:function bound(a){return new Bound(a)},Clause,clause:function clause(a,b,c=()=>!0){return new Clause(a,b,c)},bitStringMatch:function bitStringMatch(...a){return new BitStringMatch(...a)},match_or_default,defmatchgen,list_comprehension:function list_comprehension(a,b){const c=run_generators(b.pop()(),b);let d=[];for(let e of c)a.guard.apply(this,e)&&d.push(a.fn.apply(this,e));return d},list_generator:function list_generator(a,b){return function(){let c=[];for(let d of b){const b=match_or_default(a,d,()=>!0,g);if(b!=g){const[a]=b;c.push(a)}}return c}},bitstring_generator:function bitstring_generator(a,b){return function(){let c=[],d=b.slice(0,a.byte_size()),e=1;for(;d.byte_size==a.byte_size();){const f=match_or_default(a,d,()=>!0,g);if(f!=g){c.push(f)}d=b.slice(a.byte_size()*e,a.byte_size()*(e+1)),e++}return c}},bitstring_comprehension:function bitstring_comprehension(a,b){const c=run_generators(b.pop()(),b);let e=[];for(let d of c)a.guard.apply(this,d)&&e.push(a.fn.apply(this,d));return e=e.map((a)=>d.BitString.integer(a)),new d.BitString(...e)},defmatchGen:function defmatchGen(...a){return defmatchgen(...a)},defmatchAsync:function defmatchAsync(...a){const b=getArityMap(a);return async function(...a){if(b.has(a.length)){const c=b.get(a.length);let d=null,e=null;for(let b of c){let c=[];a=fillInOptionalValues(a,b.arity,b.optionals);const f=b.pattern(a,c),[g,h]=checkNamedVariables(c);if(f&&h&&(await b.guard.apply(this,c))){d=b.fn,e=c;break}}if(!d)throw console.error('No match for:',a),new MatchError(a);return d.apply(this,e)}throw console.error('Arity of',a.length,'not found. No match for:',a),new MatchError(a)}}},Integer:class Integer{},Float:class Float{},Functions:{call_property:function call_property(a,b){if(!b)return a instanceof Function||'function'==typeof a?a():a;if(a instanceof Map){let c=null;if(a.has(b)?c=b:a.has(Symbol.for(b))&&(c=Symbol.for(b)),null===c)throw new Error(`Property ${b} not found in ${a}`);return a.get(c)instanceof Function||'function'==typeof a.get(c)?a.get(c)():a.get(c)}let c=null;if('number'==typeof a||'symbol'==typeof a||'boolean'==typeof a||'string'==typeof a?void 0===a[b]?void 0!==a[Symbol.for(b)]&&(c=Symbol.for(b)):c=b:b in a?c=b:Symbol.for(b)in a&&(c=Symbol.for(b)),null===c)throw new Error(`Property ${b} not found in ${a}`);return a[c]instanceof Function||'function'==typeof a[c]?a[c]():a[c]},defprotocol:function defprotocol(a){return new Protocol(a)},defimpl:function defimpl(a,b,c){a.implementation(b,c)},build_namespace:function build_namespace(a,b){let c=b.split('.');const d=a;let e=a;'Elixir'===c[0]&&(c=c.slice(1));for(const d of c)'undefined'==typeof e[d]&&(e[d]={}),e=e[d];return d.__table__=a.__table__||{},d.__table__[Symbol.for(b)]=e,e},iterator_to_reducer,map_to_object},SpecialForms:{_case:function _case(a,b){return n.Patterns.defmatch(...b)(a)},cond:function cond(...a){for(const b of a)if(b[0])return b[1]();throw new Error},_for:function _for(a,b,c,d=[]){let[e,f]=c.into(d);const g=run_list_generators(b.pop()(),b);for(const h of g)a.guard.apply(this,h)&&(e=f(e,new n.Tuple(Symbol.for('cont'),a.fn.apply(this,h))));return f(e,Symbol.for('done'))},_try:function _try(a,b,c,d,e){let f=null;try{f=a()}catch(a){let d=null;if(b)try{return d=b(a),d}catch(a){if(a instanceof n.Patterns.MatchError)throw a}if(c)try{return d=c(a),d}catch(a){if(a instanceof n.Patterns.MatchError)throw a}throw a}finally{e&&e()}if(d)try{return d(f)}catch(a){if(a instanceof n.Patterns.MatchError)throw new Error('No Match Found in Else');throw a}else return f},_with:function _with(...a){let b=[],c=null,d=null;'function'==typeof a[a.length-2]?[c,d]=a.splice(-2):c=a.pop();for(let c=0;c{const[c,d]=b;return a.set(c,d),a},new Map)},keys:function keys(a){return!1===h.is_map(a)?new d.Tuple(k,a):Array.from(a.keys())},values:function values$1(a){return!1===h.is_map(a)?new d.Tuple(k,a):Array.from(a.values())},is_key,put:function put(a,b,c){if(!1===h.is_map(c))return new d.Tuple(k,c);const e=new Map(c);return e.set(a,b),e},merge:function merge(a,b){return!1===h.is_map(a)?new d.Tuple(k,a):!1===h.is_map(b)?new d.Tuple(k,b):new Map([...a,...b])},update:function update(a,b,c){return!1===h.is_map(c)?new d.Tuple(k,c):!1===is_key(a,c)?new d.Tuple(l,a):new Map([...c,[a,b]])},get:function get(...a){const b=a[0],c=a[1];return!1===h.is_map(c)?new d.Tuple(k,c):is_key(b)?c.get(b):3===a.length?a[2]:new d.Tuple(l,b)},take:function take(a,b){if(!1===h.is_map(b))return new d.Tuple(k,b);if(!is_key(a))return j;const c=b.get(a),e=new Map(b);return e.delete(a),new d.Tuple(c,e)}},lists:{reverse,foreach:function foreach(a,b){return b.forEach((b)=>a(b)),Symbol.for('ok')},duplicate:function duplicate(a,b){const c=[];for(;c.length{if(d.get(c-1)a.get(c-1)?1:0})},keystore:function keystore(a,b,c,d){const e=[...c];for(let f=0;fa.toString()).join()},map:function map(a,b){return b.map((b)=>a(b))},filter:function filter(a,b){return b.filter((b)=>a(b))},filtermap:function filtermap(a,b){const c=[];for(const e of b){const b=a(e);!0===b?c.push(e):b instanceof d.Tuple&&!0===b.get(0)&&c.push(b.get(1))}return c},member:function member(a,b){for(const c of b)if(c===a)return!0;return!1},all:function all(a,b){for(const c of b)if(!1===a(c))return!1;return!0},any:function any(a,b){for(const c of b)if(!0===a(c))return!0;return!1},splitwith:function splitwith(a,b){let c=!1;const e=[],f=[];for(const d of b)!0==c?f.push(d):!0===a(d)?e.push(d):(c=!0,f.push(d));return new d.Tuple(e,f)},sort:function sort(...a){if(1===a.length){const b=[...a[0]];return b.sort()}const c=a[0],b=[...a[1]];return b.sort((d,a)=>{const b=c(d,a);return!0===b?-1:1})}},elixir_errors:{warn:function warn(a){const b=a.join('');return console.warn(`warning: ${b}`),Symbol.for('ok')}}};return{Core:n}}(); diff --git a/src/javascript/lib/core/erlang_compat/erlang.js b/src/javascript/lib/core/erlang_compat/erlang.js index 670d9047..74c34ccf 100644 --- a/src/javascript/lib/core/erlang_compat/erlang.js +++ b/src/javascript/lib/core/erlang_compat/erlang.js @@ -329,6 +329,32 @@ function process_info(pid, item) { return []; } +function iolist_to_binary(ioListOrBinary) { + if (is_binary(ioListOrBinary)) { + return ioListOrBinary; + } + + if (is_bitstring(ioListOrBinary)) { + return String.fromCodePoint(...ioListOrBinary.value); + } + + const value = ioListOrBinary.reduce((acc, current) => { + if (is_integer(current)) { + return acc + String.fromCodePoint(current); + } else if (is_bitstring(current)) { + return acc + String.fromCodePoint(...current.value); + } + + return acc + iolist_to_binary(current); + }, ''); + + return value; +} + +function io_size(ioListOrBinary) { + return iolist_to_binary(ioListOrBinary).length; +} + export default { atom_to_binary, binary_to_atom, @@ -395,5 +421,7 @@ export default { tuple_size, binary_to_float, binary_to_integer, - process_info + process_info, + iolist_to_binary, + io_size }; From 9ed0e5ff4eefd5221d46081be30bab20bd14c84f Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Fri, 21 Jul 2017 07:57:58 -0500 Subject: [PATCH 189/418] Add io.put_chars --- .../passes/translate/forms/remote.ex | 3 ++- priv/build/iife/ElixirScript.Core.js | 12 +++++------ src/javascript/lib/core.js | 4 +++- src/javascript/lib/core/erlang_compat/io.js | 21 +++++++++++++++++++ 4 files changed, 32 insertions(+), 8 deletions(-) create mode 100644 src/javascript/lib/core/erlang_compat/io.js diff --git a/lib/elixir_script/passes/translate/forms/remote.ex b/lib/elixir_script/passes/translate/forms/remote.ex index 622fc3c0..38c2acc1 100644 --- a/lib/elixir_script/passes/translate/forms/remote.ex +++ b/lib/elixir_script/passes/translate/forms/remote.ex @@ -15,7 +15,8 @@ defmodule ElixirScript.Translate.Forms.Remote do :application, :code, :elixir_utils, - :file + :file, + :io ] @doc """ diff --git a/priv/build/iife/ElixirScript.Core.js b/priv/build/iife/ElixirScript.Core.js index 82295b52..a076e953 100644 --- a/priv/build/iife/ElixirScript.Core.js +++ b/priv/build/iife/ElixirScript.Core.js @@ -1,6 +1,6 @@ -var ElixirScript=function(){'use strict';/* @flow */function namedVariableResult(a,b){return new NamedVariableResult(a,b)}/* @flow */function is_number(a){return'number'==typeof a}function is_string(a){return'string'==typeof a}function is_boolean(a){return'boolean'==typeof a}function is_symbol(a){return'symbol'==typeof a}function is_object(a){return'object'==typeof a}function is_variable(a){return a instanceof Variable}function is_null(a){return null===a}function is_array(a){return Array.isArray(a)}function is_function(a){return'[object Function]'==Object.prototype.toString.call(a)}function is_map(a){return a instanceof Map}function resolveNull(){return function(a){return is_null(a)}}function resolveWildcard(){return function(){return!0}}function resolveObject(a){let b={};const c=Object.keys(a).concat(Object.getOwnPropertySymbols(a));for(let d of c)b[d]=buildMatch(a[d]);return function(d,e){if(!is_object(d)||a.length>d.length)return!1;for(let a of c)if(!(a in d)||!b[a](d[a],e))return!1;return!0}}function getSize(a,b){return a*b/8}function arraysEqual(c,a){if(c===a)return!0;if(null==c||null==a)return!1;if(c.length!=a.length)return!1;for(var b=0;be.integer(a));return new e(...b)}function resolveNoMatch(){return function(){return!1}}function buildMatch(a){if(null===a)return resolveNull(a);if('undefined'==typeof a)return resolveWildcard(a);const b=a.constructor.prototype,c=f.get(b);return c?c(a):'object'==typeof a?resolveObject(a):resolveNoMatch()}function defmatchgen(...a){const b=getArityMap(a);return function*(...a){let[c,d]=findMatchingFunction(a,b);return yield*c.apply(this,d)}}function findMatchingFunction(a,b){if(b.has(a.length)){const c=b.get(a.length);let d=null,e=null;for(let b of c){let c=[];a=fillInOptionalValues(a,b.arity,b.optionals);const f=b.pattern(a,c),[g,h]=checkNamedVariables(c);if(f&&h&&b.guard.apply(this,g)){d=b.fn,e=g;break}}if(!d)throw console.error('No match for:',a),new MatchError(a);return[d,e]}throw console.error('Arity of',a.length,'not found. No match for:',a),new MatchError(a)}function getArityMap(a){let b=new Map;for(const c of a){const a=getArityRange(c);for(const d of a){let a=[];b.has(d)&&(a=b.get(d)),a.push(c),b.set(d,a)}}return b}function getArityRange(a){const b=a.arity-a.optionals.length,c=a.arity;let d=[b];for(;d[d.length-1]!=c;)d.push(d[d.length-1]+1);return d}function getOptionalValues(a){let b=[];for(let c=0;c!0,d=null){let e=[],f=buildMatch(a);const g=f(b,e),[h,i]=checkNamedVariables(e);return g&&i&&c.apply(this,h)?h:d}function run_generators(a,b){if(0==b.length)return a.map((a)=>{return Array.isArray(a)?a:[a]});const c=b.pop();let d=[];for(let e of c())for(let b of a)d.push([e].concat(b));return run_generators(d,b)}function iterator_to_reducer(a,b,c){const d=a[Symbol.iterator]();let e=d.next(),f=b;for(;!1===e.done;){if(f=c(e.value,f.get(1)),f.get(0)===Symbol.for('halt'))return new n.Tuple(Symbol.for('halted'),f.get(1));if(f.get(0)===Symbol.for('suspend'))return new n.Tuple(Symbol.for('suspended'),f.get(1),(a)=>{return iterator_to_reducer(d,a,c)});e=d.next()}return new n.Tuple(Symbol.for('done'),f.get(1))}function map_to_object(a){const b={};for(const[c,d]of a.entries())b[c]=d instanceof Map?map_to_object(d):d;return b}function run_list_generators(a,b){if(0==b.length)return a.map((a)=>{return Array.isArray(a)?a:[a]});const c=b.pop(),d=[];for(const e of c())for(const b of a)d.push([e].concat(b));return run_list_generators(d,b)}// http://erlang.org/doc/man/erlang.html -function atom_to_binary(a,b=Symbol.for('utf8')){if(b!==Symbol.for('utf8'))throw new Error(`unsupported encoding ${b}`);return a.__MODULE__?Symbol.keyFor(a.__MODULE__):Symbol.keyFor(a)}function binary_to_atom(a,b=Symbol.for('utf8')){if(b!==Symbol.for('utf8'))throw new Error(`unsupported encoding ${b}`);return Symbol.for(a)}function is_bitstring$1(a){return a instanceof d.BitString}function is_number$1(a){return'number'==typeof a||a instanceof Number}function is_integer(b){return a(b)}function is_binary(a){return'string'==typeof a||a instanceof String}function iolist_to_binary(a){var b=String.fromCodePoint;if(is_binary(a))return a;if(is_bitstring$1(a))return b(...a.value);const c=a.reduce((a,c)=>{if(is_integer(c))return a+b(c);return is_bitstring$1(c)?a+b(...c.value):a+iolist_to_binary(c)},'');return c}function is_key(a,b){return b.has(a)}// http://erlang.org/doc/man/lists.html -function reverse(a){return[...a]}function flatten(a,b=[]){const c=a.reduce((a,b)=>{return Array.isArray(b)?a.concat(flatten(b)):a.concat(b)},[]);return c.concat(b)}function foldl(a,b,c){return c.reduce((b,c)=>{return a(c,b)},b)}function keyfind(a,b,c){for(const d of c)if(d.get(b-1)===a)return d;return!1}function keydelete(a,b,c){const d=[];let e=!1;for(let f=0;fBitString$1.integer(a));return new BitString$1(...d)}[Symbol.iterator](){return this.value[Symbol.iterator]()}toString(){var a,b='';for(a=0;a>'}process(a){let b=[];var c;for(c=0;cb?c.push(b):2048>b?c.push(192|b>>6,128|63&b):55296>b||57344<=b?c.push(224|b>>12,128|63&b>>6,128|63&b):(d++,b=65536+((1023&b)<<10|1023&a.charCodeAt(d)),c.push(240|b>>18,128|63&b>>12,128|63&b>>6,128|63&b));return c}static toUTF16Array(a){for(var b,c=[],d=0;d=b?(c.push(0),c.push(b)):(c.push(255&b>>8),c.push(255&b));return c}static toUTF32Array(a){for(var b,c=[],d=0;d=b?(c.push(0),c.push(0),c.push(0),c.push(b)):(c.push(0),c.push(0),c.push(255&b>>8),c.push(255&b));return c}//http://stackoverflow.com/questions/2003493/javascript-float-from-to-bits -static float32ToBytes(a){var b=[],c=new ArrayBuffer(4);new Float32Array(c)[0]=a;let d=new Uint32Array(c)[0];return b.push(255&d>>24),b.push(255&d>>16),b.push(255&d>>8),b.push(255&d),b}static float64ToBytes(a){var b=[],c=new ArrayBuffer(8);new Float64Array(c)[0]=a;var d=new Uint32Array(c)[0],e=new Uint32Array(c)[1];return b.push(255&e>>24),b.push(255&e>>16),b.push(255&e>>8),b.push(255&e),b.push(255&d>>24),b.push(255&d>>16),b.push(255&d>>8),b.push(255&d),b}}var d={Tuple,PID:class PID{constructor(){++b,this.id=b}toString(){return'PID#<0.'+this.id+'.0>'}},Reference:class Reference{constructor(){++c,this.id=c,this.ref=Symbol()}toString(){return'Ref#<0.0.0.'+this.id+'>'}},BitString:BitString$1};/* @flow */const e=d.BitString,f=new Map;f.set(Variable.prototype,function resolveVariable(a){return function(b,c){return null===a.name||a.name.startsWith('_')?c.push(b):c.push(namedVariableResult(a.name,b)),!0}}),f.set(Wildcard.prototype,resolveWildcard),f.set(HeadTail.prototype,function resolveHeadTail(){return function(a,b){if(!is_array(a)||2>a.length)return!1;const c=a[0],d=a.slice(1);return b.push(c),b.push(d),!0}}),f.set(StartsWith.prototype,function resolveStartsWith(a){const b=a.prefix;return function(a,c){return is_string(a)&&a.startsWith(b)&&(c.push(a.substring(b.length)),!0)}}),f.set(Capture.prototype,function resolveCapture(a){const b=buildMatch(a.value);return function(a,c){return!!b(a,c)&&(c.push(a),!0)}}),f.set(Bound.prototype,function resolveBound(a){return function(b){return typeof b==typeof a.value&&b===a.value}}),f.set(Type.prototype,function resolveType(a){return function(b,c){if(b instanceof a.type){const d=buildMatch(a.objPattern);return d(b,c)}return!1}}),f.set(BitStringMatch.prototype,function resolveBitString(a){let b=[];for(let c of a.values)if(is_variable(c.value)){let a=getSize(c.unit,c.size);fillArray(b,a)}else b=b.concat(new e(c).value);let c=a.values;return function(a,d){var f=String.fromCharCode;let g=null;if(!is_string(a)&&!(a instanceof e))return!1;g=is_string(a)?new e(e.binary(a)):a;let h=0;for(let e,j=0;jd.size)return!1;for(let a of c)if(!d.has(a)||!b.get(a)(d.get(a),e))return!1;return!0}}),f.set(Array.prototype,function resolveArray(a){const b=a.map((a)=>buildMatch(a));return function(c,d){return is_array(c)&&c.length==a.length&&c.every(function(a,e){return b[e](c[e],d)})}}),f.set(String.prototype,function resolveString(a){return function(b){return is_string(b)&&b===a}}),f.set(Boolean.prototype,function resolveBoolean(a){return function(b){return is_boolean(b)&&b===a}}),f.set(Function.prototype,function resolveFunction(a){return function(b){return is_function(b)&&b===a}}),f.set(Object.prototype,resolveObject);class MatchError extends Error{constructor(a){if(super(),'symbol'==typeof a)this.message='No match for: '+a.toString();else if(Array.isArray(a)){let b=a.map((a)=>{return null===a?'null':'undefined'==typeof a?'undefined':a.toString()});this.message='No match for: '+b}else this.message='No match for: '+a;this.stack=new Error().stack,this.name=this.constructor.name}}class Clause{constructor(a,b,c=()=>!0){this.pattern=buildMatch(a),this.arity=a.length,this.optionals=getOptionalValues(a),this.fn=b,this.guard=c}}const g=Symbol();// https://github.com/airportyh/protomorphism -class Protocol{constructor(b){function createFun(b){return function(...c){const d=c[0];let e=null;if(null===d&&this.hasImplementation(Symbol('null'))?e=this.registry.get(Symbol)[b]:a(d)&&this.hasImplementation(n.Integer)?e=this.registry.get(n.Integer)[b]:'number'==typeof d&&!a(d)&&this.hasImplementation(n.Float)?e=this.registry.get(n.Float)[b]:'string'==typeof d&&this.hasImplementation(n.BitString)?e=this.registry.get(n.BitString)[b]:d&&d.has(Symbol.for('__struct__'))&&this.hasImplementation(d)?e=this.registry.get(d.get(Symbol.for('__struct__')).__MODULE__)[b]:null!==d&&this.hasImplementation(d)?e=this.registry.get(d.constructor)[b]:this.fallback&&(e=this.fallback[b]),null!=e){const a=e.apply(this,c);return a}throw new Error(`No implementation found for ${d}`)}}for(const a in this.registry=new Map,this.fallback=null,b)this[a]=createFun(a).bind(this)}implementation(a,b){null===a?this.fallback=b:this.registry.set(a,b)}hasImplementation(a){if(a===n.Integer||a===n.Float||a===n.BitString)return this.registry.has(a);return a&&a.has(Symbol.for('__struct__'))?this.registry.has(a.get(Symbol.for('__struct__')).__MODULE__):this.registry.has(a.constructor)}}var h={atom_to_binary,binary_to_atom,binary_to_existing_atom:function binary_to_existing_atom(a,b=Symbol.for('utf8')){return binary_to_atom(a,b)},list_concatenation:function list_concatenation(a,b){return a.concat(b)},list_subtraction:function list_subtraction(a,b){const c=[...a];for(const d of b){const a=c.indexOf(d);-1b},greaterThanOrEqualTo:function greaterThanOrEqualTo(a,b){return a>=b},lessThan:function lessThan(a,b){return a>b},bxor:function bxor(a,b){return a^b},bnot:function bnot(a){return~a},is_bitstring:is_bitstring$1,is_boolean:function is_boolean$1(a){return'boolean'==typeof a||a instanceof Boolean},is_float:function is_float(b){return is_number$1(b)&&!a(b)},is_function:function is_function$1(a){return'function'==typeof a||a instanceof Function},is_integer,is_list:function is_list(a){return Array.isArray(a)},is_map:function is_map$1(a){return a instanceof Map},is_number:is_number$1,is_pid:function is_pid(a){return a instanceof d.PID},is_port:function is_port(){return!1},is_reference:function is_reference(a){return a instanceof d.Reference},is_tuple:function is_tuple(a){return a instanceof d.Tuple},is_atom:function is_atom(a){return'symbol'==typeof a||a instanceof Symbol||a.__MODULE__},is_binary,element:function element(a,b){return b.get(a-1)},setelement:function setelement(a,b,c){const e=[...b.values];return e[a-1]=c,new d.Tuple(...e)},make_tuple:function make_tuple(a,b){const c=[];for(let d=0;d!0){let d=[],e=buildMatch(a);const f=e(b,d),[g,h]=checkNamedVariables(d);if(f&&h&&c.apply(this,g))return g;throw console.error('No match for:',b),new MatchError(b)},MatchError,variable:function variable(a=null,b=Symbol.for('tailored.no_value')){return new Variable(a,b)},wildcard:function wildcard(){return new Wildcard},startsWith:function startsWith(a){return new StartsWith(a)},capture:function capture(a){return new Capture(a)},headTail:function headTail(){return new HeadTail},type:function a(a,b={}){return new Type(a,b)},bound:function bound(a){return new Bound(a)},Clause,clause:function clause(a,b,c=()=>!0){return new Clause(a,b,c)},bitStringMatch:function bitStringMatch(...a){return new BitStringMatch(...a)},match_or_default,defmatchgen,list_comprehension:function list_comprehension(a,b){const c=run_generators(b.pop()(),b);let d=[];for(let e of c)a.guard.apply(this,e)&&d.push(a.fn.apply(this,e));return d},list_generator:function list_generator(a,b){return function(){let c=[];for(let d of b){const b=match_or_default(a,d,()=>!0,g);if(b!=g){const[a]=b;c.push(a)}}return c}},bitstring_generator:function bitstring_generator(a,b){return function(){let c=[],d=b.slice(0,a.byte_size()),e=1;for(;d.byte_size==a.byte_size();){const f=match_or_default(a,d,()=>!0,g);if(f!=g){c.push(f)}d=b.slice(a.byte_size()*e,a.byte_size()*(e+1)),e++}return c}},bitstring_comprehension:function bitstring_comprehension(a,b){const c=run_generators(b.pop()(),b);let e=[];for(let d of c)a.guard.apply(this,d)&&e.push(a.fn.apply(this,d));return e=e.map((a)=>d.BitString.integer(a)),new d.BitString(...e)},defmatchGen:function defmatchGen(...a){return defmatchgen(...a)},defmatchAsync:function defmatchAsync(...a){const b=getArityMap(a);return async function(...a){if(b.has(a.length)){const c=b.get(a.length);let d=null,e=null;for(let b of c){let c=[];a=fillInOptionalValues(a,b.arity,b.optionals);const f=b.pattern(a,c),[g,h]=checkNamedVariables(c);if(f&&h&&(await b.guard.apply(this,c))){d=b.fn,e=c;break}}if(!d)throw console.error('No match for:',a),new MatchError(a);return d.apply(this,e)}throw console.error('Arity of',a.length,'not found. No match for:',a),new MatchError(a)}}},Integer:class Integer{},Float:class Float{},Functions:{call_property:function call_property(a,b){if(!b)return a instanceof Function||'function'==typeof a?a():a;if(a instanceof Map){let c=null;if(a.has(b)?c=b:a.has(Symbol.for(b))&&(c=Symbol.for(b)),null===c)throw new Error(`Property ${b} not found in ${a}`);return a.get(c)instanceof Function||'function'==typeof a.get(c)?a.get(c)():a.get(c)}let c=null;if('number'==typeof a||'symbol'==typeof a||'boolean'==typeof a||'string'==typeof a?void 0===a[b]?void 0!==a[Symbol.for(b)]&&(c=Symbol.for(b)):c=b:b in a?c=b:Symbol.for(b)in a&&(c=Symbol.for(b)),null===c)throw new Error(`Property ${b} not found in ${a}`);return a[c]instanceof Function||'function'==typeof a[c]?a[c]():a[c]},defprotocol:function defprotocol(a){return new Protocol(a)},defimpl:function defimpl(a,b,c){a.implementation(b,c)},build_namespace:function build_namespace(a,b){let c=b.split('.');const d=a;let e=a;'Elixir'===c[0]&&(c=c.slice(1));for(const d of c)'undefined'==typeof e[d]&&(e[d]={}),e=e[d];return d.__table__=a.__table__||{},d.__table__[Symbol.for(b)]=e,e},iterator_to_reducer,map_to_object},SpecialForms:{_case:function _case(a,b){return n.Patterns.defmatch(...b)(a)},cond:function cond(...a){for(const b of a)if(b[0])return b[1]();throw new Error},_for:function _for(a,b,c,d=[]){let[e,f]=c.into(d);const g=run_list_generators(b.pop()(),b);for(const h of g)a.guard.apply(this,h)&&(e=f(e,new n.Tuple(Symbol.for('cont'),a.fn.apply(this,h))));return f(e,Symbol.for('done'))},_try:function _try(a,b,c,d,e){let f=null;try{f=a()}catch(a){let d=null;if(b)try{return d=b(a),d}catch(a){if(a instanceof n.Patterns.MatchError)throw a}if(c)try{return d=c(a),d}catch(a){if(a instanceof n.Patterns.MatchError)throw a}throw a}finally{e&&e()}if(d)try{return d(f)}catch(a){if(a instanceof n.Patterns.MatchError)throw new Error('No Match Found in Else');throw a}else return f},_with:function _with(...a){let b=[],c=null,d=null;'function'==typeof a[a.length-2]?[c,d]=a.splice(-2):c=a.pop();for(let c=0;c{const[c,d]=b;return a.set(c,d),a},new Map)},keys:function keys(a){return!1===h.is_map(a)?new d.Tuple(k,a):Array.from(a.keys())},values:function values$1(a){return!1===h.is_map(a)?new d.Tuple(k,a):Array.from(a.values())},is_key,put:function put(a,b,c){if(!1===h.is_map(c))return new d.Tuple(k,c);const e=new Map(c);return e.set(a,b),e},merge:function merge(a,b){return!1===h.is_map(a)?new d.Tuple(k,a):!1===h.is_map(b)?new d.Tuple(k,b):new Map([...a,...b])},update:function update(a,b,c){return!1===h.is_map(c)?new d.Tuple(k,c):!1===is_key(a,c)?new d.Tuple(l,a):new Map([...c,[a,b]])},get:function get(...a){const b=a[0],c=a[1];return!1===h.is_map(c)?new d.Tuple(k,c):is_key(b)?c.get(b):3===a.length?a[2]:new d.Tuple(l,b)},take:function take(a,b){if(!1===h.is_map(b))return new d.Tuple(k,b);if(!is_key(a))return j;const c=b.get(a),e=new Map(b);return e.delete(a),new d.Tuple(c,e)}},lists:{reverse,foreach:function foreach(a,b){return b.forEach((b)=>a(b)),Symbol.for('ok')},duplicate:function duplicate(a,b){const c=[];for(;c.length{if(d.get(c-1)a.get(c-1)?1:0})},keystore:function keystore(a,b,c,d){const e=[...c];for(let f=0;fa.toString()).join()},map:function map(a,b){return b.map((b)=>a(b))},filter:function filter(a,b){return b.filter((b)=>a(b))},filtermap:function filtermap(a,b){const c=[];for(const e of b){const b=a(e);!0===b?c.push(e):b instanceof d.Tuple&&!0===b.get(0)&&c.push(b.get(1))}return c},member:function member(a,b){for(const c of b)if(c===a)return!0;return!1},all:function all(a,b){for(const c of b)if(!1===a(c))return!1;return!0},any:function any(a,b){for(const c of b)if(!0===a(c))return!0;return!1},splitwith:function splitwith(a,b){let c=!1;const e=[],f=[];for(const d of b)!0==c?f.push(d):!0===a(d)?e.push(d):(c=!0,f.push(d));return new d.Tuple(e,f)},sort:function sort(...a){if(1===a.length){const b=[...a[0]];return b.sort()}const c=a[0],b=[...a[1]];return b.sort((d,a)=>{const b=c(d,a);return!0===b?-1:1})}},elixir_errors:{warn:function warn(a){const b=a.join('');return console.warn(`warning: ${b}`),Symbol.for('ok')}}};return{Core:n}}(); +var ElixirScript=function(){'use strict';/* @flow */function namedVariableResult(a,b){return new NamedVariableResult(a,b)}/* @flow */function is_number(a){return'number'==typeof a}function is_string(a){return'string'==typeof a}function is_boolean(a){return'boolean'==typeof a}function is_symbol(a){return'symbol'==typeof a}function is_object(a){return'object'==typeof a}function is_variable(a){return a instanceof Variable}function is_null(a){return null===a}function is_array(a){return Array.isArray(a)}function is_function(a){return'[object Function]'==Object.prototype.toString.call(a)}function is_map(a){return a instanceof Map}function resolveNull(){return function(a){return is_null(a)}}function resolveWildcard(){return function(){return!0}}function resolveObject(a){let b={};const c=Object.keys(a).concat(Object.getOwnPropertySymbols(a));for(let d of c)b[d]=buildMatch(a[d]);return function(d,e){if(!is_object(d)||a.length>d.length)return!1;for(let a of c)if(!(a in d)||!b[a](d[a],e))return!1;return!0}}function getSize(a,b){return a*b/8}function arraysEqual(c,a){if(c===a)return!0;if(null==c||null==a)return!1;if(c.length!=a.length)return!1;for(var b=0;bf.integer(a));return new f(...b)}function resolveNoMatch(){return function(){return!1}}function buildMatch(a){if(null===a)return resolveNull(a);if('undefined'==typeof a)return resolveWildcard(a);const b=a.constructor.prototype,c=g.get(b);return c?c(a):'object'==typeof a?resolveObject(a):resolveNoMatch()}function defmatchgen(...a){const b=getArityMap(a);return function*(...a){let[c,d]=findMatchingFunction(a,b);return yield*c.apply(this,d)}}function findMatchingFunction(a,b){if(b.has(a.length)){const c=b.get(a.length);let d=null,e=null;for(let b of c){let c=[];a=fillInOptionalValues(a,b.arity,b.optionals);const f=b.pattern(a,c),[g,h]=checkNamedVariables(c);if(f&&h&&b.guard.apply(this,g)){d=b.fn,e=g;break}}if(!d)throw console.error('No match for:',a),new MatchError(a);return[d,e]}throw console.error('Arity of',a.length,'not found. No match for:',a),new MatchError(a)}function getArityMap(a){let b=new Map;for(const c of a){const a=getArityRange(c);for(const d of a){let a=[];b.has(d)&&(a=b.get(d)),a.push(c),b.set(d,a)}}return b}function getArityRange(a){const b=a.arity-a.optionals.length,c=a.arity;let d=[b];for(;d[d.length-1]!=c;)d.push(d[d.length-1]+1);return d}function getOptionalValues(a){let b=[];for(let c=0;c!0,d=null){let e=[],f=buildMatch(a);const g=f(b,e),[h,i]=checkNamedVariables(e);return g&&i&&c.apply(this,h)?h:d}function run_generators(a,b){if(0==b.length)return a.map((a)=>{return Array.isArray(a)?a:[a]});const c=b.pop();let d=[];for(let e of c())for(let b of a)d.push([e].concat(b));return run_generators(d,b)}function iterator_to_reducer(a,b,c){const d=a[Symbol.iterator]();let e=d.next(),f=b;for(;!1===e.done;){if(f=c(e.value,f.get(1)),f.get(0)===Symbol.for('halt'))return new o.Tuple(Symbol.for('halted'),f.get(1));if(f.get(0)===Symbol.for('suspend'))return new o.Tuple(Symbol.for('suspended'),f.get(1),(a)=>{return iterator_to_reducer(d,a,c)});e=d.next()}return new o.Tuple(Symbol.for('done'),f.get(1))}function map_to_object(a){const b={};for(const[c,d]of a.entries())b[c]=d instanceof Map?map_to_object(d):d;return b}function run_list_generators(a,b){if(0==b.length)return a.map((a)=>{return Array.isArray(a)?a:[a]});const c=b.pop(),d=[];for(const e of c())for(const b of a)d.push([e].concat(b));return run_list_generators(d,b)}// http://erlang.org/doc/man/erlang.html +function atom_to_binary(a,b=Symbol.for('utf8')){if(b!==Symbol.for('utf8'))throw new Error(`unsupported encoding ${b}`);return a.__MODULE__?Symbol.keyFor(a.__MODULE__):Symbol.keyFor(a)}function binary_to_atom(a,b=Symbol.for('utf8')){if(b!==Symbol.for('utf8'))throw new Error(`unsupported encoding ${b}`);return Symbol.for(a)}function is_bitstring$1(a){return a instanceof e.BitString}function is_number$1(a){return'number'==typeof a||a instanceof Number}function is_integer(a){return b(a)}function is_binary(a){return'string'==typeof a||a instanceof String}function iolist_to_binary(b){if(is_binary(b))return b;if(is_bitstring$1(b))return a(...b.value);const c=b.reduce((b,c)=>{if(is_integer(c))return b+a(c);return is_bitstring$1(c)?b+a(...c.value):b+iolist_to_binary(c)},'');return c}function is_key(a,b){return b.has(a)}// http://erlang.org/doc/man/lists.html +function reverse(a){return[...a]}function flatten(a,b=[]){const c=a.reduce((a,b)=>{return Array.isArray(b)?a.concat(flatten(b)):a.concat(b)},[]);return c.concat(b)}function foldl(a,b,c){return c.reduce((b,c)=>{return a(c,b)},b)}function keyfind(a,b,c){for(const d of c)if(d.get(b-1)===a)return d;return!1}function keydelete(a,b,c){const d=[];let e=!1;for(let f=0;fBitString$1.integer(a));return new BitString$1(...d)}[Symbol.iterator](){return this.value[Symbol.iterator]()}toString(){var a,b='';for(a=0;a>'}process(a){let b=[];var c;for(c=0;cb?c.push(b):2048>b?c.push(192|b>>6,128|63&b):55296>b||57344<=b?c.push(224|b>>12,128|63&b>>6,128|63&b):(d++,b=65536+((1023&b)<<10|1023&a.charCodeAt(d)),c.push(240|b>>18,128|63&b>>12,128|63&b>>6,128|63&b));return c}static toUTF16Array(a){for(var b,c=[],d=0;d=b?(c.push(0),c.push(b)):(c.push(255&b>>8),c.push(255&b));return c}static toUTF32Array(a){for(var b,c=[],d=0;d=b?(c.push(0),c.push(0),c.push(0),c.push(b)):(c.push(0),c.push(0),c.push(255&b>>8),c.push(255&b));return c}//http://stackoverflow.com/questions/2003493/javascript-float-from-to-bits +static float32ToBytes(a){var b=[],c=new ArrayBuffer(4);new Float32Array(c)[0]=a;let d=new Uint32Array(c)[0];return b.push(255&d>>24),b.push(255&d>>16),b.push(255&d>>8),b.push(255&d),b}static float64ToBytes(a){var b=[],c=new ArrayBuffer(8);new Float64Array(c)[0]=a;var d=new Uint32Array(c)[0],e=new Uint32Array(c)[1];return b.push(255&e>>24),b.push(255&e>>16),b.push(255&e>>8),b.push(255&e),b.push(255&d>>24),b.push(255&d>>16),b.push(255&d>>8),b.push(255&d),b}}var e={Tuple,PID:class PID{constructor(){++c,this.id=c}toString(){return'PID#<0.'+this.id+'.0>'}},Reference:class Reference{constructor(){++d,this.id=d,this.ref=Symbol()}toString(){return'Ref#<0.0.0.'+this.id+'>'}},BitString:BitString$1};/* @flow */const f=e.BitString,g=new Map;g.set(Variable.prototype,function resolveVariable(a){return function(b,c){return null===a.name||a.name.startsWith('_')?c.push(b):c.push(namedVariableResult(a.name,b)),!0}}),g.set(Wildcard.prototype,resolveWildcard),g.set(HeadTail.prototype,function resolveHeadTail(){return function(a,b){if(!is_array(a)||2>a.length)return!1;const c=a[0],d=a.slice(1);return b.push(c),b.push(d),!0}}),g.set(StartsWith.prototype,function resolveStartsWith(a){const b=a.prefix;return function(a,c){return is_string(a)&&a.startsWith(b)&&(c.push(a.substring(b.length)),!0)}}),g.set(Capture.prototype,function resolveCapture(a){const b=buildMatch(a.value);return function(a,c){return!!b(a,c)&&(c.push(a),!0)}}),g.set(Bound.prototype,function resolveBound(a){return function(b){return typeof b==typeof a.value&&b===a.value}}),g.set(Type.prototype,function resolveType(a){return function(b,c){if(b instanceof a.type){const d=buildMatch(a.objPattern);return d(b,c)}return!1}}),g.set(BitStringMatch.prototype,function resolveBitString(a){let b=[];for(let c of a.values)if(is_variable(c.value)){let a=getSize(c.unit,c.size);fillArray(b,a)}else b=b.concat(new f(c).value);let c=a.values;return function(a,d){var e=String.fromCharCode;let g=null;if(!is_string(a)&&!(a instanceof f))return!1;g=is_string(a)?new f(f.binary(a)):a;let h=0;for(let f,j=0;jd.size)return!1;for(let a of c)if(!d.has(a)||!b.get(a)(d.get(a),e))return!1;return!0}}),g.set(Array.prototype,function resolveArray(a){const b=a.map((a)=>buildMatch(a));return function(c,d){return is_array(c)&&c.length==a.length&&c.every(function(a,e){return b[e](c[e],d)})}}),g.set(String.prototype,function resolveString(a){return function(b){return is_string(b)&&b===a}}),g.set(Boolean.prototype,function resolveBoolean(a){return function(b){return is_boolean(b)&&b===a}}),g.set(Function.prototype,function resolveFunction(a){return function(b){return is_function(b)&&b===a}}),g.set(Object.prototype,resolveObject);class MatchError extends Error{constructor(a){if(super(),'symbol'==typeof a)this.message='No match for: '+a.toString();else if(Array.isArray(a)){let b=a.map((a)=>{return null===a?'null':'undefined'==typeof a?'undefined':a.toString()});this.message='No match for: '+b}else this.message='No match for: '+a;this.stack=new Error().stack,this.name=this.constructor.name}}class Clause{constructor(a,b,c=()=>!0){this.pattern=buildMatch(a),this.arity=a.length,this.optionals=getOptionalValues(a),this.fn=b,this.guard=c}}const h=Symbol();// https://github.com/airportyh/protomorphism +class Protocol{constructor(a){function createFun(a){return function(...c){const d=c[0];let e=null;if(null===d&&this.hasImplementation(Symbol('null'))?e=this.registry.get(Symbol)[a]:b(d)&&this.hasImplementation(o.Integer)?e=this.registry.get(o.Integer)[a]:'number'==typeof d&&!b(d)&&this.hasImplementation(o.Float)?e=this.registry.get(o.Float)[a]:'string'==typeof d&&this.hasImplementation(o.BitString)?e=this.registry.get(o.BitString)[a]:d&&d.has(Symbol.for('__struct__'))&&this.hasImplementation(d)?e=this.registry.get(d.get(Symbol.for('__struct__')).__MODULE__)[a]:null!==d&&this.hasImplementation(d)?e=this.registry.get(d.constructor)[a]:this.fallback&&(e=this.fallback[a]),null!=e){const a=e.apply(this,c);return a}throw new Error(`No implementation found for ${d}`)}}for(const b in this.registry=new Map,this.fallback=null,a)this[b]=createFun(b).bind(this)}implementation(a,b){null===a?this.fallback=b:this.registry.set(a,b)}hasImplementation(a){if(a===o.Integer||a===o.Float||a===o.BitString)return this.registry.has(a);return a&&a.has(Symbol.for('__struct__'))?this.registry.has(a.get(Symbol.for('__struct__')).__MODULE__):this.registry.has(a.constructor)}}var i={atom_to_binary,binary_to_atom,binary_to_existing_atom:function binary_to_existing_atom(a,b=Symbol.for('utf8')){return binary_to_atom(a,b)},list_concatenation:function list_concatenation(a,b){return a.concat(b)},list_subtraction:function list_subtraction(a,b){const c=[...a];for(const d of b){const a=c.indexOf(d);-1b},greaterThanOrEqualTo:function greaterThanOrEqualTo(a,b){return a>=b},lessThan:function lessThan(a,b){return a>b},bxor:function bxor(a,b){return a^b},bnot:function bnot(a){return~a},is_bitstring:is_bitstring$1,is_boolean:function is_boolean$1(a){return'boolean'==typeof a||a instanceof Boolean},is_float:function is_float(a){return is_number$1(a)&&!b(a)},is_function:function is_function$1(a){return'function'==typeof a||a instanceof Function},is_integer,is_list:function is_list(a){return Array.isArray(a)},is_map:function is_map$1(a){return a instanceof Map},is_number:is_number$1,is_pid:function is_pid(a){return a instanceof e.PID},is_port:function is_port(){return!1},is_reference:function is_reference(a){return a instanceof e.Reference},is_tuple:function is_tuple(a){return a instanceof e.Tuple},is_atom:function is_atom(a){return'symbol'==typeof a||a instanceof Symbol||a.__MODULE__},is_binary,element:function element(a,b){return b.get(a-1)},setelement:function setelement(a,b,c){const d=[...b.values];return d[a-1]=c,new e.Tuple(...d)},make_tuple:function make_tuple(a,b){const c=[];for(let d=0;d!0){let d=[],e=buildMatch(a);const f=e(b,d),[g,h]=checkNamedVariables(d);if(f&&h&&c.apply(this,g))return g;throw console.error('No match for:',b),new MatchError(b)},MatchError,variable:function variable(a=null,b=Symbol.for('tailored.no_value')){return new Variable(a,b)},wildcard:function wildcard(){return new Wildcard},startsWith:function startsWith(a){return new StartsWith(a)},capture:function capture(a){return new Capture(a)},headTail:function headTail(){return new HeadTail},type:function a(a,b={}){return new Type(a,b)},bound:function bound(a){return new Bound(a)},Clause,clause:function clause(a,b,c=()=>!0){return new Clause(a,b,c)},bitStringMatch:function bitStringMatch(...a){return new BitStringMatch(...a)},match_or_default,defmatchgen,list_comprehension:function list_comprehension(a,b){const c=run_generators(b.pop()(),b);let d=[];for(let e of c)a.guard.apply(this,e)&&d.push(a.fn.apply(this,e));return d},list_generator:function list_generator(a,b){return function(){let c=[];for(let d of b){const b=match_or_default(a,d,()=>!0,h);if(b!=h){const[a]=b;c.push(a)}}return c}},bitstring_generator:function bitstring_generator(a,b){return function(){let c=[],d=b.slice(0,a.byte_size()),e=1;for(;d.byte_size==a.byte_size();){const f=match_or_default(a,d,()=>!0,h);if(f!=h){c.push(f)}d=b.slice(a.byte_size()*e,a.byte_size()*(e+1)),e++}return c}},bitstring_comprehension:function bitstring_comprehension(a,b){const c=run_generators(b.pop()(),b);let d=[];for(let e of c)a.guard.apply(this,e)&&d.push(a.fn.apply(this,e));return d=d.map((a)=>e.BitString.integer(a)),new e.BitString(...d)},defmatchGen:function defmatchGen(...a){return defmatchgen(...a)},defmatchAsync:function defmatchAsync(...a){const b=getArityMap(a);return async function(...a){if(b.has(a.length)){const c=b.get(a.length);let d=null,e=null;for(let b of c){let c=[];a=fillInOptionalValues(a,b.arity,b.optionals);const f=b.pattern(a,c),[g,h]=checkNamedVariables(c);if(f&&h&&(await b.guard.apply(this,c))){d=b.fn,e=c;break}}if(!d)throw console.error('No match for:',a),new MatchError(a);return d.apply(this,e)}throw console.error('Arity of',a.length,'not found. No match for:',a),new MatchError(a)}}},Integer:class Integer{},Float:class Float{},Functions:{call_property:function call_property(a,b){if(!b)return a instanceof Function||'function'==typeof a?a():a;if(a instanceof Map){let c=null;if(a.has(b)?c=b:a.has(Symbol.for(b))&&(c=Symbol.for(b)),null===c)throw new Error(`Property ${b} not found in ${a}`);return a.get(c)instanceof Function||'function'==typeof a.get(c)?a.get(c)():a.get(c)}let c=null;if('number'==typeof a||'symbol'==typeof a||'boolean'==typeof a||'string'==typeof a?void 0===a[b]?void 0!==a[Symbol.for(b)]&&(c=Symbol.for(b)):c=b:b in a?c=b:Symbol.for(b)in a&&(c=Symbol.for(b)),null===c)throw new Error(`Property ${b} not found in ${a}`);return a[c]instanceof Function||'function'==typeof a[c]?a[c]():a[c]},defprotocol:function defprotocol(a){return new Protocol(a)},defimpl:function defimpl(a,b,c){a.implementation(b,c)},build_namespace:function build_namespace(a,b){let c=b.split('.');const d=a;let e=a;'Elixir'===c[0]&&(c=c.slice(1));for(const d of c)'undefined'==typeof e[d]&&(e[d]={}),e=e[d];return d.__table__=a.__table__||{},d.__table__[Symbol.for(b)]=e,e},iterator_to_reducer,map_to_object},SpecialForms:{_case:function _case(a,b){return o.Patterns.defmatch(...b)(a)},cond:function cond(...a){for(const b of a)if(b[0])return b[1]();throw new Error},_for:function _for(a,b,c,d=[]){let[e,f]=c.into(d);const g=run_list_generators(b.pop()(),b);for(const h of g)a.guard.apply(this,h)&&(e=f(e,new o.Tuple(Symbol.for('cont'),a.fn.apply(this,h))));return f(e,Symbol.for('done'))},_try:function _try(a,b,c,d,e){let f=null;try{f=a()}catch(a){let d=null;if(b)try{return d=b(a),d}catch(a){if(a instanceof o.Patterns.MatchError)throw a}if(c)try{return d=c(a),d}catch(a){if(a instanceof o.Patterns.MatchError)throw a}throw a}finally{e&&e()}if(d)try{return d(f)}catch(a){if(a instanceof o.Patterns.MatchError)throw new Error('No Match Found in Else');throw a}else return f},_with:function _with(...a){let b=[],c=null,d=null;'function'==typeof a[a.length-2]?[c,d]=a.splice(-2):c=a.pop();for(let c=0;c{const[c,d]=b;return a.set(c,d),a},new Map)},keys:function keys(a){return!1===i.is_map(a)?new e.Tuple(l,a):Array.from(a.keys())},values:function values$1(a){return!1===i.is_map(a)?new e.Tuple(l,a):Array.from(a.values())},is_key,put:function put(a,b,c){if(!1===i.is_map(c))return new e.Tuple(l,c);const d=new Map(c);return d.set(a,b),d},merge:function merge(a,b){return!1===i.is_map(a)?new e.Tuple(l,a):!1===i.is_map(b)?new e.Tuple(l,b):new Map([...a,...b])},update:function update(a,b,c){return!1===i.is_map(c)?new e.Tuple(l,c):!1===is_key(a,c)?new e.Tuple(m,a):new Map([...c,[a,b]])},get:function get(...a){const b=a[0],c=a[1];return!1===i.is_map(c)?new e.Tuple(l,c):is_key(b)?c.get(b):3===a.length?a[2]:new e.Tuple(m,b)},take:function take(a,b){if(!1===i.is_map(b))return new e.Tuple(l,b);if(!is_key(a))return k;const c=b.get(a),d=new Map(b);return d.delete(a),new e.Tuple(c,d)}},lists:{reverse,foreach:function foreach(a,b){return b.forEach((b)=>a(b)),Symbol.for('ok')},duplicate:function duplicate(a,b){const c=[];for(;c.length{if(d.get(c-1)a.get(c-1)?1:0})},keystore:function keystore(a,b,c,d){const e=[...c];for(let f=0;fa.toString()).join()},map:function map(a,b){return b.map((b)=>a(b))},filter:function filter(a,b){return b.filter((b)=>a(b))},filtermap:function filtermap(a,b){const c=[];for(const d of b){const b=a(d);!0===b?c.push(d):b instanceof e.Tuple&&!0===b.get(0)&&c.push(b.get(1))}return c},member:function member(a,b){for(const c of b)if(c===a)return!0;return!1},all:function all(a,b){for(const c of b)if(!1===a(c))return!1;return!0},any:function any(a,b){for(const c of b)if(!0===a(c))return!0;return!1},splitwith:function splitwith(a,b){let c=!1;const d=[],f=[];for(const e of b)!0==c?f.push(e):!0===a(e)?d.push(e):(c=!0,f.push(e));return new e.Tuple(d,f)},sort:function sort(...a){if(1===a.length){const b=[...a[0]];return b.sort()}const c=a[0],b=[...a[1]];return b.sort((d,a)=>{const b=c(d,a);return!0===b?-1:1})}},elixir_errors:{warn:function warn(a){const b=a.join('');return console.warn(`warning: ${b}`),Symbol.for('ok')}},io:{put_chars:function put_chars(b,c){let d=null;return d=Array.isArray(c)?a(...c):c,b===Symbol.for('stderr')?console.error(d):console.log(d),Symbol.for('ok')}}};return{Core:o}}(); diff --git a/src/javascript/lib/core.js b/src/javascript/lib/core.js index f0e5277f..d2677323 100644 --- a/src/javascript/lib/core.js +++ b/src/javascript/lib/core.js @@ -6,6 +6,7 @@ import erlang from './core/erlang_compat/erlang'; import maps from './core/erlang_compat/maps'; import lists from './core/erlang_compat/lists'; import elixir_errors from './core/erlang_compat/elixir_errors'; +import io from './core/erlang_compat/io'; import Store from './core/store'; class Integer {} @@ -43,5 +44,6 @@ export default { erlang, maps, lists, - elixir_errors + elixir_errors, + io }; diff --git a/src/javascript/lib/core/erlang_compat/io.js b/src/javascript/lib/core/erlang_compat/io.js new file mode 100644 index 00000000..9d7eccb3 --- /dev/null +++ b/src/javascript/lib/core/erlang_compat/io.js @@ -0,0 +1,21 @@ +function put_chars(ioDevice, charData) { + let dataToWrite = null; + + if (Array.isArray(charData)) { + dataToWrite = String.fromCodePoint(...charData); + } else { + dataToWrite = charData; + } + + if (ioDevice === Symbol.for('stderr')) { + console.error(dataToWrite); + } else { + console.log(dataToWrite); + } + + return Symbol.for('ok'); +} + +export default { + put_chars +}; From ba2b4d3f6eea02f9f7e4bcca5dbd24dece147d15 Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Fri, 21 Jul 2017 21:10:55 -0500 Subject: [PATCH 190/418] Updated find_used_functions to walk super calls Added integer_to_binary to erlang.js --- lib/elixir_script/passes/find_used_functions.ex | 3 ++- lib/elixir_script/passes/find_used_modules.ex | 2 +- lib/elixir_script/passes/translate/form.ex | 6 ++++++ priv/build/iife/ElixirScript.Core.js | 2 +- src/javascript/lib/core/erlang_compat/erlang.js | 7 ++++++- 5 files changed, 16 insertions(+), 4 deletions(-) diff --git a/lib/elixir_script/passes/find_used_functions.ex b/lib/elixir_script/passes/find_used_functions.ex index b7ffdcf6..c77cddcc 100644 --- a/lib/elixir_script/passes/find_used_functions.ex +++ b/lib/elixir_script/passes/find_used_functions.ex @@ -264,7 +264,8 @@ defmodule ElixirScript.FindUsedFunctions do walk(params, state) end - defp walk({:super, _, params}, state) do + defp walk({:super, _, [{_, function} | params]}, state) do + walk_module(state.module, function, length(params), state.pid) walk(params, state) end diff --git a/lib/elixir_script/passes/find_used_modules.ex b/lib/elixir_script/passes/find_used_modules.ex index b7ebddc7..ee65f7a0 100644 --- a/lib/elixir_script/passes/find_used_modules.ex +++ b/lib/elixir_script/passes/find_used_modules.ex @@ -286,7 +286,7 @@ defmodule ElixirScript.FindUsedModules do end end - defp walk({:super, _, params}, state) do + defp walk({:super, _, [{_, _} | params]}, state) do walk(params, state) end diff --git a/lib/elixir_script/passes/translate/form.ex b/lib/elixir_script/passes/translate/form.ex index 70e2af99..f8d6eeaa 100644 --- a/lib/elixir_script/passes/translate/form.ex +++ b/lib/elixir_script/passes/translate/form.ex @@ -286,6 +286,12 @@ defmodule ElixirScript.Translate.Form do end end + def compile({:default, _, _}, state) do + var = :__default__ + var = Pattern.get_variable_name(to_string(var), state) + { ElixirScript.Translate.Identifier.make_identifier(var), state } + end + def compile({var, _, _}, state) do var = Pattern.get_variable_name(to_string(var), state) { ElixirScript.Translate.Identifier.make_identifier(var), state } diff --git a/priv/build/iife/ElixirScript.Core.js b/priv/build/iife/ElixirScript.Core.js index a076e953..2a8420a5 100644 --- a/priv/build/iife/ElixirScript.Core.js +++ b/priv/build/iife/ElixirScript.Core.js @@ -2,5 +2,5 @@ var ElixirScript=function(){'use strict';/* @flow */function namedVariableResult function atom_to_binary(a,b=Symbol.for('utf8')){if(b!==Symbol.for('utf8'))throw new Error(`unsupported encoding ${b}`);return a.__MODULE__?Symbol.keyFor(a.__MODULE__):Symbol.keyFor(a)}function binary_to_atom(a,b=Symbol.for('utf8')){if(b!==Symbol.for('utf8'))throw new Error(`unsupported encoding ${b}`);return Symbol.for(a)}function is_bitstring$1(a){return a instanceof e.BitString}function is_number$1(a){return'number'==typeof a||a instanceof Number}function is_integer(a){return b(a)}function is_binary(a){return'string'==typeof a||a instanceof String}function iolist_to_binary(b){if(is_binary(b))return b;if(is_bitstring$1(b))return a(...b.value);const c=b.reduce((b,c)=>{if(is_integer(c))return b+a(c);return is_bitstring$1(c)?b+a(...c.value):b+iolist_to_binary(c)},'');return c}function is_key(a,b){return b.has(a)}// http://erlang.org/doc/man/lists.html function reverse(a){return[...a]}function flatten(a,b=[]){const c=a.reduce((a,b)=>{return Array.isArray(b)?a.concat(flatten(b)):a.concat(b)},[]);return c.concat(b)}function foldl(a,b,c){return c.reduce((b,c)=>{return a(c,b)},b)}function keyfind(a,b,c){for(const d of c)if(d.get(b-1)===a)return d;return!1}function keydelete(a,b,c){const d=[];let e=!1;for(let f=0;fBitString$1.integer(a));return new BitString$1(...d)}[Symbol.iterator](){return this.value[Symbol.iterator]()}toString(){var a,b='';for(a=0;a>'}process(a){let b=[];var c;for(c=0;cb?c.push(b):2048>b?c.push(192|b>>6,128|63&b):55296>b||57344<=b?c.push(224|b>>12,128|63&b>>6,128|63&b):(d++,b=65536+((1023&b)<<10|1023&a.charCodeAt(d)),c.push(240|b>>18,128|63&b>>12,128|63&b>>6,128|63&b));return c}static toUTF16Array(a){for(var b,c=[],d=0;d=b?(c.push(0),c.push(b)):(c.push(255&b>>8),c.push(255&b));return c}static toUTF32Array(a){for(var b,c=[],d=0;d=b?(c.push(0),c.push(0),c.push(0),c.push(b)):(c.push(0),c.push(0),c.push(255&b>>8),c.push(255&b));return c}//http://stackoverflow.com/questions/2003493/javascript-float-from-to-bits static float32ToBytes(a){var b=[],c=new ArrayBuffer(4);new Float32Array(c)[0]=a;let d=new Uint32Array(c)[0];return b.push(255&d>>24),b.push(255&d>>16),b.push(255&d>>8),b.push(255&d),b}static float64ToBytes(a){var b=[],c=new ArrayBuffer(8);new Float64Array(c)[0]=a;var d=new Uint32Array(c)[0],e=new Uint32Array(c)[1];return b.push(255&e>>24),b.push(255&e>>16),b.push(255&e>>8),b.push(255&e),b.push(255&d>>24),b.push(255&d>>16),b.push(255&d>>8),b.push(255&d),b}}var e={Tuple,PID:class PID{constructor(){++c,this.id=c}toString(){return'PID#<0.'+this.id+'.0>'}},Reference:class Reference{constructor(){++d,this.id=d,this.ref=Symbol()}toString(){return'Ref#<0.0.0.'+this.id+'>'}},BitString:BitString$1};/* @flow */const f=e.BitString,g=new Map;g.set(Variable.prototype,function resolveVariable(a){return function(b,c){return null===a.name||a.name.startsWith('_')?c.push(b):c.push(namedVariableResult(a.name,b)),!0}}),g.set(Wildcard.prototype,resolveWildcard),g.set(HeadTail.prototype,function resolveHeadTail(){return function(a,b){if(!is_array(a)||2>a.length)return!1;const c=a[0],d=a.slice(1);return b.push(c),b.push(d),!0}}),g.set(StartsWith.prototype,function resolveStartsWith(a){const b=a.prefix;return function(a,c){return is_string(a)&&a.startsWith(b)&&(c.push(a.substring(b.length)),!0)}}),g.set(Capture.prototype,function resolveCapture(a){const b=buildMatch(a.value);return function(a,c){return!!b(a,c)&&(c.push(a),!0)}}),g.set(Bound.prototype,function resolveBound(a){return function(b){return typeof b==typeof a.value&&b===a.value}}),g.set(Type.prototype,function resolveType(a){return function(b,c){if(b instanceof a.type){const d=buildMatch(a.objPattern);return d(b,c)}return!1}}),g.set(BitStringMatch.prototype,function resolveBitString(a){let b=[];for(let c of a.values)if(is_variable(c.value)){let a=getSize(c.unit,c.size);fillArray(b,a)}else b=b.concat(new f(c).value);let c=a.values;return function(a,d){var e=String.fromCharCode;let g=null;if(!is_string(a)&&!(a instanceof f))return!1;g=is_string(a)?new f(f.binary(a)):a;let h=0;for(let f,j=0;jd.size)return!1;for(let a of c)if(!d.has(a)||!b.get(a)(d.get(a),e))return!1;return!0}}),g.set(Array.prototype,function resolveArray(a){const b=a.map((a)=>buildMatch(a));return function(c,d){return is_array(c)&&c.length==a.length&&c.every(function(a,e){return b[e](c[e],d)})}}),g.set(String.prototype,function resolveString(a){return function(b){return is_string(b)&&b===a}}),g.set(Boolean.prototype,function resolveBoolean(a){return function(b){return is_boolean(b)&&b===a}}),g.set(Function.prototype,function resolveFunction(a){return function(b){return is_function(b)&&b===a}}),g.set(Object.prototype,resolveObject);class MatchError extends Error{constructor(a){if(super(),'symbol'==typeof a)this.message='No match for: '+a.toString();else if(Array.isArray(a)){let b=a.map((a)=>{return null===a?'null':'undefined'==typeof a?'undefined':a.toString()});this.message='No match for: '+b}else this.message='No match for: '+a;this.stack=new Error().stack,this.name=this.constructor.name}}class Clause{constructor(a,b,c=()=>!0){this.pattern=buildMatch(a),this.arity=a.length,this.optionals=getOptionalValues(a),this.fn=b,this.guard=c}}const h=Symbol();// https://github.com/airportyh/protomorphism -class Protocol{constructor(a){function createFun(a){return function(...c){const d=c[0];let e=null;if(null===d&&this.hasImplementation(Symbol('null'))?e=this.registry.get(Symbol)[a]:b(d)&&this.hasImplementation(o.Integer)?e=this.registry.get(o.Integer)[a]:'number'==typeof d&&!b(d)&&this.hasImplementation(o.Float)?e=this.registry.get(o.Float)[a]:'string'==typeof d&&this.hasImplementation(o.BitString)?e=this.registry.get(o.BitString)[a]:d&&d.has(Symbol.for('__struct__'))&&this.hasImplementation(d)?e=this.registry.get(d.get(Symbol.for('__struct__')).__MODULE__)[a]:null!==d&&this.hasImplementation(d)?e=this.registry.get(d.constructor)[a]:this.fallback&&(e=this.fallback[a]),null!=e){const a=e.apply(this,c);return a}throw new Error(`No implementation found for ${d}`)}}for(const b in this.registry=new Map,this.fallback=null,a)this[b]=createFun(b).bind(this)}implementation(a,b){null===a?this.fallback=b:this.registry.set(a,b)}hasImplementation(a){if(a===o.Integer||a===o.Float||a===o.BitString)return this.registry.has(a);return a&&a.has(Symbol.for('__struct__'))?this.registry.has(a.get(Symbol.for('__struct__')).__MODULE__):this.registry.has(a.constructor)}}var i={atom_to_binary,binary_to_atom,binary_to_existing_atom:function binary_to_existing_atom(a,b=Symbol.for('utf8')){return binary_to_atom(a,b)},list_concatenation:function list_concatenation(a,b){return a.concat(b)},list_subtraction:function list_subtraction(a,b){const c=[...a];for(const d of b){const a=c.indexOf(d);-1b},greaterThanOrEqualTo:function greaterThanOrEqualTo(a,b){return a>=b},lessThan:function lessThan(a,b){return a>b},bxor:function bxor(a,b){return a^b},bnot:function bnot(a){return~a},is_bitstring:is_bitstring$1,is_boolean:function is_boolean$1(a){return'boolean'==typeof a||a instanceof Boolean},is_float:function is_float(a){return is_number$1(a)&&!b(a)},is_function:function is_function$1(a){return'function'==typeof a||a instanceof Function},is_integer,is_list:function is_list(a){return Array.isArray(a)},is_map:function is_map$1(a){return a instanceof Map},is_number:is_number$1,is_pid:function is_pid(a){return a instanceof e.PID},is_port:function is_port(){return!1},is_reference:function is_reference(a){return a instanceof e.Reference},is_tuple:function is_tuple(a){return a instanceof e.Tuple},is_atom:function is_atom(a){return'symbol'==typeof a||a instanceof Symbol||a.__MODULE__},is_binary,element:function element(a,b){return b.get(a-1)},setelement:function setelement(a,b,c){const d=[...b.values];return d[a-1]=c,new e.Tuple(...d)},make_tuple:function make_tuple(a,b){const c=[];for(let d=0;db},greaterThanOrEqualTo:function greaterThanOrEqualTo(a,b){return a>=b},lessThan:function lessThan(a,b){return a>b},bxor:function bxor(a,b){return a^b},bnot:function bnot(a){return~a},is_bitstring:is_bitstring$1,is_boolean:function is_boolean$1(a){return'boolean'==typeof a||a instanceof Boolean},is_float:function is_float(a){return is_number$1(a)&&!b(a)},is_function:function is_function$1(a){return'function'==typeof a||a instanceof Function},is_integer,is_list:function is_list(a){return Array.isArray(a)},is_map:function is_map$1(a){return a instanceof Map},is_number:is_number$1,is_pid:function is_pid(a){return a instanceof e.PID},is_port:function is_port(){return!1},is_reference:function is_reference(a){return a instanceof e.Reference},is_tuple:function is_tuple(a){return a instanceof e.Tuple},is_atom:function is_atom(a){return'symbol'==typeof a||a instanceof Symbol||a.__MODULE__},is_binary,element:function element(a,b){return b.get(a-1)},setelement:function setelement(a,b,c){const d=[...b.values];return d[a-1]=c,new e.Tuple(...d)},make_tuple:function make_tuple(a,b){const c=[];for(let d=0;d!0){let d=[],e=buildMatch(a);const f=e(b,d),[g,h]=checkNamedVariables(d);if(f&&h&&c.apply(this,g))return g;throw console.error('No match for:',b),new MatchError(b)},MatchError,variable:function variable(a=null,b=Symbol.for('tailored.no_value')){return new Variable(a,b)},wildcard:function wildcard(){return new Wildcard},startsWith:function startsWith(a){return new StartsWith(a)},capture:function capture(a){return new Capture(a)},headTail:function headTail(){return new HeadTail},type:function a(a,b={}){return new Type(a,b)},bound:function bound(a){return new Bound(a)},Clause,clause:function clause(a,b,c=()=>!0){return new Clause(a,b,c)},bitStringMatch:function bitStringMatch(...a){return new BitStringMatch(...a)},match_or_default,defmatchgen,list_comprehension:function list_comprehension(a,b){const c=run_generators(b.pop()(),b);let d=[];for(let e of c)a.guard.apply(this,e)&&d.push(a.fn.apply(this,e));return d},list_generator:function list_generator(a,b){return function(){let c=[];for(let d of b){const b=match_or_default(a,d,()=>!0,h);if(b!=h){const[a]=b;c.push(a)}}return c}},bitstring_generator:function bitstring_generator(a,b){return function(){let c=[],d=b.slice(0,a.byte_size()),e=1;for(;d.byte_size==a.byte_size();){const f=match_or_default(a,d,()=>!0,h);if(f!=h){c.push(f)}d=b.slice(a.byte_size()*e,a.byte_size()*(e+1)),e++}return c}},bitstring_comprehension:function bitstring_comprehension(a,b){const c=run_generators(b.pop()(),b);let d=[];for(let e of c)a.guard.apply(this,e)&&d.push(a.fn.apply(this,e));return d=d.map((a)=>e.BitString.integer(a)),new e.BitString(...d)},defmatchGen:function defmatchGen(...a){return defmatchgen(...a)},defmatchAsync:function defmatchAsync(...a){const b=getArityMap(a);return async function(...a){if(b.has(a.length)){const c=b.get(a.length);let d=null,e=null;for(let b of c){let c=[];a=fillInOptionalValues(a,b.arity,b.optionals);const f=b.pattern(a,c),[g,h]=checkNamedVariables(c);if(f&&h&&(await b.guard.apply(this,c))){d=b.fn,e=c;break}}if(!d)throw console.error('No match for:',a),new MatchError(a);return d.apply(this,e)}throw console.error('Arity of',a.length,'not found. No match for:',a),new MatchError(a)}}},Integer:class Integer{},Float:class Float{},Functions:{call_property:function call_property(a,b){if(!b)return a instanceof Function||'function'==typeof a?a():a;if(a instanceof Map){let c=null;if(a.has(b)?c=b:a.has(Symbol.for(b))&&(c=Symbol.for(b)),null===c)throw new Error(`Property ${b} not found in ${a}`);return a.get(c)instanceof Function||'function'==typeof a.get(c)?a.get(c)():a.get(c)}let c=null;if('number'==typeof a||'symbol'==typeof a||'boolean'==typeof a||'string'==typeof a?void 0===a[b]?void 0!==a[Symbol.for(b)]&&(c=Symbol.for(b)):c=b:b in a?c=b:Symbol.for(b)in a&&(c=Symbol.for(b)),null===c)throw new Error(`Property ${b} not found in ${a}`);return a[c]instanceof Function||'function'==typeof a[c]?a[c]():a[c]},defprotocol:function defprotocol(a){return new Protocol(a)},defimpl:function defimpl(a,b,c){a.implementation(b,c)},build_namespace:function build_namespace(a,b){let c=b.split('.');const d=a;let e=a;'Elixir'===c[0]&&(c=c.slice(1));for(const d of c)'undefined'==typeof e[d]&&(e[d]={}),e=e[d];return d.__table__=a.__table__||{},d.__table__[Symbol.for(b)]=e,e},iterator_to_reducer,map_to_object},SpecialForms:{_case:function _case(a,b){return o.Patterns.defmatch(...b)(a)},cond:function cond(...a){for(const b of a)if(b[0])return b[1]();throw new Error},_for:function _for(a,b,c,d=[]){let[e,f]=c.into(d);const g=run_list_generators(b.pop()(),b);for(const h of g)a.guard.apply(this,h)&&(e=f(e,new o.Tuple(Symbol.for('cont'),a.fn.apply(this,h))));return f(e,Symbol.for('done'))},_try:function _try(a,b,c,d,e){let f=null;try{f=a()}catch(a){let d=null;if(b)try{return d=b(a),d}catch(a){if(a instanceof o.Patterns.MatchError)throw a}if(c)try{return d=c(a),d}catch(a){if(a instanceof o.Patterns.MatchError)throw a}throw a}finally{e&&e()}if(d)try{return d(f)}catch(a){if(a instanceof o.Patterns.MatchError)throw new Error('No Match Found in Else');throw a}else return f},_with:function _with(...a){let b=[],c=null,d=null;'function'==typeof a[a.length-2]?[c,d]=a.splice(-2):c=a.pop();for(let c=0;c{const[c,d]=b;return a.set(c,d),a},new Map)},keys:function keys(a){return!1===i.is_map(a)?new e.Tuple(l,a):Array.from(a.keys())},values:function values$1(a){return!1===i.is_map(a)?new e.Tuple(l,a):Array.from(a.values())},is_key,put:function put(a,b,c){if(!1===i.is_map(c))return new e.Tuple(l,c);const d=new Map(c);return d.set(a,b),d},merge:function merge(a,b){return!1===i.is_map(a)?new e.Tuple(l,a):!1===i.is_map(b)?new e.Tuple(l,b):new Map([...a,...b])},update:function update(a,b,c){return!1===i.is_map(c)?new e.Tuple(l,c):!1===is_key(a,c)?new e.Tuple(m,a):new Map([...c,[a,b]])},get:function get(...a){const b=a[0],c=a[1];return!1===i.is_map(c)?new e.Tuple(l,c):is_key(b)?c.get(b):3===a.length?a[2]:new e.Tuple(m,b)},take:function take(a,b){if(!1===i.is_map(b))return new e.Tuple(l,b);if(!is_key(a))return k;const c=b.get(a),d=new Map(b);return d.delete(a),new e.Tuple(c,d)}},lists:{reverse,foreach:function foreach(a,b){return b.forEach((b)=>a(b)),Symbol.for('ok')},duplicate:function duplicate(a,b){const c=[];for(;c.length{if(d.get(c-1)a.get(c-1)?1:0})},keystore:function keystore(a,b,c,d){const e=[...c];for(let f=0;fa.toString()).join()},map:function map(a,b){return b.map((b)=>a(b))},filter:function filter(a,b){return b.filter((b)=>a(b))},filtermap:function filtermap(a,b){const c=[];for(const d of b){const b=a(d);!0===b?c.push(d):b instanceof e.Tuple&&!0===b.get(0)&&c.push(b.get(1))}return c},member:function member(a,b){for(const c of b)if(c===a)return!0;return!1},all:function all(a,b){for(const c of b)if(!1===a(c))return!1;return!0},any:function any(a,b){for(const c of b)if(!0===a(c))return!0;return!1},splitwith:function splitwith(a,b){let c=!1;const d=[],f=[];for(const e of b)!0==c?f.push(e):!0===a(e)?d.push(e):(c=!0,f.push(e));return new e.Tuple(d,f)},sort:function sort(...a){if(1===a.length){const b=[...a[0]];return b.sort()}const c=a[0],b=[...a[1]];return b.sort((d,a)=>{const b=c(d,a);return!0===b?-1:1})}},elixir_errors:{warn:function warn(a){const b=a.join('');return console.warn(`warning: ${b}`),Symbol.for('ok')}},io:{put_chars:function put_chars(b,c){let d=null;return d=Array.isArray(c)?a(...c):c,b===Symbol.for('stderr')?console.error(d):console.log(d),Symbol.for('ok')}}};return{Core:o}}(); diff --git a/src/javascript/lib/core/erlang_compat/erlang.js b/src/javascript/lib/core/erlang_compat/erlang.js index 74c34ccf..69c0a4c7 100644 --- a/src/javascript/lib/core/erlang_compat/erlang.js +++ b/src/javascript/lib/core/erlang_compat/erlang.js @@ -355,6 +355,10 @@ function io_size(ioListOrBinary) { return iolist_to_binary(ioListOrBinary).length; } +function integer_to_binary(integer, base = 10) { + return integer.toString(base); +} + export default { atom_to_binary, binary_to_atom, @@ -423,5 +427,6 @@ export default { binary_to_integer, process_info, iolist_to_binary, - io_size + io_size, + integer_to_binary }; From fae3337f44787c08c8e9fe3f6bf3084c3a749c67 Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Fri, 21 Jul 2017 21:36:23 -0500 Subject: [PATCH 191/418] Translate erlang binary and unary operators to javascript one --- lib/elixir_script/passes/translate/form.ex | 80 +++++++++++++++++++ .../passes/translate/forms/remote.ex | 70 ---------------- priv/build/iife/ElixirScript.Core.js | 2 +- .../lib/core/erlang_compat/erlang.js | 73 ----------------- 4 files changed, 81 insertions(+), 144 deletions(-) diff --git a/lib/elixir_script/passes/translate/form.ex b/lib/elixir_script/passes/translate/form.ex index f8d6eeaa..1ba9b7ff 100644 --- a/lib/elixir_script/passes/translate/form.ex +++ b/lib/elixir_script/passes/translate/form.ex @@ -211,6 +211,86 @@ defmodule ElixirScript.Translate.Form do ElixirScript.Translate.Function.compile(ast, state) end + def compile({{:., _, [:erlang, op]}, _, [item]}, state) when op in [:+, :-] do + ast = J.unary_expression( + op, + true, + compile!(item, state) + ) + + {ast, state} + end + + def compile({{:., _, [:erlang, op]}, _, [left, right]}, state) when op in [:+, :-, :*, :/, :==, :>, :<, :>=] do + ast = J.binary_expression( + op, + compile!(left, state), + compile!(right, state) + ) + + {ast, state} + end + + def compile({{:., _, [:erlang, :"=<"]}, _, [left, right]}, state) do + ast = J.binary_expression( + :<=, + compile!(left, state), + compile!(right, state) + ) + + {ast, state} + end + + def compile({{:., _, [:erlang, :"=:="]}, _, [left, right]}, state) do + ast = J.binary_expression( + :===, + compile!(left, state), + compile!(right, state) + ) + + {ast, state} + end + + def compile({{:., _, [:erlang, :"=/="]}, _, [left, right]}, state) do + ast = J.binary_expression( + :!==, + compile!(left, state), + compile!(right, state) + ) + + {ast, state} + end + + def compile({{:., _, [:erlang, :"/="]}, _, [left, right]}, state) do + ast = J.binary_expression( + :!=, + compile!(left, state), + compile!(right, state) + ) + + {ast, state} + end + + def compile({{:., _, [:erlang, op]}, _, [left, right]}, state) when op in [:andalso, :and] do + ast = J.binary_expression( + :&&, + compile!(left, state), + compile!(right, state) + ) + + {ast, state} + end + + def compile({{:., _, [:erlang, op]}, _, [left, right]}, state) when op in [:orelse, :or] do + ast = J.binary_expression( + :||, + compile!(left, state), + compile!(right, state) + ) + + {ast, state} + end + def compile({{:., _, [{_, _, nil} = var, func_or_prop]}, _, []}, state) do ast = J.call_expression( ElixirScript.Translate.Forms.JS.call_property(), diff --git a/lib/elixir_script/passes/translate/forms/remote.ex b/lib/elixir_script/passes/translate/forms/remote.ex index 38c2acc1..fe8590ad 100644 --- a/lib/elixir_script/passes/translate/forms/remote.ex +++ b/lib/elixir_script/passes/translate/forms/remote.ex @@ -27,76 +27,6 @@ defmodule ElixirScript.Translate.Forms.Remote do erlang functions into JavaScript functions. """ - def compile({:., _, [:erlang, :+]}, state) do - ast = erlang_compat_function("erlang", "plus") - { ast, state } - end - - def compile({:., _, [:erlang, :-]}, state) do - ast = erlang_compat_function("erlang", "minus") - { ast, state } - end - - def compile({:., _, [:erlang, :*]}, state) do - ast = erlang_compat_function("erlang", "multiply") - { ast, state } - end - - def compile({:., _, [:erlang, :/]}, state) do - ast = erlang_compat_function("erlang", "div") - { ast, state } - end - - def compile({:., _, [:erlang, :==]}, state) do - ast = erlang_compat_function("erlang", "equal") - { ast, state } - end - - def compile({:., _, [:erlang, :>]}, state) do - ast = erlang_compat_function("erlang", "greaterThan") - { ast, state } - end - - def compile({:., _, [:erlang, :>=]}, state) do - ast = erlang_compat_function("erlang", "greaterThanOrEqualTo") - { ast, state } - end - - def compile({:., _, [:erlang, :"/="]}, state) do - ast = erlang_compat_function("erlang", "doesNotEqual") - { ast, state } - end - - def compile({:., _, [:erlang, :"<"]}, state) do - ast = erlang_compat_function("erlang", "lessThan") - { ast, state } - end - - def compile({:., _, [:erlang, :"=<"]}, state) do - ast = erlang_compat_function("erlang", "lessThanOrEqualTo") - { ast, state } - end - - def compile({:., _, [:erlang, :"=:="]}, state) do - ast = erlang_compat_function("erlang", "strictlyEqual") - { ast, state } - end - - def compile({:., _, [:erlang, :"=/="]}, state) do - ast = erlang_compat_function("erlang", "doesNotStrictlyEqual") - { ast, state } - end - - def compile({:., _, [:erlang, function]}, state) when function in [:andalso, :and] do - ast = erlang_compat_function("erlang", "and") - { ast, state } - end - - def compile({:., _, [:erlang, function]}, state) when function in [:orelse, :or] do - ast = erlang_compat_function("erlang", "or") - { ast, state } - end - def compile({:., _, [:erlang, :++]}, state) do ast = erlang_compat_function("erlang", "list_concatenation") { ast, state } diff --git a/priv/build/iife/ElixirScript.Core.js b/priv/build/iife/ElixirScript.Core.js index 2a8420a5..31cff94d 100644 --- a/priv/build/iife/ElixirScript.Core.js +++ b/priv/build/iife/ElixirScript.Core.js @@ -2,5 +2,5 @@ var ElixirScript=function(){'use strict';/* @flow */function namedVariableResult function atom_to_binary(a,b=Symbol.for('utf8')){if(b!==Symbol.for('utf8'))throw new Error(`unsupported encoding ${b}`);return a.__MODULE__?Symbol.keyFor(a.__MODULE__):Symbol.keyFor(a)}function binary_to_atom(a,b=Symbol.for('utf8')){if(b!==Symbol.for('utf8'))throw new Error(`unsupported encoding ${b}`);return Symbol.for(a)}function is_bitstring$1(a){return a instanceof e.BitString}function is_number$1(a){return'number'==typeof a||a instanceof Number}function is_integer(a){return b(a)}function is_binary(a){return'string'==typeof a||a instanceof String}function iolist_to_binary(b){if(is_binary(b))return b;if(is_bitstring$1(b))return a(...b.value);const c=b.reduce((b,c)=>{if(is_integer(c))return b+a(c);return is_bitstring$1(c)?b+a(...c.value):b+iolist_to_binary(c)},'');return c}function is_key(a,b){return b.has(a)}// http://erlang.org/doc/man/lists.html function reverse(a){return[...a]}function flatten(a,b=[]){const c=a.reduce((a,b)=>{return Array.isArray(b)?a.concat(flatten(b)):a.concat(b)},[]);return c.concat(b)}function foldl(a,b,c){return c.reduce((b,c)=>{return a(c,b)},b)}function keyfind(a,b,c){for(const d of c)if(d.get(b-1)===a)return d;return!1}function keydelete(a,b,c){const d=[];let e=!1;for(let f=0;fBitString$1.integer(a));return new BitString$1(...d)}[Symbol.iterator](){return this.value[Symbol.iterator]()}toString(){var a,b='';for(a=0;a>'}process(a){let b=[];var c;for(c=0;cb?c.push(b):2048>b?c.push(192|b>>6,128|63&b):55296>b||57344<=b?c.push(224|b>>12,128|63&b>>6,128|63&b):(d++,b=65536+((1023&b)<<10|1023&a.charCodeAt(d)),c.push(240|b>>18,128|63&b>>12,128|63&b>>6,128|63&b));return c}static toUTF16Array(a){for(var b,c=[],d=0;d=b?(c.push(0),c.push(b)):(c.push(255&b>>8),c.push(255&b));return c}static toUTF32Array(a){for(var b,c=[],d=0;d=b?(c.push(0),c.push(0),c.push(0),c.push(b)):(c.push(0),c.push(0),c.push(255&b>>8),c.push(255&b));return c}//http://stackoverflow.com/questions/2003493/javascript-float-from-to-bits static float32ToBytes(a){var b=[],c=new ArrayBuffer(4);new Float32Array(c)[0]=a;let d=new Uint32Array(c)[0];return b.push(255&d>>24),b.push(255&d>>16),b.push(255&d>>8),b.push(255&d),b}static float64ToBytes(a){var b=[],c=new ArrayBuffer(8);new Float64Array(c)[0]=a;var d=new Uint32Array(c)[0],e=new Uint32Array(c)[1];return b.push(255&e>>24),b.push(255&e>>16),b.push(255&e>>8),b.push(255&e),b.push(255&d>>24),b.push(255&d>>16),b.push(255&d>>8),b.push(255&d),b}}var e={Tuple,PID:class PID{constructor(){++c,this.id=c}toString(){return'PID#<0.'+this.id+'.0>'}},Reference:class Reference{constructor(){++d,this.id=d,this.ref=Symbol()}toString(){return'Ref#<0.0.0.'+this.id+'>'}},BitString:BitString$1};/* @flow */const f=e.BitString,g=new Map;g.set(Variable.prototype,function resolveVariable(a){return function(b,c){return null===a.name||a.name.startsWith('_')?c.push(b):c.push(namedVariableResult(a.name,b)),!0}}),g.set(Wildcard.prototype,resolveWildcard),g.set(HeadTail.prototype,function resolveHeadTail(){return function(a,b){if(!is_array(a)||2>a.length)return!1;const c=a[0],d=a.slice(1);return b.push(c),b.push(d),!0}}),g.set(StartsWith.prototype,function resolveStartsWith(a){const b=a.prefix;return function(a,c){return is_string(a)&&a.startsWith(b)&&(c.push(a.substring(b.length)),!0)}}),g.set(Capture.prototype,function resolveCapture(a){const b=buildMatch(a.value);return function(a,c){return!!b(a,c)&&(c.push(a),!0)}}),g.set(Bound.prototype,function resolveBound(a){return function(b){return typeof b==typeof a.value&&b===a.value}}),g.set(Type.prototype,function resolveType(a){return function(b,c){if(b instanceof a.type){const d=buildMatch(a.objPattern);return d(b,c)}return!1}}),g.set(BitStringMatch.prototype,function resolveBitString(a){let b=[];for(let c of a.values)if(is_variable(c.value)){let a=getSize(c.unit,c.size);fillArray(b,a)}else b=b.concat(new f(c).value);let c=a.values;return function(a,d){var e=String.fromCharCode;let g=null;if(!is_string(a)&&!(a instanceof f))return!1;g=is_string(a)?new f(f.binary(a)):a;let h=0;for(let f,j=0;jd.size)return!1;for(let a of c)if(!d.has(a)||!b.get(a)(d.get(a),e))return!1;return!0}}),g.set(Array.prototype,function resolveArray(a){const b=a.map((a)=>buildMatch(a));return function(c,d){return is_array(c)&&c.length==a.length&&c.every(function(a,e){return b[e](c[e],d)})}}),g.set(String.prototype,function resolveString(a){return function(b){return is_string(b)&&b===a}}),g.set(Boolean.prototype,function resolveBoolean(a){return function(b){return is_boolean(b)&&b===a}}),g.set(Function.prototype,function resolveFunction(a){return function(b){return is_function(b)&&b===a}}),g.set(Object.prototype,resolveObject);class MatchError extends Error{constructor(a){if(super(),'symbol'==typeof a)this.message='No match for: '+a.toString();else if(Array.isArray(a)){let b=a.map((a)=>{return null===a?'null':'undefined'==typeof a?'undefined':a.toString()});this.message='No match for: '+b}else this.message='No match for: '+a;this.stack=new Error().stack,this.name=this.constructor.name}}class Clause{constructor(a,b,c=()=>!0){this.pattern=buildMatch(a),this.arity=a.length,this.optionals=getOptionalValues(a),this.fn=b,this.guard=c}}const h=Symbol();// https://github.com/airportyh/protomorphism -class Protocol{constructor(a){function createFun(a){return function(...c){const d=c[0];let e=null;if(null===d&&this.hasImplementation(Symbol('null'))?e=this.registry.get(Symbol)[a]:b(d)&&this.hasImplementation(o.Integer)?e=this.registry.get(o.Integer)[a]:'number'==typeof d&&!b(d)&&this.hasImplementation(o.Float)?e=this.registry.get(o.Float)[a]:'string'==typeof d&&this.hasImplementation(o.BitString)?e=this.registry.get(o.BitString)[a]:d&&d.has(Symbol.for('__struct__'))&&this.hasImplementation(d)?e=this.registry.get(d.get(Symbol.for('__struct__')).__MODULE__)[a]:null!==d&&this.hasImplementation(d)?e=this.registry.get(d.constructor)[a]:this.fallback&&(e=this.fallback[a]),null!=e){const a=e.apply(this,c);return a}throw new Error(`No implementation found for ${d}`)}}for(const b in this.registry=new Map,this.fallback=null,a)this[b]=createFun(b).bind(this)}implementation(a,b){null===a?this.fallback=b:this.registry.set(a,b)}hasImplementation(a){if(a===o.Integer||a===o.Float||a===o.BitString)return this.registry.has(a);return a&&a.has(Symbol.for('__struct__'))?this.registry.has(a.get(Symbol.for('__struct__')).__MODULE__):this.registry.has(a.constructor)}}var i={atom_to_binary,binary_to_atom,binary_to_existing_atom:function binary_to_existing_atom(a,b=Symbol.for('utf8')){return binary_to_atom(a,b)},list_concatenation:function list_concatenation(a,b){return a.concat(b)},list_subtraction:function list_subtraction(a,b){const c=[...a];for(const d of b){const a=c.indexOf(d);-1b},greaterThanOrEqualTo:function greaterThanOrEqualTo(a,b){return a>=b},lessThan:function lessThan(a,b){return a>b},bxor:function bxor(a,b){return a^b},bnot:function bnot(a){return~a},is_bitstring:is_bitstring$1,is_boolean:function is_boolean$1(a){return'boolean'==typeof a||a instanceof Boolean},is_float:function is_float(a){return is_number$1(a)&&!b(a)},is_function:function is_function$1(a){return'function'==typeof a||a instanceof Function},is_integer,is_list:function is_list(a){return Array.isArray(a)},is_map:function is_map$1(a){return a instanceof Map},is_number:is_number$1,is_pid:function is_pid(a){return a instanceof e.PID},is_port:function is_port(){return!1},is_reference:function is_reference(a){return a instanceof e.Reference},is_tuple:function is_tuple(a){return a instanceof e.Tuple},is_atom:function is_atom(a){return'symbol'==typeof a||a instanceof Symbol||a.__MODULE__},is_binary,element:function element(a,b){return b.get(a-1)},setelement:function setelement(a,b,c){const d=[...b.values];return d[a-1]=c,new e.Tuple(...d)},make_tuple:function make_tuple(a,b){const c=[];for(let d=0;d>b},bxor:function bxor(a,b){return a^b},bnot:function bnot(a){return~a},is_bitstring:is_bitstring$1,is_boolean:function is_boolean$1(a){return'boolean'==typeof a||a instanceof Boolean},is_float:function is_float(a){return is_number$1(a)&&!b(a)},is_function:function is_function$1(a){return'function'==typeof a||a instanceof Function},is_integer,is_list:function is_list(a){return Array.isArray(a)},is_map:function is_map$1(a){return a instanceof Map},is_number:is_number$1,is_pid:function is_pid(a){return a instanceof e.PID},is_port:function is_port(){return!1},is_reference:function is_reference(a){return a instanceof e.Reference},is_tuple:function is_tuple(a){return a instanceof e.Tuple},is_atom:function is_atom(a){return'symbol'==typeof a||a instanceof Symbol||a.__MODULE__},is_binary,element:function element(a,b){return b.get(a-1)},setelement:function setelement(a,b,c){const d=[...b.values];return d[a-1]=c,new e.Tuple(...d)},make_tuple:function make_tuple(a,b){const c=[];for(let d=0;d!0){let d=[],e=buildMatch(a);const f=e(b,d),[g,h]=checkNamedVariables(d);if(f&&h&&c.apply(this,g))return g;throw console.error('No match for:',b),new MatchError(b)},MatchError,variable:function variable(a=null,b=Symbol.for('tailored.no_value')){return new Variable(a,b)},wildcard:function wildcard(){return new Wildcard},startsWith:function startsWith(a){return new StartsWith(a)},capture:function capture(a){return new Capture(a)},headTail:function headTail(){return new HeadTail},type:function a(a,b={}){return new Type(a,b)},bound:function bound(a){return new Bound(a)},Clause,clause:function clause(a,b,c=()=>!0){return new Clause(a,b,c)},bitStringMatch:function bitStringMatch(...a){return new BitStringMatch(...a)},match_or_default,defmatchgen,list_comprehension:function list_comprehension(a,b){const c=run_generators(b.pop()(),b);let d=[];for(let e of c)a.guard.apply(this,e)&&d.push(a.fn.apply(this,e));return d},list_generator:function list_generator(a,b){return function(){let c=[];for(let d of b){const b=match_or_default(a,d,()=>!0,h);if(b!=h){const[a]=b;c.push(a)}}return c}},bitstring_generator:function bitstring_generator(a,b){return function(){let c=[],d=b.slice(0,a.byte_size()),e=1;for(;d.byte_size==a.byte_size();){const f=match_or_default(a,d,()=>!0,h);if(f!=h){c.push(f)}d=b.slice(a.byte_size()*e,a.byte_size()*(e+1)),e++}return c}},bitstring_comprehension:function bitstring_comprehension(a,b){const c=run_generators(b.pop()(),b);let d=[];for(let e of c)a.guard.apply(this,e)&&d.push(a.fn.apply(this,e));return d=d.map((a)=>e.BitString.integer(a)),new e.BitString(...d)},defmatchGen:function defmatchGen(...a){return defmatchgen(...a)},defmatchAsync:function defmatchAsync(...a){const b=getArityMap(a);return async function(...a){if(b.has(a.length)){const c=b.get(a.length);let d=null,e=null;for(let b of c){let c=[];a=fillInOptionalValues(a,b.arity,b.optionals);const f=b.pattern(a,c),[g,h]=checkNamedVariables(c);if(f&&h&&(await b.guard.apply(this,c))){d=b.fn,e=c;break}}if(!d)throw console.error('No match for:',a),new MatchError(a);return d.apply(this,e)}throw console.error('Arity of',a.length,'not found. No match for:',a),new MatchError(a)}}},Integer:class Integer{},Float:class Float{},Functions:{call_property:function call_property(a,b){if(!b)return a instanceof Function||'function'==typeof a?a():a;if(a instanceof Map){let c=null;if(a.has(b)?c=b:a.has(Symbol.for(b))&&(c=Symbol.for(b)),null===c)throw new Error(`Property ${b} not found in ${a}`);return a.get(c)instanceof Function||'function'==typeof a.get(c)?a.get(c)():a.get(c)}let c=null;if('number'==typeof a||'symbol'==typeof a||'boolean'==typeof a||'string'==typeof a?void 0===a[b]?void 0!==a[Symbol.for(b)]&&(c=Symbol.for(b)):c=b:b in a?c=b:Symbol.for(b)in a&&(c=Symbol.for(b)),null===c)throw new Error(`Property ${b} not found in ${a}`);return a[c]instanceof Function||'function'==typeof a[c]?a[c]():a[c]},defprotocol:function defprotocol(a){return new Protocol(a)},defimpl:function defimpl(a,b,c){a.implementation(b,c)},build_namespace:function build_namespace(a,b){let c=b.split('.');const d=a;let e=a;'Elixir'===c[0]&&(c=c.slice(1));for(const d of c)'undefined'==typeof e[d]&&(e[d]={}),e=e[d];return d.__table__=a.__table__||{},d.__table__[Symbol.for(b)]=e,e},iterator_to_reducer,map_to_object},SpecialForms:{_case:function _case(a,b){return o.Patterns.defmatch(...b)(a)},cond:function cond(...a){for(const b of a)if(b[0])return b[1]();throw new Error},_for:function _for(a,b,c,d=[]){let[e,f]=c.into(d);const g=run_list_generators(b.pop()(),b);for(const h of g)a.guard.apply(this,h)&&(e=f(e,new o.Tuple(Symbol.for('cont'),a.fn.apply(this,h))));return f(e,Symbol.for('done'))},_try:function _try(a,b,c,d,e){let f=null;try{f=a()}catch(a){let d=null;if(b)try{return d=b(a),d}catch(a){if(a instanceof o.Patterns.MatchError)throw a}if(c)try{return d=c(a),d}catch(a){if(a instanceof o.Patterns.MatchError)throw a}throw a}finally{e&&e()}if(d)try{return d(f)}catch(a){if(a instanceof o.Patterns.MatchError)throw new Error('No Match Found in Else');throw a}else return f},_with:function _with(...a){let b=[],c=null,d=null;'function'==typeof a[a.length-2]?[c,d]=a.splice(-2):c=a.pop();for(let c=0;c{const[c,d]=b;return a.set(c,d),a},new Map)},keys:function keys(a){return!1===i.is_map(a)?new e.Tuple(l,a):Array.from(a.keys())},values:function values$1(a){return!1===i.is_map(a)?new e.Tuple(l,a):Array.from(a.values())},is_key,put:function put(a,b,c){if(!1===i.is_map(c))return new e.Tuple(l,c);const d=new Map(c);return d.set(a,b),d},merge:function merge(a,b){return!1===i.is_map(a)?new e.Tuple(l,a):!1===i.is_map(b)?new e.Tuple(l,b):new Map([...a,...b])},update:function update(a,b,c){return!1===i.is_map(c)?new e.Tuple(l,c):!1===is_key(a,c)?new e.Tuple(m,a):new Map([...c,[a,b]])},get:function get(...a){const b=a[0],c=a[1];return!1===i.is_map(c)?new e.Tuple(l,c):is_key(b)?c.get(b):3===a.length?a[2]:new e.Tuple(m,b)},take:function take(a,b){if(!1===i.is_map(b))return new e.Tuple(l,b);if(!is_key(a))return k;const c=b.get(a),d=new Map(b);return d.delete(a),new e.Tuple(c,d)}},lists:{reverse,foreach:function foreach(a,b){return b.forEach((b)=>a(b)),Symbol.for('ok')},duplicate:function duplicate(a,b){const c=[];for(;c.length{if(d.get(c-1)a.get(c-1)?1:0})},keystore:function keystore(a,b,c,d){const e=[...c];for(let f=0;fa.toString()).join()},map:function map(a,b){return b.map((b)=>a(b))},filter:function filter(a,b){return b.filter((b)=>a(b))},filtermap:function filtermap(a,b){const c=[];for(const d of b){const b=a(d);!0===b?c.push(d):b instanceof e.Tuple&&!0===b.get(0)&&c.push(b.get(1))}return c},member:function member(a,b){for(const c of b)if(c===a)return!0;return!1},all:function all(a,b){for(const c of b)if(!1===a(c))return!1;return!0},any:function any(a,b){for(const c of b)if(!0===a(c))return!0;return!1},splitwith:function splitwith(a,b){let c=!1;const d=[],f=[];for(const e of b)!0==c?f.push(e):!0===a(e)?d.push(e):(c=!0,f.push(e));return new e.Tuple(d,f)},sort:function sort(...a){if(1===a.length){const b=[...a[0]];return b.sort()}const c=a[0],b=[...a[1]];return b.sort((d,a)=>{const b=c(d,a);return!0===b?-1:1})}},elixir_errors:{warn:function warn(a){const b=a.join('');return console.warn(`warning: ${b}`),Symbol.for('ok')}},io:{put_chars:function put_chars(b,c){let d=null;return d=Array.isArray(c)?a(...c):c,b===Symbol.for('stderr')?console.error(d):console.log(d),Symbol.for('ok')}}};return{Core:o}}(); diff --git a/src/javascript/lib/core/erlang_compat/erlang.js b/src/javascript/lib/core/erlang_compat/erlang.js index 69c0a4c7..94eea63e 100644 --- a/src/javascript/lib/core/erlang_compat/erlang.js +++ b/src/javascript/lib/core/erlang_compat/erlang.js @@ -43,70 +43,10 @@ function list_subtraction(list1, list2) { return list; } -function plus(left, right) { - if (!right) { - return +left; - } - - return left + right; -} - -function minus(left, right) { - if (!right) { - return -left; - } - - return left - right; -} - -function multiply(left, right) { - return left * right; -} - function div(left, right) { return left / right; } -function equal(left, right) { - return left == right; -} - -function doesNotEqual(left, right) { - return left != right; -} - -function greaterThan(left, right) { - return left > right; -} - -function greaterThanOrEqualTo(left, right) { - return left >= right; -} - -function lessThan(left, right) { - return left < right; -} - -function lessThanOrEqualTo(left, right) { - return left <= right; -} - -function strictlyEqual(left, right) { - return left === right; -} - -function doesNotStrictlyEqual(left, right) { - return left !== right; -} - -function and(left, right) { - return left && right; -} - -function or(left, right) { - return left || right; -} - function not(x) { return !x; } @@ -365,20 +305,7 @@ export default { binary_to_existing_atom, list_concatenation, list_subtraction, - plus, - minus, - multiply, div, - equal, - greaterThan, - greaterThanOrEqualTo, - lessThan, - lessThanOrEqualTo, - doesNotEqual, - strictlyEqual, - doesNotStrictlyEqual, - and, - or, not, rem, band, From 4f982c02eb453a72fd806c0ca311940ec1b25ef5 Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Sat, 22 Jul 2017 09:41:13 -0500 Subject: [PATCH 192/418] Add binary.copy erlang function to compat layer Upgrade tailored version. Now ignores variables that begin with underscores. Updated pattern.ex to follow suit --- .../passes/translate/forms/pattern.ex | 10 +++++++++- .../passes/translate/forms/remote.ex | 3 ++- package.json | 4 ++-- priv/build/iife/ElixirScript.Core.js | 4 ++-- src/javascript/lib/core.js | 4 +++- src/javascript/lib/core/erlang_compat/binary.js | 7 +++++++ test/support/main.ex | 2 ++ yarn.lock | 17 +++-------------- 8 files changed, 30 insertions(+), 21 deletions(-) create mode 100644 src/javascript/lib/core/erlang_compat/binary.js diff --git a/lib/elixir_script/passes/translate/forms/pattern.ex b/lib/elixir_script/passes/translate/forms/pattern.ex index 9dc2a101..7a86da69 100644 --- a/lib/elixir_script/passes/translate/forms/pattern.ex +++ b/lib/elixir_script/passes/translate/forms/pattern.ex @@ -62,7 +62,7 @@ defmodule ElixirScript.Translate.Forms.Pattern do end defp process_pattern({:_, _, _}, _) do - { [PM.parameter()], [J.identifier(:_)] } + { [PM.parameter(J.literal("_"))], [] } end defp process_pattern({a, b}, state) do @@ -92,6 +92,14 @@ defmodule ElixirScript.Translate.Forms.Pattern do { [PM.type(tuple, pattern)], params } end + defp process_pattern([{:|, _, [head, tail]}], state) do + { head_patterns, head_params } = process_pattern(head, state) + { tail_patterns, tail_params } = process_pattern(tail, state) + params = head_params ++ tail_params + + { [PM.head_tail(hd(head_patterns), hd(tail_patterns))], params } + end + defp process_pattern(list, state) when is_list(list) do { patterns, params } = list |> Enum.map(&do_compile([&1], state)) diff --git a/lib/elixir_script/passes/translate/forms/remote.ex b/lib/elixir_script/passes/translate/forms/remote.ex index fe8590ad..59f23bc4 100644 --- a/lib/elixir_script/passes/translate/forms/remote.ex +++ b/lib/elixir_script/passes/translate/forms/remote.ex @@ -16,7 +16,8 @@ defmodule ElixirScript.Translate.Forms.Remote do :code, :elixir_utils, :file, - :io + :io, + :binary ] @doc """ diff --git a/package.json b/package.json index c243103e..d9d19d63 100644 --- a/package.json +++ b/package.json @@ -13,7 +13,7 @@ "clean": "rm -rf priv/build", "test": "nyc ava src/javascript/tests", "build:test-app": "MIX_ENV=test mix elixirscript Main -f common -o test/app/build/", - "test-app": "yarn run build:test-app && NODE_ENV=test ava 'test/app/spec/**/*.spec.js'" + "test-app": "yarn build:test-app && NODE_ENV=test ava 'test/app/spec/**/*.spec.js'" }, "repository": { "type": "git", @@ -23,7 +23,7 @@ "license": "MIT", "dependencies": { "erlang-types": "^1.0.1", - "tailored": "^2.6.1" + "tailored": "^2.6.3" }, "devDependencies": { "ava": "^0.21.0", diff --git a/priv/build/iife/ElixirScript.Core.js b/priv/build/iife/ElixirScript.Core.js index 31cff94d..5ee7a960 100644 --- a/priv/build/iife/ElixirScript.Core.js +++ b/priv/build/iife/ElixirScript.Core.js @@ -1,6 +1,6 @@ var ElixirScript=function(){'use strict';/* @flow */function namedVariableResult(a,b){return new NamedVariableResult(a,b)}/* @flow */function is_number(a){return'number'==typeof a}function is_string(a){return'string'==typeof a}function is_boolean(a){return'boolean'==typeof a}function is_symbol(a){return'symbol'==typeof a}function is_object(a){return'object'==typeof a}function is_variable(a){return a instanceof Variable}function is_null(a){return null===a}function is_array(a){return Array.isArray(a)}function is_function(a){return'[object Function]'==Object.prototype.toString.call(a)}function is_map(a){return a instanceof Map}function resolveNull(){return function(a){return is_null(a)}}function resolveWildcard(){return function(){return!0}}function resolveObject(a){let b={};const c=Object.keys(a).concat(Object.getOwnPropertySymbols(a));for(let d of c)b[d]=buildMatch(a[d]);return function(d,e){if(!is_object(d)||a.length>d.length)return!1;for(let a of c)if(!(a in d)||!b[a](d[a],e))return!1;return!0}}function getSize(a,b){return a*b/8}function arraysEqual(c,a){if(c===a)return!0;if(null==c||null==a)return!1;if(c.length!=a.length)return!1;for(var b=0;bf.integer(a));return new f(...b)}function resolveNoMatch(){return function(){return!1}}function buildMatch(a){if(null===a)return resolveNull(a);if('undefined'==typeof a)return resolveWildcard(a);const b=a.constructor.prototype,c=g.get(b);return c?c(a):'object'==typeof a?resolveObject(a):resolveNoMatch()}function defmatchgen(...a){const b=getArityMap(a);return function*(...a){let[c,d]=findMatchingFunction(a,b);return yield*c.apply(this,d)}}function findMatchingFunction(a,b){if(b.has(a.length)){const c=b.get(a.length);let d=null,e=null;for(let b of c){let c=[];a=fillInOptionalValues(a,b.arity,b.optionals);const f=b.pattern(a,c),[g,h]=checkNamedVariables(c);if(f&&h&&b.guard.apply(this,g)){d=b.fn,e=g;break}}if(!d)throw console.error('No match for:',a),new MatchError(a);return[d,e]}throw console.error('Arity of',a.length,'not found. No match for:',a),new MatchError(a)}function getArityMap(a){let b=new Map;for(const c of a){const a=getArityRange(c);for(const d of a){let a=[];b.has(d)&&(a=b.get(d)),a.push(c),b.set(d,a)}}return b}function getArityRange(a){const b=a.arity-a.optionals.length,c=a.arity;let d=[b];for(;d[d.length-1]!=c;)d.push(d[d.length-1]+1);return d}function getOptionalValues(a){let b=[];for(let c=0;c!0,d=null){let e=[],f=buildMatch(a);const g=f(b,e),[h,i]=checkNamedVariables(e);return g&&i&&c.apply(this,h)?h:d}function run_generators(a,b){if(0==b.length)return a.map((a)=>{return Array.isArray(a)?a:[a]});const c=b.pop();let d=[];for(let e of c())for(let b of a)d.push([e].concat(b));return run_generators(d,b)}function iterator_to_reducer(a,b,c){const d=a[Symbol.iterator]();let e=d.next(),f=b;for(;!1===e.done;){if(f=c(e.value,f.get(1)),f.get(0)===Symbol.for('halt'))return new o.Tuple(Symbol.for('halted'),f.get(1));if(f.get(0)===Symbol.for('suspend'))return new o.Tuple(Symbol.for('suspended'),f.get(1),(a)=>{return iterator_to_reducer(d,a,c)});e=d.next()}return new o.Tuple(Symbol.for('done'),f.get(1))}function map_to_object(a){const b={};for(const[c,d]of a.entries())b[c]=d instanceof Map?map_to_object(d):d;return b}function run_list_generators(a,b){if(0==b.length)return a.map((a)=>{return Array.isArray(a)?a:[a]});const c=b.pop(),d=[];for(const e of c())for(const b of a)d.push([e].concat(b));return run_list_generators(d,b)}// http://erlang.org/doc/man/erlang.html function atom_to_binary(a,b=Symbol.for('utf8')){if(b!==Symbol.for('utf8'))throw new Error(`unsupported encoding ${b}`);return a.__MODULE__?Symbol.keyFor(a.__MODULE__):Symbol.keyFor(a)}function binary_to_atom(a,b=Symbol.for('utf8')){if(b!==Symbol.for('utf8'))throw new Error(`unsupported encoding ${b}`);return Symbol.for(a)}function is_bitstring$1(a){return a instanceof e.BitString}function is_number$1(a){return'number'==typeof a||a instanceof Number}function is_integer(a){return b(a)}function is_binary(a){return'string'==typeof a||a instanceof String}function iolist_to_binary(b){if(is_binary(b))return b;if(is_bitstring$1(b))return a(...b.value);const c=b.reduce((b,c)=>{if(is_integer(c))return b+a(c);return is_bitstring$1(c)?b+a(...c.value):b+iolist_to_binary(c)},'');return c}function is_key(a,b){return b.has(a)}// http://erlang.org/doc/man/lists.html function reverse(a){return[...a]}function flatten(a,b=[]){const c=a.reduce((a,b)=>{return Array.isArray(b)?a.concat(flatten(b)):a.concat(b)},[]);return c.concat(b)}function foldl(a,b,c){return c.reduce((b,c)=>{return a(c,b)},b)}function keyfind(a,b,c){for(const d of c)if(d.get(b-1)===a)return d;return!1}function keydelete(a,b,c){const d=[];let e=!1;for(let f=0;fBitString$1.integer(a));return new BitString$1(...d)}[Symbol.iterator](){return this.value[Symbol.iterator]()}toString(){var a,b='';for(a=0;a>'}process(a){let b=[];var c;for(c=0;cb?c.push(b):2048>b?c.push(192|b>>6,128|63&b):55296>b||57344<=b?c.push(224|b>>12,128|63&b>>6,128|63&b):(d++,b=65536+((1023&b)<<10|1023&a.charCodeAt(d)),c.push(240|b>>18,128|63&b>>12,128|63&b>>6,128|63&b));return c}static toUTF16Array(a){for(var b,c=[],d=0;d=b?(c.push(0),c.push(b)):(c.push(255&b>>8),c.push(255&b));return c}static toUTF32Array(a){for(var b,c=[],d=0;d=b?(c.push(0),c.push(0),c.push(0),c.push(b)):(c.push(0),c.push(0),c.push(255&b>>8),c.push(255&b));return c}//http://stackoverflow.com/questions/2003493/javascript-float-from-to-bits -static float32ToBytes(a){var b=[],c=new ArrayBuffer(4);new Float32Array(c)[0]=a;let d=new Uint32Array(c)[0];return b.push(255&d>>24),b.push(255&d>>16),b.push(255&d>>8),b.push(255&d),b}static float64ToBytes(a){var b=[],c=new ArrayBuffer(8);new Float64Array(c)[0]=a;var d=new Uint32Array(c)[0],e=new Uint32Array(c)[1];return b.push(255&e>>24),b.push(255&e>>16),b.push(255&e>>8),b.push(255&e),b.push(255&d>>24),b.push(255&d>>16),b.push(255&d>>8),b.push(255&d),b}}var e={Tuple,PID:class PID{constructor(){++c,this.id=c}toString(){return'PID#<0.'+this.id+'.0>'}},Reference:class Reference{constructor(){++d,this.id=d,this.ref=Symbol()}toString(){return'Ref#<0.0.0.'+this.id+'>'}},BitString:BitString$1};/* @flow */const f=e.BitString,g=new Map;g.set(Variable.prototype,function resolveVariable(a){return function(b,c){return null===a.name||a.name.startsWith('_')?c.push(b):c.push(namedVariableResult(a.name,b)),!0}}),g.set(Wildcard.prototype,resolveWildcard),g.set(HeadTail.prototype,function resolveHeadTail(){return function(a,b){if(!is_array(a)||2>a.length)return!1;const c=a[0],d=a.slice(1);return b.push(c),b.push(d),!0}}),g.set(StartsWith.prototype,function resolveStartsWith(a){const b=a.prefix;return function(a,c){return is_string(a)&&a.startsWith(b)&&(c.push(a.substring(b.length)),!0)}}),g.set(Capture.prototype,function resolveCapture(a){const b=buildMatch(a.value);return function(a,c){return!!b(a,c)&&(c.push(a),!0)}}),g.set(Bound.prototype,function resolveBound(a){return function(b){return typeof b==typeof a.value&&b===a.value}}),g.set(Type.prototype,function resolveType(a){return function(b,c){if(b instanceof a.type){const d=buildMatch(a.objPattern);return d(b,c)}return!1}}),g.set(BitStringMatch.prototype,function resolveBitString(a){let b=[];for(let c of a.values)if(is_variable(c.value)){let a=getSize(c.unit,c.size);fillArray(b,a)}else b=b.concat(new f(c).value);let c=a.values;return function(a,d){var e=String.fromCharCode;let g=null;if(!is_string(a)&&!(a instanceof f))return!1;g=is_string(a)?new f(f.binary(a)):a;let h=0;for(let f,j=0;jd.size)return!1;for(let a of c)if(!d.has(a)||!b.get(a)(d.get(a),e))return!1;return!0}}),g.set(Array.prototype,function resolveArray(a){const b=a.map((a)=>buildMatch(a));return function(c,d){return is_array(c)&&c.length==a.length&&c.every(function(a,e){return b[e](c[e],d)})}}),g.set(String.prototype,function resolveString(a){return function(b){return is_string(b)&&b===a}}),g.set(Boolean.prototype,function resolveBoolean(a){return function(b){return is_boolean(b)&&b===a}}),g.set(Function.prototype,function resolveFunction(a){return function(b){return is_function(b)&&b===a}}),g.set(Object.prototype,resolveObject);class MatchError extends Error{constructor(a){if(super(),'symbol'==typeof a)this.message='No match for: '+a.toString();else if(Array.isArray(a)){let b=a.map((a)=>{return null===a?'null':'undefined'==typeof a?'undefined':a.toString()});this.message='No match for: '+b}else this.message='No match for: '+a;this.stack=new Error().stack,this.name=this.constructor.name}}class Clause{constructor(a,b,c=()=>!0){this.pattern=buildMatch(a),this.arity=a.length,this.optionals=getOptionalValues(a),this.fn=b,this.guard=c}}const h=Symbol();// https://github.com/airportyh/protomorphism +static float32ToBytes(a){var b=[],c=new ArrayBuffer(4);new Float32Array(c)[0]=a;let d=new Uint32Array(c)[0];return b.push(255&d>>24),b.push(255&d>>16),b.push(255&d>>8),b.push(255&d),b}static float64ToBytes(a){var b=[],c=new ArrayBuffer(8);new Float64Array(c)[0]=a;var d=new Uint32Array(c)[0],e=new Uint32Array(c)[1];return b.push(255&e>>24),b.push(255&e>>16),b.push(255&e>>8),b.push(255&e),b.push(255&d>>24),b.push(255&d>>16),b.push(255&d>>8),b.push(255&d),b}}var e={Tuple,PID:class PID{constructor(){++c,this.id=c}toString(){return'PID#<0.'+this.id+'.0>'}},Reference:class Reference{constructor(){++d,this.id=d,this.ref=Symbol()}toString(){return'Ref#<0.0.0.'+this.id+'>'}},BitString:BitString$1};/* @flow */const f=e.BitString,g=new Map;g.set(Variable.prototype,function resolveVariable(a){return function(b,c){return null===a.name?c.push(b):!a.name.startsWith('_')&&c.push(namedVariableResult(a.name,b)),!0}}),g.set(Wildcard.prototype,resolveWildcard),g.set(HeadTail.prototype,function resolveHeadTail(){return function(a,b){if(!is_array(a)||0===a.length)return!1;const c=a[0],d=a.slice(1);return b.push(c),b.push(d),!0}}),g.set(StartsWith.prototype,function resolveStartsWith(a){const b=a.prefix;return function(a,c){return is_string(a)&&a.startsWith(b)&&(c.push(a.substring(b.length)),!0)}}),g.set(Capture.prototype,function resolveCapture(a){const b=buildMatch(a.value);return function(a,c){return!!b(a,c)&&(c.push(a),!0)}}),g.set(Bound.prototype,function resolveBound(a){return function(b){return typeof b==typeof a.value&&b===a.value}}),g.set(Type.prototype,function resolveType(a){return function(b,c){if(b instanceof a.type){const d=buildMatch(a.objPattern);return d(b,c)}return!1}}),g.set(BitStringMatch.prototype,function resolveBitString(a){let b=[];for(let c of a.values)if(is_variable(c.value)){let a=getSize(c.unit,c.size);fillArray(b,a)}else b=b.concat(new f(c).value);let c=a.values;return function(a,d){var e=String.fromCharCode;let g=null;if(!is_string(a)&&!(a instanceof f))return!1;g=is_string(a)?new f(f.binary(a)):a;let h=0;for(let f,j=0;jd.size)return!1;for(let a of c)if(!d.has(a)||!b.get(a)(d.get(a),e))return!1;return!0}}),g.set(Array.prototype,function resolveArray(a){const b=a.map((a)=>buildMatch(a));return function(c,d){return is_array(c)&&c.length==a.length&&c.every(function(a,e){return b[e](c[e],d)})}}),g.set(String.prototype,function resolveString(a){return function(b){return is_string(b)&&b===a}}),g.set(Boolean.prototype,function resolveBoolean(a){return function(b){return is_boolean(b)&&b===a}}),g.set(Function.prototype,function resolveFunction(a){return function(b){return is_function(b)&&b===a}}),g.set(Object.prototype,resolveObject);class MatchError extends Error{constructor(a){if(super(),'symbol'==typeof a)this.message='No match for: '+a.toString();else if(Array.isArray(a)){let b=a.map((a)=>{return null===a?'null':'undefined'==typeof a?'undefined':a.toString()});this.message='No match for: '+b}else this.message='No match for: '+a;this.stack=new Error().stack,this.name=this.constructor.name}}class Clause{constructor(a,b,c=()=>!0){this.pattern=buildMatch(a),this.arity=a.length,this.optionals=getOptionalValues(a),this.fn=b,this.guard=c}}const h=Symbol();// https://github.com/airportyh/protomorphism class Protocol{constructor(a){function createFun(a){return function(...c){const d=c[0];let e=null;if(null===d&&this.hasImplementation(Symbol('null'))?e=this.registry.get(Symbol)[a]:b(d)&&this.hasImplementation(o.Integer)?e=this.registry.get(o.Integer)[a]:'number'==typeof d&&!b(d)&&this.hasImplementation(o.Float)?e=this.registry.get(o.Float)[a]:'string'==typeof d&&this.hasImplementation(o.BitString)?e=this.registry.get(o.BitString)[a]:d&&d.has(Symbol.for('__struct__'))&&this.hasImplementation(d)?e=this.registry.get(d.get(Symbol.for('__struct__')).__MODULE__)[a]:null!==d&&this.hasImplementation(d)?e=this.registry.get(d.constructor)[a]:this.fallback&&(e=this.fallback[a]),null!=e){const a=e.apply(this,c);return a}throw new Error(`No implementation found for ${d}`)}}for(const b in this.registry=new Map,this.fallback=null,a)this[b]=createFun(b).bind(this)}implementation(a,b){null===a?this.fallback=b:this.registry.set(a,b)}hasImplementation(a){if(a===o.Integer||a===o.Float||a===o.BitString)return this.registry.has(a);return a&&a.has(Symbol.for('__struct__'))?this.registry.has(a.get(Symbol.for('__struct__')).__MODULE__):this.registry.has(a.constructor)}}var i={atom_to_binary,binary_to_atom,binary_to_existing_atom:function binary_to_existing_atom(a,b=Symbol.for('utf8')){return binary_to_atom(a,b)},list_concatenation:function list_concatenation(a,b){return a.concat(b)},list_subtraction:function list_subtraction(a,b){const c=[...a];for(const d of b){const a=c.indexOf(d);-1>b},bxor:function bxor(a,b){return a^b},bnot:function bnot(a){return~a},is_bitstring:is_bitstring$1,is_boolean:function is_boolean$1(a){return'boolean'==typeof a||a instanceof Boolean},is_float:function is_float(a){return is_number$1(a)&&!b(a)},is_function:function is_function$1(a){return'function'==typeof a||a instanceof Function},is_integer,is_list:function is_list(a){return Array.isArray(a)},is_map:function is_map$1(a){return a instanceof Map},is_number:is_number$1,is_pid:function is_pid(a){return a instanceof e.PID},is_port:function is_port(){return!1},is_reference:function is_reference(a){return a instanceof e.Reference},is_tuple:function is_tuple(a){return a instanceof e.Tuple},is_atom:function is_atom(a){return'symbol'==typeof a||a instanceof Symbol||a.__MODULE__},is_binary,element:function element(a,b){return b.get(a-1)},setelement:function setelement(a,b,c){const d=[...b.values];return d[a-1]=c,new e.Tuple(...d)},make_tuple:function make_tuple(a,b){const c=[];for(let d=0;d!0){let d=[],e=buildMatch(a);const f=e(b,d),[g,h]=checkNamedVariables(d);if(f&&h&&c.apply(this,g))return g;throw console.error('No match for:',b),new MatchError(b)},MatchError,variable:function variable(a=null,b=Symbol.for('tailored.no_value')){return new Variable(a,b)},wildcard:function wildcard(){return new Wildcard},startsWith:function startsWith(a){return new StartsWith(a)},capture:function capture(a){return new Capture(a)},headTail:function headTail(){return new HeadTail},type:function a(a,b={}){return new Type(a,b)},bound:function bound(a){return new Bound(a)},Clause,clause:function clause(a,b,c=()=>!0){return new Clause(a,b,c)},bitStringMatch:function bitStringMatch(...a){return new BitStringMatch(...a)},match_or_default,defmatchgen,list_comprehension:function list_comprehension(a,b){const c=run_generators(b.pop()(),b);let d=[];for(let e of c)a.guard.apply(this,e)&&d.push(a.fn.apply(this,e));return d},list_generator:function list_generator(a,b){return function(){let c=[];for(let d of b){const b=match_or_default(a,d,()=>!0,h);if(b!=h){const[a]=b;c.push(a)}}return c}},bitstring_generator:function bitstring_generator(a,b){return function(){let c=[],d=b.slice(0,a.byte_size()),e=1;for(;d.byte_size==a.byte_size();){const f=match_or_default(a,d,()=>!0,h);if(f!=h){c.push(f)}d=b.slice(a.byte_size()*e,a.byte_size()*(e+1)),e++}return c}},bitstring_comprehension:function bitstring_comprehension(a,b){const c=run_generators(b.pop()(),b);let d=[];for(let e of c)a.guard.apply(this,e)&&d.push(a.fn.apply(this,e));return d=d.map((a)=>e.BitString.integer(a)),new e.BitString(...d)},defmatchGen:function defmatchGen(...a){return defmatchgen(...a)},defmatchAsync:function defmatchAsync(...a){const b=getArityMap(a);return async function(...a){if(b.has(a.length)){const c=b.get(a.length);let d=null,e=null;for(let b of c){let c=[];a=fillInOptionalValues(a,b.arity,b.optionals);const f=b.pattern(a,c),[g,h]=checkNamedVariables(c);if(f&&h&&(await b.guard.apply(this,c))){d=b.fn,e=c;break}}if(!d)throw console.error('No match for:',a),new MatchError(a);return d.apply(this,e)}throw console.error('Arity of',a.length,'not found. No match for:',a),new MatchError(a)}}},Integer:class Integer{},Float:class Float{},Functions:{call_property:function call_property(a,b){if(!b)return a instanceof Function||'function'==typeof a?a():a;if(a instanceof Map){let c=null;if(a.has(b)?c=b:a.has(Symbol.for(b))&&(c=Symbol.for(b)),null===c)throw new Error(`Property ${b} not found in ${a}`);return a.get(c)instanceof Function||'function'==typeof a.get(c)?a.get(c)():a.get(c)}let c=null;if('number'==typeof a||'symbol'==typeof a||'boolean'==typeof a||'string'==typeof a?void 0===a[b]?void 0!==a[Symbol.for(b)]&&(c=Symbol.for(b)):c=b:b in a?c=b:Symbol.for(b)in a&&(c=Symbol.for(b)),null===c)throw new Error(`Property ${b} not found in ${a}`);return a[c]instanceof Function||'function'==typeof a[c]?a[c]():a[c]},defprotocol:function defprotocol(a){return new Protocol(a)},defimpl:function defimpl(a,b,c){a.implementation(b,c)},build_namespace:function build_namespace(a,b){let c=b.split('.');const d=a;let e=a;'Elixir'===c[0]&&(c=c.slice(1));for(const d of c)'undefined'==typeof e[d]&&(e[d]={}),e=e[d];return d.__table__=a.__table__||{},d.__table__[Symbol.for(b)]=e,e},iterator_to_reducer,map_to_object},SpecialForms:{_case:function _case(a,b){return o.Patterns.defmatch(...b)(a)},cond:function cond(...a){for(const b of a)if(b[0])return b[1]();throw new Error},_for:function _for(a,b,c,d=[]){let[e,f]=c.into(d);const g=run_list_generators(b.pop()(),b);for(const h of g)a.guard.apply(this,h)&&(e=f(e,new o.Tuple(Symbol.for('cont'),a.fn.apply(this,h))));return f(e,Symbol.for('done'))},_try:function _try(a,b,c,d,e){let f=null;try{f=a()}catch(a){let d=null;if(b)try{return d=b(a),d}catch(a){if(a instanceof o.Patterns.MatchError)throw a}if(c)try{return d=c(a),d}catch(a){if(a instanceof o.Patterns.MatchError)throw a}throw a}finally{e&&e()}if(d)try{return d(f)}catch(a){if(a instanceof o.Patterns.MatchError)throw new Error('No Match Found in Else');throw a}else return f},_with:function _with(...a){let b=[],c=null,d=null;'function'==typeof a[a.length-2]?[c,d]=a.splice(-2):c=a.pop();for(let c=0;c{const[c,d]=b;return a.set(c,d),a},new Map)},keys:function keys(a){return!1===i.is_map(a)?new e.Tuple(l,a):Array.from(a.keys())},values:function values$1(a){return!1===i.is_map(a)?new e.Tuple(l,a):Array.from(a.values())},is_key,put:function put(a,b,c){if(!1===i.is_map(c))return new e.Tuple(l,c);const d=new Map(c);return d.set(a,b),d},merge:function merge(a,b){return!1===i.is_map(a)?new e.Tuple(l,a):!1===i.is_map(b)?new e.Tuple(l,b):new Map([...a,...b])},update:function update(a,b,c){return!1===i.is_map(c)?new e.Tuple(l,c):!1===is_key(a,c)?new e.Tuple(m,a):new Map([...c,[a,b]])},get:function get(...a){const b=a[0],c=a[1];return!1===i.is_map(c)?new e.Tuple(l,c):is_key(b)?c.get(b):3===a.length?a[2]:new e.Tuple(m,b)},take:function take(a,b){if(!1===i.is_map(b))return new e.Tuple(l,b);if(!is_key(a))return k;const c=b.get(a),d=new Map(b);return d.delete(a),new e.Tuple(c,d)}},lists:{reverse,foreach:function foreach(a,b){return b.forEach((b)=>a(b)),Symbol.for('ok')},duplicate:function duplicate(a,b){const c=[];for(;c.length{if(d.get(c-1)a.get(c-1)?1:0})},keystore:function keystore(a,b,c,d){const e=[...c];for(let f=0;fa.toString()).join()},map:function map(a,b){return b.map((b)=>a(b))},filter:function filter(a,b){return b.filter((b)=>a(b))},filtermap:function filtermap(a,b){const c=[];for(const d of b){const b=a(d);!0===b?c.push(d):b instanceof e.Tuple&&!0===b.get(0)&&c.push(b.get(1))}return c},member:function member(a,b){for(const c of b)if(c===a)return!0;return!1},all:function all(a,b){for(const c of b)if(!1===a(c))return!1;return!0},any:function any(a,b){for(const c of b)if(!0===a(c))return!0;return!1},splitwith:function splitwith(a,b){let c=!1;const d=[],f=[];for(const e of b)!0==c?f.push(e):!0===a(e)?d.push(e):(c=!0,f.push(e));return new e.Tuple(d,f)},sort:function sort(...a){if(1===a.length){const b=[...a[0]];return b.sort()}const c=a[0],b=[...a[1]];return b.sort((d,a)=>{const b=c(d,a);return!0===b?-1:1})}},elixir_errors:{warn:function warn(a){const b=a.join('');return console.warn(`warning: ${b}`),Symbol.for('ok')}},io:{put_chars:function put_chars(b,c){let d=null;return d=Array.isArray(c)?a(...c):c,b===Symbol.for('stderr')?console.error(d):console.log(d),Symbol.for('ok')}}};return{Core:o}}(); +const j=Symbol.for('ok'),k=Symbol.for('error'),l=Symbol.for('badmap'),m=Symbol.for('badkey');const n=function get_global(){return'undefined'==typeof self?'undefined'==typeof window?'undefined'==typeof global?(console.warn('No global state found'),null):global:window:self}();n.__elixirscript_store__=new Map,n.__elixirscript_names__=new Map;var o={Tuple:e.Tuple,PID:e.PID,BitString:e.BitString,Patterns:{defmatch:function defmatch(...a){const b=getArityMap(a);return function(...a){let[c,d]=findMatchingFunction(a,b);return c.apply(this,d)}},match:function match(a,b,c=()=>!0){let d=[],e=buildMatch(a);const f=e(b,d),[g,h]=checkNamedVariables(d);if(f&&h&&c.apply(this,g))return g;throw console.error('No match for:',b),new MatchError(b)},MatchError,variable:function variable(a=null,b=Symbol.for('tailored.no_value')){return new Variable(a,b)},wildcard:function wildcard(){return new Wildcard},startsWith:function startsWith(a){return new StartsWith(a)},capture:function capture(a){return new Capture(a)},headTail:function headTail(){return new HeadTail},type:function a(a,b={}){return new Type(a,b)},bound:function bound(a){return new Bound(a)},Clause,clause:function clause(a,b,c=()=>!0){return new Clause(a,b,c)},bitStringMatch:function bitStringMatch(...a){return new BitStringMatch(...a)},match_or_default,defmatchgen,list_comprehension:function list_comprehension(a,b){const c=run_generators(b.pop()(),b);let d=[];for(let e of c)a.guard.apply(this,e)&&d.push(a.fn.apply(this,e));return d},list_generator:function list_generator(a,b){return function(){let c=[];for(let d of b){const b=match_or_default(a,d,()=>!0,h);if(b!=h){const[a]=b;c.push(a)}}return c}},bitstring_generator:function bitstring_generator(a,b){return function(){let c=[],d=b.slice(0,a.byte_size()),e=1;for(;d.byte_size==a.byte_size();){const f=match_or_default(a,d,()=>!0,h);if(f!=h){c.push(f)}d=b.slice(a.byte_size()*e,a.byte_size()*(e+1)),e++}return c}},bitstring_comprehension:function bitstring_comprehension(a,b){const c=run_generators(b.pop()(),b);let d=[];for(let e of c)a.guard.apply(this,e)&&d.push(a.fn.apply(this,e));return d=d.map((a)=>e.BitString.integer(a)),new e.BitString(...d)},defmatchGen:function defmatchGen(...a){return defmatchgen(...a)},defmatchAsync:function defmatchAsync(...a){const b=getArityMap(a);return async function(...a){if(b.has(a.length)){const c=b.get(a.length);let d=null,e=null;for(let b of c){let c=[];a=fillInOptionalValues(a,b.arity,b.optionals);const f=b.pattern(a,c),[g,h]=checkNamedVariables(c);if(f&&h&&(await b.guard.apply(this,c))){d=b.fn,e=c;break}}if(!d)throw console.error('No match for:',a),new MatchError(a);return d.apply(this,e)}throw console.error('Arity of',a.length,'not found. No match for:',a),new MatchError(a)}}},Integer:class Integer{},Float:class Float{},Functions:{call_property:function call_property(a,b){if(!b)return a instanceof Function||'function'==typeof a?a():a;if(a instanceof Map){let c=null;if(a.has(b)?c=b:a.has(Symbol.for(b))&&(c=Symbol.for(b)),null===c)throw new Error(`Property ${b} not found in ${a}`);return a.get(c)instanceof Function||'function'==typeof a.get(c)?a.get(c)():a.get(c)}let c=null;if('number'==typeof a||'symbol'==typeof a||'boolean'==typeof a||'string'==typeof a?void 0===a[b]?void 0!==a[Symbol.for(b)]&&(c=Symbol.for(b)):c=b:b in a?c=b:Symbol.for(b)in a&&(c=Symbol.for(b)),null===c)throw new Error(`Property ${b} not found in ${a}`);return a[c]instanceof Function||'function'==typeof a[c]?a[c]():a[c]},defprotocol:function defprotocol(a){return new Protocol(a)},defimpl:function defimpl(a,b,c){a.implementation(b,c)},build_namespace:function build_namespace(a,b){let c=b.split('.');const d=a;let e=a;'Elixir'===c[0]&&(c=c.slice(1));for(const d of c)'undefined'==typeof e[d]&&(e[d]={}),e=e[d];return d.__table__=a.__table__||{},d.__table__[Symbol.for(b)]=e,e},iterator_to_reducer,map_to_object},SpecialForms:{_case:function _case(a,b){return o.Patterns.defmatch(...b)(a)},cond:function cond(...a){for(const b of a)if(b[0])return b[1]();throw new Error},_for:function _for(a,b,c,d=[]){let[e,f]=c.into(d);const g=run_list_generators(b.pop()(),b);for(const h of g)a.guard.apply(this,h)&&(e=f(e,new o.Tuple(Symbol.for('cont'),a.fn.apply(this,h))));return f(e,Symbol.for('done'))},_try:function _try(a,b,c,d,e){let f=null;try{f=a()}catch(a){let d=null;if(b)try{return d=b(a),d}catch(a){if(a instanceof o.Patterns.MatchError)throw a}if(c)try{return d=c(a),d}catch(a){if(a instanceof o.Patterns.MatchError)throw a}throw a}finally{e&&e()}if(d)try{return d(f)}catch(a){if(a instanceof o.Patterns.MatchError)throw new Error('No Match Found in Else');throw a}else return f},_with:function _with(...a){let b=[],c=null,d=null;'function'==typeof a[a.length-2]?[c,d]=a.splice(-2):c=a.pop();for(let c=0;c{const[c,d]=b;return a.set(c,d),a},new Map)},keys:function keys(a){return!1===i.is_map(a)?new e.Tuple(l,a):Array.from(a.keys())},values:function values$1(a){return!1===i.is_map(a)?new e.Tuple(l,a):Array.from(a.values())},is_key,put:function put(a,b,c){if(!1===i.is_map(c))return new e.Tuple(l,c);const d=new Map(c);return d.set(a,b),d},merge:function merge(a,b){return!1===i.is_map(a)?new e.Tuple(l,a):!1===i.is_map(b)?new e.Tuple(l,b):new Map([...a,...b])},update:function update(a,b,c){return!1===i.is_map(c)?new e.Tuple(l,c):!1===is_key(a,c)?new e.Tuple(m,a):new Map([...c,[a,b]])},get:function get(...a){const b=a[0],c=a[1];return!1===i.is_map(c)?new e.Tuple(l,c):is_key(b)?c.get(b):3===a.length?a[2]:new e.Tuple(m,b)},take:function take(a,b){if(!1===i.is_map(b))return new e.Tuple(l,b);if(!is_key(a))return k;const c=b.get(a),d=new Map(b);return d.delete(a),new e.Tuple(c,d)}},lists:{reverse,foreach:function foreach(a,b){return b.forEach((b)=>a(b)),Symbol.for('ok')},duplicate:function duplicate(a,b){const c=[];for(;c.length{if(d.get(c-1)a.get(c-1)?1:0})},keystore:function keystore(a,b,c,d){const e=[...c];for(let f=0;fa.toString()).join()},map:function map(a,b){return b.map((b)=>a(b))},filter:function filter(a,b){return b.filter((b)=>a(b))},filtermap:function filtermap(a,b){const c=[];for(const d of b){const b=a(d);!0===b?c.push(d):b instanceof e.Tuple&&!0===b.get(0)&&c.push(b.get(1))}return c},member:function member(a,b){for(const c of b)if(c===a)return!0;return!1},all:function all(a,b){for(const c of b)if(!1===a(c))return!1;return!0},any:function any(a,b){for(const c of b)if(!0===a(c))return!0;return!1},splitwith:function splitwith(a,b){let c=!1;const d=[],f=[];for(const e of b)!0==c?f.push(e):!0===a(e)?d.push(e):(c=!0,f.push(e));return new e.Tuple(d,f)},sort:function sort(...a){if(1===a.length){const b=[...a[0]];return b.sort()}const c=a[0],b=[...a[1]];return b.sort((d,a)=>{const b=c(d,a);return!0===b?-1:1})}},elixir_errors:{warn:function warn(a){const b=a.join('');return console.warn(`warning: ${b}`),Symbol.for('ok')}},io:{put_chars:function put_chars(b,c){let d=null;return d=Array.isArray(c)?a(...c):c,b===Symbol.for('stderr')?console.error(d):console.log(d),Symbol.for('ok')}},binary:{copy:function copy(a,b=1){return a.repeat(b)}}};return{Core:o}}(); diff --git a/src/javascript/lib/core.js b/src/javascript/lib/core.js index d2677323..f47e61bd 100644 --- a/src/javascript/lib/core.js +++ b/src/javascript/lib/core.js @@ -7,6 +7,7 @@ import maps from './core/erlang_compat/maps'; import lists from './core/erlang_compat/lists'; import elixir_errors from './core/erlang_compat/elixir_errors'; import io from './core/erlang_compat/io'; +import binary from './core/erlang_compat/binary'; import Store from './core/store'; class Integer {} @@ -45,5 +46,6 @@ export default { maps, lists, elixir_errors, - io + io, + binary }; diff --git a/src/javascript/lib/core/erlang_compat/binary.js b/src/javascript/lib/core/erlang_compat/binary.js new file mode 100644 index 00000000..0e0c8f96 --- /dev/null +++ b/src/javascript/lib/core/erlang_compat/binary.js @@ -0,0 +1,7 @@ +function copy(subject, n = 1) { + return subject.repeat(n); +} + +export default { + copy +}; diff --git a/test/support/main.ex b/test/support/main.ex index a18d3d90..5d94e7ac 100644 --- a/test/support/main.ex +++ b/test/support/main.ex @@ -1,5 +1,7 @@ defmodule Main do def start(:normal, [callback]) do callback.("started") + + IO.inspect 1 end end diff --git a/yarn.lock b/yarn.lock index 0c91a8ec..ebbc6518 100644 --- a/yarn.lock +++ b/yarn.lock @@ -605,10 +605,6 @@ babel-plugin-syntax-exponentiation-operator@^6.8.0: version "6.13.0" resolved "https://registry.yarnpkg.com/babel-plugin-syntax-exponentiation-operator/-/babel-plugin-syntax-exponentiation-operator-6.13.0.tgz#9ee7e8337290da95288201a6a57f4170317830de" -babel-plugin-syntax-object-rest-spread@^6.8.0: - version "6.13.0" - resolved "https://registry.yarnpkg.com/babel-plugin-syntax-object-rest-spread/-/babel-plugin-syntax-object-rest-spread-6.13.0.tgz#fd6536f2bce13836ffa3a5458c4903a597bb3bf5" - babel-plugin-syntax-trailing-function-commas@^6.20.0, babel-plugin-syntax-trailing-function-commas@^6.22.0: version "6.22.0" resolved "https://registry.yarnpkg.com/babel-plugin-syntax-trailing-function-commas/-/babel-plugin-syntax-trailing-function-commas-6.22.0.tgz#ba0360937f8d06e40180a43fe0d5616fff532cf3" @@ -813,13 +809,6 @@ babel-plugin-transform-minify-booleans@^6.8.2: version "6.8.2" resolved "https://registry.yarnpkg.com/babel-plugin-transform-minify-booleans/-/babel-plugin-transform-minify-booleans-6.8.2.tgz#8451579f706e702c1e1ab2756de5c8ea369cf07c" -babel-plugin-transform-object-rest-spread@^6.23.0: - version "6.23.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-object-rest-spread/-/babel-plugin-transform-object-rest-spread-6.23.0.tgz#875d6bc9be761c58a2ae3feee5dc4895d8c7f921" - dependencies: - babel-plugin-syntax-object-rest-spread "^6.8.0" - babel-runtime "^6.22.0" - babel-plugin-transform-property-literals@^6.8.4: version "6.8.4" resolved "https://registry.yarnpkg.com/babel-plugin-transform-property-literals/-/babel-plugin-transform-property-literals-6.8.4.tgz#6ad311110b80a192a56efb5ddf4fe3ca6f7a61da" @@ -3689,9 +3678,9 @@ table@^4.0.1: slice-ansi "0.0.4" string-width "^2.0.0" -tailored@^2.6.1: - version "2.6.1" - resolved "https://registry.yarnpkg.com/tailored/-/tailored-2.6.1.tgz#afac1114f4622eceba11d87fcc35b42a658ded84" +tailored@^2.6.3: + version "2.6.3" + resolved "https://registry.yarnpkg.com/tailored/-/tailored-2.6.3.tgz#27d1069dd3f5b2f2009d6437efcb26c595bccfda" dependencies: erlang-types "^1.0.1" From 7f48f5a30a38ba23d4be1dd260b945741f213a21 Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Sat, 22 Jul 2017 09:43:40 -0500 Subject: [PATCH 193/418] Revert changes to main.ex --- test/support/main.ex | 2 -- 1 file changed, 2 deletions(-) diff --git a/test/support/main.ex b/test/support/main.ex index 5d94e7ac..a18d3d90 100644 --- a/test/support/main.ex +++ b/test/support/main.ex @@ -1,7 +1,5 @@ defmodule Main do def start(:normal, [callback]) do callback.("started") - - IO.inspect 1 end end From 439208eb82263132eb93113c4f5b0b251792dcbb Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Sun, 23 Jul 2017 14:16:29 -0500 Subject: [PATCH 194/418] Update erlang.iolist_to_binary to flatten given iolist Also update to io.put_chars to call iolist_to_binary before outputting data --- priv/build/iife/ElixirScript.Core.js | 12 ++++++------ src/javascript/lib/core/erlang_compat/erlang.js | 13 +++++++++++-- src/javascript/lib/core/erlang_compat/io.js | 10 +++------- 3 files changed, 20 insertions(+), 15 deletions(-) diff --git a/priv/build/iife/ElixirScript.Core.js b/priv/build/iife/ElixirScript.Core.js index 5ee7a960..850b7ab7 100644 --- a/priv/build/iife/ElixirScript.Core.js +++ b/priv/build/iife/ElixirScript.Core.js @@ -1,6 +1,6 @@ -var ElixirScript=function(){'use strict';/* @flow */function namedVariableResult(a,b){return new NamedVariableResult(a,b)}/* @flow */function is_number(a){return'number'==typeof a}function is_string(a){return'string'==typeof a}function is_boolean(a){return'boolean'==typeof a}function is_symbol(a){return'symbol'==typeof a}function is_object(a){return'object'==typeof a}function is_variable(a){return a instanceof Variable}function is_null(a){return null===a}function is_array(a){return Array.isArray(a)}function is_function(a){return'[object Function]'==Object.prototype.toString.call(a)}function is_map(a){return a instanceof Map}function resolveNull(){return function(a){return is_null(a)}}function resolveWildcard(){return function(){return!0}}function resolveObject(a){let b={};const c=Object.keys(a).concat(Object.getOwnPropertySymbols(a));for(let d of c)b[d]=buildMatch(a[d]);return function(d,e){if(!is_object(d)||a.length>d.length)return!1;for(let a of c)if(!(a in d)||!b[a](d[a],e))return!1;return!0}}function getSize(a,b){return a*b/8}function arraysEqual(c,a){if(c===a)return!0;if(null==c||null==a)return!1;if(c.length!=a.length)return!1;for(var b=0;bf.integer(a));return new f(...b)}function resolveNoMatch(){return function(){return!1}}function buildMatch(a){if(null===a)return resolveNull(a);if('undefined'==typeof a)return resolveWildcard(a);const b=a.constructor.prototype,c=g.get(b);return c?c(a):'object'==typeof a?resolveObject(a):resolveNoMatch()}function defmatchgen(...a){const b=getArityMap(a);return function*(...a){let[c,d]=findMatchingFunction(a,b);return yield*c.apply(this,d)}}function findMatchingFunction(a,b){if(b.has(a.length)){const c=b.get(a.length);let d=null,e=null;for(let b of c){let c=[];a=fillInOptionalValues(a,b.arity,b.optionals);const f=b.pattern(a,c),[g,h]=checkNamedVariables(c);if(f&&h&&b.guard.apply(this,g)){d=b.fn,e=g;break}}if(!d)throw console.error('No match for:',a),new MatchError(a);return[d,e]}throw console.error('Arity of',a.length,'not found. No match for:',a),new MatchError(a)}function getArityMap(a){let b=new Map;for(const c of a){const a=getArityRange(c);for(const d of a){let a=[];b.has(d)&&(a=b.get(d)),a.push(c),b.set(d,a)}}return b}function getArityRange(a){const b=a.arity-a.optionals.length,c=a.arity;let d=[b];for(;d[d.length-1]!=c;)d.push(d[d.length-1]+1);return d}function getOptionalValues(a){let b=[];for(let c=0;c!0,d=null){let e=[],f=buildMatch(a);const g=f(b,e),[h,i]=checkNamedVariables(e);return g&&i&&c.apply(this,h)?h:d}function run_generators(a,b){if(0==b.length)return a.map((a)=>{return Array.isArray(a)?a:[a]});const c=b.pop();let d=[];for(let e of c())for(let b of a)d.push([e].concat(b));return run_generators(d,b)}function iterator_to_reducer(a,b,c){const d=a[Symbol.iterator]();let e=d.next(),f=b;for(;!1===e.done;){if(f=c(e.value,f.get(1)),f.get(0)===Symbol.for('halt'))return new o.Tuple(Symbol.for('halted'),f.get(1));if(f.get(0)===Symbol.for('suspend'))return new o.Tuple(Symbol.for('suspended'),f.get(1),(a)=>{return iterator_to_reducer(d,a,c)});e=d.next()}return new o.Tuple(Symbol.for('done'),f.get(1))}function map_to_object(a){const b={};for(const[c,d]of a.entries())b[c]=d instanceof Map?map_to_object(d):d;return b}function run_list_generators(a,b){if(0==b.length)return a.map((a)=>{return Array.isArray(a)?a:[a]});const c=b.pop(),d=[];for(const e of c())for(const b of a)d.push([e].concat(b));return run_list_generators(d,b)}// http://erlang.org/doc/man/erlang.html -function atom_to_binary(a,b=Symbol.for('utf8')){if(b!==Symbol.for('utf8'))throw new Error(`unsupported encoding ${b}`);return a.__MODULE__?Symbol.keyFor(a.__MODULE__):Symbol.keyFor(a)}function binary_to_atom(a,b=Symbol.for('utf8')){if(b!==Symbol.for('utf8'))throw new Error(`unsupported encoding ${b}`);return Symbol.for(a)}function is_bitstring$1(a){return a instanceof e.BitString}function is_number$1(a){return'number'==typeof a||a instanceof Number}function is_integer(a){return b(a)}function is_binary(a){return'string'==typeof a||a instanceof String}function iolist_to_binary(b){if(is_binary(b))return b;if(is_bitstring$1(b))return a(...b.value);const c=b.reduce((b,c)=>{if(is_integer(c))return b+a(c);return is_bitstring$1(c)?b+a(...c.value):b+iolist_to_binary(c)},'');return c}function is_key(a,b){return b.has(a)}// http://erlang.org/doc/man/lists.html -function reverse(a){return[...a]}function flatten(a,b=[]){const c=a.reduce((a,b)=>{return Array.isArray(b)?a.concat(flatten(b)):a.concat(b)},[]);return c.concat(b)}function foldl(a,b,c){return c.reduce((b,c)=>{return a(c,b)},b)}function keyfind(a,b,c){for(const d of c)if(d.get(b-1)===a)return d;return!1}function keydelete(a,b,c){const d=[];let e=!1;for(let f=0;fBitString$1.integer(a));return new BitString$1(...d)}[Symbol.iterator](){return this.value[Symbol.iterator]()}toString(){var a,b='';for(a=0;a>'}process(a){let b=[];var c;for(c=0;cb?c.push(b):2048>b?c.push(192|b>>6,128|63&b):55296>b||57344<=b?c.push(224|b>>12,128|63&b>>6,128|63&b):(d++,b=65536+((1023&b)<<10|1023&a.charCodeAt(d)),c.push(240|b>>18,128|63&b>>12,128|63&b>>6,128|63&b));return c}static toUTF16Array(a){for(var b,c=[],d=0;d=b?(c.push(0),c.push(b)):(c.push(255&b>>8),c.push(255&b));return c}static toUTF32Array(a){for(var b,c=[],d=0;d=b?(c.push(0),c.push(0),c.push(0),c.push(b)):(c.push(0),c.push(0),c.push(255&b>>8),c.push(255&b));return c}//http://stackoverflow.com/questions/2003493/javascript-float-from-to-bits -static float32ToBytes(a){var b=[],c=new ArrayBuffer(4);new Float32Array(c)[0]=a;let d=new Uint32Array(c)[0];return b.push(255&d>>24),b.push(255&d>>16),b.push(255&d>>8),b.push(255&d),b}static float64ToBytes(a){var b=[],c=new ArrayBuffer(8);new Float64Array(c)[0]=a;var d=new Uint32Array(c)[0],e=new Uint32Array(c)[1];return b.push(255&e>>24),b.push(255&e>>16),b.push(255&e>>8),b.push(255&e),b.push(255&d>>24),b.push(255&d>>16),b.push(255&d>>8),b.push(255&d),b}}var e={Tuple,PID:class PID{constructor(){++c,this.id=c}toString(){return'PID#<0.'+this.id+'.0>'}},Reference:class Reference{constructor(){++d,this.id=d,this.ref=Symbol()}toString(){return'Ref#<0.0.0.'+this.id+'>'}},BitString:BitString$1};/* @flow */const f=e.BitString,g=new Map;g.set(Variable.prototype,function resolveVariable(a){return function(b,c){return null===a.name?c.push(b):!a.name.startsWith('_')&&c.push(namedVariableResult(a.name,b)),!0}}),g.set(Wildcard.prototype,resolveWildcard),g.set(HeadTail.prototype,function resolveHeadTail(){return function(a,b){if(!is_array(a)||0===a.length)return!1;const c=a[0],d=a.slice(1);return b.push(c),b.push(d),!0}}),g.set(StartsWith.prototype,function resolveStartsWith(a){const b=a.prefix;return function(a,c){return is_string(a)&&a.startsWith(b)&&(c.push(a.substring(b.length)),!0)}}),g.set(Capture.prototype,function resolveCapture(a){const b=buildMatch(a.value);return function(a,c){return!!b(a,c)&&(c.push(a),!0)}}),g.set(Bound.prototype,function resolveBound(a){return function(b){return typeof b==typeof a.value&&b===a.value}}),g.set(Type.prototype,function resolveType(a){return function(b,c){if(b instanceof a.type){const d=buildMatch(a.objPattern);return d(b,c)}return!1}}),g.set(BitStringMatch.prototype,function resolveBitString(a){let b=[];for(let c of a.values)if(is_variable(c.value)){let a=getSize(c.unit,c.size);fillArray(b,a)}else b=b.concat(new f(c).value);let c=a.values;return function(a,d){var e=String.fromCharCode;let g=null;if(!is_string(a)&&!(a instanceof f))return!1;g=is_string(a)?new f(f.binary(a)):a;let h=0;for(let f,j=0;jd.size)return!1;for(let a of c)if(!d.has(a)||!b.get(a)(d.get(a),e))return!1;return!0}}),g.set(Array.prototype,function resolveArray(a){const b=a.map((a)=>buildMatch(a));return function(c,d){return is_array(c)&&c.length==a.length&&c.every(function(a,e){return b[e](c[e],d)})}}),g.set(String.prototype,function resolveString(a){return function(b){return is_string(b)&&b===a}}),g.set(Boolean.prototype,function resolveBoolean(a){return function(b){return is_boolean(b)&&b===a}}),g.set(Function.prototype,function resolveFunction(a){return function(b){return is_function(b)&&b===a}}),g.set(Object.prototype,resolveObject);class MatchError extends Error{constructor(a){if(super(),'symbol'==typeof a)this.message='No match for: '+a.toString();else if(Array.isArray(a)){let b=a.map((a)=>{return null===a?'null':'undefined'==typeof a?'undefined':a.toString()});this.message='No match for: '+b}else this.message='No match for: '+a;this.stack=new Error().stack,this.name=this.constructor.name}}class Clause{constructor(a,b,c=()=>!0){this.pattern=buildMatch(a),this.arity=a.length,this.optionals=getOptionalValues(a),this.fn=b,this.guard=c}}const h=Symbol();// https://github.com/airportyh/protomorphism -class Protocol{constructor(a){function createFun(a){return function(...c){const d=c[0];let e=null;if(null===d&&this.hasImplementation(Symbol('null'))?e=this.registry.get(Symbol)[a]:b(d)&&this.hasImplementation(o.Integer)?e=this.registry.get(o.Integer)[a]:'number'==typeof d&&!b(d)&&this.hasImplementation(o.Float)?e=this.registry.get(o.Float)[a]:'string'==typeof d&&this.hasImplementation(o.BitString)?e=this.registry.get(o.BitString)[a]:d&&d.has(Symbol.for('__struct__'))&&this.hasImplementation(d)?e=this.registry.get(d.get(Symbol.for('__struct__')).__MODULE__)[a]:null!==d&&this.hasImplementation(d)?e=this.registry.get(d.constructor)[a]:this.fallback&&(e=this.fallback[a]),null!=e){const a=e.apply(this,c);return a}throw new Error(`No implementation found for ${d}`)}}for(const b in this.registry=new Map,this.fallback=null,a)this[b]=createFun(b).bind(this)}implementation(a,b){null===a?this.fallback=b:this.registry.set(a,b)}hasImplementation(a){if(a===o.Integer||a===o.Float||a===o.BitString)return this.registry.has(a);return a&&a.has(Symbol.for('__struct__'))?this.registry.has(a.get(Symbol.for('__struct__')).__MODULE__):this.registry.has(a.constructor)}}var i={atom_to_binary,binary_to_atom,binary_to_existing_atom:function binary_to_existing_atom(a,b=Symbol.for('utf8')){return binary_to_atom(a,b)},list_concatenation:function list_concatenation(a,b){return a.concat(b)},list_subtraction:function list_subtraction(a,b){const c=[...a];for(const d of b){const a=c.indexOf(d);-1>b},bxor:function bxor(a,b){return a^b},bnot:function bnot(a){return~a},is_bitstring:is_bitstring$1,is_boolean:function is_boolean$1(a){return'boolean'==typeof a||a instanceof Boolean},is_float:function is_float(a){return is_number$1(a)&&!b(a)},is_function:function is_function$1(a){return'function'==typeof a||a instanceof Function},is_integer,is_list:function is_list(a){return Array.isArray(a)},is_map:function is_map$1(a){return a instanceof Map},is_number:is_number$1,is_pid:function is_pid(a){return a instanceof e.PID},is_port:function is_port(){return!1},is_reference:function is_reference(a){return a instanceof e.Reference},is_tuple:function is_tuple(a){return a instanceof e.Tuple},is_atom:function is_atom(a){return'symbol'==typeof a||a instanceof Symbol||a.__MODULE__},is_binary,element:function element(a,b){return b.get(a-1)},setelement:function setelement(a,b,c){const d=[...b.values];return d[a-1]=c,new e.Tuple(...d)},make_tuple:function make_tuple(a,b){const c=[];for(let d=0;d!0){let d=[],e=buildMatch(a);const f=e(b,d),[g,h]=checkNamedVariables(d);if(f&&h&&c.apply(this,g))return g;throw console.error('No match for:',b),new MatchError(b)},MatchError,variable:function variable(a=null,b=Symbol.for('tailored.no_value')){return new Variable(a,b)},wildcard:function wildcard(){return new Wildcard},startsWith:function startsWith(a){return new StartsWith(a)},capture:function capture(a){return new Capture(a)},headTail:function headTail(){return new HeadTail},type:function a(a,b={}){return new Type(a,b)},bound:function bound(a){return new Bound(a)},Clause,clause:function clause(a,b,c=()=>!0){return new Clause(a,b,c)},bitStringMatch:function bitStringMatch(...a){return new BitStringMatch(...a)},match_or_default,defmatchgen,list_comprehension:function list_comprehension(a,b){const c=run_generators(b.pop()(),b);let d=[];for(let e of c)a.guard.apply(this,e)&&d.push(a.fn.apply(this,e));return d},list_generator:function list_generator(a,b){return function(){let c=[];for(let d of b){const b=match_or_default(a,d,()=>!0,h);if(b!=h){const[a]=b;c.push(a)}}return c}},bitstring_generator:function bitstring_generator(a,b){return function(){let c=[],d=b.slice(0,a.byte_size()),e=1;for(;d.byte_size==a.byte_size();){const f=match_or_default(a,d,()=>!0,h);if(f!=h){c.push(f)}d=b.slice(a.byte_size()*e,a.byte_size()*(e+1)),e++}return c}},bitstring_comprehension:function bitstring_comprehension(a,b){const c=run_generators(b.pop()(),b);let d=[];for(let e of c)a.guard.apply(this,e)&&d.push(a.fn.apply(this,e));return d=d.map((a)=>e.BitString.integer(a)),new e.BitString(...d)},defmatchGen:function defmatchGen(...a){return defmatchgen(...a)},defmatchAsync:function defmatchAsync(...a){const b=getArityMap(a);return async function(...a){if(b.has(a.length)){const c=b.get(a.length);let d=null,e=null;for(let b of c){let c=[];a=fillInOptionalValues(a,b.arity,b.optionals);const f=b.pattern(a,c),[g,h]=checkNamedVariables(c);if(f&&h&&(await b.guard.apply(this,c))){d=b.fn,e=c;break}}if(!d)throw console.error('No match for:',a),new MatchError(a);return d.apply(this,e)}throw console.error('Arity of',a.length,'not found. No match for:',a),new MatchError(a)}}},Integer:class Integer{},Float:class Float{},Functions:{call_property:function call_property(a,b){if(!b)return a instanceof Function||'function'==typeof a?a():a;if(a instanceof Map){let c=null;if(a.has(b)?c=b:a.has(Symbol.for(b))&&(c=Symbol.for(b)),null===c)throw new Error(`Property ${b} not found in ${a}`);return a.get(c)instanceof Function||'function'==typeof a.get(c)?a.get(c)():a.get(c)}let c=null;if('number'==typeof a||'symbol'==typeof a||'boolean'==typeof a||'string'==typeof a?void 0===a[b]?void 0!==a[Symbol.for(b)]&&(c=Symbol.for(b)):c=b:b in a?c=b:Symbol.for(b)in a&&(c=Symbol.for(b)),null===c)throw new Error(`Property ${b} not found in ${a}`);return a[c]instanceof Function||'function'==typeof a[c]?a[c]():a[c]},defprotocol:function defprotocol(a){return new Protocol(a)},defimpl:function defimpl(a,b,c){a.implementation(b,c)},build_namespace:function build_namespace(a,b){let c=b.split('.');const d=a;let e=a;'Elixir'===c[0]&&(c=c.slice(1));for(const d of c)'undefined'==typeof e[d]&&(e[d]={}),e=e[d];return d.__table__=a.__table__||{},d.__table__[Symbol.for(b)]=e,e},iterator_to_reducer,map_to_object},SpecialForms:{_case:function _case(a,b){return o.Patterns.defmatch(...b)(a)},cond:function cond(...a){for(const b of a)if(b[0])return b[1]();throw new Error},_for:function _for(a,b,c,d=[]){let[e,f]=c.into(d);const g=run_list_generators(b.pop()(),b);for(const h of g)a.guard.apply(this,h)&&(e=f(e,new o.Tuple(Symbol.for('cont'),a.fn.apply(this,h))));return f(e,Symbol.for('done'))},_try:function _try(a,b,c,d,e){let f=null;try{f=a()}catch(a){let d=null;if(b)try{return d=b(a),d}catch(a){if(a instanceof o.Patterns.MatchError)throw a}if(c)try{return d=c(a),d}catch(a){if(a instanceof o.Patterns.MatchError)throw a}throw a}finally{e&&e()}if(d)try{return d(f)}catch(a){if(a instanceof o.Patterns.MatchError)throw new Error('No Match Found in Else');throw a}else return f},_with:function _with(...a){let b=[],c=null,d=null;'function'==typeof a[a.length-2]?[c,d]=a.splice(-2):c=a.pop();for(let c=0;c{const[c,d]=b;return a.set(c,d),a},new Map)},keys:function keys(a){return!1===i.is_map(a)?new e.Tuple(l,a):Array.from(a.keys())},values:function values$1(a){return!1===i.is_map(a)?new e.Tuple(l,a):Array.from(a.values())},is_key,put:function put(a,b,c){if(!1===i.is_map(c))return new e.Tuple(l,c);const d=new Map(c);return d.set(a,b),d},merge:function merge(a,b){return!1===i.is_map(a)?new e.Tuple(l,a):!1===i.is_map(b)?new e.Tuple(l,b):new Map([...a,...b])},update:function update(a,b,c){return!1===i.is_map(c)?new e.Tuple(l,c):!1===is_key(a,c)?new e.Tuple(m,a):new Map([...c,[a,b]])},get:function get(...a){const b=a[0],c=a[1];return!1===i.is_map(c)?new e.Tuple(l,c):is_key(b)?c.get(b):3===a.length?a[2]:new e.Tuple(m,b)},take:function take(a,b){if(!1===i.is_map(b))return new e.Tuple(l,b);if(!is_key(a))return k;const c=b.get(a),d=new Map(b);return d.delete(a),new e.Tuple(c,d)}},lists:{reverse,foreach:function foreach(a,b){return b.forEach((b)=>a(b)),Symbol.for('ok')},duplicate:function duplicate(a,b){const c=[];for(;c.length{if(d.get(c-1)a.get(c-1)?1:0})},keystore:function keystore(a,b,c,d){const e=[...c];for(let f=0;fa.toString()).join()},map:function map(a,b){return b.map((b)=>a(b))},filter:function filter(a,b){return b.filter((b)=>a(b))},filtermap:function filtermap(a,b){const c=[];for(const d of b){const b=a(d);!0===b?c.push(d):b instanceof e.Tuple&&!0===b.get(0)&&c.push(b.get(1))}return c},member:function member(a,b){for(const c of b)if(c===a)return!0;return!1},all:function all(a,b){for(const c of b)if(!1===a(c))return!1;return!0},any:function any(a,b){for(const c of b)if(!0===a(c))return!0;return!1},splitwith:function splitwith(a,b){let c=!1;const d=[],f=[];for(const e of b)!0==c?f.push(e):!0===a(e)?d.push(e):(c=!0,f.push(e));return new e.Tuple(d,f)},sort:function sort(...a){if(1===a.length){const b=[...a[0]];return b.sort()}const c=a[0],b=[...a[1]];return b.sort((d,a)=>{const b=c(d,a);return!0===b?-1:1})}},elixir_errors:{warn:function warn(a){const b=a.join('');return console.warn(`warning: ${b}`),Symbol.for('ok')}},io:{put_chars:function put_chars(b,c){let d=null;return d=Array.isArray(c)?a(...c):c,b===Symbol.for('stderr')?console.error(d):console.log(d),Symbol.for('ok')}},binary:{copy:function copy(a,b=1){return a.repeat(b)}}};return{Core:o}}(); +var ElixirScript=function(){'use strict';/* @flow */function namedVariableResult(a,b){return new NamedVariableResult(a,b)}/* @flow */function is_number(a){return'number'==typeof a}function is_string(a){return'string'==typeof a}function is_boolean(a){return'boolean'==typeof a}function is_symbol(a){return'symbol'==typeof a}function is_object(a){return'object'==typeof a}function is_variable(a){return a instanceof Variable}function is_null(a){return null===a}function is_array(a){return Array.isArray(a)}function is_function(a){return'[object Function]'==Object.prototype.toString.call(a)}function is_map(a){return a instanceof Map}function resolveNull(){return function(a){return is_null(a)}}function resolveWildcard(){return function(){return!0}}function resolveObject(a){let b={};const c=Object.keys(a).concat(Object.getOwnPropertySymbols(a));for(let d of c)b[d]=buildMatch(a[d]);return function(d,e){if(!is_object(d)||a.length>d.length)return!1;for(let a of c)if(!(a in d)||!b[a](d[a],e))return!1;return!0}}function getSize(a,b){return a*b/8}function arraysEqual(c,a){if(c===a)return!0;if(null==c||null==a)return!1;if(c.length!=a.length)return!1;for(var b=0;be.integer(a));return new e(...b)}function resolveNoMatch(){return function(){return!1}}function buildMatch(a){if(null===a)return resolveNull(a);if('undefined'==typeof a)return resolveWildcard(a);const b=a.constructor.prototype,c=f.get(b);return c?c(a):'object'==typeof a?resolveObject(a):resolveNoMatch()}function defmatchgen(...a){const b=getArityMap(a);return function*(...a){let[c,d]=findMatchingFunction(a,b);return yield*c.apply(this,d)}}function findMatchingFunction(a,b){if(b.has(a.length)){const c=b.get(a.length);let d=null,e=null;for(let b of c){let c=[];a=fillInOptionalValues(a,b.arity,b.optionals);const f=b.pattern(a,c),[g,h]=checkNamedVariables(c);if(f&&h&&b.guard.apply(this,g)){d=b.fn,e=g;break}}if(!d)throw console.error('No match for:',a),new MatchError(a);return[d,e]}throw console.error('Arity of',a.length,'not found. No match for:',a),new MatchError(a)}function getArityMap(a){let b=new Map;for(const c of a){const a=getArityRange(c);for(const d of a){let a=[];b.has(d)&&(a=b.get(d)),a.push(c),b.set(d,a)}}return b}function getArityRange(a){const b=a.arity-a.optionals.length,c=a.arity;let d=[b];for(;d[d.length-1]!=c;)d.push(d[d.length-1]+1);return d}function getOptionalValues(a){let b=[];for(let c=0;c!0,d=null){let e=[],f=buildMatch(a);const g=f(b,e),[h,i]=checkNamedVariables(e);return g&&i&&c.apply(this,h)?h:d}function run_generators(a,b){if(0==b.length)return a.map((a)=>{return Array.isArray(a)?a:[a]});const c=b.pop();let d=[];for(let e of c())for(let b of a)d.push([e].concat(b));return run_generators(d,b)}function iterator_to_reducer(a,b,c){const d=a[Symbol.iterator]();let e=d.next(),f=b;for(;!1===e.done;){if(f=c(e.value,f.get(1)),f.get(0)===Symbol.for('halt'))return new o.Tuple(Symbol.for('halted'),f.get(1));if(f.get(0)===Symbol.for('suspend'))return new o.Tuple(Symbol.for('suspended'),f.get(1),(a)=>{return iterator_to_reducer(d,a,c)});e=d.next()}return new o.Tuple(Symbol.for('done'),f.get(1))}function map_to_object(a){const b={};for(const[c,d]of a.entries())b[c]=d instanceof Map?map_to_object(d):d;return b}function run_list_generators(a,b){if(0==b.length)return a.map((a)=>{return Array.isArray(a)?a:[a]});const c=b.pop(),d=[];for(const e of c())for(const b of a)d.push([e].concat(b));return run_list_generators(d,b)}// http://erlang.org/doc/man/lists.html +function reverse(a){return[...a]}function flatten(a,b=[]){const c=a.reduce((a,b)=>{return Array.isArray(b)?a.concat(flatten(b)):a.concat(b)},[]);return c.concat(b)}function foldl(a,b,c){return c.reduce((b,c)=>{return a(c,b)},b)}function keyfind(a,b,c){for(const d of c)if(d.get(b-1)===a)return d;return!1}function keydelete(a,b,c){const d=[];let e=!1;for(let f=0;f{if(null===c)return a;return is_integer(c)?a+b(c):is_bitstring$1(c)?a+b(...c.value):a+iolist_to_binary(c)},'');return d}function is_key(a,b){return b.has(a)}function get_key(a){let b=a;if(__elixirscript_names__.has(a)&&(b=__elixirscript_names__.get(a)),__elixirscript_store__.has(b))return b;throw new Error(`Key ${b} not found`)}var a=Number.isInteger;class Variable{constructor(a=null,b=Symbol.for('tailored.no_value')){this.name=a,this.default_value=b}}class Wildcard{constructor(){}}class StartsWith{constructor(a){this.prefix=a}}class Capture{constructor(a){this.value=a}}class HeadTail{constructor(){}}class Type{constructor(a,b={}){this.type=a,this.objPattern=b}}class Bound{constructor(a){this.value=a}}class BitStringMatch{constructor(...a){this.values=a}length(){return values.length}bit_size(){return 8*this.byte_size()}byte_size(){let a=0;for(let b of this.values)a+=b.unit*b.size/8;return a}getValue(a){return this.values(a)}getSizeOfValue(a){let b=this.getValue(a);return b.unit*b.size}getTypeOfValue(a){return this.getValue(a).type}}class NamedVariableResult{constructor(a,b){this.name=a,this.value=b}}class Tuple{constructor(...a){this.values=Object.freeze(a),this.length=this.values.length}get(a){return this.values[a]}count(){return this.values.length}[Symbol.iterator](){return this.values[Symbol.iterator]()}toString(){let a,b='';for(a=0;aBitString$1.integer(a));return new BitString$1(...d)}[Symbol.iterator](){return this.value[Symbol.iterator]()}toString(){var a,b='';for(a=0;a>'}process(a){let b=[];var c;for(c=0;cb?c.push(b):2048>b?c.push(192|b>>6,128|63&b):55296>b||57344<=b?c.push(224|b>>12,128|63&b>>6,128|63&b):(d++,b=65536+((1023&b)<<10|1023&a.charCodeAt(d)),c.push(240|b>>18,128|63&b>>12,128|63&b>>6,128|63&b));return c}static toUTF16Array(a){for(var b,c=[],d=0;d=b?(c.push(0),c.push(b)):(c.push(255&b>>8),c.push(255&b));return c}static toUTF32Array(a){for(var b,c=[],d=0;d=b?(c.push(0),c.push(0),c.push(0),c.push(b)):(c.push(0),c.push(0),c.push(255&b>>8),c.push(255&b));return c}//http://stackoverflow.com/questions/2003493/javascript-float-from-to-bits +static float32ToBytes(a){var b=[],c=new ArrayBuffer(4);new Float32Array(c)[0]=a;let d=new Uint32Array(c)[0];return b.push(255&d>>24),b.push(255&d>>16),b.push(255&d>>8),b.push(255&d),b}static float64ToBytes(a){var b=[],c=new ArrayBuffer(8);new Float64Array(c)[0]=a;var d=new Uint32Array(c)[0],e=new Uint32Array(c)[1];return b.push(255&e>>24),b.push(255&e>>16),b.push(255&e>>8),b.push(255&e),b.push(255&d>>24),b.push(255&d>>16),b.push(255&d>>8),b.push(255&d),b}}var d={Tuple,PID:class PID{constructor(){++b,this.id=b}toString(){return'PID#<0.'+this.id+'.0>'}},Reference:class Reference{constructor(){++c,this.id=c,this.ref=Symbol()}toString(){return'Ref#<0.0.0.'+this.id+'>'}},BitString:BitString$1};/* @flow */const e=d.BitString,f=new Map;f.set(Variable.prototype,function resolveVariable(a){return function(b,c){return null===a.name?c.push(b):!a.name.startsWith('_')&&c.push(namedVariableResult(a.name,b)),!0}}),f.set(Wildcard.prototype,resolveWildcard),f.set(HeadTail.prototype,function resolveHeadTail(){return function(a,b){if(!is_array(a)||0===a.length)return!1;const c=a[0],d=a.slice(1);return b.push(c),b.push(d),!0}}),f.set(StartsWith.prototype,function resolveStartsWith(a){const b=a.prefix;return function(a,c){return is_string(a)&&a.startsWith(b)&&(c.push(a.substring(b.length)),!0)}}),f.set(Capture.prototype,function resolveCapture(a){const b=buildMatch(a.value);return function(a,c){return!!b(a,c)&&(c.push(a),!0)}}),f.set(Bound.prototype,function resolveBound(a){return function(b){return typeof b==typeof a.value&&b===a.value}}),f.set(Type.prototype,function resolveType(a){return function(b,c){if(b instanceof a.type){const d=buildMatch(a.objPattern);return d(b,c)}return!1}}),f.set(BitStringMatch.prototype,function resolveBitString(a){let b=[];for(let c of a.values)if(is_variable(c.value)){let a=getSize(c.unit,c.size);fillArray(b,a)}else b=b.concat(new e(c).value);let c=a.values;return function(a,d){var f=String.fromCharCode;let g=null;if(!is_string(a)&&!(a instanceof e))return!1;g=is_string(a)?new e(e.binary(a)):a;let h=0;for(let e,j=0;jd.size)return!1;for(let a of c)if(!d.has(a)||!b.get(a)(d.get(a),e))return!1;return!0}}),f.set(Array.prototype,function resolveArray(a){const b=a.map((a)=>buildMatch(a));return function(c,d){return is_array(c)&&c.length==a.length&&c.every(function(a,e){return b[e](c[e],d)})}}),f.set(String.prototype,function resolveString(a){return function(b){return is_string(b)&&b===a}}),f.set(Boolean.prototype,function resolveBoolean(a){return function(b){return is_boolean(b)&&b===a}}),f.set(Function.prototype,function resolveFunction(a){return function(b){return is_function(b)&&b===a}}),f.set(Object.prototype,resolveObject);class MatchError extends Error{constructor(a){if(super(),'symbol'==typeof a)this.message='No match for: '+a.toString();else if(Array.isArray(a)){let b=a.map((a)=>{return null===a?'null':'undefined'==typeof a?'undefined':a.toString()});this.message='No match for: '+b}else this.message='No match for: '+a;this.stack=new Error().stack,this.name=this.constructor.name}}class Clause{constructor(a,b,c=()=>!0){this.pattern=buildMatch(a),this.arity=a.length,this.optionals=getOptionalValues(a),this.fn=b,this.guard=c}}const g=Symbol();// https://github.com/airportyh/protomorphism +class Protocol{constructor(b){function createFun(b){return function(...c){const d=c[0];let e=null;if(null===d&&this.hasImplementation(Symbol('null'))?e=this.registry.get(Symbol)[b]:a(d)&&this.hasImplementation(o.Integer)?e=this.registry.get(o.Integer)[b]:'number'==typeof d&&!a(d)&&this.hasImplementation(o.Float)?e=this.registry.get(o.Float)[b]:'string'==typeof d&&this.hasImplementation(o.BitString)?e=this.registry.get(o.BitString)[b]:d&&d.has(Symbol.for('__struct__'))&&this.hasImplementation(d)?e=this.registry.get(d.get(Symbol.for('__struct__')).__MODULE__)[b]:null!==d&&this.hasImplementation(d)?e=this.registry.get(d.constructor)[b]:this.fallback&&(e=this.fallback[b]),null!=e){const a=e.apply(this,c);return a}throw new Error(`No implementation found for ${d}`)}}for(const a in this.registry=new Map,this.fallback=null,b)this[a]=createFun(a).bind(this)}implementation(a,b){null===a?this.fallback=b:this.registry.set(a,b)}hasImplementation(a){if(a===o.Integer||a===o.Float||a===o.BitString)return this.registry.has(a);return a&&a.has(Symbol.for('__struct__'))?this.registry.has(a.get(Symbol.for('__struct__')).__MODULE__):this.registry.has(a.constructor)}}var h={reverse,foreach:function foreach(a,b){return b.forEach((b)=>a(b)),Symbol.for('ok')},duplicate:function duplicate(a,b){const c=[];for(;c.length{if(d.get(c-1)a.get(c-1)?1:0})},keystore:function keystore(a,b,c,d){const e=[...c];for(let f=0;fa.toString()).join()},map:function map(a,b){return b.map((b)=>a(b))},filter:function filter(a,b){return b.filter((b)=>a(b))},filtermap:function filtermap(a,b){const c=[];for(const e of b){const b=a(e);!0===b?c.push(e):b instanceof d.Tuple&&!0===b.get(0)&&c.push(b.get(1))}return c},member:function member(a,b){for(const c of b)if(c===a)return!0;return!1},all:function all(a,b){for(const c of b)if(!1===a(c))return!1;return!0},any:function any(a,b){for(const c of b)if(!0===a(c))return!0;return!1},splitwith:function splitwith(a,b){let c=!1;const e=[],f=[];for(const d of b)!0==c?f.push(d):!0===a(d)?e.push(d):(c=!0,f.push(d));return new d.Tuple(e,f)},sort:function sort(...a){if(1===a.length){const b=[...a[0]];return b.sort()}const c=a[0],b=[...a[1]];return b.sort((d,a)=>{const b=c(d,a);return!0===b?-1:1})}},i={atom_to_binary,binary_to_atom,binary_to_existing_atom:function binary_to_existing_atom(a,b=Symbol.for('utf8')){return binary_to_atom(a,b)},list_concatenation:function list_concatenation(a,b){return a.concat(b)},list_subtraction:function list_subtraction(a,b){const c=[...a];for(const d of b){const a=c.indexOf(d);-1>b},bxor:function bxor(a,b){return a^b},bnot:function bnot(a){return~a},is_bitstring:is_bitstring$1,is_boolean:function is_boolean$1(a){return'boolean'==typeof a||a instanceof Boolean},is_float:function is_float(b){return is_number$1(b)&&!a(b)},is_function:function is_function$1(a){return'function'==typeof a||a instanceof Function},is_integer,is_list:function is_list(a){return Array.isArray(a)},is_map:function is_map$1(a){return a instanceof Map},is_number:is_number$1,is_pid:function is_pid(a){return a instanceof d.PID},is_port:function is_port(){return!1},is_reference:function is_reference(a){return a instanceof d.Reference},is_tuple:function is_tuple(a){return a instanceof d.Tuple},is_atom:function is_atom(a){return'symbol'==typeof a||a instanceof Symbol||a.__MODULE__},is_binary,element:function element(a,b){return b.get(a-1)},setelement:function setelement(a,b,c){const e=[...b.values];return e[a-1]=c,new d.Tuple(...e)},make_tuple:function make_tuple(a,b){const c=[];for(let d=0;d!0){let d=[],e=buildMatch(a);const f=e(b,d),[g,h]=checkNamedVariables(d);if(f&&h&&c.apply(this,g))return g;throw console.error('No match for:',b),new MatchError(b)},MatchError,variable:function variable(a=null,b=Symbol.for('tailored.no_value')){return new Variable(a,b)},wildcard:function wildcard(){return new Wildcard},startsWith:function startsWith(a){return new StartsWith(a)},capture:function capture(a){return new Capture(a)},headTail:function headTail(){return new HeadTail},type:function a(a,b={}){return new Type(a,b)},bound:function bound(a){return new Bound(a)},Clause,clause:function clause(a,b,c=()=>!0){return new Clause(a,b,c)},bitStringMatch:function bitStringMatch(...a){return new BitStringMatch(...a)},match_or_default,defmatchgen,list_comprehension:function list_comprehension(a,b){const c=run_generators(b.pop()(),b);let d=[];for(let e of c)a.guard.apply(this,e)&&d.push(a.fn.apply(this,e));return d},list_generator:function list_generator(a,b){return function(){let c=[];for(let d of b){const b=match_or_default(a,d,()=>!0,g);if(b!=g){const[a]=b;c.push(a)}}return c}},bitstring_generator:function bitstring_generator(a,b){return function(){let c=[],d=b.slice(0,a.byte_size()),e=1;for(;d.byte_size==a.byte_size();){const f=match_or_default(a,d,()=>!0,g);if(f!=g){c.push(f)}d=b.slice(a.byte_size()*e,a.byte_size()*(e+1)),e++}return c}},bitstring_comprehension:function bitstring_comprehension(a,b){const c=run_generators(b.pop()(),b);let e=[];for(let d of c)a.guard.apply(this,d)&&e.push(a.fn.apply(this,d));return e=e.map((a)=>d.BitString.integer(a)),new d.BitString(...e)},defmatchGen:function defmatchGen(...a){return defmatchgen(...a)},defmatchAsync:function defmatchAsync(...a){const b=getArityMap(a);return async function(...a){if(b.has(a.length)){const c=b.get(a.length);let d=null,e=null;for(let b of c){let c=[];a=fillInOptionalValues(a,b.arity,b.optionals);const f=b.pattern(a,c),[g,h]=checkNamedVariables(c);if(f&&h&&(await b.guard.apply(this,c))){d=b.fn,e=c;break}}if(!d)throw console.error('No match for:',a),new MatchError(a);return d.apply(this,e)}throw console.error('Arity of',a.length,'not found. No match for:',a),new MatchError(a)}}},Integer:class Integer{},Float:class Float{},Functions:{call_property:function call_property(a,b){if(!b)return a instanceof Function||'function'==typeof a?a():a;if(a instanceof Map){let c=null;if(a.has(b)?c=b:a.has(Symbol.for(b))&&(c=Symbol.for(b)),null===c)throw new Error(`Property ${b} not found in ${a}`);return a.get(c)instanceof Function||'function'==typeof a.get(c)?a.get(c)():a.get(c)}let c=null;if('number'==typeof a||'symbol'==typeof a||'boolean'==typeof a||'string'==typeof a?void 0===a[b]?void 0!==a[Symbol.for(b)]&&(c=Symbol.for(b)):c=b:b in a?c=b:Symbol.for(b)in a&&(c=Symbol.for(b)),null===c)throw new Error(`Property ${b} not found in ${a}`);return a[c]instanceof Function||'function'==typeof a[c]?a[c]():a[c]},defprotocol:function defprotocol(a){return new Protocol(a)},defimpl:function defimpl(a,b,c){a.implementation(b,c)},build_namespace:function build_namespace(a,b){let c=b.split('.');const d=a;let e=a;'Elixir'===c[0]&&(c=c.slice(1));for(const d of c)'undefined'==typeof e[d]&&(e[d]={}),e=e[d];return d.__table__=a.__table__||{},d.__table__[Symbol.for(b)]=e,e},iterator_to_reducer,map_to_object},SpecialForms:{_case:function _case(a,b){return o.Patterns.defmatch(...b)(a)},cond:function cond(...a){for(const b of a)if(b[0])return b[1]();throw new Error},_for:function _for(a,b,c,d=[]){let[e,f]=c.into(d);const g=run_list_generators(b.pop()(),b);for(const h of g)a.guard.apply(this,h)&&(e=f(e,new o.Tuple(Symbol.for('cont'),a.fn.apply(this,h))));return f(e,Symbol.for('done'))},_try:function _try(a,b,c,d,e){let f=null;try{f=a()}catch(a){let d=null;if(b)try{return d=b(a),d}catch(a){if(a instanceof o.Patterns.MatchError)throw a}if(c)try{return d=c(a),d}catch(a){if(a instanceof o.Patterns.MatchError)throw a}throw a}finally{e&&e()}if(d)try{return d(f)}catch(a){if(a instanceof o.Patterns.MatchError)throw new Error('No Match Found in Else');throw a}else return f},_with:function _with(...a){let b=[],c=null,d=null;'function'==typeof a[a.length-2]?[c,d]=a.splice(-2):c=a.pop();for(let c=0;c{const[c,d]=b;return a.set(c,d),a},new Map)},keys:function keys(a){return!1===i.is_map(a)?new d.Tuple(l,a):Array.from(a.keys())},values:function values$1(a){return!1===i.is_map(a)?new d.Tuple(l,a):Array.from(a.values())},is_key,put:function put(a,b,c){if(!1===i.is_map(c))return new d.Tuple(l,c);const e=new Map(c);return e.set(a,b),e},merge:function merge(a,b){return!1===i.is_map(a)?new d.Tuple(l,a):!1===i.is_map(b)?new d.Tuple(l,b):new Map([...a,...b])},update:function update(a,b,c){return!1===i.is_map(c)?new d.Tuple(l,c):!1===is_key(a,c)?new d.Tuple(m,a):new Map([...c,[a,b]])},get:function get(...a){const b=a[0],c=a[1];return!1===i.is_map(c)?new d.Tuple(l,c):is_key(b)?c.get(b):3===a.length?a[2]:new d.Tuple(m,b)},take:function take(a,b){if(!1===i.is_map(b))return new d.Tuple(l,b);if(!is_key(a))return k;const c=b.get(a),e=new Map(b);return e.delete(a),new d.Tuple(c,e)}},lists:h,elixir_errors:{warn:function warn(a){const b=a.join('');return console.warn(`warning: ${b}`),Symbol.for('ok')}},io:{put_chars:function put_chars(a,b){let c=i.iolist_to_binary(b);return a===Symbol.for('stderr')?console.error(c):console.log(c),Symbol.for('ok')}},binary:{copy:function copy(a,b=1){return a.repeat(b)}}};return{Core:o}}(); diff --git a/src/javascript/lib/core/erlang_compat/erlang.js b/src/javascript/lib/core/erlang_compat/erlang.js index 94eea63e..683ba0f6 100644 --- a/src/javascript/lib/core/erlang_compat/erlang.js +++ b/src/javascript/lib/core/erlang_compat/erlang.js @@ -1,5 +1,6 @@ // http://erlang.org/doc/man/erlang.html import ErlangTypes from 'erlang-types'; +import lists from './lists'; function atom_to_binary(atom, encoding = Symbol.for('utf8')) { if (encoding !== Symbol.for('utf8')) { @@ -270,6 +271,10 @@ function process_info(pid, item) { } function iolist_to_binary(ioListOrBinary) { + if (ioListOrBinary === null) { + return ''; + } + if (is_binary(ioListOrBinary)) { return ioListOrBinary; } @@ -278,8 +283,12 @@ function iolist_to_binary(ioListOrBinary) { return String.fromCodePoint(...ioListOrBinary.value); } - const value = ioListOrBinary.reduce((acc, current) => { - if (is_integer(current)) { + const iolistFlattened = lists.flatten(ioListOrBinary); + + const value = iolistFlattened.reduce((acc, current) => { + if (current === null) { + return acc; + } else if (is_integer(current)) { return acc + String.fromCodePoint(current); } else if (is_bitstring(current)) { return acc + String.fromCodePoint(...current.value); diff --git a/src/javascript/lib/core/erlang_compat/io.js b/src/javascript/lib/core/erlang_compat/io.js index 9d7eccb3..d01c42c6 100644 --- a/src/javascript/lib/core/erlang_compat/io.js +++ b/src/javascript/lib/core/erlang_compat/io.js @@ -1,11 +1,7 @@ -function put_chars(ioDevice, charData) { - let dataToWrite = null; +import erlang from './erlang'; - if (Array.isArray(charData)) { - dataToWrite = String.fromCodePoint(...charData); - } else { - dataToWrite = charData; - } +function put_chars(ioDevice, charData) { + let dataToWrite = erlang.iolist_to_binary(charData); if (ioDevice === Symbol.for('stderr')) { console.error(dataToWrite); From 3938cc9b0d41e698d1ea395635bf98b53fa49131 Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Thu, 27 Jul 2017 20:45:25 -0500 Subject: [PATCH 195/418] Update list concat translation to not wrap extra list --- lib/elixir_script/passes/translate/form.ex | 12 + package.json | 2 +- priv/build/iife/ElixirScript.Core.js | 2565 ++++++++++++++++++- src/javascript/lib/core/erlang_compat/io.js | 2 +- src/javascript/lib/core/protocol.js | 7 +- yarn.lock | 6 +- 6 files changed, 2582 insertions(+), 12 deletions(-) diff --git a/lib/elixir_script/passes/translate/form.ex b/lib/elixir_script/passes/translate/form.ex index 1ba9b7ff..a447a9b2 100644 --- a/lib/elixir_script/passes/translate/form.ex +++ b/lib/elixir_script/passes/translate/form.ex @@ -22,6 +22,18 @@ defmodule ElixirScript.Translate.Form do { J.literal(form), state } end + def compile([{:|, _, [head, tail]}], state) do + ast = J.call_expression( + J.member_expression( + J.array_expression([compile!(head, state)]), + J.identifier("concat") + ), + [compile!(tail, state)] + ) + + { ast, state } + end + def compile({:|, _, [head, tail]}, state) do ast = J.call_expression( J.member_expression( diff --git a/package.json b/package.json index d9d19d63..95032896 100644 --- a/package.json +++ b/package.json @@ -23,7 +23,7 @@ "license": "MIT", "dependencies": { "erlang-types": "^1.0.1", - "tailored": "^2.6.3" + "tailored": "^2.6.4" }, "devDependencies": { "ava": "^0.21.0", diff --git a/priv/build/iife/ElixirScript.Core.js b/priv/build/iife/ElixirScript.Core.js index 850b7ab7..80caf094 100644 --- a/priv/build/iife/ElixirScript.Core.js +++ b/priv/build/iife/ElixirScript.Core.js @@ -1,6 +1,2559 @@ -var ElixirScript=function(){'use strict';/* @flow */function namedVariableResult(a,b){return new NamedVariableResult(a,b)}/* @flow */function is_number(a){return'number'==typeof a}function is_string(a){return'string'==typeof a}function is_boolean(a){return'boolean'==typeof a}function is_symbol(a){return'symbol'==typeof a}function is_object(a){return'object'==typeof a}function is_variable(a){return a instanceof Variable}function is_null(a){return null===a}function is_array(a){return Array.isArray(a)}function is_function(a){return'[object Function]'==Object.prototype.toString.call(a)}function is_map(a){return a instanceof Map}function resolveNull(){return function(a){return is_null(a)}}function resolveWildcard(){return function(){return!0}}function resolveObject(a){let b={};const c=Object.keys(a).concat(Object.getOwnPropertySymbols(a));for(let d of c)b[d]=buildMatch(a[d]);return function(d,e){if(!is_object(d)||a.length>d.length)return!1;for(let a of c)if(!(a in d)||!b[a](d[a],e))return!1;return!0}}function getSize(a,b){return a*b/8}function arraysEqual(c,a){if(c===a)return!0;if(null==c||null==a)return!1;if(c.length!=a.length)return!1;for(var b=0;be.integer(a));return new e(...b)}function resolveNoMatch(){return function(){return!1}}function buildMatch(a){if(null===a)return resolveNull(a);if('undefined'==typeof a)return resolveWildcard(a);const b=a.constructor.prototype,c=f.get(b);return c?c(a):'object'==typeof a?resolveObject(a):resolveNoMatch()}function defmatchgen(...a){const b=getArityMap(a);return function*(...a){let[c,d]=findMatchingFunction(a,b);return yield*c.apply(this,d)}}function findMatchingFunction(a,b){if(b.has(a.length)){const c=b.get(a.length);let d=null,e=null;for(let b of c){let c=[];a=fillInOptionalValues(a,b.arity,b.optionals);const f=b.pattern(a,c),[g,h]=checkNamedVariables(c);if(f&&h&&b.guard.apply(this,g)){d=b.fn,e=g;break}}if(!d)throw console.error('No match for:',a),new MatchError(a);return[d,e]}throw console.error('Arity of',a.length,'not found. No match for:',a),new MatchError(a)}function getArityMap(a){let b=new Map;for(const c of a){const a=getArityRange(c);for(const d of a){let a=[];b.has(d)&&(a=b.get(d)),a.push(c),b.set(d,a)}}return b}function getArityRange(a){const b=a.arity-a.optionals.length,c=a.arity;let d=[b];for(;d[d.length-1]!=c;)d.push(d[d.length-1]+1);return d}function getOptionalValues(a){let b=[];for(let c=0;c!0,d=null){let e=[],f=buildMatch(a);const g=f(b,e),[h,i]=checkNamedVariables(e);return g&&i&&c.apply(this,h)?h:d}function run_generators(a,b){if(0==b.length)return a.map((a)=>{return Array.isArray(a)?a:[a]});const c=b.pop();let d=[];for(let e of c())for(let b of a)d.push([e].concat(b));return run_generators(d,b)}function iterator_to_reducer(a,b,c){const d=a[Symbol.iterator]();let e=d.next(),f=b;for(;!1===e.done;){if(f=c(e.value,f.get(1)),f.get(0)===Symbol.for('halt'))return new o.Tuple(Symbol.for('halted'),f.get(1));if(f.get(0)===Symbol.for('suspend'))return new o.Tuple(Symbol.for('suspended'),f.get(1),(a)=>{return iterator_to_reducer(d,a,c)});e=d.next()}return new o.Tuple(Symbol.for('done'),f.get(1))}function map_to_object(a){const b={};for(const[c,d]of a.entries())b[c]=d instanceof Map?map_to_object(d):d;return b}function run_list_generators(a,b){if(0==b.length)return a.map((a)=>{return Array.isArray(a)?a:[a]});const c=b.pop(),d=[];for(const e of c())for(const b of a)d.push([e].concat(b));return run_list_generators(d,b)}// http://erlang.org/doc/man/lists.html -function reverse(a){return[...a]}function flatten(a,b=[]){const c=a.reduce((a,b)=>{return Array.isArray(b)?a.concat(flatten(b)):a.concat(b)},[]);return c.concat(b)}function foldl(a,b,c){return c.reduce((b,c)=>{return a(c,b)},b)}function keyfind(a,b,c){for(const d of c)if(d.get(b-1)===a)return d;return!1}function keydelete(a,b,c){const d=[];let e=!1;for(let f=0;f{if(null===c)return a;return is_integer(c)?a+b(c):is_bitstring$1(c)?a+b(...c.value):a+iolist_to_binary(c)},'');return d}function is_key(a,b){return b.has(a)}function get_key(a){let b=a;if(__elixirscript_names__.has(a)&&(b=__elixirscript_names__.get(a)),__elixirscript_store__.has(b))return b;throw new Error(`Key ${b} not found`)}var a=Number.isInteger;class Variable{constructor(a=null,b=Symbol.for('tailored.no_value')){this.name=a,this.default_value=b}}class Wildcard{constructor(){}}class StartsWith{constructor(a){this.prefix=a}}class Capture{constructor(a){this.value=a}}class HeadTail{constructor(){}}class Type{constructor(a,b={}){this.type=a,this.objPattern=b}}class Bound{constructor(a){this.value=a}}class BitStringMatch{constructor(...a){this.values=a}length(){return values.length}bit_size(){return 8*this.byte_size()}byte_size(){let a=0;for(let b of this.values)a+=b.unit*b.size/8;return a}getValue(a){return this.values(a)}getSizeOfValue(a){let b=this.getValue(a);return b.unit*b.size}getTypeOfValue(a){return this.getValue(a).type}}class NamedVariableResult{constructor(a,b){this.name=a,this.value=b}}class Tuple{constructor(...a){this.values=Object.freeze(a),this.length=this.values.length}get(a){return this.values[a]}count(){return this.values.length}[Symbol.iterator](){return this.values[Symbol.iterator]()}toString(){let a,b='';for(a=0;aBitString$1.integer(a));return new BitString$1(...d)}[Symbol.iterator](){return this.value[Symbol.iterator]()}toString(){var a,b='';for(a=0;a>'}process(a){let b=[];var c;for(c=0;cb?c.push(b):2048>b?c.push(192|b>>6,128|63&b):55296>b||57344<=b?c.push(224|b>>12,128|63&b>>6,128|63&b):(d++,b=65536+((1023&b)<<10|1023&a.charCodeAt(d)),c.push(240|b>>18,128|63&b>>12,128|63&b>>6,128|63&b));return c}static toUTF16Array(a){for(var b,c=[],d=0;d=b?(c.push(0),c.push(b)):(c.push(255&b>>8),c.push(255&b));return c}static toUTF32Array(a){for(var b,c=[],d=0;d=b?(c.push(0),c.push(0),c.push(0),c.push(b)):(c.push(0),c.push(0),c.push(255&b>>8),c.push(255&b));return c}//http://stackoverflow.com/questions/2003493/javascript-float-from-to-bits -static float32ToBytes(a){var b=[],c=new ArrayBuffer(4);new Float32Array(c)[0]=a;let d=new Uint32Array(c)[0];return b.push(255&d>>24),b.push(255&d>>16),b.push(255&d>>8),b.push(255&d),b}static float64ToBytes(a){var b=[],c=new ArrayBuffer(8);new Float64Array(c)[0]=a;var d=new Uint32Array(c)[0],e=new Uint32Array(c)[1];return b.push(255&e>>24),b.push(255&e>>16),b.push(255&e>>8),b.push(255&e),b.push(255&d>>24),b.push(255&d>>16),b.push(255&d>>8),b.push(255&d),b}}var d={Tuple,PID:class PID{constructor(){++b,this.id=b}toString(){return'PID#<0.'+this.id+'.0>'}},Reference:class Reference{constructor(){++c,this.id=c,this.ref=Symbol()}toString(){return'Ref#<0.0.0.'+this.id+'>'}},BitString:BitString$1};/* @flow */const e=d.BitString,f=new Map;f.set(Variable.prototype,function resolveVariable(a){return function(b,c){return null===a.name?c.push(b):!a.name.startsWith('_')&&c.push(namedVariableResult(a.name,b)),!0}}),f.set(Wildcard.prototype,resolveWildcard),f.set(HeadTail.prototype,function resolveHeadTail(){return function(a,b){if(!is_array(a)||0===a.length)return!1;const c=a[0],d=a.slice(1);return b.push(c),b.push(d),!0}}),f.set(StartsWith.prototype,function resolveStartsWith(a){const b=a.prefix;return function(a,c){return is_string(a)&&a.startsWith(b)&&(c.push(a.substring(b.length)),!0)}}),f.set(Capture.prototype,function resolveCapture(a){const b=buildMatch(a.value);return function(a,c){return!!b(a,c)&&(c.push(a),!0)}}),f.set(Bound.prototype,function resolveBound(a){return function(b){return typeof b==typeof a.value&&b===a.value}}),f.set(Type.prototype,function resolveType(a){return function(b,c){if(b instanceof a.type){const d=buildMatch(a.objPattern);return d(b,c)}return!1}}),f.set(BitStringMatch.prototype,function resolveBitString(a){let b=[];for(let c of a.values)if(is_variable(c.value)){let a=getSize(c.unit,c.size);fillArray(b,a)}else b=b.concat(new e(c).value);let c=a.values;return function(a,d){var f=String.fromCharCode;let g=null;if(!is_string(a)&&!(a instanceof e))return!1;g=is_string(a)?new e(e.binary(a)):a;let h=0;for(let e,j=0;jd.size)return!1;for(let a of c)if(!d.has(a)||!b.get(a)(d.get(a),e))return!1;return!0}}),f.set(Array.prototype,function resolveArray(a){const b=a.map((a)=>buildMatch(a));return function(c,d){return is_array(c)&&c.length==a.length&&c.every(function(a,e){return b[e](c[e],d)})}}),f.set(String.prototype,function resolveString(a){return function(b){return is_string(b)&&b===a}}),f.set(Boolean.prototype,function resolveBoolean(a){return function(b){return is_boolean(b)&&b===a}}),f.set(Function.prototype,function resolveFunction(a){return function(b){return is_function(b)&&b===a}}),f.set(Object.prototype,resolveObject);class MatchError extends Error{constructor(a){if(super(),'symbol'==typeof a)this.message='No match for: '+a.toString();else if(Array.isArray(a)){let b=a.map((a)=>{return null===a?'null':'undefined'==typeof a?'undefined':a.toString()});this.message='No match for: '+b}else this.message='No match for: '+a;this.stack=new Error().stack,this.name=this.constructor.name}}class Clause{constructor(a,b,c=()=>!0){this.pattern=buildMatch(a),this.arity=a.length,this.optionals=getOptionalValues(a),this.fn=b,this.guard=c}}const g=Symbol();// https://github.com/airportyh/protomorphism -class Protocol{constructor(b){function createFun(b){return function(...c){const d=c[0];let e=null;if(null===d&&this.hasImplementation(Symbol('null'))?e=this.registry.get(Symbol)[b]:a(d)&&this.hasImplementation(o.Integer)?e=this.registry.get(o.Integer)[b]:'number'==typeof d&&!a(d)&&this.hasImplementation(o.Float)?e=this.registry.get(o.Float)[b]:'string'==typeof d&&this.hasImplementation(o.BitString)?e=this.registry.get(o.BitString)[b]:d&&d.has(Symbol.for('__struct__'))&&this.hasImplementation(d)?e=this.registry.get(d.get(Symbol.for('__struct__')).__MODULE__)[b]:null!==d&&this.hasImplementation(d)?e=this.registry.get(d.constructor)[b]:this.fallback&&(e=this.fallback[b]),null!=e){const a=e.apply(this,c);return a}throw new Error(`No implementation found for ${d}`)}}for(const a in this.registry=new Map,this.fallback=null,b)this[a]=createFun(a).bind(this)}implementation(a,b){null===a?this.fallback=b:this.registry.set(a,b)}hasImplementation(a){if(a===o.Integer||a===o.Float||a===o.BitString)return this.registry.has(a);return a&&a.has(Symbol.for('__struct__'))?this.registry.has(a.get(Symbol.for('__struct__')).__MODULE__):this.registry.has(a.constructor)}}var h={reverse,foreach:function foreach(a,b){return b.forEach((b)=>a(b)),Symbol.for('ok')},duplicate:function duplicate(a,b){const c=[];for(;c.length{if(d.get(c-1)a.get(c-1)?1:0})},keystore:function keystore(a,b,c,d){const e=[...c];for(let f=0;fa.toString()).join()},map:function map(a,b){return b.map((b)=>a(b))},filter:function filter(a,b){return b.filter((b)=>a(b))},filtermap:function filtermap(a,b){const c=[];for(const e of b){const b=a(e);!0===b?c.push(e):b instanceof d.Tuple&&!0===b.get(0)&&c.push(b.get(1))}return c},member:function member(a,b){for(const c of b)if(c===a)return!0;return!1},all:function all(a,b){for(const c of b)if(!1===a(c))return!1;return!0},any:function any(a,b){for(const c of b)if(!0===a(c))return!0;return!1},splitwith:function splitwith(a,b){let c=!1;const e=[],f=[];for(const d of b)!0==c?f.push(d):!0===a(d)?e.push(d):(c=!0,f.push(d));return new d.Tuple(e,f)},sort:function sort(...a){if(1===a.length){const b=[...a[0]];return b.sort()}const c=a[0],b=[...a[1]];return b.sort((d,a)=>{const b=c(d,a);return!0===b?-1:1})}},i={atom_to_binary,binary_to_atom,binary_to_existing_atom:function binary_to_existing_atom(a,b=Symbol.for('utf8')){return binary_to_atom(a,b)},list_concatenation:function list_concatenation(a,b){return a.concat(b)},list_subtraction:function list_subtraction(a,b){const c=[...a];for(const d of b){const a=c.indexOf(d);-1>b},bxor:function bxor(a,b){return a^b},bnot:function bnot(a){return~a},is_bitstring:is_bitstring$1,is_boolean:function is_boolean$1(a){return'boolean'==typeof a||a instanceof Boolean},is_float:function is_float(b){return is_number$1(b)&&!a(b)},is_function:function is_function$1(a){return'function'==typeof a||a instanceof Function},is_integer,is_list:function is_list(a){return Array.isArray(a)},is_map:function is_map$1(a){return a instanceof Map},is_number:is_number$1,is_pid:function is_pid(a){return a instanceof d.PID},is_port:function is_port(){return!1},is_reference:function is_reference(a){return a instanceof d.Reference},is_tuple:function is_tuple(a){return a instanceof d.Tuple},is_atom:function is_atom(a){return'symbol'==typeof a||a instanceof Symbol||a.__MODULE__},is_binary,element:function element(a,b){return b.get(a-1)},setelement:function setelement(a,b,c){const e=[...b.values];return e[a-1]=c,new d.Tuple(...e)},make_tuple:function make_tuple(a,b){const c=[];for(let d=0;d!0){let d=[],e=buildMatch(a);const f=e(b,d),[g,h]=checkNamedVariables(d);if(f&&h&&c.apply(this,g))return g;throw console.error('No match for:',b),new MatchError(b)},MatchError,variable:function variable(a=null,b=Symbol.for('tailored.no_value')){return new Variable(a,b)},wildcard:function wildcard(){return new Wildcard},startsWith:function startsWith(a){return new StartsWith(a)},capture:function capture(a){return new Capture(a)},headTail:function headTail(){return new HeadTail},type:function a(a,b={}){return new Type(a,b)},bound:function bound(a){return new Bound(a)},Clause,clause:function clause(a,b,c=()=>!0){return new Clause(a,b,c)},bitStringMatch:function bitStringMatch(...a){return new BitStringMatch(...a)},match_or_default,defmatchgen,list_comprehension:function list_comprehension(a,b){const c=run_generators(b.pop()(),b);let d=[];for(let e of c)a.guard.apply(this,e)&&d.push(a.fn.apply(this,e));return d},list_generator:function list_generator(a,b){return function(){let c=[];for(let d of b){const b=match_or_default(a,d,()=>!0,g);if(b!=g){const[a]=b;c.push(a)}}return c}},bitstring_generator:function bitstring_generator(a,b){return function(){let c=[],d=b.slice(0,a.byte_size()),e=1;for(;d.byte_size==a.byte_size();){const f=match_or_default(a,d,()=>!0,g);if(f!=g){c.push(f)}d=b.slice(a.byte_size()*e,a.byte_size()*(e+1)),e++}return c}},bitstring_comprehension:function bitstring_comprehension(a,b){const c=run_generators(b.pop()(),b);let e=[];for(let d of c)a.guard.apply(this,d)&&e.push(a.fn.apply(this,d));return e=e.map((a)=>d.BitString.integer(a)),new d.BitString(...e)},defmatchGen:function defmatchGen(...a){return defmatchgen(...a)},defmatchAsync:function defmatchAsync(...a){const b=getArityMap(a);return async function(...a){if(b.has(a.length)){const c=b.get(a.length);let d=null,e=null;for(let b of c){let c=[];a=fillInOptionalValues(a,b.arity,b.optionals);const f=b.pattern(a,c),[g,h]=checkNamedVariables(c);if(f&&h&&(await b.guard.apply(this,c))){d=b.fn,e=c;break}}if(!d)throw console.error('No match for:',a),new MatchError(a);return d.apply(this,e)}throw console.error('Arity of',a.length,'not found. No match for:',a),new MatchError(a)}}},Integer:class Integer{},Float:class Float{},Functions:{call_property:function call_property(a,b){if(!b)return a instanceof Function||'function'==typeof a?a():a;if(a instanceof Map){let c=null;if(a.has(b)?c=b:a.has(Symbol.for(b))&&(c=Symbol.for(b)),null===c)throw new Error(`Property ${b} not found in ${a}`);return a.get(c)instanceof Function||'function'==typeof a.get(c)?a.get(c)():a.get(c)}let c=null;if('number'==typeof a||'symbol'==typeof a||'boolean'==typeof a||'string'==typeof a?void 0===a[b]?void 0!==a[Symbol.for(b)]&&(c=Symbol.for(b)):c=b:b in a?c=b:Symbol.for(b)in a&&(c=Symbol.for(b)),null===c)throw new Error(`Property ${b} not found in ${a}`);return a[c]instanceof Function||'function'==typeof a[c]?a[c]():a[c]},defprotocol:function defprotocol(a){return new Protocol(a)},defimpl:function defimpl(a,b,c){a.implementation(b,c)},build_namespace:function build_namespace(a,b){let c=b.split('.');const d=a;let e=a;'Elixir'===c[0]&&(c=c.slice(1));for(const d of c)'undefined'==typeof e[d]&&(e[d]={}),e=e[d];return d.__table__=a.__table__||{},d.__table__[Symbol.for(b)]=e,e},iterator_to_reducer,map_to_object},SpecialForms:{_case:function _case(a,b){return o.Patterns.defmatch(...b)(a)},cond:function cond(...a){for(const b of a)if(b[0])return b[1]();throw new Error},_for:function _for(a,b,c,d=[]){let[e,f]=c.into(d);const g=run_list_generators(b.pop()(),b);for(const h of g)a.guard.apply(this,h)&&(e=f(e,new o.Tuple(Symbol.for('cont'),a.fn.apply(this,h))));return f(e,Symbol.for('done'))},_try:function _try(a,b,c,d,e){let f=null;try{f=a()}catch(a){let d=null;if(b)try{return d=b(a),d}catch(a){if(a instanceof o.Patterns.MatchError)throw a}if(c)try{return d=c(a),d}catch(a){if(a instanceof o.Patterns.MatchError)throw a}throw a}finally{e&&e()}if(d)try{return d(f)}catch(a){if(a instanceof o.Patterns.MatchError)throw new Error('No Match Found in Else');throw a}else return f},_with:function _with(...a){let b=[],c=null,d=null;'function'==typeof a[a.length-2]?[c,d]=a.splice(-2):c=a.pop();for(let c=0;c{const[c,d]=b;return a.set(c,d),a},new Map)},keys:function keys(a){return!1===i.is_map(a)?new d.Tuple(l,a):Array.from(a.keys())},values:function values$1(a){return!1===i.is_map(a)?new d.Tuple(l,a):Array.from(a.values())},is_key,put:function put(a,b,c){if(!1===i.is_map(c))return new d.Tuple(l,c);const e=new Map(c);return e.set(a,b),e},merge:function merge(a,b){return!1===i.is_map(a)?new d.Tuple(l,a):!1===i.is_map(b)?new d.Tuple(l,b):new Map([...a,...b])},update:function update(a,b,c){return!1===i.is_map(c)?new d.Tuple(l,c):!1===is_key(a,c)?new d.Tuple(m,a):new Map([...c,[a,b]])},get:function get(...a){const b=a[0],c=a[1];return!1===i.is_map(c)?new d.Tuple(l,c):is_key(b)?c.get(b):3===a.length?a[2]:new d.Tuple(m,b)},take:function take(a,b){if(!1===i.is_map(b))return new d.Tuple(l,b);if(!is_key(a))return k;const c=b.get(a),e=new Map(b);return e.delete(a),new d.Tuple(c,e)}},lists:h,elixir_errors:{warn:function warn(a){const b=a.join('');return console.warn(`warning: ${b}`),Symbol.for('ok')}},io:{put_chars:function put_chars(a,b){let c=i.iolist_to_binary(b);return a===Symbol.for('stderr')?console.error(c):console.log(c),Symbol.for('ok')}},binary:{copy:function copy(a,b=1){return a.repeat(b)}}};return{Core:o}}(); +var ElixirScript = (function () { +'use strict'; + +/* @flow */ + +class Variable { + constructor(name = null, default_value = Symbol.for('tailored.no_value')) { + this.name = name; + this.default_value = default_value; + } +} + +class Wildcard { + constructor() {} +} + +class StartsWith { + constructor(prefix) { + this.prefix = prefix; + } +} + +class Capture { + constructor(value) { + this.value = value; + } +} + +class HeadTail { + constructor(head, tail) { + this.head = head; + this.tail = tail; + } +} + +class Type { + constructor(type, objPattern = {}) { + this.type = type; + this.objPattern = objPattern; + } +} + +class Bound { + constructor(value) { + this.value = value; + } +} + +class BitStringMatch { + constructor(...values) { + this.values = values; + } + + length() { + return values.length; + } + + bit_size() { + return this.byte_size() * 8; + } + + byte_size() { + let s = 0; + + for (let val of this.values) { + s = s + val.unit * val.size / 8; + } + + return s; + } + + getValue(index) { + return this.values(index); + } + + getSizeOfValue(index) { + let val = this.getValue(index); + return val.unit * val.size; + } + + getTypeOfValue(index) { + return this.getValue(index).type; + } +} + +class NamedVariableResult { + constructor(name, value) { + this.name = name; + this.value = value; + } +} + +function variable(name = null, default_value = Symbol.for('tailored.no_value')) { + return new Variable(name, default_value); +} + +function wildcard() { + return new Wildcard(); +} + +function startsWith(prefix) { + return new StartsWith(prefix); +} + +function capture(value) { + return new Capture(value); +} + +function headTail(head, tail) { + return new HeadTail(head, tail); +} + +function type(type, objPattern = {}) { + return new Type(type, objPattern); +} + +function bound(value) { + return new Bound(value); +} + +function bitStringMatch(...values) { + return new BitStringMatch(...values); +} + +function namedVariableResult(name, value) { + return new NamedVariableResult(name, value); +} + +/* @flow */ + +function is_number(value) { + return typeof value === 'number'; +} + +function is_string(value) { + return typeof value === 'string'; +} + +function is_boolean(value) { + return typeof value === 'boolean'; +} + +function is_symbol(value) { + return typeof value === 'symbol'; +} + +function is_object(value) { + return typeof value === 'object'; +} + +function is_variable(value) { + return value instanceof Variable; +} + +function is_null(value) { + return value === null; +} + +function is_array(value) { + return Array.isArray(value); +} + +function is_function(value) { + return Object.prototype.toString.call(value) == '[object Function]'; +} + +function is_map(value) { + return value instanceof Map; +} + +class Tuple { + constructor(...args) { + this.values = Object.freeze(args); + this.length = this.values.length; + } + + get(index) { + return this.values[index]; + } + + count() { + return this.values.length; + } + + [Symbol.iterator]() { + return this.values[Symbol.iterator](); + } + + toString() { + let i, + s = ''; + for (i = 0; i < this.values.length; i++) { + if (s !== '') { + s += ', '; + } + + const stringToAppend = this.values[i] ? this.values[i].toString() : ''; + + s += stringToAppend; + } + + return '{' + s + '}'; + } + + put_elem(index, elem) { + if (index === this.length) { + let new_values = this.values.concat([elem]); + return new Tuple(...new_values); + } + + let new_values = this.values.concat([]); + new_values.splice(index, 0, elem); + return new Tuple(...new_values); + } + + remove_elem(index) { + let new_values = this.values.concat([]); + new_values.splice(index, 1); + return new Tuple(...new_values); + } +} + +let process_counter = -1; + +class PID { + constructor() { + process_counter = process_counter + 1; + this.id = process_counter; + } + + toString() { + return 'PID#<0.' + this.id + '.0>'; + } +} + +let ref_counter = -1; + +class Reference { + constructor() { + ref_counter = ref_counter + 1; + this.id = ref_counter; + this.ref = Symbol(); + } + + toString() { + return 'Ref#<0.0.0.' + this.id + '>'; + } +} + +class BitString$1 { + constructor(...args) { + this.value = Object.freeze(this.process(args)); + this.length = this.value.length; + this.bit_size = this.length * 8; + this.byte_size = this.length; + } + + get(index) { + return this.value[index]; + } + + count() { + return this.value.length; + } + + slice(start, end = null) { + let s = this.value.slice(start, end); + let ms = s.map(elem => BitString$1.integer(elem)); + return new BitString$1(...ms); + } + + [Symbol.iterator]() { + return this.value[Symbol.iterator](); + } + + toString() { + var i, + s = ''; + for (i = 0; i < this.count(); i++) { + if (s !== '') { + s += ', '; + } + s += this.get(i).toString(); + } + + return '<<' + s + '>>'; + } + + process(bitStringParts) { + let processed_values = []; + + var i; + for (i = 0; i < bitStringParts.length; i++) { + let processed_value = this['process_' + bitStringParts[i].type](bitStringParts[i]); + + for (let attr of bitStringParts[i].attributes) { + processed_value = this['process_' + attr](processed_value); + } + + processed_values = processed_values.concat(processed_value); + } + + return processed_values; + } + + process_integer(value) { + return value.value; + } + + process_float(value) { + if (value.size === 64) { + return BitString$1.float64ToBytes(value.value); + } else if (value.size === 32) { + return BitString$1.float32ToBytes(value.value); + } + + throw new Error('Invalid size for float'); + } + + process_bitstring(value) { + return value.value.value; + } + + process_binary(value) { + return BitString$1.toUTF8Array(value.value); + } + + process_utf8(value) { + return BitString$1.toUTF8Array(value.value); + } + + process_utf16(value) { + return BitString$1.toUTF16Array(value.value); + } + + process_utf32(value) { + return BitString$1.toUTF32Array(value.value); + } + + process_signed(value) { + return new Uint8Array([value])[0]; + } + + process_unsigned(value) { + return value; + } + + process_native(value) { + return value; + } + + process_big(value) { + return value; + } + + process_little(value) { + return value.reverse(); + } + + process_size(value) { + return value; + } + + process_unit(value) { + return value; + } + + static integer(value) { + return BitString$1.wrap(value, { type: 'integer', unit: 1, size: 8 }); + } + + static float(value) { + return BitString$1.wrap(value, { type: 'float', unit: 1, size: 64 }); + } + + static bitstring(value) { + return BitString$1.wrap(value, { + type: 'bitstring', + unit: 1, + size: value.bit_size + }); + } + + static bits(value) { + return BitString$1.bitstring(value); + } + + static binary(value) { + return BitString$1.wrap(value, { + type: 'binary', + unit: 8, + size: value.length + }); + } + + static bytes(value) { + return BitString$1.binary(value); + } + + static utf8(value) { + return BitString$1.wrap(value, { type: 'utf8', unit: 1, size: value.length }); + } + + static utf16(value) { + return BitString$1.wrap(value, { + type: 'utf16', + unit: 1, + size: value.length * 2 + }); + } + + static utf32(value) { + return BitString$1.wrap(value, { + type: 'utf32', + unit: 1, + size: value.length * 4 + }); + } + + static signed(value) { + return BitString$1.wrap(value, {}, 'signed'); + } + + static unsigned(value) { + return BitString$1.wrap(value, {}, 'unsigned'); + } + + static native(value) { + return BitString$1.wrap(value, {}, 'native'); + } + + static big(value) { + return BitString$1.wrap(value, {}, 'big'); + } + + static little(value) { + return BitString$1.wrap(value, {}, 'little'); + } + + static size(value, count) { + return BitString$1.wrap(value, { size: count }); + } + + static unit(value, count) { + return BitString$1.wrap(value, { unit: count }); + } + + static wrap(value, opt, new_attribute = null) { + let the_value = value; + + if (!(value instanceof Object)) { + the_value = { value: value, attributes: [] }; + } + + the_value = Object.assign(the_value, opt); + + if (new_attribute) { + the_value.attributes.push(new_attribute); + } + + return the_value; + } + + static toUTF8Array(str) { + var utf8 = []; + for (var i = 0; i < str.length; i++) { + var charcode = str.charCodeAt(i); + if (charcode < 0x80) { + utf8.push(charcode); + } else if (charcode < 0x800) { + utf8.push(0xc0 | charcode >> 6, 0x80 | charcode & 0x3f); + } else if (charcode < 0xd800 || charcode >= 0xe000) { + utf8.push(0xe0 | charcode >> 12, 0x80 | charcode >> 6 & 0x3f, 0x80 | charcode & 0x3f); + } else { + // surrogate pair + i++; + // UTF-16 encodes 0x10000-0x10FFFF by + // subtracting 0x10000 and splitting the + // 20 bits of 0x0-0xFFFFF into two halves + charcode = 0x10000 + ((charcode & 0x3ff) << 10 | str.charCodeAt(i) & 0x3ff); + utf8.push(0xf0 | charcode >> 18, 0x80 | charcode >> 12 & 0x3f, 0x80 | charcode >> 6 & 0x3f, 0x80 | charcode & 0x3f); + } + } + return utf8; + } + + static toUTF16Array(str) { + var utf16 = []; + for (var i = 0; i < str.length; i++) { + var codePoint = str.codePointAt(i); + + if (codePoint <= 255) { + utf16.push(0); + utf16.push(codePoint); + } else { + utf16.push(codePoint >> 8 & 0xff); + utf16.push(codePoint & 0xff); + } + } + return utf16; + } + + static toUTF32Array(str) { + var utf32 = []; + for (var i = 0; i < str.length; i++) { + var codePoint = str.codePointAt(i); + + if (codePoint <= 255) { + utf32.push(0); + utf32.push(0); + utf32.push(0); + utf32.push(codePoint); + } else { + utf32.push(0); + utf32.push(0); + utf32.push(codePoint >> 8 & 0xff); + utf32.push(codePoint & 0xff); + } + } + return utf32; + } + + //http://stackoverflow.com/questions/2003493/javascript-float-from-to-bits + static float32ToBytes(f) { + var bytes = []; + + var buf = new ArrayBuffer(4); + new Float32Array(buf)[0] = f; + + let intVersion = new Uint32Array(buf)[0]; + + bytes.push(intVersion >> 24 & 0xff); + bytes.push(intVersion >> 16 & 0xff); + bytes.push(intVersion >> 8 & 0xff); + bytes.push(intVersion & 0xff); + + return bytes; + } + + static float64ToBytes(f) { + var bytes = []; + + var buf = new ArrayBuffer(8); + new Float64Array(buf)[0] = f; + + var intVersion1 = new Uint32Array(buf)[0]; + var intVersion2 = new Uint32Array(buf)[1]; + + bytes.push(intVersion2 >> 24 & 0xff); + bytes.push(intVersion2 >> 16 & 0xff); + bytes.push(intVersion2 >> 8 & 0xff); + bytes.push(intVersion2 & 0xff); + + bytes.push(intVersion1 >> 24 & 0xff); + bytes.push(intVersion1 >> 16 & 0xff); + bytes.push(intVersion1 >> 8 & 0xff); + bytes.push(intVersion1 & 0xff); + + return bytes; + } +} + +var ErlangTypes = { + Tuple, + PID, + Reference, + BitString: BitString$1 +}; + +/* @flow */ + +const BitString = ErlangTypes.BitString; + +function resolveSymbol(pattern) { + return function (value) { + return is_symbol(value) && value === pattern; + }; +} + +function resolveString(pattern) { + return function (value) { + return is_string(value) && value === pattern; + }; +} + +function resolveNumber(pattern) { + return function (value) { + return is_number(value) && value === pattern; + }; +} + +function resolveBoolean(pattern) { + return function (value) { + return is_boolean(value) && value === pattern; + }; +} + +function resolveFunction(pattern) { + return function (value) { + return is_function(value) && value === pattern; + }; +} + +function resolveNull(pattern) { + return function (value) { + return is_null(value); + }; +} + +function resolveBound(pattern) { + return function (value, args) { + if (typeof value === typeof pattern.value && value === pattern.value) { + return true; + } + + return false; + }; +} + +function resolveWildcard() { + return function () { + return true; + }; +} + +function resolveVariable(pattern) { + return function (value, args) { + if (pattern.name === null) { + args.push(value); + } else if (!pattern.name.startsWith('_')) { + args.push(namedVariableResult(pattern.name, value)); + } + + return true; + }; +} + +function resolveHeadTail(pattern) { + const headMatches = buildMatch(pattern.head); + const tailMatches = buildMatch(pattern.tail); + + return function (value, args) { + if (!is_array(value) || value.length === 0) { + return false; + } + + const head = value[0]; + const tail = value.slice(1); + + if (headMatches(head, args) && tailMatches(tail, args)) { + return true; + } + + return false; + }; +} + +function resolveCapture(pattern) { + const matches = buildMatch(pattern.value); + + return function (value, args) { + if (matches(value, args)) { + args.push(value); + return true; + } + + return false; + }; +} + +function resolveStartsWith(pattern) { + const prefix = pattern.prefix; + + return function (value, args) { + if (is_string(value) && value.startsWith(prefix)) { + args.push(value.substring(prefix.length)); + return true; + } + + return false; + }; +} + +function resolveType(pattern) { + return function (value, args) { + if (value instanceof pattern.type) { + const matches = buildMatch(pattern.objPattern); + return matches(value, args); + } + + return false; + }; +} + +function resolveArray(pattern) { + const matches = pattern.map(x => buildMatch(x)); + + return function (value, args) { + if (!is_array(value) || value.length != pattern.length) { + return false; + } + + return value.every(function (v, i) { + return matches[i](value[i], args); + }); + }; +} + +function resolveMap(pattern) { + let matches = new Map(); + + const keys = Array.from(pattern.keys()); + + for (let key of keys) { + matches.set(key, buildMatch(pattern.get(key))); + } + + return function (value, args) { + if (!is_map(value) || pattern.size > value.size) { + return false; + } + + for (let key of keys) { + if (!value.has(key) || !matches.get(key)(value.get(key), args)) { + return false; + } + } + + return true; + }; +} + +function resolveObject(pattern) { + let matches = {}; + + const keys = Object.keys(pattern).concat(Object.getOwnPropertySymbols(pattern)); + + for (let key of keys) { + matches[key] = buildMatch(pattern[key]); + } + + return function (value, args) { + if (!is_object(value) || pattern.length > value.length) { + return false; + } + + for (let key of keys) { + if (!(key in value) || !matches[key](value[key], args)) { + return false; + } + } + + return true; + }; +} + +function resolveBitString(pattern) { + let patternBitString = []; + + for (let bitstringMatchPart of pattern.values) { + if (is_variable(bitstringMatchPart.value)) { + let size = getSize(bitstringMatchPart.unit, bitstringMatchPart.size); + fillArray(patternBitString, size); + } else { + patternBitString = patternBitString.concat(new BitString(bitstringMatchPart).value); + } + } + + let patternValues = pattern.values; + + return function (value, args) { + let bsValue = null; + + if (!is_string(value) && !(value instanceof BitString)) { + return false; + } + + if (is_string(value)) { + bsValue = new BitString(BitString.binary(value)); + } else { + bsValue = value; + } + + let beginningIndex = 0; + + for (let i = 0; i < patternValues.length; i++) { + let bitstringMatchPart = patternValues[i]; + + if (is_variable(bitstringMatchPart.value) && bitstringMatchPart.type == 'binary' && bitstringMatchPart.size === undefined && i < patternValues.length - 1) { + throw new Error('a binary field without size is only allowed at the end of a binary pattern'); + } + + let size = 0; + let bsValueArrayPart = []; + let patternBitStringArrayPart = []; + size = getSize(bitstringMatchPart.unit, bitstringMatchPart.size); + + if (i === patternValues.length - 1) { + bsValueArrayPart = bsValue.value.slice(beginningIndex); + patternBitStringArrayPart = patternBitString.slice(beginningIndex); + } else { + bsValueArrayPart = bsValue.value.slice(beginningIndex, beginningIndex + size); + patternBitStringArrayPart = patternBitString.slice(beginningIndex, beginningIndex + size); + } + + if (is_variable(bitstringMatchPart.value)) { + switch (bitstringMatchPart.type) { + case 'integer': + if (bitstringMatchPart.attributes && bitstringMatchPart.attributes.indexOf('signed') != -1) { + args.push(new Int8Array([bsValueArrayPart[0]])[0]); + } else { + args.push(new Uint8Array([bsValueArrayPart[0]])[0]); + } + break; + + case 'float': + if (size === 64) { + args.push(Float64Array.from(bsValueArrayPart)[0]); + } else if (size === 32) { + args.push(Float32Array.from(bsValueArrayPart)[0]); + } else { + return false; + } + break; + + case 'bitstring': + args.push(createBitString(bsValueArrayPart)); + break; + + case 'binary': + args.push(String.fromCharCode.apply(null, new Uint8Array(bsValueArrayPart))); + break; + + case 'utf8': + args.push(String.fromCharCode.apply(null, new Uint8Array(bsValueArrayPart))); + break; + + case 'utf16': + args.push(String.fromCharCode.apply(null, new Uint16Array(bsValueArrayPart))); + break; + + case 'utf32': + args.push(String.fromCharCode.apply(null, new Uint32Array(bsValueArrayPart))); + break; + + default: + return false; + } + } else if (!arraysEqual(bsValueArrayPart, patternBitStringArrayPart)) { + return false; + } + + beginningIndex = beginningIndex + size; + } + + return true; + }; +} + +function getSize(unit, size) { + return unit * size / 8; +} + +function arraysEqual(a, b) { + if (a === b) return true; + if (a == null || b == null) return false; + if (a.length != b.length) return false; + + for (var i = 0; i < a.length; ++i) { + if (a[i] !== b[i]) return false; + } + + return true; +} + +function fillArray(arr, num) { + for (let i = 0; i < num; i++) { + arr.push(0); + } +} + +function createBitString(arr) { + let integerParts = arr.map(elem => BitString.integer(elem)); + return new BitString(...integerParts); +} + +function resolveNoMatch() { + return function () { + return false; + }; +} + +const patternMap = new Map(); +patternMap.set(Variable.prototype, resolveVariable); +patternMap.set(Wildcard.prototype, resolveWildcard); +patternMap.set(HeadTail.prototype, resolveHeadTail); +patternMap.set(StartsWith.prototype, resolveStartsWith); +patternMap.set(Capture.prototype, resolveCapture); +patternMap.set(Bound.prototype, resolveBound); +patternMap.set(Type.prototype, resolveType); +patternMap.set(BitStringMatch.prototype, resolveBitString); +patternMap.set(Number.prototype, resolveNumber); +patternMap.set(Symbol.prototype, resolveSymbol); +patternMap.set(Map.prototype, resolveMap); +patternMap.set(Array.prototype, resolveArray); +patternMap.set(String.prototype, resolveString); +patternMap.set(Boolean.prototype, resolveBoolean); +patternMap.set(Function.prototype, resolveFunction); +patternMap.set(Object.prototype, resolveObject); + +function buildMatch(pattern) { + if (pattern === null) { + return resolveNull(pattern); + } + + if (typeof pattern === 'undefined') { + return resolveWildcard(pattern); + } + + const type$$1 = pattern.constructor.prototype; + const resolver = patternMap.get(type$$1); + + if (resolver) { + return resolver(pattern); + } + + if (typeof pattern === 'object') { + return resolveObject(pattern); + } + + return resolveNoMatch(); +} + +class MatchError extends Error { + constructor(arg) { + super(); + + if (typeof arg === 'symbol') { + this.message = 'No match for: ' + arg.toString(); + } else if (Array.isArray(arg)) { + let mappedValues = arg.map(x => { + if (x === null) { + return 'null'; + } else if (typeof x === 'undefined') { + return 'undefined'; + } + + return x.toString(); + }); + + this.message = 'No match for: ' + mappedValues; + } else { + this.message = 'No match for: ' + arg; + } + + this.stack = new Error().stack; + this.name = this.constructor.name; + } +} + +class Clause { + constructor(pattern, fn, guard = () => true) { + this.pattern = buildMatch(pattern); + this.arity = pattern.length; + this.optionals = getOptionalValues(pattern); + this.fn = fn; + this.guard = guard; + } +} + +function clause(pattern, fn, guard = () => true) { + return new Clause(pattern, fn, guard); +} + + + +function defmatch(...clauses) { + const arities = getArityMap(clauses); + + return function (...args) { + let [funcToCall, params] = findMatchingFunction(args, arities); + return funcToCall.apply(this, params); + }; +} + +function defmatchgen(...clauses) { + const arities = getArityMap(clauses); + + return function* (...args) { + let [funcToCall, params] = findMatchingFunction(args, arities); + return yield* funcToCall.apply(this, params); + }; +} + +function defmatchGen(...args) { + return defmatchgen(...args); +} + +function defmatchAsync(...clauses) { + const arities = getArityMap(clauses); + + return async function (...args) { + if (arities.has(args.length)) { + const arityClauses = arities.get(args.length); + + let funcToCall = null; + let params = null; + for (let processedClause of arityClauses) { + let result = []; + args = fillInOptionalValues(args, processedClause.arity, processedClause.optionals); + + const doesMatch = processedClause.pattern(args, result); + const [filteredResult, allNamesMatch] = checkNamedVariables(result); + + if (doesMatch && allNamesMatch && (await processedClause.guard.apply(this, result))) { + funcToCall = processedClause.fn; + params = result; + break; + } + } + + if (!funcToCall) { + console.error('No match for:', args); + throw new MatchError(args); + } + + return funcToCall.apply(this, params); + } else { + console.error('Arity of', args.length, 'not found. No match for:', args); + throw new MatchError(args); + } + }; +} + +function findMatchingFunction(args, arities) { + if (arities.has(args.length)) { + const arityClauses = arities.get(args.length); + + let funcToCall = null; + let params = null; + for (let processedClause of arityClauses) { + let result = []; + args = fillInOptionalValues(args, processedClause.arity, processedClause.optionals); + + const doesMatch = processedClause.pattern(args, result); + const [filteredResult, allNamesMatch] = checkNamedVariables(result); + + if (doesMatch && allNamesMatch && processedClause.guard.apply(this, filteredResult)) { + funcToCall = processedClause.fn; + params = filteredResult; + break; + } + } + + if (!funcToCall) { + console.error('No match for:', args); + throw new MatchError(args); + } + + return [funcToCall, params]; + } else { + console.error('Arity of', args.length, 'not found. No match for:', args); + throw new MatchError(args); + } +} + +function getArityMap(clauses) { + let map = new Map(); + + for (const clause of clauses) { + const range = getArityRange(clause); + + for (const arity of range) { + let arityClauses = []; + + if (map.has(arity)) { + arityClauses = map.get(arity); + } + + arityClauses.push(clause); + map.set(arity, arityClauses); + } + } + + return map; +} + +function getArityRange(clause) { + const min = clause.arity - clause.optionals.length; + const max = clause.arity; + + let range = [min]; + + while (range[range.length - 1] != max) { + range.push(range[range.length - 1] + 1); + } + + return range; +} + +function getOptionalValues(pattern) { + let optionals = []; + + for (let i = 0; i < pattern.length; i++) { + if (pattern[i] instanceof Variable && pattern[i].default_value != Symbol.for('tailored.no_value')) { + optionals.push([i, pattern[i].default_value]); + } + } + + return optionals; +} + +function fillInOptionalValues(args, arity, optionals) { + if (args.length === arity || optionals.length === 0) { + return args; + } + + if (args.length + optionals.length < arity) { + return args; + } + + let numberOfOptionalsToFill = arity - args.length; + let optionalsToRemove = optionals.length - numberOfOptionalsToFill; + + let optionalsToUse = optionals.slice(optionalsToRemove); + + for (let [index, value] of optionalsToUse) { + args.splice(index, 0, value); + if (args.length === arity) { + break; + } + } + + return args; +} + +function match(pattern, expr, guard = () => true) { + let result = []; + let processedPattern = buildMatch(pattern); + const doesMatch = processedPattern(expr, result); + const [filteredResult, allNamesMatch] = checkNamedVariables(result); + + if (doesMatch && allNamesMatch && guard.apply(this, filteredResult)) { + return filteredResult; + } else { + console.error('No match for:', expr); + throw new MatchError(expr); + } +} + +function checkNamedVariables(results) { + const namesMap = {}; + const filteredResults = []; + + for (let i = 0; i < results.length; i++) { + const current = results[i]; + if (current instanceof NamedVariableResult) { + if (namesMap[current.name] && namesMap[current.name] !== current.value) { + return [results, false]; + } else if (namesMap[current.name] && namesMap[current.name] === current.value) { + filteredResults.push(current.value); + } else { + namesMap[current.name] = current.value; + filteredResults.push(current.value); + } + } else { + filteredResults.push(current); + } + } + + return [filteredResults, true]; +} + +function match_or_default(pattern, expr, guard = () => true, default_value = null) { + let result = []; + let processedPattern = buildMatch(pattern); + const doesMatch = processedPattern(expr, result); + const [filteredResult, allNamesMatch] = checkNamedVariables(result); + + if (doesMatch && allNamesMatch && guard.apply(this, filteredResult)) { + return filteredResult; + } else { + return default_value; + } +} + +const NO_MATCH = Symbol(); + +function bitstring_generator(pattern, bitstring) { + return function () { + let returnResult = []; + let bsSlice = bitstring.slice(0, pattern.byte_size()); + let i = 1; + + while (bsSlice.byte_size == pattern.byte_size()) { + const result = match_or_default(pattern, bsSlice, () => true, NO_MATCH); + + if (result != NO_MATCH) { + const [value] = result; + returnResult.push(result); + } + + bsSlice = bitstring.slice(pattern.byte_size() * i, pattern.byte_size() * (i + 1)); + + i++; + } + + return returnResult; + }; +} + +function list_generator(pattern, list) { + return function () { + let returnResult = []; + for (let i of list) { + const result = match_or_default(pattern, i, () => true, NO_MATCH); + if (result != NO_MATCH) { + const [value] = result; + returnResult.push(value); + } + } + + return returnResult; + }; +} + +function list_comprehension(expression, generators) { + const generatedValues = run_generators(generators.pop()(), generators); + + let result = []; + + for (let value of generatedValues) { + if (expression.guard.apply(this, value)) { + result.push(expression.fn.apply(this, value)); + } + } + + return result; +} + +function run_generators(generator, generators) { + if (generators.length == 0) { + return generator.map(x => { + if (Array.isArray(x)) { + return x; + } else { + return [x]; + } + }); + } else { + const list = generators.pop(); + + let next_gen = []; + for (let j of list()) { + for (let i of generator) { + next_gen.push([j].concat(i)); + } + } + + return run_generators(next_gen, generators); + } +} + +function bitstring_comprehension(expression, generators) { + const generatedValues = run_generators(generators.pop()(), generators); + + let result = []; + + for (let value of generatedValues) { + if (expression.guard.apply(this, value)) { + result.push(expression.fn.apply(this, value)); + } + } + + result = result.map(x => ErlangTypes.BitString.integer(x)); + return new ErlangTypes.BitString(...result); +} + +var Patterns = { + defmatch, + match, + MatchError, + variable, + wildcard, + startsWith, + capture, + headTail, + type, + bound, + Clause, + clause, + bitStringMatch, + match_or_default, + defmatchgen, + list_comprehension, + list_generator, + bitstring_generator, + bitstring_comprehension, + defmatchGen, + defmatchAsync +}; + +// https://github.com/airportyh/protomorphism +class Protocol { + constructor(spec) { + this.registry = new Map(); + this.fallback = null; + + function createFun(funName) { + return function (...args) { + const thing = args[0]; + let fun = null; + + if (thing === null && this.hasImplementation(Symbol('null'))) { + fun = this.registry.get(Symbol)[funName]; + } else if (Number.isInteger(thing) && this.hasImplementation(Core.Integer)) { + fun = this.registry.get(Core.Integer)[funName]; + } else if (typeof thing === 'number' && !Number.isInteger(thing) && this.hasImplementation(Core.Float)) { + fun = this.registry.get(Core.Float)[funName]; + } else if (typeof thing === 'string' && this.hasImplementation(Core.BitString)) { + fun = this.registry.get(Core.BitString)[funName]; + } else if (thing && thing instanceof Map && thing.has(Symbol.for('__struct__')) && this.hasImplementation(thing)) { + fun = this.registry.get(thing.get(Symbol.for('__struct__')).__MODULE__)[funName]; + } else if (thing !== null && this.hasImplementation(thing)) { + fun = this.registry.get(thing.constructor)[funName]; + } else if (this.fallback) { + fun = this.fallback[funName]; + } + + if (fun != null) { + const retval = fun.apply(this, args); + return retval; + } + + throw new Error(`No implementation found for ${thing}`); + }; + } + + for (const funName in spec) { + this[funName] = createFun(funName).bind(this); + } + } + + implementation(type, implementation) { + if (type === null) { + this.fallback = implementation; + } else { + this.registry.set(type, implementation); + } + } + + hasImplementation(thing) { + if (thing === Core.Integer || thing === Core.Float || thing === Core.BitString) { + return this.registry.has(thing); + } else if (thing && thing instanceof Map && thing.has(Symbol.for('__struct__'))) { + return this.registry.has(thing.get(Symbol.for('__struct__')).__MODULE__); + } + + return this.registry.has(thing.constructor); + } +} + +function iterator_to_reducer(iterable, acc, fun) { + const iterator = iterable[Symbol.iterator](); + let x = iterator.next(); + let _acc = acc; + + while (x.done === false) { + _acc = fun(x.value, _acc.get(1)); + if (_acc.get(0) === Symbol.for('halt')) { + return new Core.Tuple(Symbol.for('halted'), _acc.get(1)); + } else if (_acc.get(0) === Symbol.for('suspend')) { + return new Core.Tuple(Symbol.for('suspended'), _acc.get(1), new_acc => { + return iterator_to_reducer(iterator, new_acc, fun); + }); + } + + x = iterator.next(); + } + + return new Core.Tuple(Symbol.for('done'), _acc.get(1)); +} + +function call_property(item, property) { + if (!property) { + if (item instanceof Function || typeof item === 'function') { + return item(); + } + + return item; + } + + if (item instanceof Map) { + let prop = null; + + if (item.has(property)) { + prop = property; + } else if (item.has(Symbol.for(property))) { + prop = Symbol.for(property); + } + + if (prop === null) { + throw new Error(`Property ${property} not found in ${item}`); + } + + if (item.get(prop) instanceof Function || typeof item.get(prop) === 'function') { + return item.get(prop)(); + } + return item.get(prop); + } + + let prop = null; + + if (typeof item === 'number' || typeof item === 'symbol' || typeof item === 'boolean' || typeof item === 'string') { + if (item[property] !== undefined) { + prop = property; + } else if (item[Symbol.for(property)] !== undefined) { + prop = Symbol.for(property); + } + } else if (property in item) { + prop = property; + } else if (Symbol.for(property) in item) { + prop = Symbol.for(property); + } + + if (prop === null) { + throw new Error(`Property ${property} not found in ${item}`); + } + + if (item[prop] instanceof Function || typeof item[prop] === 'function') { + return item[prop](); + } + return item[prop]; +} + +function defprotocol(spec) { + return new Protocol(spec); +} + +function defimpl(protocol, type, impl) { + protocol.implementation(type, impl); +} + +function build_namespace(ns, ns_string) { + let parts = ns_string.split('.'); + const root = ns; + let parent = ns; + + if (parts[0] === 'Elixir') { + parts = parts.slice(1); + } + + for (const part of parts) { + if (typeof parent[part] === 'undefined') { + parent[part] = {}; + } + + parent = parent[part]; + } + + root.__table__ = ns.__table__ || {}; + root.__table__[Symbol.for(ns_string)] = parent; + + return parent; +} + +function map_to_object(map) { + const object = {}; + + for (const [key, value] of map.entries()) { + if (value instanceof Map) { + object[key] = map_to_object(value); + } else { + object[key] = value; + } + } + + return object; +} + +var Functions = { + call_property, + defprotocol, + defimpl, + build_namespace, + iterator_to_reducer, + map_to_object +}; + +function _case(condition, clauses) { + return Core.Patterns.defmatch(...clauses)(condition); +} + +function cond(...clauses) { + for (const clause of clauses) { + if (clause[0]) { + return clause[1](); + } + } + + throw new Error(); +} + +function _for(expression, generators, collectable_protocol, into = []) { + let [result, fun] = collectable_protocol.into(into); + + const generatedValues = run_list_generators(generators.pop()(), generators); + + for (const value of generatedValues) { + if (expression.guard.apply(this, value)) { + result = fun(result, new Core.Tuple(Symbol.for('cont'), expression.fn.apply(this, value))); + } + } + + return fun(result, Symbol.for('done')); +} + +function run_list_generators(generator, generators) { + if (generators.length == 0) { + return generator.map(x => { + if (Array.isArray(x)) { + return x; + } + return [x]; + }); + } + const list = generators.pop(); + + const next_gen = []; + for (const j of list()) { + for (const i of generator) { + next_gen.push([j].concat(i)); + } + } + + return run_list_generators(next_gen, generators); +} + +function _try(do_fun, rescue_function, catch_fun, else_function, after_function) { + let result = null; + + try { + result = do_fun(); + } catch (e) { + let ex_result = null; + + if (rescue_function) { + try { + ex_result = rescue_function(e); + return ex_result; + } catch (ex) { + if (ex instanceof Core.Patterns.MatchError) { + throw ex; + } + } + } + + if (catch_fun) { + try { + ex_result = catch_fun(e); + return ex_result; + } catch (ex) { + if (ex instanceof Core.Patterns.MatchError) { + throw ex; + } + } + } + + throw e; + } finally { + if (after_function) { + after_function(); + } + } + + if (else_function) { + try { + return else_function(result); + } catch (ex) { + if (ex instanceof Core.Patterns.MatchError) { + throw new Error('No Match Found in Else'); + } + + throw ex; + } + } else { + return result; + } +} + +function _with(...args) { + let argsToPass = []; + let successFunction = null; + let elseFunction = null; + + if (typeof args[args.length - 2] === 'function') { + [successFunction, elseFunction] = args.splice(-2); + } else { + successFunction = args.pop(); + } + + for (let i = 0; i < args.length; i++) { + const [pattern, func] = args[i]; + + const result = func(...argsToPass); + + const patternResult = Core.Patterns.match_or_default(pattern, result); + + if (patternResult == null) { + if (elseFunction) { + return elseFunction.call(null, result); + } + return result; + } + + argsToPass = argsToPass.concat(patternResult); + } + + return successFunction(...argsToPass); +} + +function receive(clauses, after) { + console.warn('Receive not supported'); +} + +var SpecialForms = { + _case, + cond, + _for, + _try, + _with, + receive +}; + +// http://erlang.org/doc/man/lists.html +function reverse(list) { + return [...list].reverse(); +} + +function foreach(fun, list) { + list.forEach(x => fun(x)); + + return Symbol.for('ok'); +} + +function duplicate(n, elem) { + const list = []; + + while (list.length < n) { + list.push(elem); + } + + return list; +} + +function flatten(deepList, tail = []) { + const val = deepList.reduce((acc, value) => { + if (Array.isArray(value)) { + return acc.concat(flatten(value)); + } + + return acc.concat(value); + }, []); + + return val.concat(tail); +} + +function foldl(fun, acc0, list) { + return list.reduce((acc, value) => { + return fun(value, acc); + }, acc0); +} + +function foldr(fun, acc0, list) { + return foldl(fun, acc0, reverse(list)); +} + +function keyfind(key, n, tupleList) { + for (const tuple of tupleList) { + if (tuple.get(n - 1) === key) { + return tuple; + } + } + + return false; +} + +function keymember(key, n, tupleList) { + if (keyfind(key, n, tupleList) === false) { + return false; + } + + return true; +} + +function keyreplace(key, n, tupleList, newTuple) { + const newTupleList = [...tupleList]; + + for (let index = 0; index < newTupleList.length; index++) { + if (newTupleList[index].get(n - 1) === key) { + newTupleList[index] = newTuple; + return newTupleList; + } + } + + return newTupleList; +} + +function keysort(n, tupleList) { + const newTupleList = [...tupleList]; + + return newTupleList.sort((a, b) => { + if (a.get(n - 1) < b.get(n - 1)) { + return -1; + } else if (a.get(n - 1) > b.get(n - 1)) { + return 1; + } + + return 0; + }); +} + +function keystore(key, n, tupleList, newTuple) { + const newTupleList = [...tupleList]; + + for (let index = 0; index < newTupleList.length; index++) { + if (newTupleList[index].get(n - 1) === key) { + newTupleList[index] = newTuple; + return newTupleList; + } + } + + return newTupleList.concat(newTuple); +} + +function keydelete(key, n, tupleList) { + const newTupleList = []; + let deleted = false; + + for (let index = 0; index < tupleList.length; index++) { + if (deleted === false && tupleList[index].get(n - 1) === key) { + deleted = true; + } else { + newTupleList.push(tupleList[index]); + } + } + + return newTupleList; +} + +function keytake(key, n, tupleList) { + const result = keyfind(key, n, tupleList); + + if (result !== false) { + return new ErlangTypes.Tuple(result.get(n - 1), result, keydelete(key, n, tupleList)); + } + + return false; +} + +function mapfoldl(fun, acc0, list1) { + const listResult = []; + let accResult = acc0; + + for (const item of list1) { + const tuple = fun(item, accResult); + listResult.push(tuple.get(0)); + accResult = tuple.get(1); + } + + return new ErlangTypes.Tuple(listResult, accResult); +} + +function concat(things) { + return things.map(v => v.toString()).join(); +} + +function map(fun, list) { + return list.map(value => fun(value)); +} + +function filter(pred, list1) { + return list1.filter(x => pred(x)); +} + +function filtermap(fun, list1) { + const list2 = []; + + for (const item of list1) { + const value = fun(item); + + if (value === true) { + list2.push(item); + } else if (value instanceof ErlangTypes.Tuple && value.get(0) === true) { + list2.push(value.get(1)); + } + } + + return list2; +} + +function member(elem, list) { + for (const item of list) { + if (item === elem) { + return true; + } + } + + return false; +} + +function all(pred, list) { + for (const item of list) { + if (pred(item) === false) { + return false; + } + } + + return true; +} + +function any(pred, list) { + for (const item of list) { + if (pred(item) === true) { + return true; + } + } + + return false; +} + +function splitwith(pred, list) { + let switchToList2 = false; + const list1 = []; + const list2 = []; + + for (const item of list) { + if (switchToList2 === true) { + list2.push(item); + } else if (pred(item) === true) { + list1.push(item); + } else { + switchToList2 = true; + list2.push(item); + } + } + + return new ErlangTypes.Tuple(list1, list2); +} + +function sort(...args) { + if (args.length === 1) { + const list2 = [...args[0]]; + return list2.sort(); + } + + const fun = args[0]; + const list2 = [...args[1]]; + + return list2.sort((a, b) => { + const result = fun(a, b); + + if (result === true) { + return -1; + } + + return 1; + }); +} + +var lists = { + reverse, + foreach, + duplicate, + flatten, + foldl, + foldr, + keydelete, + keyfind, + keymember, + keyreplace, + keysort, + keystore, + keytake, + mapfoldl, + concat, + map, + filter, + filtermap, + member, + all, + any, + splitwith, + sort +}; + +// http://erlang.org/doc/man/erlang.html +function atom_to_binary(atom, encoding = Symbol.for('utf8')) { + if (encoding !== Symbol.for('utf8')) { + throw new Error(`unsupported encoding ${encoding}`); + } + + if (atom.__MODULE__) { + return Symbol.keyFor(atom.__MODULE__); + } + + return Symbol.keyFor(atom); +} + +function binary_to_atom(binary, encoding = Symbol.for('utf8')) { + if (encoding !== Symbol.for('utf8')) { + throw new Error(`unsupported encoding ${encoding}`); + } + + return Symbol.for(binary); +} + +function binary_to_existing_atom(binary, encoding = Symbol.for('utf8')) { + return binary_to_atom(binary, encoding); +} + +function list_concatenation(list1, list2) { + return list1.concat(list2); +} + +function list_subtraction(list1, list2) { + const list = [...list1]; + + for (const item of list2) { + const index = list.indexOf(item); + + if (index > -1) { + list.splice(index, 1); + } + } + + return list; +} + +function div(left, right) { + return left / right; +} + +function not(x) { + return !x; +} + +function rem(left, right) { + return left % right; +} + +function band(left, right) { + return left & right; +} + +function bor(left, right) { + return left | right; +} + +function bnot(x) { + return ~x; +} + +function bsl(left, right) { + return left << right; +} + +function bsr(left, right) { + return left >> right; +} + +function bxor(left, right) { + return left ^ right; +} + +function is_atom(value) { + return typeof value === 'symbol' || value instanceof Symbol || value.__MODULE__; +} + +function is_bitstring$1(value) { + return value instanceof ErlangTypes.BitString; +} + +function is_boolean$1(value) { + return typeof value === 'boolean' || value instanceof Boolean; +} + +function is_number$1(value) { + return typeof value === 'number' || value instanceof Number; +} + +function is_float(value) { + return is_number$1(value) && !Number.isInteger(value); +} + +function is_function$1(value) { + return typeof value === 'function' || value instanceof Function; +} + +function is_integer(value) { + return Number.isInteger(value); +} + +function is_list(value) { + return Array.isArray(value); +} + +function is_map$1(value) { + return value instanceof Map; +} + +function is_pid(value) { + return value instanceof ErlangTypes.PID; +} + +function is_port() { + return false; +} + +function is_reference(value) { + return value instanceof ErlangTypes.Reference; +} + +function is_tuple(value) { + return value instanceof ErlangTypes.Tuple; +} + +function is_binary(value) { + return typeof value === 'string' || value instanceof String; +} + +function element(n, tuple) { + return tuple.get(n - 1); +} + +function setelement(index, tuple1, value) { + const tupleData = [...tuple1.values]; + + tupleData[index - 1] = value; + + return new ErlangTypes.Tuple(...tupleData); +} + +function make_tuple(arity, initialValue) { + const list = []; + + for (let i = 0; i < arity; i++) { + list.push(initialValue); + } + + return new ErlangTypes.Tuple(...list); +} + +function insert_element(index, tuple, term) { + const list = [...tuple.values]; + list.splice(index - 1, 0, term); + + return new ErlangTypes.Tuple(...list); +} + +function append_element(tuple, term) { + const list = [...tuple.values]; + list.push(term); + + return new ErlangTypes.Tuple(...list); +} + +function delete_element(index, tuple) { + const list = [...tuple.values]; + list.splice(index - 1, 1); + + return new ErlangTypes.Tuple(...list); +} + +function tuple_to_list(tuple) { + const list = [...tuple.values]; + return list; +} + +function abs(number) { + return Math.abs(number); +} + +function apply(...args) { + if (args.length === 2) { + return args[0].apply(this, ...args[1]); + } + + return args[0][atom_to_binary(args[1])].apply(this, ...args[2]); +} + +function binary_part(binary, start, length) { + return binary.substring(start, start + length); +} + +function bit_size(bitstring) { + return bitstring.bit_size; +} + +function byte_size(bitstring) { + return bitstring.byte_size; +} + +function hd(list) { + return list[0]; +} + +function length(list) { + return list.length; +} + +function make_ref() { + return new ErlangTypes.Reference(); +} + +function map_size(map) { + return map.size; +} + +function max(first, second) { + return Math.max(first, second); +} + +function min(first, second) { + return Math.min(first, second); +} + +function round(number) { + return Math.round(number); +} + +function tl(list) { + return list.slice(1); +} + +function trunc(number) { + return Math.trunc(number); +} + +function tuple_size(tuple) { + return tuple.length; +} + +function binary_to_float(str) { + return parseFloat(str); +} + +function binary_to_integer(str, base = 10) { + return parseInt(str, base); +} + +function process_info(pid, item) { + if (item) { + if (item === Symbol.for('current_stacktrace')) { + return new ErlangTypes.Tuple(item, []); + } + + return new ErlangTypes.Tuple(item, null); + } + + return []; +} + +function iolist_to_binary(ioListOrBinary) { + if (ioListOrBinary === null) { + return ''; + } + + if (is_binary(ioListOrBinary)) { + return ioListOrBinary; + } + + if (is_bitstring$1(ioListOrBinary)) { + return String.fromCodePoint(...ioListOrBinary.value); + } + + const iolistFlattened = lists.flatten(ioListOrBinary); + + const value = iolistFlattened.reduce((acc, current) => { + if (current === null) { + return acc; + } else if (is_integer(current)) { + return acc + String.fromCodePoint(current); + } else if (is_bitstring$1(current)) { + return acc + String.fromCodePoint(...current.value); + } + + return acc + iolist_to_binary(current); + }, ''); + + return value; +} + +function io_size(ioListOrBinary) { + return iolist_to_binary(ioListOrBinary).length; +} + +function integer_to_binary(integer, base = 10) { + return integer.toString(base); +} + +var erlang = { + atom_to_binary, + binary_to_atom, + binary_to_existing_atom, + list_concatenation, + list_subtraction, + div, + not, + rem, + band, + bor, + bsl, + bsr, + bxor, + bnot, + is_bitstring: is_bitstring$1, + is_boolean: is_boolean$1, + is_float, + is_function: is_function$1, + is_integer, + is_list, + is_map: is_map$1, + is_number: is_number$1, + is_pid, + is_port, + is_reference, + is_tuple, + is_atom, + is_binary, + element, + setelement, + make_tuple, + insert_element, + append_element, + delete_element, + tuple_to_list, + abs, + apply, + binary_part, + bit_size, + byte_size, + hd, + length, + make_ref, + map_size, + max, + min, + round, + tl, + trunc, + tuple_size, + binary_to_float, + binary_to_integer, + process_info, + iolist_to_binary, + io_size, + integer_to_binary +}; + +// http://erlang.org/doc/man/maps.html +const OK = Symbol.for('ok'); +const ERROR = Symbol.for('error'); +const BADMAP = Symbol.for('badmap'); +const BADKEY = Symbol.for('badkey'); + +function find(key, map) { + if (erlang.is_map(map) === false) { + return new ErlangTypes.Tuple(BADMAP, map); + } + + const value = map.get(key); + + if (typeof value !== 'undefined') { + return new ErlangTypes.Tuple(OK, value); + } + + return ERROR; +} + +function fold(fun, init, map) { + let acc = init; + + for (const [key, value] of map.entries()) { + acc = fun(key, value, acc); + } + + return acc; +} + +function remove(key, map1) { + if (erlang.is_map(map1) === false) { + return new ErlangTypes.Tuple(BADMAP, map1); + } + + const map2 = new Map(map1); + + map2.delete(key); + + return map2; +} + +function to_list(map) { + if (erlang.is_map(map) === false) { + return new ErlangTypes.Tuple(BADMAP, map); + } + + const list = []; + + for (const [key, value] of map.entries()) { + list.push(new ErlangTypes.Tuple(key, value)); + } + + return list; +} + +function from_list(list) { + return list.reduce((acc, item) => { + const [key, value] = item; + acc.set(key, value); + + return acc; + }, new Map()); +} + +function keys(map) { + if (erlang.is_map(map) === false) { + return new ErlangTypes.Tuple(BADMAP, map); + } + + return Array.from(map.keys()); +} + +function values$1(map) { + if (erlang.is_map(map) === false) { + return new ErlangTypes.Tuple(BADMAP, map); + } + + return Array.from(map.values()); +} + +function is_key(key, map) { + return map.has(key); +} + +function put(key, value, map1) { + if (erlang.is_map(map1) === false) { + return new ErlangTypes.Tuple(BADMAP, map1); + } + + const map2 = new Map(map1); + map2.set(key, value); + + return map2; +} + +function merge(map1, map2) { + if (erlang.is_map(map1) === false) { + return new ErlangTypes.Tuple(BADMAP, map1); + } + + if (erlang.is_map(map2) === false) { + return new ErlangTypes.Tuple(BADMAP, map2); + } + + return new Map([...map1, ...map2]); +} + +function update(key, value, map1) { + if (erlang.is_map(map1) === false) { + return new ErlangTypes.Tuple(BADMAP, map1); + } + + if (is_key(key, map1) === false) { + return new ErlangTypes.Tuple(BADKEY, key); + } + + return new Map([...map1, [key, value]]); +} + +function get(...args) { + const key = args[0]; + const map = args[1]; + + if (erlang.is_map(map) === false) { + return new ErlangTypes.Tuple(BADMAP, map); + } + + if (is_key(key)) { + return map.get(key); + } + + if (args.length === 3) { + return args[2]; + } + + return new ErlangTypes.Tuple(BADKEY, key); +} + +function take(key, map1) { + if (erlang.is_map(map1) === false) { + return new ErlangTypes.Tuple(BADMAP, map1); + } + + if (!is_key(key)) { + return ERROR; + } + + const value = map1.get(key); + const map2 = new Map(map1); + map2.delete(key); + + return new ErlangTypes.Tuple(value, map2); +} + +var maps = { + find, + fold, + remove, + to_list, + from_list, + keys, + values: values$1, + is_key, + put, + merge, + update, + get, + take +}; + +function warn(message) { + const messageString = message.join(''); + console.warn(`warning: ${messageString}`); + + return Symbol.for('ok'); +} + +var elixir_errors = { + warn +}; + +function put_chars(ioDevice, charData) { + const dataToWrite = erlang.iolist_to_binary(charData); + + if (ioDevice === Symbol.for('stderr')) { + console.error(dataToWrite); + } else { + console.log(dataToWrite); + } + + return Symbol.for('ok'); +} + +var io = { + put_chars +}; + +function copy(subject, n = 1) { + return subject.repeat(n); +} + +var binary = { + copy +}; + +function get_key(key) { + let real_key = key; + + if (__elixirscript_names__.has(key)) { + real_key = __elixirscript_names__.get(key); + } + + if (__elixirscript_store__.has(real_key)) { + return real_key; + } + + throw new Error(`Key ${real_key} not found`); +} + +function create(value, name = null) { + const key = new Core.PID(); + + if (name !== null) { + __elixirscript_names__.set(name, key); + } + + return __elixirscript_store__.set(key, value); +} + +function update$1(key, value) { + const real_key = get_key(key); + return __elixirscript_store__.set(real_key, value); +} + +function read(key) { + const real_key = get_key(key); + return __elixirscript_store__.get(real_key); +} + +function remove$1(key) { + const real_key = get_key(key); + return __elixirscript_store__.delete(real_key); +} + +var Store = { + create, + update: update$1, + read, + remove: remove$1 +}; + +class Integer {} +class Float {} + +function get_global() { + if (typeof self !== 'undefined') { + return self; + } else if (typeof window !== 'undefined') { + return window; + } else if (typeof global !== 'undefined') { + return global; + } + + console.warn('No global state found'); + return null; +} + +const globalState = get_global(); + +globalState.__elixirscript_store__ = new Map(); +globalState.__elixirscript_names__ = new Map(); + +var Core = { + Tuple: ErlangTypes.Tuple, + PID: ErlangTypes.PID, + BitString: ErlangTypes.BitString, + Patterns, + Integer, + Float, + Functions, + SpecialForms, + Store, + global: globalState, + erlang, + maps, + lists, + elixir_errors, + io, + binary +}; + +var elixir = { + Core +}; + +return elixir; + +}()); diff --git a/src/javascript/lib/core/erlang_compat/io.js b/src/javascript/lib/core/erlang_compat/io.js index d01c42c6..5d297921 100644 --- a/src/javascript/lib/core/erlang_compat/io.js +++ b/src/javascript/lib/core/erlang_compat/io.js @@ -1,7 +1,7 @@ import erlang from './erlang'; function put_chars(ioDevice, charData) { - let dataToWrite = erlang.iolist_to_binary(charData); + const dataToWrite = erlang.iolist_to_binary(charData); if (ioDevice === Symbol.for('stderr')) { console.error(dataToWrite); diff --git a/src/javascript/lib/core/protocol.js b/src/javascript/lib/core/protocol.js index ac292a81..1b508e29 100644 --- a/src/javascript/lib/core/protocol.js +++ b/src/javascript/lib/core/protocol.js @@ -31,6 +31,7 @@ class Protocol { fun = this.registry.get(Core.BitString)[funName]; } else if ( thing && + thing instanceof Map && thing.has(Symbol.for('__struct__')) && this.hasImplementation(thing) ) { @@ -72,7 +73,11 @@ class Protocol { thing === Core.BitString ) { return this.registry.has(thing); - } else if (thing && thing.has(Symbol.for('__struct__'))) { + } else if ( + thing && + thing instanceof Map && + thing.has(Symbol.for('__struct__')) + ) { return this.registry.has(thing.get(Symbol.for('__struct__')).__MODULE__); } diff --git a/yarn.lock b/yarn.lock index ebbc6518..66443a82 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3678,9 +3678,9 @@ table@^4.0.1: slice-ansi "0.0.4" string-width "^2.0.0" -tailored@^2.6.3: - version "2.6.3" - resolved "https://registry.yarnpkg.com/tailored/-/tailored-2.6.3.tgz#27d1069dd3f5b2f2009d6437efcb26c595bccfda" +tailored@^2.6.4: + version "2.6.4" + resolved "https://registry.yarnpkg.com/tailored/-/tailored-2.6.4.tgz#c81bdfe8b50c35298ed87c684d493467a87182c5" dependencies: erlang-types "^1.0.1" From 82824a8bfa38d0e2b5f6e5eb132917945259a4ff Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Sat, 29 Jul 2017 11:03:01 -0500 Subject: [PATCH 196/418] Add tail call tail call optimization This works by using a trampoline function defined in ElixirScript.Core.Functions JavaScript module. --- .../passes/translate/function.ex | 97 +- priv/build/iife/ElixirScript.Core.js | 2565 +---------------- .../lib/core/erlang_compat/erlang.js | 4 + src/javascript/lib/core/functions.js | 20 +- test/compiler_test.exs | 6 +- test/passes/translate/form_test.exs | 5 +- 6 files changed, 129 insertions(+), 2568 deletions(-) diff --git a/lib/elixir_script/passes/translate/function.ex b/lib/elixir_script/passes/translate/function.ex index fe67824c..b6c70245 100644 --- a/lib/elixir_script/passes/translate/function.ex +++ b/lib/elixir_script/passes/translate/function.ex @@ -31,7 +31,8 @@ defmodule ElixirScript.Translate.Function do :let ) - function_dec = J.arrow_function_expression( + function_recur_dec = J.function_declaration( + J.identifier("recur"), [J.rest_element(J.identifier("__function_args__"))], [], J.block_statement([ @@ -49,6 +50,17 @@ defmodule ElixirScript.Translate.Function do ]) ) + function_dec = J.arrow_function_expression( + [J.rest_element(J.identifier("__function_args__"))], + [], + J.block_statement([ + function_recur_dec, + J.return_statement( + trampoline() + ) + ]) + ) + { function_dec, state } end @@ -66,8 +78,8 @@ defmodule ElixirScript.Translate.Function do :let ) - function_dec = J.function_declaration( - ElixirScript.Translate.Identifier.make_function_name(name), + function_recur_dec = J.function_declaration( + J.identifier("recur"), [J.rest_element(J.identifier("__function_args__"))], [], J.block_statement([ @@ -85,6 +97,18 @@ defmodule ElixirScript.Translate.Function do ]) ) + function_dec = J.function_declaration( + ElixirScript.Translate.Identifier.make_function_name(name), + [J.rest_element(J.identifier("__function_args__"))], + [], + J.block_statement([ + function_recur_dec, + J.return_statement( + trampoline() + ) + ]) + ) + { function_dec, state } end @@ -132,6 +156,7 @@ defmodule ElixirScript.Translate.Function do body = body |> Clause.return_last_statement + |> update_last_call(state) declarator = J.variable_declarator( J.array_expression(params), @@ -168,4 +193,70 @@ defmodule ElixirScript.Translate.Function do {ast, state} end + + defp update_last_call(clause_body, %{function: {name, _}}) do + last_item = List.last(clause_body) + function_name = ElixirScript.Translate.Identifier.make_function_name(name) + + case last_item do + %ESTree.ReturnStatement{ argument: %ESTree.CallExpression{ callee: ^function_name, arguments: arguments } } -> + new_last_item = J.return_statement( + recurse( + recur_bind(arguments) + ) + ) + + List.replace_at(clause_body, length(clause_body) - 1, new_last_item) + _ -> + clause_body + end + end + + defp recur_bind(args) do + J.call_expression( + J.member_expression( + J.identifier("recur"), + J.identifier("bind") + ), + [J.identifier("null")] ++ args + ) + end + + defp recurse(func) do + J.new_expression( + J.member_expression( + J.member_expression( + J.identifier("ElixirScript"), + J.member_expression( + J.identifier("Core"), + J.identifier("Functions") + ) + ), + J.identifier("Recurse") + ), + [ + func + ] + ) + end + + defp trampoline() do + J.call_expression( + J.member_expression( + J.member_expression( + J.identifier("ElixirScript"), + J.member_expression( + J.identifier("Core"), + J.identifier("Functions") + ) + ), + J.identifier("trampoline") + ), + [ + recurse( + recur_bind([J.rest_element(J.identifier("__function_args__"))]) + ) + ] + ) + end end diff --git a/priv/build/iife/ElixirScript.Core.js b/priv/build/iife/ElixirScript.Core.js index 80caf094..0242e617 100644 --- a/priv/build/iife/ElixirScript.Core.js +++ b/priv/build/iife/ElixirScript.Core.js @@ -1,2559 +1,6 @@ -var ElixirScript = (function () { -'use strict'; - -/* @flow */ - -class Variable { - constructor(name = null, default_value = Symbol.for('tailored.no_value')) { - this.name = name; - this.default_value = default_value; - } -} - -class Wildcard { - constructor() {} -} - -class StartsWith { - constructor(prefix) { - this.prefix = prefix; - } -} - -class Capture { - constructor(value) { - this.value = value; - } -} - -class HeadTail { - constructor(head, tail) { - this.head = head; - this.tail = tail; - } -} - -class Type { - constructor(type, objPattern = {}) { - this.type = type; - this.objPattern = objPattern; - } -} - -class Bound { - constructor(value) { - this.value = value; - } -} - -class BitStringMatch { - constructor(...values) { - this.values = values; - } - - length() { - return values.length; - } - - bit_size() { - return this.byte_size() * 8; - } - - byte_size() { - let s = 0; - - for (let val of this.values) { - s = s + val.unit * val.size / 8; - } - - return s; - } - - getValue(index) { - return this.values(index); - } - - getSizeOfValue(index) { - let val = this.getValue(index); - return val.unit * val.size; - } - - getTypeOfValue(index) { - return this.getValue(index).type; - } -} - -class NamedVariableResult { - constructor(name, value) { - this.name = name; - this.value = value; - } -} - -function variable(name = null, default_value = Symbol.for('tailored.no_value')) { - return new Variable(name, default_value); -} - -function wildcard() { - return new Wildcard(); -} - -function startsWith(prefix) { - return new StartsWith(prefix); -} - -function capture(value) { - return new Capture(value); -} - -function headTail(head, tail) { - return new HeadTail(head, tail); -} - -function type(type, objPattern = {}) { - return new Type(type, objPattern); -} - -function bound(value) { - return new Bound(value); -} - -function bitStringMatch(...values) { - return new BitStringMatch(...values); -} - -function namedVariableResult(name, value) { - return new NamedVariableResult(name, value); -} - -/* @flow */ - -function is_number(value) { - return typeof value === 'number'; -} - -function is_string(value) { - return typeof value === 'string'; -} - -function is_boolean(value) { - return typeof value === 'boolean'; -} - -function is_symbol(value) { - return typeof value === 'symbol'; -} - -function is_object(value) { - return typeof value === 'object'; -} - -function is_variable(value) { - return value instanceof Variable; -} - -function is_null(value) { - return value === null; -} - -function is_array(value) { - return Array.isArray(value); -} - -function is_function(value) { - return Object.prototype.toString.call(value) == '[object Function]'; -} - -function is_map(value) { - return value instanceof Map; -} - -class Tuple { - constructor(...args) { - this.values = Object.freeze(args); - this.length = this.values.length; - } - - get(index) { - return this.values[index]; - } - - count() { - return this.values.length; - } - - [Symbol.iterator]() { - return this.values[Symbol.iterator](); - } - - toString() { - let i, - s = ''; - for (i = 0; i < this.values.length; i++) { - if (s !== '') { - s += ', '; - } - - const stringToAppend = this.values[i] ? this.values[i].toString() : ''; - - s += stringToAppend; - } - - return '{' + s + '}'; - } - - put_elem(index, elem) { - if (index === this.length) { - let new_values = this.values.concat([elem]); - return new Tuple(...new_values); - } - - let new_values = this.values.concat([]); - new_values.splice(index, 0, elem); - return new Tuple(...new_values); - } - - remove_elem(index) { - let new_values = this.values.concat([]); - new_values.splice(index, 1); - return new Tuple(...new_values); - } -} - -let process_counter = -1; - -class PID { - constructor() { - process_counter = process_counter + 1; - this.id = process_counter; - } - - toString() { - return 'PID#<0.' + this.id + '.0>'; - } -} - -let ref_counter = -1; - -class Reference { - constructor() { - ref_counter = ref_counter + 1; - this.id = ref_counter; - this.ref = Symbol(); - } - - toString() { - return 'Ref#<0.0.0.' + this.id + '>'; - } -} - -class BitString$1 { - constructor(...args) { - this.value = Object.freeze(this.process(args)); - this.length = this.value.length; - this.bit_size = this.length * 8; - this.byte_size = this.length; - } - - get(index) { - return this.value[index]; - } - - count() { - return this.value.length; - } - - slice(start, end = null) { - let s = this.value.slice(start, end); - let ms = s.map(elem => BitString$1.integer(elem)); - return new BitString$1(...ms); - } - - [Symbol.iterator]() { - return this.value[Symbol.iterator](); - } - - toString() { - var i, - s = ''; - for (i = 0; i < this.count(); i++) { - if (s !== '') { - s += ', '; - } - s += this.get(i).toString(); - } - - return '<<' + s + '>>'; - } - - process(bitStringParts) { - let processed_values = []; - - var i; - for (i = 0; i < bitStringParts.length; i++) { - let processed_value = this['process_' + bitStringParts[i].type](bitStringParts[i]); - - for (let attr of bitStringParts[i].attributes) { - processed_value = this['process_' + attr](processed_value); - } - - processed_values = processed_values.concat(processed_value); - } - - return processed_values; - } - - process_integer(value) { - return value.value; - } - - process_float(value) { - if (value.size === 64) { - return BitString$1.float64ToBytes(value.value); - } else if (value.size === 32) { - return BitString$1.float32ToBytes(value.value); - } - - throw new Error('Invalid size for float'); - } - - process_bitstring(value) { - return value.value.value; - } - - process_binary(value) { - return BitString$1.toUTF8Array(value.value); - } - - process_utf8(value) { - return BitString$1.toUTF8Array(value.value); - } - - process_utf16(value) { - return BitString$1.toUTF16Array(value.value); - } - - process_utf32(value) { - return BitString$1.toUTF32Array(value.value); - } - - process_signed(value) { - return new Uint8Array([value])[0]; - } - - process_unsigned(value) { - return value; - } - - process_native(value) { - return value; - } - - process_big(value) { - return value; - } - - process_little(value) { - return value.reverse(); - } - - process_size(value) { - return value; - } - - process_unit(value) { - return value; - } - - static integer(value) { - return BitString$1.wrap(value, { type: 'integer', unit: 1, size: 8 }); - } - - static float(value) { - return BitString$1.wrap(value, { type: 'float', unit: 1, size: 64 }); - } - - static bitstring(value) { - return BitString$1.wrap(value, { - type: 'bitstring', - unit: 1, - size: value.bit_size - }); - } - - static bits(value) { - return BitString$1.bitstring(value); - } - - static binary(value) { - return BitString$1.wrap(value, { - type: 'binary', - unit: 8, - size: value.length - }); - } - - static bytes(value) { - return BitString$1.binary(value); - } - - static utf8(value) { - return BitString$1.wrap(value, { type: 'utf8', unit: 1, size: value.length }); - } - - static utf16(value) { - return BitString$1.wrap(value, { - type: 'utf16', - unit: 1, - size: value.length * 2 - }); - } - - static utf32(value) { - return BitString$1.wrap(value, { - type: 'utf32', - unit: 1, - size: value.length * 4 - }); - } - - static signed(value) { - return BitString$1.wrap(value, {}, 'signed'); - } - - static unsigned(value) { - return BitString$1.wrap(value, {}, 'unsigned'); - } - - static native(value) { - return BitString$1.wrap(value, {}, 'native'); - } - - static big(value) { - return BitString$1.wrap(value, {}, 'big'); - } - - static little(value) { - return BitString$1.wrap(value, {}, 'little'); - } - - static size(value, count) { - return BitString$1.wrap(value, { size: count }); - } - - static unit(value, count) { - return BitString$1.wrap(value, { unit: count }); - } - - static wrap(value, opt, new_attribute = null) { - let the_value = value; - - if (!(value instanceof Object)) { - the_value = { value: value, attributes: [] }; - } - - the_value = Object.assign(the_value, opt); - - if (new_attribute) { - the_value.attributes.push(new_attribute); - } - - return the_value; - } - - static toUTF8Array(str) { - var utf8 = []; - for (var i = 0; i < str.length; i++) { - var charcode = str.charCodeAt(i); - if (charcode < 0x80) { - utf8.push(charcode); - } else if (charcode < 0x800) { - utf8.push(0xc0 | charcode >> 6, 0x80 | charcode & 0x3f); - } else if (charcode < 0xd800 || charcode >= 0xe000) { - utf8.push(0xe0 | charcode >> 12, 0x80 | charcode >> 6 & 0x3f, 0x80 | charcode & 0x3f); - } else { - // surrogate pair - i++; - // UTF-16 encodes 0x10000-0x10FFFF by - // subtracting 0x10000 and splitting the - // 20 bits of 0x0-0xFFFFF into two halves - charcode = 0x10000 + ((charcode & 0x3ff) << 10 | str.charCodeAt(i) & 0x3ff); - utf8.push(0xf0 | charcode >> 18, 0x80 | charcode >> 12 & 0x3f, 0x80 | charcode >> 6 & 0x3f, 0x80 | charcode & 0x3f); - } - } - return utf8; - } - - static toUTF16Array(str) { - var utf16 = []; - for (var i = 0; i < str.length; i++) { - var codePoint = str.codePointAt(i); - - if (codePoint <= 255) { - utf16.push(0); - utf16.push(codePoint); - } else { - utf16.push(codePoint >> 8 & 0xff); - utf16.push(codePoint & 0xff); - } - } - return utf16; - } - - static toUTF32Array(str) { - var utf32 = []; - for (var i = 0; i < str.length; i++) { - var codePoint = str.codePointAt(i); - - if (codePoint <= 255) { - utf32.push(0); - utf32.push(0); - utf32.push(0); - utf32.push(codePoint); - } else { - utf32.push(0); - utf32.push(0); - utf32.push(codePoint >> 8 & 0xff); - utf32.push(codePoint & 0xff); - } - } - return utf32; - } - - //http://stackoverflow.com/questions/2003493/javascript-float-from-to-bits - static float32ToBytes(f) { - var bytes = []; - - var buf = new ArrayBuffer(4); - new Float32Array(buf)[0] = f; - - let intVersion = new Uint32Array(buf)[0]; - - bytes.push(intVersion >> 24 & 0xff); - bytes.push(intVersion >> 16 & 0xff); - bytes.push(intVersion >> 8 & 0xff); - bytes.push(intVersion & 0xff); - - return bytes; - } - - static float64ToBytes(f) { - var bytes = []; - - var buf = new ArrayBuffer(8); - new Float64Array(buf)[0] = f; - - var intVersion1 = new Uint32Array(buf)[0]; - var intVersion2 = new Uint32Array(buf)[1]; - - bytes.push(intVersion2 >> 24 & 0xff); - bytes.push(intVersion2 >> 16 & 0xff); - bytes.push(intVersion2 >> 8 & 0xff); - bytes.push(intVersion2 & 0xff); - - bytes.push(intVersion1 >> 24 & 0xff); - bytes.push(intVersion1 >> 16 & 0xff); - bytes.push(intVersion1 >> 8 & 0xff); - bytes.push(intVersion1 & 0xff); - - return bytes; - } -} - -var ErlangTypes = { - Tuple, - PID, - Reference, - BitString: BitString$1 -}; - -/* @flow */ - -const BitString = ErlangTypes.BitString; - -function resolveSymbol(pattern) { - return function (value) { - return is_symbol(value) && value === pattern; - }; -} - -function resolveString(pattern) { - return function (value) { - return is_string(value) && value === pattern; - }; -} - -function resolveNumber(pattern) { - return function (value) { - return is_number(value) && value === pattern; - }; -} - -function resolveBoolean(pattern) { - return function (value) { - return is_boolean(value) && value === pattern; - }; -} - -function resolveFunction(pattern) { - return function (value) { - return is_function(value) && value === pattern; - }; -} - -function resolveNull(pattern) { - return function (value) { - return is_null(value); - }; -} - -function resolveBound(pattern) { - return function (value, args) { - if (typeof value === typeof pattern.value && value === pattern.value) { - return true; - } - - return false; - }; -} - -function resolveWildcard() { - return function () { - return true; - }; -} - -function resolveVariable(pattern) { - return function (value, args) { - if (pattern.name === null) { - args.push(value); - } else if (!pattern.name.startsWith('_')) { - args.push(namedVariableResult(pattern.name, value)); - } - - return true; - }; -} - -function resolveHeadTail(pattern) { - const headMatches = buildMatch(pattern.head); - const tailMatches = buildMatch(pattern.tail); - - return function (value, args) { - if (!is_array(value) || value.length === 0) { - return false; - } - - const head = value[0]; - const tail = value.slice(1); - - if (headMatches(head, args) && tailMatches(tail, args)) { - return true; - } - - return false; - }; -} - -function resolveCapture(pattern) { - const matches = buildMatch(pattern.value); - - return function (value, args) { - if (matches(value, args)) { - args.push(value); - return true; - } - - return false; - }; -} - -function resolveStartsWith(pattern) { - const prefix = pattern.prefix; - - return function (value, args) { - if (is_string(value) && value.startsWith(prefix)) { - args.push(value.substring(prefix.length)); - return true; - } - - return false; - }; -} - -function resolveType(pattern) { - return function (value, args) { - if (value instanceof pattern.type) { - const matches = buildMatch(pattern.objPattern); - return matches(value, args); - } - - return false; - }; -} - -function resolveArray(pattern) { - const matches = pattern.map(x => buildMatch(x)); - - return function (value, args) { - if (!is_array(value) || value.length != pattern.length) { - return false; - } - - return value.every(function (v, i) { - return matches[i](value[i], args); - }); - }; -} - -function resolveMap(pattern) { - let matches = new Map(); - - const keys = Array.from(pattern.keys()); - - for (let key of keys) { - matches.set(key, buildMatch(pattern.get(key))); - } - - return function (value, args) { - if (!is_map(value) || pattern.size > value.size) { - return false; - } - - for (let key of keys) { - if (!value.has(key) || !matches.get(key)(value.get(key), args)) { - return false; - } - } - - return true; - }; -} - -function resolveObject(pattern) { - let matches = {}; - - const keys = Object.keys(pattern).concat(Object.getOwnPropertySymbols(pattern)); - - for (let key of keys) { - matches[key] = buildMatch(pattern[key]); - } - - return function (value, args) { - if (!is_object(value) || pattern.length > value.length) { - return false; - } - - for (let key of keys) { - if (!(key in value) || !matches[key](value[key], args)) { - return false; - } - } - - return true; - }; -} - -function resolveBitString(pattern) { - let patternBitString = []; - - for (let bitstringMatchPart of pattern.values) { - if (is_variable(bitstringMatchPart.value)) { - let size = getSize(bitstringMatchPart.unit, bitstringMatchPart.size); - fillArray(patternBitString, size); - } else { - patternBitString = patternBitString.concat(new BitString(bitstringMatchPart).value); - } - } - - let patternValues = pattern.values; - - return function (value, args) { - let bsValue = null; - - if (!is_string(value) && !(value instanceof BitString)) { - return false; - } - - if (is_string(value)) { - bsValue = new BitString(BitString.binary(value)); - } else { - bsValue = value; - } - - let beginningIndex = 0; - - for (let i = 0; i < patternValues.length; i++) { - let bitstringMatchPart = patternValues[i]; - - if (is_variable(bitstringMatchPart.value) && bitstringMatchPart.type == 'binary' && bitstringMatchPart.size === undefined && i < patternValues.length - 1) { - throw new Error('a binary field without size is only allowed at the end of a binary pattern'); - } - - let size = 0; - let bsValueArrayPart = []; - let patternBitStringArrayPart = []; - size = getSize(bitstringMatchPart.unit, bitstringMatchPart.size); - - if (i === patternValues.length - 1) { - bsValueArrayPart = bsValue.value.slice(beginningIndex); - patternBitStringArrayPart = patternBitString.slice(beginningIndex); - } else { - bsValueArrayPart = bsValue.value.slice(beginningIndex, beginningIndex + size); - patternBitStringArrayPart = patternBitString.slice(beginningIndex, beginningIndex + size); - } - - if (is_variable(bitstringMatchPart.value)) { - switch (bitstringMatchPart.type) { - case 'integer': - if (bitstringMatchPart.attributes && bitstringMatchPart.attributes.indexOf('signed') != -1) { - args.push(new Int8Array([bsValueArrayPart[0]])[0]); - } else { - args.push(new Uint8Array([bsValueArrayPart[0]])[0]); - } - break; - - case 'float': - if (size === 64) { - args.push(Float64Array.from(bsValueArrayPart)[0]); - } else if (size === 32) { - args.push(Float32Array.from(bsValueArrayPart)[0]); - } else { - return false; - } - break; - - case 'bitstring': - args.push(createBitString(bsValueArrayPart)); - break; - - case 'binary': - args.push(String.fromCharCode.apply(null, new Uint8Array(bsValueArrayPart))); - break; - - case 'utf8': - args.push(String.fromCharCode.apply(null, new Uint8Array(bsValueArrayPart))); - break; - - case 'utf16': - args.push(String.fromCharCode.apply(null, new Uint16Array(bsValueArrayPart))); - break; - - case 'utf32': - args.push(String.fromCharCode.apply(null, new Uint32Array(bsValueArrayPart))); - break; - - default: - return false; - } - } else if (!arraysEqual(bsValueArrayPart, patternBitStringArrayPart)) { - return false; - } - - beginningIndex = beginningIndex + size; - } - - return true; - }; -} - -function getSize(unit, size) { - return unit * size / 8; -} - -function arraysEqual(a, b) { - if (a === b) return true; - if (a == null || b == null) return false; - if (a.length != b.length) return false; - - for (var i = 0; i < a.length; ++i) { - if (a[i] !== b[i]) return false; - } - - return true; -} - -function fillArray(arr, num) { - for (let i = 0; i < num; i++) { - arr.push(0); - } -} - -function createBitString(arr) { - let integerParts = arr.map(elem => BitString.integer(elem)); - return new BitString(...integerParts); -} - -function resolveNoMatch() { - return function () { - return false; - }; -} - -const patternMap = new Map(); -patternMap.set(Variable.prototype, resolveVariable); -patternMap.set(Wildcard.prototype, resolveWildcard); -patternMap.set(HeadTail.prototype, resolveHeadTail); -patternMap.set(StartsWith.prototype, resolveStartsWith); -patternMap.set(Capture.prototype, resolveCapture); -patternMap.set(Bound.prototype, resolveBound); -patternMap.set(Type.prototype, resolveType); -patternMap.set(BitStringMatch.prototype, resolveBitString); -patternMap.set(Number.prototype, resolveNumber); -patternMap.set(Symbol.prototype, resolveSymbol); -patternMap.set(Map.prototype, resolveMap); -patternMap.set(Array.prototype, resolveArray); -patternMap.set(String.prototype, resolveString); -patternMap.set(Boolean.prototype, resolveBoolean); -patternMap.set(Function.prototype, resolveFunction); -patternMap.set(Object.prototype, resolveObject); - -function buildMatch(pattern) { - if (pattern === null) { - return resolveNull(pattern); - } - - if (typeof pattern === 'undefined') { - return resolveWildcard(pattern); - } - - const type$$1 = pattern.constructor.prototype; - const resolver = patternMap.get(type$$1); - - if (resolver) { - return resolver(pattern); - } - - if (typeof pattern === 'object') { - return resolveObject(pattern); - } - - return resolveNoMatch(); -} - -class MatchError extends Error { - constructor(arg) { - super(); - - if (typeof arg === 'symbol') { - this.message = 'No match for: ' + arg.toString(); - } else if (Array.isArray(arg)) { - let mappedValues = arg.map(x => { - if (x === null) { - return 'null'; - } else if (typeof x === 'undefined') { - return 'undefined'; - } - - return x.toString(); - }); - - this.message = 'No match for: ' + mappedValues; - } else { - this.message = 'No match for: ' + arg; - } - - this.stack = new Error().stack; - this.name = this.constructor.name; - } -} - -class Clause { - constructor(pattern, fn, guard = () => true) { - this.pattern = buildMatch(pattern); - this.arity = pattern.length; - this.optionals = getOptionalValues(pattern); - this.fn = fn; - this.guard = guard; - } -} - -function clause(pattern, fn, guard = () => true) { - return new Clause(pattern, fn, guard); -} - - - -function defmatch(...clauses) { - const arities = getArityMap(clauses); - - return function (...args) { - let [funcToCall, params] = findMatchingFunction(args, arities); - return funcToCall.apply(this, params); - }; -} - -function defmatchgen(...clauses) { - const arities = getArityMap(clauses); - - return function* (...args) { - let [funcToCall, params] = findMatchingFunction(args, arities); - return yield* funcToCall.apply(this, params); - }; -} - -function defmatchGen(...args) { - return defmatchgen(...args); -} - -function defmatchAsync(...clauses) { - const arities = getArityMap(clauses); - - return async function (...args) { - if (arities.has(args.length)) { - const arityClauses = arities.get(args.length); - - let funcToCall = null; - let params = null; - for (let processedClause of arityClauses) { - let result = []; - args = fillInOptionalValues(args, processedClause.arity, processedClause.optionals); - - const doesMatch = processedClause.pattern(args, result); - const [filteredResult, allNamesMatch] = checkNamedVariables(result); - - if (doesMatch && allNamesMatch && (await processedClause.guard.apply(this, result))) { - funcToCall = processedClause.fn; - params = result; - break; - } - } - - if (!funcToCall) { - console.error('No match for:', args); - throw new MatchError(args); - } - - return funcToCall.apply(this, params); - } else { - console.error('Arity of', args.length, 'not found. No match for:', args); - throw new MatchError(args); - } - }; -} - -function findMatchingFunction(args, arities) { - if (arities.has(args.length)) { - const arityClauses = arities.get(args.length); - - let funcToCall = null; - let params = null; - for (let processedClause of arityClauses) { - let result = []; - args = fillInOptionalValues(args, processedClause.arity, processedClause.optionals); - - const doesMatch = processedClause.pattern(args, result); - const [filteredResult, allNamesMatch] = checkNamedVariables(result); - - if (doesMatch && allNamesMatch && processedClause.guard.apply(this, filteredResult)) { - funcToCall = processedClause.fn; - params = filteredResult; - break; - } - } - - if (!funcToCall) { - console.error('No match for:', args); - throw new MatchError(args); - } - - return [funcToCall, params]; - } else { - console.error('Arity of', args.length, 'not found. No match for:', args); - throw new MatchError(args); - } -} - -function getArityMap(clauses) { - let map = new Map(); - - for (const clause of clauses) { - const range = getArityRange(clause); - - for (const arity of range) { - let arityClauses = []; - - if (map.has(arity)) { - arityClauses = map.get(arity); - } - - arityClauses.push(clause); - map.set(arity, arityClauses); - } - } - - return map; -} - -function getArityRange(clause) { - const min = clause.arity - clause.optionals.length; - const max = clause.arity; - - let range = [min]; - - while (range[range.length - 1] != max) { - range.push(range[range.length - 1] + 1); - } - - return range; -} - -function getOptionalValues(pattern) { - let optionals = []; - - for (let i = 0; i < pattern.length; i++) { - if (pattern[i] instanceof Variable && pattern[i].default_value != Symbol.for('tailored.no_value')) { - optionals.push([i, pattern[i].default_value]); - } - } - - return optionals; -} - -function fillInOptionalValues(args, arity, optionals) { - if (args.length === arity || optionals.length === 0) { - return args; - } - - if (args.length + optionals.length < arity) { - return args; - } - - let numberOfOptionalsToFill = arity - args.length; - let optionalsToRemove = optionals.length - numberOfOptionalsToFill; - - let optionalsToUse = optionals.slice(optionalsToRemove); - - for (let [index, value] of optionalsToUse) { - args.splice(index, 0, value); - if (args.length === arity) { - break; - } - } - - return args; -} - -function match(pattern, expr, guard = () => true) { - let result = []; - let processedPattern = buildMatch(pattern); - const doesMatch = processedPattern(expr, result); - const [filteredResult, allNamesMatch] = checkNamedVariables(result); - - if (doesMatch && allNamesMatch && guard.apply(this, filteredResult)) { - return filteredResult; - } else { - console.error('No match for:', expr); - throw new MatchError(expr); - } -} - -function checkNamedVariables(results) { - const namesMap = {}; - const filteredResults = []; - - for (let i = 0; i < results.length; i++) { - const current = results[i]; - if (current instanceof NamedVariableResult) { - if (namesMap[current.name] && namesMap[current.name] !== current.value) { - return [results, false]; - } else if (namesMap[current.name] && namesMap[current.name] === current.value) { - filteredResults.push(current.value); - } else { - namesMap[current.name] = current.value; - filteredResults.push(current.value); - } - } else { - filteredResults.push(current); - } - } - - return [filteredResults, true]; -} - -function match_or_default(pattern, expr, guard = () => true, default_value = null) { - let result = []; - let processedPattern = buildMatch(pattern); - const doesMatch = processedPattern(expr, result); - const [filteredResult, allNamesMatch] = checkNamedVariables(result); - - if (doesMatch && allNamesMatch && guard.apply(this, filteredResult)) { - return filteredResult; - } else { - return default_value; - } -} - -const NO_MATCH = Symbol(); - -function bitstring_generator(pattern, bitstring) { - return function () { - let returnResult = []; - let bsSlice = bitstring.slice(0, pattern.byte_size()); - let i = 1; - - while (bsSlice.byte_size == pattern.byte_size()) { - const result = match_or_default(pattern, bsSlice, () => true, NO_MATCH); - - if (result != NO_MATCH) { - const [value] = result; - returnResult.push(result); - } - - bsSlice = bitstring.slice(pattern.byte_size() * i, pattern.byte_size() * (i + 1)); - - i++; - } - - return returnResult; - }; -} - -function list_generator(pattern, list) { - return function () { - let returnResult = []; - for (let i of list) { - const result = match_or_default(pattern, i, () => true, NO_MATCH); - if (result != NO_MATCH) { - const [value] = result; - returnResult.push(value); - } - } - - return returnResult; - }; -} - -function list_comprehension(expression, generators) { - const generatedValues = run_generators(generators.pop()(), generators); - - let result = []; - - for (let value of generatedValues) { - if (expression.guard.apply(this, value)) { - result.push(expression.fn.apply(this, value)); - } - } - - return result; -} - -function run_generators(generator, generators) { - if (generators.length == 0) { - return generator.map(x => { - if (Array.isArray(x)) { - return x; - } else { - return [x]; - } - }); - } else { - const list = generators.pop(); - - let next_gen = []; - for (let j of list()) { - for (let i of generator) { - next_gen.push([j].concat(i)); - } - } - - return run_generators(next_gen, generators); - } -} - -function bitstring_comprehension(expression, generators) { - const generatedValues = run_generators(generators.pop()(), generators); - - let result = []; - - for (let value of generatedValues) { - if (expression.guard.apply(this, value)) { - result.push(expression.fn.apply(this, value)); - } - } - - result = result.map(x => ErlangTypes.BitString.integer(x)); - return new ErlangTypes.BitString(...result); -} - -var Patterns = { - defmatch, - match, - MatchError, - variable, - wildcard, - startsWith, - capture, - headTail, - type, - bound, - Clause, - clause, - bitStringMatch, - match_or_default, - defmatchgen, - list_comprehension, - list_generator, - bitstring_generator, - bitstring_comprehension, - defmatchGen, - defmatchAsync -}; - -// https://github.com/airportyh/protomorphism -class Protocol { - constructor(spec) { - this.registry = new Map(); - this.fallback = null; - - function createFun(funName) { - return function (...args) { - const thing = args[0]; - let fun = null; - - if (thing === null && this.hasImplementation(Symbol('null'))) { - fun = this.registry.get(Symbol)[funName]; - } else if (Number.isInteger(thing) && this.hasImplementation(Core.Integer)) { - fun = this.registry.get(Core.Integer)[funName]; - } else if (typeof thing === 'number' && !Number.isInteger(thing) && this.hasImplementation(Core.Float)) { - fun = this.registry.get(Core.Float)[funName]; - } else if (typeof thing === 'string' && this.hasImplementation(Core.BitString)) { - fun = this.registry.get(Core.BitString)[funName]; - } else if (thing && thing instanceof Map && thing.has(Symbol.for('__struct__')) && this.hasImplementation(thing)) { - fun = this.registry.get(thing.get(Symbol.for('__struct__')).__MODULE__)[funName]; - } else if (thing !== null && this.hasImplementation(thing)) { - fun = this.registry.get(thing.constructor)[funName]; - } else if (this.fallback) { - fun = this.fallback[funName]; - } - - if (fun != null) { - const retval = fun.apply(this, args); - return retval; - } - - throw new Error(`No implementation found for ${thing}`); - }; - } - - for (const funName in spec) { - this[funName] = createFun(funName).bind(this); - } - } - - implementation(type, implementation) { - if (type === null) { - this.fallback = implementation; - } else { - this.registry.set(type, implementation); - } - } - - hasImplementation(thing) { - if (thing === Core.Integer || thing === Core.Float || thing === Core.BitString) { - return this.registry.has(thing); - } else if (thing && thing instanceof Map && thing.has(Symbol.for('__struct__'))) { - return this.registry.has(thing.get(Symbol.for('__struct__')).__MODULE__); - } - - return this.registry.has(thing.constructor); - } -} - -function iterator_to_reducer(iterable, acc, fun) { - const iterator = iterable[Symbol.iterator](); - let x = iterator.next(); - let _acc = acc; - - while (x.done === false) { - _acc = fun(x.value, _acc.get(1)); - if (_acc.get(0) === Symbol.for('halt')) { - return new Core.Tuple(Symbol.for('halted'), _acc.get(1)); - } else if (_acc.get(0) === Symbol.for('suspend')) { - return new Core.Tuple(Symbol.for('suspended'), _acc.get(1), new_acc => { - return iterator_to_reducer(iterator, new_acc, fun); - }); - } - - x = iterator.next(); - } - - return new Core.Tuple(Symbol.for('done'), _acc.get(1)); -} - -function call_property(item, property) { - if (!property) { - if (item instanceof Function || typeof item === 'function') { - return item(); - } - - return item; - } - - if (item instanceof Map) { - let prop = null; - - if (item.has(property)) { - prop = property; - } else if (item.has(Symbol.for(property))) { - prop = Symbol.for(property); - } - - if (prop === null) { - throw new Error(`Property ${property} not found in ${item}`); - } - - if (item.get(prop) instanceof Function || typeof item.get(prop) === 'function') { - return item.get(prop)(); - } - return item.get(prop); - } - - let prop = null; - - if (typeof item === 'number' || typeof item === 'symbol' || typeof item === 'boolean' || typeof item === 'string') { - if (item[property] !== undefined) { - prop = property; - } else if (item[Symbol.for(property)] !== undefined) { - prop = Symbol.for(property); - } - } else if (property in item) { - prop = property; - } else if (Symbol.for(property) in item) { - prop = Symbol.for(property); - } - - if (prop === null) { - throw new Error(`Property ${property} not found in ${item}`); - } - - if (item[prop] instanceof Function || typeof item[prop] === 'function') { - return item[prop](); - } - return item[prop]; -} - -function defprotocol(spec) { - return new Protocol(spec); -} - -function defimpl(protocol, type, impl) { - protocol.implementation(type, impl); -} - -function build_namespace(ns, ns_string) { - let parts = ns_string.split('.'); - const root = ns; - let parent = ns; - - if (parts[0] === 'Elixir') { - parts = parts.slice(1); - } - - for (const part of parts) { - if (typeof parent[part] === 'undefined') { - parent[part] = {}; - } - - parent = parent[part]; - } - - root.__table__ = ns.__table__ || {}; - root.__table__[Symbol.for(ns_string)] = parent; - - return parent; -} - -function map_to_object(map) { - const object = {}; - - for (const [key, value] of map.entries()) { - if (value instanceof Map) { - object[key] = map_to_object(value); - } else { - object[key] = value; - } - } - - return object; -} - -var Functions = { - call_property, - defprotocol, - defimpl, - build_namespace, - iterator_to_reducer, - map_to_object -}; - -function _case(condition, clauses) { - return Core.Patterns.defmatch(...clauses)(condition); -} - -function cond(...clauses) { - for (const clause of clauses) { - if (clause[0]) { - return clause[1](); - } - } - - throw new Error(); -} - -function _for(expression, generators, collectable_protocol, into = []) { - let [result, fun] = collectable_protocol.into(into); - - const generatedValues = run_list_generators(generators.pop()(), generators); - - for (const value of generatedValues) { - if (expression.guard.apply(this, value)) { - result = fun(result, new Core.Tuple(Symbol.for('cont'), expression.fn.apply(this, value))); - } - } - - return fun(result, Symbol.for('done')); -} - -function run_list_generators(generator, generators) { - if (generators.length == 0) { - return generator.map(x => { - if (Array.isArray(x)) { - return x; - } - return [x]; - }); - } - const list = generators.pop(); - - const next_gen = []; - for (const j of list()) { - for (const i of generator) { - next_gen.push([j].concat(i)); - } - } - - return run_list_generators(next_gen, generators); -} - -function _try(do_fun, rescue_function, catch_fun, else_function, after_function) { - let result = null; - - try { - result = do_fun(); - } catch (e) { - let ex_result = null; - - if (rescue_function) { - try { - ex_result = rescue_function(e); - return ex_result; - } catch (ex) { - if (ex instanceof Core.Patterns.MatchError) { - throw ex; - } - } - } - - if (catch_fun) { - try { - ex_result = catch_fun(e); - return ex_result; - } catch (ex) { - if (ex instanceof Core.Patterns.MatchError) { - throw ex; - } - } - } - - throw e; - } finally { - if (after_function) { - after_function(); - } - } - - if (else_function) { - try { - return else_function(result); - } catch (ex) { - if (ex instanceof Core.Patterns.MatchError) { - throw new Error('No Match Found in Else'); - } - - throw ex; - } - } else { - return result; - } -} - -function _with(...args) { - let argsToPass = []; - let successFunction = null; - let elseFunction = null; - - if (typeof args[args.length - 2] === 'function') { - [successFunction, elseFunction] = args.splice(-2); - } else { - successFunction = args.pop(); - } - - for (let i = 0; i < args.length; i++) { - const [pattern, func] = args[i]; - - const result = func(...argsToPass); - - const patternResult = Core.Patterns.match_or_default(pattern, result); - - if (patternResult == null) { - if (elseFunction) { - return elseFunction.call(null, result); - } - return result; - } - - argsToPass = argsToPass.concat(patternResult); - } - - return successFunction(...argsToPass); -} - -function receive(clauses, after) { - console.warn('Receive not supported'); -} - -var SpecialForms = { - _case, - cond, - _for, - _try, - _with, - receive -}; - -// http://erlang.org/doc/man/lists.html -function reverse(list) { - return [...list].reverse(); -} - -function foreach(fun, list) { - list.forEach(x => fun(x)); - - return Symbol.for('ok'); -} - -function duplicate(n, elem) { - const list = []; - - while (list.length < n) { - list.push(elem); - } - - return list; -} - -function flatten(deepList, tail = []) { - const val = deepList.reduce((acc, value) => { - if (Array.isArray(value)) { - return acc.concat(flatten(value)); - } - - return acc.concat(value); - }, []); - - return val.concat(tail); -} - -function foldl(fun, acc0, list) { - return list.reduce((acc, value) => { - return fun(value, acc); - }, acc0); -} - -function foldr(fun, acc0, list) { - return foldl(fun, acc0, reverse(list)); -} - -function keyfind(key, n, tupleList) { - for (const tuple of tupleList) { - if (tuple.get(n - 1) === key) { - return tuple; - } - } - - return false; -} - -function keymember(key, n, tupleList) { - if (keyfind(key, n, tupleList) === false) { - return false; - } - - return true; -} - -function keyreplace(key, n, tupleList, newTuple) { - const newTupleList = [...tupleList]; - - for (let index = 0; index < newTupleList.length; index++) { - if (newTupleList[index].get(n - 1) === key) { - newTupleList[index] = newTuple; - return newTupleList; - } - } - - return newTupleList; -} - -function keysort(n, tupleList) { - const newTupleList = [...tupleList]; - - return newTupleList.sort((a, b) => { - if (a.get(n - 1) < b.get(n - 1)) { - return -1; - } else if (a.get(n - 1) > b.get(n - 1)) { - return 1; - } - - return 0; - }); -} - -function keystore(key, n, tupleList, newTuple) { - const newTupleList = [...tupleList]; - - for (let index = 0; index < newTupleList.length; index++) { - if (newTupleList[index].get(n - 1) === key) { - newTupleList[index] = newTuple; - return newTupleList; - } - } - - return newTupleList.concat(newTuple); -} - -function keydelete(key, n, tupleList) { - const newTupleList = []; - let deleted = false; - - for (let index = 0; index < tupleList.length; index++) { - if (deleted === false && tupleList[index].get(n - 1) === key) { - deleted = true; - } else { - newTupleList.push(tupleList[index]); - } - } - - return newTupleList; -} - -function keytake(key, n, tupleList) { - const result = keyfind(key, n, tupleList); - - if (result !== false) { - return new ErlangTypes.Tuple(result.get(n - 1), result, keydelete(key, n, tupleList)); - } - - return false; -} - -function mapfoldl(fun, acc0, list1) { - const listResult = []; - let accResult = acc0; - - for (const item of list1) { - const tuple = fun(item, accResult); - listResult.push(tuple.get(0)); - accResult = tuple.get(1); - } - - return new ErlangTypes.Tuple(listResult, accResult); -} - -function concat(things) { - return things.map(v => v.toString()).join(); -} - -function map(fun, list) { - return list.map(value => fun(value)); -} - -function filter(pred, list1) { - return list1.filter(x => pred(x)); -} - -function filtermap(fun, list1) { - const list2 = []; - - for (const item of list1) { - const value = fun(item); - - if (value === true) { - list2.push(item); - } else if (value instanceof ErlangTypes.Tuple && value.get(0) === true) { - list2.push(value.get(1)); - } - } - - return list2; -} - -function member(elem, list) { - for (const item of list) { - if (item === elem) { - return true; - } - } - - return false; -} - -function all(pred, list) { - for (const item of list) { - if (pred(item) === false) { - return false; - } - } - - return true; -} - -function any(pred, list) { - for (const item of list) { - if (pred(item) === true) { - return true; - } - } - - return false; -} - -function splitwith(pred, list) { - let switchToList2 = false; - const list1 = []; - const list2 = []; - - for (const item of list) { - if (switchToList2 === true) { - list2.push(item); - } else if (pred(item) === true) { - list1.push(item); - } else { - switchToList2 = true; - list2.push(item); - } - } - - return new ErlangTypes.Tuple(list1, list2); -} - -function sort(...args) { - if (args.length === 1) { - const list2 = [...args[0]]; - return list2.sort(); - } - - const fun = args[0]; - const list2 = [...args[1]]; - - return list2.sort((a, b) => { - const result = fun(a, b); - - if (result === true) { - return -1; - } - - return 1; - }); -} - -var lists = { - reverse, - foreach, - duplicate, - flatten, - foldl, - foldr, - keydelete, - keyfind, - keymember, - keyreplace, - keysort, - keystore, - keytake, - mapfoldl, - concat, - map, - filter, - filtermap, - member, - all, - any, - splitwith, - sort -}; - -// http://erlang.org/doc/man/erlang.html -function atom_to_binary(atom, encoding = Symbol.for('utf8')) { - if (encoding !== Symbol.for('utf8')) { - throw new Error(`unsupported encoding ${encoding}`); - } - - if (atom.__MODULE__) { - return Symbol.keyFor(atom.__MODULE__); - } - - return Symbol.keyFor(atom); -} - -function binary_to_atom(binary, encoding = Symbol.for('utf8')) { - if (encoding !== Symbol.for('utf8')) { - throw new Error(`unsupported encoding ${encoding}`); - } - - return Symbol.for(binary); -} - -function binary_to_existing_atom(binary, encoding = Symbol.for('utf8')) { - return binary_to_atom(binary, encoding); -} - -function list_concatenation(list1, list2) { - return list1.concat(list2); -} - -function list_subtraction(list1, list2) { - const list = [...list1]; - - for (const item of list2) { - const index = list.indexOf(item); - - if (index > -1) { - list.splice(index, 1); - } - } - - return list; -} - -function div(left, right) { - return left / right; -} - -function not(x) { - return !x; -} - -function rem(left, right) { - return left % right; -} - -function band(left, right) { - return left & right; -} - -function bor(left, right) { - return left | right; -} - -function bnot(x) { - return ~x; -} - -function bsl(left, right) { - return left << right; -} - -function bsr(left, right) { - return left >> right; -} - -function bxor(left, right) { - return left ^ right; -} - -function is_atom(value) { - return typeof value === 'symbol' || value instanceof Symbol || value.__MODULE__; -} - -function is_bitstring$1(value) { - return value instanceof ErlangTypes.BitString; -} - -function is_boolean$1(value) { - return typeof value === 'boolean' || value instanceof Boolean; -} - -function is_number$1(value) { - return typeof value === 'number' || value instanceof Number; -} - -function is_float(value) { - return is_number$1(value) && !Number.isInteger(value); -} - -function is_function$1(value) { - return typeof value === 'function' || value instanceof Function; -} - -function is_integer(value) { - return Number.isInteger(value); -} - -function is_list(value) { - return Array.isArray(value); -} - -function is_map$1(value) { - return value instanceof Map; -} - -function is_pid(value) { - return value instanceof ErlangTypes.PID; -} - -function is_port() { - return false; -} - -function is_reference(value) { - return value instanceof ErlangTypes.Reference; -} - -function is_tuple(value) { - return value instanceof ErlangTypes.Tuple; -} - -function is_binary(value) { - return typeof value === 'string' || value instanceof String; -} - -function element(n, tuple) { - return tuple.get(n - 1); -} - -function setelement(index, tuple1, value) { - const tupleData = [...tuple1.values]; - - tupleData[index - 1] = value; - - return new ErlangTypes.Tuple(...tupleData); -} - -function make_tuple(arity, initialValue) { - const list = []; - - for (let i = 0; i < arity; i++) { - list.push(initialValue); - } - - return new ErlangTypes.Tuple(...list); -} - -function insert_element(index, tuple, term) { - const list = [...tuple.values]; - list.splice(index - 1, 0, term); - - return new ErlangTypes.Tuple(...list); -} - -function append_element(tuple, term) { - const list = [...tuple.values]; - list.push(term); - - return new ErlangTypes.Tuple(...list); -} - -function delete_element(index, tuple) { - const list = [...tuple.values]; - list.splice(index - 1, 1); - - return new ErlangTypes.Tuple(...list); -} - -function tuple_to_list(tuple) { - const list = [...tuple.values]; - return list; -} - -function abs(number) { - return Math.abs(number); -} - -function apply(...args) { - if (args.length === 2) { - return args[0].apply(this, ...args[1]); - } - - return args[0][atom_to_binary(args[1])].apply(this, ...args[2]); -} - -function binary_part(binary, start, length) { - return binary.substring(start, start + length); -} - -function bit_size(bitstring) { - return bitstring.bit_size; -} - -function byte_size(bitstring) { - return bitstring.byte_size; -} - -function hd(list) { - return list[0]; -} - -function length(list) { - return list.length; -} - -function make_ref() { - return new ErlangTypes.Reference(); -} - -function map_size(map) { - return map.size; -} - -function max(first, second) { - return Math.max(first, second); -} - -function min(first, second) { - return Math.min(first, second); -} - -function round(number) { - return Math.round(number); -} - -function tl(list) { - return list.slice(1); -} - -function trunc(number) { - return Math.trunc(number); -} - -function tuple_size(tuple) { - return tuple.length; -} - -function binary_to_float(str) { - return parseFloat(str); -} - -function binary_to_integer(str, base = 10) { - return parseInt(str, base); -} - -function process_info(pid, item) { - if (item) { - if (item === Symbol.for('current_stacktrace')) { - return new ErlangTypes.Tuple(item, []); - } - - return new ErlangTypes.Tuple(item, null); - } - - return []; -} - -function iolist_to_binary(ioListOrBinary) { - if (ioListOrBinary === null) { - return ''; - } - - if (is_binary(ioListOrBinary)) { - return ioListOrBinary; - } - - if (is_bitstring$1(ioListOrBinary)) { - return String.fromCodePoint(...ioListOrBinary.value); - } - - const iolistFlattened = lists.flatten(ioListOrBinary); - - const value = iolistFlattened.reduce((acc, current) => { - if (current === null) { - return acc; - } else if (is_integer(current)) { - return acc + String.fromCodePoint(current); - } else if (is_bitstring$1(current)) { - return acc + String.fromCodePoint(...current.value); - } - - return acc + iolist_to_binary(current); - }, ''); - - return value; -} - -function io_size(ioListOrBinary) { - return iolist_to_binary(ioListOrBinary).length; -} - -function integer_to_binary(integer, base = 10) { - return integer.toString(base); -} - -var erlang = { - atom_to_binary, - binary_to_atom, - binary_to_existing_atom, - list_concatenation, - list_subtraction, - div, - not, - rem, - band, - bor, - bsl, - bsr, - bxor, - bnot, - is_bitstring: is_bitstring$1, - is_boolean: is_boolean$1, - is_float, - is_function: is_function$1, - is_integer, - is_list, - is_map: is_map$1, - is_number: is_number$1, - is_pid, - is_port, - is_reference, - is_tuple, - is_atom, - is_binary, - element, - setelement, - make_tuple, - insert_element, - append_element, - delete_element, - tuple_to_list, - abs, - apply, - binary_part, - bit_size, - byte_size, - hd, - length, - make_ref, - map_size, - max, - min, - round, - tl, - trunc, - tuple_size, - binary_to_float, - binary_to_integer, - process_info, - iolist_to_binary, - io_size, - integer_to_binary -}; - -// http://erlang.org/doc/man/maps.html -const OK = Symbol.for('ok'); -const ERROR = Symbol.for('error'); -const BADMAP = Symbol.for('badmap'); -const BADKEY = Symbol.for('badkey'); - -function find(key, map) { - if (erlang.is_map(map) === false) { - return new ErlangTypes.Tuple(BADMAP, map); - } - - const value = map.get(key); - - if (typeof value !== 'undefined') { - return new ErlangTypes.Tuple(OK, value); - } - - return ERROR; -} - -function fold(fun, init, map) { - let acc = init; - - for (const [key, value] of map.entries()) { - acc = fun(key, value, acc); - } - - return acc; -} - -function remove(key, map1) { - if (erlang.is_map(map1) === false) { - return new ErlangTypes.Tuple(BADMAP, map1); - } - - const map2 = new Map(map1); - - map2.delete(key); - - return map2; -} - -function to_list(map) { - if (erlang.is_map(map) === false) { - return new ErlangTypes.Tuple(BADMAP, map); - } - - const list = []; - - for (const [key, value] of map.entries()) { - list.push(new ErlangTypes.Tuple(key, value)); - } - - return list; -} - -function from_list(list) { - return list.reduce((acc, item) => { - const [key, value] = item; - acc.set(key, value); - - return acc; - }, new Map()); -} - -function keys(map) { - if (erlang.is_map(map) === false) { - return new ErlangTypes.Tuple(BADMAP, map); - } - - return Array.from(map.keys()); -} - -function values$1(map) { - if (erlang.is_map(map) === false) { - return new ErlangTypes.Tuple(BADMAP, map); - } - - return Array.from(map.values()); -} - -function is_key(key, map) { - return map.has(key); -} - -function put(key, value, map1) { - if (erlang.is_map(map1) === false) { - return new ErlangTypes.Tuple(BADMAP, map1); - } - - const map2 = new Map(map1); - map2.set(key, value); - - return map2; -} - -function merge(map1, map2) { - if (erlang.is_map(map1) === false) { - return new ErlangTypes.Tuple(BADMAP, map1); - } - - if (erlang.is_map(map2) === false) { - return new ErlangTypes.Tuple(BADMAP, map2); - } - - return new Map([...map1, ...map2]); -} - -function update(key, value, map1) { - if (erlang.is_map(map1) === false) { - return new ErlangTypes.Tuple(BADMAP, map1); - } - - if (is_key(key, map1) === false) { - return new ErlangTypes.Tuple(BADKEY, key); - } - - return new Map([...map1, [key, value]]); -} - -function get(...args) { - const key = args[0]; - const map = args[1]; - - if (erlang.is_map(map) === false) { - return new ErlangTypes.Tuple(BADMAP, map); - } - - if (is_key(key)) { - return map.get(key); - } - - if (args.length === 3) { - return args[2]; - } - - return new ErlangTypes.Tuple(BADKEY, key); -} - -function take(key, map1) { - if (erlang.is_map(map1) === false) { - return new ErlangTypes.Tuple(BADMAP, map1); - } - - if (!is_key(key)) { - return ERROR; - } - - const value = map1.get(key); - const map2 = new Map(map1); - map2.delete(key); - - return new ErlangTypes.Tuple(value, map2); -} - -var maps = { - find, - fold, - remove, - to_list, - from_list, - keys, - values: values$1, - is_key, - put, - merge, - update, - get, - take -}; - -function warn(message) { - const messageString = message.join(''); - console.warn(`warning: ${messageString}`); - - return Symbol.for('ok'); -} - -var elixir_errors = { - warn -}; - -function put_chars(ioDevice, charData) { - const dataToWrite = erlang.iolist_to_binary(charData); - - if (ioDevice === Symbol.for('stderr')) { - console.error(dataToWrite); - } else { - console.log(dataToWrite); - } - - return Symbol.for('ok'); -} - -var io = { - put_chars -}; - -function copy(subject, n = 1) { - return subject.repeat(n); -} - -var binary = { - copy -}; - -function get_key(key) { - let real_key = key; - - if (__elixirscript_names__.has(key)) { - real_key = __elixirscript_names__.get(key); - } - - if (__elixirscript_store__.has(real_key)) { - return real_key; - } - - throw new Error(`Key ${real_key} not found`); -} - -function create(value, name = null) { - const key = new Core.PID(); - - if (name !== null) { - __elixirscript_names__.set(name, key); - } - - return __elixirscript_store__.set(key, value); -} - -function update$1(key, value) { - const real_key = get_key(key); - return __elixirscript_store__.set(real_key, value); -} - -function read(key) { - const real_key = get_key(key); - return __elixirscript_store__.get(real_key); -} - -function remove$1(key) { - const real_key = get_key(key); - return __elixirscript_store__.delete(real_key); -} - -var Store = { - create, - update: update$1, - read, - remove: remove$1 -}; - -class Integer {} -class Float {} - -function get_global() { - if (typeof self !== 'undefined') { - return self; - } else if (typeof window !== 'undefined') { - return window; - } else if (typeof global !== 'undefined') { - return global; - } - - console.warn('No global state found'); - return null; -} - -const globalState = get_global(); - -globalState.__elixirscript_store__ = new Map(); -globalState.__elixirscript_names__ = new Map(); - -var Core = { - Tuple: ErlangTypes.Tuple, - PID: ErlangTypes.PID, - BitString: ErlangTypes.BitString, - Patterns, - Integer, - Float, - Functions, - SpecialForms, - Store, - global: globalState, - erlang, - maps, - lists, - elixir_errors, - io, - binary -}; - -var elixir = { - Core -}; - -return elixir; - -}()); +var ElixirScript=function(){'use strict';/* @flow */function namedVariableResult(a,b){return new NamedVariableResult(a,b)}/* @flow */function is_number(a){return'number'==typeof a}function is_string(a){return'string'==typeof a}function is_boolean(a){return'boolean'==typeof a}function is_symbol(a){return'symbol'==typeof a}function is_object(a){return'object'==typeof a}function is_variable(a){return a instanceof Variable}function is_null(a){return null===a}function is_array(a){return Array.isArray(a)}function is_function(a){return'[object Function]'==Object.prototype.toString.call(a)}function is_map(a){return a instanceof Map}function resolveNull(){return function(a){return is_null(a)}}function resolveWildcard(){return function(){return!0}}function resolveObject(a){let b={};const c=Object.keys(a).concat(Object.getOwnPropertySymbols(a));for(let d of c)b[d]=buildMatch(a[d]);return function(d,e){if(!is_object(d)||a.length>d.length)return!1;for(let a of c)if(!(a in d)||!b[a](d[a],e))return!1;return!0}}function getSize(a,b){return a*b/8}function arraysEqual(c,a){if(c===a)return!0;if(null==c||null==a)return!1;if(c.length!=a.length)return!1;for(var b=0;be.integer(a));return new e(...b)}function resolveNoMatch(){return function(){return!1}}function buildMatch(a){if(null===a)return resolveNull(a);if('undefined'==typeof a)return resolveWildcard(a);const b=a.constructor.prototype,c=f.get(b);return c?c(a):'object'==typeof a?resolveObject(a):resolveNoMatch()}function defmatchgen(...a){const b=getArityMap(a);return function*(...a){let[c,d]=findMatchingFunction(a,b);return yield*c.apply(this,d)}}function findMatchingFunction(a,b){if(b.has(a.length)){const c=b.get(a.length);let d=null,e=null;for(let b of c){let c=[];a=fillInOptionalValues(a,b.arity,b.optionals);const f=b.pattern(a,c),[g,h]=checkNamedVariables(c);if(f&&h&&b.guard.apply(this,g)){d=b.fn,e=g;break}}if(!d)throw console.error('No match for:',a),new MatchError(a);return[d,e]}throw console.error('Arity of',a.length,'not found. No match for:',a),new MatchError(a)}function getArityMap(a){let b=new Map;for(const c of a){const a=getArityRange(c);for(const d of a){let a=[];b.has(d)&&(a=b.get(d)),a.push(c),b.set(d,a)}}return b}function getArityRange(a){const b=a.arity-a.optionals.length,c=a.arity;let d=[b];for(;d[d.length-1]!=c;)d.push(d[d.length-1]+1);return d}function getOptionalValues(a){let b=[];for(let c=0;c!0,d=null){let e=[],f=buildMatch(a);const g=f(b,e),[h,i]=checkNamedVariables(e);return g&&i&&c.apply(this,h)?h:d}function run_generators(a,b){if(0==b.length)return a.map((a)=>{return Array.isArray(a)?a:[a]});const c=b.pop();let d=[];for(let e of c())for(let b of a)d.push([e].concat(b));return run_generators(d,b)}function iterator_to_reducer(a,b,c){const d=a[Symbol.iterator]();let e=d.next(),f=b;for(;!1===e.done;){if(f=c(e.value,f.get(1)),f.get(0)===Symbol.for('halt'))return new o.Tuple(Symbol.for('halted'),f.get(1));if(f.get(0)===Symbol.for('suspend'))return new o.Tuple(Symbol.for('suspended'),f.get(1),(a)=>{return iterator_to_reducer(d,a,c)});e=d.next()}return new o.Tuple(Symbol.for('done'),f.get(1))}function map_to_object(a){const b={};for(const[c,d]of a.entries())b[c]=d instanceof Map?map_to_object(d):d;return b}function run_list_generators(a,b){if(0==b.length)return a.map((a)=>{return Array.isArray(a)?a:[a]});const c=b.pop(),d=[];for(const e of c())for(const b of a)d.push([e].concat(b));return run_list_generators(d,b)}// http://erlang.org/doc/man/lists.html +function reverse(a){return[...a]}function flatten(a,b=[]){const c=a.reduce((a,b)=>{return Array.isArray(b)?a.concat(flatten(b)):a.concat(b)},[]);return c.concat(b)}function foldl(a,b,c){return c.reduce((b,c)=>{return a(c,b)},b)}function keyfind(a,b,c){for(const d of c)if(d.get(b-1)===a)return d;return!1}function keydelete(a,b,c){const d=[];let e=!1;for(let f=0;f{if(null===c)return a;return is_integer(c)?a+b(c):is_bitstring$1(c)?a+b(...c.value):a+iolist_to_binary(c)},'');return d}function is_key(a,b){return b.has(a)}function get_key(a){let b=a;if(__elixirscript_names__.has(a)&&(b=__elixirscript_names__.get(a)),__elixirscript_store__.has(b))return b;throw new Error(`Key ${b} not found`)}var a=Number.isInteger;class Variable{constructor(a=null,b=Symbol.for('tailored.no_value')){this.name=a,this.default_value=b}}class Wildcard{constructor(){}}class StartsWith{constructor(a){this.prefix=a}}class Capture{constructor(a){this.value=a}}class HeadTail{constructor(a,b){this.head=a,this.tail=b}}class Type{constructor(a,b={}){this.type=a,this.objPattern=b}}class Bound{constructor(a){this.value=a}}class BitStringMatch{constructor(...a){this.values=a}length(){return values.length}bit_size(){return 8*this.byte_size()}byte_size(){let a=0;for(let b of this.values)a+=b.unit*b.size/8;return a}getValue(a){return this.values(a)}getSizeOfValue(a){let b=this.getValue(a);return b.unit*b.size}getTypeOfValue(a){return this.getValue(a).type}}class NamedVariableResult{constructor(a,b){this.name=a,this.value=b}}class Tuple{constructor(...a){this.values=Object.freeze(a),this.length=this.values.length}get(a){return this.values[a]}count(){return this.values.length}[Symbol.iterator](){return this.values[Symbol.iterator]()}toString(){let a,b='';for(a=0;aBitString$1.integer(a));return new BitString$1(...d)}[Symbol.iterator](){return this.value[Symbol.iterator]()}toString(){var a,b='';for(a=0;a>'}process(a){let b=[];var c;for(c=0;cb?c.push(b):2048>b?c.push(192|b>>6,128|63&b):55296>b||57344<=b?c.push(224|b>>12,128|63&b>>6,128|63&b):(d++,b=65536+((1023&b)<<10|1023&a.charCodeAt(d)),c.push(240|b>>18,128|63&b>>12,128|63&b>>6,128|63&b));return c}static toUTF16Array(a){for(var b,c=[],d=0;d=b?(c.push(0),c.push(b)):(c.push(255&b>>8),c.push(255&b));return c}static toUTF32Array(a){for(var b,c=[],d=0;d=b?(c.push(0),c.push(0),c.push(0),c.push(b)):(c.push(0),c.push(0),c.push(255&b>>8),c.push(255&b));return c}//http://stackoverflow.com/questions/2003493/javascript-float-from-to-bits +static float32ToBytes(a){var b=[],c=new ArrayBuffer(4);new Float32Array(c)[0]=a;let d=new Uint32Array(c)[0];return b.push(255&d>>24),b.push(255&d>>16),b.push(255&d>>8),b.push(255&d),b}static float64ToBytes(a){var b=[],c=new ArrayBuffer(8);new Float64Array(c)[0]=a;var d=new Uint32Array(c)[0],e=new Uint32Array(c)[1];return b.push(255&e>>24),b.push(255&e>>16),b.push(255&e>>8),b.push(255&e),b.push(255&d>>24),b.push(255&d>>16),b.push(255&d>>8),b.push(255&d),b}}var d={Tuple,PID:class PID{constructor(){++b,this.id=b}toString(){return'PID#<0.'+this.id+'.0>'}},Reference:class Reference{constructor(){++c,this.id=c,this.ref=Symbol()}toString(){return'Ref#<0.0.0.'+this.id+'>'}},BitString:BitString$1};/* @flow */const e=d.BitString,f=new Map;f.set(Variable.prototype,function resolveVariable(a){return function(b,c){return null===a.name?c.push(b):!a.name.startsWith('_')&&c.push(namedVariableResult(a.name,b)),!0}}),f.set(Wildcard.prototype,resolveWildcard),f.set(HeadTail.prototype,function resolveHeadTail(a){const b=buildMatch(a.head),c=buildMatch(a.tail);return function(a,d){if(!is_array(a)||0===a.length)return!1;const e=a[0],f=a.slice(1);return b(e,d)&&c(f,d)}}),f.set(StartsWith.prototype,function resolveStartsWith(a){const b=a.prefix;return function(a,c){return is_string(a)&&a.startsWith(b)&&(c.push(a.substring(b.length)),!0)}}),f.set(Capture.prototype,function resolveCapture(a){const b=buildMatch(a.value);return function(a,c){return!!b(a,c)&&(c.push(a),!0)}}),f.set(Bound.prototype,function resolveBound(a){return function(b){return typeof b==typeof a.value&&b===a.value}}),f.set(Type.prototype,function resolveType(a){return function(b,c){if(b instanceof a.type){const d=buildMatch(a.objPattern);return d(b,c)}return!1}}),f.set(BitStringMatch.prototype,function resolveBitString(a){let b=[];for(let c of a.values)if(is_variable(c.value)){let a=getSize(c.unit,c.size);fillArray(b,a)}else b=b.concat(new e(c).value);let c=a.values;return function(a,d){var f=String.fromCharCode;let g=null;if(!is_string(a)&&!(a instanceof e))return!1;g=is_string(a)?new e(e.binary(a)):a;let h=0;for(let e,j=0;jd.size)return!1;for(let a of c)if(!d.has(a)||!b.get(a)(d.get(a),e))return!1;return!0}}),f.set(Array.prototype,function resolveArray(a){const b=a.map((a)=>buildMatch(a));return function(c,d){return is_array(c)&&c.length==a.length&&c.every(function(a,e){return b[e](c[e],d)})}}),f.set(String.prototype,function resolveString(a){return function(b){return is_string(b)&&b===a}}),f.set(Boolean.prototype,function resolveBoolean(a){return function(b){return is_boolean(b)&&b===a}}),f.set(Function.prototype,function resolveFunction(a){return function(b){return is_function(b)&&b===a}}),f.set(Object.prototype,resolveObject);class MatchError extends Error{constructor(a){if(super(),'symbol'==typeof a)this.message='No match for: '+a.toString();else if(Array.isArray(a)){let b=a.map((a)=>{return null===a?'null':'undefined'==typeof a?'undefined':a.toString()});this.message='No match for: '+b}else this.message='No match for: '+a;this.stack=new Error().stack,this.name=this.constructor.name}}class Clause{constructor(a,b,c=()=>!0){this.pattern=buildMatch(a),this.arity=a.length,this.optionals=getOptionalValues(a),this.fn=b,this.guard=c}}const g=Symbol();// https://github.com/airportyh/protomorphism +class Protocol{constructor(b){function createFun(b){return function(...c){const d=c[0];let e=null;if(null===d&&this.hasImplementation(Symbol('null'))?e=this.registry.get(Symbol)[b]:a(d)&&this.hasImplementation(o.Integer)?e=this.registry.get(o.Integer)[b]:'number'==typeof d&&!a(d)&&this.hasImplementation(o.Float)?e=this.registry.get(o.Float)[b]:'string'==typeof d&&this.hasImplementation(o.BitString)?e=this.registry.get(o.BitString)[b]:d&&d instanceof Map&&d.has(Symbol.for('__struct__'))&&this.hasImplementation(d)?e=this.registry.get(d.get(Symbol.for('__struct__')).__MODULE__)[b]:null!==d&&this.hasImplementation(d)?e=this.registry.get(d.constructor)[b]:this.fallback&&(e=this.fallback[b]),null!=e){const a=e.apply(this,c);return a}throw new Error(`No implementation found for ${d}`)}}for(const a in this.registry=new Map,this.fallback=null,b)this[a]=createFun(a).bind(this)}implementation(a,b){null===a?this.fallback=b:this.registry.set(a,b)}hasImplementation(a){if(a===o.Integer||a===o.Float||a===o.BitString)return this.registry.has(a);return a&&a instanceof Map&&a.has(Symbol.for('__struct__'))?this.registry.has(a.get(Symbol.for('__struct__')).__MODULE__):this.registry.has(a.constructor)}}class Recurse{constructor(a){this.func=a}}var h={reverse,foreach:function foreach(a,b){return b.forEach((b)=>a(b)),Symbol.for('ok')},duplicate:function duplicate(a,b){const c=[];for(;c.length{if(d.get(c-1)a.get(c-1)?1:0})},keystore:function keystore(a,b,c,d){const e=[...c];for(let f=0;fa.toString()).join()},map:function map(a,b){return b.map((b)=>a(b))},filter:function filter(a,b){return b.filter((b)=>a(b))},filtermap:function filtermap(a,b){const c=[];for(const e of b){const b=a(e);!0===b?c.push(e):b instanceof d.Tuple&&!0===b.get(0)&&c.push(b.get(1))}return c},member:function member(a,b){for(const c of b)if(c===a)return!0;return!1},all:function all(a,b){for(const c of b)if(!1===a(c))return!1;return!0},any:function any(a,b){for(const c of b)if(!0===a(c))return!0;return!1},splitwith:function splitwith(a,b){let c=!1;const e=[],f=[];for(const d of b)!0==c?f.push(d):!0===a(d)?e.push(d):(c=!0,f.push(d));return new d.Tuple(e,f)},sort:function sort(...a){if(1===a.length){const b=[...a[0]];return b.sort()}const c=a[0],b=[...a[1]];return b.sort((d,a)=>{const b=c(d,a);return!0===b?-1:1})}},i={atom_to_binary,binary_to_atom,binary_to_existing_atom:function binary_to_existing_atom(a,b=Symbol.for('utf8')){return binary_to_atom(a,b)},list_concatenation:function list_concatenation(a,b){return a.concat(b)},list_subtraction:function list_subtraction(a,b){const c=[...a];for(const d of b){const a=c.indexOf(d);-1>b},bxor:function bxor(a,b){return a^b},bnot:function bnot(a){return~a},is_bitstring:is_bitstring$1,is_boolean:function is_boolean$1(a){return'boolean'==typeof a||a instanceof Boolean},is_float:function is_float(b){return is_number$1(b)&&!a(b)},is_function:function is_function$1(a){return'function'==typeof a||a instanceof Function},is_integer,is_list:function is_list(a){return Array.isArray(a)},is_map:function is_map$1(a){return a instanceof Map},is_number:is_number$1,is_pid:function is_pid(a){return a instanceof d.PID},is_port:function is_port(){return!1},is_reference:function is_reference(a){return a instanceof d.Reference},is_tuple:function is_tuple(a){return a instanceof d.Tuple},is_atom:function is_atom(a){return'symbol'==typeof a||a instanceof Symbol||a.__MODULE__},is_binary,element:function element(a,b){return b.get(a-1)},setelement:function setelement(a,b,c){const e=[...b.values];return e[a-1]=c,new d.Tuple(...e)},make_tuple:function make_tuple(a,b){const c=[];for(let d=0;d!0){let d=[],e=buildMatch(a);const f=e(b,d),[g,h]=checkNamedVariables(d);if(f&&h&&c.apply(this,g))return g;throw console.error('No match for:',b),new MatchError(b)},MatchError,variable:function variable(a=null,b=Symbol.for('tailored.no_value')){return new Variable(a,b)},wildcard:function wildcard(){return new Wildcard},startsWith:function startsWith(a){return new StartsWith(a)},capture:function capture(a){return new Capture(a)},headTail:function headTail(a,b){return new HeadTail(a,b)},type:function a(a,b={}){return new Type(a,b)},bound:function bound(a){return new Bound(a)},Clause,clause:function clause(a,b,c=()=>!0){return new Clause(a,b,c)},bitStringMatch:function bitStringMatch(...a){return new BitStringMatch(...a)},match_or_default,defmatchgen,list_comprehension:function list_comprehension(a,b){const c=run_generators(b.pop()(),b);let d=[];for(let e of c)a.guard.apply(this,e)&&d.push(a.fn.apply(this,e));return d},list_generator:function list_generator(a,b){return function(){let c=[];for(let d of b){const b=match_or_default(a,d,()=>!0,g);if(b!=g){const[a]=b;c.push(a)}}return c}},bitstring_generator:function bitstring_generator(a,b){return function(){let c=[],d=b.slice(0,a.byte_size()),e=1;for(;d.byte_size==a.byte_size();){const f=match_or_default(a,d,()=>!0,g);if(f!=g){c.push(f)}d=b.slice(a.byte_size()*e,a.byte_size()*(e+1)),e++}return c}},bitstring_comprehension:function bitstring_comprehension(a,b){const c=run_generators(b.pop()(),b);let e=[];for(let d of c)a.guard.apply(this,d)&&e.push(a.fn.apply(this,d));return e=e.map((a)=>d.BitString.integer(a)),new d.BitString(...e)},defmatchGen:function defmatchGen(...a){return defmatchgen(...a)},defmatchAsync:function defmatchAsync(...a){const b=getArityMap(a);return async function(...a){if(b.has(a.length)){const c=b.get(a.length);let d=null,e=null;for(let b of c){let c=[];a=fillInOptionalValues(a,b.arity,b.optionals);const f=b.pattern(a,c),[g,h]=checkNamedVariables(c);if(f&&h&&(await b.guard.apply(this,c))){d=b.fn,e=c;break}}if(!d)throw console.error('No match for:',a),new MatchError(a);return d.apply(this,e)}throw console.error('Arity of',a.length,'not found. No match for:',a),new MatchError(a)}}},Integer:class Integer{},Float:class Float{},Functions:{call_property:function call_property(a,b){if(!b)return a instanceof Function||'function'==typeof a?a():a;if(a instanceof Map){let c=null;if(a.has(b)?c=b:a.has(Symbol.for(b))&&(c=Symbol.for(b)),null===c)throw new Error(`Property ${b} not found in ${a}`);return a.get(c)instanceof Function||'function'==typeof a.get(c)?a.get(c)():a.get(c)}let c=null;if('number'==typeof a||'symbol'==typeof a||'boolean'==typeof a||'string'==typeof a?void 0===a[b]?void 0!==a[Symbol.for(b)]&&(c=Symbol.for(b)):c=b:b in a?c=b:Symbol.for(b)in a&&(c=Symbol.for(b)),null===c)throw new Error(`Property ${b} not found in ${a}`);return a[c]instanceof Function||'function'==typeof a[c]?a[c]():a[c]},defprotocol:function defprotocol(a){return new Protocol(a)},defimpl:function defimpl(a,b,c){a.implementation(b,c)},build_namespace:function build_namespace(a,b){let c=b.split('.');const d=a;let e=a;'Elixir'===c[0]&&(c=c.slice(1));for(const d of c)'undefined'==typeof e[d]&&(e[d]={}),e=e[d];return d.__table__=a.__table__||{},d.__table__[Symbol.for(b)]=e,e},iterator_to_reducer,map_to_object,trampoline:function trampoline$1(a){let b=a;for(;b&&b instanceof Recurse;)b=b.func();return b},Recurse},SpecialForms:{_case:function _case(a,b){return o.Patterns.defmatch(...b)(a)},cond:function cond(...a){for(const b of a)if(b[0])return b[1]();throw new Error},_for:function _for(a,b,c,d=[]){let[e,f]=c.into(d);const g=run_list_generators(b.pop()(),b);for(const h of g)a.guard.apply(this,h)&&(e=f(e,new o.Tuple(Symbol.for('cont'),a.fn.apply(this,h))));return f(e,Symbol.for('done'))},_try:function _try(a,b,c,d,e){let f=null;try{f=a()}catch(a){let d=null;if(b)try{return d=b(a),d}catch(a){if(a instanceof o.Patterns.MatchError)throw a}if(c)try{return d=c(a),d}catch(a){if(a instanceof o.Patterns.MatchError)throw a}throw a}finally{e&&e()}if(d)try{return d(f)}catch(a){if(a instanceof o.Patterns.MatchError)throw new Error('No Match Found in Else');throw a}else return f},_with:function _with(...a){let b=[],c=null,d=null;'function'==typeof a[a.length-2]?[c,d]=a.splice(-2):c=a.pop();for(let c=0;c{const[c,d]=b;return a.set(c,d),a},new Map)},keys:function keys(a){return!1===i.is_map(a)?new d.Tuple(l,a):Array.from(a.keys())},values:function values$1(a){return!1===i.is_map(a)?new d.Tuple(l,a):Array.from(a.values())},is_key,put:function put(a,b,c){if(!1===i.is_map(c))return new d.Tuple(l,c);const e=new Map(c);return e.set(a,b),e},merge:function merge(a,b){return!1===i.is_map(a)?new d.Tuple(l,a):!1===i.is_map(b)?new d.Tuple(l,b):new Map([...a,...b])},update:function update(a,b,c){return!1===i.is_map(c)?new d.Tuple(l,c):!1===is_key(a,c)?new d.Tuple(m,a):new Map([...c,[a,b]])},get:function get(...a){const b=a[0],c=a[1];return!1===i.is_map(c)?new d.Tuple(l,c):is_key(b)?c.get(b):3===a.length?a[2]:new d.Tuple(m,b)},take:function take(a,b){if(!1===i.is_map(b))return new d.Tuple(l,b);if(!is_key(a))return k;const c=b.get(a),e=new Map(b);return e.delete(a),new d.Tuple(c,e)}},lists:h,elixir_errors:{warn:function warn(a){const b=a.join('');return console.warn(`warning: ${b}`),Symbol.for('ok')}},io:{put_chars:function put_chars(a,b){const c=i.iolist_to_binary(b);return a===Symbol.for('stderr')?console.error(c):console.log(c),Symbol.for('ok')}},binary:{copy:function copy(a,b=1){return a.repeat(b)}}};return{Core:o}}(); diff --git a/src/javascript/lib/core/erlang_compat/erlang.js b/src/javascript/lib/core/erlang_compat/erlang.js index 683ba0f6..78dcef94 100644 --- a/src/javascript/lib/core/erlang_compat/erlang.js +++ b/src/javascript/lib/core/erlang_compat/erlang.js @@ -283,6 +283,10 @@ function iolist_to_binary(ioListOrBinary) { return String.fromCodePoint(...ioListOrBinary.value); } + if (is_number(ioListOrBinary)) { + return String.fromCodePoint(ioListOrBinary); + } + const iolistFlattened = lists.flatten(ioListOrBinary); const value = iolistFlattened.reduce((acc, current) => { diff --git a/src/javascript/lib/core/functions.js b/src/javascript/lib/core/functions.js index 4fdabcac..d61dc21a 100644 --- a/src/javascript/lib/core/functions.js +++ b/src/javascript/lib/core/functions.js @@ -127,11 +127,29 @@ function map_to_object(map) { return object; } +class Recurse { + constructor(func) { + this.func = func; + } +} + +function trampoline(f) { + let currentValue = f; + + while (currentValue && currentValue instanceof Recurse) { + currentValue = currentValue.func(); + } + + return currentValue; +} + export default { call_property, defprotocol, defimpl, build_namespace, iterator_to_reducer, - map_to_object + map_to_object, + trampoline, + Recurse }; diff --git a/test/compiler_test.exs b/test/compiler_test.exs index f41aa7bf..36e510e7 100644 --- a/test/compiler_test.exs +++ b/test/compiler_test.exs @@ -35,7 +35,7 @@ defmodule ElixirScript.Compiler.Test do test "Output file with default name" do path = System.tmp_dir() - result = ElixirScript.Compiler.compile(Atom, [output: path]) + ElixirScript.Compiler.compile(Atom, [output: path]) assert File.exists?(Path.join([path, "Elixir.App.js"])) end @@ -43,7 +43,7 @@ defmodule ElixirScript.Compiler.Test do path = System.tmp_dir() path = Path.join([path, "myfile.js"]) - result = ElixirScript.Compiler.compile(Atom, [output: path]) + ElixirScript.Compiler.compile(Atom, [output: path]) assert File.exists?(path) end -end \ No newline at end of file +end diff --git a/test/passes/translate/form_test.exs b/test/passes/translate/form_test.exs index ea154950..f2cc2cce 100644 --- a/test/passes/translate/form_test.exs +++ b/test/passes/translate/form_test.exs @@ -120,10 +120,11 @@ defmodule ElixirScript.Translate.Forms.Test do test "function returning an array" do ast = {:fn, [], [{:foo, [], [], [1, 2, 3]}]} - state = %{} + state = %{function: {:something, nil}} {js_ast, _} = Form.compile(ast, state) - return_statement = Enum.at(Enum.at(js_ast.body.body, 1).consequent.body, 1) + + return_statement = Enum.at(Enum.at(hd(js_ast.body.body).body.body, 1).consequent.body, 1) assert return_statement.argument == J.array_expression([ J.literal(1), From 0edd518ed0f77b3288d09afbebf606ed3d7680cf Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Sat, 29 Jul 2017 15:24:52 -0500 Subject: [PATCH 197/418] Add todo-elixirscript to README.md --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index 40bb0e11..b3b413d5 100644 --- a/README.md +++ b/README.md @@ -13,6 +13,11 @@ Usage Please check the [Getting Started Guide](GettingStarted.md) for usage +Examples +========== + +[ElixirScript Todo Example](https://github.com/elixirscript/todo-elixirscript) + Development =========== From 4da3f46d3a600b57043082cc3cb2c71d24888ce4 Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Sat, 29 Jul 2017 18:38:09 -0500 Subject: [PATCH 198/418] Update String module debug_info code. Get debug_info from String module, but then replace functions found in ElixirScript.String. This is so we don't have to reimplement the entire String module. --- .tool-versions | 2 +- lib/elixir_script/beam.ex | 44 +++++++++++++++++-- .../passes/translate/forms/remote.ex | 3 +- src/javascript/lib/core.js | 4 +- .../lib/core/erlang_compat/unicode.js | 18 ++++++++ test/support/main.ex | 2 + 6 files changed, 66 insertions(+), 7 deletions(-) create mode 100644 src/javascript/lib/core/erlang_compat/unicode.js diff --git a/.tool-versions b/.tool-versions index 8dbeeb38..a6c3da3e 100644 --- a/.tool-versions +++ b/.tool-versions @@ -1,3 +1,3 @@ erlang 20.0 -elixir ref-v1.5.0-rc.2 +elixir 1.5.0-otp-20 nodejs 8.2.0 diff --git a/lib/elixir_script/beam.ex b/lib/elixir_script/beam.ex index e850d837..51c15910 100644 --- a/lib/elixir_script/beam.ex +++ b/lib/elixir_script/beam.ex @@ -10,9 +10,24 @@ defmodule ElixirScript.Beam do @spec debug_info(atom) :: {:ok | :error, map | binary} def debug_info(module) - #Replace some modules with ElixirScript versions - def debug_info(module) when module in [String, Agent] do - case debug_info(Module.concat(ElixirScript, module)) do + # We get debug info from String and then replace + # functions in it with equivalents in ElixirScript.String. + # This is so that we don't include the unicode database + # in our output + def debug_info(String) do + {:ok, info} = do_debug_info(String) + {:ok, ex_string_info} = do_debug_info(ElixirScript.String) + + definitions = replace_definitions(info.definitions, ex_string_info.definitions) + + info = %{info | definitions: definitions} + + {:ok, info} + end + + # Replace some modules with ElixirScript versions + def debug_info(module) when module in [Agent] do + case do_debug_info(Module.concat(ElixirScript, module)) do {:ok, info} -> {:ok, Map.put(info, :module, module)} e -> @@ -21,6 +36,10 @@ defmodule ElixirScript.Beam do end def debug_info(module) when is_atom(module) do + do_debug_info(module) + end + + defp do_debug_info(module) when is_atom(module) do #TODO: Get modified date from _beam_path to check for cached version? with {_, beam, _beam_path} <- :code.get_object_code(module), {:ok, {^module, [debug_info: {:debug_info_v1, backend, data}]}} <- :beam_lib.chunks(beam, [:debug_info]), @@ -59,4 +78,21 @@ defmodule ElixirScript.Beam do {:ok, module, implementations} end -end \ No newline at end of file + defp replace_definitions(original_definitions, replacement_definitions) do + Enum.map(original_definitions, fn + {{function, arity}, type, _, _} = ast -> + ex_ast = Enum.find(replacement_definitions, fn + {{ex_function, ex_arity}, ex_type, _, _} -> + ex_function == function and ex_arity == arity and ex_type == type + end) + + case ex_ast do + nil -> + ast + _ -> + ex_ast + end + end) + end + +end diff --git a/lib/elixir_script/passes/translate/forms/remote.ex b/lib/elixir_script/passes/translate/forms/remote.ex index 59f23bc4..70651e11 100644 --- a/lib/elixir_script/passes/translate/forms/remote.ex +++ b/lib/elixir_script/passes/translate/forms/remote.ex @@ -17,7 +17,8 @@ defmodule ElixirScript.Translate.Forms.Remote do :elixir_utils, :file, :io, - :binary + :binary, + :unicode ] @doc """ diff --git a/src/javascript/lib/core.js b/src/javascript/lib/core.js index f47e61bd..99305e96 100644 --- a/src/javascript/lib/core.js +++ b/src/javascript/lib/core.js @@ -8,6 +8,7 @@ import lists from './core/erlang_compat/lists'; import elixir_errors from './core/erlang_compat/elixir_errors'; import io from './core/erlang_compat/io'; import binary from './core/erlang_compat/binary'; +import unicode from './core/erlang_compat/unicode'; import Store from './core/store'; class Integer {} @@ -47,5 +48,6 @@ export default { lists, elixir_errors, io, - binary + binary, + unicode }; diff --git a/src/javascript/lib/core/erlang_compat/unicode.js b/src/javascript/lib/core/erlang_compat/unicode.js new file mode 100644 index 00000000..c50c2890 --- /dev/null +++ b/src/javascript/lib/core/erlang_compat/unicode.js @@ -0,0 +1,18 @@ +import erlang from './erlang'; + +function characters_to_list(characters) { + return characters.split('').map(c => c.codePointAt(0)); +} + +function characters_to_binary(characters) { + if (erlang.is_binary(characters)) { + return characters; + } + + return String.fromCodePoint(...characters); +} + +export default { + characters_to_list, + characters_to_binary +}; diff --git a/test/support/main.ex b/test/support/main.ex index a18d3d90..c4b37b87 100644 --- a/test/support/main.ex +++ b/test/support/main.ex @@ -1,5 +1,7 @@ defmodule Main do def start(:normal, [callback]) do callback.("started") + + String.upcase("d") end end From f08f471942a7744c3082daee2188f11a7269dccc Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Sat, 29 Jul 2017 21:04:10 -0500 Subject: [PATCH 199/418] Add __info__ function to modules --- .../passes/translate/forms/pattern.ex | 6 +- lib/elixir_script/passes/translate/module.ex | 125 +++++++++++++++++- test/beam_test.exs | 6 - 3 files changed, 126 insertions(+), 11 deletions(-) diff --git a/lib/elixir_script/passes/translate/forms/pattern.ex b/lib/elixir_script/passes/translate/forms/pattern.ex index 7a86da69..26aa7089 100644 --- a/lib/elixir_script/passes/translate/forms/pattern.ex +++ b/lib/elixir_script/passes/translate/forms/pattern.ex @@ -223,10 +223,14 @@ defmodule ElixirScript.Translate.Forms.Pattern do unify(name, left, state) end - defp process_pattern({var, _, _}, _) do + defp process_pattern({var, _, a}, _) when is_atom(a) do { [PM.parameter(J.literal(to_string(var)))], [ElixirScript.Translate.Identifier.make_identifier(var)] } end + defp process_pattern(ast, state) do + { [Form.compile!(ast, state)], [] } + end + defp reduce_patterns(patterns, _) do patterns |> Enum.reduce({ [], [] }, fn({ pattern, new_param }, { patterns, new_params }) -> diff --git a/lib/elixir_script/passes/translate/module.ex b/lib/elixir_script/passes/translate/module.ex index 7dde8c3e..9343200d 100644 --- a/lib/elixir_script/passes/translate/module.ex +++ b/lib/elixir_script/passes/translate/module.ex @@ -3,6 +3,7 @@ defmodule ElixirScript.Translate.Module do alias ESTree.Tools.Builder, as: J alias ElixirScript.Translate.Function alias ElixirScript.State, as: ModuleState + alias ElixirScript.Translate.Form @doc """ Translate the given module's ast to @@ -59,15 +60,17 @@ defmodule ElixirScript.Translate.Module do #we combine our function arities combined_defs = combine_defs(used_defs) - exports = make_exports(module, combined_defs) + exports = make_exports(module, combined_defs, defs, state) # If there are no public exports, skip compilation case exports do - %ESTree.ObjectExpression{ properties: [] } -> + %ESTree.ObjectExpression{ properties: props } when length(props) == 2 -> nil _ -> { compiled_functions, _ } = Enum.map_reduce(combined_defs, state, &Function.compile(&1, &2)) + compiled_functions = compiled_functions ++ [make_info_function(module, defs, state)] + js_ast = ElixirScript.ModuleSystems.Namespace.build( module, compiled_functions, @@ -90,7 +93,7 @@ defmodule ElixirScript.Translate.Module do end) end - defp make_exports(module, reachable_defs) do + defp make_exports(module, reachable_defs, definitions, state) do exports = Enum.reduce(reachable_defs, [], fn {{name, _arity}, :def, _, _}, list -> function_name = ElixirScript.Translate.Identifier.make_identifier(name) @@ -110,7 +113,13 @@ defmodule ElixirScript.Translate.Module do ), [J.literal(to_string(module))] ) - }] + }, + J.property( + J.identifier("__info__"), + J.identifier("__info__"), + :init, + true + )] J.object_expression(exports) end @@ -150,4 +159,112 @@ defmodule ElixirScript.Translate.Module do false end end + + # Builds the __info__ function that Elixir modules + # have. Only supports the `functions`, `macros` and + # `module` kinds + defp make_info_function(module, definitions, state) do + functions = Enum.filter(definitions, fn + {_, :def, _, _} -> + true + _ -> + false + end) + |> Enum.map(fn + {func, _, _, _} -> + func + end) + + functions = Form.compile!(functions, state) + + macros = Enum.filter(definitions, fn + {_, :defmacro, _, _} -> + true + _ -> + false + end) + |> Enum.map(fn + {func, _, _, _} -> + func + end) + + macros = Form.compile!(macros, state) + + module = J.call_expression( + J.member_expression( + J.identifier("Symbol"), + J.identifier("for") + ), + [J.literal(to_string(module))] + ) + + body = J.if_statement( + J.binary_expression( + :===, + J.identifier("kind"), + J.call_expression( + J.member_expression( + J.identifier("Symbol"), + J.identifier("for") + ), + [J.literal("functions")] + ) + ), + J.block_statement([ + J.return_statement(functions) + ]), + J.if_statement( + J.binary_expression( + :===, + J.identifier("kind"), + J.call_expression( + J.member_expression( + J.identifier("Symbol"), + J.identifier("for") + ), + [J.literal("macros")] + ) + ), + J.block_statement([ + J.return_statement(macros) + ]), + J.if_statement( + J.binary_expression( + :===, + J.identifier("kind"), + J.call_expression( + J.member_expression( + J.identifier("Symbol"), + J.identifier("for") + ), + [J.literal("module")] + ) + ), + J.block_statement([ + J.return_statement(module) + ]) + ) + ) + ) + + body = J.block_statement([ + body, + J.throw_statement( + J.new_expression( + J.member_expression( + Function.patterns_ast(), + J.identifier("MatchError") + ), + [J.identifier("kind")] + ) + ) + ]) + + J.function_declaration( + J.identifier("__info__"), + [J.identifier("kind")], + [], + body + ) + end end diff --git a/test/beam_test.exs b/test/beam_test.exs index 43c45880..bc6671a3 100644 --- a/test/beam_test.exs +++ b/test/beam_test.exs @@ -12,10 +12,4 @@ defmodule ElixirScript.Beam.Test do test "can get ast from beam that is protocol" do assert {:ok, Enumerable, _} = ElixirScript.Beam.debug_info(Enumerable) end - - test "replaces String with ElixirScript.String" do - assert {:ok, map} = ElixirScript.Beam.debug_info(String) - assert {:ok, map2} = ElixirScript.Beam.debug_info(ElixirScript.String) - assert map.definitions == map2.definitions - end end From 51f9576968c5e2f68f5443b956d337548e10eeda Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Sat, 29 Jul 2017 21:06:36 -0500 Subject: [PATCH 200/418] Update travis.yml to final version of elixir 1.5.0 --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index ed00c03d..9ac2cc0b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -9,8 +9,8 @@ install: - npm install -g yarn - yarn before_script: - - wget https://repo.hex.pm/builds/elixir/v1.5.0-rc.2-otp-20.zip - - unzip -d elixir v1.5.0-rc.2-otp-20.zip + - wget https://repo.hex.pm/builds/elixir/v1.5.0-otp-20.zip + - unzip -d elixir v1.5.0-otp-20.zip - export PATH=$(pwd)/elixir/bin:${PATH} - mix local.rebar --force - mix local.hex --force From 5c0ef8b757224a69c060bca7fad2275d2c23aa1e Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Sun, 30 Jul 2017 04:40:29 -0500 Subject: [PATCH 201/418] Some bug fixes. Add elixir_config erlang compat module --- .tool-versions | 2 +- lib/elixir_script/passes/translate/clause.ex | 16 +---- lib/elixir_script/passes/translate/form.ex | 4 ++ .../passes/translate/forms/bitstring.ex | 2 +- .../passes/translate/forms/remote.ex | 1 + lib/elixir_script/passes/translate/module.ex | 4 +- package.json | 12 ++-- priv/build/iife/ElixirScript.Core.js | 10 +-- src/javascript/lib/core.js | 4 +- .../lib/core/erlang_compat/elixir_config.js | 43 +++++++++++++ .../lib/core/erlang_compat/erlang.js | 11 +++- test/support/main.ex | 2 - yarn.lock | 63 ++++++++++++++----- 13 files changed, 124 insertions(+), 50 deletions(-) create mode 100644 src/javascript/lib/core/erlang_compat/elixir_config.js diff --git a/.tool-versions b/.tool-versions index a6c3da3e..4676ecd7 100644 --- a/.tool-versions +++ b/.tool-versions @@ -1,3 +1,3 @@ erlang 20.0 elixir 1.5.0-otp-20 -nodejs 8.2.0 +nodejs 8.2.1 diff --git a/lib/elixir_script/passes/translate/clause.ex b/lib/elixir_script/passes/translate/clause.ex index 3cebc738..74d96f5e 100644 --- a/lib/elixir_script/passes/translate/clause.ex +++ b/lib/elixir_script/passes/translate/clause.ex @@ -2,6 +2,7 @@ defmodule ElixirScript.Translate.Clause do alias ESTree.Tools.Builder, as: J alias ElixirScript.Translate.Form alias ElixirScript.Translate.Forms.Pattern + alias ElixirScript.Translate.Function @moduledoc """ Handles translation of all of the clause ASTs @@ -19,20 +20,7 @@ defmodule ElixirScript.Translate.Clause do {patterns, params, state} = Pattern.compile(args, state) guard = compile_guard(params, guards, state) - body = case body do - nil -> - J.identifier("null") - {:__block__, _, block_body} -> - {list, _} = Enum.map_reduce(block_body, state, &Form.compile(&1, &2)) - List.flatten(list) - b when is_list(b) -> - {list, _} = Enum.map_reduce(b, state, &Form.compile(&1, &2)) - List.flatten(list) - _ -> - Form.compile!(body, state) - |> List.wrap - |> List.flatten - end + {body, _state} = Function.compile_block(body, state) body = body |> return_last_statement diff --git a/lib/elixir_script/passes/translate/form.ex b/lib/elixir_script/passes/translate/form.ex index a447a9b2..5f7e37b5 100644 --- a/lib/elixir_script/passes/translate/form.ex +++ b/lib/elixir_script/passes/translate/form.ex @@ -102,6 +102,10 @@ defmodule ElixirScript.Translate.Form do ElixirScript.Translate.Forms.Map.compile(map, state) end + def compile({:<<>>, _, []} = bitstring, state) do + Bitstring.compile(bitstring, state) + end + def compile({:<<>>, _, elements} = bitstring, state) do is_interpolated_string = Enum.all?(elements, fn(x) -> case x do diff --git a/lib/elixir_script/passes/translate/forms/bitstring.ex b/lib/elixir_script/passes/translate/forms/bitstring.ex index 0db3e2ef..80e872d2 100644 --- a/lib/elixir_script/passes/translate/forms/bitstring.ex +++ b/lib/elixir_script/passes/translate/forms/bitstring.ex @@ -27,7 +27,7 @@ defmodule ElixirScript.Translate.Forms.Bitstring do do_compile_element({:binary, Form.compile!(element, state)}) end - def compile_element({:<<>>, [], elements}, state) do + def compile_element({:<<>>, _, elements}, state) do {ast, _} = compile(elements, state) ast end diff --git a/lib/elixir_script/passes/translate/forms/remote.ex b/lib/elixir_script/passes/translate/forms/remote.ex index 70651e11..cf6ac235 100644 --- a/lib/elixir_script/passes/translate/forms/remote.ex +++ b/lib/elixir_script/passes/translate/forms/remote.ex @@ -11,6 +11,7 @@ defmodule ElixirScript.Translate.Forms.Remote do :lists, :gen, :elixir_errors, + :elixir_config, :supervisor, :application, :code, diff --git a/lib/elixir_script/passes/translate/module.ex b/lib/elixir_script/passes/translate/module.ex index 9343200d..43522b7b 100644 --- a/lib/elixir_script/passes/translate/module.ex +++ b/lib/elixir_script/passes/translate/module.ex @@ -60,7 +60,7 @@ defmodule ElixirScript.Translate.Module do #we combine our function arities combined_defs = combine_defs(used_defs) - exports = make_exports(module, combined_defs, defs, state) + exports = make_exports(module, combined_defs) # If there are no public exports, skip compilation case exports do @@ -93,7 +93,7 @@ defmodule ElixirScript.Translate.Module do end) end - defp make_exports(module, reachable_defs, definitions, state) do + defp make_exports(module, reachable_defs) do exports = Enum.reduce(reachable_defs, [], fn {{name, _arity}, :def, _, _}, list -> function_name = ElixirScript.Translate.Identifier.make_identifier(name) diff --git a/package.json b/package.json index 95032896..afaa2624 100644 --- a/package.json +++ b/package.json @@ -30,18 +30,20 @@ "babel-core": "^6.24.0", "babel-preset-env": "^1.6.0", "babel-register": "^6.24.0", - "eslint": "^4.2.0", - "eslint-config-airbnb-base": "^11.1.0", + "eslint": "^4.3.0", + "eslint-config-airbnb-base": "^11.3.1", "eslint-plugin-import": "^2.7.0", - "nyc": "^11.0.3", + "nyc": "^11.1.0", "rollup": "^0.45.2", "rollup-plugin-babel": "^2.7.1", "rollup-plugin-babili": "^3.1.0", "rollup-plugin-node-resolve": "^3.0.0", - "sinon": "^2.3.8" + "sinon": "^2.4.1" }, "ava": { - "require": ["babel-register"], + "require": [ + "babel-register" + ], "babel": { "babelrc": true } diff --git a/priv/build/iife/ElixirScript.Core.js b/priv/build/iife/ElixirScript.Core.js index 0242e617..44fc71e3 100644 --- a/priv/build/iife/ElixirScript.Core.js +++ b/priv/build/iife/ElixirScript.Core.js @@ -1,6 +1,6 @@ -var ElixirScript=function(){'use strict';/* @flow */function namedVariableResult(a,b){return new NamedVariableResult(a,b)}/* @flow */function is_number(a){return'number'==typeof a}function is_string(a){return'string'==typeof a}function is_boolean(a){return'boolean'==typeof a}function is_symbol(a){return'symbol'==typeof a}function is_object(a){return'object'==typeof a}function is_variable(a){return a instanceof Variable}function is_null(a){return null===a}function is_array(a){return Array.isArray(a)}function is_function(a){return'[object Function]'==Object.prototype.toString.call(a)}function is_map(a){return a instanceof Map}function resolveNull(){return function(a){return is_null(a)}}function resolveWildcard(){return function(){return!0}}function resolveObject(a){let b={};const c=Object.keys(a).concat(Object.getOwnPropertySymbols(a));for(let d of c)b[d]=buildMatch(a[d]);return function(d,e){if(!is_object(d)||a.length>d.length)return!1;for(let a of c)if(!(a in d)||!b[a](d[a],e))return!1;return!0}}function getSize(a,b){return a*b/8}function arraysEqual(c,a){if(c===a)return!0;if(null==c||null==a)return!1;if(c.length!=a.length)return!1;for(var b=0;be.integer(a));return new e(...b)}function resolveNoMatch(){return function(){return!1}}function buildMatch(a){if(null===a)return resolveNull(a);if('undefined'==typeof a)return resolveWildcard(a);const b=a.constructor.prototype,c=f.get(b);return c?c(a):'object'==typeof a?resolveObject(a):resolveNoMatch()}function defmatchgen(...a){const b=getArityMap(a);return function*(...a){let[c,d]=findMatchingFunction(a,b);return yield*c.apply(this,d)}}function findMatchingFunction(a,b){if(b.has(a.length)){const c=b.get(a.length);let d=null,e=null;for(let b of c){let c=[];a=fillInOptionalValues(a,b.arity,b.optionals);const f=b.pattern(a,c),[g,h]=checkNamedVariables(c);if(f&&h&&b.guard.apply(this,g)){d=b.fn,e=g;break}}if(!d)throw console.error('No match for:',a),new MatchError(a);return[d,e]}throw console.error('Arity of',a.length,'not found. No match for:',a),new MatchError(a)}function getArityMap(a){let b=new Map;for(const c of a){const a=getArityRange(c);for(const d of a){let a=[];b.has(d)&&(a=b.get(d)),a.push(c),b.set(d,a)}}return b}function getArityRange(a){const b=a.arity-a.optionals.length,c=a.arity;let d=[b];for(;d[d.length-1]!=c;)d.push(d[d.length-1]+1);return d}function getOptionalValues(a){let b=[];for(let c=0;c!0,d=null){let e=[],f=buildMatch(a);const g=f(b,e),[h,i]=checkNamedVariables(e);return g&&i&&c.apply(this,h)?h:d}function run_generators(a,b){if(0==b.length)return a.map((a)=>{return Array.isArray(a)?a:[a]});const c=b.pop();let d=[];for(let e of c())for(let b of a)d.push([e].concat(b));return run_generators(d,b)}function iterator_to_reducer(a,b,c){const d=a[Symbol.iterator]();let e=d.next(),f=b;for(;!1===e.done;){if(f=c(e.value,f.get(1)),f.get(0)===Symbol.for('halt'))return new o.Tuple(Symbol.for('halted'),f.get(1));if(f.get(0)===Symbol.for('suspend'))return new o.Tuple(Symbol.for('suspended'),f.get(1),(a)=>{return iterator_to_reducer(d,a,c)});e=d.next()}return new o.Tuple(Symbol.for('done'),f.get(1))}function map_to_object(a){const b={};for(const[c,d]of a.entries())b[c]=d instanceof Map?map_to_object(d):d;return b}function run_list_generators(a,b){if(0==b.length)return a.map((a)=>{return Array.isArray(a)?a:[a]});const c=b.pop(),d=[];for(const e of c())for(const b of a)d.push([e].concat(b));return run_list_generators(d,b)}// http://erlang.org/doc/man/lists.html +var ElixirScript=function(){'use strict';/* @flow */function namedVariableResult(a,b){return new NamedVariableResult(a,b)}/* @flow */function is_number(a){return'number'==typeof a}function is_string(a){return'string'==typeof a}function is_boolean(a){return'boolean'==typeof a}function is_symbol(a){return'symbol'==typeof a}function is_object(a){return'object'==typeof a}function is_variable(a){return a instanceof Variable}function is_null(a){return null===a}function is_array(a){return Array.isArray(a)}function is_function(a){return'[object Function]'==Object.prototype.toString.call(a)}function is_map(a){return a instanceof Map}function resolveNull(){return function(a){return is_null(a)}}function resolveWildcard(){return function(){return!0}}function resolveObject(a){let b={};const c=Object.keys(a).concat(Object.getOwnPropertySymbols(a));for(let d of c)b[d]=buildMatch(a[d]);return function(d,e){if(!is_object(d)||a.length>d.length)return!1;for(let a of c)if(!(a in d)||!b[a](d[a],e))return!1;return!0}}function getSize(a,b){return a*b/8}function arraysEqual(c,a){if(c===a)return!0;if(null==c||null==a)return!1;if(c.length!=a.length)return!1;for(var b=0;bf.integer(a));return new f(...b)}function resolveNoMatch(){return function(){return!1}}function buildMatch(a){if(null===a)return resolveNull(a);if('undefined'==typeof a)return resolveWildcard(a);const b=a.constructor.prototype,c=g.get(b);return c?c(a):'object'==typeof a?resolveObject(a):resolveNoMatch()}function defmatchgen(...a){const b=getArityMap(a);return function*(...a){let[c,d]=findMatchingFunction(a,b);return yield*c.apply(this,d)}}function findMatchingFunction(a,b){if(b.has(a.length)){const c=b.get(a.length);let d=null,e=null;for(let b of c){let c=[];a=fillInOptionalValues(a,b.arity,b.optionals);const f=b.pattern(a,c),[g,h]=checkNamedVariables(c);if(f&&h&&b.guard.apply(this,g)){d=b.fn,e=g;break}}if(!d)throw console.error('No match for:',a),new MatchError(a);return[d,e]}throw console.error('Arity of',a.length,'not found. No match for:',a),new MatchError(a)}function getArityMap(a){let b=new Map;for(const c of a){const a=getArityRange(c);for(const d of a){let a=[];b.has(d)&&(a=b.get(d)),a.push(c),b.set(d,a)}}return b}function getArityRange(a){const b=a.arity-a.optionals.length,c=a.arity;let d=[b];for(;d[d.length-1]!=c;)d.push(d[d.length-1]+1);return d}function getOptionalValues(a){let b=[];for(let c=0;c!0,d=null){let e=[],f=buildMatch(a);const g=f(b,e),[h,i]=checkNamedVariables(e);return g&&i&&c.apply(this,h)?h:d}function run_generators(a,b){if(0==b.length)return a.map((a)=>{return Array.isArray(a)?a:[a]});const c=b.pop();let d=[];for(let e of c())for(let b of a)d.push([e].concat(b));return run_generators(d,b)}function iterator_to_reducer(a,b,c){const d=a[Symbol.iterator]();let e=d.next(),f=b;for(;!1===e.done;){if(f=c(e.value,f.get(1)),f.get(0)===Symbol.for('halt'))return new r.Tuple(Symbol.for('halted'),f.get(1));if(f.get(0)===Symbol.for('suspend'))return new r.Tuple(Symbol.for('suspended'),f.get(1),(a)=>{return iterator_to_reducer(d,a,c)});e=d.next()}return new r.Tuple(Symbol.for('done'),f.get(1))}function map_to_object(a){const b={};for(const[c,d]of a.entries())b[c]=d instanceof Map?map_to_object(d):d;return b}function run_list_generators(a,b){if(0==b.length)return a.map((a)=>{return Array.isArray(a)?a:[a]});const c=b.pop(),d=[];for(const e of c())for(const b of a)d.push([e].concat(b));return run_list_generators(d,b)}// http://erlang.org/doc/man/lists.html function reverse(a){return[...a]}function flatten(a,b=[]){const c=a.reduce((a,b)=>{return Array.isArray(b)?a.concat(flatten(b)):a.concat(b)},[]);return c.concat(b)}function foldl(a,b,c){return c.reduce((b,c)=>{return a(c,b)},b)}function keyfind(a,b,c){for(const d of c)if(d.get(b-1)===a)return d;return!1}function keydelete(a,b,c){const d=[];let e=!1;for(let f=0;f{if(null===c)return a;return is_integer(c)?a+b(c):is_bitstring$1(c)?a+b(...c.value):a+iolist_to_binary(c)},'');return d}function is_key(a,b){return b.has(a)}function get_key(a){let b=a;if(__elixirscript_names__.has(a)&&(b=__elixirscript_names__.get(a)),__elixirscript_store__.has(b))return b;throw new Error(`Key ${b} not found`)}var a=Number.isInteger;class Variable{constructor(a=null,b=Symbol.for('tailored.no_value')){this.name=a,this.default_value=b}}class Wildcard{constructor(){}}class StartsWith{constructor(a){this.prefix=a}}class Capture{constructor(a){this.value=a}}class HeadTail{constructor(a,b){this.head=a,this.tail=b}}class Type{constructor(a,b={}){this.type=a,this.objPattern=b}}class Bound{constructor(a){this.value=a}}class BitStringMatch{constructor(...a){this.values=a}length(){return values.length}bit_size(){return 8*this.byte_size()}byte_size(){let a=0;for(let b of this.values)a+=b.unit*b.size/8;return a}getValue(a){return this.values(a)}getSizeOfValue(a){let b=this.getValue(a);return b.unit*b.size}getTypeOfValue(a){return this.getValue(a).type}}class NamedVariableResult{constructor(a,b){this.name=a,this.value=b}}class Tuple{constructor(...a){this.values=Object.freeze(a),this.length=this.values.length}get(a){return this.values[a]}count(){return this.values.length}[Symbol.iterator](){return this.values[Symbol.iterator]()}toString(){let a,b='';for(a=0;aBitString$1.integer(a));return new BitString$1(...d)}[Symbol.iterator](){return this.value[Symbol.iterator]()}toString(){var a,b='';for(a=0;a>'}process(a){let b=[];var c;for(c=0;cb?c.push(b):2048>b?c.push(192|b>>6,128|63&b):55296>b||57344<=b?c.push(224|b>>12,128|63&b>>6,128|63&b):(d++,b=65536+((1023&b)<<10|1023&a.charCodeAt(d)),c.push(240|b>>18,128|63&b>>12,128|63&b>>6,128|63&b));return c}static toUTF16Array(a){for(var b,c=[],d=0;d=b?(c.push(0),c.push(b)):(c.push(255&b>>8),c.push(255&b));return c}static toUTF32Array(a){for(var b,c=[],d=0;d=b?(c.push(0),c.push(0),c.push(0),c.push(b)):(c.push(0),c.push(0),c.push(255&b>>8),c.push(255&b));return c}//http://stackoverflow.com/questions/2003493/javascript-float-from-to-bits -static float32ToBytes(a){var b=[],c=new ArrayBuffer(4);new Float32Array(c)[0]=a;let d=new Uint32Array(c)[0];return b.push(255&d>>24),b.push(255&d>>16),b.push(255&d>>8),b.push(255&d),b}static float64ToBytes(a){var b=[],c=new ArrayBuffer(8);new Float64Array(c)[0]=a;var d=new Uint32Array(c)[0],e=new Uint32Array(c)[1];return b.push(255&e>>24),b.push(255&e>>16),b.push(255&e>>8),b.push(255&e),b.push(255&d>>24),b.push(255&d>>16),b.push(255&d>>8),b.push(255&d),b}}var d={Tuple,PID:class PID{constructor(){++b,this.id=b}toString(){return'PID#<0.'+this.id+'.0>'}},Reference:class Reference{constructor(){++c,this.id=c,this.ref=Symbol()}toString(){return'Ref#<0.0.0.'+this.id+'>'}},BitString:BitString$1};/* @flow */const e=d.BitString,f=new Map;f.set(Variable.prototype,function resolveVariable(a){return function(b,c){return null===a.name?c.push(b):!a.name.startsWith('_')&&c.push(namedVariableResult(a.name,b)),!0}}),f.set(Wildcard.prototype,resolveWildcard),f.set(HeadTail.prototype,function resolveHeadTail(a){const b=buildMatch(a.head),c=buildMatch(a.tail);return function(a,d){if(!is_array(a)||0===a.length)return!1;const e=a[0],f=a.slice(1);return b(e,d)&&c(f,d)}}),f.set(StartsWith.prototype,function resolveStartsWith(a){const b=a.prefix;return function(a,c){return is_string(a)&&a.startsWith(b)&&(c.push(a.substring(b.length)),!0)}}),f.set(Capture.prototype,function resolveCapture(a){const b=buildMatch(a.value);return function(a,c){return!!b(a,c)&&(c.push(a),!0)}}),f.set(Bound.prototype,function resolveBound(a){return function(b){return typeof b==typeof a.value&&b===a.value}}),f.set(Type.prototype,function resolveType(a){return function(b,c){if(b instanceof a.type){const d=buildMatch(a.objPattern);return d(b,c)}return!1}}),f.set(BitStringMatch.prototype,function resolveBitString(a){let b=[];for(let c of a.values)if(is_variable(c.value)){let a=getSize(c.unit,c.size);fillArray(b,a)}else b=b.concat(new e(c).value);let c=a.values;return function(a,d){var f=String.fromCharCode;let g=null;if(!is_string(a)&&!(a instanceof e))return!1;g=is_string(a)?new e(e.binary(a)):a;let h=0;for(let e,j=0;jd.size)return!1;for(let a of c)if(!d.has(a)||!b.get(a)(d.get(a),e))return!1;return!0}}),f.set(Array.prototype,function resolveArray(a){const b=a.map((a)=>buildMatch(a));return function(c,d){return is_array(c)&&c.length==a.length&&c.every(function(a,e){return b[e](c[e],d)})}}),f.set(String.prototype,function resolveString(a){return function(b){return is_string(b)&&b===a}}),f.set(Boolean.prototype,function resolveBoolean(a){return function(b){return is_boolean(b)&&b===a}}),f.set(Function.prototype,function resolveFunction(a){return function(b){return is_function(b)&&b===a}}),f.set(Object.prototype,resolveObject);class MatchError extends Error{constructor(a){if(super(),'symbol'==typeof a)this.message='No match for: '+a.toString();else if(Array.isArray(a)){let b=a.map((a)=>{return null===a?'null':'undefined'==typeof a?'undefined':a.toString()});this.message='No match for: '+b}else this.message='No match for: '+a;this.stack=new Error().stack,this.name=this.constructor.name}}class Clause{constructor(a,b,c=()=>!0){this.pattern=buildMatch(a),this.arity=a.length,this.optionals=getOptionalValues(a),this.fn=b,this.guard=c}}const g=Symbol();// https://github.com/airportyh/protomorphism -class Protocol{constructor(b){function createFun(b){return function(...c){const d=c[0];let e=null;if(null===d&&this.hasImplementation(Symbol('null'))?e=this.registry.get(Symbol)[b]:a(d)&&this.hasImplementation(o.Integer)?e=this.registry.get(o.Integer)[b]:'number'==typeof d&&!a(d)&&this.hasImplementation(o.Float)?e=this.registry.get(o.Float)[b]:'string'==typeof d&&this.hasImplementation(o.BitString)?e=this.registry.get(o.BitString)[b]:d&&d instanceof Map&&d.has(Symbol.for('__struct__'))&&this.hasImplementation(d)?e=this.registry.get(d.get(Symbol.for('__struct__')).__MODULE__)[b]:null!==d&&this.hasImplementation(d)?e=this.registry.get(d.constructor)[b]:this.fallback&&(e=this.fallback[b]),null!=e){const a=e.apply(this,c);return a}throw new Error(`No implementation found for ${d}`)}}for(const a in this.registry=new Map,this.fallback=null,b)this[a]=createFun(a).bind(this)}implementation(a,b){null===a?this.fallback=b:this.registry.set(a,b)}hasImplementation(a){if(a===o.Integer||a===o.Float||a===o.BitString)return this.registry.has(a);return a&&a instanceof Map&&a.has(Symbol.for('__struct__'))?this.registry.has(a.get(Symbol.for('__struct__')).__MODULE__):this.registry.has(a.constructor)}}class Recurse{constructor(a){this.func=a}}var h={reverse,foreach:function foreach(a,b){return b.forEach((b)=>a(b)),Symbol.for('ok')},duplicate:function duplicate(a,b){const c=[];for(;c.length{if(d.get(c-1)a.get(c-1)?1:0})},keystore:function keystore(a,b,c,d){const e=[...c];for(let f=0;fa.toString()).join()},map:function map(a,b){return b.map((b)=>a(b))},filter:function filter(a,b){return b.filter((b)=>a(b))},filtermap:function filtermap(a,b){const c=[];for(const e of b){const b=a(e);!0===b?c.push(e):b instanceof d.Tuple&&!0===b.get(0)&&c.push(b.get(1))}return c},member:function member(a,b){for(const c of b)if(c===a)return!0;return!1},all:function all(a,b){for(const c of b)if(!1===a(c))return!1;return!0},any:function any(a,b){for(const c of b)if(!0===a(c))return!0;return!1},splitwith:function splitwith(a,b){let c=!1;const e=[],f=[];for(const d of b)!0==c?f.push(d):!0===a(d)?e.push(d):(c=!0,f.push(d));return new d.Tuple(e,f)},sort:function sort(...a){if(1===a.length){const b=[...a[0]];return b.sort()}const c=a[0],b=[...a[1]];return b.sort((d,a)=>{const b=c(d,a);return!0===b?-1:1})}},i={atom_to_binary,binary_to_atom,binary_to_existing_atom:function binary_to_existing_atom(a,b=Symbol.for('utf8')){return binary_to_atom(a,b)},list_concatenation:function list_concatenation(a,b){return a.concat(b)},list_subtraction:function list_subtraction(a,b){const c=[...a];for(const d of b){const a=c.indexOf(d);-1>b},bxor:function bxor(a,b){return a^b},bnot:function bnot(a){return~a},is_bitstring:is_bitstring$1,is_boolean:function is_boolean$1(a){return'boolean'==typeof a||a instanceof Boolean},is_float:function is_float(b){return is_number$1(b)&&!a(b)},is_function:function is_function$1(a){return'function'==typeof a||a instanceof Function},is_integer,is_list:function is_list(a){return Array.isArray(a)},is_map:function is_map$1(a){return a instanceof Map},is_number:is_number$1,is_pid:function is_pid(a){return a instanceof d.PID},is_port:function is_port(){return!1},is_reference:function is_reference(a){return a instanceof d.Reference},is_tuple:function is_tuple(a){return a instanceof d.Tuple},is_atom:function is_atom(a){return'symbol'==typeof a||a instanceof Symbol||a.__MODULE__},is_binary,element:function element(a,b){return b.get(a-1)},setelement:function setelement(a,b,c){const e=[...b.values];return e[a-1]=c,new d.Tuple(...e)},make_tuple:function make_tuple(a,b){const c=[];for(let d=0;d!0){let d=[],e=buildMatch(a);const f=e(b,d),[g,h]=checkNamedVariables(d);if(f&&h&&c.apply(this,g))return g;throw console.error('No match for:',b),new MatchError(b)},MatchError,variable:function variable(a=null,b=Symbol.for('tailored.no_value')){return new Variable(a,b)},wildcard:function wildcard(){return new Wildcard},startsWith:function startsWith(a){return new StartsWith(a)},capture:function capture(a){return new Capture(a)},headTail:function headTail(a,b){return new HeadTail(a,b)},type:function a(a,b={}){return new Type(a,b)},bound:function bound(a){return new Bound(a)},Clause,clause:function clause(a,b,c=()=>!0){return new Clause(a,b,c)},bitStringMatch:function bitStringMatch(...a){return new BitStringMatch(...a)},match_or_default,defmatchgen,list_comprehension:function list_comprehension(a,b){const c=run_generators(b.pop()(),b);let d=[];for(let e of c)a.guard.apply(this,e)&&d.push(a.fn.apply(this,e));return d},list_generator:function list_generator(a,b){return function(){let c=[];for(let d of b){const b=match_or_default(a,d,()=>!0,g);if(b!=g){const[a]=b;c.push(a)}}return c}},bitstring_generator:function bitstring_generator(a,b){return function(){let c=[],d=b.slice(0,a.byte_size()),e=1;for(;d.byte_size==a.byte_size();){const f=match_or_default(a,d,()=>!0,g);if(f!=g){c.push(f)}d=b.slice(a.byte_size()*e,a.byte_size()*(e+1)),e++}return c}},bitstring_comprehension:function bitstring_comprehension(a,b){const c=run_generators(b.pop()(),b);let e=[];for(let d of c)a.guard.apply(this,d)&&e.push(a.fn.apply(this,d));return e=e.map((a)=>d.BitString.integer(a)),new d.BitString(...e)},defmatchGen:function defmatchGen(...a){return defmatchgen(...a)},defmatchAsync:function defmatchAsync(...a){const b=getArityMap(a);return async function(...a){if(b.has(a.length)){const c=b.get(a.length);let d=null,e=null;for(let b of c){let c=[];a=fillInOptionalValues(a,b.arity,b.optionals);const f=b.pattern(a,c),[g,h]=checkNamedVariables(c);if(f&&h&&(await b.guard.apply(this,c))){d=b.fn,e=c;break}}if(!d)throw console.error('No match for:',a),new MatchError(a);return d.apply(this,e)}throw console.error('Arity of',a.length,'not found. No match for:',a),new MatchError(a)}}},Integer:class Integer{},Float:class Float{},Functions:{call_property:function call_property(a,b){if(!b)return a instanceof Function||'function'==typeof a?a():a;if(a instanceof Map){let c=null;if(a.has(b)?c=b:a.has(Symbol.for(b))&&(c=Symbol.for(b)),null===c)throw new Error(`Property ${b} not found in ${a}`);return a.get(c)instanceof Function||'function'==typeof a.get(c)?a.get(c)():a.get(c)}let c=null;if('number'==typeof a||'symbol'==typeof a||'boolean'==typeof a||'string'==typeof a?void 0===a[b]?void 0!==a[Symbol.for(b)]&&(c=Symbol.for(b)):c=b:b in a?c=b:Symbol.for(b)in a&&(c=Symbol.for(b)),null===c)throw new Error(`Property ${b} not found in ${a}`);return a[c]instanceof Function||'function'==typeof a[c]?a[c]():a[c]},defprotocol:function defprotocol(a){return new Protocol(a)},defimpl:function defimpl(a,b,c){a.implementation(b,c)},build_namespace:function build_namespace(a,b){let c=b.split('.');const d=a;let e=a;'Elixir'===c[0]&&(c=c.slice(1));for(const d of c)'undefined'==typeof e[d]&&(e[d]={}),e=e[d];return d.__table__=a.__table__||{},d.__table__[Symbol.for(b)]=e,e},iterator_to_reducer,map_to_object,trampoline:function trampoline$1(a){let b=a;for(;b&&b instanceof Recurse;)b=b.func();return b},Recurse},SpecialForms:{_case:function _case(a,b){return o.Patterns.defmatch(...b)(a)},cond:function cond(...a){for(const b of a)if(b[0])return b[1]();throw new Error},_for:function _for(a,b,c,d=[]){let[e,f]=c.into(d);const g=run_list_generators(b.pop()(),b);for(const h of g)a.guard.apply(this,h)&&(e=f(e,new o.Tuple(Symbol.for('cont'),a.fn.apply(this,h))));return f(e,Symbol.for('done'))},_try:function _try(a,b,c,d,e){let f=null;try{f=a()}catch(a){let d=null;if(b)try{return d=b(a),d}catch(a){if(a instanceof o.Patterns.MatchError)throw a}if(c)try{return d=c(a),d}catch(a){if(a instanceof o.Patterns.MatchError)throw a}throw a}finally{e&&e()}if(d)try{return d(f)}catch(a){if(a instanceof o.Patterns.MatchError)throw new Error('No Match Found in Else');throw a}else return f},_with:function _with(...a){let b=[],c=null,d=null;'function'==typeof a[a.length-2]?[c,d]=a.splice(-2):c=a.pop();for(let c=0;c{const[c,d]=b;return a.set(c,d),a},new Map)},keys:function keys(a){return!1===i.is_map(a)?new d.Tuple(l,a):Array.from(a.keys())},values:function values$1(a){return!1===i.is_map(a)?new d.Tuple(l,a):Array.from(a.values())},is_key,put:function put(a,b,c){if(!1===i.is_map(c))return new d.Tuple(l,c);const e=new Map(c);return e.set(a,b),e},merge:function merge(a,b){return!1===i.is_map(a)?new d.Tuple(l,a):!1===i.is_map(b)?new d.Tuple(l,b):new Map([...a,...b])},update:function update(a,b,c){return!1===i.is_map(c)?new d.Tuple(l,c):!1===is_key(a,c)?new d.Tuple(m,a):new Map([...c,[a,b]])},get:function get(...a){const b=a[0],c=a[1];return!1===i.is_map(c)?new d.Tuple(l,c):is_key(b)?c.get(b):3===a.length?a[2]:new d.Tuple(m,b)},take:function take(a,b){if(!1===i.is_map(b))return new d.Tuple(l,b);if(!is_key(a))return k;const c=b.get(a),e=new Map(b);return e.delete(a),new d.Tuple(c,e)}},lists:h,elixir_errors:{warn:function warn(a){const b=a.join('');return console.warn(`warning: ${b}`),Symbol.for('ok')}},io:{put_chars:function put_chars(a,b){const c=i.iolist_to_binary(b);return a===Symbol.for('stderr')?console.error(c):console.log(c),Symbol.for('ok')}},binary:{copy:function copy(a,b=1){return a.repeat(b)}}};return{Core:o}}(); +function atom_to_binary(a,b=Symbol.for('utf8')){if(b!==Symbol.for('utf8'))throw new Error(`unsupported encoding ${b}`);return a.__MODULE__?Symbol.keyFor(a.__MODULE__):Symbol.keyFor(a)}function binary_to_atom(a,b=Symbol.for('utf8')){if(b!==Symbol.for('utf8'))throw new Error(`unsupported encoding ${b}`);return Symbol.for(a)}function is_bitstring$1(a){return a instanceof e.BitString}function is_number$1(a){return'number'==typeof a||a instanceof Number}function is_integer(a){return b(a)}function is_binary(a){return'string'==typeof a||a instanceof String}function iolist_to_binary(b){if(console.log(b),null===b)return'';if(is_binary(b))return b;if(is_bitstring$1(b))return a(...b.value);if(is_number$1(b))return a(b);const c=i.flatten(b);console.log(c);const d=c.reduce((b,c)=>{return null===c?b:is_integer(c)?b+a(c):is_bitstring$1(c)?b+a(...c.value):b+iolist_to_binary(c)},'');return d}function is_key(a,b){return b.has(a)}function put$1(a,b){return p.get(o).set(a,b),Symbol.for('ok')}function get$1(a){return p.get(o).get(a)}function get_key(a){let b=a;if(__elixirscript_names__.has(a)&&(b=__elixirscript_names__.get(a)),__elixirscript_store__.has(b))return b;throw new Error(`Key ${b} not found`)}var a=String.fromCodePoint,b=Number.isInteger;class Variable{constructor(a=null,b=Symbol.for('tailored.no_value')){this.name=a,this.default_value=b}}class Wildcard{constructor(){}}class StartsWith{constructor(a){this.prefix=a}}class Capture{constructor(a){this.value=a}}class HeadTail{constructor(a,b){this.head=a,this.tail=b}}class Type{constructor(a,b={}){this.type=a,this.objPattern=b}}class Bound{constructor(a){this.value=a}}class BitStringMatch{constructor(...a){this.values=a}length(){return values.length}bit_size(){return 8*this.byte_size()}byte_size(){let a=0;for(let b of this.values)a+=b.unit*b.size/8;return a}getValue(a){return this.values(a)}getSizeOfValue(a){let b=this.getValue(a);return b.unit*b.size}getTypeOfValue(a){return this.getValue(a).type}}class NamedVariableResult{constructor(a,b){this.name=a,this.value=b}}class Tuple{constructor(...a){this.values=Object.freeze(a),this.length=this.values.length}get(a){return this.values[a]}count(){return this.values.length}[Symbol.iterator](){return this.values[Symbol.iterator]()}toString(){let a,b='';for(a=0;aBitString$1.integer(a));return new BitString$1(...d)}[Symbol.iterator](){return this.value[Symbol.iterator]()}toString(){var a,b='';for(a=0;a>'}process(a){let b=[];var c;for(c=0;cb?c.push(b):2048>b?c.push(192|b>>6,128|63&b):55296>b||57344<=b?c.push(224|b>>12,128|63&b>>6,128|63&b):(d++,b=65536+((1023&b)<<10|1023&a.charCodeAt(d)),c.push(240|b>>18,128|63&b>>12,128|63&b>>6,128|63&b));return c}static toUTF16Array(a){for(var b,c=[],d=0;d=b?(c.push(0),c.push(b)):(c.push(255&b>>8),c.push(255&b));return c}static toUTF32Array(a){for(var b,c=[],d=0;d=b?(c.push(0),c.push(0),c.push(0),c.push(b)):(c.push(0),c.push(0),c.push(255&b>>8),c.push(255&b));return c}//http://stackoverflow.com/questions/2003493/javascript-float-from-to-bits +static float32ToBytes(a){var b=[],c=new ArrayBuffer(4);new Float32Array(c)[0]=a;let d=new Uint32Array(c)[0];return b.push(255&d>>24),b.push(255&d>>16),b.push(255&d>>8),b.push(255&d),b}static float64ToBytes(a){var b=[],c=new ArrayBuffer(8);new Float64Array(c)[0]=a;var d=new Uint32Array(c)[0],e=new Uint32Array(c)[1];return b.push(255&e>>24),b.push(255&e>>16),b.push(255&e>>8),b.push(255&e),b.push(255&d>>24),b.push(255&d>>16),b.push(255&d>>8),b.push(255&d),b}}var e={Tuple,PID:class PID{constructor(){++c,this.id=c}toString(){return'PID#<0.'+this.id+'.0>'}},Reference:class Reference{constructor(){++d,this.id=d,this.ref=Symbol()}toString(){return'Ref#<0.0.0.'+this.id+'>'}},BitString:BitString$1};/* @flow */const f=e.BitString,g=new Map;g.set(Variable.prototype,function resolveVariable(a){return function(b,c){return null===a.name?c.push(b):!a.name.startsWith('_')&&c.push(namedVariableResult(a.name,b)),!0}}),g.set(Wildcard.prototype,resolveWildcard),g.set(HeadTail.prototype,function resolveHeadTail(a){const b=buildMatch(a.head),c=buildMatch(a.tail);return function(a,d){if(!is_array(a)||0===a.length)return!1;const e=a[0],f=a.slice(1);return b(e,d)&&c(f,d)}}),g.set(StartsWith.prototype,function resolveStartsWith(a){const b=a.prefix;return function(a,c){return is_string(a)&&a.startsWith(b)&&(c.push(a.substring(b.length)),!0)}}),g.set(Capture.prototype,function resolveCapture(a){const b=buildMatch(a.value);return function(a,c){return!!b(a,c)&&(c.push(a),!0)}}),g.set(Bound.prototype,function resolveBound(a){return function(b){return typeof b==typeof a.value&&b===a.value}}),g.set(Type.prototype,function resolveType(a){return function(b,c){if(b instanceof a.type){const d=buildMatch(a.objPattern);return d(b,c)}return!1}}),g.set(BitStringMatch.prototype,function resolveBitString(a){let b=[];for(let c of a.values)if(is_variable(c.value)){let a=getSize(c.unit,c.size);fillArray(b,a)}else b=b.concat(new f(c).value);let c=a.values;return function(a,d){var e=String.fromCharCode;let g=null;if(!is_string(a)&&!(a instanceof f))return!1;g=is_string(a)?new f(f.binary(a)):a;let h=0;for(let f,j=0;jd.size)return!1;for(let a of c)if(!d.has(a)||!b.get(a)(d.get(a),e))return!1;return!0}}),g.set(Array.prototype,function resolveArray(a){const b=a.map((a)=>buildMatch(a));return function(c,d){return is_array(c)&&c.length==a.length&&c.every(function(a,e){return b[e](c[e],d)})}}),g.set(String.prototype,function resolveString(a){return function(b){return is_string(b)&&b===a}}),g.set(Boolean.prototype,function resolveBoolean(a){return function(b){return is_boolean(b)&&b===a}}),g.set(Function.prototype,function resolveFunction(a){return function(b){return is_function(b)&&b===a}}),g.set(Object.prototype,resolveObject);class MatchError extends Error{constructor(a){if(super(),'symbol'==typeof a)this.message='No match for: '+a.toString();else if(Array.isArray(a)){let b=a.map((a)=>{return null===a?'null':'undefined'==typeof a?'undefined':a.toString()});this.message='No match for: '+b}else this.message='No match for: '+a;this.stack=new Error().stack,this.name=this.constructor.name}}class Clause{constructor(a,b,c=()=>!0){this.pattern=buildMatch(a),this.arity=a.length,this.optionals=getOptionalValues(a),this.fn=b,this.guard=c}}const h=Symbol();// https://github.com/airportyh/protomorphism +class Protocol{constructor(a){function createFun(a){return function(...c){const d=c[0];let e=null;if(null===d&&this.hasImplementation(Symbol('null'))?e=this.registry.get(Symbol)[a]:b(d)&&this.hasImplementation(r.Integer)?e=this.registry.get(r.Integer)[a]:'number'==typeof d&&!b(d)&&this.hasImplementation(r.Float)?e=this.registry.get(r.Float)[a]:'string'==typeof d&&this.hasImplementation(r.BitString)?e=this.registry.get(r.BitString)[a]:d&&d instanceof Map&&d.has(Symbol.for('__struct__'))&&this.hasImplementation(d)?e=this.registry.get(d.get(Symbol.for('__struct__')).__MODULE__)[a]:null!==d&&this.hasImplementation(d)?e=this.registry.get(d.constructor)[a]:this.fallback&&(e=this.fallback[a]),null!=e){const a=e.apply(this,c);return a}throw new Error(`No implementation found for ${d}`)}}for(const b in this.registry=new Map,this.fallback=null,a)this[b]=createFun(b).bind(this)}implementation(a,b){null===a?this.fallback=b:this.registry.set(a,b)}hasImplementation(a){if(a===r.Integer||a===r.Float||a===r.BitString)return this.registry.has(a);return a&&a instanceof Map&&a.has(Symbol.for('__struct__'))?this.registry.has(a.get(Symbol.for('__struct__')).__MODULE__):this.registry.has(a.constructor)}}class Recurse{constructor(a){this.func=a}}var i={reverse,foreach:function foreach(a,b){return b.forEach((b)=>a(b)),Symbol.for('ok')},duplicate:function duplicate(a,b){const c=[];for(;c.length{if(d.get(c-1)a.get(c-1)?1:0})},keystore:function keystore(a,b,c,d){const e=[...c];for(let f=0;fa.toString()).join()},map:function map(a,b){return b.map((b)=>a(b))},filter:function filter(a,b){return b.filter((b)=>a(b))},filtermap:function filtermap(a,b){const c=[];for(const d of b){const b=a(d);!0===b?c.push(d):b instanceof e.Tuple&&!0===b.get(0)&&c.push(b.get(1))}return c},member:function member(a,b){for(const c of b)if(c===a)return!0;return!1},all:function all(a,b){for(const c of b)if(!1===a(c))return!1;return!0},any:function any(a,b){for(const c of b)if(!0===a(c))return!0;return!1},splitwith:function splitwith(a,b){let c=!1;const d=[],f=[];for(const e of b)!0==c?f.push(e):!0===a(e)?d.push(e):(c=!0,f.push(e));return new e.Tuple(d,f)},sort:function sort(...a){if(1===a.length){const b=[...a[0]];return b.sort()}const c=a[0],b=[...a[1]];return b.sort((d,a)=>{const b=c(d,a);return!0===b?-1:1})}},j={atom_to_binary,binary_to_atom,binary_to_existing_atom:function binary_to_existing_atom(a,b=Symbol.for('utf8')){return binary_to_atom(a,b)},list_concatenation:function list_concatenation(a,b){return a.concat(b)},list_subtraction:function list_subtraction(a,b){const c=[...a];for(const d of b){const a=c.indexOf(d);-1>b},bxor:function bxor(a,b){return a^b},bnot:function bnot(a){return~a},is_bitstring:is_bitstring$1,is_boolean:function is_boolean$1(a){return'boolean'==typeof a||a instanceof Boolean},is_float:function is_float(a){return is_number$1(a)&&!b(a)},is_function:function is_function$1(a){return'function'==typeof a||a instanceof Function},is_integer,is_list:function is_list(a){return Array.isArray(a)},is_map:function is_map$1(a){return a instanceof Map},is_number:is_number$1,is_pid:function is_pid(a){return a instanceof e.PID},is_port:function is_port(){return!1},is_reference:function is_reference(a){return a instanceof e.Reference},is_tuple:function is_tuple(a){return a instanceof e.Tuple},is_atom:function is_atom(a){return'symbol'==typeof a||a instanceof Symbol||a.__MODULE__},is_binary,element:function element(a,b){return b.get(a-1)},setelement:function setelement(a,b,c){const d=[...b.values];return d[a-1]=c,new e.Tuple(...d)},make_tuple:function make_tuple(a,b){const c=[];for(let d=0;d!0){let d=[],e=buildMatch(a);const f=e(b,d),[g,h]=checkNamedVariables(d);if(f&&h&&c.apply(this,g))return g;throw console.error('No match for:',b),new MatchError(b)},MatchError,variable:function variable(a=null,b=Symbol.for('tailored.no_value')){return new Variable(a,b)},wildcard:function wildcard(){return new Wildcard},startsWith:function startsWith(a){return new StartsWith(a)},capture:function capture(a){return new Capture(a)},headTail:function headTail(a,b){return new HeadTail(a,b)},type:function a(a,b={}){return new Type(a,b)},bound:function bound(a){return new Bound(a)},Clause,clause:function clause(a,b,c=()=>!0){return new Clause(a,b,c)},bitStringMatch:function bitStringMatch(...a){return new BitStringMatch(...a)},match_or_default,defmatchgen,list_comprehension:function list_comprehension(a,b){const c=run_generators(b.pop()(),b);let d=[];for(let e of c)a.guard.apply(this,e)&&d.push(a.fn.apply(this,e));return d},list_generator:function list_generator(a,b){return function(){let c=[];for(let d of b){const b=match_or_default(a,d,()=>!0,h);if(b!=h){const[a]=b;c.push(a)}}return c}},bitstring_generator:function bitstring_generator(a,b){return function(){let c=[],d=b.slice(0,a.byte_size()),e=1;for(;d.byte_size==a.byte_size();){const f=match_or_default(a,d,()=>!0,h);if(f!=h){c.push(f)}d=b.slice(a.byte_size()*e,a.byte_size()*(e+1)),e++}return c}},bitstring_comprehension:function bitstring_comprehension(a,b){const c=run_generators(b.pop()(),b);let d=[];for(let e of c)a.guard.apply(this,e)&&d.push(a.fn.apply(this,e));return d=d.map((a)=>e.BitString.integer(a)),new e.BitString(...d)},defmatchGen:function defmatchGen(...a){return defmatchgen(...a)},defmatchAsync:function defmatchAsync(...a){const b=getArityMap(a);return async function(...a){if(b.has(a.length)){const c=b.get(a.length);let d=null,e=null;for(let b of c){let c=[];a=fillInOptionalValues(a,b.arity,b.optionals);const f=b.pattern(a,c),[g,h]=checkNamedVariables(c);if(f&&h&&(await b.guard.apply(this,c))){d=b.fn,e=c;break}}if(!d)throw console.error('No match for:',a),new MatchError(a);return d.apply(this,e)}throw console.error('Arity of',a.length,'not found. No match for:',a),new MatchError(a)}}},Integer:class Integer{},Float:class Float{},Functions:{call_property:function call_property(a,b){if(!b)return a instanceof Function||'function'==typeof a?a():a;if(a instanceof Map){let c=null;if(a.has(b)?c=b:a.has(Symbol.for(b))&&(c=Symbol.for(b)),null===c)throw new Error(`Property ${b} not found in ${a}`);return a.get(c)instanceof Function||'function'==typeof a.get(c)?a.get(c)():a.get(c)}let c=null;if('number'==typeof a||'symbol'==typeof a||'boolean'==typeof a||'string'==typeof a?void 0===a[b]?void 0!==a[Symbol.for(b)]&&(c=Symbol.for(b)):c=b:b in a?c=b:Symbol.for(b)in a&&(c=Symbol.for(b)),null===c)throw new Error(`Property ${b} not found in ${a}`);return a[c]instanceof Function||'function'==typeof a[c]?a[c]():a[c]},defprotocol:function defprotocol(a){return new Protocol(a)},defimpl:function defimpl(a,b,c){a.implementation(b,c)},build_namespace:function build_namespace(a,b){let c=b.split('.');const d=a;let e=a;'Elixir'===c[0]&&(c=c.slice(1));for(const d of c)'undefined'==typeof e[d]&&(e[d]={}),e=e[d];return d.__table__=a.__table__||{},d.__table__[Symbol.for(b)]=e,e},iterator_to_reducer,map_to_object,trampoline:function trampoline$1(a){let b=a;for(;b&&b instanceof Recurse;)b=b.func();return b},Recurse},SpecialForms:{_case:function _case(a,b){return r.Patterns.defmatch(...b)(a)},cond:function cond(...a){for(const b of a)if(b[0])return b[1]();throw new Error},_for:function _for(a,b,c,d=[]){let[e,f]=c.into(d);const g=run_list_generators(b.pop()(),b);for(const h of g)a.guard.apply(this,h)&&(e=f(e,new r.Tuple(Symbol.for('cont'),a.fn.apply(this,h))));return f(e,Symbol.for('done'))},_try:function _try(a,b,c,d,e){let f=null;try{f=a()}catch(a){let d=null;if(b)try{return d=b(a),d}catch(a){if(a instanceof r.Patterns.MatchError)throw a}if(c)try{return d=c(a),d}catch(a){if(a instanceof r.Patterns.MatchError)throw a}throw a}finally{e&&e()}if(d)try{return d(f)}catch(a){if(a instanceof r.Patterns.MatchError)throw new Error('No Match Found in Else');throw a}else return f},_with:function _with(...a){let b=[],c=null,d=null;'function'==typeof a[a.length-2]?[c,d]=a.splice(-2):c=a.pop();for(let c=0;c{const[c,d]=b;return a.set(c,d),a},new Map)},keys:function keys(a){return!1===j.is_map(a)?new e.Tuple(m,a):Array.from(a.keys())},values:function values$1(a){return!1===j.is_map(a)?new e.Tuple(m,a):Array.from(a.values())},is_key,put:function put(a,b,c){if(!1===j.is_map(c))return new e.Tuple(m,c);const d=new Map(c);return d.set(a,b),d},merge:function merge(a,b){return!1===j.is_map(a)?new e.Tuple(m,a):!1===j.is_map(b)?new e.Tuple(m,b):new Map([...a,...b])},update:function update(a,b,c){return!1===j.is_map(c)?new e.Tuple(m,c):!1===is_key(a,c)?new e.Tuple(n,a):new Map([...c,[a,b]])},get:function get(...a){const b=a[0],c=a[1];return!1===j.is_map(c)?new e.Tuple(m,c):is_key(b)?c.get(b):3===a.length?a[2]:new e.Tuple(n,b)},take:function take(a,b){if(!1===j.is_map(b))return new e.Tuple(m,b);if(!is_key(a))return l;const c=b.get(a),d=new Map(b);return d.delete(a),new e.Tuple(c,d)}},lists:i,elixir_errors:{warn:function warn(a){const b=a.join('');return console.warn(`warning: ${b}`),Symbol.for('ok')}},io:{put_chars:function put_chars(a,b){const c=j.iolist_to_binary(b);return a===Symbol.for('stderr')?console.error(c):console.log(c),Symbol.for('ok')}},binary:{copy:function copy(a,b=1){return a.repeat(b)}},unicode:{characters_to_list:function characters_to_list(a){return a.split('').map((a)=>a.codePointAt(0))},characters_to_binary:function characters_to_binary(b){return j.is_binary(b)?b:a(...b)}},elixir_config:{new:function _new(a){return p.set(o,new Map),p.get(o).set(o,a),o},delete:function _delete(a){return p.delete(a),!0},put:put$1,get:get$1,update:function update$1(a,b){const c=b(p.get(o).get(a));return put$1(a,c),c},get_and_put:function get_and_put(a,b){const c=get$1(a);return put$1(a,b),c}}};return{Core:r}}(); diff --git a/src/javascript/lib/core.js b/src/javascript/lib/core.js index 99305e96..65431d05 100644 --- a/src/javascript/lib/core.js +++ b/src/javascript/lib/core.js @@ -6,6 +6,7 @@ import erlang from './core/erlang_compat/erlang'; import maps from './core/erlang_compat/maps'; import lists from './core/erlang_compat/lists'; import elixir_errors from './core/erlang_compat/elixir_errors'; +import elixir_config from './core/erlang_compat/elixir_config'; import io from './core/erlang_compat/io'; import binary from './core/erlang_compat/binary'; import unicode from './core/erlang_compat/unicode'; @@ -49,5 +50,6 @@ export default { elixir_errors, io, binary, - unicode + unicode, + elixir_config }; diff --git a/src/javascript/lib/core/erlang_compat/elixir_config.js b/src/javascript/lib/core/erlang_compat/elixir_config.js new file mode 100644 index 00000000..1d785fd9 --- /dev/null +++ b/src/javascript/lib/core/erlang_compat/elixir_config.js @@ -0,0 +1,43 @@ +const MODULE = Symbol.for('elixir_config'); +const ets = new Map(); + +function _new(opts) { + ets.set(MODULE, new Map()); + ets.get(MODULE).set(MODULE, opts); + return MODULE; +} + +function _delete(module) { + ets.delete(module); + return true; +} + +function put(key, value) { + ets.get(MODULE).set(key, value); + return Symbol.for('ok'); +} + +function get(key) { + return ets.get(MODULE).get(key); +} + +function update(key, fun) { + const value = fun(ets.get(MODULE).get(key)); + put(key, value); + return value; +} + +function get_and_put(key, value) { + const oldValue = get(key); + put(key, value); + return oldValue; +} + +export default { + new: _new, + delete: _delete, + put, + get, + update, + get_and_put +}; diff --git a/src/javascript/lib/core/erlang_compat/erlang.js b/src/javascript/lib/core/erlang_compat/erlang.js index 78dcef94..5b853793 100644 --- a/src/javascript/lib/core/erlang_compat/erlang.js +++ b/src/javascript/lib/core/erlang_compat/erlang.js @@ -2,6 +2,10 @@ import ErlangTypes from 'erlang-types'; import lists from './lists'; +function atom_to_list(atom) { + return Symbol.keyFor(atom); +} + function atom_to_binary(atom, encoding = Symbol.for('utf8')) { if (encoding !== Symbol.for('utf8')) { throw new Error(`unsupported encoding ${encoding}`); @@ -198,8 +202,8 @@ function apply(...args) { return args[0][atom_to_binary(args[1])].apply(this, ...args[2]); } -function binary_part(binary, start, length) { - return binary.substring(start, start + length); +function binary_part(binary, start, _length) { + return binary.substring(start, start + _length); } function bit_size(bitstring) { @@ -368,5 +372,6 @@ export default { process_info, iolist_to_binary, io_size, - integer_to_binary + integer_to_binary, + atom_to_list }; diff --git a/test/support/main.ex b/test/support/main.ex index c4b37b87..a18d3d90 100644 --- a/test/support/main.ex +++ b/test/support/main.ex @@ -1,7 +1,5 @@ defmodule Main do def start(:normal, [callback]) do callback.("started") - - String.upcase("d") end end diff --git a/yarn.lock b/yarn.lock index 66443a82..d4a33f9c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1354,6 +1354,14 @@ cross-spawn@^4, cross-spawn@^4.0.0: lru-cache "^4.0.1" which "^1.2.9" +cross-spawn@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-5.1.0.tgz#e8bd0efee58fcff6f8f94510a0a554bbfa235449" + dependencies: + lru-cache "^4.0.1" + shebang-command "^1.2.0" + which "^1.2.9" + cryptiles@2.x.x: version "2.0.5" resolved "https://registry.yarnpkg.com/cryptiles/-/cryptiles-2.0.5.tgz#3bdfecdc608147c1c67202fa291e7dca59eaa3b8" @@ -1515,9 +1523,11 @@ escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.4, escape-string-regexp@^ version "1.0.5" resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" -eslint-config-airbnb-base@^11.1.0: - version "11.2.0" - resolved "https://registry.yarnpkg.com/eslint-config-airbnb-base/-/eslint-config-airbnb-base-11.2.0.tgz#19a9dc4481a26f70904545ec040116876018f853" +eslint-config-airbnb-base@^11.3.1: + version "11.3.1" + resolved "https://registry.yarnpkg.com/eslint-config-airbnb-base/-/eslint-config-airbnb-base-11.3.1.tgz#c0ab108c9beed503cb999e4c60f4ef98eda0ed30" + dependencies: + eslint-restricted-globals "^0.1.1" eslint-import-resolver-node@^0.3.1: version "0.3.1" @@ -1548,6 +1558,10 @@ eslint-plugin-import@^2.7.0: minimatch "^3.0.3" read-pkg-up "^2.0.0" +eslint-restricted-globals@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/eslint-restricted-globals/-/eslint-restricted-globals-0.1.1.tgz#35f0d5cbc64c2e3ed62e93b4b1a7af05ba7ed4d7" + eslint-scope@^3.7.1: version "3.7.1" resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-3.7.1.tgz#3d63c3edfda02e06e01a452ad88caacc7cdcb6e8" @@ -1555,14 +1569,15 @@ eslint-scope@^3.7.1: esrecurse "^4.1.0" estraverse "^4.1.1" -eslint@^4.2.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-4.2.0.tgz#a2b3184111b198e02e9c7f3cca625a5e01c56b3d" +eslint@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-4.3.0.tgz#fcd7c96376bbf34c85ee67ed0012a299642b108f" dependencies: ajv "^5.2.0" babel-code-frame "^6.22.0" chalk "^1.1.3" concat-stream "^1.6.0" + cross-spawn "^5.1.0" debug "^2.6.8" doctrine "^2.0.0" eslint-scope "^3.7.1" @@ -1571,6 +1586,7 @@ eslint@^4.2.0: estraverse "^4.2.0" esutils "^2.0.2" file-entry-cache "^2.0.0" + functional-red-black-tree "^1.0.1" glob "^7.1.2" globals "^9.17.0" ignore "^3.3.3" @@ -1589,6 +1605,7 @@ eslint@^4.2.0: pluralize "^4.0.0" progress "^2.0.0" require-uncached "^1.0.3" + semver "^5.3.0" strip-json-comments "~2.0.1" table "^4.0.1" text-table "~0.2.0" @@ -1853,6 +1870,10 @@ function-name-support@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/function-name-support/-/function-name-support-0.2.0.tgz#55d3bfaa6eafd505a50f9bc81fdf57564a0bb071" +functional-red-black-tree@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327" + gauge@~2.7.3: version "2.7.4" resolved "https://registry.yarnpkg.com/gauge/-/gauge-2.7.4.tgz#2c03405c7538c39d7eb37b317022e325fb018bf7" @@ -2351,7 +2372,7 @@ istanbul-lib-hook@^1.0.7: dependencies: append-transform "^0.4.0" -istanbul-lib-instrument@^1.7.3: +istanbul-lib-instrument@^1.7.4: version "1.7.4" resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-1.7.4.tgz#e9fd920e4767f3d19edc765e2d6b3f5ccbd0eea8" dependencies: @@ -2802,9 +2823,9 @@ number-is-nan@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" -nyc@^11.0.3: - version "11.0.3" - resolved "https://registry.yarnpkg.com/nyc/-/nyc-11.0.3.tgz#0c28bc669a851621709bf7a08503034bee3812b6" +nyc@^11.1.0: + version "11.1.0" + resolved "https://registry.yarnpkg.com/nyc/-/nyc-11.1.0.tgz#d6b3c5e16892a25af63138ba484676aa8a22eda7" dependencies: archy "^1.0.0" arrify "^1.0.1" @@ -2818,7 +2839,7 @@ nyc@^11.0.3: glob "^7.0.6" istanbul-lib-coverage "^1.1.1" istanbul-lib-hook "^1.0.7" - istanbul-lib-instrument "^1.7.3" + istanbul-lib-instrument "^1.7.4" istanbul-lib-report "^1.1.1" istanbul-lib-source-maps "^1.2.1" istanbul-reports "^1.1.1" @@ -2829,7 +2850,7 @@ nyc@^11.0.3: resolve-from "^2.0.0" rimraf "^2.5.4" signal-exit "^3.0.1" - spawn-wrap "^1.3.7" + spawn-wrap "^1.3.8" test-exclude "^4.1.1" yargs "^8.0.1" yargs-parser "^5.0.0" @@ -3461,13 +3482,23 @@ set-immediate-shim@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz#4b2b1b27eb808a9f8dcc481a58e5e56f599f3f61" +shebang-command@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea" + dependencies: + shebang-regex "^1.0.0" + +shebang-regex@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3" + signal-exit@^3.0.0, signal-exit@^3.0.1, signal-exit@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d" -sinon@^2.3.8: - version "2.3.8" - resolved "https://registry.yarnpkg.com/sinon/-/sinon-2.3.8.tgz#31de06fed8fba3a671e576dd96d0a5863796f25c" +sinon@^2.4.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/sinon/-/sinon-2.4.1.tgz#021fd64b54cb77d9d2fb0d43cdedfae7629c3a36" dependencies: diff "^3.1.0" formatio "1.2.0" @@ -3518,7 +3549,7 @@ source-map@^0.5.0, source-map@^0.5.3, source-map@^0.5.6, source-map@~0.5.1: version "0.5.6" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.6.tgz#75ce38f52bf0733c5a7f0c118d81334a2bb5f412" -spawn-wrap@^1.3.7: +spawn-wrap@^1.3.8: version "1.3.8" resolved "https://registry.yarnpkg.com/spawn-wrap/-/spawn-wrap-1.3.8.tgz#fa2a79b990cbb0bb0018dca6748d88367b19ec31" dependencies: From 1e010fb360aba7238e70174956ea5689edce7a1c Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Mon, 31 Jul 2017 21:28:01 -0500 Subject: [PATCH 202/418] Update estree dep --- mix.lock | 2 +- priv/build/iife/ElixirScript.Core.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/mix.lock b/mix.lock index 992c5f2f..46e32342 100644 --- a/mix.lock +++ b/mix.lock @@ -2,7 +2,7 @@ "certifi": {:hex, :certifi, "1.2.1", "c3904f192bd5284e5b13f20db3ceac9626e14eeacfbb492e19583cf0e37b22be", [:rebar3], [], "hexpm"}, "credo": {:hex, :credo, "0.8.3", "efe6e9078de64cefdd25d8df7a97292e29e63f42a8988990340eaf1f40d93224", [:mix], [{:bunt, "~> 0.2.0", [hex: :bunt, repo: "hexpm", optional: false]}], "hexpm"}, "earmark": {:hex, :earmark, "1.2.2", "f718159d6b65068e8daeef709ccddae5f7fdc770707d82e7d126f584cd925b74", [:mix], [], "hexpm"}, - "estree": {:hex, :estree, "2.6.0", "86a301b0c355fa55c19e7ef9dceb1b1e983c6df526a2b7846818a38c258fc3fb", [:mix], [], "hexpm"}, + "estree": {:hex, :estree, "2.6.1", "0a17cc0e9e35315dc4fcd79d30a746b1f3e9ed654be6084ce882ab491165ae22", [:mix], [], "hexpm"}, "ex_doc": {:hex, :ex_doc, "0.16.2", "3b3e210ebcd85a7c76b4e73f85c5640c011d2a0b2f06dcdf5acdb2ae904e5084", [:mix], [{:earmark, "~> 1.1", [hex: :earmark, repo: "hexpm", optional: false]}], "hexpm"}, "excoveralls": {:hex, :excoveralls, "0.7.1", "3dd659db19c290692b5e2c4a2365ae6d4488091a1ba58f62dcbdaa0c03da5491", [:mix], [{:exjsx, ">= 3.0.0", [hex: :exjsx, repo: "hexpm", optional: false]}, {:hackney, ">= 0.12.0", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm"}, "exjsx": {:hex, :exjsx, "4.0.0", "60548841e0212df401e38e63c0078ec57b33e7ea49b032c796ccad8cde794b5c", [:mix], [{:jsx, "~> 2.8.0", [hex: :jsx, repo: "hexpm", optional: false]}], "hexpm"}, diff --git a/priv/build/iife/ElixirScript.Core.js b/priv/build/iife/ElixirScript.Core.js index 44fc71e3..a0c0b537 100644 --- a/priv/build/iife/ElixirScript.Core.js +++ b/priv/build/iife/ElixirScript.Core.js @@ -1,6 +1,6 @@ var ElixirScript=function(){'use strict';/* @flow */function namedVariableResult(a,b){return new NamedVariableResult(a,b)}/* @flow */function is_number(a){return'number'==typeof a}function is_string(a){return'string'==typeof a}function is_boolean(a){return'boolean'==typeof a}function is_symbol(a){return'symbol'==typeof a}function is_object(a){return'object'==typeof a}function is_variable(a){return a instanceof Variable}function is_null(a){return null===a}function is_array(a){return Array.isArray(a)}function is_function(a){return'[object Function]'==Object.prototype.toString.call(a)}function is_map(a){return a instanceof Map}function resolveNull(){return function(a){return is_null(a)}}function resolveWildcard(){return function(){return!0}}function resolveObject(a){let b={};const c=Object.keys(a).concat(Object.getOwnPropertySymbols(a));for(let d of c)b[d]=buildMatch(a[d]);return function(d,e){if(!is_object(d)||a.length>d.length)return!1;for(let a of c)if(!(a in d)||!b[a](d[a],e))return!1;return!0}}function getSize(a,b){return a*b/8}function arraysEqual(c,a){if(c===a)return!0;if(null==c||null==a)return!1;if(c.length!=a.length)return!1;for(var b=0;bf.integer(a));return new f(...b)}function resolveNoMatch(){return function(){return!1}}function buildMatch(a){if(null===a)return resolveNull(a);if('undefined'==typeof a)return resolveWildcard(a);const b=a.constructor.prototype,c=g.get(b);return c?c(a):'object'==typeof a?resolveObject(a):resolveNoMatch()}function defmatchgen(...a){const b=getArityMap(a);return function*(...a){let[c,d]=findMatchingFunction(a,b);return yield*c.apply(this,d)}}function findMatchingFunction(a,b){if(b.has(a.length)){const c=b.get(a.length);let d=null,e=null;for(let b of c){let c=[];a=fillInOptionalValues(a,b.arity,b.optionals);const f=b.pattern(a,c),[g,h]=checkNamedVariables(c);if(f&&h&&b.guard.apply(this,g)){d=b.fn,e=g;break}}if(!d)throw console.error('No match for:',a),new MatchError(a);return[d,e]}throw console.error('Arity of',a.length,'not found. No match for:',a),new MatchError(a)}function getArityMap(a){let b=new Map;for(const c of a){const a=getArityRange(c);for(const d of a){let a=[];b.has(d)&&(a=b.get(d)),a.push(c),b.set(d,a)}}return b}function getArityRange(a){const b=a.arity-a.optionals.length,c=a.arity;let d=[b];for(;d[d.length-1]!=c;)d.push(d[d.length-1]+1);return d}function getOptionalValues(a){let b=[];for(let c=0;c!0,d=null){let e=[],f=buildMatch(a);const g=f(b,e),[h,i]=checkNamedVariables(e);return g&&i&&c.apply(this,h)?h:d}function run_generators(a,b){if(0==b.length)return a.map((a)=>{return Array.isArray(a)?a:[a]});const c=b.pop();let d=[];for(let e of c())for(let b of a)d.push([e].concat(b));return run_generators(d,b)}function iterator_to_reducer(a,b,c){const d=a[Symbol.iterator]();let e=d.next(),f=b;for(;!1===e.done;){if(f=c(e.value,f.get(1)),f.get(0)===Symbol.for('halt'))return new r.Tuple(Symbol.for('halted'),f.get(1));if(f.get(0)===Symbol.for('suspend'))return new r.Tuple(Symbol.for('suspended'),f.get(1),(a)=>{return iterator_to_reducer(d,a,c)});e=d.next()}return new r.Tuple(Symbol.for('done'),f.get(1))}function map_to_object(a){const b={};for(const[c,d]of a.entries())b[c]=d instanceof Map?map_to_object(d):d;return b}function run_list_generators(a,b){if(0==b.length)return a.map((a)=>{return Array.isArray(a)?a:[a]});const c=b.pop(),d=[];for(const e of c())for(const b of a)d.push([e].concat(b));return run_list_generators(d,b)}// http://erlang.org/doc/man/lists.html function reverse(a){return[...a]}function flatten(a,b=[]){const c=a.reduce((a,b)=>{return Array.isArray(b)?a.concat(flatten(b)):a.concat(b)},[]);return c.concat(b)}function foldl(a,b,c){return c.reduce((b,c)=>{return a(c,b)},b)}function keyfind(a,b,c){for(const d of c)if(d.get(b-1)===a)return d;return!1}function keydelete(a,b,c){const d=[];let e=!1;for(let f=0;f{return null===c?b:is_integer(c)?b+a(c):is_bitstring$1(c)?b+a(...c.value):b+iolist_to_binary(c)},'');return d}function is_key(a,b){return b.has(a)}function put$1(a,b){return p.get(o).set(a,b),Symbol.for('ok')}function get$1(a){return p.get(o).get(a)}function get_key(a){let b=a;if(__elixirscript_names__.has(a)&&(b=__elixirscript_names__.get(a)),__elixirscript_store__.has(b))return b;throw new Error(`Key ${b} not found`)}var a=String.fromCodePoint,b=Number.isInteger;class Variable{constructor(a=null,b=Symbol.for('tailored.no_value')){this.name=a,this.default_value=b}}class Wildcard{constructor(){}}class StartsWith{constructor(a){this.prefix=a}}class Capture{constructor(a){this.value=a}}class HeadTail{constructor(a,b){this.head=a,this.tail=b}}class Type{constructor(a,b={}){this.type=a,this.objPattern=b}}class Bound{constructor(a){this.value=a}}class BitStringMatch{constructor(...a){this.values=a}length(){return values.length}bit_size(){return 8*this.byte_size()}byte_size(){let a=0;for(let b of this.values)a+=b.unit*b.size/8;return a}getValue(a){return this.values(a)}getSizeOfValue(a){let b=this.getValue(a);return b.unit*b.size}getTypeOfValue(a){return this.getValue(a).type}}class NamedVariableResult{constructor(a,b){this.name=a,this.value=b}}class Tuple{constructor(...a){this.values=Object.freeze(a),this.length=this.values.length}get(a){return this.values[a]}count(){return this.values.length}[Symbol.iterator](){return this.values[Symbol.iterator]()}toString(){let a,b='';for(a=0;aBitString$1.integer(a));return new BitString$1(...d)}[Symbol.iterator](){return this.value[Symbol.iterator]()}toString(){var a,b='';for(a=0;a>'}process(a){let b=[];var c;for(c=0;cb?c.push(b):2048>b?c.push(192|b>>6,128|63&b):55296>b||57344<=b?c.push(224|b>>12,128|63&b>>6,128|63&b):(d++,b=65536+((1023&b)<<10|1023&a.charCodeAt(d)),c.push(240|b>>18,128|63&b>>12,128|63&b>>6,128|63&b));return c}static toUTF16Array(a){for(var b,c=[],d=0;d=b?(c.push(0),c.push(b)):(c.push(255&b>>8),c.push(255&b));return c}static toUTF32Array(a){for(var b,c=[],d=0;d=b?(c.push(0),c.push(0),c.push(0),c.push(b)):(c.push(0),c.push(0),c.push(255&b>>8),c.push(255&b));return c}//http://stackoverflow.com/questions/2003493/javascript-float-from-to-bits +function atom_to_binary(a,b=Symbol.for('utf8')){if(b!==Symbol.for('utf8'))throw new Error(`unsupported encoding ${b}`);return a.__MODULE__?Symbol.keyFor(a.__MODULE__):Symbol.keyFor(a)}function binary_to_atom(a,b=Symbol.for('utf8')){if(b!==Symbol.for('utf8'))throw new Error(`unsupported encoding ${b}`);return Symbol.for(a)}function is_bitstring$1(a){return a instanceof e.BitString}function is_number$1(a){return'number'==typeof a||a instanceof Number}function is_integer(a){return b(a)}function is_binary(a){return'string'==typeof a||a instanceof String}function iolist_to_binary(b){if(null===b)return'';if(is_binary(b))return b;if(is_bitstring$1(b))return a(...b.value);if(is_number$1(b))return a(b);const c=i.flatten(b),d=c.reduce((b,c)=>{if(null===c)return b;return is_integer(c)?b+a(c):is_bitstring$1(c)?b+a(...c.value):b+iolist_to_binary(c)},'');return d}function is_key(a,b){return b.has(a)}function put$1(a,b){return p.get(o).set(a,b),Symbol.for('ok')}function get$1(a){return p.get(o).get(a)}function get_key(a){let b=a;if(__elixirscript_names__.has(a)&&(b=__elixirscript_names__.get(a)),__elixirscript_store__.has(b))return b;throw new Error(`Key ${b} not found`)}var a=String.fromCodePoint,b=Number.isInteger;class Variable{constructor(a=null,b=Symbol.for('tailored.no_value')){this.name=a,this.default_value=b}}class Wildcard{constructor(){}}class StartsWith{constructor(a){this.prefix=a}}class Capture{constructor(a){this.value=a}}class HeadTail{constructor(a,b){this.head=a,this.tail=b}}class Type{constructor(a,b={}){this.type=a,this.objPattern=b}}class Bound{constructor(a){this.value=a}}class BitStringMatch{constructor(...a){this.values=a}length(){return values.length}bit_size(){return 8*this.byte_size()}byte_size(){let a=0;for(let b of this.values)a+=b.unit*b.size/8;return a}getValue(a){return this.values(a)}getSizeOfValue(a){let b=this.getValue(a);return b.unit*b.size}getTypeOfValue(a){return this.getValue(a).type}}class NamedVariableResult{constructor(a,b){this.name=a,this.value=b}}class Tuple{constructor(...a){this.values=Object.freeze(a),this.length=this.values.length}get(a){return this.values[a]}count(){return this.values.length}[Symbol.iterator](){return this.values[Symbol.iterator]()}toString(){let a,b='';for(a=0;aBitString$1.integer(a));return new BitString$1(...d)}[Symbol.iterator](){return this.value[Symbol.iterator]()}toString(){var a,b='';for(a=0;a>'}process(a){let b=[];var c;for(c=0;cb?c.push(b):2048>b?c.push(192|b>>6,128|63&b):55296>b||57344<=b?c.push(224|b>>12,128|63&b>>6,128|63&b):(d++,b=65536+((1023&b)<<10|1023&a.charCodeAt(d)),c.push(240|b>>18,128|63&b>>12,128|63&b>>6,128|63&b));return c}static toUTF16Array(a){for(var b,c=[],d=0;d=b?(c.push(0),c.push(b)):(c.push(255&b>>8),c.push(255&b));return c}static toUTF32Array(a){for(var b,c=[],d=0;d=b?(c.push(0),c.push(0),c.push(0),c.push(b)):(c.push(0),c.push(0),c.push(255&b>>8),c.push(255&b));return c}//http://stackoverflow.com/questions/2003493/javascript-float-from-to-bits static float32ToBytes(a){var b=[],c=new ArrayBuffer(4);new Float32Array(c)[0]=a;let d=new Uint32Array(c)[0];return b.push(255&d>>24),b.push(255&d>>16),b.push(255&d>>8),b.push(255&d),b}static float64ToBytes(a){var b=[],c=new ArrayBuffer(8);new Float64Array(c)[0]=a;var d=new Uint32Array(c)[0],e=new Uint32Array(c)[1];return b.push(255&e>>24),b.push(255&e>>16),b.push(255&e>>8),b.push(255&e),b.push(255&d>>24),b.push(255&d>>16),b.push(255&d>>8),b.push(255&d),b}}var e={Tuple,PID:class PID{constructor(){++c,this.id=c}toString(){return'PID#<0.'+this.id+'.0>'}},Reference:class Reference{constructor(){++d,this.id=d,this.ref=Symbol()}toString(){return'Ref#<0.0.0.'+this.id+'>'}},BitString:BitString$1};/* @flow */const f=e.BitString,g=new Map;g.set(Variable.prototype,function resolveVariable(a){return function(b,c){return null===a.name?c.push(b):!a.name.startsWith('_')&&c.push(namedVariableResult(a.name,b)),!0}}),g.set(Wildcard.prototype,resolveWildcard),g.set(HeadTail.prototype,function resolveHeadTail(a){const b=buildMatch(a.head),c=buildMatch(a.tail);return function(a,d){if(!is_array(a)||0===a.length)return!1;const e=a[0],f=a.slice(1);return b(e,d)&&c(f,d)}}),g.set(StartsWith.prototype,function resolveStartsWith(a){const b=a.prefix;return function(a,c){return is_string(a)&&a.startsWith(b)&&(c.push(a.substring(b.length)),!0)}}),g.set(Capture.prototype,function resolveCapture(a){const b=buildMatch(a.value);return function(a,c){return!!b(a,c)&&(c.push(a),!0)}}),g.set(Bound.prototype,function resolveBound(a){return function(b){return typeof b==typeof a.value&&b===a.value}}),g.set(Type.prototype,function resolveType(a){return function(b,c){if(b instanceof a.type){const d=buildMatch(a.objPattern);return d(b,c)}return!1}}),g.set(BitStringMatch.prototype,function resolveBitString(a){let b=[];for(let c of a.values)if(is_variable(c.value)){let a=getSize(c.unit,c.size);fillArray(b,a)}else b=b.concat(new f(c).value);let c=a.values;return function(a,d){var e=String.fromCharCode;let g=null;if(!is_string(a)&&!(a instanceof f))return!1;g=is_string(a)?new f(f.binary(a)):a;let h=0;for(let f,j=0;jd.size)return!1;for(let a of c)if(!d.has(a)||!b.get(a)(d.get(a),e))return!1;return!0}}),g.set(Array.prototype,function resolveArray(a){const b=a.map((a)=>buildMatch(a));return function(c,d){return is_array(c)&&c.length==a.length&&c.every(function(a,e){return b[e](c[e],d)})}}),g.set(String.prototype,function resolveString(a){return function(b){return is_string(b)&&b===a}}),g.set(Boolean.prototype,function resolveBoolean(a){return function(b){return is_boolean(b)&&b===a}}),g.set(Function.prototype,function resolveFunction(a){return function(b){return is_function(b)&&b===a}}),g.set(Object.prototype,resolveObject);class MatchError extends Error{constructor(a){if(super(),'symbol'==typeof a)this.message='No match for: '+a.toString();else if(Array.isArray(a)){let b=a.map((a)=>{return null===a?'null':'undefined'==typeof a?'undefined':a.toString()});this.message='No match for: '+b}else this.message='No match for: '+a;this.stack=new Error().stack,this.name=this.constructor.name}}class Clause{constructor(a,b,c=()=>!0){this.pattern=buildMatch(a),this.arity=a.length,this.optionals=getOptionalValues(a),this.fn=b,this.guard=c}}const h=Symbol();// https://github.com/airportyh/protomorphism class Protocol{constructor(a){function createFun(a){return function(...c){const d=c[0];let e=null;if(null===d&&this.hasImplementation(Symbol('null'))?e=this.registry.get(Symbol)[a]:b(d)&&this.hasImplementation(r.Integer)?e=this.registry.get(r.Integer)[a]:'number'==typeof d&&!b(d)&&this.hasImplementation(r.Float)?e=this.registry.get(r.Float)[a]:'string'==typeof d&&this.hasImplementation(r.BitString)?e=this.registry.get(r.BitString)[a]:d&&d instanceof Map&&d.has(Symbol.for('__struct__'))&&this.hasImplementation(d)?e=this.registry.get(d.get(Symbol.for('__struct__')).__MODULE__)[a]:null!==d&&this.hasImplementation(d)?e=this.registry.get(d.constructor)[a]:this.fallback&&(e=this.fallback[a]),null!=e){const a=e.apply(this,c);return a}throw new Error(`No implementation found for ${d}`)}}for(const b in this.registry=new Map,this.fallback=null,a)this[b]=createFun(b).bind(this)}implementation(a,b){null===a?this.fallback=b:this.registry.set(a,b)}hasImplementation(a){if(a===r.Integer||a===r.Float||a===r.BitString)return this.registry.has(a);return a&&a instanceof Map&&a.has(Symbol.for('__struct__'))?this.registry.has(a.get(Symbol.for('__struct__')).__MODULE__):this.registry.has(a.constructor)}}class Recurse{constructor(a){this.func=a}}var i={reverse,foreach:function foreach(a,b){return b.forEach((b)=>a(b)),Symbol.for('ok')},duplicate:function duplicate(a,b){const c=[];for(;c.length{if(d.get(c-1)a.get(c-1)?1:0})},keystore:function keystore(a,b,c,d){const e=[...c];for(let f=0;fa.toString()).join()},map:function map(a,b){return b.map((b)=>a(b))},filter:function filter(a,b){return b.filter((b)=>a(b))},filtermap:function filtermap(a,b){const c=[];for(const d of b){const b=a(d);!0===b?c.push(d):b instanceof e.Tuple&&!0===b.get(0)&&c.push(b.get(1))}return c},member:function member(a,b){for(const c of b)if(c===a)return!0;return!1},all:function all(a,b){for(const c of b)if(!1===a(c))return!1;return!0},any:function any(a,b){for(const c of b)if(!0===a(c))return!0;return!1},splitwith:function splitwith(a,b){let c=!1;const d=[],f=[];for(const e of b)!0==c?f.push(e):!0===a(e)?d.push(e):(c=!0,f.push(e));return new e.Tuple(d,f)},sort:function sort(...a){if(1===a.length){const b=[...a[0]];return b.sort()}const c=a[0],b=[...a[1]];return b.sort((d,a)=>{const b=c(d,a);return!0===b?-1:1})}},j={atom_to_binary,binary_to_atom,binary_to_existing_atom:function binary_to_existing_atom(a,b=Symbol.for('utf8')){return binary_to_atom(a,b)},list_concatenation:function list_concatenation(a,b){return a.concat(b)},list_subtraction:function list_subtraction(a,b){const c=[...a];for(const d of b){const a=c.indexOf(d);-1>b},bxor:function bxor(a,b){return a^b},bnot:function bnot(a){return~a},is_bitstring:is_bitstring$1,is_boolean:function is_boolean$1(a){return'boolean'==typeof a||a instanceof Boolean},is_float:function is_float(a){return is_number$1(a)&&!b(a)},is_function:function is_function$1(a){return'function'==typeof a||a instanceof Function},is_integer,is_list:function is_list(a){return Array.isArray(a)},is_map:function is_map$1(a){return a instanceof Map},is_number:is_number$1,is_pid:function is_pid(a){return a instanceof e.PID},is_port:function is_port(){return!1},is_reference:function is_reference(a){return a instanceof e.Reference},is_tuple:function is_tuple(a){return a instanceof e.Tuple},is_atom:function is_atom(a){return'symbol'==typeof a||a instanceof Symbol||a.__MODULE__},is_binary,element:function element(a,b){return b.get(a-1)},setelement:function setelement(a,b,c){const d=[...b.values];return d[a-1]=c,new e.Tuple(...d)},make_tuple:function make_tuple(a,b){const c=[];for(let d=0;d!0){let d=[],e=buildMatch(a);const f=e(b,d),[g,h]=checkNamedVariables(d);if(f&&h&&c.apply(this,g))return g;throw console.error('No match for:',b),new MatchError(b)},MatchError,variable:function variable(a=null,b=Symbol.for('tailored.no_value')){return new Variable(a,b)},wildcard:function wildcard(){return new Wildcard},startsWith:function startsWith(a){return new StartsWith(a)},capture:function capture(a){return new Capture(a)},headTail:function headTail(a,b){return new HeadTail(a,b)},type:function a(a,b={}){return new Type(a,b)},bound:function bound(a){return new Bound(a)},Clause,clause:function clause(a,b,c=()=>!0){return new Clause(a,b,c)},bitStringMatch:function bitStringMatch(...a){return new BitStringMatch(...a)},match_or_default,defmatchgen,list_comprehension:function list_comprehension(a,b){const c=run_generators(b.pop()(),b);let d=[];for(let e of c)a.guard.apply(this,e)&&d.push(a.fn.apply(this,e));return d},list_generator:function list_generator(a,b){return function(){let c=[];for(let d of b){const b=match_or_default(a,d,()=>!0,h);if(b!=h){const[a]=b;c.push(a)}}return c}},bitstring_generator:function bitstring_generator(a,b){return function(){let c=[],d=b.slice(0,a.byte_size()),e=1;for(;d.byte_size==a.byte_size();){const f=match_or_default(a,d,()=>!0,h);if(f!=h){c.push(f)}d=b.slice(a.byte_size()*e,a.byte_size()*(e+1)),e++}return c}},bitstring_comprehension:function bitstring_comprehension(a,b){const c=run_generators(b.pop()(),b);let d=[];for(let e of c)a.guard.apply(this,e)&&d.push(a.fn.apply(this,e));return d=d.map((a)=>e.BitString.integer(a)),new e.BitString(...d)},defmatchGen:function defmatchGen(...a){return defmatchgen(...a)},defmatchAsync:function defmatchAsync(...a){const b=getArityMap(a);return async function(...a){if(b.has(a.length)){const c=b.get(a.length);let d=null,e=null;for(let b of c){let c=[];a=fillInOptionalValues(a,b.arity,b.optionals);const f=b.pattern(a,c),[g,h]=checkNamedVariables(c);if(f&&h&&(await b.guard.apply(this,c))){d=b.fn,e=c;break}}if(!d)throw console.error('No match for:',a),new MatchError(a);return d.apply(this,e)}throw console.error('Arity of',a.length,'not found. No match for:',a),new MatchError(a)}}},Integer:class Integer{},Float:class Float{},Functions:{call_property:function call_property(a,b){if(!b)return a instanceof Function||'function'==typeof a?a():a;if(a instanceof Map){let c=null;if(a.has(b)?c=b:a.has(Symbol.for(b))&&(c=Symbol.for(b)),null===c)throw new Error(`Property ${b} not found in ${a}`);return a.get(c)instanceof Function||'function'==typeof a.get(c)?a.get(c)():a.get(c)}let c=null;if('number'==typeof a||'symbol'==typeof a||'boolean'==typeof a||'string'==typeof a?void 0===a[b]?void 0!==a[Symbol.for(b)]&&(c=Symbol.for(b)):c=b:b in a?c=b:Symbol.for(b)in a&&(c=Symbol.for(b)),null===c)throw new Error(`Property ${b} not found in ${a}`);return a[c]instanceof Function||'function'==typeof a[c]?a[c]():a[c]},defprotocol:function defprotocol(a){return new Protocol(a)},defimpl:function defimpl(a,b,c){a.implementation(b,c)},build_namespace:function build_namespace(a,b){let c=b.split('.');const d=a;let e=a;'Elixir'===c[0]&&(c=c.slice(1));for(const d of c)'undefined'==typeof e[d]&&(e[d]={}),e=e[d];return d.__table__=a.__table__||{},d.__table__[Symbol.for(b)]=e,e},iterator_to_reducer,map_to_object,trampoline:function trampoline$1(a){let b=a;for(;b&&b instanceof Recurse;)b=b.func();return b},Recurse},SpecialForms:{_case:function _case(a,b){return r.Patterns.defmatch(...b)(a)},cond:function cond(...a){for(const b of a)if(b[0])return b[1]();throw new Error},_for:function _for(a,b,c,d=[]){let[e,f]=c.into(d);const g=run_list_generators(b.pop()(),b);for(const h of g)a.guard.apply(this,h)&&(e=f(e,new r.Tuple(Symbol.for('cont'),a.fn.apply(this,h))));return f(e,Symbol.for('done'))},_try:function _try(a,b,c,d,e){let f=null;try{f=a()}catch(a){let d=null;if(b)try{return d=b(a),d}catch(a){if(a instanceof r.Patterns.MatchError)throw a}if(c)try{return d=c(a),d}catch(a){if(a instanceof r.Patterns.MatchError)throw a}throw a}finally{e&&e()}if(d)try{return d(f)}catch(a){if(a instanceof r.Patterns.MatchError)throw new Error('No Match Found in Else');throw a}else return f},_with:function _with(...a){let b=[],c=null,d=null;'function'==typeof a[a.length-2]?[c,d]=a.splice(-2):c=a.pop();for(let c=0;c{const[c,d]=b;return a.set(c,d),a},new Map)},keys:function keys(a){return!1===j.is_map(a)?new e.Tuple(m,a):Array.from(a.keys())},values:function values$1(a){return!1===j.is_map(a)?new e.Tuple(m,a):Array.from(a.values())},is_key,put:function put(a,b,c){if(!1===j.is_map(c))return new e.Tuple(m,c);const d=new Map(c);return d.set(a,b),d},merge:function merge(a,b){return!1===j.is_map(a)?new e.Tuple(m,a):!1===j.is_map(b)?new e.Tuple(m,b):new Map([...a,...b])},update:function update(a,b,c){return!1===j.is_map(c)?new e.Tuple(m,c):!1===is_key(a,c)?new e.Tuple(n,a):new Map([...c,[a,b]])},get:function get(...a){const b=a[0],c=a[1];return!1===j.is_map(c)?new e.Tuple(m,c):is_key(b)?c.get(b):3===a.length?a[2]:new e.Tuple(n,b)},take:function take(a,b){if(!1===j.is_map(b))return new e.Tuple(m,b);if(!is_key(a))return l;const c=b.get(a),d=new Map(b);return d.delete(a),new e.Tuple(c,d)}},lists:i,elixir_errors:{warn:function warn(a){const b=a.join('');return console.warn(`warning: ${b}`),Symbol.for('ok')}},io:{put_chars:function put_chars(a,b){const c=j.iolist_to_binary(b);return a===Symbol.for('stderr')?console.error(c):console.log(c),Symbol.for('ok')}},binary:{copy:function copy(a,b=1){return a.repeat(b)}},unicode:{characters_to_list:function characters_to_list(a){return a.split('').map((a)=>a.codePointAt(0))},characters_to_binary:function characters_to_binary(b){return j.is_binary(b)?b:a(...b)}},elixir_config:{new:function _new(a){return p.set(o,new Map),p.get(o).set(o,a),o},delete:function _delete(a){return p.delete(a),!0},put:put$1,get:get$1,update:function update$1(a,b){const c=b(p.get(o).get(a));return put$1(a,c),c},get_and_put:function get_and_put(a,b){const c=get$1(a);return put$1(a,b),c}}};return{Core:r}}(); From 508b9220cae0b45b3d0d9543a4eaabd7692187f2 Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Tue, 1 Aug 2017 21:55:56 -0500 Subject: [PATCH 203/418] Add more erlang compat functions from Kernel module --- priv/build/iife/ElixirScript.Core.js | 2721 ++++++++++++++++- .../lib/core/erlang_compat/binary.js | 9 +- .../lib/core/erlang_compat/erlang.js | 67 +- 3 files changed, 2789 insertions(+), 8 deletions(-) diff --git a/priv/build/iife/ElixirScript.Core.js b/priv/build/iife/ElixirScript.Core.js index a0c0b537..6253bea7 100644 --- a/priv/build/iife/ElixirScript.Core.js +++ b/priv/build/iife/ElixirScript.Core.js @@ -1,6 +1,2715 @@ -var ElixirScript=function(){'use strict';/* @flow */function namedVariableResult(a,b){return new NamedVariableResult(a,b)}/* @flow */function is_number(a){return'number'==typeof a}function is_string(a){return'string'==typeof a}function is_boolean(a){return'boolean'==typeof a}function is_symbol(a){return'symbol'==typeof a}function is_object(a){return'object'==typeof a}function is_variable(a){return a instanceof Variable}function is_null(a){return null===a}function is_array(a){return Array.isArray(a)}function is_function(a){return'[object Function]'==Object.prototype.toString.call(a)}function is_map(a){return a instanceof Map}function resolveNull(){return function(a){return is_null(a)}}function resolveWildcard(){return function(){return!0}}function resolveObject(a){let b={};const c=Object.keys(a).concat(Object.getOwnPropertySymbols(a));for(let d of c)b[d]=buildMatch(a[d]);return function(d,e){if(!is_object(d)||a.length>d.length)return!1;for(let a of c)if(!(a in d)||!b[a](d[a],e))return!1;return!0}}function getSize(a,b){return a*b/8}function arraysEqual(c,a){if(c===a)return!0;if(null==c||null==a)return!1;if(c.length!=a.length)return!1;for(var b=0;bf.integer(a));return new f(...b)}function resolveNoMatch(){return function(){return!1}}function buildMatch(a){if(null===a)return resolveNull(a);if('undefined'==typeof a)return resolveWildcard(a);const b=a.constructor.prototype,c=g.get(b);return c?c(a):'object'==typeof a?resolveObject(a):resolveNoMatch()}function defmatchgen(...a){const b=getArityMap(a);return function*(...a){let[c,d]=findMatchingFunction(a,b);return yield*c.apply(this,d)}}function findMatchingFunction(a,b){if(b.has(a.length)){const c=b.get(a.length);let d=null,e=null;for(let b of c){let c=[];a=fillInOptionalValues(a,b.arity,b.optionals);const f=b.pattern(a,c),[g,h]=checkNamedVariables(c);if(f&&h&&b.guard.apply(this,g)){d=b.fn,e=g;break}}if(!d)throw console.error('No match for:',a),new MatchError(a);return[d,e]}throw console.error('Arity of',a.length,'not found. No match for:',a),new MatchError(a)}function getArityMap(a){let b=new Map;for(const c of a){const a=getArityRange(c);for(const d of a){let a=[];b.has(d)&&(a=b.get(d)),a.push(c),b.set(d,a)}}return b}function getArityRange(a){const b=a.arity-a.optionals.length,c=a.arity;let d=[b];for(;d[d.length-1]!=c;)d.push(d[d.length-1]+1);return d}function getOptionalValues(a){let b=[];for(let c=0;c!0,d=null){let e=[],f=buildMatch(a);const g=f(b,e),[h,i]=checkNamedVariables(e);return g&&i&&c.apply(this,h)?h:d}function run_generators(a,b){if(0==b.length)return a.map((a)=>{return Array.isArray(a)?a:[a]});const c=b.pop();let d=[];for(let e of c())for(let b of a)d.push([e].concat(b));return run_generators(d,b)}function iterator_to_reducer(a,b,c){const d=a[Symbol.iterator]();let e=d.next(),f=b;for(;!1===e.done;){if(f=c(e.value,f.get(1)),f.get(0)===Symbol.for('halt'))return new r.Tuple(Symbol.for('halted'),f.get(1));if(f.get(0)===Symbol.for('suspend'))return new r.Tuple(Symbol.for('suspended'),f.get(1),(a)=>{return iterator_to_reducer(d,a,c)});e=d.next()}return new r.Tuple(Symbol.for('done'),f.get(1))}function map_to_object(a){const b={};for(const[c,d]of a.entries())b[c]=d instanceof Map?map_to_object(d):d;return b}function run_list_generators(a,b){if(0==b.length)return a.map((a)=>{return Array.isArray(a)?a:[a]});const c=b.pop(),d=[];for(const e of c())for(const b of a)d.push([e].concat(b));return run_list_generators(d,b)}// http://erlang.org/doc/man/lists.html -function reverse(a){return[...a]}function flatten(a,b=[]){const c=a.reduce((a,b)=>{return Array.isArray(b)?a.concat(flatten(b)):a.concat(b)},[]);return c.concat(b)}function foldl(a,b,c){return c.reduce((b,c)=>{return a(c,b)},b)}function keyfind(a,b,c){for(const d of c)if(d.get(b-1)===a)return d;return!1}function keydelete(a,b,c){const d=[];let e=!1;for(let f=0;f{if(null===c)return b;return is_integer(c)?b+a(c):is_bitstring$1(c)?b+a(...c.value):b+iolist_to_binary(c)},'');return d}function is_key(a,b){return b.has(a)}function put$1(a,b){return p.get(o).set(a,b),Symbol.for('ok')}function get$1(a){return p.get(o).get(a)}function get_key(a){let b=a;if(__elixirscript_names__.has(a)&&(b=__elixirscript_names__.get(a)),__elixirscript_store__.has(b))return b;throw new Error(`Key ${b} not found`)}var a=String.fromCodePoint,b=Number.isInteger;class Variable{constructor(a=null,b=Symbol.for('tailored.no_value')){this.name=a,this.default_value=b}}class Wildcard{constructor(){}}class StartsWith{constructor(a){this.prefix=a}}class Capture{constructor(a){this.value=a}}class HeadTail{constructor(a,b){this.head=a,this.tail=b}}class Type{constructor(a,b={}){this.type=a,this.objPattern=b}}class Bound{constructor(a){this.value=a}}class BitStringMatch{constructor(...a){this.values=a}length(){return values.length}bit_size(){return 8*this.byte_size()}byte_size(){let a=0;for(let b of this.values)a+=b.unit*b.size/8;return a}getValue(a){return this.values(a)}getSizeOfValue(a){let b=this.getValue(a);return b.unit*b.size}getTypeOfValue(a){return this.getValue(a).type}}class NamedVariableResult{constructor(a,b){this.name=a,this.value=b}}class Tuple{constructor(...a){this.values=Object.freeze(a),this.length=this.values.length}get(a){return this.values[a]}count(){return this.values.length}[Symbol.iterator](){return this.values[Symbol.iterator]()}toString(){let a,b='';for(a=0;aBitString$1.integer(a));return new BitString$1(...d)}[Symbol.iterator](){return this.value[Symbol.iterator]()}toString(){var a,b='';for(a=0;a>'}process(a){let b=[];var c;for(c=0;cb?c.push(b):2048>b?c.push(192|b>>6,128|63&b):55296>b||57344<=b?c.push(224|b>>12,128|63&b>>6,128|63&b):(d++,b=65536+((1023&b)<<10|1023&a.charCodeAt(d)),c.push(240|b>>18,128|63&b>>12,128|63&b>>6,128|63&b));return c}static toUTF16Array(a){for(var b,c=[],d=0;d=b?(c.push(0),c.push(b)):(c.push(255&b>>8),c.push(255&b));return c}static toUTF32Array(a){for(var b,c=[],d=0;d=b?(c.push(0),c.push(0),c.push(0),c.push(b)):(c.push(0),c.push(0),c.push(255&b>>8),c.push(255&b));return c}//http://stackoverflow.com/questions/2003493/javascript-float-from-to-bits -static float32ToBytes(a){var b=[],c=new ArrayBuffer(4);new Float32Array(c)[0]=a;let d=new Uint32Array(c)[0];return b.push(255&d>>24),b.push(255&d>>16),b.push(255&d>>8),b.push(255&d),b}static float64ToBytes(a){var b=[],c=new ArrayBuffer(8);new Float64Array(c)[0]=a;var d=new Uint32Array(c)[0],e=new Uint32Array(c)[1];return b.push(255&e>>24),b.push(255&e>>16),b.push(255&e>>8),b.push(255&e),b.push(255&d>>24),b.push(255&d>>16),b.push(255&d>>8),b.push(255&d),b}}var e={Tuple,PID:class PID{constructor(){++c,this.id=c}toString(){return'PID#<0.'+this.id+'.0>'}},Reference:class Reference{constructor(){++d,this.id=d,this.ref=Symbol()}toString(){return'Ref#<0.0.0.'+this.id+'>'}},BitString:BitString$1};/* @flow */const f=e.BitString,g=new Map;g.set(Variable.prototype,function resolveVariable(a){return function(b,c){return null===a.name?c.push(b):!a.name.startsWith('_')&&c.push(namedVariableResult(a.name,b)),!0}}),g.set(Wildcard.prototype,resolveWildcard),g.set(HeadTail.prototype,function resolveHeadTail(a){const b=buildMatch(a.head),c=buildMatch(a.tail);return function(a,d){if(!is_array(a)||0===a.length)return!1;const e=a[0],f=a.slice(1);return b(e,d)&&c(f,d)}}),g.set(StartsWith.prototype,function resolveStartsWith(a){const b=a.prefix;return function(a,c){return is_string(a)&&a.startsWith(b)&&(c.push(a.substring(b.length)),!0)}}),g.set(Capture.prototype,function resolveCapture(a){const b=buildMatch(a.value);return function(a,c){return!!b(a,c)&&(c.push(a),!0)}}),g.set(Bound.prototype,function resolveBound(a){return function(b){return typeof b==typeof a.value&&b===a.value}}),g.set(Type.prototype,function resolveType(a){return function(b,c){if(b instanceof a.type){const d=buildMatch(a.objPattern);return d(b,c)}return!1}}),g.set(BitStringMatch.prototype,function resolveBitString(a){let b=[];for(let c of a.values)if(is_variable(c.value)){let a=getSize(c.unit,c.size);fillArray(b,a)}else b=b.concat(new f(c).value);let c=a.values;return function(a,d){var e=String.fromCharCode;let g=null;if(!is_string(a)&&!(a instanceof f))return!1;g=is_string(a)?new f(f.binary(a)):a;let h=0;for(let f,j=0;jd.size)return!1;for(let a of c)if(!d.has(a)||!b.get(a)(d.get(a),e))return!1;return!0}}),g.set(Array.prototype,function resolveArray(a){const b=a.map((a)=>buildMatch(a));return function(c,d){return is_array(c)&&c.length==a.length&&c.every(function(a,e){return b[e](c[e],d)})}}),g.set(String.prototype,function resolveString(a){return function(b){return is_string(b)&&b===a}}),g.set(Boolean.prototype,function resolveBoolean(a){return function(b){return is_boolean(b)&&b===a}}),g.set(Function.prototype,function resolveFunction(a){return function(b){return is_function(b)&&b===a}}),g.set(Object.prototype,resolveObject);class MatchError extends Error{constructor(a){if(super(),'symbol'==typeof a)this.message='No match for: '+a.toString();else if(Array.isArray(a)){let b=a.map((a)=>{return null===a?'null':'undefined'==typeof a?'undefined':a.toString()});this.message='No match for: '+b}else this.message='No match for: '+a;this.stack=new Error().stack,this.name=this.constructor.name}}class Clause{constructor(a,b,c=()=>!0){this.pattern=buildMatch(a),this.arity=a.length,this.optionals=getOptionalValues(a),this.fn=b,this.guard=c}}const h=Symbol();// https://github.com/airportyh/protomorphism -class Protocol{constructor(a){function createFun(a){return function(...c){const d=c[0];let e=null;if(null===d&&this.hasImplementation(Symbol('null'))?e=this.registry.get(Symbol)[a]:b(d)&&this.hasImplementation(r.Integer)?e=this.registry.get(r.Integer)[a]:'number'==typeof d&&!b(d)&&this.hasImplementation(r.Float)?e=this.registry.get(r.Float)[a]:'string'==typeof d&&this.hasImplementation(r.BitString)?e=this.registry.get(r.BitString)[a]:d&&d instanceof Map&&d.has(Symbol.for('__struct__'))&&this.hasImplementation(d)?e=this.registry.get(d.get(Symbol.for('__struct__')).__MODULE__)[a]:null!==d&&this.hasImplementation(d)?e=this.registry.get(d.constructor)[a]:this.fallback&&(e=this.fallback[a]),null!=e){const a=e.apply(this,c);return a}throw new Error(`No implementation found for ${d}`)}}for(const b in this.registry=new Map,this.fallback=null,a)this[b]=createFun(b).bind(this)}implementation(a,b){null===a?this.fallback=b:this.registry.set(a,b)}hasImplementation(a){if(a===r.Integer||a===r.Float||a===r.BitString)return this.registry.has(a);return a&&a instanceof Map&&a.has(Symbol.for('__struct__'))?this.registry.has(a.get(Symbol.for('__struct__')).__MODULE__):this.registry.has(a.constructor)}}class Recurse{constructor(a){this.func=a}}var i={reverse,foreach:function foreach(a,b){return b.forEach((b)=>a(b)),Symbol.for('ok')},duplicate:function duplicate(a,b){const c=[];for(;c.length{if(d.get(c-1)a.get(c-1)?1:0})},keystore:function keystore(a,b,c,d){const e=[...c];for(let f=0;fa.toString()).join()},map:function map(a,b){return b.map((b)=>a(b))},filter:function filter(a,b){return b.filter((b)=>a(b))},filtermap:function filtermap(a,b){const c=[];for(const d of b){const b=a(d);!0===b?c.push(d):b instanceof e.Tuple&&!0===b.get(0)&&c.push(b.get(1))}return c},member:function member(a,b){for(const c of b)if(c===a)return!0;return!1},all:function all(a,b){for(const c of b)if(!1===a(c))return!1;return!0},any:function any(a,b){for(const c of b)if(!0===a(c))return!0;return!1},splitwith:function splitwith(a,b){let c=!1;const d=[],f=[];for(const e of b)!0==c?f.push(e):!0===a(e)?d.push(e):(c=!0,f.push(e));return new e.Tuple(d,f)},sort:function sort(...a){if(1===a.length){const b=[...a[0]];return b.sort()}const c=a[0],b=[...a[1]];return b.sort((d,a)=>{const b=c(d,a);return!0===b?-1:1})}},j={atom_to_binary,binary_to_atom,binary_to_existing_atom:function binary_to_existing_atom(a,b=Symbol.for('utf8')){return binary_to_atom(a,b)},list_concatenation:function list_concatenation(a,b){return a.concat(b)},list_subtraction:function list_subtraction(a,b){const c=[...a];for(const d of b){const a=c.indexOf(d);-1>b},bxor:function bxor(a,b){return a^b},bnot:function bnot(a){return~a},is_bitstring:is_bitstring$1,is_boolean:function is_boolean$1(a){return'boolean'==typeof a||a instanceof Boolean},is_float:function is_float(a){return is_number$1(a)&&!b(a)},is_function:function is_function$1(a){return'function'==typeof a||a instanceof Function},is_integer,is_list:function is_list(a){return Array.isArray(a)},is_map:function is_map$1(a){return a instanceof Map},is_number:is_number$1,is_pid:function is_pid(a){return a instanceof e.PID},is_port:function is_port(){return!1},is_reference:function is_reference(a){return a instanceof e.Reference},is_tuple:function is_tuple(a){return a instanceof e.Tuple},is_atom:function is_atom(a){return'symbol'==typeof a||a instanceof Symbol||a.__MODULE__},is_binary,element:function element(a,b){return b.get(a-1)},setelement:function setelement(a,b,c){const d=[...b.values];return d[a-1]=c,new e.Tuple(...d)},make_tuple:function make_tuple(a,b){const c=[];for(let d=0;d!0){let d=[],e=buildMatch(a);const f=e(b,d),[g,h]=checkNamedVariables(d);if(f&&h&&c.apply(this,g))return g;throw console.error('No match for:',b),new MatchError(b)},MatchError,variable:function variable(a=null,b=Symbol.for('tailored.no_value')){return new Variable(a,b)},wildcard:function wildcard(){return new Wildcard},startsWith:function startsWith(a){return new StartsWith(a)},capture:function capture(a){return new Capture(a)},headTail:function headTail(a,b){return new HeadTail(a,b)},type:function a(a,b={}){return new Type(a,b)},bound:function bound(a){return new Bound(a)},Clause,clause:function clause(a,b,c=()=>!0){return new Clause(a,b,c)},bitStringMatch:function bitStringMatch(...a){return new BitStringMatch(...a)},match_or_default,defmatchgen,list_comprehension:function list_comprehension(a,b){const c=run_generators(b.pop()(),b);let d=[];for(let e of c)a.guard.apply(this,e)&&d.push(a.fn.apply(this,e));return d},list_generator:function list_generator(a,b){return function(){let c=[];for(let d of b){const b=match_or_default(a,d,()=>!0,h);if(b!=h){const[a]=b;c.push(a)}}return c}},bitstring_generator:function bitstring_generator(a,b){return function(){let c=[],d=b.slice(0,a.byte_size()),e=1;for(;d.byte_size==a.byte_size();){const f=match_or_default(a,d,()=>!0,h);if(f!=h){c.push(f)}d=b.slice(a.byte_size()*e,a.byte_size()*(e+1)),e++}return c}},bitstring_comprehension:function bitstring_comprehension(a,b){const c=run_generators(b.pop()(),b);let d=[];for(let e of c)a.guard.apply(this,e)&&d.push(a.fn.apply(this,e));return d=d.map((a)=>e.BitString.integer(a)),new e.BitString(...d)},defmatchGen:function defmatchGen(...a){return defmatchgen(...a)},defmatchAsync:function defmatchAsync(...a){const b=getArityMap(a);return async function(...a){if(b.has(a.length)){const c=b.get(a.length);let d=null,e=null;for(let b of c){let c=[];a=fillInOptionalValues(a,b.arity,b.optionals);const f=b.pattern(a,c),[g,h]=checkNamedVariables(c);if(f&&h&&(await b.guard.apply(this,c))){d=b.fn,e=c;break}}if(!d)throw console.error('No match for:',a),new MatchError(a);return d.apply(this,e)}throw console.error('Arity of',a.length,'not found. No match for:',a),new MatchError(a)}}},Integer:class Integer{},Float:class Float{},Functions:{call_property:function call_property(a,b){if(!b)return a instanceof Function||'function'==typeof a?a():a;if(a instanceof Map){let c=null;if(a.has(b)?c=b:a.has(Symbol.for(b))&&(c=Symbol.for(b)),null===c)throw new Error(`Property ${b} not found in ${a}`);return a.get(c)instanceof Function||'function'==typeof a.get(c)?a.get(c)():a.get(c)}let c=null;if('number'==typeof a||'symbol'==typeof a||'boolean'==typeof a||'string'==typeof a?void 0===a[b]?void 0!==a[Symbol.for(b)]&&(c=Symbol.for(b)):c=b:b in a?c=b:Symbol.for(b)in a&&(c=Symbol.for(b)),null===c)throw new Error(`Property ${b} not found in ${a}`);return a[c]instanceof Function||'function'==typeof a[c]?a[c]():a[c]},defprotocol:function defprotocol(a){return new Protocol(a)},defimpl:function defimpl(a,b,c){a.implementation(b,c)},build_namespace:function build_namespace(a,b){let c=b.split('.');const d=a;let e=a;'Elixir'===c[0]&&(c=c.slice(1));for(const d of c)'undefined'==typeof e[d]&&(e[d]={}),e=e[d];return d.__table__=a.__table__||{},d.__table__[Symbol.for(b)]=e,e},iterator_to_reducer,map_to_object,trampoline:function trampoline$1(a){let b=a;for(;b&&b instanceof Recurse;)b=b.func();return b},Recurse},SpecialForms:{_case:function _case(a,b){return r.Patterns.defmatch(...b)(a)},cond:function cond(...a){for(const b of a)if(b[0])return b[1]();throw new Error},_for:function _for(a,b,c,d=[]){let[e,f]=c.into(d);const g=run_list_generators(b.pop()(),b);for(const h of g)a.guard.apply(this,h)&&(e=f(e,new r.Tuple(Symbol.for('cont'),a.fn.apply(this,h))));return f(e,Symbol.for('done'))},_try:function _try(a,b,c,d,e){let f=null;try{f=a()}catch(a){let d=null;if(b)try{return d=b(a),d}catch(a){if(a instanceof r.Patterns.MatchError)throw a}if(c)try{return d=c(a),d}catch(a){if(a instanceof r.Patterns.MatchError)throw a}throw a}finally{e&&e()}if(d)try{return d(f)}catch(a){if(a instanceof r.Patterns.MatchError)throw new Error('No Match Found in Else');throw a}else return f},_with:function _with(...a){let b=[],c=null,d=null;'function'==typeof a[a.length-2]?[c,d]=a.splice(-2):c=a.pop();for(let c=0;c{const[c,d]=b;return a.set(c,d),a},new Map)},keys:function keys(a){return!1===j.is_map(a)?new e.Tuple(m,a):Array.from(a.keys())},values:function values$1(a){return!1===j.is_map(a)?new e.Tuple(m,a):Array.from(a.values())},is_key,put:function put(a,b,c){if(!1===j.is_map(c))return new e.Tuple(m,c);const d=new Map(c);return d.set(a,b),d},merge:function merge(a,b){return!1===j.is_map(a)?new e.Tuple(m,a):!1===j.is_map(b)?new e.Tuple(m,b):new Map([...a,...b])},update:function update(a,b,c){return!1===j.is_map(c)?new e.Tuple(m,c):!1===is_key(a,c)?new e.Tuple(n,a):new Map([...c,[a,b]])},get:function get(...a){const b=a[0],c=a[1];return!1===j.is_map(c)?new e.Tuple(m,c):is_key(b)?c.get(b):3===a.length?a[2]:new e.Tuple(n,b)},take:function take(a,b){if(!1===j.is_map(b))return new e.Tuple(m,b);if(!is_key(a))return l;const c=b.get(a),d=new Map(b);return d.delete(a),new e.Tuple(c,d)}},lists:i,elixir_errors:{warn:function warn(a){const b=a.join('');return console.warn(`warning: ${b}`),Symbol.for('ok')}},io:{put_chars:function put_chars(a,b){const c=j.iolist_to_binary(b);return a===Symbol.for('stderr')?console.error(c):console.log(c),Symbol.for('ok')}},binary:{copy:function copy(a,b=1){return a.repeat(b)}},unicode:{characters_to_list:function characters_to_list(a){return a.split('').map((a)=>a.codePointAt(0))},characters_to_binary:function characters_to_binary(b){return j.is_binary(b)?b:a(...b)}},elixir_config:{new:function _new(a){return p.set(o,new Map),p.get(o).set(o,a),o},delete:function _delete(a){return p.delete(a),!0},put:put$1,get:get$1,update:function update$1(a,b){const c=b(p.get(o).get(a));return put$1(a,c),c},get_and_put:function get_and_put(a,b){const c=get$1(a);return put$1(a,b),c}}};return{Core:r}}(); +var ElixirScript = (function () { +'use strict'; + +/* @flow */ + +class Variable { + constructor(name = null, default_value = Symbol.for('tailored.no_value')) { + this.name = name; + this.default_value = default_value; + } +} + +class Wildcard { + constructor() {} +} + +class StartsWith { + constructor(prefix) { + this.prefix = prefix; + } +} + +class Capture { + constructor(value) { + this.value = value; + } +} + +class HeadTail { + constructor(head, tail) { + this.head = head; + this.tail = tail; + } +} + +class Type { + constructor(type, objPattern = {}) { + this.type = type; + this.objPattern = objPattern; + } +} + +class Bound { + constructor(value) { + this.value = value; + } +} + +class BitStringMatch { + constructor(...values) { + this.values = values; + } + + length() { + return values.length; + } + + bit_size() { + return this.byte_size() * 8; + } + + byte_size() { + let s = 0; + + for (let val of this.values) { + s = s + val.unit * val.size / 8; + } + + return s; + } + + getValue(index) { + return this.values(index); + } + + getSizeOfValue(index) { + let val = this.getValue(index); + return val.unit * val.size; + } + + getTypeOfValue(index) { + return this.getValue(index).type; + } +} + +class NamedVariableResult { + constructor(name, value) { + this.name = name; + this.value = value; + } +} + +function variable(name = null, default_value = Symbol.for('tailored.no_value')) { + return new Variable(name, default_value); +} + +function wildcard() { + return new Wildcard(); +} + +function startsWith(prefix) { + return new StartsWith(prefix); +} + +function capture(value) { + return new Capture(value); +} + +function headTail(head, tail) { + return new HeadTail(head, tail); +} + +function type(type, objPattern = {}) { + return new Type(type, objPattern); +} + +function bound(value) { + return new Bound(value); +} + +function bitStringMatch(...values) { + return new BitStringMatch(...values); +} + +function namedVariableResult(name, value) { + return new NamedVariableResult(name, value); +} + +/* @flow */ + +function is_number(value) { + return typeof value === 'number'; +} + +function is_string(value) { + return typeof value === 'string'; +} + +function is_boolean(value) { + return typeof value === 'boolean'; +} + +function is_symbol(value) { + return typeof value === 'symbol'; +} + +function is_object(value) { + return typeof value === 'object'; +} + +function is_variable(value) { + return value instanceof Variable; +} + +function is_null(value) { + return value === null; +} + +function is_array(value) { + return Array.isArray(value); +} + +function is_function(value) { + return Object.prototype.toString.call(value) == '[object Function]'; +} + +function is_map(value) { + return value instanceof Map; +} + +class Tuple { + constructor(...args) { + this.values = Object.freeze(args); + this.length = this.values.length; + } + + get(index) { + return this.values[index]; + } + + count() { + return this.values.length; + } + + [Symbol.iterator]() { + return this.values[Symbol.iterator](); + } + + toString() { + let i, + s = ''; + for (i = 0; i < this.values.length; i++) { + if (s !== '') { + s += ', '; + } + + const stringToAppend = this.values[i] ? this.values[i].toString() : ''; + + s += stringToAppend; + } + + return '{' + s + '}'; + } + + put_elem(index, elem) { + if (index === this.length) { + let new_values = this.values.concat([elem]); + return new Tuple(...new_values); + } + + let new_values = this.values.concat([]); + new_values.splice(index, 0, elem); + return new Tuple(...new_values); + } + + remove_elem(index) { + let new_values = this.values.concat([]); + new_values.splice(index, 1); + return new Tuple(...new_values); + } +} + +let process_counter = -1; + +class PID { + constructor() { + process_counter = process_counter + 1; + this.id = process_counter; + } + + toString() { + return 'PID#<0.' + this.id + '.0>'; + } +} + +let ref_counter = -1; + +class Reference { + constructor() { + ref_counter = ref_counter + 1; + this.id = ref_counter; + this.ref = Symbol(); + } + + toString() { + return 'Ref#<0.0.0.' + this.id + '>'; + } +} + +class BitString$1 { + constructor(...args) { + this.value = Object.freeze(this.process(args)); + this.length = this.value.length; + this.bit_size = this.length * 8; + this.byte_size = this.length; + } + + get(index) { + return this.value[index]; + } + + count() { + return this.value.length; + } + + slice(start, end = null) { + let s = this.value.slice(start, end); + let ms = s.map(elem => BitString$1.integer(elem)); + return new BitString$1(...ms); + } + + [Symbol.iterator]() { + return this.value[Symbol.iterator](); + } + + toString() { + var i, + s = ''; + for (i = 0; i < this.count(); i++) { + if (s !== '') { + s += ', '; + } + s += this.get(i).toString(); + } + + return '<<' + s + '>>'; + } + + process(bitStringParts) { + let processed_values = []; + + var i; + for (i = 0; i < bitStringParts.length; i++) { + let processed_value = this['process_' + bitStringParts[i].type](bitStringParts[i]); + + for (let attr of bitStringParts[i].attributes) { + processed_value = this['process_' + attr](processed_value); + } + + processed_values = processed_values.concat(processed_value); + } + + return processed_values; + } + + process_integer(value) { + return value.value; + } + + process_float(value) { + if (value.size === 64) { + return BitString$1.float64ToBytes(value.value); + } else if (value.size === 32) { + return BitString$1.float32ToBytes(value.value); + } + + throw new Error('Invalid size for float'); + } + + process_bitstring(value) { + return value.value.value; + } + + process_binary(value) { + return BitString$1.toUTF8Array(value.value); + } + + process_utf8(value) { + return BitString$1.toUTF8Array(value.value); + } + + process_utf16(value) { + return BitString$1.toUTF16Array(value.value); + } + + process_utf32(value) { + return BitString$1.toUTF32Array(value.value); + } + + process_signed(value) { + return new Uint8Array([value])[0]; + } + + process_unsigned(value) { + return value; + } + + process_native(value) { + return value; + } + + process_big(value) { + return value; + } + + process_little(value) { + return value.reverse(); + } + + process_size(value) { + return value; + } + + process_unit(value) { + return value; + } + + static integer(value) { + return BitString$1.wrap(value, { type: 'integer', unit: 1, size: 8 }); + } + + static float(value) { + return BitString$1.wrap(value, { type: 'float', unit: 1, size: 64 }); + } + + static bitstring(value) { + return BitString$1.wrap(value, { + type: 'bitstring', + unit: 1, + size: value.bit_size + }); + } + + static bits(value) { + return BitString$1.bitstring(value); + } + + static binary(value) { + return BitString$1.wrap(value, { + type: 'binary', + unit: 8, + size: value.length + }); + } + + static bytes(value) { + return BitString$1.binary(value); + } + + static utf8(value) { + return BitString$1.wrap(value, { type: 'utf8', unit: 1, size: value.length }); + } + + static utf16(value) { + return BitString$1.wrap(value, { + type: 'utf16', + unit: 1, + size: value.length * 2 + }); + } + + static utf32(value) { + return BitString$1.wrap(value, { + type: 'utf32', + unit: 1, + size: value.length * 4 + }); + } + + static signed(value) { + return BitString$1.wrap(value, {}, 'signed'); + } + + static unsigned(value) { + return BitString$1.wrap(value, {}, 'unsigned'); + } + + static native(value) { + return BitString$1.wrap(value, {}, 'native'); + } + + static big(value) { + return BitString$1.wrap(value, {}, 'big'); + } + + static little(value) { + return BitString$1.wrap(value, {}, 'little'); + } + + static size(value, count) { + return BitString$1.wrap(value, { size: count }); + } + + static unit(value, count) { + return BitString$1.wrap(value, { unit: count }); + } + + static wrap(value, opt, new_attribute = null) { + let the_value = value; + + if (!(value instanceof Object)) { + the_value = { value: value, attributes: [] }; + } + + the_value = Object.assign(the_value, opt); + + if (new_attribute) { + the_value.attributes.push(new_attribute); + } + + return the_value; + } + + static toUTF8Array(str) { + var utf8 = []; + for (var i = 0; i < str.length; i++) { + var charcode = str.charCodeAt(i); + if (charcode < 0x80) { + utf8.push(charcode); + } else if (charcode < 0x800) { + utf8.push(0xc0 | charcode >> 6, 0x80 | charcode & 0x3f); + } else if (charcode < 0xd800 || charcode >= 0xe000) { + utf8.push(0xe0 | charcode >> 12, 0x80 | charcode >> 6 & 0x3f, 0x80 | charcode & 0x3f); + } else { + // surrogate pair + i++; + // UTF-16 encodes 0x10000-0x10FFFF by + // subtracting 0x10000 and splitting the + // 20 bits of 0x0-0xFFFFF into two halves + charcode = 0x10000 + ((charcode & 0x3ff) << 10 | str.charCodeAt(i) & 0x3ff); + utf8.push(0xf0 | charcode >> 18, 0x80 | charcode >> 12 & 0x3f, 0x80 | charcode >> 6 & 0x3f, 0x80 | charcode & 0x3f); + } + } + return utf8; + } + + static toUTF16Array(str) { + var utf16 = []; + for (var i = 0; i < str.length; i++) { + var codePoint = str.codePointAt(i); + + if (codePoint <= 255) { + utf16.push(0); + utf16.push(codePoint); + } else { + utf16.push(codePoint >> 8 & 0xff); + utf16.push(codePoint & 0xff); + } + } + return utf16; + } + + static toUTF32Array(str) { + var utf32 = []; + for (var i = 0; i < str.length; i++) { + var codePoint = str.codePointAt(i); + + if (codePoint <= 255) { + utf32.push(0); + utf32.push(0); + utf32.push(0); + utf32.push(codePoint); + } else { + utf32.push(0); + utf32.push(0); + utf32.push(codePoint >> 8 & 0xff); + utf32.push(codePoint & 0xff); + } + } + return utf32; + } + + //http://stackoverflow.com/questions/2003493/javascript-float-from-to-bits + static float32ToBytes(f) { + var bytes = []; + + var buf = new ArrayBuffer(4); + new Float32Array(buf)[0] = f; + + let intVersion = new Uint32Array(buf)[0]; + + bytes.push(intVersion >> 24 & 0xff); + bytes.push(intVersion >> 16 & 0xff); + bytes.push(intVersion >> 8 & 0xff); + bytes.push(intVersion & 0xff); + + return bytes; + } + + static float64ToBytes(f) { + var bytes = []; + + var buf = new ArrayBuffer(8); + new Float64Array(buf)[0] = f; + + var intVersion1 = new Uint32Array(buf)[0]; + var intVersion2 = new Uint32Array(buf)[1]; + + bytes.push(intVersion2 >> 24 & 0xff); + bytes.push(intVersion2 >> 16 & 0xff); + bytes.push(intVersion2 >> 8 & 0xff); + bytes.push(intVersion2 & 0xff); + + bytes.push(intVersion1 >> 24 & 0xff); + bytes.push(intVersion1 >> 16 & 0xff); + bytes.push(intVersion1 >> 8 & 0xff); + bytes.push(intVersion1 & 0xff); + + return bytes; + } +} + +var ErlangTypes = { + Tuple, + PID, + Reference, + BitString: BitString$1 +}; + +/* @flow */ + +const BitString = ErlangTypes.BitString; + +function resolveSymbol(pattern) { + return function (value) { + return is_symbol(value) && value === pattern; + }; +} + +function resolveString(pattern) { + return function (value) { + return is_string(value) && value === pattern; + }; +} + +function resolveNumber(pattern) { + return function (value) { + return is_number(value) && value === pattern; + }; +} + +function resolveBoolean(pattern) { + return function (value) { + return is_boolean(value) && value === pattern; + }; +} + +function resolveFunction(pattern) { + return function (value) { + return is_function(value) && value === pattern; + }; +} + +function resolveNull(pattern) { + return function (value) { + return is_null(value); + }; +} + +function resolveBound(pattern) { + return function (value, args) { + if (typeof value === typeof pattern.value && value === pattern.value) { + return true; + } + + return false; + }; +} + +function resolveWildcard() { + return function () { + return true; + }; +} + +function resolveVariable(pattern) { + return function (value, args) { + if (pattern.name === null) { + args.push(value); + } else if (!pattern.name.startsWith('_')) { + args.push(namedVariableResult(pattern.name, value)); + } + + return true; + }; +} + +function resolveHeadTail(pattern) { + const headMatches = buildMatch(pattern.head); + const tailMatches = buildMatch(pattern.tail); + + return function (value, args) { + if (!is_array(value) || value.length === 0) { + return false; + } + + const head = value[0]; + const tail = value.slice(1); + + if (headMatches(head, args) && tailMatches(tail, args)) { + return true; + } + + return false; + }; +} + +function resolveCapture(pattern) { + const matches = buildMatch(pattern.value); + + return function (value, args) { + if (matches(value, args)) { + args.push(value); + return true; + } + + return false; + }; +} + +function resolveStartsWith(pattern) { + const prefix = pattern.prefix; + + return function (value, args) { + if (is_string(value) && value.startsWith(prefix)) { + args.push(value.substring(prefix.length)); + return true; + } + + return false; + }; +} + +function resolveType(pattern) { + return function (value, args) { + if (value instanceof pattern.type) { + const matches = buildMatch(pattern.objPattern); + return matches(value, args); + } + + return false; + }; +} + +function resolveArray(pattern) { + const matches = pattern.map(x => buildMatch(x)); + + return function (value, args) { + if (!is_array(value) || value.length != pattern.length) { + return false; + } + + return value.every(function (v, i) { + return matches[i](value[i], args); + }); + }; +} + +function resolveMap(pattern) { + let matches = new Map(); + + const keys = Array.from(pattern.keys()); + + for (let key of keys) { + matches.set(key, buildMatch(pattern.get(key))); + } + + return function (value, args) { + if (!is_map(value) || pattern.size > value.size) { + return false; + } + + for (let key of keys) { + if (!value.has(key) || !matches.get(key)(value.get(key), args)) { + return false; + } + } + + return true; + }; +} + +function resolveObject(pattern) { + let matches = {}; + + const keys = Object.keys(pattern).concat(Object.getOwnPropertySymbols(pattern)); + + for (let key of keys) { + matches[key] = buildMatch(pattern[key]); + } + + return function (value, args) { + if (!is_object(value) || pattern.length > value.length) { + return false; + } + + for (let key of keys) { + if (!(key in value) || !matches[key](value[key], args)) { + return false; + } + } + + return true; + }; +} + +function resolveBitString(pattern) { + let patternBitString = []; + + for (let bitstringMatchPart of pattern.values) { + if (is_variable(bitstringMatchPart.value)) { + let size = getSize(bitstringMatchPart.unit, bitstringMatchPart.size); + fillArray(patternBitString, size); + } else { + patternBitString = patternBitString.concat(new BitString(bitstringMatchPart).value); + } + } + + let patternValues = pattern.values; + + return function (value, args) { + let bsValue = null; + + if (!is_string(value) && !(value instanceof BitString)) { + return false; + } + + if (is_string(value)) { + bsValue = new BitString(BitString.binary(value)); + } else { + bsValue = value; + } + + let beginningIndex = 0; + + for (let i = 0; i < patternValues.length; i++) { + let bitstringMatchPart = patternValues[i]; + + if (is_variable(bitstringMatchPart.value) && bitstringMatchPart.type == 'binary' && bitstringMatchPart.size === undefined && i < patternValues.length - 1) { + throw new Error('a binary field without size is only allowed at the end of a binary pattern'); + } + + let size = 0; + let bsValueArrayPart = []; + let patternBitStringArrayPart = []; + size = getSize(bitstringMatchPart.unit, bitstringMatchPart.size); + + if (i === patternValues.length - 1) { + bsValueArrayPart = bsValue.value.slice(beginningIndex); + patternBitStringArrayPart = patternBitString.slice(beginningIndex); + } else { + bsValueArrayPart = bsValue.value.slice(beginningIndex, beginningIndex + size); + patternBitStringArrayPart = patternBitString.slice(beginningIndex, beginningIndex + size); + } + + if (is_variable(bitstringMatchPart.value)) { + switch (bitstringMatchPart.type) { + case 'integer': + if (bitstringMatchPart.attributes && bitstringMatchPart.attributes.indexOf('signed') != -1) { + args.push(new Int8Array([bsValueArrayPart[0]])[0]); + } else { + args.push(new Uint8Array([bsValueArrayPart[0]])[0]); + } + break; + + case 'float': + if (size === 64) { + args.push(Float64Array.from(bsValueArrayPart)[0]); + } else if (size === 32) { + args.push(Float32Array.from(bsValueArrayPart)[0]); + } else { + return false; + } + break; + + case 'bitstring': + args.push(createBitString(bsValueArrayPart)); + break; + + case 'binary': + args.push(String.fromCharCode.apply(null, new Uint8Array(bsValueArrayPart))); + break; + + case 'utf8': + args.push(String.fromCharCode.apply(null, new Uint8Array(bsValueArrayPart))); + break; + + case 'utf16': + args.push(String.fromCharCode.apply(null, new Uint16Array(bsValueArrayPart))); + break; + + case 'utf32': + args.push(String.fromCharCode.apply(null, new Uint32Array(bsValueArrayPart))); + break; + + default: + return false; + } + } else if (!arraysEqual(bsValueArrayPart, patternBitStringArrayPart)) { + return false; + } + + beginningIndex = beginningIndex + size; + } + + return true; + }; +} + +function getSize(unit, size) { + return unit * size / 8; +} + +function arraysEqual(a, b) { + if (a === b) return true; + if (a == null || b == null) return false; + if (a.length != b.length) return false; + + for (var i = 0; i < a.length; ++i) { + if (a[i] !== b[i]) return false; + } + + return true; +} + +function fillArray(arr, num) { + for (let i = 0; i < num; i++) { + arr.push(0); + } +} + +function createBitString(arr) { + let integerParts = arr.map(elem => BitString.integer(elem)); + return new BitString(...integerParts); +} + +function resolveNoMatch() { + return function () { + return false; + }; +} + +const patternMap = new Map(); +patternMap.set(Variable.prototype, resolveVariable); +patternMap.set(Wildcard.prototype, resolveWildcard); +patternMap.set(HeadTail.prototype, resolveHeadTail); +patternMap.set(StartsWith.prototype, resolveStartsWith); +patternMap.set(Capture.prototype, resolveCapture); +patternMap.set(Bound.prototype, resolveBound); +patternMap.set(Type.prototype, resolveType); +patternMap.set(BitStringMatch.prototype, resolveBitString); +patternMap.set(Number.prototype, resolveNumber); +patternMap.set(Symbol.prototype, resolveSymbol); +patternMap.set(Map.prototype, resolveMap); +patternMap.set(Array.prototype, resolveArray); +patternMap.set(String.prototype, resolveString); +patternMap.set(Boolean.prototype, resolveBoolean); +patternMap.set(Function.prototype, resolveFunction); +patternMap.set(Object.prototype, resolveObject); + +function buildMatch(pattern) { + if (pattern === null) { + return resolveNull(pattern); + } + + if (typeof pattern === 'undefined') { + return resolveWildcard(pattern); + } + + const type$$1 = pattern.constructor.prototype; + const resolver = patternMap.get(type$$1); + + if (resolver) { + return resolver(pattern); + } + + if (typeof pattern === 'object') { + return resolveObject(pattern); + } + + return resolveNoMatch(); +} + +class MatchError extends Error { + constructor(arg) { + super(); + + if (typeof arg === 'symbol') { + this.message = 'No match for: ' + arg.toString(); + } else if (Array.isArray(arg)) { + let mappedValues = arg.map(x => { + if (x === null) { + return 'null'; + } else if (typeof x === 'undefined') { + return 'undefined'; + } + + return x.toString(); + }); + + this.message = 'No match for: ' + mappedValues; + } else { + this.message = 'No match for: ' + arg; + } + + this.stack = new Error().stack; + this.name = this.constructor.name; + } +} + +class Clause { + constructor(pattern, fn, guard = () => true) { + this.pattern = buildMatch(pattern); + this.arity = pattern.length; + this.optionals = getOptionalValues(pattern); + this.fn = fn; + this.guard = guard; + } +} + +function clause(pattern, fn, guard = () => true) { + return new Clause(pattern, fn, guard); +} + + + +function defmatch(...clauses) { + const arities = getArityMap(clauses); + + return function (...args) { + let [funcToCall, params] = findMatchingFunction(args, arities); + return funcToCall.apply(this, params); + }; +} + +function defmatchgen(...clauses) { + const arities = getArityMap(clauses); + + return function* (...args) { + let [funcToCall, params] = findMatchingFunction(args, arities); + return yield* funcToCall.apply(this, params); + }; +} + +function defmatchGen(...args) { + return defmatchgen(...args); +} + +function defmatchAsync(...clauses) { + const arities = getArityMap(clauses); + + return async function (...args) { + if (arities.has(args.length)) { + const arityClauses = arities.get(args.length); + + let funcToCall = null; + let params = null; + for (let processedClause of arityClauses) { + let result = []; + args = fillInOptionalValues(args, processedClause.arity, processedClause.optionals); + + const doesMatch = processedClause.pattern(args, result); + const [filteredResult, allNamesMatch] = checkNamedVariables(result); + + if (doesMatch && allNamesMatch && (await processedClause.guard.apply(this, result))) { + funcToCall = processedClause.fn; + params = result; + break; + } + } + + if (!funcToCall) { + console.error('No match for:', args); + throw new MatchError(args); + } + + return funcToCall.apply(this, params); + } else { + console.error('Arity of', args.length, 'not found. No match for:', args); + throw new MatchError(args); + } + }; +} + +function findMatchingFunction(args, arities) { + if (arities.has(args.length)) { + const arityClauses = arities.get(args.length); + + let funcToCall = null; + let params = null; + for (let processedClause of arityClauses) { + let result = []; + args = fillInOptionalValues(args, processedClause.arity, processedClause.optionals); + + const doesMatch = processedClause.pattern(args, result); + const [filteredResult, allNamesMatch] = checkNamedVariables(result); + + if (doesMatch && allNamesMatch && processedClause.guard.apply(this, filteredResult)) { + funcToCall = processedClause.fn; + params = filteredResult; + break; + } + } + + if (!funcToCall) { + console.error('No match for:', args); + throw new MatchError(args); + } + + return [funcToCall, params]; + } else { + console.error('Arity of', args.length, 'not found. No match for:', args); + throw new MatchError(args); + } +} + +function getArityMap(clauses) { + let map = new Map(); + + for (const clause of clauses) { + const range = getArityRange(clause); + + for (const arity of range) { + let arityClauses = []; + + if (map.has(arity)) { + arityClauses = map.get(arity); + } + + arityClauses.push(clause); + map.set(arity, arityClauses); + } + } + + return map; +} + +function getArityRange(clause) { + const min = clause.arity - clause.optionals.length; + const max = clause.arity; + + let range = [min]; + + while (range[range.length - 1] != max) { + range.push(range[range.length - 1] + 1); + } + + return range; +} + +function getOptionalValues(pattern) { + let optionals = []; + + for (let i = 0; i < pattern.length; i++) { + if (pattern[i] instanceof Variable && pattern[i].default_value != Symbol.for('tailored.no_value')) { + optionals.push([i, pattern[i].default_value]); + } + } + + return optionals; +} + +function fillInOptionalValues(args, arity, optionals) { + if (args.length === arity || optionals.length === 0) { + return args; + } + + if (args.length + optionals.length < arity) { + return args; + } + + let numberOfOptionalsToFill = arity - args.length; + let optionalsToRemove = optionals.length - numberOfOptionalsToFill; + + let optionalsToUse = optionals.slice(optionalsToRemove); + + for (let [index, value] of optionalsToUse) { + args.splice(index, 0, value); + if (args.length === arity) { + break; + } + } + + return args; +} + +function match(pattern, expr, guard = () => true) { + let result = []; + let processedPattern = buildMatch(pattern); + const doesMatch = processedPattern(expr, result); + const [filteredResult, allNamesMatch] = checkNamedVariables(result); + + if (doesMatch && allNamesMatch && guard.apply(this, filteredResult)) { + return filteredResult; + } else { + console.error('No match for:', expr); + throw new MatchError(expr); + } +} + +function checkNamedVariables(results) { + const namesMap = {}; + const filteredResults = []; + + for (let i = 0; i < results.length; i++) { + const current = results[i]; + if (current instanceof NamedVariableResult) { + if (namesMap[current.name] && namesMap[current.name] !== current.value) { + return [results, false]; + } else if (namesMap[current.name] && namesMap[current.name] === current.value) { + filteredResults.push(current.value); + } else { + namesMap[current.name] = current.value; + filteredResults.push(current.value); + } + } else { + filteredResults.push(current); + } + } + + return [filteredResults, true]; +} + +function match_or_default(pattern, expr, guard = () => true, default_value = null) { + let result = []; + let processedPattern = buildMatch(pattern); + const doesMatch = processedPattern(expr, result); + const [filteredResult, allNamesMatch] = checkNamedVariables(result); + + if (doesMatch && allNamesMatch && guard.apply(this, filteredResult)) { + return filteredResult; + } else { + return default_value; + } +} + +const NO_MATCH = Symbol(); + +function bitstring_generator(pattern, bitstring) { + return function () { + let returnResult = []; + let bsSlice = bitstring.slice(0, pattern.byte_size()); + let i = 1; + + while (bsSlice.byte_size == pattern.byte_size()) { + const result = match_or_default(pattern, bsSlice, () => true, NO_MATCH); + + if (result != NO_MATCH) { + const [value] = result; + returnResult.push(result); + } + + bsSlice = bitstring.slice(pattern.byte_size() * i, pattern.byte_size() * (i + 1)); + + i++; + } + + return returnResult; + }; +} + +function list_generator(pattern, list) { + return function () { + let returnResult = []; + for (let i of list) { + const result = match_or_default(pattern, i, () => true, NO_MATCH); + if (result != NO_MATCH) { + const [value] = result; + returnResult.push(value); + } + } + + return returnResult; + }; +} + +function list_comprehension(expression, generators) { + const generatedValues = run_generators(generators.pop()(), generators); + + let result = []; + + for (let value of generatedValues) { + if (expression.guard.apply(this, value)) { + result.push(expression.fn.apply(this, value)); + } + } + + return result; +} + +function run_generators(generator, generators) { + if (generators.length == 0) { + return generator.map(x => { + if (Array.isArray(x)) { + return x; + } else { + return [x]; + } + }); + } else { + const list = generators.pop(); + + let next_gen = []; + for (let j of list()) { + for (let i of generator) { + next_gen.push([j].concat(i)); + } + } + + return run_generators(next_gen, generators); + } +} + +function bitstring_comprehension(expression, generators) { + const generatedValues = run_generators(generators.pop()(), generators); + + let result = []; + + for (let value of generatedValues) { + if (expression.guard.apply(this, value)) { + result.push(expression.fn.apply(this, value)); + } + } + + result = result.map(x => ErlangTypes.BitString.integer(x)); + return new ErlangTypes.BitString(...result); +} + +var Patterns = { + defmatch, + match, + MatchError, + variable, + wildcard, + startsWith, + capture, + headTail, + type, + bound, + Clause, + clause, + bitStringMatch, + match_or_default, + defmatchgen, + list_comprehension, + list_generator, + bitstring_generator, + bitstring_comprehension, + defmatchGen, + defmatchAsync +}; + +// https://github.com/airportyh/protomorphism +class Protocol { + constructor(spec) { + this.registry = new Map(); + this.fallback = null; + + function createFun(funName) { + return function (...args) { + const thing = args[0]; + let fun = null; + + if (thing === null && this.hasImplementation(Symbol('null'))) { + fun = this.registry.get(Symbol)[funName]; + } else if (Number.isInteger(thing) && this.hasImplementation(Core.Integer)) { + fun = this.registry.get(Core.Integer)[funName]; + } else if (typeof thing === 'number' && !Number.isInteger(thing) && this.hasImplementation(Core.Float)) { + fun = this.registry.get(Core.Float)[funName]; + } else if (typeof thing === 'string' && this.hasImplementation(Core.BitString)) { + fun = this.registry.get(Core.BitString)[funName]; + } else if (thing && thing instanceof Map && thing.has(Symbol.for('__struct__')) && this.hasImplementation(thing)) { + fun = this.registry.get(thing.get(Symbol.for('__struct__')).__MODULE__)[funName]; + } else if (thing !== null && this.hasImplementation(thing)) { + fun = this.registry.get(thing.constructor)[funName]; + } else if (this.fallback) { + fun = this.fallback[funName]; + } + + if (fun != null) { + const retval = fun.apply(this, args); + return retval; + } + + throw new Error(`No implementation found for ${thing}`); + }; + } + + for (const funName in spec) { + this[funName] = createFun(funName).bind(this); + } + } + + implementation(type, implementation) { + if (type === null) { + this.fallback = implementation; + } else { + this.registry.set(type, implementation); + } + } + + hasImplementation(thing) { + if (thing === Core.Integer || thing === Core.Float || thing === Core.BitString) { + return this.registry.has(thing); + } else if (thing && thing instanceof Map && thing.has(Symbol.for('__struct__'))) { + return this.registry.has(thing.get(Symbol.for('__struct__')).__MODULE__); + } + + return this.registry.has(thing.constructor); + } +} + +function iterator_to_reducer(iterable, acc, fun) { + const iterator = iterable[Symbol.iterator](); + let x = iterator.next(); + let _acc = acc; + + while (x.done === false) { + _acc = fun(x.value, _acc.get(1)); + if (_acc.get(0) === Symbol.for('halt')) { + return new Core.Tuple(Symbol.for('halted'), _acc.get(1)); + } else if (_acc.get(0) === Symbol.for('suspend')) { + return new Core.Tuple(Symbol.for('suspended'), _acc.get(1), new_acc => { + return iterator_to_reducer(iterator, new_acc, fun); + }); + } + + x = iterator.next(); + } + + return new Core.Tuple(Symbol.for('done'), _acc.get(1)); +} + +function call_property(item, property) { + if (!property) { + if (item instanceof Function || typeof item === 'function') { + return item(); + } + + return item; + } + + if (item instanceof Map) { + let prop = null; + + if (item.has(property)) { + prop = property; + } else if (item.has(Symbol.for(property))) { + prop = Symbol.for(property); + } + + if (prop === null) { + throw new Error(`Property ${property} not found in ${item}`); + } + + if (item.get(prop) instanceof Function || typeof item.get(prop) === 'function') { + return item.get(prop)(); + } + return item.get(prop); + } + + let prop = null; + + if (typeof item === 'number' || typeof item === 'symbol' || typeof item === 'boolean' || typeof item === 'string') { + if (item[property] !== undefined) { + prop = property; + } else if (item[Symbol.for(property)] !== undefined) { + prop = Symbol.for(property); + } + } else if (property in item) { + prop = property; + } else if (Symbol.for(property) in item) { + prop = Symbol.for(property); + } + + if (prop === null) { + throw new Error(`Property ${property} not found in ${item}`); + } + + if (item[prop] instanceof Function || typeof item[prop] === 'function') { + return item[prop](); + } + return item[prop]; +} + +function defprotocol(spec) { + return new Protocol(spec); +} + +function defimpl(protocol, type, impl) { + protocol.implementation(type, impl); +} + +function build_namespace(ns, ns_string) { + let parts = ns_string.split('.'); + const root = ns; + let parent = ns; + + if (parts[0] === 'Elixir') { + parts = parts.slice(1); + } + + for (const part of parts) { + if (typeof parent[part] === 'undefined') { + parent[part] = {}; + } + + parent = parent[part]; + } + + root.__table__ = ns.__table__ || {}; + root.__table__[Symbol.for(ns_string)] = parent; + + return parent; +} + +function map_to_object(map) { + const object = {}; + + for (const [key, value] of map.entries()) { + if (value instanceof Map) { + object[key] = map_to_object(value); + } else { + object[key] = value; + } + } + + return object; +} + +class Recurse { + constructor(func) { + this.func = func; + } +} + +function trampoline$1(f) { + let currentValue = f; + + while (currentValue && currentValue instanceof Recurse) { + currentValue = currentValue.func(); + } + + return currentValue; +} + +var Functions = { + call_property, + defprotocol, + defimpl, + build_namespace, + iterator_to_reducer, + map_to_object, + trampoline: trampoline$1, + Recurse +}; + +function _case(condition, clauses) { + return Core.Patterns.defmatch(...clauses)(condition); +} + +function cond(...clauses) { + for (const clause of clauses) { + if (clause[0]) { + return clause[1](); + } + } + + throw new Error(); +} + +function _for(expression, generators, collectable_protocol, into = []) { + let [result, fun] = collectable_protocol.into(into); + + const generatedValues = run_list_generators(generators.pop()(), generators); + + for (const value of generatedValues) { + if (expression.guard.apply(this, value)) { + result = fun(result, new Core.Tuple(Symbol.for('cont'), expression.fn.apply(this, value))); + } + } + + return fun(result, Symbol.for('done')); +} + +function run_list_generators(generator, generators) { + if (generators.length == 0) { + return generator.map(x => { + if (Array.isArray(x)) { + return x; + } + return [x]; + }); + } + const list = generators.pop(); + + const next_gen = []; + for (const j of list()) { + for (const i of generator) { + next_gen.push([j].concat(i)); + } + } + + return run_list_generators(next_gen, generators); +} + +function _try(do_fun, rescue_function, catch_fun, else_function, after_function) { + let result = null; + + try { + result = do_fun(); + } catch (e) { + let ex_result = null; + + if (rescue_function) { + try { + ex_result = rescue_function(e); + return ex_result; + } catch (ex) { + if (ex instanceof Core.Patterns.MatchError) { + throw ex; + } + } + } + + if (catch_fun) { + try { + ex_result = catch_fun(e); + return ex_result; + } catch (ex) { + if (ex instanceof Core.Patterns.MatchError) { + throw ex; + } + } + } + + throw e; + } finally { + if (after_function) { + after_function(); + } + } + + if (else_function) { + try { + return else_function(result); + } catch (ex) { + if (ex instanceof Core.Patterns.MatchError) { + throw new Error('No Match Found in Else'); + } + + throw ex; + } + } else { + return result; + } +} + +function _with(...args) { + let argsToPass = []; + let successFunction = null; + let elseFunction = null; + + if (typeof args[args.length - 2] === 'function') { + [successFunction, elseFunction] = args.splice(-2); + } else { + successFunction = args.pop(); + } + + for (let i = 0; i < args.length; i++) { + const [pattern, func] = args[i]; + + const result = func(...argsToPass); + + const patternResult = Core.Patterns.match_or_default(pattern, result); + + if (patternResult == null) { + if (elseFunction) { + return elseFunction.call(null, result); + } + return result; + } + + argsToPass = argsToPass.concat(patternResult); + } + + return successFunction(...argsToPass); +} + +function receive(clauses, after) { + console.warn('Receive not supported'); +} + +var SpecialForms = { + _case, + cond, + _for, + _try, + _with, + receive +}; + +// http://erlang.org/doc/man/lists.html +function reverse(list) { + return [...list].reverse(); +} + +function foreach(fun, list) { + list.forEach(x => fun(x)); + + return Symbol.for('ok'); +} + +function duplicate(n, elem) { + const list = []; + + while (list.length < n) { + list.push(elem); + } + + return list; +} + +function flatten(deepList, tail = []) { + const val = deepList.reduce((acc, value) => { + if (Array.isArray(value)) { + return acc.concat(flatten(value)); + } + + return acc.concat(value); + }, []); + + return val.concat(tail); +} + +function foldl(fun, acc0, list) { + return list.reduce((acc, value) => { + return fun(value, acc); + }, acc0); +} + +function foldr(fun, acc0, list) { + return foldl(fun, acc0, reverse(list)); +} + +function keyfind(key, n, tupleList) { + for (const tuple of tupleList) { + if (tuple.get(n - 1) === key) { + return tuple; + } + } + + return false; +} + +function keymember(key, n, tupleList) { + if (keyfind(key, n, tupleList) === false) { + return false; + } + + return true; +} + +function keyreplace(key, n, tupleList, newTuple) { + const newTupleList = [...tupleList]; + + for (let index = 0; index < newTupleList.length; index++) { + if (newTupleList[index].get(n - 1) === key) { + newTupleList[index] = newTuple; + return newTupleList; + } + } + + return newTupleList; +} + +function keysort(n, tupleList) { + const newTupleList = [...tupleList]; + + return newTupleList.sort((a, b) => { + if (a.get(n - 1) < b.get(n - 1)) { + return -1; + } else if (a.get(n - 1) > b.get(n - 1)) { + return 1; + } + + return 0; + }); +} + +function keystore(key, n, tupleList, newTuple) { + const newTupleList = [...tupleList]; + + for (let index = 0; index < newTupleList.length; index++) { + if (newTupleList[index].get(n - 1) === key) { + newTupleList[index] = newTuple; + return newTupleList; + } + } + + return newTupleList.concat(newTuple); +} + +function keydelete(key, n, tupleList) { + const newTupleList = []; + let deleted = false; + + for (let index = 0; index < tupleList.length; index++) { + if (deleted === false && tupleList[index].get(n - 1) === key) { + deleted = true; + } else { + newTupleList.push(tupleList[index]); + } + } + + return newTupleList; +} + +function keytake(key, n, tupleList) { + const result = keyfind(key, n, tupleList); + + if (result !== false) { + return new ErlangTypes.Tuple(result.get(n - 1), result, keydelete(key, n, tupleList)); + } + + return false; +} + +function mapfoldl(fun, acc0, list1) { + const listResult = []; + let accResult = acc0; + + for (const item of list1) { + const tuple = fun(item, accResult); + listResult.push(tuple.get(0)); + accResult = tuple.get(1); + } + + return new ErlangTypes.Tuple(listResult, accResult); +} + +function concat(things) { + return things.map(v => v.toString()).join(); +} + +function map(fun, list) { + return list.map(value => fun(value)); +} + +function filter(pred, list1) { + return list1.filter(x => pred(x)); +} + +function filtermap(fun, list1) { + const list2 = []; + + for (const item of list1) { + const value = fun(item); + + if (value === true) { + list2.push(item); + } else if (value instanceof ErlangTypes.Tuple && value.get(0) === true) { + list2.push(value.get(1)); + } + } + + return list2; +} + +function member(elem, list) { + for (const item of list) { + if (item === elem) { + return true; + } + } + + return false; +} + +function all(pred, list) { + for (const item of list) { + if (pred(item) === false) { + return false; + } + } + + return true; +} + +function any(pred, list) { + for (const item of list) { + if (pred(item) === true) { + return true; + } + } + + return false; +} + +function splitwith(pred, list) { + let switchToList2 = false; + const list1 = []; + const list2 = []; + + for (const item of list) { + if (switchToList2 === true) { + list2.push(item); + } else if (pred(item) === true) { + list1.push(item); + } else { + switchToList2 = true; + list2.push(item); + } + } + + return new ErlangTypes.Tuple(list1, list2); +} + +function sort(...args) { + if (args.length === 1) { + const list2 = [...args[0]]; + return list2.sort(); + } + + const fun = args[0]; + const list2 = [...args[1]]; + + return list2.sort((a, b) => { + const result = fun(a, b); + + if (result === true) { + return -1; + } + + return 1; + }); +} + +var lists = { + reverse, + foreach, + duplicate, + flatten, + foldl, + foldr, + keydelete, + keyfind, + keymember, + keyreplace, + keysort, + keystore, + keytake, + mapfoldl, + concat, + map, + filter, + filtermap, + member, + all, + any, + splitwith, + sort +}; + +// http://erlang.org/doc/man/erlang.html +const selfPID = new ErlangTypes.PID(); + +function atom_to_list(atom) { + return Symbol.keyFor(atom); +} + +function atom_to_binary(atom, encoding = Symbol.for('utf8')) { + if (encoding !== Symbol.for('utf8')) { + throw new Error(`unsupported encoding ${encoding}`); + } + + if (atom.__MODULE__) { + return Symbol.keyFor(atom.__MODULE__); + } + + return Symbol.keyFor(atom); +} + +function binary_to_atom(binary, encoding = Symbol.for('utf8')) { + if (encoding !== Symbol.for('utf8')) { + throw new Error(`unsupported encoding ${encoding}`); + } + + return Symbol.for(binary); +} + +function binary_to_existing_atom(binary, encoding = Symbol.for('utf8')) { + return binary_to_atom(binary, encoding); +} + +function list_concatenation(list1, list2) { + return list1.concat(list2); +} + +function list_subtraction(list1, list2) { + const list = [...list1]; + + for (const item of list2) { + const index = list.indexOf(item); + + if (index > -1) { + list.splice(index, 1); + } + } + + return list; +} + +function div(left, right) { + return left / right; +} + +function not(x) { + return !x; +} + +function rem(left, right) { + return left % right; +} + +function band(left, right) { + return left & right; +} + +function bor(left, right) { + return left | right; +} + +function bnot(x) { + return ~x; +} + +function bsl(left, right) { + return left << right; +} + +function bsr(left, right) { + return left >> right; +} + +function bxor(left, right) { + return left ^ right; +} + +function is_atom(value) { + return typeof value === 'symbol' || value instanceof Symbol || value.__MODULE__; +} + +function is_bitstring$1(value) { + return value instanceof ErlangTypes.BitString; +} + +function is_boolean$1(value) { + return typeof value === 'boolean' || value instanceof Boolean; +} + +function is_number$1(value) { + return typeof value === 'number' || value instanceof Number; +} + +function is_float(value) { + return is_number$1(value) && !Number.isInteger(value); +} + +function is_function$1(value) { + return typeof value === 'function' || value instanceof Function; +} + +function is_integer(value) { + return Number.isInteger(value); +} + +function is_list(value) { + return Array.isArray(value); +} + +function is_map$1(value) { + return value instanceof Map; +} + +function is_pid(value) { + return value instanceof ErlangTypes.PID; +} + +function is_port() { + return false; +} + +function is_reference(value) { + return value instanceof ErlangTypes.Reference; +} + +function is_tuple(value) { + return value instanceof ErlangTypes.Tuple; +} + +function is_binary(value) { + return typeof value === 'string' || value instanceof String; +} + +function element(n, tuple) { + return tuple.get(n - 1); +} + +function setelement(index, tuple1, value) { + const tupleData = [...tuple1.values]; + + tupleData[index - 1] = value; + + return new ErlangTypes.Tuple(...tupleData); +} + +function make_tuple(arity, initialValue) { + const list = []; + + for (let i = 0; i < arity; i++) { + list.push(initialValue); + } + + return new ErlangTypes.Tuple(...list); +} + +function insert_element(index, tuple, term) { + const list = [...tuple.values]; + list.splice(index - 1, 0, term); + + return new ErlangTypes.Tuple(...list); +} + +function append_element(tuple, term) { + const list = [...tuple.values]; + list.push(term); + + return new ErlangTypes.Tuple(...list); +} + +function delete_element(index, tuple) { + const list = [...tuple.values]; + list.splice(index - 1, 1); + + return new ErlangTypes.Tuple(...list); +} + +function tuple_to_list(tuple) { + const list = [...tuple.values]; + return list; +} + +function abs(number) { + return Math.abs(number); +} + +function apply(...args) { + if (args.length === 2) { + return args[0].apply(this, ...args[1]); + } + + return args[0][atom_to_binary(args[1])].apply(this, ...args[2]); +} + +function binary_part(binary, start, _length) { + return binary.substring(start, start + _length); +} + +function bit_size(bitstring) { + return bitstring.bit_size; +} + +function byte_size(bitstring) { + return bitstring.byte_size; +} + +function hd(list) { + return list[0]; +} + +function length(list) { + return list.length; +} + +function make_ref() { + return new ErlangTypes.Reference(); +} + +function map_size(map) { + return map.size; +} + +function max(first, second) { + return Math.max(first, second); +} + +function min(first, second) { + return Math.min(first, second); +} + +function round(number) { + return Math.round(number); +} + +function tl(list) { + return list.slice(1); +} + +function trunc(number) { + return Math.trunc(number); +} + +function tuple_size(tuple) { + return tuple.length; +} + +function binary_to_float(str) { + return parseFloat(str); +} + +function binary_to_integer(str, base = 10) { + return parseInt(str, base); +} + +function process_info(pid, item) { + if (item) { + if (item === Symbol.for('current_stacktrace')) { + return new ErlangTypes.Tuple(item, []); + } + + return new ErlangTypes.Tuple(item, null); + } + + return []; +} + +function list_to_binary(iolist) { + const iolistFlattened = lists.flatten(iolist); + + const value = iolistFlattened.reduce((acc, current) => { + if (current === null) { + return acc; + } else if (is_integer(current)) { + return acc + String.fromCodePoint(current); + } else if (is_bitstring$1(current)) { + return acc + String.fromCodePoint(...current.value); + } + + return acc + current; + }, ''); + + return value; +} + +function iolist_to_binary(ioListOrBinary) { + if (ioListOrBinary === null) { + return ''; + } + + if (is_binary(ioListOrBinary)) { + return ioListOrBinary; + } + + if (is_bitstring$1(ioListOrBinary)) { + return String.fromCodePoint(...ioListOrBinary.value); + } + + if (is_number$1(ioListOrBinary)) { + return String.fromCodePoint(ioListOrBinary); + } + + const iolistFlattened = lists.flatten(ioListOrBinary); + + const value = iolistFlattened.reduce((acc, current) => { + if (current === null) { + return acc; + } else if (is_integer(current)) { + return acc + String.fromCodePoint(current); + } else if (is_bitstring$1(current)) { + return acc + String.fromCodePoint(...current.value); + } + + return acc + iolist_to_binary(current); + }, ''); + + return value; +} + +function io_size(ioListOrBinary) { + return iolist_to_binary(ioListOrBinary).length; +} + +function integer_to_binary(integer, base = 10) { + return integer.toString(base); +} + +function node() { + return Symbol.for('nonode@nohost'); +} + +function self$1() { + return selfPID; +} + +function _throw(term) { + throw term; +} + +function error(reason) { + throw new ErlangTypes.Tuple(reason, []); +} + +function exit(...args) { + if (args.length === 2) { + throw args[1]; + } else { + throw args[0]; + } +} + +function raise(_class, reason) { + if (_class === Symbol.for('throw')) { + _throw(reason); + } else if (_class === Symbol.for('error')) { + error(reason); + } else { + exit(reason); + } +} + +var erlang = { + atom_to_binary, + binary_to_atom, + binary_to_existing_atom, + list_concatenation, + list_subtraction, + div, + not, + rem, + band, + bor, + bsl, + bsr, + bxor, + bnot, + is_bitstring: is_bitstring$1, + is_boolean: is_boolean$1, + is_float, + is_function: is_function$1, + is_integer, + is_list, + is_map: is_map$1, + is_number: is_number$1, + is_pid, + is_port, + is_reference, + is_tuple, + is_atom, + is_binary, + element, + setelement, + make_tuple, + insert_element, + append_element, + delete_element, + tuple_to_list, + abs, + apply, + binary_part, + bit_size, + byte_size, + hd, + length, + make_ref, + map_size, + max, + min, + round, + tl, + trunc, + tuple_size, + binary_to_float, + binary_to_integer, + process_info, + iolist_to_binary, + io_size, + integer_to_binary, + atom_to_list, + node, + self: self$1, + throw: _throw, + error, + exit, + raise, + list_to_binary +}; + +// http://erlang.org/doc/man/maps.html +const OK = Symbol.for('ok'); +const ERROR = Symbol.for('error'); +const BADMAP = Symbol.for('badmap'); +const BADKEY = Symbol.for('badkey'); + +function find(key, map) { + if (erlang.is_map(map) === false) { + return new ErlangTypes.Tuple(BADMAP, map); + } + + const value = map.get(key); + + if (typeof value !== 'undefined') { + return new ErlangTypes.Tuple(OK, value); + } + + return ERROR; +} + +function fold(fun, init, map) { + let acc = init; + + for (const [key, value] of map.entries()) { + acc = fun(key, value, acc); + } + + return acc; +} + +function remove(key, map1) { + if (erlang.is_map(map1) === false) { + return new ErlangTypes.Tuple(BADMAP, map1); + } + + const map2 = new Map(map1); + + map2.delete(key); + + return map2; +} + +function to_list(map) { + if (erlang.is_map(map) === false) { + return new ErlangTypes.Tuple(BADMAP, map); + } + + const list = []; + + for (const [key, value] of map.entries()) { + list.push(new ErlangTypes.Tuple(key, value)); + } + + return list; +} + +function from_list(list) { + return list.reduce((acc, item) => { + const [key, value] = item; + acc.set(key, value); + + return acc; + }, new Map()); +} + +function keys(map) { + if (erlang.is_map(map) === false) { + return new ErlangTypes.Tuple(BADMAP, map); + } + + return Array.from(map.keys()); +} + +function values$1(map) { + if (erlang.is_map(map) === false) { + return new ErlangTypes.Tuple(BADMAP, map); + } + + return Array.from(map.values()); +} + +function is_key(key, map) { + return map.has(key); +} + +function put(key, value, map1) { + if (erlang.is_map(map1) === false) { + return new ErlangTypes.Tuple(BADMAP, map1); + } + + const map2 = new Map(map1); + map2.set(key, value); + + return map2; +} + +function merge(map1, map2) { + if (erlang.is_map(map1) === false) { + return new ErlangTypes.Tuple(BADMAP, map1); + } + + if (erlang.is_map(map2) === false) { + return new ErlangTypes.Tuple(BADMAP, map2); + } + + return new Map([...map1, ...map2]); +} + +function update(key, value, map1) { + if (erlang.is_map(map1) === false) { + return new ErlangTypes.Tuple(BADMAP, map1); + } + + if (is_key(key, map1) === false) { + return new ErlangTypes.Tuple(BADKEY, key); + } + + return new Map([...map1, [key, value]]); +} + +function get(...args) { + const key = args[0]; + const map = args[1]; + + if (erlang.is_map(map) === false) { + return new ErlangTypes.Tuple(BADMAP, map); + } + + if (is_key(key)) { + return map.get(key); + } + + if (args.length === 3) { + return args[2]; + } + + return new ErlangTypes.Tuple(BADKEY, key); +} + +function take(key, map1) { + if (erlang.is_map(map1) === false) { + return new ErlangTypes.Tuple(BADMAP, map1); + } + + if (!is_key(key)) { + return ERROR; + } + + const value = map1.get(key); + const map2 = new Map(map1); + map2.delete(key); + + return new ErlangTypes.Tuple(value, map2); +} + +var maps = { + find, + fold, + remove, + to_list, + from_list, + keys, + values: values$1, + is_key, + put, + merge, + update, + get, + take +}; + +function warn(message) { + const messageString = message.join(''); + console.warn(`warning: ${messageString}`); + + return Symbol.for('ok'); +} + +var elixir_errors = { + warn +}; + +const MODULE = Symbol.for('elixir_config'); +const ets = new Map(); + +function _new(opts) { + ets.set(MODULE, new Map()); + ets.get(MODULE).set(MODULE, opts); + return MODULE; +} + +function _delete(module) { + ets.delete(module); + return true; +} + +function put$1(key, value) { + ets.get(MODULE).set(key, value); + return Symbol.for('ok'); +} + +function get$1(key) { + return ets.get(MODULE).get(key); +} + +function update$1(key, fun) { + const value = fun(ets.get(MODULE).get(key)); + put$1(key, value); + return value; +} + +function get_and_put(key, value) { + const oldValue = get$1(key); + put$1(key, value); + return oldValue; +} + +var elixir_config = { + new: _new, + delete: _delete, + put: put$1, + get: get$1, + update: update$1, + get_and_put +}; + +function put_chars(ioDevice, charData) { + const dataToWrite = erlang.iolist_to_binary(charData); + + if (ioDevice === Symbol.for('stderr')) { + console.error(dataToWrite); + } else { + console.log(dataToWrite); + } + + return Symbol.for('ok'); +} + +var io = { + put_chars +}; + +function copy(subject, n = 1) { + return subject.repeat(n); +} + +function list_to_bin(bytelist) { + return erlang.list_to_binary(bytelist); +} + +var binary = { + copy, + list_to_bin +}; + +function characters_to_list(characters) { + return characters.split('').map(c => c.codePointAt(0)); +} + +function characters_to_binary(characters) { + if (erlang.is_binary(characters)) { + return characters; + } + + return String.fromCodePoint(...characters); +} + +var unicode = { + characters_to_list, + characters_to_binary +}; + +function get_key(key) { + let real_key = key; + + if (__elixirscript_names__.has(key)) { + real_key = __elixirscript_names__.get(key); + } + + if (__elixirscript_store__.has(real_key)) { + return real_key; + } + + throw new Error(`Key ${real_key} not found`); +} + +function create(value, name = null) { + const key = new Core.PID(); + + if (name !== null) { + __elixirscript_names__.set(name, key); + } + + return __elixirscript_store__.set(key, value); +} + +function update$2(key, value) { + const real_key = get_key(key); + return __elixirscript_store__.set(real_key, value); +} + +function read(key) { + const real_key = get_key(key); + return __elixirscript_store__.get(real_key); +} + +function remove$1(key) { + const real_key = get_key(key); + return __elixirscript_store__.delete(real_key); +} + +var Store = { + create, + update: update$2, + read, + remove: remove$1 +}; + +class Integer {} +class Float {} + +function get_global() { + if (typeof self !== 'undefined') { + return self; + } else if (typeof window !== 'undefined') { + return window; + } else if (typeof global !== 'undefined') { + return global; + } + + console.warn('No global state found'); + return null; +} + +const globalState = get_global(); + +globalState.__elixirscript_store__ = new Map(); +globalState.__elixirscript_names__ = new Map(); + +var Core = { + Tuple: ErlangTypes.Tuple, + PID: ErlangTypes.PID, + BitString: ErlangTypes.BitString, + Patterns, + Integer, + Float, + Functions, + SpecialForms, + Store, + global: globalState, + erlang, + maps, + lists, + elixir_errors, + io, + binary, + unicode, + elixir_config +}; + +var elixir = { + Core +}; + +return elixir; + +}()); diff --git a/src/javascript/lib/core/erlang_compat/binary.js b/src/javascript/lib/core/erlang_compat/binary.js index 0e0c8f96..da07675d 100644 --- a/src/javascript/lib/core/erlang_compat/binary.js +++ b/src/javascript/lib/core/erlang_compat/binary.js @@ -1,7 +1,14 @@ +import erlang from './erlang'; + function copy(subject, n = 1) { return subject.repeat(n); } +function list_to_bin(bytelist) { + return erlang.list_to_binary(bytelist); +} + export default { - copy + copy, + list_to_bin }; diff --git a/src/javascript/lib/core/erlang_compat/erlang.js b/src/javascript/lib/core/erlang_compat/erlang.js index 5b853793..faf71dd8 100644 --- a/src/javascript/lib/core/erlang_compat/erlang.js +++ b/src/javascript/lib/core/erlang_compat/erlang.js @@ -2,6 +2,8 @@ import ErlangTypes from 'erlang-types'; import lists from './lists'; +const selfPID = new ErlangTypes.PID(); + function atom_to_list(atom) { return Symbol.keyFor(atom); } @@ -274,6 +276,24 @@ function process_info(pid, item) { return []; } +function list_to_binary(iolist) { + const iolistFlattened = lists.flatten(iolist); + + const value = iolistFlattened.reduce((acc, current) => { + if (current === null) { + return acc; + } else if (is_integer(current)) { + return acc + String.fromCodePoint(current); + } else if (is_bitstring(current)) { + return acc + String.fromCodePoint(...current.value); + } + + return acc + current; + }, ''); + + return value; +} + function iolist_to_binary(ioListOrBinary) { if (ioListOrBinary === null) { return ''; @@ -316,6 +336,44 @@ function integer_to_binary(integer, base = 10) { return integer.toString(base); } +function node() { + return Symbol.for('nonode@nohost'); +} + +function self() { + return selfPID; +} + +function _throw(term) { + throw term; +} + +function error(reason) { + throw new ErlangTypes.Tuple(reason, []); +} + +function exit(...args) { + if (args.length === 2) { + throw args[1]; + } else { + throw args[0]; + } +} + +function raise(_class, reason) { + if (_class === Symbol.for('throw')) { + _throw(reason); + } else if (_class === Symbol.for('error')) { + error(reason); + } else { + exit(reason); + } +} + +function function_exported(module, _function) { + return module[_function] != null; +} + export default { atom_to_binary, binary_to_atom, @@ -373,5 +431,12 @@ export default { iolist_to_binary, io_size, integer_to_binary, - atom_to_list + atom_to_list, + node, + self, + throw: _throw, + error, + exit, + raise, + list_to_binary }; From 7fed1c7fe6a507d96d0aa8ad3ef3bbf33b990500 Mon Sep 17 00:00:00 2001 From: vans163 Date: Wed, 2 Aug 2017 14:33:43 -0400 Subject: [PATCH 204/418] specify node.js version required in README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index b3b413d5..b5feac14 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ Requirements =========== * Erlang 20 or greater * Elixir 1.5 or greater (must be compiled with Erlang 20 or greater) -* Node (only for development) +* Node 8.2.1 or greater (only for development) Usage ======== From a7b33901b429f17fc625bcbc36d3e5b5fd9f1074 Mon Sep 17 00:00:00 2001 From: vans163 Date: Wed, 2 Aug 2017 14:49:49 -0400 Subject: [PATCH 205/418] lowercase JavaScriptInterop.html to prevent 404 --- GettingStarted.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/GettingStarted.md b/GettingStarted.md index c5b4681b..2026231f 100644 --- a/GettingStarted.md +++ b/GettingStarted.md @@ -61,4 +61,4 @@ Elixirscript supports all macros ### JavaScript Interop -Check out the [JavaScript Interoperability](JavaScriptInterop.html) documentation +Check out the [JavaScript Interoperability](JavascriptInterop.html) documentation From 9adeb3b7aa32ef0c4e0bd16a8bf1bfafdd42ac51 Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Thu, 3 Aug 2017 20:30:25 -0500 Subject: [PATCH 206/418] Rename foreign to defexternal --- JavascriptInterop.md | 6 +++--- lib/elixir_script/compiler.ex | 6 +----- lib/elixir_script/ffi.ex | 14 +++++++------- lib/elixir_script/lib/store.ex | 8 ++++---- test/ffi_test.exs | 4 ++-- 5 files changed, 17 insertions(+), 21 deletions(-) diff --git a/JavascriptInterop.md b/JavascriptInterop.md index 438a2781..751de238 100644 --- a/JavascriptInterop.md +++ b/JavascriptInterop.md @@ -25,12 +25,12 @@ Here is an example of a foreign module for a JSON module defmodule MyApp.JSON do use ElixirScript.FFI - foreign stringify(map) - foreign parse(string) + defexternal stringify(map) + defexternal parse(string) end ``` -Foreign modules map to JavaScript files that export functions defined with the `foreign` macro. +Foreign modules map to JavaScript files that export functions defined with the `defexternal` macro. ElixirScript expects JavaScript modules to be in the `priv/elixir_script` directory. These modules are copied to the output directory upon compilation. diff --git a/lib/elixir_script/compiler.ex b/lib/elixir_script/compiler.ex index 1c2d9c85..24f9bdc9 100644 --- a/lib/elixir_script/compiler.ex +++ b/lib/elixir_script/compiler.ex @@ -16,17 +16,13 @@ defmodule ElixirScript.Compiler do entry_modules = List.wrap(entry_modules) - IO.puts "Finding used modules" ElixirScript.FindUsedModules.execute(entry_modules, pid) - IO.puts "Finding used functions" ElixirScript.FindUsedFunctions.execute(entry_modules, pid) - IO.puts "Compiling" modules = ElixirScript.State.list_modules(pid) ElixirScript.Translate.execute(modules, pid) - IO.puts "Building Output" modules = ElixirScript.State.list_modules(pid) result = ElixirScript.Output.execute(modules, pid) @@ -56,4 +52,4 @@ defmodule ElixirScript.Compiler do defp get_module_formatter(_) do ElixirScript.ModuleSystems.ES end -end \ No newline at end of file +end diff --git a/lib/elixir_script/ffi.ex b/lib/elixir_script/ffi.ex index 3ee1ea94..6ae2d85e 100644 --- a/lib/elixir_script/ffi.ex +++ b/lib/elixir_script/ffi.ex @@ -3,7 +3,7 @@ defmodule ElixirScript.FFI do The foreign function interface for interacting with JavaScript To define a foreign module, make a new module and add `use ElixirScript.FFI`. to it - To define foreign functions, use the `foreign` macro. + To define external functions, use the `defexternal` macro. Here is an example of a foreign module for a JSON module @@ -11,12 +11,12 @@ defmodule ElixirScript.FFI do defmodule MyApp.JSON do use ElixirScript.FFI - foreign stringify(map) - foreign parse(string) + defexternal stringify(map) + defexternal parse(string) end ``` - Foreign modules map to JavaScript files that export functions defined with the `foreign` macro. + Foreign modules map to JavaScript files that export functions defined with the `defexternal` macro. ElixirScript expects JavaScript modules to be in the `priv/elixir_script` directory. These modules are copied to the output directory upon compilation. @@ -46,13 +46,13 @@ defmodule ElixirScript.FFI do @doc """ Defines a JavaScript function to be called from Elixir modules - To define a foreign function, pass the name and arguments to `foreign` + To define an external function, pass the name and arguments to `defexternal` ```elixir - foreign my_js_function(arg1, arg2, arg3) + defexternal my_js_function(arg1, arg2, arg3) ``` """ - defmacro foreign({name, _, args}) do + defmacro defexternal({name, _, args}) do args = Enum.map(args, fn {:\\, meta0, [{name, meta, atom}, value]}-> name = String.to_atom("_" <> Atom.to_string(name)) diff --git a/lib/elixir_script/lib/store.ex b/lib/elixir_script/lib/store.ex index 5c2efa23..9e98bce3 100644 --- a/lib/elixir_script/lib/store.ex +++ b/lib/elixir_script/lib/store.ex @@ -2,11 +2,11 @@ defmodule ElixirScript.Core.Store do @moduledoc false use ElixirScript.FFI, global: true - foreign create(value, name \\ nil) + defexternal create(value, name \\ nil) - foreign update(key, value) + defexternal update(key, value) - foreign read(key) + defexternal read(key) - foreign remove(key) + defexternal remove(key) end diff --git a/test/ffi_test.exs b/test/ffi_test.exs index dbbaa77d..5b593d52 100644 --- a/test/ffi_test.exs +++ b/test/ffi_test.exs @@ -4,7 +4,7 @@ defmodule ElixirScript.FFI.Test do defmodule MyTestModule do use ElixirScript.FFI - foreign my_test_function(arg1, arg2) + defexternal my_test_function(arg1, arg2) end test "FFI module has __foreign_info__ attribute" do @@ -14,4 +14,4 @@ defmodule ElixirScript.FFI.Test do test "FFI module makes foreign function" do assert Keyword.has_key?(MyTestModule.__info__(:functions), :my_test_function) end -end \ No newline at end of file +end From 4666746253c8d4d5affa61c66f3878bdd9cb6425 Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Thu, 3 Aug 2017 21:39:44 -0500 Subject: [PATCH 207/418] Document global option on FFI module Add name option. The value is used as the module name when creating the function call in JavaScript --- lib/elixir_script/ffi.ex | 11 +++++++++-- lib/elixir_script/passes/find_used_modules.ex | 10 ++++++++-- lib/elixir_script/passes/translate/forms/remote.ex | 13 +++++++++---- lib/elixir_script/passes/translate/module.ex | 10 ++++++++-- 4 files changed, 34 insertions(+), 10 deletions(-) diff --git a/lib/elixir_script/ffi.ex b/lib/elixir_script/ffi.ex index 6ae2d85e..8c94f78f 100644 --- a/lib/elixir_script/ffi.ex +++ b/lib/elixir_script/ffi.ex @@ -29,6 +29,13 @@ defmodule ElixirScript.FFI do parse: JSON.parse } ``` + + `ElixirScript.FFI` takes the following options + * `global`: If the module is defined in the global state or not. If this is set to `true`, + nothing is imported and instead ElixirScript will use the name of the module to call a module and + function in the global scope. + * `name`: Only applicable with `global` is set to `true`. This will use the name defined here + instead of the module name for calling modules and functions in the global scope """ defmacro __using__(opts) do @@ -37,7 +44,7 @@ defmodule ElixirScript.FFI do Module.register_attribute __MODULE__, :__foreign_info__, persist: true @__foreign_info__ %{ path: Macro.underscore(__MODULE__), - name: Enum.join(Module.split(__MODULE__), "_"), + name: unquote(Keyword.get(opts, :name, nil)), global: unquote(Keyword.get(opts, :global, false)) } end @@ -54,7 +61,7 @@ defmodule ElixirScript.FFI do """ defmacro defexternal({name, _, args}) do args = Enum.map(args, fn - {:\\, meta0, [{name, meta, atom}, value]}-> + {:\\, meta0, [{name, meta, atom}, value]} -> name = String.to_atom("_" <> Atom.to_string(name)) {:\\, meta0, [{name, meta, atom}, value]} diff --git a/lib/elixir_script/passes/find_used_modules.ex b/lib/elixir_script/passes/find_used_modules.ex index ee65f7a0..300cace0 100644 --- a/lib/elixir_script/passes/find_used_modules.ex +++ b/lib/elixir_script/passes/find_used_modules.ex @@ -26,8 +26,14 @@ defmodule ElixirScript.FindUsedModules do end defp walk_module(module, %{attributes: [__foreign_info__: %{path: path, name: name, global: global}]} = info, pid) do - path = if global, do: nil, else: path - name = if global, do: module, else: name + {name, path} = if global do + name = if name, do: name, else: module + path = nil + {name, path} + else + name = Enum.join(Module.split(module), "_") + {name, path} + end ModuleState.put_javascript_module(pid, module, name, path) ModuleState.put_module(pid, module, info) diff --git a/lib/elixir_script/passes/translate/forms/remote.ex b/lib/elixir_script/passes/translate/forms/remote.ex index cf6ac235..d9813bc5 100644 --- a/lib/elixir_script/passes/translate/forms/remote.ex +++ b/lib/elixir_script/passes/translate/forms/remote.ex @@ -99,11 +99,16 @@ defmodule ElixirScript.Translate.Forms.Remote do defp process_js_module_name(module, state) do case ModuleState.get_js_module_name(state.pid, module) do - name when is_atom(name) -> - members = Module.split(module) - Identifier.make_namespace_members(members) - name -> + name when is_binary(name) -> J.identifier(name) + name when is_atom(name) -> + case to_string(name) do + "Elixir." <> _ -> + members = Module.split(module) + Identifier.make_namespace_members(members) + x -> + J.identifier(x) + end end end diff --git a/lib/elixir_script/passes/translate/module.ex b/lib/elixir_script/passes/translate/module.ex index 43522b7b..f895df6c 100644 --- a/lib/elixir_script/passes/translate/module.ex +++ b/lib/elixir_script/passes/translate/module.ex @@ -14,8 +14,14 @@ defmodule ElixirScript.Translate.Module do end def compile(module, %{attributes: [__foreign_info__: %{path: path, name: name, global: global}]}, pid) do - path = if global, do: nil, else: path - name = if global, do: module, else: name + {name, path} = if global do + name = if name, do: name, else: module + path = nil + {name, path} + else + name = Enum.join(Module.split(module), "_") + {name, path} + end ModuleState.put_javascript_module(pid, module, name, path) From b322739198fc1c15e8c9b05fb8e83cb3970b8c86 Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Thu, 3 Aug 2017 21:51:37 -0500 Subject: [PATCH 208/418] Build minified version of ElixirScript.Core.js --- priv/build/iife/ElixirScript.Core.js | 2721 +------------------------- 1 file changed, 6 insertions(+), 2715 deletions(-) diff --git a/priv/build/iife/ElixirScript.Core.js b/priv/build/iife/ElixirScript.Core.js index 6253bea7..de1667aa 100644 --- a/priv/build/iife/ElixirScript.Core.js +++ b/priv/build/iife/ElixirScript.Core.js @@ -1,2715 +1,6 @@ -var ElixirScript = (function () { -'use strict'; - -/* @flow */ - -class Variable { - constructor(name = null, default_value = Symbol.for('tailored.no_value')) { - this.name = name; - this.default_value = default_value; - } -} - -class Wildcard { - constructor() {} -} - -class StartsWith { - constructor(prefix) { - this.prefix = prefix; - } -} - -class Capture { - constructor(value) { - this.value = value; - } -} - -class HeadTail { - constructor(head, tail) { - this.head = head; - this.tail = tail; - } -} - -class Type { - constructor(type, objPattern = {}) { - this.type = type; - this.objPattern = objPattern; - } -} - -class Bound { - constructor(value) { - this.value = value; - } -} - -class BitStringMatch { - constructor(...values) { - this.values = values; - } - - length() { - return values.length; - } - - bit_size() { - return this.byte_size() * 8; - } - - byte_size() { - let s = 0; - - for (let val of this.values) { - s = s + val.unit * val.size / 8; - } - - return s; - } - - getValue(index) { - return this.values(index); - } - - getSizeOfValue(index) { - let val = this.getValue(index); - return val.unit * val.size; - } - - getTypeOfValue(index) { - return this.getValue(index).type; - } -} - -class NamedVariableResult { - constructor(name, value) { - this.name = name; - this.value = value; - } -} - -function variable(name = null, default_value = Symbol.for('tailored.no_value')) { - return new Variable(name, default_value); -} - -function wildcard() { - return new Wildcard(); -} - -function startsWith(prefix) { - return new StartsWith(prefix); -} - -function capture(value) { - return new Capture(value); -} - -function headTail(head, tail) { - return new HeadTail(head, tail); -} - -function type(type, objPattern = {}) { - return new Type(type, objPattern); -} - -function bound(value) { - return new Bound(value); -} - -function bitStringMatch(...values) { - return new BitStringMatch(...values); -} - -function namedVariableResult(name, value) { - return new NamedVariableResult(name, value); -} - -/* @flow */ - -function is_number(value) { - return typeof value === 'number'; -} - -function is_string(value) { - return typeof value === 'string'; -} - -function is_boolean(value) { - return typeof value === 'boolean'; -} - -function is_symbol(value) { - return typeof value === 'symbol'; -} - -function is_object(value) { - return typeof value === 'object'; -} - -function is_variable(value) { - return value instanceof Variable; -} - -function is_null(value) { - return value === null; -} - -function is_array(value) { - return Array.isArray(value); -} - -function is_function(value) { - return Object.prototype.toString.call(value) == '[object Function]'; -} - -function is_map(value) { - return value instanceof Map; -} - -class Tuple { - constructor(...args) { - this.values = Object.freeze(args); - this.length = this.values.length; - } - - get(index) { - return this.values[index]; - } - - count() { - return this.values.length; - } - - [Symbol.iterator]() { - return this.values[Symbol.iterator](); - } - - toString() { - let i, - s = ''; - for (i = 0; i < this.values.length; i++) { - if (s !== '') { - s += ', '; - } - - const stringToAppend = this.values[i] ? this.values[i].toString() : ''; - - s += stringToAppend; - } - - return '{' + s + '}'; - } - - put_elem(index, elem) { - if (index === this.length) { - let new_values = this.values.concat([elem]); - return new Tuple(...new_values); - } - - let new_values = this.values.concat([]); - new_values.splice(index, 0, elem); - return new Tuple(...new_values); - } - - remove_elem(index) { - let new_values = this.values.concat([]); - new_values.splice(index, 1); - return new Tuple(...new_values); - } -} - -let process_counter = -1; - -class PID { - constructor() { - process_counter = process_counter + 1; - this.id = process_counter; - } - - toString() { - return 'PID#<0.' + this.id + '.0>'; - } -} - -let ref_counter = -1; - -class Reference { - constructor() { - ref_counter = ref_counter + 1; - this.id = ref_counter; - this.ref = Symbol(); - } - - toString() { - return 'Ref#<0.0.0.' + this.id + '>'; - } -} - -class BitString$1 { - constructor(...args) { - this.value = Object.freeze(this.process(args)); - this.length = this.value.length; - this.bit_size = this.length * 8; - this.byte_size = this.length; - } - - get(index) { - return this.value[index]; - } - - count() { - return this.value.length; - } - - slice(start, end = null) { - let s = this.value.slice(start, end); - let ms = s.map(elem => BitString$1.integer(elem)); - return new BitString$1(...ms); - } - - [Symbol.iterator]() { - return this.value[Symbol.iterator](); - } - - toString() { - var i, - s = ''; - for (i = 0; i < this.count(); i++) { - if (s !== '') { - s += ', '; - } - s += this.get(i).toString(); - } - - return '<<' + s + '>>'; - } - - process(bitStringParts) { - let processed_values = []; - - var i; - for (i = 0; i < bitStringParts.length; i++) { - let processed_value = this['process_' + bitStringParts[i].type](bitStringParts[i]); - - for (let attr of bitStringParts[i].attributes) { - processed_value = this['process_' + attr](processed_value); - } - - processed_values = processed_values.concat(processed_value); - } - - return processed_values; - } - - process_integer(value) { - return value.value; - } - - process_float(value) { - if (value.size === 64) { - return BitString$1.float64ToBytes(value.value); - } else if (value.size === 32) { - return BitString$1.float32ToBytes(value.value); - } - - throw new Error('Invalid size for float'); - } - - process_bitstring(value) { - return value.value.value; - } - - process_binary(value) { - return BitString$1.toUTF8Array(value.value); - } - - process_utf8(value) { - return BitString$1.toUTF8Array(value.value); - } - - process_utf16(value) { - return BitString$1.toUTF16Array(value.value); - } - - process_utf32(value) { - return BitString$1.toUTF32Array(value.value); - } - - process_signed(value) { - return new Uint8Array([value])[0]; - } - - process_unsigned(value) { - return value; - } - - process_native(value) { - return value; - } - - process_big(value) { - return value; - } - - process_little(value) { - return value.reverse(); - } - - process_size(value) { - return value; - } - - process_unit(value) { - return value; - } - - static integer(value) { - return BitString$1.wrap(value, { type: 'integer', unit: 1, size: 8 }); - } - - static float(value) { - return BitString$1.wrap(value, { type: 'float', unit: 1, size: 64 }); - } - - static bitstring(value) { - return BitString$1.wrap(value, { - type: 'bitstring', - unit: 1, - size: value.bit_size - }); - } - - static bits(value) { - return BitString$1.bitstring(value); - } - - static binary(value) { - return BitString$1.wrap(value, { - type: 'binary', - unit: 8, - size: value.length - }); - } - - static bytes(value) { - return BitString$1.binary(value); - } - - static utf8(value) { - return BitString$1.wrap(value, { type: 'utf8', unit: 1, size: value.length }); - } - - static utf16(value) { - return BitString$1.wrap(value, { - type: 'utf16', - unit: 1, - size: value.length * 2 - }); - } - - static utf32(value) { - return BitString$1.wrap(value, { - type: 'utf32', - unit: 1, - size: value.length * 4 - }); - } - - static signed(value) { - return BitString$1.wrap(value, {}, 'signed'); - } - - static unsigned(value) { - return BitString$1.wrap(value, {}, 'unsigned'); - } - - static native(value) { - return BitString$1.wrap(value, {}, 'native'); - } - - static big(value) { - return BitString$1.wrap(value, {}, 'big'); - } - - static little(value) { - return BitString$1.wrap(value, {}, 'little'); - } - - static size(value, count) { - return BitString$1.wrap(value, { size: count }); - } - - static unit(value, count) { - return BitString$1.wrap(value, { unit: count }); - } - - static wrap(value, opt, new_attribute = null) { - let the_value = value; - - if (!(value instanceof Object)) { - the_value = { value: value, attributes: [] }; - } - - the_value = Object.assign(the_value, opt); - - if (new_attribute) { - the_value.attributes.push(new_attribute); - } - - return the_value; - } - - static toUTF8Array(str) { - var utf8 = []; - for (var i = 0; i < str.length; i++) { - var charcode = str.charCodeAt(i); - if (charcode < 0x80) { - utf8.push(charcode); - } else if (charcode < 0x800) { - utf8.push(0xc0 | charcode >> 6, 0x80 | charcode & 0x3f); - } else if (charcode < 0xd800 || charcode >= 0xe000) { - utf8.push(0xe0 | charcode >> 12, 0x80 | charcode >> 6 & 0x3f, 0x80 | charcode & 0x3f); - } else { - // surrogate pair - i++; - // UTF-16 encodes 0x10000-0x10FFFF by - // subtracting 0x10000 and splitting the - // 20 bits of 0x0-0xFFFFF into two halves - charcode = 0x10000 + ((charcode & 0x3ff) << 10 | str.charCodeAt(i) & 0x3ff); - utf8.push(0xf0 | charcode >> 18, 0x80 | charcode >> 12 & 0x3f, 0x80 | charcode >> 6 & 0x3f, 0x80 | charcode & 0x3f); - } - } - return utf8; - } - - static toUTF16Array(str) { - var utf16 = []; - for (var i = 0; i < str.length; i++) { - var codePoint = str.codePointAt(i); - - if (codePoint <= 255) { - utf16.push(0); - utf16.push(codePoint); - } else { - utf16.push(codePoint >> 8 & 0xff); - utf16.push(codePoint & 0xff); - } - } - return utf16; - } - - static toUTF32Array(str) { - var utf32 = []; - for (var i = 0; i < str.length; i++) { - var codePoint = str.codePointAt(i); - - if (codePoint <= 255) { - utf32.push(0); - utf32.push(0); - utf32.push(0); - utf32.push(codePoint); - } else { - utf32.push(0); - utf32.push(0); - utf32.push(codePoint >> 8 & 0xff); - utf32.push(codePoint & 0xff); - } - } - return utf32; - } - - //http://stackoverflow.com/questions/2003493/javascript-float-from-to-bits - static float32ToBytes(f) { - var bytes = []; - - var buf = new ArrayBuffer(4); - new Float32Array(buf)[0] = f; - - let intVersion = new Uint32Array(buf)[0]; - - bytes.push(intVersion >> 24 & 0xff); - bytes.push(intVersion >> 16 & 0xff); - bytes.push(intVersion >> 8 & 0xff); - bytes.push(intVersion & 0xff); - - return bytes; - } - - static float64ToBytes(f) { - var bytes = []; - - var buf = new ArrayBuffer(8); - new Float64Array(buf)[0] = f; - - var intVersion1 = new Uint32Array(buf)[0]; - var intVersion2 = new Uint32Array(buf)[1]; - - bytes.push(intVersion2 >> 24 & 0xff); - bytes.push(intVersion2 >> 16 & 0xff); - bytes.push(intVersion2 >> 8 & 0xff); - bytes.push(intVersion2 & 0xff); - - bytes.push(intVersion1 >> 24 & 0xff); - bytes.push(intVersion1 >> 16 & 0xff); - bytes.push(intVersion1 >> 8 & 0xff); - bytes.push(intVersion1 & 0xff); - - return bytes; - } -} - -var ErlangTypes = { - Tuple, - PID, - Reference, - BitString: BitString$1 -}; - -/* @flow */ - -const BitString = ErlangTypes.BitString; - -function resolveSymbol(pattern) { - return function (value) { - return is_symbol(value) && value === pattern; - }; -} - -function resolveString(pattern) { - return function (value) { - return is_string(value) && value === pattern; - }; -} - -function resolveNumber(pattern) { - return function (value) { - return is_number(value) && value === pattern; - }; -} - -function resolveBoolean(pattern) { - return function (value) { - return is_boolean(value) && value === pattern; - }; -} - -function resolveFunction(pattern) { - return function (value) { - return is_function(value) && value === pattern; - }; -} - -function resolveNull(pattern) { - return function (value) { - return is_null(value); - }; -} - -function resolveBound(pattern) { - return function (value, args) { - if (typeof value === typeof pattern.value && value === pattern.value) { - return true; - } - - return false; - }; -} - -function resolveWildcard() { - return function () { - return true; - }; -} - -function resolveVariable(pattern) { - return function (value, args) { - if (pattern.name === null) { - args.push(value); - } else if (!pattern.name.startsWith('_')) { - args.push(namedVariableResult(pattern.name, value)); - } - - return true; - }; -} - -function resolveHeadTail(pattern) { - const headMatches = buildMatch(pattern.head); - const tailMatches = buildMatch(pattern.tail); - - return function (value, args) { - if (!is_array(value) || value.length === 0) { - return false; - } - - const head = value[0]; - const tail = value.slice(1); - - if (headMatches(head, args) && tailMatches(tail, args)) { - return true; - } - - return false; - }; -} - -function resolveCapture(pattern) { - const matches = buildMatch(pattern.value); - - return function (value, args) { - if (matches(value, args)) { - args.push(value); - return true; - } - - return false; - }; -} - -function resolveStartsWith(pattern) { - const prefix = pattern.prefix; - - return function (value, args) { - if (is_string(value) && value.startsWith(prefix)) { - args.push(value.substring(prefix.length)); - return true; - } - - return false; - }; -} - -function resolveType(pattern) { - return function (value, args) { - if (value instanceof pattern.type) { - const matches = buildMatch(pattern.objPattern); - return matches(value, args); - } - - return false; - }; -} - -function resolveArray(pattern) { - const matches = pattern.map(x => buildMatch(x)); - - return function (value, args) { - if (!is_array(value) || value.length != pattern.length) { - return false; - } - - return value.every(function (v, i) { - return matches[i](value[i], args); - }); - }; -} - -function resolveMap(pattern) { - let matches = new Map(); - - const keys = Array.from(pattern.keys()); - - for (let key of keys) { - matches.set(key, buildMatch(pattern.get(key))); - } - - return function (value, args) { - if (!is_map(value) || pattern.size > value.size) { - return false; - } - - for (let key of keys) { - if (!value.has(key) || !matches.get(key)(value.get(key), args)) { - return false; - } - } - - return true; - }; -} - -function resolveObject(pattern) { - let matches = {}; - - const keys = Object.keys(pattern).concat(Object.getOwnPropertySymbols(pattern)); - - for (let key of keys) { - matches[key] = buildMatch(pattern[key]); - } - - return function (value, args) { - if (!is_object(value) || pattern.length > value.length) { - return false; - } - - for (let key of keys) { - if (!(key in value) || !matches[key](value[key], args)) { - return false; - } - } - - return true; - }; -} - -function resolveBitString(pattern) { - let patternBitString = []; - - for (let bitstringMatchPart of pattern.values) { - if (is_variable(bitstringMatchPart.value)) { - let size = getSize(bitstringMatchPart.unit, bitstringMatchPart.size); - fillArray(patternBitString, size); - } else { - patternBitString = patternBitString.concat(new BitString(bitstringMatchPart).value); - } - } - - let patternValues = pattern.values; - - return function (value, args) { - let bsValue = null; - - if (!is_string(value) && !(value instanceof BitString)) { - return false; - } - - if (is_string(value)) { - bsValue = new BitString(BitString.binary(value)); - } else { - bsValue = value; - } - - let beginningIndex = 0; - - for (let i = 0; i < patternValues.length; i++) { - let bitstringMatchPart = patternValues[i]; - - if (is_variable(bitstringMatchPart.value) && bitstringMatchPart.type == 'binary' && bitstringMatchPart.size === undefined && i < patternValues.length - 1) { - throw new Error('a binary field without size is only allowed at the end of a binary pattern'); - } - - let size = 0; - let bsValueArrayPart = []; - let patternBitStringArrayPart = []; - size = getSize(bitstringMatchPart.unit, bitstringMatchPart.size); - - if (i === patternValues.length - 1) { - bsValueArrayPart = bsValue.value.slice(beginningIndex); - patternBitStringArrayPart = patternBitString.slice(beginningIndex); - } else { - bsValueArrayPart = bsValue.value.slice(beginningIndex, beginningIndex + size); - patternBitStringArrayPart = patternBitString.slice(beginningIndex, beginningIndex + size); - } - - if (is_variable(bitstringMatchPart.value)) { - switch (bitstringMatchPart.type) { - case 'integer': - if (bitstringMatchPart.attributes && bitstringMatchPart.attributes.indexOf('signed') != -1) { - args.push(new Int8Array([bsValueArrayPart[0]])[0]); - } else { - args.push(new Uint8Array([bsValueArrayPart[0]])[0]); - } - break; - - case 'float': - if (size === 64) { - args.push(Float64Array.from(bsValueArrayPart)[0]); - } else if (size === 32) { - args.push(Float32Array.from(bsValueArrayPart)[0]); - } else { - return false; - } - break; - - case 'bitstring': - args.push(createBitString(bsValueArrayPart)); - break; - - case 'binary': - args.push(String.fromCharCode.apply(null, new Uint8Array(bsValueArrayPart))); - break; - - case 'utf8': - args.push(String.fromCharCode.apply(null, new Uint8Array(bsValueArrayPart))); - break; - - case 'utf16': - args.push(String.fromCharCode.apply(null, new Uint16Array(bsValueArrayPart))); - break; - - case 'utf32': - args.push(String.fromCharCode.apply(null, new Uint32Array(bsValueArrayPart))); - break; - - default: - return false; - } - } else if (!arraysEqual(bsValueArrayPart, patternBitStringArrayPart)) { - return false; - } - - beginningIndex = beginningIndex + size; - } - - return true; - }; -} - -function getSize(unit, size) { - return unit * size / 8; -} - -function arraysEqual(a, b) { - if (a === b) return true; - if (a == null || b == null) return false; - if (a.length != b.length) return false; - - for (var i = 0; i < a.length; ++i) { - if (a[i] !== b[i]) return false; - } - - return true; -} - -function fillArray(arr, num) { - for (let i = 0; i < num; i++) { - arr.push(0); - } -} - -function createBitString(arr) { - let integerParts = arr.map(elem => BitString.integer(elem)); - return new BitString(...integerParts); -} - -function resolveNoMatch() { - return function () { - return false; - }; -} - -const patternMap = new Map(); -patternMap.set(Variable.prototype, resolveVariable); -patternMap.set(Wildcard.prototype, resolveWildcard); -patternMap.set(HeadTail.prototype, resolveHeadTail); -patternMap.set(StartsWith.prototype, resolveStartsWith); -patternMap.set(Capture.prototype, resolveCapture); -patternMap.set(Bound.prototype, resolveBound); -patternMap.set(Type.prototype, resolveType); -patternMap.set(BitStringMatch.prototype, resolveBitString); -patternMap.set(Number.prototype, resolveNumber); -patternMap.set(Symbol.prototype, resolveSymbol); -patternMap.set(Map.prototype, resolveMap); -patternMap.set(Array.prototype, resolveArray); -patternMap.set(String.prototype, resolveString); -patternMap.set(Boolean.prototype, resolveBoolean); -patternMap.set(Function.prototype, resolveFunction); -patternMap.set(Object.prototype, resolveObject); - -function buildMatch(pattern) { - if (pattern === null) { - return resolveNull(pattern); - } - - if (typeof pattern === 'undefined') { - return resolveWildcard(pattern); - } - - const type$$1 = pattern.constructor.prototype; - const resolver = patternMap.get(type$$1); - - if (resolver) { - return resolver(pattern); - } - - if (typeof pattern === 'object') { - return resolveObject(pattern); - } - - return resolveNoMatch(); -} - -class MatchError extends Error { - constructor(arg) { - super(); - - if (typeof arg === 'symbol') { - this.message = 'No match for: ' + arg.toString(); - } else if (Array.isArray(arg)) { - let mappedValues = arg.map(x => { - if (x === null) { - return 'null'; - } else if (typeof x === 'undefined') { - return 'undefined'; - } - - return x.toString(); - }); - - this.message = 'No match for: ' + mappedValues; - } else { - this.message = 'No match for: ' + arg; - } - - this.stack = new Error().stack; - this.name = this.constructor.name; - } -} - -class Clause { - constructor(pattern, fn, guard = () => true) { - this.pattern = buildMatch(pattern); - this.arity = pattern.length; - this.optionals = getOptionalValues(pattern); - this.fn = fn; - this.guard = guard; - } -} - -function clause(pattern, fn, guard = () => true) { - return new Clause(pattern, fn, guard); -} - - - -function defmatch(...clauses) { - const arities = getArityMap(clauses); - - return function (...args) { - let [funcToCall, params] = findMatchingFunction(args, arities); - return funcToCall.apply(this, params); - }; -} - -function defmatchgen(...clauses) { - const arities = getArityMap(clauses); - - return function* (...args) { - let [funcToCall, params] = findMatchingFunction(args, arities); - return yield* funcToCall.apply(this, params); - }; -} - -function defmatchGen(...args) { - return defmatchgen(...args); -} - -function defmatchAsync(...clauses) { - const arities = getArityMap(clauses); - - return async function (...args) { - if (arities.has(args.length)) { - const arityClauses = arities.get(args.length); - - let funcToCall = null; - let params = null; - for (let processedClause of arityClauses) { - let result = []; - args = fillInOptionalValues(args, processedClause.arity, processedClause.optionals); - - const doesMatch = processedClause.pattern(args, result); - const [filteredResult, allNamesMatch] = checkNamedVariables(result); - - if (doesMatch && allNamesMatch && (await processedClause.guard.apply(this, result))) { - funcToCall = processedClause.fn; - params = result; - break; - } - } - - if (!funcToCall) { - console.error('No match for:', args); - throw new MatchError(args); - } - - return funcToCall.apply(this, params); - } else { - console.error('Arity of', args.length, 'not found. No match for:', args); - throw new MatchError(args); - } - }; -} - -function findMatchingFunction(args, arities) { - if (arities.has(args.length)) { - const arityClauses = arities.get(args.length); - - let funcToCall = null; - let params = null; - for (let processedClause of arityClauses) { - let result = []; - args = fillInOptionalValues(args, processedClause.arity, processedClause.optionals); - - const doesMatch = processedClause.pattern(args, result); - const [filteredResult, allNamesMatch] = checkNamedVariables(result); - - if (doesMatch && allNamesMatch && processedClause.guard.apply(this, filteredResult)) { - funcToCall = processedClause.fn; - params = filteredResult; - break; - } - } - - if (!funcToCall) { - console.error('No match for:', args); - throw new MatchError(args); - } - - return [funcToCall, params]; - } else { - console.error('Arity of', args.length, 'not found. No match for:', args); - throw new MatchError(args); - } -} - -function getArityMap(clauses) { - let map = new Map(); - - for (const clause of clauses) { - const range = getArityRange(clause); - - for (const arity of range) { - let arityClauses = []; - - if (map.has(arity)) { - arityClauses = map.get(arity); - } - - arityClauses.push(clause); - map.set(arity, arityClauses); - } - } - - return map; -} - -function getArityRange(clause) { - const min = clause.arity - clause.optionals.length; - const max = clause.arity; - - let range = [min]; - - while (range[range.length - 1] != max) { - range.push(range[range.length - 1] + 1); - } - - return range; -} - -function getOptionalValues(pattern) { - let optionals = []; - - for (let i = 0; i < pattern.length; i++) { - if (pattern[i] instanceof Variable && pattern[i].default_value != Symbol.for('tailored.no_value')) { - optionals.push([i, pattern[i].default_value]); - } - } - - return optionals; -} - -function fillInOptionalValues(args, arity, optionals) { - if (args.length === arity || optionals.length === 0) { - return args; - } - - if (args.length + optionals.length < arity) { - return args; - } - - let numberOfOptionalsToFill = arity - args.length; - let optionalsToRemove = optionals.length - numberOfOptionalsToFill; - - let optionalsToUse = optionals.slice(optionalsToRemove); - - for (let [index, value] of optionalsToUse) { - args.splice(index, 0, value); - if (args.length === arity) { - break; - } - } - - return args; -} - -function match(pattern, expr, guard = () => true) { - let result = []; - let processedPattern = buildMatch(pattern); - const doesMatch = processedPattern(expr, result); - const [filteredResult, allNamesMatch] = checkNamedVariables(result); - - if (doesMatch && allNamesMatch && guard.apply(this, filteredResult)) { - return filteredResult; - } else { - console.error('No match for:', expr); - throw new MatchError(expr); - } -} - -function checkNamedVariables(results) { - const namesMap = {}; - const filteredResults = []; - - for (let i = 0; i < results.length; i++) { - const current = results[i]; - if (current instanceof NamedVariableResult) { - if (namesMap[current.name] && namesMap[current.name] !== current.value) { - return [results, false]; - } else if (namesMap[current.name] && namesMap[current.name] === current.value) { - filteredResults.push(current.value); - } else { - namesMap[current.name] = current.value; - filteredResults.push(current.value); - } - } else { - filteredResults.push(current); - } - } - - return [filteredResults, true]; -} - -function match_or_default(pattern, expr, guard = () => true, default_value = null) { - let result = []; - let processedPattern = buildMatch(pattern); - const doesMatch = processedPattern(expr, result); - const [filteredResult, allNamesMatch] = checkNamedVariables(result); - - if (doesMatch && allNamesMatch && guard.apply(this, filteredResult)) { - return filteredResult; - } else { - return default_value; - } -} - -const NO_MATCH = Symbol(); - -function bitstring_generator(pattern, bitstring) { - return function () { - let returnResult = []; - let bsSlice = bitstring.slice(0, pattern.byte_size()); - let i = 1; - - while (bsSlice.byte_size == pattern.byte_size()) { - const result = match_or_default(pattern, bsSlice, () => true, NO_MATCH); - - if (result != NO_MATCH) { - const [value] = result; - returnResult.push(result); - } - - bsSlice = bitstring.slice(pattern.byte_size() * i, pattern.byte_size() * (i + 1)); - - i++; - } - - return returnResult; - }; -} - -function list_generator(pattern, list) { - return function () { - let returnResult = []; - for (let i of list) { - const result = match_or_default(pattern, i, () => true, NO_MATCH); - if (result != NO_MATCH) { - const [value] = result; - returnResult.push(value); - } - } - - return returnResult; - }; -} - -function list_comprehension(expression, generators) { - const generatedValues = run_generators(generators.pop()(), generators); - - let result = []; - - for (let value of generatedValues) { - if (expression.guard.apply(this, value)) { - result.push(expression.fn.apply(this, value)); - } - } - - return result; -} - -function run_generators(generator, generators) { - if (generators.length == 0) { - return generator.map(x => { - if (Array.isArray(x)) { - return x; - } else { - return [x]; - } - }); - } else { - const list = generators.pop(); - - let next_gen = []; - for (let j of list()) { - for (let i of generator) { - next_gen.push([j].concat(i)); - } - } - - return run_generators(next_gen, generators); - } -} - -function bitstring_comprehension(expression, generators) { - const generatedValues = run_generators(generators.pop()(), generators); - - let result = []; - - for (let value of generatedValues) { - if (expression.guard.apply(this, value)) { - result.push(expression.fn.apply(this, value)); - } - } - - result = result.map(x => ErlangTypes.BitString.integer(x)); - return new ErlangTypes.BitString(...result); -} - -var Patterns = { - defmatch, - match, - MatchError, - variable, - wildcard, - startsWith, - capture, - headTail, - type, - bound, - Clause, - clause, - bitStringMatch, - match_or_default, - defmatchgen, - list_comprehension, - list_generator, - bitstring_generator, - bitstring_comprehension, - defmatchGen, - defmatchAsync -}; - -// https://github.com/airportyh/protomorphism -class Protocol { - constructor(spec) { - this.registry = new Map(); - this.fallback = null; - - function createFun(funName) { - return function (...args) { - const thing = args[0]; - let fun = null; - - if (thing === null && this.hasImplementation(Symbol('null'))) { - fun = this.registry.get(Symbol)[funName]; - } else if (Number.isInteger(thing) && this.hasImplementation(Core.Integer)) { - fun = this.registry.get(Core.Integer)[funName]; - } else if (typeof thing === 'number' && !Number.isInteger(thing) && this.hasImplementation(Core.Float)) { - fun = this.registry.get(Core.Float)[funName]; - } else if (typeof thing === 'string' && this.hasImplementation(Core.BitString)) { - fun = this.registry.get(Core.BitString)[funName]; - } else if (thing && thing instanceof Map && thing.has(Symbol.for('__struct__')) && this.hasImplementation(thing)) { - fun = this.registry.get(thing.get(Symbol.for('__struct__')).__MODULE__)[funName]; - } else if (thing !== null && this.hasImplementation(thing)) { - fun = this.registry.get(thing.constructor)[funName]; - } else if (this.fallback) { - fun = this.fallback[funName]; - } - - if (fun != null) { - const retval = fun.apply(this, args); - return retval; - } - - throw new Error(`No implementation found for ${thing}`); - }; - } - - for (const funName in spec) { - this[funName] = createFun(funName).bind(this); - } - } - - implementation(type, implementation) { - if (type === null) { - this.fallback = implementation; - } else { - this.registry.set(type, implementation); - } - } - - hasImplementation(thing) { - if (thing === Core.Integer || thing === Core.Float || thing === Core.BitString) { - return this.registry.has(thing); - } else if (thing && thing instanceof Map && thing.has(Symbol.for('__struct__'))) { - return this.registry.has(thing.get(Symbol.for('__struct__')).__MODULE__); - } - - return this.registry.has(thing.constructor); - } -} - -function iterator_to_reducer(iterable, acc, fun) { - const iterator = iterable[Symbol.iterator](); - let x = iterator.next(); - let _acc = acc; - - while (x.done === false) { - _acc = fun(x.value, _acc.get(1)); - if (_acc.get(0) === Symbol.for('halt')) { - return new Core.Tuple(Symbol.for('halted'), _acc.get(1)); - } else if (_acc.get(0) === Symbol.for('suspend')) { - return new Core.Tuple(Symbol.for('suspended'), _acc.get(1), new_acc => { - return iterator_to_reducer(iterator, new_acc, fun); - }); - } - - x = iterator.next(); - } - - return new Core.Tuple(Symbol.for('done'), _acc.get(1)); -} - -function call_property(item, property) { - if (!property) { - if (item instanceof Function || typeof item === 'function') { - return item(); - } - - return item; - } - - if (item instanceof Map) { - let prop = null; - - if (item.has(property)) { - prop = property; - } else if (item.has(Symbol.for(property))) { - prop = Symbol.for(property); - } - - if (prop === null) { - throw new Error(`Property ${property} not found in ${item}`); - } - - if (item.get(prop) instanceof Function || typeof item.get(prop) === 'function') { - return item.get(prop)(); - } - return item.get(prop); - } - - let prop = null; - - if (typeof item === 'number' || typeof item === 'symbol' || typeof item === 'boolean' || typeof item === 'string') { - if (item[property] !== undefined) { - prop = property; - } else if (item[Symbol.for(property)] !== undefined) { - prop = Symbol.for(property); - } - } else if (property in item) { - prop = property; - } else if (Symbol.for(property) in item) { - prop = Symbol.for(property); - } - - if (prop === null) { - throw new Error(`Property ${property} not found in ${item}`); - } - - if (item[prop] instanceof Function || typeof item[prop] === 'function') { - return item[prop](); - } - return item[prop]; -} - -function defprotocol(spec) { - return new Protocol(spec); -} - -function defimpl(protocol, type, impl) { - protocol.implementation(type, impl); -} - -function build_namespace(ns, ns_string) { - let parts = ns_string.split('.'); - const root = ns; - let parent = ns; - - if (parts[0] === 'Elixir') { - parts = parts.slice(1); - } - - for (const part of parts) { - if (typeof parent[part] === 'undefined') { - parent[part] = {}; - } - - parent = parent[part]; - } - - root.__table__ = ns.__table__ || {}; - root.__table__[Symbol.for(ns_string)] = parent; - - return parent; -} - -function map_to_object(map) { - const object = {}; - - for (const [key, value] of map.entries()) { - if (value instanceof Map) { - object[key] = map_to_object(value); - } else { - object[key] = value; - } - } - - return object; -} - -class Recurse { - constructor(func) { - this.func = func; - } -} - -function trampoline$1(f) { - let currentValue = f; - - while (currentValue && currentValue instanceof Recurse) { - currentValue = currentValue.func(); - } - - return currentValue; -} - -var Functions = { - call_property, - defprotocol, - defimpl, - build_namespace, - iterator_to_reducer, - map_to_object, - trampoline: trampoline$1, - Recurse -}; - -function _case(condition, clauses) { - return Core.Patterns.defmatch(...clauses)(condition); -} - -function cond(...clauses) { - for (const clause of clauses) { - if (clause[0]) { - return clause[1](); - } - } - - throw new Error(); -} - -function _for(expression, generators, collectable_protocol, into = []) { - let [result, fun] = collectable_protocol.into(into); - - const generatedValues = run_list_generators(generators.pop()(), generators); - - for (const value of generatedValues) { - if (expression.guard.apply(this, value)) { - result = fun(result, new Core.Tuple(Symbol.for('cont'), expression.fn.apply(this, value))); - } - } - - return fun(result, Symbol.for('done')); -} - -function run_list_generators(generator, generators) { - if (generators.length == 0) { - return generator.map(x => { - if (Array.isArray(x)) { - return x; - } - return [x]; - }); - } - const list = generators.pop(); - - const next_gen = []; - for (const j of list()) { - for (const i of generator) { - next_gen.push([j].concat(i)); - } - } - - return run_list_generators(next_gen, generators); -} - -function _try(do_fun, rescue_function, catch_fun, else_function, after_function) { - let result = null; - - try { - result = do_fun(); - } catch (e) { - let ex_result = null; - - if (rescue_function) { - try { - ex_result = rescue_function(e); - return ex_result; - } catch (ex) { - if (ex instanceof Core.Patterns.MatchError) { - throw ex; - } - } - } - - if (catch_fun) { - try { - ex_result = catch_fun(e); - return ex_result; - } catch (ex) { - if (ex instanceof Core.Patterns.MatchError) { - throw ex; - } - } - } - - throw e; - } finally { - if (after_function) { - after_function(); - } - } - - if (else_function) { - try { - return else_function(result); - } catch (ex) { - if (ex instanceof Core.Patterns.MatchError) { - throw new Error('No Match Found in Else'); - } - - throw ex; - } - } else { - return result; - } -} - -function _with(...args) { - let argsToPass = []; - let successFunction = null; - let elseFunction = null; - - if (typeof args[args.length - 2] === 'function') { - [successFunction, elseFunction] = args.splice(-2); - } else { - successFunction = args.pop(); - } - - for (let i = 0; i < args.length; i++) { - const [pattern, func] = args[i]; - - const result = func(...argsToPass); - - const patternResult = Core.Patterns.match_or_default(pattern, result); - - if (patternResult == null) { - if (elseFunction) { - return elseFunction.call(null, result); - } - return result; - } - - argsToPass = argsToPass.concat(patternResult); - } - - return successFunction(...argsToPass); -} - -function receive(clauses, after) { - console.warn('Receive not supported'); -} - -var SpecialForms = { - _case, - cond, - _for, - _try, - _with, - receive -}; - -// http://erlang.org/doc/man/lists.html -function reverse(list) { - return [...list].reverse(); -} - -function foreach(fun, list) { - list.forEach(x => fun(x)); - - return Symbol.for('ok'); -} - -function duplicate(n, elem) { - const list = []; - - while (list.length < n) { - list.push(elem); - } - - return list; -} - -function flatten(deepList, tail = []) { - const val = deepList.reduce((acc, value) => { - if (Array.isArray(value)) { - return acc.concat(flatten(value)); - } - - return acc.concat(value); - }, []); - - return val.concat(tail); -} - -function foldl(fun, acc0, list) { - return list.reduce((acc, value) => { - return fun(value, acc); - }, acc0); -} - -function foldr(fun, acc0, list) { - return foldl(fun, acc0, reverse(list)); -} - -function keyfind(key, n, tupleList) { - for (const tuple of tupleList) { - if (tuple.get(n - 1) === key) { - return tuple; - } - } - - return false; -} - -function keymember(key, n, tupleList) { - if (keyfind(key, n, tupleList) === false) { - return false; - } - - return true; -} - -function keyreplace(key, n, tupleList, newTuple) { - const newTupleList = [...tupleList]; - - for (let index = 0; index < newTupleList.length; index++) { - if (newTupleList[index].get(n - 1) === key) { - newTupleList[index] = newTuple; - return newTupleList; - } - } - - return newTupleList; -} - -function keysort(n, tupleList) { - const newTupleList = [...tupleList]; - - return newTupleList.sort((a, b) => { - if (a.get(n - 1) < b.get(n - 1)) { - return -1; - } else if (a.get(n - 1) > b.get(n - 1)) { - return 1; - } - - return 0; - }); -} - -function keystore(key, n, tupleList, newTuple) { - const newTupleList = [...tupleList]; - - for (let index = 0; index < newTupleList.length; index++) { - if (newTupleList[index].get(n - 1) === key) { - newTupleList[index] = newTuple; - return newTupleList; - } - } - - return newTupleList.concat(newTuple); -} - -function keydelete(key, n, tupleList) { - const newTupleList = []; - let deleted = false; - - for (let index = 0; index < tupleList.length; index++) { - if (deleted === false && tupleList[index].get(n - 1) === key) { - deleted = true; - } else { - newTupleList.push(tupleList[index]); - } - } - - return newTupleList; -} - -function keytake(key, n, tupleList) { - const result = keyfind(key, n, tupleList); - - if (result !== false) { - return new ErlangTypes.Tuple(result.get(n - 1), result, keydelete(key, n, tupleList)); - } - - return false; -} - -function mapfoldl(fun, acc0, list1) { - const listResult = []; - let accResult = acc0; - - for (const item of list1) { - const tuple = fun(item, accResult); - listResult.push(tuple.get(0)); - accResult = tuple.get(1); - } - - return new ErlangTypes.Tuple(listResult, accResult); -} - -function concat(things) { - return things.map(v => v.toString()).join(); -} - -function map(fun, list) { - return list.map(value => fun(value)); -} - -function filter(pred, list1) { - return list1.filter(x => pred(x)); -} - -function filtermap(fun, list1) { - const list2 = []; - - for (const item of list1) { - const value = fun(item); - - if (value === true) { - list2.push(item); - } else if (value instanceof ErlangTypes.Tuple && value.get(0) === true) { - list2.push(value.get(1)); - } - } - - return list2; -} - -function member(elem, list) { - for (const item of list) { - if (item === elem) { - return true; - } - } - - return false; -} - -function all(pred, list) { - for (const item of list) { - if (pred(item) === false) { - return false; - } - } - - return true; -} - -function any(pred, list) { - for (const item of list) { - if (pred(item) === true) { - return true; - } - } - - return false; -} - -function splitwith(pred, list) { - let switchToList2 = false; - const list1 = []; - const list2 = []; - - for (const item of list) { - if (switchToList2 === true) { - list2.push(item); - } else if (pred(item) === true) { - list1.push(item); - } else { - switchToList2 = true; - list2.push(item); - } - } - - return new ErlangTypes.Tuple(list1, list2); -} - -function sort(...args) { - if (args.length === 1) { - const list2 = [...args[0]]; - return list2.sort(); - } - - const fun = args[0]; - const list2 = [...args[1]]; - - return list2.sort((a, b) => { - const result = fun(a, b); - - if (result === true) { - return -1; - } - - return 1; - }); -} - -var lists = { - reverse, - foreach, - duplicate, - flatten, - foldl, - foldr, - keydelete, - keyfind, - keymember, - keyreplace, - keysort, - keystore, - keytake, - mapfoldl, - concat, - map, - filter, - filtermap, - member, - all, - any, - splitwith, - sort -}; - -// http://erlang.org/doc/man/erlang.html -const selfPID = new ErlangTypes.PID(); - -function atom_to_list(atom) { - return Symbol.keyFor(atom); -} - -function atom_to_binary(atom, encoding = Symbol.for('utf8')) { - if (encoding !== Symbol.for('utf8')) { - throw new Error(`unsupported encoding ${encoding}`); - } - - if (atom.__MODULE__) { - return Symbol.keyFor(atom.__MODULE__); - } - - return Symbol.keyFor(atom); -} - -function binary_to_atom(binary, encoding = Symbol.for('utf8')) { - if (encoding !== Symbol.for('utf8')) { - throw new Error(`unsupported encoding ${encoding}`); - } - - return Symbol.for(binary); -} - -function binary_to_existing_atom(binary, encoding = Symbol.for('utf8')) { - return binary_to_atom(binary, encoding); -} - -function list_concatenation(list1, list2) { - return list1.concat(list2); -} - -function list_subtraction(list1, list2) { - const list = [...list1]; - - for (const item of list2) { - const index = list.indexOf(item); - - if (index > -1) { - list.splice(index, 1); - } - } - - return list; -} - -function div(left, right) { - return left / right; -} - -function not(x) { - return !x; -} - -function rem(left, right) { - return left % right; -} - -function band(left, right) { - return left & right; -} - -function bor(left, right) { - return left | right; -} - -function bnot(x) { - return ~x; -} - -function bsl(left, right) { - return left << right; -} - -function bsr(left, right) { - return left >> right; -} - -function bxor(left, right) { - return left ^ right; -} - -function is_atom(value) { - return typeof value === 'symbol' || value instanceof Symbol || value.__MODULE__; -} - -function is_bitstring$1(value) { - return value instanceof ErlangTypes.BitString; -} - -function is_boolean$1(value) { - return typeof value === 'boolean' || value instanceof Boolean; -} - -function is_number$1(value) { - return typeof value === 'number' || value instanceof Number; -} - -function is_float(value) { - return is_number$1(value) && !Number.isInteger(value); -} - -function is_function$1(value) { - return typeof value === 'function' || value instanceof Function; -} - -function is_integer(value) { - return Number.isInteger(value); -} - -function is_list(value) { - return Array.isArray(value); -} - -function is_map$1(value) { - return value instanceof Map; -} - -function is_pid(value) { - return value instanceof ErlangTypes.PID; -} - -function is_port() { - return false; -} - -function is_reference(value) { - return value instanceof ErlangTypes.Reference; -} - -function is_tuple(value) { - return value instanceof ErlangTypes.Tuple; -} - -function is_binary(value) { - return typeof value === 'string' || value instanceof String; -} - -function element(n, tuple) { - return tuple.get(n - 1); -} - -function setelement(index, tuple1, value) { - const tupleData = [...tuple1.values]; - - tupleData[index - 1] = value; - - return new ErlangTypes.Tuple(...tupleData); -} - -function make_tuple(arity, initialValue) { - const list = []; - - for (let i = 0; i < arity; i++) { - list.push(initialValue); - } - - return new ErlangTypes.Tuple(...list); -} - -function insert_element(index, tuple, term) { - const list = [...tuple.values]; - list.splice(index - 1, 0, term); - - return new ErlangTypes.Tuple(...list); -} - -function append_element(tuple, term) { - const list = [...tuple.values]; - list.push(term); - - return new ErlangTypes.Tuple(...list); -} - -function delete_element(index, tuple) { - const list = [...tuple.values]; - list.splice(index - 1, 1); - - return new ErlangTypes.Tuple(...list); -} - -function tuple_to_list(tuple) { - const list = [...tuple.values]; - return list; -} - -function abs(number) { - return Math.abs(number); -} - -function apply(...args) { - if (args.length === 2) { - return args[0].apply(this, ...args[1]); - } - - return args[0][atom_to_binary(args[1])].apply(this, ...args[2]); -} - -function binary_part(binary, start, _length) { - return binary.substring(start, start + _length); -} - -function bit_size(bitstring) { - return bitstring.bit_size; -} - -function byte_size(bitstring) { - return bitstring.byte_size; -} - -function hd(list) { - return list[0]; -} - -function length(list) { - return list.length; -} - -function make_ref() { - return new ErlangTypes.Reference(); -} - -function map_size(map) { - return map.size; -} - -function max(first, second) { - return Math.max(first, second); -} - -function min(first, second) { - return Math.min(first, second); -} - -function round(number) { - return Math.round(number); -} - -function tl(list) { - return list.slice(1); -} - -function trunc(number) { - return Math.trunc(number); -} - -function tuple_size(tuple) { - return tuple.length; -} - -function binary_to_float(str) { - return parseFloat(str); -} - -function binary_to_integer(str, base = 10) { - return parseInt(str, base); -} - -function process_info(pid, item) { - if (item) { - if (item === Symbol.for('current_stacktrace')) { - return new ErlangTypes.Tuple(item, []); - } - - return new ErlangTypes.Tuple(item, null); - } - - return []; -} - -function list_to_binary(iolist) { - const iolistFlattened = lists.flatten(iolist); - - const value = iolistFlattened.reduce((acc, current) => { - if (current === null) { - return acc; - } else if (is_integer(current)) { - return acc + String.fromCodePoint(current); - } else if (is_bitstring$1(current)) { - return acc + String.fromCodePoint(...current.value); - } - - return acc + current; - }, ''); - - return value; -} - -function iolist_to_binary(ioListOrBinary) { - if (ioListOrBinary === null) { - return ''; - } - - if (is_binary(ioListOrBinary)) { - return ioListOrBinary; - } - - if (is_bitstring$1(ioListOrBinary)) { - return String.fromCodePoint(...ioListOrBinary.value); - } - - if (is_number$1(ioListOrBinary)) { - return String.fromCodePoint(ioListOrBinary); - } - - const iolistFlattened = lists.flatten(ioListOrBinary); - - const value = iolistFlattened.reduce((acc, current) => { - if (current === null) { - return acc; - } else if (is_integer(current)) { - return acc + String.fromCodePoint(current); - } else if (is_bitstring$1(current)) { - return acc + String.fromCodePoint(...current.value); - } - - return acc + iolist_to_binary(current); - }, ''); - - return value; -} - -function io_size(ioListOrBinary) { - return iolist_to_binary(ioListOrBinary).length; -} - -function integer_to_binary(integer, base = 10) { - return integer.toString(base); -} - -function node() { - return Symbol.for('nonode@nohost'); -} - -function self$1() { - return selfPID; -} - -function _throw(term) { - throw term; -} - -function error(reason) { - throw new ErlangTypes.Tuple(reason, []); -} - -function exit(...args) { - if (args.length === 2) { - throw args[1]; - } else { - throw args[0]; - } -} - -function raise(_class, reason) { - if (_class === Symbol.for('throw')) { - _throw(reason); - } else if (_class === Symbol.for('error')) { - error(reason); - } else { - exit(reason); - } -} - -var erlang = { - atom_to_binary, - binary_to_atom, - binary_to_existing_atom, - list_concatenation, - list_subtraction, - div, - not, - rem, - band, - bor, - bsl, - bsr, - bxor, - bnot, - is_bitstring: is_bitstring$1, - is_boolean: is_boolean$1, - is_float, - is_function: is_function$1, - is_integer, - is_list, - is_map: is_map$1, - is_number: is_number$1, - is_pid, - is_port, - is_reference, - is_tuple, - is_atom, - is_binary, - element, - setelement, - make_tuple, - insert_element, - append_element, - delete_element, - tuple_to_list, - abs, - apply, - binary_part, - bit_size, - byte_size, - hd, - length, - make_ref, - map_size, - max, - min, - round, - tl, - trunc, - tuple_size, - binary_to_float, - binary_to_integer, - process_info, - iolist_to_binary, - io_size, - integer_to_binary, - atom_to_list, - node, - self: self$1, - throw: _throw, - error, - exit, - raise, - list_to_binary -}; - -// http://erlang.org/doc/man/maps.html -const OK = Symbol.for('ok'); -const ERROR = Symbol.for('error'); -const BADMAP = Symbol.for('badmap'); -const BADKEY = Symbol.for('badkey'); - -function find(key, map) { - if (erlang.is_map(map) === false) { - return new ErlangTypes.Tuple(BADMAP, map); - } - - const value = map.get(key); - - if (typeof value !== 'undefined') { - return new ErlangTypes.Tuple(OK, value); - } - - return ERROR; -} - -function fold(fun, init, map) { - let acc = init; - - for (const [key, value] of map.entries()) { - acc = fun(key, value, acc); - } - - return acc; -} - -function remove(key, map1) { - if (erlang.is_map(map1) === false) { - return new ErlangTypes.Tuple(BADMAP, map1); - } - - const map2 = new Map(map1); - - map2.delete(key); - - return map2; -} - -function to_list(map) { - if (erlang.is_map(map) === false) { - return new ErlangTypes.Tuple(BADMAP, map); - } - - const list = []; - - for (const [key, value] of map.entries()) { - list.push(new ErlangTypes.Tuple(key, value)); - } - - return list; -} - -function from_list(list) { - return list.reduce((acc, item) => { - const [key, value] = item; - acc.set(key, value); - - return acc; - }, new Map()); -} - -function keys(map) { - if (erlang.is_map(map) === false) { - return new ErlangTypes.Tuple(BADMAP, map); - } - - return Array.from(map.keys()); -} - -function values$1(map) { - if (erlang.is_map(map) === false) { - return new ErlangTypes.Tuple(BADMAP, map); - } - - return Array.from(map.values()); -} - -function is_key(key, map) { - return map.has(key); -} - -function put(key, value, map1) { - if (erlang.is_map(map1) === false) { - return new ErlangTypes.Tuple(BADMAP, map1); - } - - const map2 = new Map(map1); - map2.set(key, value); - - return map2; -} - -function merge(map1, map2) { - if (erlang.is_map(map1) === false) { - return new ErlangTypes.Tuple(BADMAP, map1); - } - - if (erlang.is_map(map2) === false) { - return new ErlangTypes.Tuple(BADMAP, map2); - } - - return new Map([...map1, ...map2]); -} - -function update(key, value, map1) { - if (erlang.is_map(map1) === false) { - return new ErlangTypes.Tuple(BADMAP, map1); - } - - if (is_key(key, map1) === false) { - return new ErlangTypes.Tuple(BADKEY, key); - } - - return new Map([...map1, [key, value]]); -} - -function get(...args) { - const key = args[0]; - const map = args[1]; - - if (erlang.is_map(map) === false) { - return new ErlangTypes.Tuple(BADMAP, map); - } - - if (is_key(key)) { - return map.get(key); - } - - if (args.length === 3) { - return args[2]; - } - - return new ErlangTypes.Tuple(BADKEY, key); -} - -function take(key, map1) { - if (erlang.is_map(map1) === false) { - return new ErlangTypes.Tuple(BADMAP, map1); - } - - if (!is_key(key)) { - return ERROR; - } - - const value = map1.get(key); - const map2 = new Map(map1); - map2.delete(key); - - return new ErlangTypes.Tuple(value, map2); -} - -var maps = { - find, - fold, - remove, - to_list, - from_list, - keys, - values: values$1, - is_key, - put, - merge, - update, - get, - take -}; - -function warn(message) { - const messageString = message.join(''); - console.warn(`warning: ${messageString}`); - - return Symbol.for('ok'); -} - -var elixir_errors = { - warn -}; - -const MODULE = Symbol.for('elixir_config'); -const ets = new Map(); - -function _new(opts) { - ets.set(MODULE, new Map()); - ets.get(MODULE).set(MODULE, opts); - return MODULE; -} - -function _delete(module) { - ets.delete(module); - return true; -} - -function put$1(key, value) { - ets.get(MODULE).set(key, value); - return Symbol.for('ok'); -} - -function get$1(key) { - return ets.get(MODULE).get(key); -} - -function update$1(key, fun) { - const value = fun(ets.get(MODULE).get(key)); - put$1(key, value); - return value; -} - -function get_and_put(key, value) { - const oldValue = get$1(key); - put$1(key, value); - return oldValue; -} - -var elixir_config = { - new: _new, - delete: _delete, - put: put$1, - get: get$1, - update: update$1, - get_and_put -}; - -function put_chars(ioDevice, charData) { - const dataToWrite = erlang.iolist_to_binary(charData); - - if (ioDevice === Symbol.for('stderr')) { - console.error(dataToWrite); - } else { - console.log(dataToWrite); - } - - return Symbol.for('ok'); -} - -var io = { - put_chars -}; - -function copy(subject, n = 1) { - return subject.repeat(n); -} - -function list_to_bin(bytelist) { - return erlang.list_to_binary(bytelist); -} - -var binary = { - copy, - list_to_bin -}; - -function characters_to_list(characters) { - return characters.split('').map(c => c.codePointAt(0)); -} - -function characters_to_binary(characters) { - if (erlang.is_binary(characters)) { - return characters; - } - - return String.fromCodePoint(...characters); -} - -var unicode = { - characters_to_list, - characters_to_binary -}; - -function get_key(key) { - let real_key = key; - - if (__elixirscript_names__.has(key)) { - real_key = __elixirscript_names__.get(key); - } - - if (__elixirscript_store__.has(real_key)) { - return real_key; - } - - throw new Error(`Key ${real_key} not found`); -} - -function create(value, name = null) { - const key = new Core.PID(); - - if (name !== null) { - __elixirscript_names__.set(name, key); - } - - return __elixirscript_store__.set(key, value); -} - -function update$2(key, value) { - const real_key = get_key(key); - return __elixirscript_store__.set(real_key, value); -} - -function read(key) { - const real_key = get_key(key); - return __elixirscript_store__.get(real_key); -} - -function remove$1(key) { - const real_key = get_key(key); - return __elixirscript_store__.delete(real_key); -} - -var Store = { - create, - update: update$2, - read, - remove: remove$1 -}; - -class Integer {} -class Float {} - -function get_global() { - if (typeof self !== 'undefined') { - return self; - } else if (typeof window !== 'undefined') { - return window; - } else if (typeof global !== 'undefined') { - return global; - } - - console.warn('No global state found'); - return null; -} - -const globalState = get_global(); - -globalState.__elixirscript_store__ = new Map(); -globalState.__elixirscript_names__ = new Map(); - -var Core = { - Tuple: ErlangTypes.Tuple, - PID: ErlangTypes.PID, - BitString: ErlangTypes.BitString, - Patterns, - Integer, - Float, - Functions, - SpecialForms, - Store, - global: globalState, - erlang, - maps, - lists, - elixir_errors, - io, - binary, - unicode, - elixir_config -}; - -var elixir = { - Core -}; - -return elixir; - -}()); +var ElixirScript=function(){'use strict';/* @flow */function namedVariableResult(a,b){return new NamedVariableResult(a,b)}/* @flow */function is_number(a){return'number'==typeof a}function is_string(a){return'string'==typeof a}function is_boolean(a){return'boolean'==typeof a}function is_symbol(a){return'symbol'==typeof a}function is_object(a){return'object'==typeof a}function is_variable(a){return a instanceof Variable}function is_null(a){return null===a}function is_array(a){return Array.isArray(a)}function is_function(a){return'[object Function]'==Object.prototype.toString.call(a)}function is_map(a){return a instanceof Map}function resolveNull(){return function(a){return is_null(a)}}function resolveWildcard(){return function(){return!0}}function resolveObject(a){let b={};const c=Object.keys(a).concat(Object.getOwnPropertySymbols(a));for(let d of c)b[d]=buildMatch(a[d]);return function(d,e){if(!is_object(d)||a.length>d.length)return!1;for(let a of c)if(!(a in d)||!b[a](d[a],e))return!1;return!0}}function getSize(a,b){return a*b/8}function arraysEqual(c,a){if(c===a)return!0;if(null==c||null==a)return!1;if(c.length!=a.length)return!1;for(var b=0;bf.integer(a));return new f(...b)}function resolveNoMatch(){return function(){return!1}}function buildMatch(a){if(null===a)return resolveNull(a);if('undefined'==typeof a)return resolveWildcard(a);const b=a.constructor.prototype,c=g.get(b);return c?c(a):'object'==typeof a?resolveObject(a):resolveNoMatch()}function defmatchgen(...a){const b=getArityMap(a);return function*(...a){let[c,d]=findMatchingFunction(a,b);return yield*c.apply(this,d)}}function findMatchingFunction(a,b){if(b.has(a.length)){const c=b.get(a.length);let d=null,e=null;for(let b of c){let c=[];a=fillInOptionalValues(a,b.arity,b.optionals);const f=b.pattern(a,c),[g,h]=checkNamedVariables(c);if(f&&h&&b.guard.apply(this,g)){d=b.fn,e=g;break}}if(!d)throw console.error('No match for:',a),new MatchError(a);return[d,e]}throw console.error('Arity of',a.length,'not found. No match for:',a),new MatchError(a)}function getArityMap(a){let b=new Map;for(const c of a){const a=getArityRange(c);for(const d of a){let a=[];b.has(d)&&(a=b.get(d)),a.push(c),b.set(d,a)}}return b}function getArityRange(a){const b=a.arity-a.optionals.length,c=a.arity;let d=[b];for(;d[d.length-1]!=c;)d.push(d[d.length-1]+1);return d}function getOptionalValues(a){let b=[];for(let c=0;c!0,d=null){let e=[],f=buildMatch(a);const g=f(b,e),[h,i]=checkNamedVariables(e);return g&&i&&c.apply(this,h)?h:d}function run_generators(a,b){if(0==b.length)return a.map((a)=>{return Array.isArray(a)?a:[a]});const c=b.pop();let d=[];for(let e of c())for(let b of a)d.push([e].concat(b));return run_generators(d,b)}function iterator_to_reducer(a,b,c){const d=a[Symbol.iterator]();let e=d.next(),f=b;for(;!1===e.done;){if(f=c(e.value,f.get(1)),f.get(0)===Symbol.for('halt'))return new s.Tuple(Symbol.for('halted'),f.get(1));if(f.get(0)===Symbol.for('suspend'))return new s.Tuple(Symbol.for('suspended'),f.get(1),(a)=>{return iterator_to_reducer(d,a,c)});e=d.next()}return new s.Tuple(Symbol.for('done'),f.get(1))}function map_to_object(a){const b={};for(const[c,d]of a.entries())b[c]=d instanceof Map?map_to_object(d):d;return b}function run_list_generators(a,b){if(0==b.length)return a.map((a)=>{return Array.isArray(a)?a:[a]});const c=b.pop(),d=[];for(const e of c())for(const b of a)d.push([e].concat(b));return run_list_generators(d,b)}// http://erlang.org/doc/man/lists.html +function reverse(a){return[...a]}function flatten(a,b=[]){const c=a.reduce((a,b)=>{return Array.isArray(b)?a.concat(flatten(b)):a.concat(b)},[]);return c.concat(b)}function foldl(a,b,c){return c.reduce((b,c)=>{return a(c,b)},b)}function keyfind(a,b,c){for(const d of c)if(d.get(b-1)===a)return d;return!1}function keydelete(a,b,c){const d=[];let e=!1;for(let f=0;f{if(null===c)return b;return is_integer(c)?b+a(c):is_bitstring$1(c)?b+a(...c.value):b+iolist_to_binary(c)},'');return d}function _throw(a){throw a}function error(a){throw new e.Tuple(a,[])}function exit(...a){if(2===a.length)throw a[1];else throw a[0]}function is_key(a,b){return b.has(a)}function put$1(a,b){return q.get(p).set(a,b),Symbol.for('ok')}function get$1(a){return q.get(p).get(a)}function get_key(a){let b=a;if(__elixirscript_names__.has(a)&&(b=__elixirscript_names__.get(a)),__elixirscript_store__.has(b))return b;throw new Error(`Key ${b} not found`)}var a=String.fromCodePoint,b=Number.isInteger;class Variable{constructor(a=null,b=Symbol.for('tailored.no_value')){this.name=a,this.default_value=b}}class Wildcard{constructor(){}}class StartsWith{constructor(a){this.prefix=a}}class Capture{constructor(a){this.value=a}}class HeadTail{constructor(a,b){this.head=a,this.tail=b}}class Type{constructor(a,b={}){this.type=a,this.objPattern=b}}class Bound{constructor(a){this.value=a}}class BitStringMatch{constructor(...a){this.values=a}length(){return values.length}bit_size(){return 8*this.byte_size()}byte_size(){let a=0;for(let b of this.values)a+=b.unit*b.size/8;return a}getValue(a){return this.values(a)}getSizeOfValue(a){let b=this.getValue(a);return b.unit*b.size}getTypeOfValue(a){return this.getValue(a).type}}class NamedVariableResult{constructor(a,b){this.name=a,this.value=b}}class Tuple{constructor(...a){this.values=Object.freeze(a),this.length=this.values.length}get(a){return this.values[a]}count(){return this.values.length}[Symbol.iterator](){return this.values[Symbol.iterator]()}toString(){let a,b='';for(a=0;aBitString$1.integer(a));return new BitString$1(...d)}[Symbol.iterator](){return this.value[Symbol.iterator]()}toString(){var a,b='';for(a=0;a>'}process(a){let b=[];var c;for(c=0;cb?c.push(b):2048>b?c.push(192|b>>6,128|63&b):55296>b||57344<=b?c.push(224|b>>12,128|63&b>>6,128|63&b):(d++,b=65536+((1023&b)<<10|1023&a.charCodeAt(d)),c.push(240|b>>18,128|63&b>>12,128|63&b>>6,128|63&b));return c}static toUTF16Array(a){for(var b,c=[],d=0;d=b?(c.push(0),c.push(b)):(c.push(255&b>>8),c.push(255&b));return c}static toUTF32Array(a){for(var b,c=[],d=0;d=b?(c.push(0),c.push(0),c.push(0),c.push(b)):(c.push(0),c.push(0),c.push(255&b>>8),c.push(255&b));return c}//http://stackoverflow.com/questions/2003493/javascript-float-from-to-bits +static float32ToBytes(a){var b=[],c=new ArrayBuffer(4);new Float32Array(c)[0]=a;let d=new Uint32Array(c)[0];return b.push(255&d>>24),b.push(255&d>>16),b.push(255&d>>8),b.push(255&d),b}static float64ToBytes(a){var b=[],c=new ArrayBuffer(8);new Float64Array(c)[0]=a;var d=new Uint32Array(c)[0],e=new Uint32Array(c)[1];return b.push(255&e>>24),b.push(255&e>>16),b.push(255&e>>8),b.push(255&e),b.push(255&d>>24),b.push(255&d>>16),b.push(255&d>>8),b.push(255&d),b}}var e={Tuple,PID:class PID{constructor(){++c,this.id=c}toString(){return'PID#<0.'+this.id+'.0>'}},Reference:class Reference{constructor(){++d,this.id=d,this.ref=Symbol()}toString(){return'Ref#<0.0.0.'+this.id+'>'}},BitString:BitString$1};/* @flow */const f=e.BitString,g=new Map;g.set(Variable.prototype,function resolveVariable(a){return function(b,c){return null===a.name?c.push(b):!a.name.startsWith('_')&&c.push(namedVariableResult(a.name,b)),!0}}),g.set(Wildcard.prototype,resolveWildcard),g.set(HeadTail.prototype,function resolveHeadTail(a){const b=buildMatch(a.head),c=buildMatch(a.tail);return function(a,d){if(!is_array(a)||0===a.length)return!1;const e=a[0],f=a.slice(1);return b(e,d)&&c(f,d)}}),g.set(StartsWith.prototype,function resolveStartsWith(a){const b=a.prefix;return function(a,c){return is_string(a)&&a.startsWith(b)&&(c.push(a.substring(b.length)),!0)}}),g.set(Capture.prototype,function resolveCapture(a){const b=buildMatch(a.value);return function(a,c){return!!b(a,c)&&(c.push(a),!0)}}),g.set(Bound.prototype,function resolveBound(a){return function(b){return typeof b==typeof a.value&&b===a.value}}),g.set(Type.prototype,function resolveType(a){return function(b,c){if(b instanceof a.type){const d=buildMatch(a.objPattern);return d(b,c)}return!1}}),g.set(BitStringMatch.prototype,function resolveBitString(a){let b=[];for(let c of a.values)if(is_variable(c.value)){let a=getSize(c.unit,c.size);fillArray(b,a)}else b=b.concat(new f(c).value);let c=a.values;return function(a,d){var e=String.fromCharCode;let g=null;if(!is_string(a)&&!(a instanceof f))return!1;g=is_string(a)?new f(f.binary(a)):a;let h=0;for(let f,j=0;jd.size)return!1;for(let a of c)if(!d.has(a)||!b.get(a)(d.get(a),e))return!1;return!0}}),g.set(Array.prototype,function resolveArray(a){const b=a.map((a)=>buildMatch(a));return function(c,d){return is_array(c)&&c.length==a.length&&c.every(function(a,e){return b[e](c[e],d)})}}),g.set(String.prototype,function resolveString(a){return function(b){return is_string(b)&&b===a}}),g.set(Boolean.prototype,function resolveBoolean(a){return function(b){return is_boolean(b)&&b===a}}),g.set(Function.prototype,function resolveFunction(a){return function(b){return is_function(b)&&b===a}}),g.set(Object.prototype,resolveObject);class MatchError extends Error{constructor(a){if(super(),'symbol'==typeof a)this.message='No match for: '+a.toString();else if(Array.isArray(a)){let b=a.map((a)=>{return null===a?'null':'undefined'==typeof a?'undefined':a.toString()});this.message='No match for: '+b}else this.message='No match for: '+a;this.stack=new Error().stack,this.name=this.constructor.name}}class Clause{constructor(a,b,c=()=>!0){this.pattern=buildMatch(a),this.arity=a.length,this.optionals=getOptionalValues(a),this.fn=b,this.guard=c}}const h=Symbol();// https://github.com/airportyh/protomorphism +class Protocol{constructor(a){function createFun(a){return function(...c){const d=c[0];let e=null;if(null===d&&this.hasImplementation(Symbol('null'))?e=this.registry.get(Symbol)[a]:b(d)&&this.hasImplementation(s.Integer)?e=this.registry.get(s.Integer)[a]:'number'==typeof d&&!b(d)&&this.hasImplementation(s.Float)?e=this.registry.get(s.Float)[a]:'string'==typeof d&&this.hasImplementation(s.BitString)?e=this.registry.get(s.BitString)[a]:d&&d instanceof Map&&d.has(Symbol.for('__struct__'))&&this.hasImplementation(d)?e=this.registry.get(d.get(Symbol.for('__struct__')).__MODULE__)[a]:null!==d&&this.hasImplementation(d)?e=this.registry.get(d.constructor)[a]:this.fallback&&(e=this.fallback[a]),null!=e){const a=e.apply(this,c);return a}throw new Error(`No implementation found for ${d}`)}}for(const b in this.registry=new Map,this.fallback=null,a)this[b]=createFun(b).bind(this)}implementation(a,b){null===a?this.fallback=b:this.registry.set(a,b)}hasImplementation(a){if(a===s.Integer||a===s.Float||a===s.BitString)return this.registry.has(a);return a&&a instanceof Map&&a.has(Symbol.for('__struct__'))?this.registry.has(a.get(Symbol.for('__struct__')).__MODULE__):this.registry.has(a.constructor)}}class Recurse{constructor(a){this.func=a}}var i={reverse,foreach:function foreach(a,b){return b.forEach((b)=>a(b)),Symbol.for('ok')},duplicate:function duplicate(a,b){const c=[];for(;c.length{if(d.get(c-1)a.get(c-1)?1:0})},keystore:function keystore(a,b,c,d){const e=[...c];for(let f=0;fa.toString()).join()},map:function map(a,b){return b.map((b)=>a(b))},filter:function filter(a,b){return b.filter((b)=>a(b))},filtermap:function filtermap(a,b){const c=[];for(const d of b){const b=a(d);!0===b?c.push(d):b instanceof e.Tuple&&!0===b.get(0)&&c.push(b.get(1))}return c},member:function member(a,b){for(const c of b)if(c===a)return!0;return!1},all:function all(a,b){for(const c of b)if(!1===a(c))return!1;return!0},any:function any(a,b){for(const c of b)if(!0===a(c))return!0;return!1},splitwith:function splitwith(a,b){let c=!1;const d=[],f=[];for(const e of b)!0==c?f.push(e):!0===a(e)?d.push(e):(c=!0,f.push(e));return new e.Tuple(d,f)},sort:function sort(...a){if(1===a.length){const b=[...a[0]];return b.sort()}const c=a[0],b=[...a[1]];return b.sort((d,a)=>{const b=c(d,a);return!0===b?-1:1})}};// http://erlang.org/doc/man/erlang.html +const j=new e.PID;var k={atom_to_binary,binary_to_atom,binary_to_existing_atom:function binary_to_existing_atom(a,b=Symbol.for('utf8')){return binary_to_atom(a,b)},list_concatenation:function list_concatenation(a,b){return a.concat(b)},list_subtraction:function list_subtraction(a,b){const c=[...a];for(const d of b){const a=c.indexOf(d);-1>b},bxor:function bxor(a,b){return a^b},bnot:function bnot(a){return~a},is_bitstring:is_bitstring$1,is_boolean:function is_boolean$1(a){return'boolean'==typeof a||a instanceof Boolean},is_float:function is_float(a){return is_number$1(a)&&!b(a)},is_function:function is_function$1(a){return'function'==typeof a||a instanceof Function},is_integer,is_list:function is_list(a){return Array.isArray(a)},is_map:function is_map$1(a){return a instanceof Map},is_number:is_number$1,is_pid:function is_pid(a){return a instanceof e.PID},is_port:function is_port(){return!1},is_reference:function is_reference(a){return a instanceof e.Reference},is_tuple:function is_tuple(a){return a instanceof e.Tuple},is_atom:function is_atom(a){return'symbol'==typeof a||a instanceof Symbol||a.__MODULE__},is_binary,element:function element(a,b){return b.get(a-1)},setelement:function setelement(a,b,c){const d=[...b.values];return d[a-1]=c,new e.Tuple(...d)},make_tuple:function make_tuple(a,b){const c=[];for(let d=0;d{if(null===c)return b;return is_integer(c)?b+a(c):is_bitstring$1(c)?b+a(...c.value):b+c},'');return d}};// http://erlang.org/doc/man/maps.html +const l=Symbol.for('ok'),m=Symbol.for('error'),n=Symbol.for('badmap'),o=Symbol.for('badkey');const p=Symbol.for('elixir_config'),q=new Map;const r=function get_global(){return'undefined'==typeof self?'undefined'==typeof window?'undefined'==typeof global?(console.warn('No global state found'),null):global:window:self}();r.__elixirscript_store__=new Map,r.__elixirscript_names__=new Map;var s={Tuple:e.Tuple,PID:e.PID,BitString:e.BitString,Patterns:{defmatch:function defmatch(...a){const b=getArityMap(a);return function(...a){let[c,d]=findMatchingFunction(a,b);return c.apply(this,d)}},match:function match(a,b,c=()=>!0){let d=[],e=buildMatch(a);const f=e(b,d),[g,h]=checkNamedVariables(d);if(f&&h&&c.apply(this,g))return g;throw console.error('No match for:',b),new MatchError(b)},MatchError,variable:function variable(a=null,b=Symbol.for('tailored.no_value')){return new Variable(a,b)},wildcard:function wildcard(){return new Wildcard},startsWith:function startsWith(a){return new StartsWith(a)},capture:function capture(a){return new Capture(a)},headTail:function headTail(a,b){return new HeadTail(a,b)},type:function a(a,b={}){return new Type(a,b)},bound:function bound(a){return new Bound(a)},Clause,clause:function clause(a,b,c=()=>!0){return new Clause(a,b,c)},bitStringMatch:function bitStringMatch(...a){return new BitStringMatch(...a)},match_or_default,defmatchgen,list_comprehension:function list_comprehension(a,b){const c=run_generators(b.pop()(),b);let d=[];for(let e of c)a.guard.apply(this,e)&&d.push(a.fn.apply(this,e));return d},list_generator:function list_generator(a,b){return function(){let c=[];for(let d of b){const b=match_or_default(a,d,()=>!0,h);if(b!=h){const[a]=b;c.push(a)}}return c}},bitstring_generator:function bitstring_generator(a,b){return function(){let c=[],d=b.slice(0,a.byte_size()),e=1;for(;d.byte_size==a.byte_size();){const f=match_or_default(a,d,()=>!0,h);if(f!=h){c.push(f)}d=b.slice(a.byte_size()*e,a.byte_size()*(e+1)),e++}return c}},bitstring_comprehension:function bitstring_comprehension(a,b){const c=run_generators(b.pop()(),b);let d=[];for(let e of c)a.guard.apply(this,e)&&d.push(a.fn.apply(this,e));return d=d.map((a)=>e.BitString.integer(a)),new e.BitString(...d)},defmatchGen:function defmatchGen(...a){return defmatchgen(...a)},defmatchAsync:function defmatchAsync(...a){const b=getArityMap(a);return async function(...a){if(b.has(a.length)){const c=b.get(a.length);let d=null,e=null;for(let b of c){let c=[];a=fillInOptionalValues(a,b.arity,b.optionals);const f=b.pattern(a,c),[g,h]=checkNamedVariables(c);if(f&&h&&(await b.guard.apply(this,c))){d=b.fn,e=c;break}}if(!d)throw console.error('No match for:',a),new MatchError(a);return d.apply(this,e)}throw console.error('Arity of',a.length,'not found. No match for:',a),new MatchError(a)}}},Integer:class Integer{},Float:class Float{},Functions:{call_property:function call_property(a,b){if(!b)return a instanceof Function||'function'==typeof a?a():a;if(a instanceof Map){let c=null;if(a.has(b)?c=b:a.has(Symbol.for(b))&&(c=Symbol.for(b)),null===c)throw new Error(`Property ${b} not found in ${a}`);return a.get(c)instanceof Function||'function'==typeof a.get(c)?a.get(c)():a.get(c)}let c=null;if('number'==typeof a||'symbol'==typeof a||'boolean'==typeof a||'string'==typeof a?void 0===a[b]?void 0!==a[Symbol.for(b)]&&(c=Symbol.for(b)):c=b:b in a?c=b:Symbol.for(b)in a&&(c=Symbol.for(b)),null===c)throw new Error(`Property ${b} not found in ${a}`);return a[c]instanceof Function||'function'==typeof a[c]?a[c]():a[c]},defprotocol:function defprotocol(a){return new Protocol(a)},defimpl:function defimpl(a,b,c){a.implementation(b,c)},build_namespace:function build_namespace(a,b){let c=b.split('.');const d=a;let e=a;'Elixir'===c[0]&&(c=c.slice(1));for(const d of c)'undefined'==typeof e[d]&&(e[d]={}),e=e[d];return d.__table__=a.__table__||{},d.__table__[Symbol.for(b)]=e,e},iterator_to_reducer,map_to_object,trampoline:function trampoline$1(a){let b=a;for(;b&&b instanceof Recurse;)b=b.func();return b},Recurse},SpecialForms:{_case:function _case(a,b){return s.Patterns.defmatch(...b)(a)},cond:function cond(...a){for(const b of a)if(b[0])return b[1]();throw new Error},_for:function _for(a,b,c,d=[]){let[e,f]=c.into(d);const g=run_list_generators(b.pop()(),b);for(const h of g)a.guard.apply(this,h)&&(e=f(e,new s.Tuple(Symbol.for('cont'),a.fn.apply(this,h))));return f(e,Symbol.for('done'))},_try:function _try(a,b,c,d,e){let f=null;try{f=a()}catch(a){let d=null;if(b)try{return d=b(a),d}catch(a){if(a instanceof s.Patterns.MatchError)throw a}if(c)try{return d=c(a),d}catch(a){if(a instanceof s.Patterns.MatchError)throw a}throw a}finally{e&&e()}if(d)try{return d(f)}catch(a){if(a instanceof s.Patterns.MatchError)throw new Error('No Match Found in Else');throw a}else return f},_with:function _with(...a){let b=[],c=null,d=null;'function'==typeof a[a.length-2]?[c,d]=a.splice(-2):c=a.pop();for(let c=0;c{const[c,d]=b;return a.set(c,d),a},new Map)},keys:function keys(a){return!1===k.is_map(a)?new e.Tuple(n,a):Array.from(a.keys())},values:function values$1(a){return!1===k.is_map(a)?new e.Tuple(n,a):Array.from(a.values())},is_key,put:function put(a,b,c){if(!1===k.is_map(c))return new e.Tuple(n,c);const d=new Map(c);return d.set(a,b),d},merge:function merge(a,b){return!1===k.is_map(a)?new e.Tuple(n,a):!1===k.is_map(b)?new e.Tuple(n,b):new Map([...a,...b])},update:function update(a,b,c){return!1===k.is_map(c)?new e.Tuple(n,c):!1===is_key(a,c)?new e.Tuple(o,a):new Map([...c,[a,b]])},get:function get(...a){const b=a[0],c=a[1];return!1===k.is_map(c)?new e.Tuple(n,c):is_key(b)?c.get(b):3===a.length?a[2]:new e.Tuple(o,b)},take:function take(a,b){if(!1===k.is_map(b))return new e.Tuple(n,b);if(!is_key(a))return m;const c=b.get(a),d=new Map(b);return d.delete(a),new e.Tuple(c,d)}},lists:i,elixir_errors:{warn:function warn(a){const b=a.join('');return console.warn(`warning: ${b}`),Symbol.for('ok')}},io:{put_chars:function put_chars(a,b){const c=k.iolist_to_binary(b);return a===Symbol.for('stderr')?console.error(c):console.log(c),Symbol.for('ok')}},binary:{copy:function copy(a,b=1){return a.repeat(b)},list_to_bin:function list_to_bin(a){return k.list_to_binary(a)}},unicode:{characters_to_list:function characters_to_list(a){return a.split('').map((a)=>a.codePointAt(0))},characters_to_binary:function characters_to_binary(b){return k.is_binary(b)?b:a(...b)}},elixir_config:{new:function _new(a){return q.set(p,new Map),q.get(p).set(p,a),p},delete:function _delete(a){return q.delete(a),!0},put:put$1,get:get$1,update:function update$1(a,b){const c=b(q.get(p).get(a));return put$1(a,c),c},get_and_put:function get_and_put(a,b){const c=get$1(a);return put$1(a,b),c}}};return{Core:s}}(); From 83be891c1255af520d8d1aa5b53228381ff49f03 Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Fri, 4 Aug 2017 21:04:15 -0500 Subject: [PATCH 209/418] Add more text about global FFI --- lib/elixir_script/ffi.ex | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/lib/elixir_script/ffi.ex b/lib/elixir_script/ffi.ex index 8c94f78f..68249c14 100644 --- a/lib/elixir_script/ffi.ex +++ b/lib/elixir_script/ffi.ex @@ -36,6 +36,31 @@ defmodule ElixirScript.FFI do function in the global scope. * `name`: Only applicable with `global` is set to `true`. This will use the name defined here instead of the module name for calling modules and functions in the global scope + + An example using the global option to reference the JSON module in browsers + + ```elixir + defmodule JSON do + use ElixirScript.FFI, global: true + + defexternal stringify(map) + defexternal parse(string) + end + ``` + + The calls above are translated to calls to the `JSON` module in the global scope + + An example using global and name options + + ```elixir + defmodule Console do + use ElixirScript.FFI, global: true, name: :console + + defexternal log(term) + end + ``` + + With the above, calls in ElixirScript to `Console.log` will translate to `console.log` in JavaScript """ defmacro __using__(opts) do From 93dca72233fe9316c6fbf0c5758c75dac2ca29e1 Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Sat, 5 Aug 2017 21:21:30 -0500 Subject: [PATCH 210/418] Remove support for CommonJS and UMD modules output ElixirScript now only supports ES Modules. The default output path has also been changed. --- CHANGELOG.md | 7 +- GettingStarted.md | 30 +++--- lib/elixir_script/cli.ex | 10 +- lib/elixir_script/compiler.ex | 16 +--- lib/elixir_script/module_systems/common.ex | 50 ---------- lib/elixir_script/module_systems/umd.ex | 106 --------------------- lib/mix/tasks/compile.elixir_script.ex | 13 +-- mix.exs | 2 +- package.json | 6 +- test/app/spec/main.spec.js | 4 +- test/cli_test.exs | 6 +- test/compiler_test.exs | 14 +-- 12 files changed, 37 insertions(+), 227 deletions(-) delete mode 100644 lib/elixir_script/module_systems/common.ex delete mode 100644 lib/elixir_script/module_systems/umd.ex diff --git a/CHANGELOG.md b/CHANGELOG.md index 38eb4911..ea9c0319 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,13 +7,18 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ## [Unreleased] ### Added -- ElixirScript now has an FFI layer for interoperability with JavaScript. For more details, see documentation at `ElixirScript.FFI` +- ElixirScript now has a Foreign Function Interface (FFI) for interoperability with JavaScript. For more details, see documentation at `ElixirScript.FFI` - `ElixirScript.JS.mutate/3` - `ElixirScript.JS.map_to_object/1` ### Changed - Compiler has been completely rewritten. ElixirScript now requires Erlang 20+ and Elixir 1.5+ - `JS` module renamed to `ElixirScript.JS` +- Default output path is now `priv/elixir_script/build` + +### Removed +- Support for CommonJS and UMD output formats has been removed. Output will be in ES module format +- The `js_modules` option has been removed in favor of the new FFI ## [0.28.0] - 2017-06-11 diff --git a/GettingStarted.md b/GettingStarted.md index 2026231f..6381548f 100644 --- a/GettingStarted.md +++ b/GettingStarted.md @@ -7,11 +7,11 @@ Adding Elixirscript to your mix project gives you the ability to add it to your Add dependency to your deps in mix.exs: ``` elixir -{:elixir_script, "~> 0.29"} +{:elixir_script, "~> 0.30"} ``` Elixirscript uses default output and module formats if options are not given. If you wish to change any or all options, add an `elixir_script` key to your project configuration. - + ``` elixir def project do [ @@ -21,13 +21,7 @@ Elixirscript uses default output and module formats if options are not given. If deps: deps, elixir_script: [ input: MyEntryModule, - output: "priv/elixirscript/Elixir.App.js", - format: :es, - js_modules: [ - {React, "react"}, - {ReactDOM, "react-dom"}, - {Phoenix, "phoenix", default: false} - ] + output: "priv/elixir_script/build/Elixir.App.js" ], compilers: Mix.compilers ++ [:elixir_script] ] @@ -38,22 +32,24 @@ Available options are: * `input`: The entry module(s) for your application or library -* `output`: The path of the generated JavaScript file. (defaults to `priv/elixirscript`) +* `output`: The path of the generated JavaScript file. (defaults to `priv/elixir_script/build`) If path ends in `.js` then that will be the name of the file. If a directory is given, file will be named `Elixir.App.js` -* `format`: The module format of generated JavaScript code. (defaults to `:es`). Choices are:     - - * `:es` - ES Modules - * `:common` - CommonJS +Now run `mix compile` and you should see a JavaScript file named `Elixir.App.js` in the `priv/elixir_script/build/` directory. ElixirScript outputs JavaScript in the ES Module format. If your browser supports it, you can include the output in a script tag with the type "module" - * `:umd` - UMD +```html + +``` - * `default` - Defaults to true. Set to false if the imported module has no default export. +If your browser does not yet support ES modules directly, use a tool such as [webpack](https://webpack.js.org/) or [brunch](http://brunch.io/) to convert it into something that can be used in the browser ### Macros diff --git a/lib/elixir_script/cli.ex b/lib/elixir_script/cli.ex index 79ffcd80..70475e2d 100644 --- a/lib/elixir_script/cli.ex +++ b/lib/elixir_script/cli.ex @@ -7,15 +7,13 @@ defmodule ElixirScript.CLI do output: :string, help: :boolean, version: :boolean, - watch: :boolean, - format: :string + watch: :boolean ] @aliases [ o: :output, h: :help, - v: :version, - f: :format + v: :version ] def parse_args(args) do @@ -42,7 +40,6 @@ defmodule ElixirScript.CLI do the entry module of your application options: - -f --format [format] module format of output. options: es (default), common, umd -o --output [path] places output at the given path. Can be a directory or filename. -v --version the current version number @@ -70,8 +67,7 @@ defmodule ElixirScript.CLI do {watch, options} = Keyword.pop(options, :watch, false) compile_opts = [ - output: Keyword.get(options, :output, :stdout), - format: String.to_atom(Keyword.get(options, :format, "es")) + output: Keyword.get(options, :output, :stdout) ] input = handle_input(input) diff --git a/lib/elixir_script/compiler.ex b/lib/elixir_script/compiler.ex index 24f9bdc9..75499921 100644 --- a/lib/elixir_script/compiler.ex +++ b/lib/elixir_script/compiler.ex @@ -34,22 +34,10 @@ defmodule ElixirScript.Compiler do defp build_compiler_options(opts, entry_modules) do default_options = Map.new |> Map.put(:output, Keyword.get(opts, :output)) - |> Map.put(:format, Keyword.get(opts, :format, :es)) + |> Map.put(:format, :es) |> Map.put(:entry_modules, entry_modules) options = default_options - Map.put(options, :module_formatter, get_module_formatter(options[:format])) - end - - defp get_module_formatter(:umd) do - ElixirScript.ModuleSystems.UMD - end - - defp get_module_formatter(:common) do - ElixirScript.ModuleSystems.Common - end - - defp get_module_formatter(_) do - ElixirScript.ModuleSystems.ES + Map.put(options, :module_formatter, ElixirScript.ModuleSystems.ES) end end diff --git a/lib/elixir_script/module_systems/common.ex b/lib/elixir_script/module_systems/common.ex deleted file mode 100644 index 2f4da76b..00000000 --- a/lib/elixir_script/module_systems/common.ex +++ /dev/null @@ -1,50 +0,0 @@ -defmodule ElixirScript.ModuleSystems.Common do - @moduledoc false - alias ESTree.Tools.Builder, as: JS - - def build(imports, js_imports, body, exports) do - module_imports = Enum.map(imports, fn {module, path} -> import_module(module, path) end) - - imports = js_imports - |> Enum.map(fn - {_module, name, path} -> import_module(name, path) - end) - - imports = Enum.uniq(imports ++ module_imports) - - export = if is_nil(exports), do: [], else: [export_module(exports)] - imports ++ body ++ export - end - - defp import_module(name, from) do - js_module_name = JS.identifier(name) - do_import_module(js_module_name, from) - end - - defp do_import_module(ref, file_path) do - - ref_declarator = JS.variable_declarator( - ref, - JS.call_expression( - JS.identifier("require"), - [JS.literal(file_path)] - ) - ) - - JS.variable_declaration([ref_declarator], :const) - - end - - defp export_module(exported_object) do - JS.assignment_expression( - :=, - JS.member_expression( - JS.identifier("module"), - JS.identifier("exports") - ), - exported_object - ) - end - - -end diff --git a/lib/elixir_script/module_systems/umd.ex b/lib/elixir_script/module_systems/umd.ex deleted file mode 100644 index fcd30795..00000000 --- a/lib/elixir_script/module_systems/umd.ex +++ /dev/null @@ -1,106 +0,0 @@ -defmodule ElixirScript.ModuleSystems.UMD do - @moduledoc false - alias ESTree.Tools.Builder, as: JS - - def build(imports, js_imports, body, exports) do - module_imports = Enum.map(imports, fn - {module, path} -> import_module(module, path) - end) - - imports = js_imports - |> Enum.map(fn - {_module, name, path} -> import_module(name, path) - end) - - imports = Enum.uniq(imports ++ module_imports) - - export = export_module(exports) - List.wrap(make_umd(imports, body, export)) - end - - defp import_module(module_name, from) do - js_module_name = JS.identifier(module_name) - {js_module_name, JS.literal(from)} - end - - defp export_module(exported_object) do - exported_object - end - - defp make_umd(imports, body, exports) do - import_paths = Enum.map(imports, fn({_, path}) -> path end) - import_identifiers = Enum.map(imports, fn({id, _}) -> id end) - exports = if is_nil(exports), do: [], else: [JS.return_statement(exports)] - - JS.expression_statement( - JS.call_expression( - JS.function_expression([JS.identifier("root"), JS.identifier("factory")], [], JS.block_statement([ - JS.if_statement( - JS.logical_expression( - :&&, - JS.binary_expression( - :===, - JS.unary_expression(:typeof, true, JS.identifier("define")), - JS.literal("function") - ), - JS.member_expression( - JS.identifier("define"), - JS.identifier("amd") - ) - ), - JS.block_statement([ - JS.call_expression( - JS.identifier("define"), - [JS.array_expression(import_paths), JS.identifier("factory")] - ) - ]), - JS.if_statement( - JS.binary_expression( - :===, - JS.unary_expression(:typeof, true, JS.identifier("exports")), - JS.literal("object") - ), - JS.block_statement([ - JS.assignment_expression( - :=, - JS.member_expression( - JS.identifier("module"), - JS.identifier("exports") - ), - JS.call_expression( - JS.identifier("factory"), - Enum.map(import_paths, fn x -> - JS.call_expression( - JS.identifier("require"), - [x] - ) - end) - ) - ) - ]), - JS.block_statement([ - JS.assignment_expression( - :=, - JS.member_expression( - JS.identifier("root"), - JS.identifier("Elixir") - ), - JS.call_expression( - JS.identifier("factory"), - Enum.map(import_identifiers, fn x -> - JS.member_expression( - JS.identifier("root"), - x - ) - end) - ) - ) - ]) - ) - ) - ])), - [JS.this_expression(), JS.function_expression(import_identifiers, [], JS.block_statement(body ++ exports))] - ) - ) - end -end \ No newline at end of file diff --git a/lib/mix/tasks/compile.elixir_script.ex b/lib/mix/tasks/compile.elixir_script.ex index 1e6067e2..95b9fb93 100644 --- a/lib/mix/tasks/compile.elixir_script.ex +++ b/lib/mix/tasks/compile.elixir_script.ex @@ -21,15 +21,10 @@ defmodule Mix.Tasks.Compile.ElixirScript do Available options are: * `input`: The module or modules that are the entry to your application (required) - * `output`: The path of the generated JavaScript file. (defaults to `priv/elixirscript`) + * `output`: The path of the generated JavaScript file. (defaults to `priv/elixir_script/build`) If path ends in `.js` then that will be the name of the file. If a directory is given, file will be named `Elixir.App.js` - * `format`: The module format of generated JavaScript code. (defaults to `:es`). - Choices are: - * `:es` - ES Modules - * `:common` - CommonJS - * `:umd` - UMD The mix compiler will also compile any dependencies that have the elixirscript compiler in its mix compilers as well """ @@ -64,8 +59,7 @@ defmodule Mix.Tasks.Compile.ElixirScript do elixirscript_config = get_elixirscript_config() input = Keyword.fetch!(elixirscript_config, :input) opts = [ - output: Keyword.get(elixirscript_config, :output), - format: Keyword.get(elixirscript_config, :format) + output: Keyword.get(elixirscript_config, :output) ] {input, opts} @@ -87,8 +81,7 @@ defmodule Mix.Tasks.Compile.ElixirScript do defp defaults() do [ - output: "priv/elixirscript", - format: :es + output: "priv/elixir_script/build" ] end diff --git a/mix.exs b/mix.exs index 8bd543b2..3e40a7a7 100644 --- a/mix.exs +++ b/mix.exs @@ -4,7 +4,7 @@ defmodule ElixirScript.Mixfile do def project do [ app: :elixir_script, - version: "0.29.0-dev", + version: "0.30.0-dev", elixir: "~> 1.5-dev", elixirc_paths: elixirc_paths(Mix.env), deps: deps(), diff --git a/package.json b/package.json index afaa2624..22ad2649 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,7 @@ "build": "rollup -c rollup.config.js", "clean": "rm -rf priv/build", "test": "nyc ava src/javascript/tests", - "build:test-app": "MIX_ENV=test mix elixirscript Main -f common -o test/app/build/", + "build:test-app": "MIX_ENV=test mix elixirscript Main -o test/app/build/", "test-app": "yarn build:test-app && NODE_ENV=test ava 'test/app/spec/**/*.spec.js'" }, "repository": { @@ -41,9 +41,7 @@ "sinon": "^2.4.1" }, "ava": { - "require": [ - "babel-register" - ], + "require": ["babel-register"], "babel": { "babelrc": true } diff --git a/test/app/spec/main.spec.js b/test/app/spec/main.spec.js index eb44ba0e..be8b70b9 100644 --- a/test/app/spec/main.spec.js +++ b/test/app/spec/main.spec.js @@ -1,7 +1,7 @@ import test from 'ava'; -const sinon = require('sinon'); +import Elixir from '../build/Elixir.App'; -const Elixir = require('../build/Elixir.App'); +const sinon = require('sinon'); test('Elixir.start:calls the modules start function', t => { const callback = sinon.spy(); diff --git a/test/cli_test.exs b/test/cli_test.exs index b08c1d93..fbf1f85f 100644 --- a/test/cli_test.exs +++ b/test/cli_test.exs @@ -3,8 +3,8 @@ defmodule ElixirScript.CLI.Test do import ExUnit.CaptureIO test "parse_args" do - {_, args} = ElixirScript.CLI.parse_args(["Atom", "--format", "umd"]) - assert args == [format: "umd"] + {_, args} = ElixirScript.CLI.parse_args(["Atom", "--output", "build"]) + assert args == [output: "build"] end test "process help" do @@ -30,4 +30,4 @@ defmodule ElixirScript.CLI.Test do ElixirScript.CLI.process({["Atom"], []}) end) =~ "export default Elixir" end -end \ No newline at end of file +end diff --git a/test/compiler_test.exs b/test/compiler_test.exs index 36e510e7..984f1846 100644 --- a/test/compiler_test.exs +++ b/test/compiler_test.exs @@ -17,21 +17,11 @@ defmodule ElixirScript.Compiler.Test do end end - test "Output format: es" do - result = ElixirScript.Compiler.compile(Atom, [format: :es, js_modules: [{React, "react"}, {ReactDOM, "react-dom", default: false}]]) + test "Output" do + result = ElixirScript.Compiler.compile(Atom, []) assert result =~ "export default Elixir" end - test "Output format: umd" do - result = ElixirScript.Compiler.compile(Atom, [format: :umd, js_modules: [{React, "react"}]]) - assert result =~ "factory" - end - - test "Output format: common" do - result = ElixirScript.Compiler.compile(Atom, [format: :common, js_modules: [{React, "react"}]]) - assert result =~ "module.exports = Elixir" - end - test "Output file with default name" do path = System.tmp_dir() From ba22c80e750b893348eb1a644ef330112b58cb01 Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Sun, 6 Aug 2017 08:54:23 -0500 Subject: [PATCH 211/418] Add root option. Keep extension for imports Root option allows for specifying the first part of imports used when importing FFI modules. The extension change is also for FFI module imports. Both are added from testing inside of Chrome when using ES modules directly. --- CHANGELOG.md | 2 ++ GettingStarted.md | 4 +++- JavascriptInterop.md | 5 +++-- lib/elixir_script/cli.ex | 7 +++++-- lib/elixir_script/compiler.ex | 1 + lib/elixir_script/passes/find_used_modules.ex | 1 + lib/elixir_script/passes/output.ex | 2 +- lib/elixir_script/passes/translate/module.ex | 15 --------------- lib/elixir_script/state.ex | 2 +- 9 files changed, 17 insertions(+), 22 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ea9c0319..74088bab 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/). - ElixirScript now has a Foreign Function Interface (FFI) for interoperability with JavaScript. For more details, see documentation at `ElixirScript.FFI` - `ElixirScript.JS.mutate/3` - `ElixirScript.JS.map_to_object/1` +- `root` option for specifying the root import path for FFI JavaScript modules. Defaults to `"."` +- For imports, now keeping the `.js` extension ### Changed - Compiler has been completely rewritten. ElixirScript now requires Erlang 20+ and Elixir 1.5+ diff --git a/GettingStarted.md b/GettingStarted.md index 6381548f..5a406627 100644 --- a/GettingStarted.md +++ b/GettingStarted.md @@ -37,12 +37,14 @@ Available options are: If path ends in `.js` then that will be the name of the file. If a directory is given, file will be named `Elixir.App.js` +* `root`: Optional root for imports of FFI JavaScript modules. Defaults to `.`. If using output directly in a browser, you may want to make it something like `/js` or some uri. + Now run `mix compile` and you should see a JavaScript file named `Elixir.App.js` in the `priv/elixir_script/build/` directory. ElixirScript outputs JavaScript in the ES Module format. If your browser supports it, you can include the output in a script tag with the type "module" ```html -``` - -If your browser does not yet support ES modules directly, use a tool such as [webpack](https://webpack.js.org/) or [brunch](http://brunch.io/) to convert it into something that can be used in the browser - -### JavaScript Interop - -Check out the [JavaScript Interoperability](JavascriptInterop.html) documentation - -### Limitations - -ElixirScript does not support `receive` or any of OTP at this time. diff --git a/README.md b/README.md index b5feac14..48c528d0 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,35 @@ Requirements Usage ======== -Please check the [Getting Started Guide](GettingStarted.md) for usage +Add dependency to your deps in mix.exs: + +``` elixir +{:elixir_script, "~> x.x"} +``` + +Add `elixir_script` to list of mix compilers in mix.exs +Also add `elixir_script` configuration + +```elixir + def project do + [ + app: :my_app, + # ... + # Add elixir_script as a compilter + compilers: Mix.compilers ++ [:elixir_script], + # Our elixir_script configuration + elixir_script: [ + # Entry module. Can also be a list of modules + input: MyEntryModule, + # Output path. Either a path to a js file or a directory + output: "priv/elixir_script/build/Elixir.App.js" + ] + ] + end +``` + +Run `mix compile` + Examples ========== diff --git a/lib/elixir_script.ex b/lib/elixir_script.ex index d69317d6..618282f8 100644 --- a/lib/elixir_script.ex +++ b/lib/elixir_script.ex @@ -1,3 +1,71 @@ defmodule ElixirScript do - @moduledoc false + @moduledoc """ + + ElixirScript acts as a mix compiler. This means that when you execute `mix compile`, + ElixirScript's compiler will run as well. Make sure to add ElixirScript to your + list of compilers in mix.exs. + + ElixirScript must be told which modules to use as the entry to your ElixirScript application. + This is done by adding an `elixir_script` key to your project configuration whose value is a keyword list of options. + Add an `input` key and make the value either the name of a module or a list of modules + that are the entry modules you wish to compile to JavaScript. ElixirScript will use + those modules to find what other modules and functions it needs to convert to JavaScript. + ElixirScript by default places output in `priv/elixir_script/build`. If you wish to change this, + add an `output` key to your ElixirScript configuration. + + An example configuration for a project is shown below + + ``` elixir + def project do + [ + app: :my_app, + version: "0.1.0", + elixir: "~> 1.0", + deps: deps, + # Add elixir_script as a compilter + compilers: Mix.compilers ++ [:elixir_script], + # Our elixir_script configuration + elixir_script: [ + # Entry module. Can also be a list of modules + input: MyEntryModule, + # Output path. Either a path to a js file or a directory + output: "priv/elixir_script/build/Elixir.App.js" + ] + ] + end + ``` + + Available options are: + + * `input` (required): The entry module(s) for your application or library + + * `output`: The path of the generated JavaScript file. (defaults to `priv/elixir_script/build`) + + If path ends in `.js` then that will be the name of the file. If a directory is given, + file will be named `Elixir.App.js` + + * `root`: Optional root for imports of FFI JavaScript modules. Defaults to `.`. If using output directly in a browser, you may want to make it something like `/js` or some uri. + + + Now run `mix compile` and you should see a JavaScript file named `Elixir.App.js` in the `priv/elixir_script/build/` directory. ElixirScript outputs JavaScript in the ES Module format. If your browser supports it, you can include the output in a script tag with the type "module" + + ```html + + ``` + + If your browser does not yet support ES modules directly, use a tool such as [webpack](https://webpack.js.org/) or [brunch](http://brunch.io/) to convert it into something that can be used in the browser + + ### JavaScript Interop + + Check out the [JavaScript Interoperability](JavascriptInterop.html) documentation + + ### Limitations + + ElixirScript does not support `receive` or any of OTP at this time. + """ end diff --git a/mix.exs b/mix.exs index 3e40a7a7..6cd8af58 100644 --- a/mix.exs +++ b/mix.exs @@ -14,7 +14,8 @@ defmodule ElixirScript.Mixfile do aliases: aliases(), test_coverage: [tool: ExCoveralls], docs: [ - extras: ["GettingStarted.md", "JavaScriptInterop.md"] + main: "ElixirScript", + extras: ["JavaScriptInterop.md"] ] ] end From 2f2c48d77182a2f4531aa3b57005cd2a0594ff63 Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Tue, 8 Aug 2017 16:57:22 -0500 Subject: [PATCH 219/418] Add example to readme --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index 48c528d0..8565d6d3 100644 --- a/README.md +++ b/README.md @@ -44,8 +44,11 @@ Run `mix compile` Examples ========== +### Application [ElixirScript Todo Example](https://github.com/elixirscript/todo-elixirscript) +### Library +[ElixirScript React](https://github.com/elixirscript/elixirscript_react) Development =========== From 6c839df2407c580dd84d5b22ee1417b1441b3d98 Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Thu, 10 Aug 2017 09:32:55 -0500 Subject: [PATCH 220/418] Add in a data type conversion chart to JavaScriptInterop.md --- JavascriptInterop.md | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/JavascriptInterop.md b/JavascriptInterop.md index a09810d1..0b22dbe0 100644 --- a/JavascriptInterop.md +++ b/JavascriptInterop.md @@ -1,5 +1,24 @@ # JavaScript Interoperability +## Data Type Conversions + +ElixirScript translates Elixir primitive types to the following: + +| Elixir | JavaScript | +|--------|------------| +| Integer | Number | +| Float | Number | +| Binary | String | +| Atom | Symbol | +| List | Array | +| Map | Map | +| Tuple | ErlangTypes.Tuple | +| Bitstring | ErlangTypes.Bitstring | +| PID | ErlangTypes.PID | +| Reference | ErlangTypes.Reference | + +The ErlangTypes library can be found [here](https://github.com/elixirscript/erlang-types) + ## ElixirScript Calling JavaScript ### ElixirScript.JS module From a108812b94166e3f676f5f8ea57c93bbfe34438c Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Thu, 10 Aug 2017 11:34:17 -0500 Subject: [PATCH 221/418] Make sure _ref identifiers created are unique --- lib/elixir_script/passes/translate/forms/match.ex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/elixir_script/passes/translate/forms/match.ex b/lib/elixir_script/passes/translate/forms/match.ex index aeaac2ee..e3625c4d 100644 --- a/lib/elixir_script/passes/translate/forms/match.ex +++ b/lib/elixir_script/passes/translate/forms/match.ex @@ -87,7 +87,7 @@ defmodule ElixirScript.Translate.Forms.Match do defp make_params(params) do - ref = J.identifier("_ref") + ref = J.identifier("_ref#{:rand.uniform(10000000)}") params = Enum.map(params, fn (nil) -> J.identifier(:undefined) From 5eeb1d8d2317585472edbdfec822fb26c2e02ea9 Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Thu, 10 Aug 2017 12:26:24 -0500 Subject: [PATCH 222/418] Now throwing warnings for unknown modules --- lib/elixir_script/passes/find_used_modules.ex | 5 +++++ test/compiler_test.exs | 6 ------ 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/lib/elixir_script/passes/find_used_modules.ex b/lib/elixir_script/passes/find_used_modules.ex index f2be293f..c8862606 100644 --- a/lib/elixir_script/passes/find_used_modules.ex +++ b/lib/elixir_script/passes/find_used_modules.ex @@ -1,6 +1,7 @@ defmodule ElixirScript.FindUsedModules do @moduledoc false alias ElixirScript.State, as: ModuleState + require Logger @doc """ Takes a list of entry modules and finds modules they use. @@ -20,6 +21,10 @@ defmodule ElixirScript.FindUsedModules do walk_module(module, info, pid) {:ok, module, implementations} -> walk_protocol(module, implementations, pid) + {:error, "Unknown module"} -> + Logger.warn fn() -> + "#{inspect module} is missing or unavailable" + end {:error, error} -> raise ElixirScript.CompileError, "An error occurred while compiling #{inspect module}: #{error}" end diff --git a/test/compiler_test.exs b/test/compiler_test.exs index 984f1846..45465c75 100644 --- a/test/compiler_test.exs +++ b/test/compiler_test.exs @@ -11,12 +11,6 @@ defmodule ElixirScript.Compiler.Test do assert is_binary(result) end - test "Error on unknown module" do - assert_raise ElixirScript.CompileError, fn -> - ElixirScript.Compiler.compile(SomeModule) - end - end - test "Output" do result = ElixirScript.Compiler.compile(Atom, []) assert result =~ "export default Elixir" From a9a0ca2ee04a653c725b83e4e4965ab6b7ab30de Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Thu, 10 Aug 2017 12:32:54 -0500 Subject: [PATCH 223/418] Prepend ElixirScript to warnings thrown --- lib/elixir_script/passes/find_used_modules.ex | 2 +- lib/elixir_script/passes/translate/form.ex | 2 +- lib/elixir_script/watcher.ex | 5 +---- 3 files changed, 3 insertions(+), 6 deletions(-) diff --git a/lib/elixir_script/passes/find_used_modules.ex b/lib/elixir_script/passes/find_used_modules.ex index c8862606..1c470fc9 100644 --- a/lib/elixir_script/passes/find_used_modules.ex +++ b/lib/elixir_script/passes/find_used_modules.ex @@ -23,7 +23,7 @@ defmodule ElixirScript.FindUsedModules do walk_protocol(module, implementations, pid) {:error, "Unknown module"} -> Logger.warn fn() -> - "#{inspect module} is missing or unavailable" + "ElixirScript: #{inspect module} is missing or unavailable" end {:error, error} -> raise ElixirScript.CompileError, "An error occurred while compiling #{inspect module}: #{error}" diff --git a/lib/elixir_script/passes/translate/form.ex b/lib/elixir_script/passes/translate/form.ex index b0b49f79..867add78 100644 --- a/lib/elixir_script/passes/translate/form.ex +++ b/lib/elixir_script/passes/translate/form.ex @@ -210,7 +210,7 @@ defmodule ElixirScript.Translate.Form do line = Keyword.get(context, :line, 1) {function, _arity} = Map.get(state, :function) Logger.warn fn() -> - "receive not supported, Module: #{inspect state.module}, Function: #{function}, Line: #{line}" + "ElixirScript: receive not supported, Module: #{inspect state.module}, Function: #{function}, Line: #{line}" end Receive.compile(blocks, state) end diff --git a/lib/elixir_script/watcher.ex b/lib/elixir_script/watcher.ex index 88fc0991..aa0dd74b 100644 --- a/lib/elixir_script/watcher.ex +++ b/lib/elixir_script/watcher.ex @@ -26,14 +26,11 @@ defmodule ElixirScript.Watcher do try do if input_changed?(to_string(path)) do - Logger.debug fn() -> - "Event: #{inspect event} Path: #{path}" - end ElixirScript.Compiler.compile(state[:input], state[:options]) end rescue x -> - Logger.error(x.message) + Logger.error("#{inspect __MODULE__}: #{x.message}") end {:noreply, state} From 4ce8dda289b8ec528d15fa14fb31cf2056f201ff Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Thu, 10 Aug 2017 12:34:01 -0500 Subject: [PATCH 224/418] Fix warning --- lib/elixir_script/watcher.ex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/elixir_script/watcher.ex b/lib/elixir_script/watcher.ex index aa0dd74b..b33ca450 100644 --- a/lib/elixir_script/watcher.ex +++ b/lib/elixir_script/watcher.ex @@ -22,7 +22,7 @@ defmodule ElixirScript.Watcher do {:ok, args} end - def handle_info({_pid, {:fs, :file_event}, {path, event}}, state) do + def handle_info({_pid, {:fs, :file_event}, {path, _event}}, state) do try do if input_changed?(to_string(path)) do From df032500e9c8649c0e2c9142f0a87ea906bfa74b Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Thu, 10 Aug 2017 15:43:30 -0500 Subject: [PATCH 225/418] More documentation --- lib/elixir_script.ex | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/lib/elixir_script.ex b/lib/elixir_script.ex index 618282f8..e0ad5334 100644 --- a/lib/elixir_script.ex +++ b/lib/elixir_script.ex @@ -67,5 +67,14 @@ defmodule ElixirScript do ### Limitations ElixirScript does not support `receive` or any of OTP at this time. + + ### Dependencies + + ElixirScript can use many of the same Hex packages and dependencies that currently exist. + It is also possible to make packages that are specific to ElixirScript. If you decide to + make such a package, please prepend `elixir_script` to the app name. For instance is making + a package for ElixirScript with FFI modules for interacting with React, the name would be + `elixir_script_react`. This is to make sure that other developers know that a package in Hex + is specifically for use with ElixirScript. """ end From 482b8751b3992ad102034ee2ba1efd308e34a0a3 Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Fri, 11 Aug 2017 14:58:36 -0500 Subject: [PATCH 226/418] Making sure to only change return to recursion if in a non-anonymous function --- .../passes/translate/function.ex | 22 ++++++++++++++----- 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/lib/elixir_script/passes/translate/function.ex b/lib/elixir_script/passes/translate/function.ex index 58b564ea..6818866a 100644 --- a/lib/elixir_script/passes/translate/function.ex +++ b/lib/elixir_script/passes/translate/function.ex @@ -19,6 +19,9 @@ defmodule ElixirScript.Translate.Function do end def compile({:fn, _, clauses}, state) do + anonymous? = Map.get(state, :anonymous_fn, false) + + state = Map.put(state, :anonymous_fn, true) clauses = compile_clauses(clauses, state) arg_matches_declarator = J.variable_declarator( @@ -61,11 +64,14 @@ defmodule ElixirScript.Translate.Function do ]) ) + state = Map.put(state, :anonymous_fn, anonymous?) { function_dec, state } end def compile({{name, arity}, _type, _, clauses}, state) do state = Map.put(state, :function, {name, arity}) + |> Map.put(:anonymous_fn, false) + clauses = compile_clauses(clauses, state) arg_matches_declarator = J.variable_declarator( @@ -194,19 +200,23 @@ defmodule ElixirScript.Translate.Function do {ast, state} end - defp update_last_call(clause_body, %{function: {name, _}}) do + defp update_last_call(clause_body, %{function: {name, _}, anonymous_fn: anonymous?}) do last_item = List.last(clause_body) function_name = ElixirScript.Translate.Identifier.make_function_name(name) case last_item do %ESTree.ReturnStatement{ argument: %ESTree.CallExpression{ callee: ^function_name, arguments: arguments } } -> - new_last_item = J.return_statement( - recurse( - recur_bind(arguments) + if anonymous? do + clause_body + else + new_last_item = J.return_statement( + recurse( + recur_bind(arguments) + ) ) - ) - List.replace_at(clause_body, length(clause_body) - 1, new_last_item) + List.replace_at(clause_body, length(clause_body) - 1, new_last_item) + end _ -> clause_body end From dc00d1df189347c23dfe3d79ac0b1397ad0a1c38 Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Fri, 11 Aug 2017 16:19:22 -0500 Subject: [PATCH 227/418] Make sure that is_atom considers true, false, and null as atoms --- .../lib/core/erlang_compat/erlang.js | 32 +++++++++++++++---- .../tests/core/erlang_compat/erlang_spec.js | 15 ++++++++- 2 files changed, 40 insertions(+), 7 deletions(-) diff --git a/src/javascript/lib/core/erlang_compat/erlang.js b/src/javascript/lib/core/erlang_compat/erlang.js index faf71dd8..db95aae0 100644 --- a/src/javascript/lib/core/erlang_compat/erlang.js +++ b/src/javascript/lib/core/erlang_compat/erlang.js @@ -4,27 +4,39 @@ import lists from './lists'; const selfPID = new ErlangTypes.PID(); -function atom_to_list(atom) { - return Symbol.keyFor(atom); -} - function atom_to_binary(atom, encoding = Symbol.for('utf8')) { if (encoding !== Symbol.for('utf8')) { throw new Error(`unsupported encoding ${encoding}`); } - if (atom.__MODULE__) { + if (atom === null) { + return 'nil'; + } else if (is_boolean(atom)) { + return atom.toString(); + } else if (atom.__MODULE__) { return Symbol.keyFor(atom.__MODULE__); } return Symbol.keyFor(atom); } +function atom_to_list(atom) { + return atom_to_binary(atom); +} + function binary_to_atom(binary, encoding = Symbol.for('utf8')) { if (encoding !== Symbol.for('utf8')) { throw new Error(`unsupported encoding ${encoding}`); } + if (binary === 'nil') { + return null; + } else if (binary === 'true') { + return true; + } else if (binary === 'false') { + return false; + } + return Symbol.for(binary); } @@ -87,8 +99,16 @@ function bxor(left, right) { } function is_atom(value) { + if (value === null) { + return true; + } else if (is_boolean(value)) { + return true; + } + return ( - typeof value === 'symbol' || value instanceof Symbol || value.__MODULE__ + typeof value === 'symbol' || + value instanceof Symbol || + value.__MODULE__ != null ); } diff --git a/src/javascript/tests/core/erlang_compat/erlang_spec.js b/src/javascript/tests/core/erlang_compat/erlang_spec.js index 6bc6d4d0..0abab51e 100644 --- a/src/javascript/tests/core/erlang_compat/erlang_spec.js +++ b/src/javascript/tests/core/erlang_compat/erlang_spec.js @@ -1,6 +1,14 @@ import test from 'ava'; import Core from '../../../lib/core'; +test('is_atom', t => { + t.is(Core.erlang.is_atom(null), true); + t.is(Core.erlang.is_atom(true), true); + t.is(Core.erlang.is_atom(false), true); + t.is(Core.erlang.is_atom(Symbol.for('error')), true); + t.is(Core.erlang.is_atom('Hello'), false); +}); + test('atom_to_binary', t => { t.is(Core.erlang.atom_to_binary(Symbol.for('error')), 'error'); t.is( @@ -8,6 +16,11 @@ test('atom_to_binary', t => { 'error' ); + t.is(Core.erlang.atom_to_binary(null, Symbol.for('utf8')), 'nil'); + + t.is(Core.erlang.atom_to_binary(true, Symbol.for('utf8')), 'true'); + t.is(Core.erlang.atom_to_binary(false, Symbol.for('utf8')), 'false'); + t.throws( () => Core.erlang.atom_to_binary(Symbol.for('error'), Symbol.for('utf16')), Error @@ -23,7 +36,7 @@ test('list_concatenation', t => { 3, 4, 5, - 6, + 6 ]); }); From 090ed684960fd5a8d2d6896e8a23af75eeb24f3f Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Fri, 11 Aug 2017 21:07:32 -0500 Subject: [PATCH 228/418] Change Elixir.App.js to elixirscript.build.js --- JavascriptInterop.md | 2 +- README.md | 2 +- lib/elixir_script.ex | 8 ++++---- lib/elixir_script/compiler.ex | 2 +- lib/elixir_script/passes/output.ex | 2 +- lib/mix/tasks/compile.elixir_script.ex | 2 +- test/compiler_test.exs | 2 +- 7 files changed, 10 insertions(+), 10 deletions(-) diff --git a/JavascriptInterop.md b/JavascriptInterop.md index 0b22dbe0..9e01c189 100644 --- a/JavascriptInterop.md +++ b/JavascriptInterop.md @@ -81,7 +81,7 @@ For more information and options. Check the documentation for `ElixirScript.FFI` ``` ```javascript - import Elixir from './Elixir.App.js' + import Elixir from './elixirscript.build.js' Elixir.start(Elixir.Main, [1, 2, 3]) ``` diff --git a/README.md b/README.md index 8565d6d3..ba961ca4 100644 --- a/README.md +++ b/README.md @@ -32,7 +32,7 @@ Also add `elixir_script` configuration # Entry module. Can also be a list of modules input: MyEntryModule, # Output path. Either a path to a js file or a directory - output: "priv/elixir_script/build/Elixir.App.js" + output: "priv/elixir_script/build/elixirscript.build.js" ] ] end diff --git a/lib/elixir_script.ex b/lib/elixir_script.ex index e0ad5334..bc54565a 100644 --- a/lib/elixir_script.ex +++ b/lib/elixir_script.ex @@ -29,7 +29,7 @@ defmodule ElixirScript do # Entry module. Can also be a list of modules input: MyEntryModule, # Output path. Either a path to a js file or a directory - output: "priv/elixir_script/build/Elixir.App.js" + output: "priv/elixir_script/build/elixirscript.build.js" ] ] end @@ -42,16 +42,16 @@ defmodule ElixirScript do * `output`: The path of the generated JavaScript file. (defaults to `priv/elixir_script/build`) If path ends in `.js` then that will be the name of the file. If a directory is given, - file will be named `Elixir.App.js` + file will be named `elixirscript.build.js` * `root`: Optional root for imports of FFI JavaScript modules. Defaults to `.`. If using output directly in a browser, you may want to make it something like `/js` or some uri. - Now run `mix compile` and you should see a JavaScript file named `Elixir.App.js` in the `priv/elixir_script/build/` directory. ElixirScript outputs JavaScript in the ES Module format. If your browser supports it, you can include the output in a script tag with the type "module" + Now run `mix compile` and you should see a JavaScript file named `elixirscript.build.js` in the `priv/elixir_script/build/` directory. ElixirScript outputs JavaScript in the ES Module format. If your browser supports it, you can include the output in a script tag with the type "module" ```html ``` diff --git a/lib/elixir_script/passes/find_used_modules.ex b/lib/elixir_script/passes/find_used_modules.ex index 6e3c85aa..5b33127a 100644 --- a/lib/elixir_script/passes/find_used_modules.ex +++ b/lib/elixir_script/passes/find_used_modules.ex @@ -136,8 +136,8 @@ defmodule ElixirScript.FindUsedModules do defp walk(form, state) when is_atom(form) and form not in [BitString, Function, PID, Port, Reference, Any, Elixir] do if ElixirScript.Translate.Module.is_elixir_module(form) and !ElixirScript.Translate.Module.is_js_module(form, state) do + ModuleState.add_used_module(state.pid, state.module, form) if ModuleState.get_module(state.pid, form) == nil do - ModuleState.add_used_module(state.pid, state.module, form) do_execute(form, state.pid) end end @@ -166,8 +166,8 @@ defmodule ElixirScript.FindUsedModules do defp walk({:%, _, [module, params]}, state) do if ElixirScript.Translate.Module.is_elixir_module(module) and !ElixirScript.Translate.Module.is_js_module(module, state) do + ModuleState.add_used_module(state.pid, state.module, module) if ModuleState.get_module(state.pid, module) == nil do - ModuleState.add_used_module(state.pid, state.module, module) do_execute(module, state.pid) end end @@ -302,8 +302,8 @@ defmodule ElixirScript.FindUsedModules do defp walk({:., _, [module, function]}, state) do cond do ElixirScript.Translate.Module.is_elixir_module(module) -> + ModuleState.add_used_module(state.pid, state.module, module) if ModuleState.get_module(state.pid, module) == nil do - ModuleState.add_used_module(state.pid, state.module, module) do_execute(module, state.pid) end true -> diff --git a/lib/elixir_script/passes/output.ex b/lib/elixir_script/passes/output.ex index 650a6336..ce6ad187 100644 --- a/lib/elixir_script/passes/output.ex +++ b/lib/elixir_script/passes/output.ex @@ -80,7 +80,7 @@ defmodule ElixirScript.Output do end def module_to_name(module) do - "#{inspect module}" + "$#{inspect module}$" |> String.replace(".", "$") end @@ -93,7 +93,12 @@ defmodule ElixirScript.Output do end defp output(code, module, path, js_modules) do - output_dir = Path.dirname(path) + output_dir = if File.dir?(path) do + path + else + Path.dirname(path) + end + file_name = Path.join(output_dir, "Elixir.#{inspect module}.js") if !File.exists?(output_dir) do diff --git a/lib/elixir_script/passes/translate/module.ex b/lib/elixir_script/passes/translate/module.ex index 2d15d67d..81ed418b 100644 --- a/lib/elixir_script/passes/translate/module.ex +++ b/lib/elixir_script/passes/translate/module.ex @@ -54,20 +54,14 @@ defmodule ElixirScript.Translate.Module do combined_defs = combine_defs(used_defs) exports = make_exports(module, combined_defs) - # If there are no public exports, skip compilation - case exports do - %ESTree.ObjectExpression{ properties: props } when length(props) == 2 -> - nil - _ -> - { compiled_functions, _ } = Enum.map_reduce(combined_defs, state, &Function.compile(&1, &2)) + { compiled_functions, _ } = Enum.map_reduce(combined_defs, state, &Function.compile(&1, &2)) - info_function = make_info_function(module, state) - compiled_functions = [info_function] ++ compiled_functions + info_function = make_info_function(module, state) + compiled_functions = [info_function] ++ compiled_functions - js_ast = [compiled_functions, exports] + js_ast = [compiled_functions, exports] - ModuleState.put_module(pid, module, Map.put(info, :js_ast, js_ast)) - end + ModuleState.put_module(pid, module, Map.put(info, :js_ast, js_ast)) end defp combine_defs(used_defs) do diff --git a/test/passes/translate/form_test.exs b/test/passes/translate/form_test.exs index b0a6c34d..d40f4e30 100644 --- a/test/passes/translate/form_test.exs +++ b/test/passes/translate/form_test.exs @@ -1,7 +1,6 @@ defmodule ElixirScript.Translate.Forms.Test do use ExUnit.Case alias ElixirScript.Translate.Form - alias ElixirScript.Translate.Identifier alias ElixirScript.Translate.Helpers alias ESTree.Tools.Builder, as: J use ExUnitProperties @@ -127,7 +126,7 @@ defmodule ElixirScript.Translate.Forms.Test do ast = IO {js_ast, _} = Form.compile(ast, state) - assert js_ast == %ESTree.Identifier{loc: nil, name: "IO", type: "Identifier"} + assert js_ast == %ESTree.Identifier{loc: nil, name: "$IO$", type: "Identifier"} end test "function returning an array" do diff --git a/test/support/helpers.ex b/test/support/helpers.ex index 090554fc..813b6cf9 100644 --- a/test/support/helpers.ex +++ b/test/support/helpers.ex @@ -3,10 +3,7 @@ defmodule Helpers do def call_compiled_function(module, func, args \\ []) when is_list(args) do File.mkdir "tmp" - filename = Macro.underscore(inspect(module) <> "_" <> to_string(func)) - path = Path.join("tmp", filename <> ".mjs") - - ElixirScript.Compiler.compile(module, [output: path]) + ElixirScript.Compiler.compile(module, [output: "tmp"]) args_to_js = args |> Enum.map(&ElixirScript.TermConverter.encode/1) @@ -14,9 +11,7 @@ defmodule Helpers do main = """ import ElixirScript from './ElixirScript.Core.js'; - import Elixir from './#{filename}.mjs'; - - const mod = Elixir.#{inspect module}.__load(Elixir) + import mod from './Elixir.#{inspect module}.js'; const ret = mod.#{func}(#{args_to_js}) const jsonRet = JSON.stringify(ret, (name, value) => { @@ -34,7 +29,7 @@ defmodule Helpers do process.stdout.write(jsonRet) """ - main_path = Path.join("tmp", filename <> ".main.mjs") + main_path = Path.join("tmp", "Elixir.#{inspect module}.main.mjs") File.write!(main_path, main) {out, _a} = System.cmd "node", ["-r", "@std/esm", main_path] From f3ab23ecc579fd977ad6379039c98b0a3a0968d8 Mon Sep 17 00:00:00 2001 From: Mohamed Seleem Date: Sat, 21 Oct 2017 22:23:07 +0200 Subject: [PATCH 337/418] Add filename.join/1 --- src/javascript/lib/core.js | 2 ++ .../lib/core/erlang_compat/filename.js | 18 ++++++++++++++++++ .../tests/core/erlang_compat/filename_spec.js | 13 +++++++++++++ 3 files changed, 33 insertions(+) create mode 100644 src/javascript/lib/core/erlang_compat/filename.js create mode 100644 src/javascript/tests/core/erlang_compat/filename_spec.js diff --git a/src/javascript/lib/core.js b/src/javascript/lib/core.js index a13c9489..093816c2 100644 --- a/src/javascript/lib/core.js +++ b/src/javascript/lib/core.js @@ -8,6 +8,7 @@ import lists from './core/erlang_compat/lists'; import elixir_errors from './core/erlang_compat/elixir_errors'; import elixir_config from './core/erlang_compat/elixir_config'; import io from './core/erlang_compat/io'; +import filename from './core/erlang_compat/filename'; import binary from './core/erlang_compat/binary'; import unicode from './core/erlang_compat/unicode'; import Store from './core/store'; @@ -64,6 +65,7 @@ export default { lists, elixir_errors, io, + filename, binary, unicode, elixir_config, diff --git a/src/javascript/lib/core/erlang_compat/filename.js b/src/javascript/lib/core/erlang_compat/filename.js new file mode 100644 index 00000000..ec474109 --- /dev/null +++ b/src/javascript/lib/core/erlang_compat/filename.js @@ -0,0 +1,18 @@ +function join(arg = [], extra = []) { + let components = Array.isArray(arg) ? arg : [arg]; + components = components.concat(extra) + let names = []; + for (let i = components.length - 1; i >= 0; i--) { + const name = components[i]; + const normalized_name = name.replace(/\/+/g, '/').replace(/^\/|\/$/g, ''); + names.push(normalized_name); + if (name[0] == '/') { + names.push(''); + break; + } + } + return names.reverse().join('/'); +} +export default { + join, +}; diff --git a/src/javascript/tests/core/erlang_compat/filename_spec.js b/src/javascript/tests/core/erlang_compat/filename_spec.js new file mode 100644 index 00000000..57692d3b --- /dev/null +++ b/src/javascript/tests/core/erlang_compat/filename_spec.js @@ -0,0 +1,13 @@ +import test from 'ava'; +import Core from '../../../lib/core'; + +test('join/1', (t) => { + let result = Core.filename.join(['/usr', 'local', 'bin']); + t.is(result, '/usr/local/bin'); + + result = Core.filename.join(['a', '///b/', 'c/']); + t.is(result, '/b/c'); + + result = Core.filename.join(['a/b///c/']); + t.is(result, 'a/b/c'); +}); From f39e21c17d51045769a3e2ee872baa28ee16cc0d Mon Sep 17 00:00:00 2001 From: Mohamed Seleem Date: Sun, 22 Oct 2017 10:32:10 +0200 Subject: [PATCH 338/418] Add filename.dirname/1 --- src/javascript/lib/core/erlang_compat/filename.js | 8 ++++++++ src/javascript/tests/core/erlang_compat/filename_spec.js | 8 ++++++++ 2 files changed, 16 insertions(+) diff --git a/src/javascript/lib/core/erlang_compat/filename.js b/src/javascript/lib/core/erlang_compat/filename.js index ec474109..49d2aa83 100644 --- a/src/javascript/lib/core/erlang_compat/filename.js +++ b/src/javascript/lib/core/erlang_compat/filename.js @@ -13,6 +13,14 @@ function join(arg = [], extra = []) { } return names.reverse().join('/'); } + +function dirname(arg) { + const path = join([arg]); + const index = path.lastIndexOf('/'); + return index == -1 ? '.' : path.substr(0, index); +} + export default { join, + dirname, }; diff --git a/src/javascript/tests/core/erlang_compat/filename_spec.js b/src/javascript/tests/core/erlang_compat/filename_spec.js index 57692d3b..c5976942 100644 --- a/src/javascript/tests/core/erlang_compat/filename_spec.js +++ b/src/javascript/tests/core/erlang_compat/filename_spec.js @@ -1,6 +1,14 @@ import test from 'ava'; import Core from '../../../lib/core'; +test('dirname/1', (t) => { + let result = Core.filename.dirname('/usr/src/kalle.erl'); + t.is(result, '/usr/src'); + + result = Core.filename.dirname('kalle.erl'); + t.is(result, '.'); +}); + test('join/1', (t) => { let result = Core.filename.join(['/usr', 'local', 'bin']); t.is(result, '/usr/local/bin'); From a9eae953e66b55147b2426ec93ee0f0aebc046e8 Mon Sep 17 00:00:00 2001 From: Mohamed Seleem Date: Sun, 22 Oct 2017 10:34:02 +0200 Subject: [PATCH 339/418] Fix filename.join/2 signature --- src/javascript/lib/core/erlang_compat/filename.js | 5 ++--- src/javascript/tests/core/erlang_compat/filename_spec.js | 5 +++++ 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/javascript/lib/core/erlang_compat/filename.js b/src/javascript/lib/core/erlang_compat/filename.js index 49d2aa83..42458b94 100644 --- a/src/javascript/lib/core/erlang_compat/filename.js +++ b/src/javascript/lib/core/erlang_compat/filename.js @@ -1,6 +1,5 @@ -function join(arg = [], extra = []) { - let components = Array.isArray(arg) ? arg : [arg]; - components = components.concat(extra) +function join(arg, extra = null) { + const components = Array.isArray(arg) ? arg : [arg, extra]; let names = []; for (let i = components.length - 1; i >= 0; i--) { const name = components[i]; diff --git a/src/javascript/tests/core/erlang_compat/filename_spec.js b/src/javascript/tests/core/erlang_compat/filename_spec.js index c5976942..a647b1e6 100644 --- a/src/javascript/tests/core/erlang_compat/filename_spec.js +++ b/src/javascript/tests/core/erlang_compat/filename_spec.js @@ -19,3 +19,8 @@ test('join/1', (t) => { result = Core.filename.join(['a/b///c/']); t.is(result, 'a/b/c'); }); + +test('join/2', (t) => { + let result = Core.filename.join('/usr', 'bin'); + t.is(result, '/usr/bin'); +}); From a6741fdcdfa71749b90b73e676c9a349dc84c7ea Mon Sep 17 00:00:00 2001 From: Mohamed Seleem Date: Sun, 22 Oct 2017 13:40:53 +0200 Subject: [PATCH 340/418] Fix returning empty string if the path passed to filename.dirname/1 is a path to a file in the root directory --- src/javascript/lib/core/erlang_compat/filename.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/javascript/lib/core/erlang_compat/filename.js b/src/javascript/lib/core/erlang_compat/filename.js index 42458b94..401821df 100644 --- a/src/javascript/lib/core/erlang_compat/filename.js +++ b/src/javascript/lib/core/erlang_compat/filename.js @@ -16,7 +16,7 @@ function join(arg, extra = null) { function dirname(arg) { const path = join([arg]); const index = path.lastIndexOf('/'); - return index == -1 ? '.' : path.substr(0, index); + return index == -1 ? '.' : path.substr(0, index) || '/'; } export default { From 26392edc4f5371cd43acf96632529dd5c5ae79a4 Mon Sep 17 00:00:00 2001 From: Mohamed Seleem Date: Sun, 22 Oct 2017 13:41:05 +0200 Subject: [PATCH 341/418] Add more test cases --- src/javascript/tests/core/erlang_compat/filename_spec.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/javascript/tests/core/erlang_compat/filename_spec.js b/src/javascript/tests/core/erlang_compat/filename_spec.js index a647b1e6..053130f7 100644 --- a/src/javascript/tests/core/erlang_compat/filename_spec.js +++ b/src/javascript/tests/core/erlang_compat/filename_spec.js @@ -5,8 +5,14 @@ test('dirname/1', (t) => { let result = Core.filename.dirname('/usr/src/kalle.erl'); t.is(result, '/usr/src'); + result = Core.filename.dirname('usr/kalle.erl'); + t.is(result, 'usr'); + result = Core.filename.dirname('kalle.erl'); t.is(result, '.'); + + result = Core.filename.dirname('/kalle.erl'); + t.is(result, '/'); }); test('join/1', (t) => { From 39a3e3d2d6d603be9acf355cdbdd4d9882fe492d Mon Sep 17 00:00:00 2001 From: Mohamed Seleem Date: Sun, 22 Oct 2017 13:43:57 +0200 Subject: [PATCH 342/418] Fix issues found by ebert --- src/javascript/lib/core/erlang_compat/filename.js | 4 ++-- src/javascript/tests/core/erlang_compat/filename_spec.js | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/javascript/lib/core/erlang_compat/filename.js b/src/javascript/lib/core/erlang_compat/filename.js index 401821df..1d2fe0af 100644 --- a/src/javascript/lib/core/erlang_compat/filename.js +++ b/src/javascript/lib/core/erlang_compat/filename.js @@ -5,7 +5,7 @@ function join(arg, extra = null) { const name = components[i]; const normalized_name = name.replace(/\/+/g, '/').replace(/^\/|\/$/g, ''); names.push(normalized_name); - if (name[0] == '/') { + if (name[0] === '/') { names.push(''); break; } @@ -16,7 +16,7 @@ function join(arg, extra = null) { function dirname(arg) { const path = join([arg]); const index = path.lastIndexOf('/'); - return index == -1 ? '.' : path.substr(0, index) || '/'; + return index === -1 ? '.' : (path.substr(0, index) || '/'); } export default { diff --git a/src/javascript/tests/core/erlang_compat/filename_spec.js b/src/javascript/tests/core/erlang_compat/filename_spec.js index 053130f7..98bc1ab3 100644 --- a/src/javascript/tests/core/erlang_compat/filename_spec.js +++ b/src/javascript/tests/core/erlang_compat/filename_spec.js @@ -27,6 +27,6 @@ test('join/1', (t) => { }); test('join/2', (t) => { - let result = Core.filename.join('/usr', 'bin'); + const result = Core.filename.join('/usr', 'bin'); t.is(result, '/usr/bin'); }); From 0557c584ca47fbc69fac7cfc79560fa1ad42bf26 Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Sun, 22 Oct 2017 20:16:07 -0500 Subject: [PATCH 343/418] Beginnings of a testing framework --- lib/elixir_script/test.ex | 64 +++++++++++++++++++++++ lib/elixir_script/test/assertion_error.ex | 3 ++ lib/elixir_script/test/assertions.ex | 9 ++++ lib/mix/tasks/elixirscript.test.ex | 25 +++++++++ test_elixir_script/test_test.exs | 7 +++ 5 files changed, 108 insertions(+) create mode 100644 lib/elixir_script/test.ex create mode 100644 lib/elixir_script/test/assertion_error.ex create mode 100644 lib/elixir_script/test/assertions.ex create mode 100644 lib/mix/tasks/elixirscript.test.ex create mode 100644 test_elixir_script/test_test.exs diff --git a/lib/elixir_script/test.ex b/lib/elixir_script/test.ex new file mode 100644 index 00000000..9072c234 --- /dev/null +++ b/lib/elixir_script/test.ex @@ -0,0 +1,64 @@ +defmodule ElixirScript.Test do + @doc false + defmacro __using__(_opts) do + quote do + import unquote(__MODULE__), only: [test: 2, test: 3] + import ElixirScript.Test.Assertions + + def __elixir_script_test_module__(), do: true + end + end + + defmacro test(message, context \\ quote(do: _), contents) do + contents = + case contents do + [do: block] -> + quote do + unquote(block) + :ok + end + _ -> + quote do + try(unquote(contents)) + :ok + end + end + + context = Macro.escape(context) + contents = Macro.escape(contents, unquote: true) + name = String.to_atom("__test_#{String.replace(message, " ", "_")}") + + quote bind_quoted: [context: context, contents: contents, message: message, name: name] do + def unquote(name)(unquote(context)) do + %{ + message: unquote(message), + test: fn(context) -> unquote(contents) end + } + end + end + end + + @doc """ + Runs tests found in the given path. Accepts wildcards + """ + def start(path, opts \\ %{}) do + output = Path.join([System.tmp_dir!(), "elixirscript_tests"]) + File.mkdir_p!(output) + + ElixirScript.Compiler.compile(path, [output: output]) + + js_files = output + |> Path.expand + |> Path.join("Elixir.*.js") + |> Path.wildcard() + + test_script_path = Path.join([:code.priv_dir(:elixir_script), "index.js"]) + + {out, _a} = System.cmd "node", [test_script_path] ++ js_files, into: IO.stream(:stdio, :line) + + # Delete directory at the end + File.rm_rf!(output) + + :ok + end +end diff --git a/lib/elixir_script/test/assertion_error.ex b/lib/elixir_script/test/assertion_error.ex new file mode 100644 index 00000000..3a88fde2 --- /dev/null +++ b/lib/elixir_script/test/assertion_error.ex @@ -0,0 +1,3 @@ +defmodule ElixirScript.Test.AssertionError do + defexception [:message] +end diff --git a/lib/elixir_script/test/assertions.ex b/lib/elixir_script/test/assertions.ex new file mode 100644 index 00000000..49a0db1c --- /dev/null +++ b/lib/elixir_script/test/assertions.ex @@ -0,0 +1,9 @@ +defmodule ElixirScript.Test.Assertions do + def assert(value) do + if !value do + ElixirScript.JS.throw(%ElixirScript.Test.AssertionError{ + message: "failed" + }) + end + end +end diff --git a/lib/mix/tasks/elixirscript.test.ex b/lib/mix/tasks/elixirscript.test.ex new file mode 100644 index 00000000..153a4cff --- /dev/null +++ b/lib/mix/tasks/elixirscript.test.ex @@ -0,0 +1,25 @@ +defmodule Mix.Tasks.Elixirscript.Test do + @moduledoc """ + Runs ElixirScript Tests + """ + use Mix.Task + + @shortdoc "Runs ElixirScript Tests" + + + def run(args) do + Mix.Task.run "app.start" + + path = Path.join([default_test_path(), "**", "*_test.exs"]) + ElixirScript.Test.start(path) + + end + + defp default_test_path do + if File.dir?("test_elixir_script") do + "test_elixir_script" + else + "" + end + end +end diff --git a/test_elixir_script/test_test.exs b/test_elixir_script/test_test.exs new file mode 100644 index 00000000..069409f0 --- /dev/null +++ b/test_elixir_script/test_test.exs @@ -0,0 +1,7 @@ +defmodule ElixirScript.Test.Test do + use ElixirScript.Test + + test "can get ast from beam" do + assert 1 == 2 + end +end From 6982cbcb07e5d13305f6ad4c5f09aa6f71422675 Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Mon, 23 Oct 2017 21:53:14 -0500 Subject: [PATCH 344/418] Using raise instead of JS.throw --- lib/elixir_script/test/assertions.ex | 4 +--- src/javascript/lib/core/erlang_compat/erlang.js | 12 +++++++++--- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/lib/elixir_script/test/assertions.ex b/lib/elixir_script/test/assertions.ex index 49a0db1c..2d8496b6 100644 --- a/lib/elixir_script/test/assertions.ex +++ b/lib/elixir_script/test/assertions.ex @@ -1,9 +1,7 @@ defmodule ElixirScript.Test.Assertions do def assert(value) do if !value do - ElixirScript.JS.throw(%ElixirScript.Test.AssertionError{ - message: "failed" - }) + raise ElixirScript.Test.AssertionError, message: "failed" end end end diff --git a/src/javascript/lib/core/erlang_compat/erlang.js b/src/javascript/lib/core/erlang_compat/erlang.js index 9867a9f5..18ec72d9 100644 --- a/src/javascript/lib/core/erlang_compat/erlang.js +++ b/src/javascript/lib/core/erlang_compat/erlang.js @@ -478,6 +478,8 @@ function _throw(term) { } function error(reason) { + let theError = null; + if (reason instanceof Map && reason.has(Symbol.for('__exception__'))) { let name = Symbol.keyFor(reason.get(Symbol.for('__struct__')).__MODULE__); name = name @@ -485,12 +487,16 @@ function error(reason) { .slice(1) .join('.'); const message = reason.get(Symbol.for('message')); - throw new Error(`** (${name}) ${message}`); + theError = new Error(`** (${name}) ${message}`); } else if (is_binary(reason)) { - throw new Error(`** (RuntimeError) ${reason}`); + theError = new Error(`** (RuntimeError) ${reason}`); } else { - throw new Error(`** (ErlangError) Erlang Error ${reason.toString()}`); + theError = new Error(`** (ErlangError) Erlang Error ${reason.toString()}`); } + + theError.__reason = reason; + + throw theError; } function exit(...args) { From 4f827e0469ad8ec86d4e8b025b89194c273e7b4d Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Tue, 24 Oct 2017 21:24:21 -0500 Subject: [PATCH 345/418] Some refactoring --- lib/{elixir_script => elixir_script_test}/test.ex | 2 +- .../test/assertion_error.ex | 0 lib/{elixir_script => elixir_script_test}/test/assertions.ex | 0 lib/mix/tasks/elixirscript.test.ex | 3 +-- test_elixir_script/test_test.exs | 2 +- 5 files changed, 3 insertions(+), 4 deletions(-) rename lib/{elixir_script => elixir_script_test}/test.ex (97%) rename lib/{elixir_script => elixir_script_test}/test/assertion_error.ex (100%) rename lib/{elixir_script => elixir_script_test}/test/assertions.ex (100%) diff --git a/lib/elixir_script/test.ex b/lib/elixir_script_test/test.ex similarity index 97% rename from lib/elixir_script/test.ex rename to lib/elixir_script_test/test.ex index 9072c234..b8bbd440 100644 --- a/lib/elixir_script/test.ex +++ b/lib/elixir_script_test/test.ex @@ -3,7 +3,7 @@ defmodule ElixirScript.Test do defmacro __using__(_opts) do quote do import unquote(__MODULE__), only: [test: 2, test: 3] - import ElixirScript.Test.Assertions + import ExUnit.Assertions def __elixir_script_test_module__(), do: true end diff --git a/lib/elixir_script/test/assertion_error.ex b/lib/elixir_script_test/test/assertion_error.ex similarity index 100% rename from lib/elixir_script/test/assertion_error.ex rename to lib/elixir_script_test/test/assertion_error.ex diff --git a/lib/elixir_script/test/assertions.ex b/lib/elixir_script_test/test/assertions.ex similarity index 100% rename from lib/elixir_script/test/assertions.ex rename to lib/elixir_script_test/test/assertions.ex diff --git a/lib/mix/tasks/elixirscript.test.ex b/lib/mix/tasks/elixirscript.test.ex index 153a4cff..3d282b23 100644 --- a/lib/mix/tasks/elixirscript.test.ex +++ b/lib/mix/tasks/elixirscript.test.ex @@ -5,14 +5,13 @@ defmodule Mix.Tasks.Elixirscript.Test do use Mix.Task @shortdoc "Runs ElixirScript Tests" - + @preferred_cli_env :test def run(args) do Mix.Task.run "app.start" path = Path.join([default_test_path(), "**", "*_test.exs"]) ElixirScript.Test.start(path) - end defp default_test_path do diff --git a/test_elixir_script/test_test.exs b/test_elixir_script/test_test.exs index 069409f0..c4d5c4a9 100644 --- a/test_elixir_script/test_test.exs +++ b/test_elixir_script/test_test.exs @@ -2,6 +2,6 @@ defmodule ElixirScript.Test.Test do use ElixirScript.Test test "can get ast from beam" do - assert 1 == 2 + assert 1 = 2 end end From 55763cebb3512a9832a903453d3118c0ffcec3b0 Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Tue, 24 Oct 2017 21:27:58 -0500 Subject: [PATCH 346/418] Testrunner --- .gitignore | 2 +- lib/elixir_script_test/test.ex | 2 +- priv/testrunner/esm/LICENSE | 23 ++++++ priv/testrunner/esm/README.md | 131 +++++++++++++++++++++++++++++++ priv/testrunner/esm/esm.js.gz | Bin 0 -> 44315 bytes priv/testrunner/esm/package.json | 20 +++++ priv/testrunner/testRunner.js | 51 ++++++++++++ 7 files changed, 227 insertions(+), 2 deletions(-) create mode 100644 priv/testrunner/esm/LICENSE create mode 100644 priv/testrunner/esm/README.md create mode 100644 priv/testrunner/esm/esm.js.gz create mode 100644 priv/testrunner/esm/package.json create mode 100644 priv/testrunner/testRunner.js diff --git a/.gitignore b/.gitignore index 755b82c6..cb91ffe0 100644 --- a/.gitignore +++ b/.gitignore @@ -22,6 +22,6 @@ stdlib_state.bin test/app/build .vscode cover -/priv +/priv/build /tmp .esm-cache diff --git a/lib/elixir_script_test/test.ex b/lib/elixir_script_test/test.ex index b8bbd440..cc5da921 100644 --- a/lib/elixir_script_test/test.ex +++ b/lib/elixir_script_test/test.ex @@ -52,7 +52,7 @@ defmodule ElixirScript.Test do |> Path.join("Elixir.*.js") |> Path.wildcard() - test_script_path = Path.join([:code.priv_dir(:elixir_script), "index.js"]) + test_script_path = Path.join([:code.priv_dir(:elixir_script), "testrunner", "index.js"]) {out, _a} = System.cmd "node", [test_script_path] ++ js_files, into: IO.stream(:stdio, :line) diff --git a/priv/testrunner/esm/LICENSE b/priv/testrunner/esm/LICENSE new file mode 100644 index 00000000..2902552d --- /dev/null +++ b/priv/testrunner/esm/LICENSE @@ -0,0 +1,23 @@ +The MIT License (MIT) + +Copyright @std/esm contributors + +Based on reify, copyright Ben Newman + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/priv/testrunner/esm/README.md b/priv/testrunner/esm/README.md new file mode 100644 index 00000000..83c5c840 --- /dev/null +++ b/priv/testrunner/esm/README.md @@ -0,0 +1,131 @@ +# @std/esm + +This fast, small, zero dependency, package is all you need to enable +ES modules in Node 4+ today! + +:book: See the [release post](https://medium.com/web-on-the-edge/es-modules-in-node-today-32cff914e4b) +for all the details. + +Getting started +--- + + 1. Run `npm i --save @std/esm` in your app or package directory. + 2. Add `.esm-cache` to your `.gitignore`. + 3. Create the ESM loader to import your main ES module: + + **index.js** + ```js + require = require("@std/esm")(module) + module.exports = require("./main.mjs").default + ``` + + By default, `@std/esm` **only** processes files of packages that opt-in + with a `@std/esm` options object or `@std/esm` as a dependency, dev + dependency, or peer dependency in their package.json. However, you can + enable processing **all** files with specific options by passing an options + object as the second argument or passing `true` to use the options from + your package.json. + + ```js + const loader1 = require("@std/esm")(module, { cjs: true, esm: "js" }) + const loader2 = require("@std/esm")(module, true) + ``` + +Enable ESM in the Node CLI by loading `@std/esm` with the [`-r` option](https://nodejs.org/api/cli.html#cli_r_require_module): + +```shell +node -r @std/esm file.mjs +``` + +Enable ESM in the Node REPL by loading `@std/esm` upon entering: + +```shell +$ node +> require("@std/esm") +@std/esm enabled +> import p from "path" +undefined +> p.join("hello", "world") +'hello/world' +``` + +*Note: The `"cjs"` and `"gz"` options are [unlocked](#unlockables) in the Node REPL.* + +Standard Features +--- + +The `@std/esm` loader is as spec-compliant +as possible and follows [Node’s rules](https://github.com/nodejs/node-eps/blob/master/002-es-modules.md). + +:point_right: This means, by default, ESM requires the use of the `.mjs` file +extension.
+:unlock: You can [unlock](#unlockables) ESM with the `.js` file extension using +the `"js"` ESM mode. + +Out of the box `@std/esm` just works, no configuration necessary, and supports: + +* [`import`](https://ponyfoo.com/articles/es6-modules-in-depth#import) / [`export`](https://ponyfoo.com/articles/es6-modules-in-depth#export) +* [Dynamic `import()`](https://github.com/tc39/proposal-dynamic-import) +* [Live bindings](https://ponyfoo.com/articles/es6-modules-in-depth#bindings-not-values) +* [Loading `.mjs` files as ESM](https://github.com/nodejs/node-eps/blob/master/002-es-modules.md#32-determining-if-source-is-an-es-module) +* [The file URI scheme](https://en.wikipedia.org/wiki/File_URI_scheme) +* Node 4+ support + +Unlockables +--- + +Unlock extra features with `"@std/esm":options` or +`"@std":{"esm":options}` in your package.json. + +*Note: All options are **off** by default and may be specified as either an object or ESM mode string.* + + + + + + + + + + + + + + + + + + + + + + + + +
+
{
+  "@std/esm": {
+
"esm": +

A string ESM mode

+
    +
  • "mjs" files as ESM (default)
  • +
  • "all" files as ESM
  • +
  • "js" files with import, export, or "use module" as ESM
  • +
+
"cjs": +

A boolean for CJS features in ESM

+ +
"await":

A boolean for top-level await in the main ES module

"gz": +

A boolean for gzipped module support (i.e. .js.gz, .mjs.gz)

+ +
+
  }
+}
+
diff --git a/priv/testrunner/esm/esm.js.gz b/priv/testrunner/esm/esm.js.gz new file mode 100644 index 0000000000000000000000000000000000000000..d199117df28f418ef7774a106399c091d28c06c9 GIT binary patch literal 44315 zcmV(zK<2+6iwFP!000021FRVbm*O`1uXz0K5h*BMCOv?L^xm%@%gr-JU~P=eNn&Pr z;QxN#Crd7@hipq(OJDDj*l@2!ppBA=2`5RBYZDm0Emr$XOsY>L9(IK?nv?ZDPmC;b zV(8JY13@G`$~Dn*xu8mzy~+bzd$!44tb&{)h#%!xvTS^H%^Y%kEX#>wGRTy~Sw?ct z%W~GN1%*wGQFaG;M?ys?;R26l?5z$HDMepx;fiHTNXEpzd! zDt1DdgC#pc6xMRHSMf3v*4BK#6>c|T8)3$>q$SADc{?JNEoLw<(e16!KiS~TY6^Pv zexlNNpP6#pgKW97BASJ92<9@4>Wa2IqGoZP>{MY2bJ&R}jrA}0x%a6GDKemp9S=h$ zh=?@*@I6{mGACW3rcSpK|JzF?NVtnl8Uiirkb+sqs$L{_CL~J4ModH$^XEO2B;RKl zE&JrSJrdbkLdq-7mDgan@?lY2Hm-6cWTx!LiTfarVuoK?x+)~sbdm`Jq{un}eGJW& zeO7h+Fy0oyQF^fsj58_pG$H3)oK9h3qhWW0fpf+5`i(|OYZOD<-UZ`O>4h{C@Q4!Y z61ZlwdO0x{YvXZk)@&?h+0>8Mbh%pAI;59;eHVSTE-U!FM_B=%k12~0IHD}UF9f1; zA?09uBD9W{GGEDj!!kY(s}2nrDr2F{^$xr&6s+^u$UA}1y^&eCh?H3E6G6zOm=+jQ zG?TQ-7OO;0j5-`OPpcp}Q!o@sY?2ga^1Lnxjzh*C z3DL^-VysJwtOnxgQeG8E_EI^&y{)F)H^La9Zf~uKb8hEGlWqXAv#J%<5UpBCVkQ-Q zu0O#XO7bD*P)0c^Ac=?ud+GE<-u1@kQgTl<&nt%V-Uw)2u zvC@LAI$`x)y^n6igAuuwAc#&@^Dug*!$rq09}~?Xu#pn+>T8*azaH|02rQ8G$041- zv`&ic4iLoYNvrhPiCM`l@<%1N(%KfP4z1o;6Wyv9ld9rAFwqtqjyHmfVK@%LVGY2j zTfKR)5~#PYa(A$Esxzya($b!^TfSlki1z#M`e<+bB%Ev@xk=hg#!b|OkZ)nT$%?yb6gb&Q9IY*{NIg!(Aa)!HC@} zX&j=Ym#SHJRA{Cs^Caafwa{N*qlNkpJcQUY5A=faI8X3w$*CVJ6F`M{Kg&1aReki( z)|f^L6J;XbnDpl7bIcVHv)||cUW|XAf3u*G5!w(#J5*S#evg$wOlQKiNXxP|Jb%pa zV`WZJXn`kSKO_h+IkQADb)ldT2yNO&Rqaz%%hGrQn5;KYXnu;pEo?9#2Fzk$o1hFJS912w z^;p6}&#uR2DsXFV1Z+l)nxZqCnkv>b!b2}sf>az_!>DkE!oKZ95}W)p8I+&yMgn`mu;&0S`q? zLIZ{7x}nIq0a<#oR3iRkVr5^wLD^Slvcqv@zW>4^=c#-9c8x$x)`Pi0MBIn4Ec+hJ z6cI@u!m{kT829!aUuJ~8!n|k07KP6#bNWJ*)UNz(zqea&a?9bF!8ZqT z;BkRYJQpL+<>{=&NZA{hEj^=ml-)Qq$CH(So*8c3D17o%zy0*|^aP(LJ(JjpZ({j- zoNom2M<^|66_02wGb23redye~n-qan{LbQR-eMqd z&}9uZGFu7lz+cti2Zd@K_?H?CF;|YbQNL-tyfUX#_<++1VpIHB+za(ZtOcO}e%pc@ zwq?g^AIl~o!wZ>su)Gk;=vg6i5(Z%_91rb-3-2|B!HbPDi%G3aiCq>ag6Q+NBg>hh zM;{pMs0KVik%bqs!S{2)p=~xq;tB`QP!Gds6peyuI3%#Srqv#a@(xirl!!t?+#{rhItT3cAE(hh~m#Cr(v>i|A7#+zAH2($ddvWVt+_oOen&J3(ZGY9N z?It7tveQ}ngZIUX{q{n!JLJ*$_gTBpwJmhRrpQ$Bj4LwA1lLW5BW!_jf+k}AWxHi% zlXt7f(|BH_YnPj!mCVPn8Gr)Rc8cVeM~dXH?$AUIpVc~Xzt0b5!NPV4{6RXIVlhit z$}+ZRyIQ*7c0T#(xF+=Qg@-aw$I$wGxEO@w#d*D>3-MXTvV&U06;SLAY37+`fUS2 zcICYpmEJACXubKK`G+C?+9h~(nH8-4!|WM%ApEPmk@8vdax~mOrX^*KKw0%ZmKK)P z+P^J9vwvVI99Uh421tn z&^9gZ5Qfd&tzo#^whry{{q`@HTxf&aC9m9jhcgyF9`GPPMfNwp{gICkgG^3h;p|5r zNQK95tMPmzUg=d!@%^4Cs_9~Zkp;OzXUzy zl^|H3n_Hb;>&1o&br)5i)uJHg|f!xoD!>1x|!~lI3sgGcivs+ zo_A)eJ_!U90#yG+Q}+jWe<1FG-92{ScioQ5u@F?3qemXOdBL3~6gp92dEU$~2c>GD zs-aa0B>sFrRR>iaP{lU1X8^@PNZUi&UPw#)K&vCIu4u08*5MQmqPadFB zNyVO_*fSLGsCdT(i`|J0x_Zw|gqxfx3o0Go4aaxGF$of9oRQ}kfO$?~07~SkDGOnk z6o!X{j#DzOWGT`AnR(uj+dyo9tZ&MkHl}GSaq3gtLZAgPMX;@4+lsLmCdwk3vlU!MxD0UV8=OHn!^4Df31t{tZQ;)|)OD!CQ7rMS+xy!f}Rcm1HD2MK}NA{3a)ixQ_I zvC8>n{Pk&C5*>0$@aLJ94|E7nnn52m=h5Jp5sx+L7$bV#Ax1pa(5V^mI2!RZ8u2t5 z@k-0DbbC;m5$`nT&g2*oN18PHw(x2B$!(1Xhsb@>+^3(o;|BLab1%&KO!I(XWDCZ< zh>m*^9rsMToypEAflSeN&5frua>Z-{chd6%B;{)V&FR+c=Up z{8ePm(P9MOaSl1OHj{SGX5UW{)H(X!L?oc-%q zByJQ6g+g7#&UDPfc|+X8dGq2k{UN6DRrkCRuaC}~<5Yaa&+Tm&zixJ%m+niJ0cJ`_ zNG4Te!{r1|3NKzkGH`P7zE)Gh0*pA$;;y<2_XKEyvdiP%Cawziw9A6StPq7)4;!hW z?=2E)+9oouc+cs|Orc zvihQ|<<9LCqP9>HbsosfA>54h#e@f*llBGe_)UXvbA=9XZ^Oh7m87)RQKEd?NFUmF z)%A-d8vdo;ZL%tmj9;JZ7LR{h$Auwh3tGsBgQFcO)|%y1!+)-8PIc|Bns-<1xQgG~ zWoL^|H`@H8(rmbeX2?)VsH}-o&>x|ZPwO~T;`^3h+YgphxM$_MMFY#p+fi~I!KGdc z3RYcoGQYZj9Z;_)7nV;I!v$Jmu5}Gx>o9PQBuT#=XxWxm%j3o45neoD=?QINm z*GMY>U3FZOqH*wAe1E^ZBHz=ME_FW`xivJsvNgc8PkZ3*=F+7GwvP8hgat&{!Q`ZjO(#eSx<`hsNgbGcldMyb`Hs(zQh zTgu!%PU9*(Gby%?(|&t$tF*-^6O~aW5}MM!ltt6YtMeHiSfywMNs(sJD@&Ko$hn9q zjTbgqJE_PVKxH)nim6-LX2n&fXif{IY(MR0UFdkE&dyxVPT_okr`TM~aZ#x#=!ez8 zt+-ySk}OsPwoaWw24nU!EgZ>Uu&MkDqdi_|4&b2L;8{b$S&xopx?31l-Ufq^g9KVCe!SUeqT9zk!++<O<}ZdfeZ*AUz6NMvMF)y_+wae|+D z*kDvN9FA$yziJFj>jLQsV8cExKIJk3ke@^F?c$FIw8PMHkA& zZB|)}Ar&8w~AaEv+vl>cTI$a0G=oB^ATP zJ`dtPT{BDYTuKZF7>_PWaRL!VXZr0efug*0mG|9L@OVgr6GkEW!0Il1x;SH`W?r(lQl!yBwrva)KyEiRru7k84x@*sk0W?w|#0> zG;dT*jC!5@s+sZYPdecSq@>luiS^%A<~(SSTCT7w;G32MUaOkCv=#?6XEND>IIKB*Jt2BN2vqKf?Lb{0Uo|PPuRux>Afz#M@e4SvT72MoX*b9WJM1{ zlEjWqj2#5t$FsWO9I920C7!CAX;ad}=)B4&_$^SB2xrmM);sv3X{P1}uN>2W9tw&6 zN~FQToqql?BZAB1hu+{WI#vaW;w+^f%96SpE^{)H!*ZmD)Tjvo9}i>wx4D4>ay4c* zWc*yB-ap6cG&vUI5bp45-C(cfl_u_VCc-|vssE~)i*BNqyU53zn#773T$Ia#wncZG zuJ(DBkcTvbrr%xR{p{RZjjJeO8PL?@wXd}a}OVS2Ln4D^KLk3~061-TvX zrk=2Tx|y7oV|3X~{;h6Co3fttC0M&x@U2b}OyCf&!ts2^Vy2OvcE$dZW7xHFw9z4*yByM!E+A9e`rFr^KD~bT z=aaYZfBgB)VV1ng3sgK)#i+xiv-5{K;lifS$;ZP_@8A6VnM~16-W>k<<*Wb7l0VcP zU9Fr^z0;eHnxJ2zJXCw5^G2TM!yB5{MSiKu3dx3ubgs(Tc+{bEX)3FxlQ+Ik>g+E+ zzy5f5a`@?OmS{7_SuJh*P1ykf>KuORaQKzJuE}&`g}-;ZgL+}pX=4RJGk%oyuu@Y< zjjHw%?+7buQD&{%ZJ+5%?&!*2Nx$$mpMIP3XogwUHA#M7GOvq}6fmo3UJNah3)>18 zm}GdQ<%Pv^eJvL1=3xR@o05~Fy$@jJ_Yv9XL~)6s+3*rcR7?^<1PYo%@uJ=@z@Z-% zAt5ZB`MqQ}dXO;DKsURR=h$POW0wz!#rs7NJB56}%L4;&dC(f_Wb`U&ungv? zl+jye0!bY6%UM1Xb zzq-M%1td`Ww%`g^;kF51GF%Vr>;cN;N)@|1MB-hH4w5T0AmW1sC_mrPV&=?Ex01xC zT}ln|ut$4CTi+&7>^+01sWp4YuGCS}i)VFgR<7~qtrVqO$egsDymWGX-7TDoyP+MS zM@%xU$4~iJk3|i-C2*ph@IM^1%aVfG?LVIo%Z!@t%P*rs65sU^?GH$ z%xIc+k@IkS5is|#TS5J5IUzsg8xYS1e|Ljg)TinXGx6HwSr96_P z&W^52y1?qazB(pIjyVRGVH=<(ie-b2+9DExoJV||KPb*jJR{4R&lsGJy>}Kfa)4I) zQgdCwWo~CT6|L7rREq8u>0Dp;sQd-}JORs9>ySV*H1pUqO}Gc0)#5ChZrIBWpWz?P zT=g1{vKF@UEJl@xVdaQC*ke(oo^&8LWHBreQmW57lM&t3LttZC9;$Sw*)}J1wS399 z0m}wqOr9$3SNE>8UlhgBc`y{y9EnOb&*a?LCAe=pGiuHa!B^;_Oootg3u{l!o`usZ zqv@StdQK_bEVAQ4J#);sdt2S)jX}dS9c=ZtmoRaC+qYJR3^cbi77nc$3pKLkz?PV` zf0{B9d8`>{L&lm}HeSG*Pc$qs&GHRA)S*(tq-0*!SnXc zF0lvkkhtf8=>d)RoA^j|UEI&^w`h$(NA5Kn#WfL1vLhBR@cS{A+(v#%SB6d7;;?CZ zdmJ{6C~8hWyL%>T8ogiO{Rsyu9J`olC84?tbw{Yp+vjC5`jF3R`M!WBWW$E$*{Yd4 zX$$)Qx^Y$I(rbZ1GsrT8{dHR1J*o_dY=TqL-XxC}#Z z!-Sfp%yt)?XfvvxR8==`RAJ&GW|_;DmpL3@-NA#GvCF1&`jQM51|bPw$V>YyrUQ$@ z)kl)XAv<@BKy*jhl#b_koyiF6W2^)vU} z_wJs1^34U>i*Ap6#Y55@mv<(QNVL+#G%~tl^4`hE;DK&BTm+^rx`rC1j$|Ss98nlC zP_JE`IiOMw&5Efio#!p*0xT1Wo2xSf1hjTC7A`g}*E9^BcL_9IS~i?;0*#q@b4y-u zI-kGaIN<~6ns&T?67R#Y>vaE$Ovq;twr^?U$Bg5|N?8#BmkxYXRfTFe;va?jLjp!} zS38;=Io-$y^zW!~F@F1|{d3>GZX1k0uNU`l$vv1O>?aGnVU$dkW?yGht`H7mc@Ur> zw(Bd?HFpf6HkDO&NH0F9Aww>Br(Be5Bl(A9N!n|AheTTDcJGb!f{GJXn19U>1M&UJ z7>JKeu+ztUn^^_bf+p11*(eXldpSr>0Y0mxYtO;1HI`q?Tqa_|4Z@dxqtS1_9@LC) zxUn>SaOCdQkOZH=cdmjkR;v<&II*GtGf5~(2{+&L`93hj*tg%e^f~NB*tCVtQi1|t z8mg6^w}BK6{S1p?Rt`$jKyw_-1+GVN`;ET)4IQTgHk$IFfU0ESwEfV>YFP#CHF^CW zHHbgwJMNGUZ_CvTA^+{lfedL+zu*<+;BD^kn&hhB4U!GTkf>J%-yNa4L(yO^X!hYZ zh=z6?M32*aNTssi1j!PXS+f07UCyeZgvfhe5lNFaAaz!I`I54S?I*qr_g{AFMJZ&_ zB89B7LIZRl$$B=c=}$i~%_l5pxY7(!l}5oNqYbfEK?s!BoJio}H+_$WooRGAL77Oo zg_U~KMd>JfTxlZ~pA0XcNXCUufLU|wayVfEk`DD5%vsT#)e9$3P~n`R!4YNVYSFZT zQ>A6+Z5td;p$x+*INq$JGXcRuV1BH0suxG^SLR8(KtQDua5!k|FEG3j$->ceo$LD+B@<662Rj`YZJbbXX&AE6eE!@gv&ff z6JFSxZi|rTa}-69+i8bX8p?JQ<9#dHh_}J{!?!_Ux50(02Z4UNU()J-hMSxeg(x8t z3vqW#NGg?;Awig7EA=M7QNP6S4h84A#;Fz3=42Q(kyhwg6^9Q|}m-9Vh_!Z5c*6&`C|$3+!JTc<0- zzu(wnWN_{eToV_0F0R?m;*#wv#MP>MpyLOTA&TsjAF4K)h!SO6vO61TYnOv=<<{$3 zkCOfNN|$H-AbHJP90FjeIB5^J@3?Helxk#pU9uFD16)7Fdk7fmiu0Al zj-LPwXY=yw3XPox|H~CdFkg)k%&*1>M!YfxE$=XX*T);%hpNR#uLR7;;`Nf+27U?R zGr0(e4;&JOSmB?tq}G`3r`Cq~b`cLTs+AwD*f!y_4e?5X0NUI0)Lhiw#^w!-FSwdS zTa^>cWyQWa>Y=A_MpHn#T?O4Co4-h;}d?hJ3a14jWn|G3zI~1OS1=I z1i;!k6|}VFsi>{=`@LiP^gAW_% z0{R4gA_TM#+VD<~_pKR&_<(6}WFlg}`Ax_85z3DEBCi7k|FFUDHkYdt^@%Z`+v2Qw zJ{s{C1$09ZA&mk?Ia6woQOA@VZNbDCE_wUKMtN1pD)TE9uPeSBQ-r>BLDxT3<-`+< zWpt^tuqC15!>$O9iRw-s*{Ol}qQ;-QajXok1Sw@Vs+h4@xy))Wr_Y%mj?Q-{@-15> z4LL1nndJhl(6K1uBC9Iuk(CTi!hPKN+)H`~L*sqaz??M1oB%hReC1TiqBD|2BaH3y zKw?-5mnv}b3N~7ci^B(6%_tNz4o$>37(Y_jKRF%(n86N82Abi%gn@wD86^OPa77Cx z0JKV98QeCm3=<6XC12U9G#WLNv@Q>+(S2gkLVB0F@;+^`4Cz0`T7bwKcUN`VN|{CE za)AX~vi+#TTNiYq@(7r6ykVzsM`tEAI-;qBNJ4s>v{(VkyLN_fWO8|9y=L|#oQX=m z;{quMxI_`2RlqX{LH&ZwK&|6@N7Q}xkqQKshnM%ymGCs?HRF=jEK#yq;xY_zs;z{f zg_KsigRhjv};^% zQCHriS6;5WA8xeSbd)zT-e`+3D!Hzo6MwwxsJ2&GH9F4hi>SLwga&xuvw!T~v7?HH zI&Zg^eA{X>^>(#UgQIV)Hi;hUN%|m5Y?1hHj3p`Ef;a3#zf~ zXhD>7fIoe^-B&8nSd6;CM$kWhd<~D2vY_?2WBkkg4HVdzWOX;+re&?J``=`Neny{& zs$X!(p#J6`cFs1{TxgZ+9VPaLw_Iu-4J*>SA1z5ux7(zqP(Xz*{X`EfIo??A*`QII zGmDQZxl(fcY{}vaQbm}((h@#MPpLM3uEr!%X6f>vz=@4NPL<4_Z|S{5f#w*$=9699 zPwtYu3X-AT_fZ!JVgm=OHUn9F(rc6m+l)8ojf{V&QvyWm-nekXSurt8geUf#=e6@R zo>%;pLy%SKIQk4yFWZLfyLHYon6vu+IeSBUcguGY^~GVV6HT5o@BJGwxv}lpZjER> zmih}BXq{Y^PojLtv$JL4wvg6r!9#aRv{7O4OgMyeO&<0c7K}p=kinNJ5s&2Az{?9~PR4tcsDW`cYISC66+L-p*Vevh4 zf3mmp^m*&_*)n7Mu9?>xBU+Foj~E(f9)$zfZKa)6j5u6rT+0OM24*TaV zUGKZm(Gq@E!>`>I_}DUX0$0c@+nHuemrb)Yk-l^?TE0I`TKOxWoJ_O57i|a-W{A8G!+tow|u$oj&n~9 zFr`cpMz<($_;#2ij!|O+aTidi;ERsJM}c|}7E>h)Dz$GPmQ+0!O~4vO3Tj7PuZeMz z15(Jfz&P#u^a)p6p=2ox8m=inFwVQWNxI#$KkT3l*Qovek#m3un$Ukr54w9ZP$g<(hzvgZj4z)nbQ)y7CDC#^L9guMULB2({l_d_TywI7dwQoi`!-J-A_7zOCX);1$)guHY@W=yM*B#x+IHEc+humZ)>|AgH8XAN zI6By(J$j-eVI1DxLVRQk{=I0Y;A4Rj!FekGCQ>dI9big zfblhlv;YHaIABUI&1sIzGF_x$<^6kG440K0U^7~_I#d3V^n>|;O-N%7g|^dD>NZlJ zE~obGK6|lqd)w9+QXkrwyK%r0#HpXOM&FC6kjDmJ1hi@}WKO+;X2{TXhcl&ffxK|+ zpEn4*Nc*kcAELrOL~RHxjmKmuir9vUmdsMFl6}cN-BTm_x$uT9A*W4)^U@ACKBT&1 z{AhWs9vbQKZ{e2RSXNj{3z;3^ z1dv3sLAymW!*~MrA1&9aMFIzHkrdiFlui-2w>Z!&SCG^$%AQcQDzB8Ru@UdB5qZNn zsa2JQQ+xOR$HS8kFF*hLU6O=qP;r<~d>cH?myl)7#(&dQJY$&wt-MpNl;E_CxYRpZ*Dyp?^A`{)tnf zdHP{g&Y*Kd88DFaNX71!%jCaNE`tup#!GjT6>bq?7Z=Lq@3Zedrr&zuW>oiOueP@% zK_|DnC{}`M`qvUxMv1mW$4zZz*ag@E-Yq_^v2FVYo}yS!8UwFIzQFu%dw_nK6!aYCfckf`z;-)zqL{gf_GV)6?iO<4&H) zfYz8B)}jD&Q+V^)w9hY8YRQS6Kk2?;D%PTx>$(w)%^E<-N~sN|W3r~KHKtj+7@VoK zUqrc7)Gb#Xhraco)qg%V^FWn8+r9OJrr8Ic&+(kk@e=3w4i54m4)SMwE!d?C!Ppq1 z%#2yY6gaq-iZhmcjriPWo0X@0H+bf4RyL0YzdPP|^!v>=oOLJ5I5H?Pnau7^#Ymir zYq~Ow>9TOHNwT>sT@g$vxpzejxBiIL1*tw@7Pc`VB=QVz=_MuObkLnH*rHw{kYS+4 z2(R-~r*o&HG~dXzntMtw2AYd4^{;{N;)-Pu+4bPsXHkZGxxHN)gT40eUk^q^c1%Sv zPWxTFb8Su$r?KEbq{Krg| zRXfl|KH{B1Jca#R7Wmct%dt2kN$Ho(FPr0%rgKr&&6m?nFiwRZk$gzsy zv|G@8^du2{5|HVGD$*fof_u;$&a5_RVS%E>i35ft!nYtyv$`AVrCUYwsW2a0M0^-z z0=%_bxNhN8PIXJy?W0*0GX$Xx&&73Ucbk7VYeN*p*@oH6xQ@e=-p>TNemUeHcZ_g1 z>7BuF=%UA>%O(=zD0tm#t0mcO=*L~NB8DJp$%R_{H(ClO4z<-B`^!PU;h91OMZ-~i zh3XaEC=%q1Xn>FQh-d1{e;Q=o8t$YkBb~A}6Cj7AbU)%Zn9vRJyWg^6+sAZwm}cKf5*wV2%d39!-aZjWHk~!J269xB z$YUfcN@?V|tZIaI@xj1~vRNlxi5k+reLWt_^L%XT9%P-Z>t|b?E{w4AjxMBwB6X%E zwUs8qMr~i$70>{`cldoyWb-XCp&K-!vJ#_KHS7B0XD_z52F?1;PQO`yviD-=$pF9f z^86`Y@Y~;gG8dCpkq1nnfGV_t1Csr3KHVa|wK+K07ELch0_@KZ9`Egul~hKapp8!4 zrQ^;y&8gn*lSj=a3B-4w!4L4J?G6RosM=#Ey5 zA|)uNx;=}E5DfIP{E>9>pXx`Usz z_pv!%YF|Fe#&grUlm7O$Ndz|O7VEjV5G1qA5uv)+yhsm%@m7mX5mdO8DE@%h6b)`%5Ru1e{H1be z8iB3X&aR_CIIyw$r|g#-I%&hDSjj7|#5%=euoRWw+}pnuJ>!`*?e>C)x<6sqk2 zFEXWXuU1mHRychFUj6y4-0909P0kr^Me55JSz)CQ6iy}PXrhA5Ij9XR7jCkZ+1S5AoB!%wFMIJ!p955!aoBpD@rHl(~ zJJoopz5h$?{a!BVGKb&lvMBR45Gl~@WgNe7r4k4%4YkHhedIcm==vICepP{$DoqIp;aoOJ5} z089r{G8OORkGssrA$hH*?+DC?yFE?XZR^bXCDzg5=9@8chtu?e9@hfa$6!%54`;A) zs3GdGP~()o4qJ$Ei~{kPJ|}rW`k%#KV+1U+mWXQ2azr(0BC0jConhbmqS>#sNn>^F z3)71OZV*we5DF07FMzCygLM{mkUW@prBGtO1ubfzMGds5ZFR03&#+{;F3Z|NkdeF( zUj*_{W*&l)Q?XDitJAy8GjCeWGjCQ#to4EfHYy=VO=+r#A~XE@xyoDAS1Tgq3VEL` z(UW%VNE~S=P#@%D94$7?ju-x{R`)&F5VPqsInWxCrnlN8bA^n;0cmBN8z1c35~hW_ zIe6CAqoVWpiKbclT&SVZ!*83`eJAa!!QL~@?n-^aNPWUceZoi=U#6v|ZcZB2VEv$5 zCIbAX-zjO&BResMg=_J*%iP&@Arz}CFIIPE>uwB@Se=XmEGepKqE^VRAY@lw$iC#c zEtI!nnpk2uIcfs84qcF3(G-UmbV^k&9LsN=;IMG=+kqnfw?#f2!x3L&Y?CCyi@>Cl z=ax$o#flrbENCxk#|9o74cq%rmzjq!;`R7=$o7ej#R}sckb7DGO3dtNPcSdl%0UB| zN{mI7+D2ewCwUbv#D$nqb}5#Zu1urlA*O|G^od{8PGU;90g8&s)^4~yJv9A~*1#1` z1=_38p07oXIpcZfffDmAtD#y1P_5bkX#r4ZXjVod8&9}p3{h0EN`zivzfl5`LjqzH zEYFSI75$F!ZrC4^>`vJS_sqD4j*KtvBntWs<;3bR-A>E2A~?5MUbJ>312L0>!EzAp z(W)TaXLkhQHZizy-isTfMmh)6N57{=-E?jANS7S;WXbnf6kfg>`vY_40&j8Z#E&i* zkxGrDF!7ov7zO>lhZ4&&c3&-HCkr^YE*@Ln&!%vY<0AWt(K0K9@~)!F`H2?xiPA=y za`(+o_6gg|p)Mu!1EnfTRTEC-2c#C1TGZ?$N9p#FaXe&X`R}`~XfU zqkmulC{h2;%{T&D68On>kB*$TqG@LPHCq*l%bt0C5yl$IT(~ z6$Rf&utoFEG>?c%nc8qn)S$aO3paxHg{wBZ&HxwKLLR7a8e&Lihmb3C}&Q z6MB0TC!7xPny}emG$FA^WI|qxz`_f0zOFX??+*GubopcZw?}{b;W&LXNPoCZd{Uy5 zlH2`slQ#M$((7ADwl*H&=h4yMjvo!aJo>VkKH5BQHA=&k3-e{(v4$9w#FK@Wlj6IZ zy{xdhY?8-Y39Abb%6V1{R;QsUcI6mgBzCK#ZRnHf`+6zZPXB!x>Z9^)&mXAmXw?1c zjwQ-is-yzw9Bl3TyR$l?q$tL2V_nME z*j!N6`d25_VQk;_c(%)5Ga7=Ne>;^lY)LLy6~Ypps-m32)iL7p{zd8Fx4E++!D)U~ zR->#Dvj!IKZXj}*31T_=lf6BXX~#~{(mO?GJDQX3(&9_#jt+wBl27k#Q%>fxw&n|_ z>7I7Ic(OOx#WktvH~Rk5rJtvR=X;!lYmiRUbqflL$+5*= z$TSTQ`(1;}*t$xgeW4~zsa_Ehhd2rj<2NCy8w_q{ADa{rS74EfvDfLKq1XOL{N-4( zayZF>2;weri<3zlii)I9^El_ zcK;X?;OnqQ_UCz<-<-;yi@dsVCN&c0?^3q7j9_~iGq`Y#iN1d5q5{wIaW~1Ya@8d1 z09oAdOQaxrpw&1cDjPiDoYIrt8O>4)n}4z7uXu8{R8#{`kk4)HyC*Y@zClcUVo|?mMd; z7s+egT9U2+*opIzbUo5h<%dGo0n??;bEEO>nD1Q3EFMWW74>qG;-m=DT^Q>q_JTyM z4aX&AN3JyE7E_UKdMsE8A!Vi(A%cDOit-NKu1ZqjU~MPykxq6CQzu;Xy?vUUa`1wh zn)BK&U%TVnZa7^uZ3_ug?{5>y04L{PN~an=Rg;h8{&uvz|Sq_ zXN{~rho?x;rm>O0Oti!P(x5d@i_Z${vpdAg5J}&Z!&EGwyBv?zv{p6UY&RS*nXGJm02 zB3Fr_xDZk_RL;h0lf$nl_G+ACQle~|>*B7>MPi#yQn!s3OI1P*65atHatH;Aq;KBC z{qFa`r{$AJD2@6+8Da>QYZG2*1fgpDn=SOXZ^>UB%*wII{1w^g^Rcn^GeM|q?&T{n zKZ9jVu^&}eX+Oq0Kej=AC!To%iU!7#7rMqB)9eW|pU#vg)EVZ*4^0QCmlJ!>k<2>8 zsMPu?ajQ|^OWl4Ax#6}*q`05gq<_R(52Cj&w4F4QuXU6fw*E4tos4I12oD!YqRS9( z2ql^Oip!Wp@yg|Yltb7=0f6mA-=QdUki&*{QAlQA-Hl@UbA0A*-}!;C;|Kl(G~a5p z70*C{U**qnP9!lsUb_xv)biz&CvN2Of!>eHCqEa`evywrDWkpcZpB^*zY2PG_b@0= zj4+IDR3iZwubuf3VwaAO4ay@t0%mo}VvP82omowTQvQxqC;Yjr7)W6L7QlpJMAsLF z6in<5PYgM3iP-s}9bcU|Gpey2aN8dprZFEZuJGqQ{s0NX<$vuj%7+pHR&x{gU)x!X zCv_!_y%!8C9~=;OzX0$~NH!6RzK#kwu9)kdXFv|64Y3$qS3fU>b;gjHn5Tk+)QZX} zIppXK48QD`2pg8n#>sj1Np_1R8_(7lxVaG#=r~g)4V~n6Z#CoO&5OQid(1vQ8Gf#Y z<_1$%>KuzEre)nXxW`v!`!=T|4i|Mxgvy@OZr z;Hx8L2d~m7DDp3STl6shfP|HyEnOE@gwjoZG2{GE4#)fjcD)an_$w0H_f^WlNJ3$+ zS^Y4O_fL_4;sZ06`6Q;>KQ8K5Ps`EGs(@#1#5ISdTpBQ%^&_T;pKvhsS?GS%sNY7s z>$YRSfvq3Fz%%0)slRy_{TgmU=f1B}<=9$5MQmVG$DvA&$!SkI+6dBH9k2w#41(o1 zj_t=Ji$R?+2>Z!TW<((z*7Wy@T$W=tTn@>s%d0!GwQC@+Vk(r=#MT~IzeKASZR!1Z z8&ShkI&MCy^NXhISY+r_@a^fBW0lvvWMkG%(#4|mD3UZhPX5~wzK1PPEH@!8{f%9z zbcs~P5T_nm!OGSp#a`Gfn-My9U*EUAI=P!m9OAMRgWN_75J}Kk*Zh2c*QR9v4Sg2Ml%#r8LBA zTyR9=;syJL{ue>4utGi(X13wM@fvqKLzM{p&j)a;2 zqy?=4IY+Ri{><3p%~|;rd0m`2k8_{mHo9~K!^?plBzP>5_z`nufb{| z@=g9?7^w?$KAc*_H3>#&!S)7W5ArdmNmtlrFWDXjW%wRuBoq~@7b6-cxugJL_Y>!) z;V17-BD-xa@I^LRHIUJ=cBc|H4N&2G;?5@nUsmMH@Of-V2=E(p9K#f&GdgX)FG@c$Lq1P=ZK zFSyT|R@~9dt+j@3t3$S|Tf_kJJ^IKQ_5Fm?Q!mg@;Hsg7w(38-#quIy=yVW-OyPf; z12Nvz(dlOK)A!kgERPm)JVT_O*3@d|jDSAniyU ztH%$a5$ONt7u>GyUnohjah2534!YoHMv^uP^f{1Q#S9KE@%StOt^)jph{W(%t82!r z5#LDs$o{fCvKaS;a&D4eiX{B{HIV`tW#w7vLV4{Q7dCn_^lSK{3g}mHG&~ma?m%F} z10Cd@N@;H#+y#D-CZ(4pUjo@pX(N$EB7y&Sz;$pR>te55h51EyNG~+GQ~IwSg4Jjz zm#S6`qyy!wfgZO>qVFg*%?hR!El2bOZTq^?)V1G*1$Md5X*KDf=~Id1B z#APD#R5y2&^!{5?e$N}<(eQ>emTyTfH>;Z^l%MJ3`Eeq8y<&~swe)~IHsJM`CgFjj zmezyE;oXRF^Q{*^p_ZXgdnl;hGE8N62`qIhSZW4~jKQ+6Vo-F`?0}}PeVL;Pt9Zi7 zPWU&O>=q42JF$~&Lf0Bc$c+7H*~FhfVZjvJMrH8l;T;lVqA#L%okJza=2)~-^Czhs zoFPj#`YSU>S1H>O)m)NsdT@ASiSF;r5iZYB)u2f67=-Uz1f9-fPR>ivlrAgQcVHLk zwz(&Bemst|IBNW$?()znn?=h)wy$oovN3BhTw05N)ntpmvYDUCvH1*)v)z*RiIcqr zS+=$&gID1dQnkzWubi#wH)T0RmU*)f<#fEWnF{UIQyGxo;(p*gGZ!w$njU`(`&k2=IMJ3OPd3Ndi z%2~|7xh#I=EZkIF23|Os*gTg?&q*qvG5jifYA|SMY75)P~lUx)ec7I{+mo%BAfi4F$(#0AN6$zu^-5oH!~QmxTBY z|Cq_TQ9-!@m&+l4a*5dir_x0UE?FM%Hi23)&hwuai^S; zwqbE0SC?Ox`a^Pi{c%ZbYCe8Xn9)s$qZivQ?d7{4kw}cT*dc(b=1SGl6imdfOZrbv z`&%L&yEI!j5qkjLOh*kxN|tS|5j>t?vyO8PD2ntKn}irob^T9>OsLZ+ky4-0EXT9@ zt@0ox2qo=?w9i+}Rhzn(X!#F`fPoSU;PsJtg;E*sn?4)=T(^%NMZI#X{MGJ$)lKw6 zLMg+%mPo)a&=E;6@ZvOjKq0G+N1}a3`Uqe2K9?2J?K9Giya&nV(KJ0Oby`VdV|tFc zFO5=;c}(~<6^*J2spb*=P(7s3k8hBhu#5?^?K5wx6Lp3}b%qA`oW(moncnIvWkA4B zD5~w-kfa|>!KTtfq8}8YV;67qV}Mp`5aS(GMn3vja%PgDq)3DUM|GXlBO(GET=6Mx`b;jh~Q)!x1U?HElK( zV+(#w(phen6%RI16}qY7jxF*Olk*mZDC^%=)d4fa<@xD5$jk{iAk@U~_tayTNYvz~ zhu58pGvX6=`$>LUH$?86&MAi+?VR2;vV&`HhdDWp`q{zv2s^we?u+nxUv$pKW!`ko z%cktm01rfGOA4+*zsmr{?F3H|9M3`@on2jvK|4D)2JZ>u*n-7nX9{^j~~kN(l`aBKa`_2>!xdqxju z^l(NGv#tNZ@qE}o6v99dt;mweP>w&L{}S$Y6y9jD5_u==jKjEYq~gZ=w+uH@vE#rn za`4I7aT*ESczKG1h4C5=jXD#CM$1o@#AqFt>^!wOUVQR}k&Sv9$uXOfd8&sIO@2x4;OT~Z6&vbhx|@<3hRhYGtj@VH!Wm!1Zsh!3 zUQHFDh>5}Y95WVdMiw47>weWv0yW@@W{6D;N#qr95@R$BY~H(9J7&z3j;S^d@>4FoJImK<6DxSZ*N96 zUPf}vj65+IW#N%+8VT7Qlbnvt$i~Z9j+qe?gYgw?Miw4WhBSU zD1k@TD_b?v@iBUmBaA#b8)J10#+R@d`S8f?M*83D$&})lvB>I1x||6!Rvb7n@W@q- z3|vN@jAW!>!-0Vx9#cNYj0KO}Zlq$DXB+vEOdm!P!!Qg*TcR>ujuQJX!2&Shc|LLZ zcHNp6G?sc-oB)df?Fz zlWs(=PN(9)W{lRUQ|*m=*X~ZIg3G668O@4DU2)+ys(m-A{dCGG$!JzIs-;cn#_)hs z5skXyJgX%{@0$i=1avLmgwq&z(#r^c4&yRx)5}N+W-WzL6^+pqebdVr23^Z4@C>@2 zo;mm!&=u3^giEJr&(9cNy09twfkQDWbj4h7DfaiA#+a$YtY{U^@m$t$TBX3Ms0(^w zOrw_uT$96X&uxa-xxjiDHDH^JaiAN+9o~;|H@%EVw9)=NW*E+j=T$^%)D;J2Ewxcs zaA{iFpdVdSb8sFEH^!>8D>l7wXP$PYUBUer;}qHz3tlaE!^n)Nv@70{Z6q2HZ!A18 zB+GQri6Nyz8+Dxy%$0WPbaE~q-HL#T(*|osVle~EvHjgyrmdk^LPxH6C;1HC`zNQ z*syB(I$er@Q%g*`6*txeal~EO04yr;CAqM|_4QWwSGWj&{*&K4p z&;A-?h20@C?OlwQ`4G@VCN4(GSVcNckz?x=S@smh{V;pX$Tt5(HeN<~wtgbrwuBj* z$g|@U$#!kLa(2Ov1DD9Lr`ww_V-w*kKzt(E=8acQN!W4V5;?Yhwlz8Z!)nJTlI_}f zk)ajO-BDX9+OD1If*c8!fboOY*&$UG9G(FWd1o~ zi5&Zd$h1E@Q-~~^LxfS9$g?Lzew>C~WZ7Cpu5H2S8y{m#J41xALga8yhDfowFbboF z$h2)SdbT4(lKp)m$F2~W_BO`L9Gpc??zV);v^7K+Cqxn!#vORh-`a5ta4s(B0V|Je>wfx8*+H_NBW5{=0qOuDMY4i&-Nm6?7aBw3*-qN z2^%h(vPich@UyGP+0~v9nf3;Q|2QK=rcF)c*wPs_+Yus+l^Hwi36W`UwJ$^_Z|*54 zH(N4pJhq0&w0(&jy8@F)!HxqjKD$4Am&miPV&e&%MSi&P*cT#`7wrA>Mu`XixH5g$SedFSj3Pl`|!ze^TU9c>Auyc zP90xk7~Glv^_S>>e7yble`@?{&Ic$sDhfZD@&Qzg|OcV6b3zheM znhy3*MJ7=W$fklUW1^&dhlh9JmE*jy{WQa)C*j!Oa;PCMn?!Diun#|nZ{+%a)uvRw=`hcALJveZ_5n%kzaGSA zug#)y{aW$K|9QQ7Nj%6r>y@p+a!}8qDn!NBqQaO51rZ|YJwmIm=+YPd`uB&w*L7By zOuZa)i;Hp&58RNHIoh5XgmR6ALPduCcGaL|^|H;mQQ~d~>#57pb_KSbL}KG$xg0!e zR_t-A@Sv7W!l$7qbQ5i~oU@UWxr7Rj9pWHPnoVO|>oSnK9PqG_B%Kf@dD;?_6O4^<>%0kT|lENO8BgXZRPeHi( zTud^95%!Hbo5=fx-#*@ce*g3R+pj;~zy0v<4so8x{fE6TVQ=K-(fliN&0%rP&gY(c zq*RnU>1R8WJd+e!5x?LMva#ZC_dM*9;C5U>9L=lwbKK7m?ZLxTQBnX1Qi{IHl z52wLrUGK(atCy9rU;9EY!V|}NkP97^ptFhoS%%`5K~5pj!hZ;gj>|v(&i>pz2#ZQ4 zAK!LaP{sb(`LA95ZAYOrzy5U%OMLrLNbEL!OrcM@THt!_c1k3I7aPVi2|4~q&PE>r zEW*Gl|KFq~cm#~NZq^Q_+}?)v?q*%P{pRwrbzN)%0E$D2H2)dF3v(;aMJq7!j|Sg$ zUyyO^;3wJ7$LGy8Iq!rFoFYCMm|_2WSKlXah_ipT5psQ2F>Y05H|uA?f6#eI-1z2|X{5;zQU%Aa!`e+j8pqE0nMX!XH~_&dzhj2v-X03bSNzV&40raMfeo_m$B_) z3Ll2LwZq=~HteKWxrjVR4sN#f&T(gb-4}OT0@{rEfu?*usu3Q1pLGUaPP5qlsP%JM z`O_3vj8Mfkmy`gICOB7s3k*B})ms5lHhibQ(atxUwh4TXn+k*WyXZ6Iib>z18Z;}v z)S`ISi3@i80KI&h%j@151Wh|a?xXd~Q4{){>^xP+6)KjfO|f=FiQO*w^eJs?GRzz( zZ{Ww$xi$4AKxOz-;>lAq47P-7zi?|85L1vqXi{;p1(V2cFr{J3(64hFU3&u19l?g6 z6NEk_SeiGu|Em)kqq402&h*f1?a$3EEsvhRQFsSVzu4SzOdx6paPMx5fqYBfr)J-@ z|Cu>Uau5lIgHU-sCs@gkGP~Tiq6}L~#*>h6r_TB+ERkwJ01b2ybfBi0l+8gNki zNUL0Oa$24Foqsx^Fq)T}yY;Fv^ER|$siZ&B0;t>+2)+Wdwdeo4U556D!2yaeoF>y0 zrtZ7V?Q{3v97zB;HoxiW?^2Jk&$|Q%o-p8de|XRQCq{v%go+aw1AhKZH(sHG479B0=i@wBOr2p=XD86RtGm`sxHlCcsRZPAN67CH_1(AZ zQebE62jG^S7Kt%MMC@1q0m35zc~DV-(E3mvw_O01piKY{NHwDihbxk0B*r1t%H3g* zvqDWM50;T-NrRLW>rzL@+`X?3X+Wyn?LK3Gab+qc*G)LS=}BDd z22fg+&Q2r1eY$lN;g3jpIEUUvan8_!2%T-UZpOLd3?OT_u_6cEr@y#iO;6~-=V zz_|6V)9iS(+EHpO9aCaoB$y32+C+!FIdDa{1!nY_mx$Up4 z6LuwJFAd+p3CDpZ*h4xiSB@_kcXXdcpWC$4|3LytfVh6P?r}iA2@q}B-h$}jne>T} zUUob2{eAJ#h%tzawhE0W5aa~e=%<$e8<%kTpb-VXH&Ja~E56t&jOMsnalU*Td|h}t zz9aNV?W~e30JELKl`x#DR^2p3?J*vaY2|AII8uZH`pVt>!%cf9bEdNWtWJM-hrPiGXu7N+A&E&ws8sa3T7^*v=Ft%Prg{%ONM`#CjI(~Pao+EnCjmQO<=Tc|Pyom8! zee1lV`uf5NOlN4~KqXOS7JZ3_Dz1Yxi&?M%c91hBLwFC25%?!`d0f+#b4xfHZb4y+ zv_s8*ccW8N%{R{FYc;beL*m_7-`qJjyh*2eDW`fKLj|Of0%R&}e-9w3U!h}l+}g!> z?RY}18utGl7Ep*aQl~+HFA$6bEf2^Pd~7KK%G3pjz-G6*;ffrjg=`H{-B>Ebe&W?0 zFxdp+aoN>lA^jHxS^L7wF031${?H{vW!i6gBEu#e?hyb+OG6sCRCbob) z>mYwj^%b->c8l+FEp3gxz$VEj@=X{D_4Di7Rx*>q2#kpGp0W#oP#B=G=zIrIMd3bG zul=;q@f$cpX(FP2%3Xw}!hIt|N4}=Tx9r^UQ|N4!knJ!l0%cyCxFUKAO@9nle2~bC z^=!@6(MekdlBH9R<)ig%JfG7wL7Q3H1ZF%UF`$rbElvxnk|AVb9P=%Sr|aZ~e9{LN zq38_T4;rpuGv2TR%0+g!j#w9VnQZ(tY)Ir^AobOV)Yo-3Zk6^l1|olmYd}z!_Kr*b zbk|(dErlnjwVl1TOS=*CB&xpy#bP)EB5zueLSDNCea72D1nb{0(`)S}^2D{>FrQMQ zqHOGTQ9UO@inTnexFbmt)_@?3wy?!&wrfdmYc~6POaoss6n0`ui(#11?+yebPC~>*n$&II5WoATe+t%Y{)A#{Y-v>k}v1-20 z77fi*i2O3zXGtiX?l8TE6N7_kMEM55RUU7>s0N!ug`Djg+JN&;o&FBfPj3Tp%G;<{I+I#FIhifT0|6CaWvNPD)HFoRn?KvRzo+GnMWq+Q{+eSfE_GU|hR%LFN9 zAOYPf8mn?aM7E<0mFfUu`;*abxVgJ}frdXM|wbxEa^mg%(X~Y7+4zjCC3=3WJ8EJ~`Q1 zT;-ym2Mjl3JB5ekE5ht?vdBP6xJO|~{f%r}OSRcXJ|51+S3D)gr^T>*m!p05ylIno zWcI+c``vCE4*h#*0_8XYq?^3gD)+D^uoQefpo^RuD+jq94RVvPt-v>uNmbW{U0S;4 z>O26QJI|UOsXE8K=szO?a-q5~FAzkovlmI!xuvp(E)Y~sIq^nv?tp4H(0=~F_UM)` z!`|=^Y;DSo0irj(Z`$vc9)xGbfJ^EU=L{$!&!NbFz~J*E!nU=pB}lprjU%NbO2-g! zkzuz+Px3SyLPrd_eHsBtJ0mXFqvH;TI#~#`{&p)>bujGDN2WY z9FKGFxgJZdAc#PQ^2?U~PgjYNjjg!&iSD@PVr?Oe>6GqQ$eD1eBYUp!G1icwLclwY zn+~B5rdi#hs2A|^g8$}zogz}l1AZh`*@I3V~o{a9I2P8T=-ZM6CQvX zG<&!6mw{=jMl~3K{sur(XqB-Uvk$nDDJ5R&+D>h)zwImA?IW&i{LC)c(Pn(3x*RRO z)tClB-U){UDX6c^{HnJq^dq~=M5SEyW9&BX#`d5t@K(9`T^_#qtwuLLdo^JDFQ!xF zk!fi!j1lkJSAtjKil)6r+gJ9bA*Jb+x3OeZ0=J+t(`hc?N=F4N^HoPdPijHXhkeN-U zv_jv>;$}${jmjydep_)&TT*w%oVbmsTKJd^?2SU*2E#D65u=7D$U{K7jC0#gVhG*J zSoKb=w1!5Gj=yWPMf8>LQ;fttf9MG_u1@GuG##xL^`CT}yv-Bci=v5Jyn))x%)aWh zLHc#3zjzJ$6Fy-yLG3*#V{BWL+D2#IC@8{W>hwvJXW_@o)x@OT}r;YGO12+T5fZf;({jB z=K^3|X*WT_S(&DASH`F?=PIGAO; z1Cc3&z7fhctyjGrD_xAPqQMpYoOZjNBb~^h%ayS{mwbW>-;7E10XV2AeBtzp)O;rKvQ<2O z2gxnpW!<7;zv}*WP|f<^`oSi;tD2qIO;|(IcDHLxreK8+Nv;>g1R;|#U4Oo~#pt5d zUr)plBPM-TyqRr`WlQAVj8`u5(lV5TfJEW6afsS2%&=)yU^q$N!Z()AAMVFL`ehfH zoAQPW=H|CVMIv7AHbG~~ggAK$-(vKit6iMW zf?q{nkR#9IjHa-h5UP-YUztXg=#rANl#SE^p1It4ABL-?59hJoOt_KC%!=jOyqx=O zdC_?}d9!w0LI1v2wMkcK?nt`<*@V)?$jIT2CsJ=a%MDTQ+t4F;N!+!)o`dt@vHIXj zKW>FB5|fMX*YFFSh798^;1-zg!Y(GB!6j#z?d{+G?Z)%e$oHe7JWmxGnxoq^Gh_|F zZI>Q0=SES(f)|Q)Eku#S>;&HxlL&BW%mHd$_0V?zV zwrk-5{*V<1l)dq)E#%#lKClQY6QfOt(LFTw7Gpng#%5mZNmW*OwD-mA1IpygPyXb* z>~wB*ZNF`Mrj@McUdcPUkkibU2YZy_QhoCI*auIaw!V6WLXD)$`WRCcL6N0)jltJU zpwbjwBaw<%={sJM`UK{SwL5z6owN#dF{2=F_Xf)jt0;5LpjE_f52d;9@bR6`eP?0$ zs4sxLb1H{&>b2562d82KTuaO`*j*T(f$A!r7=odmCp(F^4N>SR3#5Gy%Cr8@;}`2t zMVJK4k(oC>Q|oVG>sm+XfOg0Wmhc8GYbBp~?chsqf_xgm3r;61RF*0x`}km+^^-Pq zjm02G0@AhbUYoGmbxJL()1n4Qcu5Tvbbrvwc`M;>ypbU8)w@%v*W6L=}ro9lBn4PbED=q9DKZ6%sI$ z_3Kc7CT*l|R}i2_X{q>3T8iQo+PAZ2ox?`DFpcj6n$|lSk8{NT-q3iSJ6W15eXnqf_Pju0#Zmy<#Isf?8_CG0@*sHQ@RQd8?mIN1hHga#uJ zPa~b_o&8G!%FtUWO-}#%zS*DtrF`nX?Wn_yI4A(6G zU|4b4m@;YpLhn(s*Yx^?YW{-L4tIrP1aV=BzjnT{s+I?lfIcHejoZQ4pl{KJe-b0P zS!NQ3JlTi*0%#Abty6v&w2$glxiuDk7jP0T!Zcv+@H=z3?aIWHT?J)&U={RDu_zF# z@Lp$%vz`)@Nb?JSx~v?X%AJ!QFoB1eS@J#C!zS5F5{vr27)VwSscCOYY6^^tsrdc6 z)I8R;OX+*)VA^-QV*fCLg!rN3?WS&+yW}x}%;FqD_f4xa#+N&*X8un=OID_uM@NKj zU#+|4Zw#^J%$yOo8pfxy&3j%PsaxA{)2olVi0szvEq6(9fEsD^F@cziz0Or41CFD~ zkud>>XVLDH5yBqG_4^UIe&30^z$5W9Is>!x5)ek|)abJ3d&sMAc50-68zUt>rLhs^ zkd$Rk?bvxt^{ARb)S`P9oyGB0Vcx#qK-_AhxYc<4i8*WbPN2?|11H9b!E&zbG!@#xS35r<#cGwLDtkwwCWCoLrTkclPfEZaT*TZ>BgtVkSb=Q+`+i`F-?|EIbx-J<=y z(X)=ci_tYwUa+L+uJQ(zWN4XPCKoDyi)wLw3Y4Sk6D}d5@2z!mD$>iwBP@@l?Krwt zzFz3|;&NsT`XkIl51D+G`*e6}RD%FTB-94hcZ>DqiX4Cm7ekWelp|EX2;dmaTvkfH zR&YovmCM}&jwfm4usJn!F9DT2f|(!bAaH)jfF2|kozXR}LHkos1CRsdVqG?#cKR*c zG<<6gLh*d?b3Z~=P&TZ_<|~*@&sFjVLu+Sj-yio*ZL8%=K!;Nf8}yM6`v(TpVL$<^ z6&~N}lo#z)kz0001BGg9faR68y1GqwJ7IO>eo4Rzc-u7-1(HsO4%6C&^b4h?% zPE?y^!#qkHhT8EEuy=3z1e=4y8s4c}R6RKfTU>|;l{w>D&Z-Q0!V;p?^|ZCewL|QM zIrfCI2UpQ6s^tZjCm^-3m04@**}wDkPf4*zhjZ#s`Kj}Tx9*4KmMt8({oO9)JyG*M zcfS#WN}B({4*w<6o|G(H%xhY%{B>e^O~)hI=Q@Ilq&7(JV*BpGgl47obcS!Go*fqU z+#_amG@+I86L}MA1j^$>7oSWyj2p|N6vVhy*fzgc6q~}KcCevb^)6e{W%5xO2=TTR zq)6lir3fUDte7t4YpupPKqaaKf9%voksjd^J}!q#U5LFQ>Zg8ty09BL1??2a#|4(u`n*Y+}Z|GvqM|k}#r;ydTw;i|F%yQ|^i>u~(^#dof-|q9_ znqEO@ld;ZRQ$!bI;NHGjmb(fbug31jk%JJ5f4 zx1C@j;0I`d&aBF$IJ$Le;YCN17phbS_xNft60RCt=*JPe{;`uGA9583-lq8hf4A%Z z@K;469Bmoef6k?nD=_t|V}FQn=_SFQtKhxRn!R?JK4>47#zv_{)|hToCqIsg5#JuZ z=<0jY=FY0?&E~e++rJ(X_##m4iAGKP+;y5-0)q!w?4e6gbxjU%$%9-p77&py@BqNN zHZ2B*bwj4JE(WTwZ5=cDwYuDX!nY}gPWjiTbxjwzr+@eN{$DhHPM?<3mK~e9Nq6>? zRRGkgR$*r-``nzJb#QXaUt>ECzcG3QZq3m09^>EJ9|so~aQQc)_P@Z@<(<+Sd}CVl zb3rNV3|);dBo+0|S$Fm?K9~Qmc-)4&a5fh-vA%>cfqZhW>H3`%;L(mDtEJYAm;96t z|8;;CAwJmDVGSF*POyuDxEw)E=%J%o-zhq_k169P{5jzYTf4@ybAl|fazEX9*Qsq@ z&8PjBq=vNIMk%q;^ImS0>ObEoH7mFqhrMO~Nzs=ows}cQhcG#GNF4#xK^2@Q6*QNM zlJim@8E4G%bNo8J3@??u%(o$3FB6_z6&MgoE|l25Qu1$K>A3?-$4U$<7KNL-VHyIv zve#48NH5TqPWE(;nxwT~y)2-t@*gQ#?;n}wDFuA0nqOD>!g3Dz*r*}T_1VpBSD=%l zn1czSnw#)jiw9GVR7l9^t_)Geb)HTr*vBa~NI!0tuh^q{d3)>p?Pl2p)oHi6om`Xj zQ5hKz?eW#4W@?2^Ay1R|juQ^Ac3K%i=&b8F_{7>jjFt!{u%0>1wo%iLLrI=nj7wn( zB29Vs3($Hj)8zvQG3#jVlliSI@lckzm?dLD{tR4Xi`UjBa{lpX%Xa3n)1Iajk zrCT;Iyz9De&>!V&UNxk!X7PRi`*yu00Xdnm09x05VtfTb|Gk|sr$s$K)tvQEx5)T@ z-ID!_pOK46b*4(k?V<`(IZRRYO!1Rq}d9Mswa`*^(5ypZT*(eZw;gv(*M%c3S%tfK8gUVXe6BdvvJ)0m*{R83aV=mr8Q zw8Oz=ZkqLS{otBfwt(2ku~MEZ$IV|KIBxiuh}N0paiTfp&y8|;P*3vH zqnFk3%ApmSLq?XSS4^%?=p_*Y?T3&XeHj^EMf!Tn2%15kbCN7Im7 zS3fd(!N2oeqc?nVYvZQEqAJAm=>gZ2Yp)muk5$*=N-Ue~VS;Kpf~Ju~y4)q#HcG2& z8ybY;xaDi1(j;?~XM}$qy-AY6Hq3&kTQt;1Zf<@2a*$Dl{UxoqsL0>GI!X}qn~Bs2 znL{3ZAsB#bw}spKc+dD*D4IWtCUohsM{p>c4C?G5lOXzfY_F0mAV|8h-=VsA1p&0E zR!dsKwCPf#UCOk)_Lc@)c{GOP>sMwmZXZVvdm1A_+f=*dxPMg>{b&^wi%D5MYaHZ(Rw({G~P7)-`0=zY>4jL*F~X2D9C3}&5`-wQkuhP@n(EEJs##l57U$nMD# zTx3(_kt5|1br|#rr~L^WM|)M!_`8Tp#ON~(I8wF`?t|U4vy^StSXt97*0evogwBnf zR^h=R-O+W;Wq>k=U0=%MCyMX6NTXi)auCML<%DPYZpWV@#K!@9Le2?)`ZZ&SUh_Jf ztda&bh5!{}t1WXZW^JKkZBFX>OKocFZo`G`Gq z3!q8S4|N@n4}C2x!8x}$*gZ#|+0v1&9OQvKC0$x+jz|GhJ26h&^>8{V$}z-h&_zGJ zuDcKsP1Xjf=J@(hq9p9RowLystVGCXdJN`V*R-fY?nL)Y3126A08OdKCZjYXFb)6T zg($5Qw$uZz6AHetftZcA^SK@sEK!`I=4Y#E<14fy3;RXGi&eLkcVY@xBB`dDG61-UVF5t!J%^j-*I|(EkQ;Tnyn*JIHJ_o>}G$gCF9N=~|w9RN} z%WP;D3Y&BbRp^^(_+iRQ&meV50atAIKNErtJ%w@3Xrn7vYvg>kqAXc*h{r~LWM%wg zw%BVA%VLM{k2CGHfhku3Ai`?E76HL2iEk||6zJB`P$V)Lh`J1!$^|GWwi=~m$l;lb z;-RYdu-M)M{OrUX4@JwyhZ1+TFowesPNv`pr7i<@lo5BU-iCxh(URUm@M3&S&qvl7 zPB?chlLZhDh5%zZ8zwXP?TZBvXmp1YZCfAc`AIT)BT}{?W8yYL>1Ycvm=5OU zS4KZOGfm8lleAM)%(5aPxs4zO#i;AD2^a#(k*GE{LQu{Fx~2D>%k9RmObe%m`f+f? zk|IYcj%W}cU0(~W{9MWa@$uB$N12C<(v0_CD?5Irgp`8%bnAy{Tk8f8=BT$NyqWS( zd2g%Lkca8LgM_>mQLOV`2DV@9hT0ZZ->9L!4Yi28k}Fe(OGj}Ad!bXltzbON2)~Jo zHtH~pQ97h(dJB5oT9jsJ^teJ$1}jC*jksT%Su9q_-mHix5@hflKL*wFXe;nUQ`{haSv^H%mOcQf(Pv~8VsPj%Vs*k!YTNPoQvZi9jv`|ff$+p`q!`(n z@$#Zlyq+Ae@4y43$9*U*VZz))Fky~i!g8xNG~FMtk?+9szT707?+-Ny!9;J9Ta(`R zXl`+!Tu`iu_iXUt@dCtIOO6H&+qbUXapj|d-PnE+|CY>W&rypQ}xuG5~BQhw= z-HxT_;zwfprH^Q)@IAGNJ!BB5^QPQalQ>`t{GLZE09w<&7wR;(D~?!k&`{|yaD%6 zm`jnPv?U78^msq99b-{8re$<*kD_}Ex@+vF1CY#rC_pk4e+*zUo1fjf?f|<@o0p=Z z@NWdo{gx)xC%2qTa@n?7IfQ~pqR^bI0rK)+{zrB1!qqnJG!B22;?wi2^@~Uew6ryK z^Y%h_yW5s7w0kM##}g6(-Uf%Y9Vkov-QO9FG?HwG(C2o}zh{@&@<7tK~0^;0wQ0 zeX}!Zn6j;w?Eg{qiSh@SpGLy#l6*Vb^S=!wY|3-u1SJm?MXmbwjbE{3+*Dd|_te2x zc(e6_LeH<5cUYN4G8GJ3OEW|yLOnx2do>yUmt1WVTLsDstiTW5o!Uqf^vwG<`qf?o zjxF-;3>li{8Wyfr>~SN&c*SAA(nKE&Ps)rV-FyCaSVxbs&zk85f^Z&S)zcLISPw82 zKkIFL1&y)>VWNT6F8bX1UTTpV0I)rOTX$&30pu$5^FhSh5%@ zKfIAhTG?RpNdXbG)=*3Cny?t|mN2~;U1N}TQPI)@-Id~2{pcFh?f?@6r%D5+_9@*S zHbi+?%XSqdWV`0d@JTJ1>u%_muuPs0{J{-iL&vf_{JQF1t7UM_?c%DtYKEdoTrVz~ zwt$xLS!#!E=Ef$5Sa2`s<4SLQlya+$kivGGsREytv^&ekpj|F*aV>qrV*`$@ec#tv z9-pHKVflnFPIMvrcyg6KGJ60anq23JUFv-^L$RdppaRMO|61r}UGGA->nVVlj9 zcEcHbF(N3#7ZQ`!_@OCST;C`&Lm8Pi-@RFl2}ZLvzTrdN%{V0Vm+>^TYROf-=&j^$ zXLn2^-@fs!E(5Q0B9BI8vmjmXm-D26F;;_f~0_ehr*?dxxlZFDg*$p-*P z_B$>HC(k{-oTW+279h5MhOX}z8jSiZ|3JdOD>X(6{7MRq5Y2FbsikJ{q2;XI4l>9Y z;klic0hs2zI<%^;gjSs>dUY-9v_<$WsAV+IC%9{;Ceex|_TJUm(QFEx_j9#R&;6_- zCOv51ACCnYHS-#)NEm`A21YFw7IHGnRYI0qR_P>NQ=@A5C$L3MT6MR{iGoh)ae!oT zWNKL#I@M)%B@S0iMqHO)vUB|&3x70moF{x(JcLTWH~mXPNU5MQp05Db`)*HM=ma+Mem z*~}x%0k6OUh4sc2RoTL&yO-J_$Sk>BpFK$*JXnAH0D20pjefXs|NgK_;_Ath!J6pZ zTt;soRv&C`4mKV=dZe+!Zq{lTnjlnObt2^p2ZBSkY4xlZJS+^*##dGS>s}-om2_R3 zuU2)iw$^ze1X*3ja2_xq@rW)4AsjDX?5!{0MR9%T2R}2;T@>&nuF}I+^fR1~ z46;vb`55`FeQ6EfRg)TcKUiA5m}2d83KrN7kp`_Qg;dgwH`y_ixC;?ADz8&t^n`?<{JBM?|FB{1Ky+D=?WMEdW0Lr>Xg+E%yYRuCH*0WSyYh16J!duo;G_=nfcHPagr_JQ>_KGIA46 z{_GeNjZv0xhrr5X=pOiI%G+}Es%vBse?DsL%OKPP%Uuh!NT9oF_wF5%@1l>k?TBX-MF^6uPKE#%t9&Ss^_}4-L>)KT(0E4?(n**aQFnT-Zh#Q5& zmg^#EebOk(K@;;cVDLj7+HHpGzqY7f-UwNy1DU1wNrN%#*aUv5*rol2cLM9oN=uCr z$})xE|MC_rA*3dVT1XH?vq6$fwpjc;J6DIJv;Pti*jU`rF@yE{mNe7Z2_BZ(*-hNb zvv)7C$Cfk!AQqN-lvS5msjyUj!BShjJsuURYdwHoLo0wRf5wR}w|_#)cLe zn`^vXQ+0FNF)y*;WGX^hA*M)2~vQSe!$&aS8Y|S<5ZxGbu z>3?VJEMhbDH*D=@)z$K@<6b77WzJAH2KM#m;q|V`mA0Tnv)|2hr!h>B=L>b5eKjoK zS{?_KX(-G0H~mnpp?VVwqb;r(m?eq;nf7g_!FOcZHJKhfzFj7?kK20gFVDh`0VdDm z+u_C+x7lnP-<8caYOwwt`P3WE_24^lF##Vf&&1)IOrFhKq6eXzO5`F-jm_ld`}And zaI2zu$H8{$qvWa;cUJ21cN=6A#V-Z#Gw%SR70HLg4BTwi*kLXS~aY{hq1AU(G;6cEwA-s>0WA?y6U4F5L~RO5rt$ zXDR$Q1I*8-s1@G({CWQQI^JJfeLPw{ezyARpeH`p_fBNYe1&Y3+Z9?|roA{?`x=49 zES`e6z7PLHuUZ6qd2d5TIA7d3pJjQ45jQc~=FtrHsL++hi0$!MZcY`mh9#HayvS63^sF zQkM!jPEX=o7D9ARi-jIp^4f%uKA*b}LUm!K8|0K${gP%{VBSW@%-O{f$c0>MkK zZTVv~Oq|lC#R<9j7|Mff_`%x16?}gKp5uJ^wuxROQ$7zF;*ln40Cov!5a<6L4xuSQ z&bsacYHe|r!y=_~jnmnvif1B$K11rvc%#@wM;qSUrld&k?LT^aaF1q-nHcJlks>n* zG)cVIM+hB$UdY*n<7_0*`&rhpeM(D!jph6-t{1OXIt&^{LU=Q7PyBUiLAbOHYP83j!XD>bp+D7NTQ|*{?RBDGzh$2~X^S)a#^95oe}?1Mwd4Tuvr7Nxxw$g< z8#ca`PV{(_^p%ZG^1LAVw0sk{q4YqHIka%j4Pw3+#M;4Nvam;oan-wNO6cTME?uG* zJ+))GxzcwWM!W8p+H74yorxiAB-NN1JVx*Q@ur7oxjLm#U4vclH*uiabrIo4l@gq(;V%%KX zg-u&q=d@!?`)>^)Zs)?0v0y03aKs21MZW)vqE)FvKfjKiDkl4ibBZz?xF%Nzq6rRIts(!nV-btRnxXHyw==Hb zrhq9$u{hz9L{LtIG33at{?IzU>kX` z@nASe*4dc&cpVp)M%;BYVNF&ytH8XfHe&~d`O0!Zw4BAPnFDpl%%-Y%=QIM5};z+Dc^0 zo~rDjKF?^*C*MkEP>!4Z)*ZAYoNBg1V&VukC6gUVr8p%XbZBU(m(^QnY0p&pp^~{u zOWbWQ@OSV?n8n3R>2nsD(x4;N<%~U3M60x-UkM3lx2fbb;>WB>%*(7&J04xuubRdwxgkI5vNp3AeYXmx@5sy`WBx2ph7(A?0S&mMW zK;qPL9##)k8-oQ`jDlBjXnZ+U2p88u{LgixZJUo(+7)_6PP)>eBKUL$pKgDv zsJtR@f;&4vyVM0r^QGuhF6e_J)i<;54oTVcL`lluFIDy4G7Z>GjyxVRcl{v` zeO2j^k{6o#4~4wc4;!{0wu!$l02O)Iqz2zHmVgMg(dYf=5?}P)HTZx*>F^hsPAPgS zm4SJGgsOC4UnWn83OUFw0uw9qpCmm*} zpOyO8eY!&jMEYuE)&nwX)yNBI`V{p{u%!-xfF(d^9vGb#`URZuoD?_|rTNIMvY-4G zy^j4hiLJ$mA(N-c7Unazm&80Kt;e{#^s z*bL0&HUSOuX0r0)V1;!ccP-9kMp&4~54`CxvV+5g$Skel?Jp-g%vgJ-?wBx+&}-Lv zpgAXWj`s5gV{qu0CaLO3G^@|EHgGeMfzL+Z_-gF5%73HJ#T+{HOg)=sBP_*#r4it| z#6{I&dC?pr@`E{bFC*-($c`dl`&;DR>XI3K5}8|#(7Vcp(^bGllt9rDelr-Dsy}K^ z`|m^D^eduY<0yMUo%u}3cQ`{lcxW+w)9U5j8+&qgBmg_t{hqXz{(K`N=!nV_R1%~#>t6mt;Z$J_Vi~k&1C3B35s2! zj1sE<+P4}+v^$b3T|4luBMd!j4|vL5b*u_hTJ?>o&8QBUpo%By0Ai#k@j0ZaQ46;_Hs$-K5lonuEZZdK1OYSA?Kp*;;!ufK2fI@88BY)#t5HChb97FAu{KAZb* z$5~MV@6Gcssd5LO_tdBupQ?%dV8UZuk+}$KJ_pf&#vJb>p1*dVELH$f<1+5D$SM_Z z?V;^%>AxyBwEaq9mWR%CHJM30>uUxqkp<8k;HYoc)0yri(hv$X8ElDyGDYZblNR*d zWaLkTRD*M+YNF1nNCQ{5VO;iuGL%TXUQj*vLKSk!ycy&Q{r1hZA6`vk*(sx|?;L(l z6>>K3@aO<--arpkQrAXZO01B#R9X%LjC6?yiHDRChzE7;2RQldZ?U&*B zwSsc0M(|S8ZzwblPr-MT2a?ns!gk<8uyo*-50b=C=nF4fmXv!onkXOvMr2`J zJ^E?rSE#RaEM3A^0&rHS)PGsDCb@C-L4@>I9`V8sSd+gHqggdr&j4+tdr?2bXqDaC ztxjl#B{frCM1lVipGH&duvo+cYg;Y*fZt%5rKK0WRp#mMafS*&#=AVafEgzYZ{mqz zgu)<7BFqCn(Ux~(YV(fNSue$FQYjFnUf1+sPeDN&i(#|{xn(4_ezMCnfG#U~xl2E# zkU5a^BfaH@gnWy@|11@|xJ8z!GKFmYY4QA(9=dw}GLCu%cO{rxY=FU@$@zoa-;e$k z$sc-MW#q9qI1pQr)H6S^n(&*>;rIV@B0ki%x2vbZ_QniUI#MGWEuHx- z<@s!e3$1_RLgv`-fIMZ!Wof5WQaS99^$&9!S-B5-zo_%Hkc?tO@G2C%#vb#LmfX*k z{2PsB8=DsWf0|n;?6i3)VOo5 zQHM$@3HHVj-I|Y|xn(s?o7#dm2ihKGC-d37v=YZu_m0qz5njV&a>7=&Z9kgiz#{jf za(lxo@ht7iY;p*}Yt}+zFp^_=>ZHLmy=h}l^`Vo3-8?6L@?q{a_w=UfDE+GXc2jRE zu$qC}S{;jdSPNv}&$-a8$)39@HNdsaWw`R`Pm* zx&jS`{tuZjG>ZGg$ZJqGR9n_UcfN47UAOh=9-^b!4A$zo3y3%y&XT1J3I!DuEQbgB?;eZ4_K3N- z={2;YpoI)rDw<@e>$|P(;(r!x7vF8IX(eY)?<$~U+`LeR?d;s3xEA>dw1{k&O3(S1Os&-BpH47R25SzcMe~@`MCF! z#FzKac0as+_Qp%u`}5rk@AcKkH*fsc*Y94N$LDW$Ui<>ZPhIf@@#e$!?)FO!^V7#y zuiid;cewNJ&7V49_szB`=MMw&a{JY@k8eI8;hufi{_#&Jah_6e%2>#A_jv3cC+_jg zJzlxT6Zd%J9>2QB3-@@*k7nlEX7kFZxido7snDIRX7Bs*z%IS_=Lcz(!nnV#>HQqu z`(v~U?t%FD_RVkZi=RHe`$bm$D$n-B0*13de~16V*c zmxpk0?*@sfx=>TBpPsntH`~8$V}xi*<_dLkcU`D{@o8S2i>lO*rnWP6_J%7oFI*=| z6t32Mr=;)k$w$ZCRm4aB>9e1tmc{w^(u@RW&^U*=NMo(Yu*3ACJfxXIPmgC`WkkFBI-63kzE7ztKI2h=O`^&sr zGcI?7{*L#u&=syM=~qmKkmJm~ujKA?hqBzcJXQG}qpaZeye@JAtmYNdC)ltwUDW)X zR93t7aR+o*@}BYU@N7wuP=1(l_2xd>gl{EB2tgXYN_a(}!hXZ(1!-&ghoUK%E~2p!Ky?YBD`O-B}!sSdWx{rfUJN8B>St;=X$9Y4YV4YUX4K!`TTC*;j*jyogG z*ll2znnAs4#h}rgKomskclI2ynH=)p(5T2J+KDKDC6ybskgENya52R7ljsrlz^0URtb{Xo;-# z#T@a9B?tQwKtPCC$kVze{r8ad-|eQ4h*5n(aR)K~1||(*Gws|a)9ZI(rZ2b2^y8=3 z?>Wcbt#W*P=jZwBJKD4R?03%h?AA>R^S!uDK8vF2!)^nfX-f~K>c7tEc?X_<{3kn4 zzu?0>$HzU%u)Cwn^e+dFug~E1qlSCYwc57tC>qK4jfN5OyYkg5G)kCb3OeA-D4WuB zsrsjCG_lXT)!(>rhjk9Hvu=a?vEZjT_FZo6<&2^h?y6QcPMYFjl%cs6v85m>O#mGt z1>J^Car}M1bnLBaZoG|ROwGbZ&SE9$l>{fQ>U2YKs-YIsXTk1Jy`C%3ED8yd3)Cf1 z8Wu20CBaj;{*ah3fELr^YpFUPn-+ zoIsMn6zSkR03^Q{x_4&nglX+9q1+f~(A%Q`qs0Xi<3P7L_-YSJCCx2QN0aX zWgvsCAbmnKPE;6k+15u_({ppV4m^`x>0M*nEUhol+Q0&5TOz^}7x)z1z8J~WsRw?%{K(~U-< zCi8I<1zoAkyjFK9Ujv}M;$zV(4BTxa*wq!`=}L8WUR~)qnNC#ZvpeQ8)H@n;G-fnL zwa{$OYkqAdrA zD66ZTM7fDAs+m62)jd7wPq9~Se`>!lFFR zmqnZA1qi?=l^zOw$N;kh-xYqB_PdoK1<}YY{5xnvJ@fwxiTq?)1PsE&c&c!SAhC!s zn#6iq;dg1j-;!9xO&shL2T#XE26l{V`ILlEX1SJr%ovjNlV;B6oYyBUb(lO#%6Rj! z@O?d?Q^KxvE4Ko?`LaUUt@QxZtU((qXZ9V#A!i9=T@}z%p_I}8S5}jIsyvIt(0qB> z*XCnwlLnA|2XY`1BuKEHW@}||xS7HP_siLtisR0!!jCgxgV7o42*1`sw3gIb{d`sl zq>{;WXeQO|N;bn9@I}n7oRKZ3N~ZwAr-|O%i`6_=wKNkJF$0&U8JHS@%X-=VIv6JL zcLOb=`)d+RkSzl%s6ZoP#IhG9+NZJwqZme+!!H=ANbDD@12C0Gk&Ny{7z|hGkdnRV z-#Q$wGh~W9?R{0r$S)jp9)=2HRt!IUm8j6byH0$QBLw;{g8eD%PHY zm9`D)twaxY5)M&Q_+PO1R_NAy5p^pHh*!~W&C1FoE~P?a^B)yJef#zc{&+>7QPEzj zPcWqw2E-eMNJk=(%lyVU|dDGRn9}y{ zmgneK+5-=x^atNBaqEZP$PKy~1xltZ7Ck$jrrcU~HasOEcq*~IFg|=@9<^Mx_-HJIv@sO9Tag=R zx0$!1#hf|8T!ITah5h`gid!V7XeEK@{^}%zc7Clac{ofIq>?{u)yE&-n-9VLSMn}3 zcPIn7;Sv6Nym`?aKs-9)q|c?Y*}V<}?nF zboAcF=s?Bi@KBX+jWgyoM~)%AcQ4K2bs_(PpEV($!OuX*7w~gm$anDbK*%=;vTnu0 zu0HxlPQ1E=*Ma?nfOv9xLtdi9NzL$XYN(Q33>zmuKoy%pzQ+Y~{6WZ9T;?LCz}QWIH#ij4Z^7Jot>st}^+EAl)z6VM4($_lG(W)y_>@Fv(1*2< zpUAC{14TUVic(OfZN+JLjm4C8Qp>P$=bZLSX&KEcl!1%2<`7pcVa*c2(CX%A#FC zK5UDwO6H`>%2{g2UXXZy#S?`)KsL58v*B98M-WV`nbDK+mdN&J`=bNxScE)F$k?47 zp32gK5{zI^!)u(=QhIl^tJ-+;n`625MC>Q4sD8pj50Hw#WJZl}>*dhIw+be~qfx1> zP9Z!_Fel}nYrY8;;$@nNN=tyMh-lAI^iUi`#?7^W3J*nfyF;RLx)>frf_K8{bzJ&b znQb-|G=lk{CZ7gO#612&CkqxjMVk4mnxq3Vf>|#}rVP=6j4+S(=uSBinN!FW1&(k7 zg!s38d{mC~e{Qcl=!^w)im(OejCnJ!sXI_|ZLMId{_^ux6jmMiY|$rThcZz>0Vwe}RYb|-D7;;-N`JP;LjQmTqJISn zUTJbK67EiKjAwt(AC&MlSsh4KrA7QFo_fi09b|2K&tQb3_HI9ez0D%N+aH_5vO<;> zOV_gM8{kxdF8BvqJpo8#6C^)br)wy%Ty7G~%TEyUDOZOKfsa_Mf>-vbx@+j!MhKkr zvUG*9!7>N|*n3?a;MO8!3RItEhuqju;l}PiIP@?AwM+UPlUf1oZKuh&UnUT3nmuo zMK+WV?f03^U)uaKvocFag%@CYRoAsVtx!_%p}c98c4~lf&L04koy**Qc&TXhH!I}% z0uVZ*bj)8v0ciA}NyTnOaKh!3|(;EaX?6G7$0tA242|=G6xrFS1H6w5ncZQ+ZgW z+q&sLWfPd7^l4kUgNbzS=Aj8E3c@zK7**=9)TcJ&7X-o6ud@PDC(X}$l{=iUQ^~)) z*DsZPR;3+FibE3jFTzn1>c*F5-8+o;sv(*fceLFqiSaqo7{4Wi$>^q&QFbS-Z?G<) zA^;&^=fr_>t0Md$wfRiG)8xe!!*cx4YT9-P$566e=@cw>@~m>I3YCHZ21G4)vF1lY zzSbB3LLc-4$6h>W6h9|8A1kMZRPk;S!5O$sT;h>;QGsK?^*e2WTR( z>`CS-Tndu=`Qw_@uiy1q`+4iIA&tTxt8^~!YDU`-@~3L)nsuH}v;2!)vckaWvg*q} zwJ3rT|L7b=1Gn7y)394De_3An*%z35meu_$$V>V2O}8js*qYW9O9iQs9oJ54BN$#Lp7RH@jp?U2|VjQP*1(rurjnZ9)w_f`jD*g z2^qH+MVZRFqfF%(9$Xfkp~tJ9-K(kPOyPjTv$goJfjT5UJRAsliVqK9~dRmjkgP>+j^+vPUrVa5GlNQT*8~kv2YCb21YrcK+O-WT?d&USCYZ^J1IINO}KC-7I4x3{LPQc1Yr)nZ`0y1eeH|UvT zfEPjAe&Dw0#R~RPxgYh>%zE&H*b1=t0(ozT#mZWM2GQzWlUBT}Esd z$Ji)6(G<==wHiw;i{y-qxlIfIXxJzs83p?trJTvk+w;iW+;8j3@Ho_%2z46n!;JBW ze;G`?bB;G6&-rmHf+}%XOwoEdJm=69Nd&mtbRZ*q@dINBN&Eps#!x5tY&Lx0w0S(| zVx+gjdXB~L7r_@nu-$%wPrT)OmVQy#j;r(>e&v}gF+{+zimxy}0J^{&M!gdj>KlUC z;;X!nm+A5Tl{O*iQFS@|n&utmqKSl}rXsn3uVZ+SE5QotQV1?V1g+=B82Bqq^RHn% zo1txb!cCT!CVtLW+SfdhieyZCsB>wySCcZ_NIl{@ zvb4Qy$`x_ymF3U8ctWhuTMRagWKlTIn z7xL?phN_atCJztI3Kk!&`0LC$O|#(pctk{Pq36{Q?Q zK04`%d)o8=_>WnCbUDhMe~iNJ3N2Io-$O^%-;64Eij~A^Gas0F!XB7>K&%&4&4G{Y9$! zhh`+pS^7-%?RElD9`8eah2KUnzG)j#j??!zj?EWbquK+#1FOZiB?f+8>smO?0NI7r zrZXX%m8D}@);`%Q?T%+L9WV62p8vZ_MaeAuJb()7W|0z1?vWs-y)HU9(Fv^9Ux~d^2q&o?fgDKy> z>E{sO3$1KdD8hkGI%O3~HAqtlYid#ZFK90fEFfG1xk3gmLM;Py%Z-MYPEbACa6~=T zsNtXI4#AV#`Odk`dWC_KZU8&BrKQSuC(N-_BxuGy;`|9rC#G z-Bq#t!KysHL&?&(meY)4umEMO!|<*6Iv+G}Bhg_wAZk`u;7yJKvqBCF1+m53x+63; z;klO=sBcYxo+Ienj#Lo*>;cKj`YEdAf*xeEYUfI+bS&cWX~SIvSaXMGa7yx~s}>%DnV5(K!y2_$?lef5Za^*>yl0x8xd-n7UUYLgc*ij(dvPUfl zEj&Wzp~0ogexC_Js1z19N95SHLaV483XUrbwOkp`62X#+eUlsEkVl=KA|vz^i98=e z<8m6$pj~MNf7l%@@FU3d63sRoZT|9=ww?mnUn=ct`HJtJd5iH0ygKA>Zhz)Cg)T5Y zzq|uGwh}b}Sr+xbjw}2s0SJjeU^r@gnAb43VHbu_v_R};2`y9UCeB4Y<86rwE?Fw% zGAzm5g!)OPzbP19*r?$rY#SN_;2m+q1pK8G9)F*>p%`bI1BiZNly7yMX;k9X5RteQ z@R8oKycyW+upAdk{iEV*7ymF>lZ_CX$w2zyu99`>M~_N2qz!?X+?OVVX7WH{kWwtm zi%E(FxfrBa4#gcsf3GmgXtIhQDXJ*FV=ZsD`LnL+<171$)p3weO4^jzCO?>*#^(9< z9t4Mb4@e+3^y z>JaNaw=gv45lrDCQI6c>*tNv&iJ&!wugW$F93yN^M}i~F-{^VI>HP*qLs+zfuZU7z z`d?`ij9T3t7tsetHNg=v@*~OusbGTT7fPOBGCgRw*LO-mh!=yV=&Ww6@4w+1p$=1~ zS>H0bEuopj-1Y99vCj`az!@&T(x;{@4&NrcV15XpAIe`7qc@T)*d~L#6hwjI!Z0bAT8e? zST;L7h@lNF_H|)1L`bgv*#Xi9^EEA$$~2C*C99zctr=q%be5i)7y;Nb?gc~*qq>^X zbJ)eIi>iht3+Nj^Lov!Q!eS5_v+LBC9s-rLy>_cn(vGc(?9&V>TM8$B*P4QM5HKrc zCMv_`8^@mIoXoE!Y-&ecWFV?fk?N+_A(xr72~$&1p^(O^F?Q{|R6Ys=E!PdIK@R+0 z(-3P+1wEe71_=l9^sr{9KV%fn+$~F)CAh?HwlY})>QL|~B@6I!fyjXcBn6!hlY_MVF_h93{~2G|*^1hW$b_fFw!FqOZk)u{d+f|U_Op>U zN?5YdKoxwX1RFv1uo4t2o>Udm%&3ve>kyJUFO9Q-C(%@$qQ!cE zcLukDH?0eI8e$zzLok4UC_>-!=||l2^%qA^-^r%*#szjCX`9}p>xIa?yp<(FU0~%= z=ju(b)||y~-*{YQ72QyNz^0sk!ARl;`*9(+Diaw~TxALZ8doN~)U8k>ee!TZOS)TH fR>sBEc{RHwFdBmp^gvjv&({AB+lYGsJ!Jv__-+Sz literal 0 HcmV?d00001 diff --git a/priv/testrunner/esm/package.json b/priv/testrunner/esm/package.json new file mode 100644 index 00000000..fa5bb5c5 --- /dev/null +++ b/priv/testrunner/esm/package.json @@ -0,0 +1,20 @@ +{ + "name": "@std/esm", + "version": "0.8.3", + "description": "Enable ES modules in Node today!", + "keywords": "commonjs, ecmascript, export, import, modules, node, require", + "repository": "standard-things/esm", + "license": "MIT", + "author": "John-David Dalton ", + "main": "index.js", + "engines": { + "node": ">=4" + }, + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "files": [ + "index.js", + "esm.js.gz" + ] +} diff --git a/priv/testrunner/testRunner.js b/priv/testrunner/testRunner.js new file mode 100644 index 00000000..30c7d814 --- /dev/null +++ b/priv/testrunner/testRunner.js @@ -0,0 +1,51 @@ +async function start(files) { + const results = { + tests: 0, + success: 0, + failed: 0, + }; + + for (const file of files) { + const mod = await import(file); + if (mod.default.__elixir_script_test_module__) { + runTests(mod, results); + } + } + + return results; +} + +function runTests(mod, results) { + const context = []; + + for (const key of Object.keys(mod.default)) { + if (key.startsWith('__test_')) { + results.tests++; + const test = mod.default[key](context); + try { + test.get(Symbol.for('test'))(context); + results.success++; + } catch (e) { + handleError(e); + results.failed++; + } + } + } +} + +function handleError(e) { + if (e.__reason) { + if (e.__reason instanceof Map && e.__reason.get(Symbol.for('message'))) { + console.error(e.__reason.get(Symbol.for('message'))); + console.error(e.__reason.get(Symbol.for('expr')).toString()); + console.error(e.__reason.get(Symbol.for('left')).toString()); + console.error(e.__reason.get(Symbol.for('right')).toString()); + } + } else { + console.error(e.message); + } +} + +export default { + start, +}; From d2c8b27dad614f575503674dbc9892ecefe6327d Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Tue, 24 Oct 2017 21:29:52 -0500 Subject: [PATCH 347/418] Testrunner index files --- .gitignore | 1 - priv/testrunner/esm/index.js | 49 ++++++++++++++++++++++++++++++++++++ priv/testrunner/index.js | 13 ++++++++++ 3 files changed, 62 insertions(+), 1 deletion(-) create mode 100644 priv/testrunner/esm/index.js create mode 100644 priv/testrunner/index.js diff --git a/.gitignore b/.gitignore index cb91ffe0..77a9c54a 100644 --- a/.gitignore +++ b/.gitignore @@ -10,7 +10,6 @@ deploy.sh .DS_Store sample/dest fprof.trace -index.js /doc /bench/snapshots .tern-port diff --git a/priv/testrunner/esm/index.js b/priv/testrunner/esm/index.js new file mode 100644 index 00000000..7f6018cd --- /dev/null +++ b/priv/testrunner/esm/index.js @@ -0,0 +1,49 @@ +/* eslint strict: off, node/no-unsupported-features: ["error", { version: 4 }] */ +"use strict" + +const fs = require("fs") +const path = require("path") +const util = require("util") +const vm = require("vm") +const zlib = require("zlib") + +const esmPath = path.resolve(__dirname, "esm.js.gz") +const inspectKey = util.inspect.custom || "inspect" + +const descriptor = Object.create(null) +descriptor.value = () => "@std/esm enabled" + +const mod = new module.constructor(module.id) +mod.filename = __filename +mod.parent = module.parent + +const scriptOptions = Object.create(null) +scriptOptions.filename = __filename + +const content = + "(function(require,module,__filename){" + + zlib.gunzipSync(fs.readFileSync(esmPath)).toString() + + "\n})" + +const compiled = vm.runInThisContext(content, scriptOptions) + +function makeLoaderFunction() { + compiled(require, mod, __filename) + return mod.exports +} + +const loader = makeLoaderFunction() + +module.exports = (mod, options) => { + const type = typeof options + + if (options === true || + type === "function" || + (type === "object" && options !== null)) { + return makeLoaderFunction()(mod, options) + } + + return loader(mod, options) +} + +Object.freeze(Object.defineProperty(module.exports, inspectKey, descriptor)) diff --git a/priv/testrunner/index.js b/priv/testrunner/index.js new file mode 100644 index 00000000..96eaf89a --- /dev/null +++ b/priv/testrunner/index.js @@ -0,0 +1,13 @@ +require = require('./esm/index.js')(module, { cjs: true, esm: 'js' }); +const runner = require('./testRunner.js').default; + +const testFiles = process.argv.slice(2); +runner.start(testFiles).then((results) => { + console.log(`${results.tests} tests, ${results.success} succeeded, ${results.failed} failed`); + + if (results.failed > 0) { + process.exit(1); + } else { + process.exit(0); + } +}); From fe1dda9b631f7e9219f73c22deed48c0d50fad27 Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Wed, 25 Oct 2017 20:23:12 -0500 Subject: [PATCH 348/418] Testing using elixirscript.test --- Makefile | 1 + lib/elixir_script_test/test.ex | 15 ++++-- lib/mix/tasks/elixirscript.test.ex | 7 ++- priv/testrunner/index.js | 3 +- priv/testrunner/testRunner.js | 31 ++++++++++--- test/integration/integration_test.exs | 47 ------------------- test/support/helpers.ex | 41 ---------------- test/support/integration.ex | 42 ----------------- test/support/term_converter.ex | 57 ----------------------- test_elixir_script/integration_test.exs | 62 +++++++++++++++++++++++++ test_elixir_script/test_test.exs | 7 --- 11 files changed, 108 insertions(+), 205 deletions(-) delete mode 100644 test/integration/integration_test.exs delete mode 100644 test/support/helpers.ex delete mode 100644 test/support/integration.ex delete mode 100644 test/support/term_converter.ex create mode 100644 test_elixir_script/integration_test.exs delete mode 100644 test_elixir_script/test_test.exs diff --git a/Makefile b/Makefile index daf796b9..d717c5c5 100644 --- a/Makefile +++ b/Makefile @@ -17,6 +17,7 @@ js_test: elixir_test: mix test --cover + mix elixirscript.test clean: rm -rf priv/build diff --git a/lib/elixir_script_test/test.ex b/lib/elixir_script_test/test.ex index cc5da921..c3618700 100644 --- a/lib/elixir_script_test/test.ex +++ b/lib/elixir_script_test/test.ex @@ -26,7 +26,11 @@ defmodule ElixirScript.Test do context = Macro.escape(context) contents = Macro.escape(contents, unquote: true) - name = String.to_atom("__test_#{String.replace(message, " ", "_")}") + name = message + |> String.replace(" ", "_") + |> String.replace(~r/[^A-Za-z0-9]/, "") + + name = String.to_atom("__test_#{name}") quote bind_quoted: [context: context, contents: contents, message: message, name: name] do def unquote(name)(unquote(context)) do @@ -54,11 +58,16 @@ defmodule ElixirScript.Test do test_script_path = Path.join([:code.priv_dir(:elixir_script), "testrunner", "index.js"]) - {out, _a} = System.cmd "node", [test_script_path] ++ js_files, into: IO.stream(:stdio, :line) + {_, exit_status} = System.cmd "node", [test_script_path] ++ js_files, into: IO.stream(:stdio, :line) # Delete directory at the end File.rm_rf!(output) - :ok + case exit_status do + 0 -> + :ok + _ -> + :error + end end end diff --git a/lib/mix/tasks/elixirscript.test.ex b/lib/mix/tasks/elixirscript.test.ex index 3d282b23..23321491 100644 --- a/lib/mix/tasks/elixirscript.test.ex +++ b/lib/mix/tasks/elixirscript.test.ex @@ -11,7 +11,12 @@ defmodule Mix.Tasks.Elixirscript.Test do Mix.Task.run "app.start" path = Path.join([default_test_path(), "**", "*_test.exs"]) - ElixirScript.Test.start(path) + case ElixirScript.Test.start(path) do + :error -> + System.at_exit(fn _ -> exit({:shutdown, 1}) end) + :ok -> + :ok + end end defp default_test_path do diff --git a/priv/testrunner/index.js b/priv/testrunner/index.js index 96eaf89a..2c8f8c2b 100644 --- a/priv/testrunner/index.js +++ b/priv/testrunner/index.js @@ -3,7 +3,8 @@ const runner = require('./testRunner.js').default; const testFiles = process.argv.slice(2); runner.start(testFiles).then((results) => { - console.log(`${results.tests} tests, ${results.success} succeeded, ${results.failed} failed`); + process.stdout.write('\n\n'); + process.stdout.write(`${results.tests} tests, ${results.success} succeeded, ${results.failed} failed\n`); if (results.failed > 0) { process.exit(1); diff --git a/priv/testrunner/testRunner.js b/priv/testrunner/testRunner.js index 30c7d814..2aae1ad3 100644 --- a/priv/testrunner/testRunner.js +++ b/priv/testrunner/testRunner.js @@ -25,27 +25,46 @@ function runTests(mod, results) { try { test.get(Symbol.for('test'))(context); results.success++; + process.stdout.write('.'); } catch (e) { - handleError(e); results.failed++; + handleError(e, test, results, mod); } } } } -function handleError(e) { +function handleError(e, test, results, mod) { if (e.__reason) { if (e.__reason instanceof Map && e.__reason.get(Symbol.for('message'))) { - console.error(e.__reason.get(Symbol.for('message'))); - console.error(e.__reason.get(Symbol.for('expr')).toString()); - console.error(e.__reason.get(Symbol.for('left')).toString()); - console.error(e.__reason.get(Symbol.for('right')).toString()); + const errorMessage = e.__reason.get(Symbol.for('message')); + const expr = e.__reason.get(Symbol.for('expr')); + const left = e.__reason.get(Symbol.for('left')); + const right = e.__reason.get(Symbol.for('right')); + const moduleName = Symbol.keyFor(mod.default.__MODULE__).replace('Elixir.', ''); + let testMessage = test.get(Symbol.for('message')); + testMessage = `${results.failed}) ${testMessage} (${moduleName})`; + + printErrorLine(testMessage); + printErrorLine(errorMessage); + printErrorLine(left, 'left'); + printErrorLine(right, 'right'); } } else { console.error(e.message); } } +function printErrorLine(value, label = null) { + if (value !== Symbol.for('ex_unit_no_meaningful_value')) { + if (label) { + console.error(`${label}: ${value}`); + } else { + console.error(`${value}`); + } + } +} + export default { start, }; diff --git a/test/integration/integration_test.exs b/test/integration/integration_test.exs deleted file mode 100644 index beb4e8f4..00000000 --- a/test/integration/integration_test.exs +++ /dev/null @@ -1,47 +0,0 @@ -defmodule ElixirScript.Integration.Test do - use ExUnit.Case - import Helpers - - test "Atom.to_string" do - val = call_compiled_function Atom, :to_string, [:atom] - assert val == "atom" - end - - test "String interpolation with number" do - val = call_compiled_function Integration, :test_string_interpolation, [] - assert val == "5" - end - - test "shorthand failure" do - val = call_compiled_function Integration, :shorthand_failure, [] - assert val == [ - [:option, %{value: "test@hotmail.com"}, "test@hotmail.com"], - [:option, %{value: "test2@hotmail.com"}, "test2@hotmail.com"] - ] - end - - test "map equals" do - val = call_compiled_function Integration, :map_equals, [] - assert val == true - end - - test "multi-remote call" do - val = call_compiled_function Integration, :multi_field_call, [] - assert val == "5,000,000" - end - - test "filter names in guards" do - val = call_compiled_function Integration, :filter_names_in_guards, [] - assert val == true - end - - test "tuple_get" do - val = call_compiled_function Integration, :tuple_get, [] - assert val == 5 - end - - test "multi_bind" do - val = call_compiled_function Integration, :multi_bind, [] - assert val == [1, 2, 3, 4, 5] - end -end diff --git a/test/support/helpers.ex b/test/support/helpers.ex deleted file mode 100644 index 813b6cf9..00000000 --- a/test/support/helpers.ex +++ /dev/null @@ -1,41 +0,0 @@ -defmodule Helpers do - @moduledoc false - - def call_compiled_function(module, func, args \\ []) when is_list(args) do - File.mkdir "tmp" - ElixirScript.Compiler.compile(module, [output: "tmp"]) - - args_to_js = args - |> Enum.map(&ElixirScript.TermConverter.encode/1) - |> Enum.join(",") - - main = """ - import ElixirScript from './ElixirScript.Core.js'; - import mod from './Elixir.#{inspect module}.js'; - const ret = mod.#{func}(#{args_to_js}) - - const jsonRet = JSON.stringify(ret, (name, value) => { - if(typeof value === 'symbol') { - value = `@@@${Symbol.keyFor(value)}` - } - - if(value instanceof Map) { - value = {__type__: "map", values: Array.from(value.entries())} - } - - return value - }) - - process.stdout.write(jsonRet) - """ - - main_path = Path.join("tmp", "Elixir.#{inspect module}.main.mjs") - File.write!(main_path, main) - - {out, _a} = System.cmd "node", ["-r", "@std/esm", main_path] - - out - |> Poison.decode! - |> ElixirScript.TermConverter.decode - end -end diff --git a/test/support/integration.ex b/test/support/integration.ex deleted file mode 100644 index 9f1b73bf..00000000 --- a/test/support/integration.ex +++ /dev/null @@ -1,42 +0,0 @@ -defmodule Integration do - @moduledoc false - - def test_string_interpolation do - "#{5}" - end - - def shorthand_failure do - orders = [%{email: "test@hotmail.com"},%{email: "test2@hotmail.com"}] - Enum.reduce(orders, [], - &(&2 ++ [ [:option, %{value: &1.email}, &1.email] ])) - end - - def map_equals do - map1 = %{test: "map"} - map2 = %{test: "map"} - map1 == map2 - end - - def multi_field_call do - map = %{token_count: 5000000} - map.token_count.toLocaleString() - end - - def filter_names_in_guards do - has? = 5 - - case 5 do - _ when has? == 5 -> - true - end - end - - def multi_bind do - [a | _] = b = [1, 2, 3, 4, 5] - end - - def tuple_get do - map = %{{1} => 5} - Map.get(map, {1}) - end -end diff --git a/test/support/term_converter.ex b/test/support/term_converter.ex deleted file mode 100644 index 0aa6ad1f..00000000 --- a/test/support/term_converter.ex +++ /dev/null @@ -1,57 +0,0 @@ -defmodule ElixirScript.TermConverter do - - def encode(nil), do: "null" - def encode(term) when is_boolean(term) or is_number(term), do: to_string(term) - def encode(term) when is_binary(term), do: "'#{term}'" - def encode(term) when is_atom(term), do: "Symbol.for('#{to_string(term)}')" - def encode(term) when is_list(term) do - terms = term - |> Enum.map(fn(x) -> encode(x) end) - |> Enum.join(",") - - "[#{terms}]" - end - - def encode(term) when is_map(term) do - terms = term - |> Enum.map(fn({key, term}) -> - key = encode(key) - term = encode(term) - - "[#{key}, #{term}]" - end) - |> Enum.join(",") - - "[#{terms}]" - end - - def encode(term) when is_tuple(term) do - terms = term - |> Tuple.to_list - |> Enum.map(fn(x) -> encode(x) end) - |> Enum.join(",") - - "new ElixirScript.Core.Tuple(#{terms})" - end - - def decode("@@@" <> term) do - String.to_atom(term) - end - - def decode(term) when is_binary(term) or is_boolean(term) or is_number(term) or is_nil(term) do - term - end - - def decode(term) when is_list(term) do - Enum.map(term, &decode/1) - end - - def decode(%{"length" => _, "terms" => terms}) do - List.to_tuple(terms) - end - - def decode(%{"__type__" => "map", "values" => values}) do - Enum.map(values, fn [key, term] -> {decode(key), decode(term)} end) - |> Enum.into(%{}) - end -end diff --git a/test_elixir_script/integration_test.exs b/test_elixir_script/integration_test.exs new file mode 100644 index 00000000..504bf310 --- /dev/null +++ b/test_elixir_script/integration_test.exs @@ -0,0 +1,62 @@ +defmodule ElixirScript.Test.Test do + use ElixirScript.Test + + test "Atom.to_string" do + val = Atom.to_string(:atom) + assert val == "atom" + end + + test "String interpolation with number" do + val = "#{5}" + assert val == "5" + end + + test "shorthand failure" do + orders = [%{email: "test@hotmail.com"},%{email: "test2@hotmail.com"}] + + val = Enum.reduce(orders, [], + &(&2 ++ [ [:option, %{value: &1.email}, &1.email] ])) + + assert val == [ + [:option, %{value: "test@hotmail.com"}, "test@hotmail.com"], + [:option, %{value: "test2@hotmail.com"}, "test2@hotmail.com"] + ] + end + + test "map equals" do + map1 = %{test: "map"} + map2 = %{test: "map"} + + assert map1 == map2 + end + + test "multi-remote call" do + map = %{token_count: 5_000_000} + val = map.token_count.toLocaleString() + + assert val == "5,000,000" + end + + test "filter names in guards" do + has? = 5 + + val = case 5 do + _ when has? == 5 -> + true + end + + assert val == true + end + + test "tuple_get" do + map = %{{1} => 5} + val = Map.get(map, {1}) + + assert val == 5 + end + + test "multi_bind" do + [_a | _] = val = [1, 2, 3, 4, 5] + assert val == [1, 2, 3, 4, 5] + end +end diff --git a/test_elixir_script/test_test.exs b/test_elixir_script/test_test.exs deleted file mode 100644 index c4d5c4a9..00000000 --- a/test_elixir_script/test_test.exs +++ /dev/null @@ -1,7 +0,0 @@ -defmodule ElixirScript.Test.Test do - use ElixirScript.Test - - test "can get ast from beam" do - assert 1 = 2 - end -end From 5f27907a7fcd2c854212f5555fb06b9c0f587cc7 Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Thu, 26 Oct 2017 20:19:44 -0500 Subject: [PATCH 349/418] Add colors to output --- priv/testrunner/colors.js | 31 +++++++++++++++++++++++++ priv/testrunner/index.js | 13 +++++++++-- priv/testrunner/testRunner.js | 11 +++++---- test_elixir_script/integration_test.exs | 4 ++++ 4 files changed, 53 insertions(+), 6 deletions(-) create mode 100644 priv/testrunner/colors.js diff --git a/priv/testrunner/colors.js b/priv/testrunner/colors.js new file mode 100644 index 00000000..b0b48173 --- /dev/null +++ b/priv/testrunner/colors.js @@ -0,0 +1,31 @@ +export default { + Reset: '\x1b[0m', + Bright: '\x1b[1m', + Dim: '\x1b[2m', + Underscore: '\x1b[4m', + Blink: '\x1b[5m', + Reverse: '\x1b[7m', + Hidden: '\x1b[8m', + fg: { + Black: '\x1b[30m', + Red: '\x1b[31m', + Green: '\x1b[32m', + Yellow: '\x1b[33m', + Blue: '\x1b[34m', + Magenta: '\x1b[35m', + Cyan: '\x1b[36m', + White: '\x1b[37m', + Crimson: '\x1b[38m', + }, + bg: { + Black: '\x1b[40m', + Red: '\x1b[41m', + Green: '\x1b[42m', + Yellow: '\x1b[43m', + Blue: '\x1b[44m', + Magenta: '\x1b[45m', + Cyan: '\x1b[46m', + White: '\x1b[47m', + Crimson: '\x1b[48m', + }, +}; diff --git a/priv/testrunner/index.js b/priv/testrunner/index.js index 2c8f8c2b..3096fa41 100644 --- a/priv/testrunner/index.js +++ b/priv/testrunner/index.js @@ -1,12 +1,21 @@ require = require('./esm/index.js')(module, { cjs: true, esm: 'js' }); const runner = require('./testRunner.js').default; +const Colors = require('./colors.js').default; const testFiles = process.argv.slice(2); +console.time('Finished in'); runner.start(testFiles).then((results) => { + const testsFailed = results.failed > 0; + process.stdout.write('\n\n'); - process.stdout.write(`${results.tests} tests, ${results.success} succeeded, ${results.failed} failed\n`); + console.timeEnd('Finished in'); + console.log( + testsFailed ? Colors.fg.Red : Colors.fg.Green, + `${results.tests} tests, ${results.success} succeeded, ${results.failed} failed\n`, + Colors.Reset, + ); - if (results.failed > 0) { + if (testsFailed) { process.exit(1); } else { process.exit(0); diff --git a/priv/testrunner/testRunner.js b/priv/testrunner/testRunner.js index 2aae1ad3..992444d2 100644 --- a/priv/testrunner/testRunner.js +++ b/priv/testrunner/testRunner.js @@ -1,3 +1,5 @@ +import Colors from './colors.js'; + async function start(files) { const results = { tests: 0, @@ -25,9 +27,10 @@ function runTests(mod, results) { try { test.get(Symbol.for('test'))(context); results.success++; - process.stdout.write('.'); + process.stdout.write(Colors.fg.Green + '.' + Colors.Reset); } catch (e) { results.failed++; + process.stdout.write('\n'); handleError(e, test, results, mod); } } @@ -46,7 +49,7 @@ function handleError(e, test, results, mod) { testMessage = `${results.failed}) ${testMessage} (${moduleName})`; printErrorLine(testMessage); - printErrorLine(errorMessage); + console.log(Colors.fg.Red, errorMessage, Colors.Reset); printErrorLine(left, 'left'); printErrorLine(right, 'right'); } @@ -58,9 +61,9 @@ function handleError(e, test, results, mod) { function printErrorLine(value, label = null) { if (value !== Symbol.for('ex_unit_no_meaningful_value')) { if (label) { - console.error(`${label}: ${value}`); + console.log(Colors.fg.Cyan, `${label}:`, Colors.Reset, `${value}`); } else { - console.error(`${value}`); + console.log(`${value}`, Colors.Reset); } } } diff --git a/test_elixir_script/integration_test.exs b/test_elixir_script/integration_test.exs index 504bf310..550ac254 100644 --- a/test_elixir_script/integration_test.exs +++ b/test_elixir_script/integration_test.exs @@ -1,6 +1,10 @@ defmodule ElixirScript.Test.Test do use ElixirScript.Test + test "Something" do + assert {:ok, 2} = {:ok, 1} + end + test "Atom.to_string" do val = Atom.to_string(:atom) assert val == "atom" From ad8ab30601f2df623fc2741ede2e3e6b327a90f7 Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Sat, 28 Oct 2017 10:42:13 -0500 Subject: [PATCH 350/418] Add setup and setup_all --- lib/elixir_script_test/test.ex | 45 +++++++++++++-- package.json | 10 ++-- priv/testrunner/testRunner.js | 43 +++++++++++++- priv/testrunner/vendor.build.js | 66 ++++++++++++++++++++++ priv/testrunner/vendor.js | 7 +++ rollup.config.js | 74 ++++++++++++++++--------- test_elixir_script/integration_test.exs | 6 +- yarn.lock | 8 +++ 8 files changed, 220 insertions(+), 39 deletions(-) create mode 100644 priv/testrunner/vendor.build.js create mode 100644 priv/testrunner/vendor.js diff --git a/lib/elixir_script_test/test.ex b/lib/elixir_script_test/test.ex index c3618700..0d7b95c6 100644 --- a/lib/elixir_script_test/test.ex +++ b/lib/elixir_script_test/test.ex @@ -2,13 +2,44 @@ defmodule ElixirScript.Test do @doc false defmacro __using__(_opts) do quote do - import unquote(__MODULE__), only: [test: 2, test: 3] + import unquote(__MODULE__), only: [test: 2, test: 3, setup: 1, setup: 2, setup_all: 1, setup_all: 2] import ExUnit.Assertions def __elixir_script_test_module__(), do: true end end + defmacro setup_all(context \\ quote(do: _), contents) do + do_setup(context, contents, :__elixirscript_test_setup_all) + end + + defmacro setup(context \\ quote(do: _), contents) do + do_setup(context, contents, :__elixirscript_test_setup) + end + + defp do_setup(context, contents, name) do + contents = + case contents do + [do: block] -> + quote do + unquote(block) + end + _ -> + quote do + try(unquote(contents)) + end + end + + context = Macro.escape(context) + contents = Macro.escape(contents, unquote: true) + + quote bind_quoted: [context: context, contents: contents, name: name] do + def unquote(name)(unquote(context)) do + unquote(contents) + end + end + end + defmacro test(message, context \\ quote(do: _), contents) do contents = case contents do @@ -30,7 +61,7 @@ defmodule ElixirScript.Test do |> String.replace(" ", "_") |> String.replace(~r/[^A-Za-z0-9]/, "") - name = String.to_atom("__test_#{name}") + name = String.to_atom("__elixirscript_test_case_#{name}") quote bind_quoted: [context: context, contents: contents, message: message, name: name] do def unquote(name)(unquote(context)) do @@ -56,9 +87,7 @@ defmodule ElixirScript.Test do |> Path.join("Elixir.*.js") |> Path.wildcard() - test_script_path = Path.join([:code.priv_dir(:elixir_script), "testrunner", "index.js"]) - - {_, exit_status} = System.cmd "node", [test_script_path] ++ js_files, into: IO.stream(:stdio, :line) + exit_status = node_test_runner(js_files) # Delete directory at the end File.rm_rf!(output) @@ -70,4 +99,10 @@ defmodule ElixirScript.Test do :error end end + + defp node_test_runner(js_files) do + test_script_path = Path.join([:code.priv_dir(:elixir_script), "testrunner", "index.js"]) + {_, exit_status} = System.cmd "node", [test_script_path] ++ js_files, into: IO.stream(:stdio, :line) + exit_status + end end diff --git a/package.json b/package.json index c88a5ed1..1b4d76ef 100644 --- a/package.json +++ b/package.json @@ -11,9 +11,8 @@ }, "scripts": { "lint": "eslint src/javascript/lib/**/*.js src/javascript/tests/**/*.js", - "lint:fix": - "eslint src/javascript/lib/**/*.js src/javascript/tests/**/*.js --fix", - "build": "rollup -c rollup.config.js", + "lint:fix": "eslint src/javascript/lib/**/*.js src/javascript/tests/**/*.js --fix", + "build": "node rollup.config.js", "clean": "rm -rf priv/build", "test": "nyc ava src/javascript/tests" }, @@ -24,6 +23,7 @@ "author": "", "license": "MIT", "dependencies": { + "chalk": "^2.3.0", "erlang-types": "^1.0.1", "grapheme-splitter": "^1.0.2", "rollup-plugin-commonjs": "^8.2.1", @@ -45,7 +45,9 @@ "rollup-plugin-node-resolve": "^3.0.0" }, "ava": { - "require": ["babel-register"], + "require": [ + "babel-register" + ], "babel": { "babelrc": true } diff --git a/priv/testrunner/testRunner.js b/priv/testrunner/testRunner.js index 992444d2..60014c5b 100644 --- a/priv/testrunner/testRunner.js +++ b/priv/testrunner/testRunner.js @@ -1,4 +1,5 @@ import Colors from './colors.js'; +import Vendor from './vendor.build.js'; async function start(files) { const results = { @@ -17,11 +18,47 @@ async function start(files) { return results; } +function runSetup(mod, name, incomingContext = new Map()) { + if (mod.default[name]) { + const result = mod.default[name](incomingContext); + + return resolveContext(result, incomingContext); + } + + return incomingContext; +} + +function resolveContext(context, parentContext) { + if (context === Symbol.for('ok')) { + return parentContext; + } else if (context instanceof Vendor.ErlangTypes.Tuple && context.get(0) === Symbol.for('ok')) { + return resolveContext(context.get(1), parentContext); + } else if (context instanceof Map) { + return new Map([...parentContext, ...context]); + } else if (Array.isArray(context)) { + return mergeContextKeywordList(context, parentContext); + } + + throw new Error('Invalid context'); +} + +function mergeContextKeywordList(context, parentContext) { + const newContext = new Map([...parentContext]); + + for (const entry of context) { + newContext.set(entry.get(0), entry.get(1)); + } + + return newContext; +} + function runTests(mod, results) { - const context = []; + const contextSetupAll = runSetup(mod, '__elixirscript_test_setup_all'); for (const key of Object.keys(mod.default)) { - if (key.startsWith('__test_')) { + const context = runSetup(mod, '__elixirscript_test_setup', contextSetupAll); + + if (key.startsWith('__elixirscript_test_case')) { results.tests++; const test = mod.default[key](context); try { @@ -54,7 +91,7 @@ function handleError(e, test, results, mod) { printErrorLine(right, 'right'); } } else { - console.error(e.message); + console.log(e); } } diff --git a/priv/testrunner/vendor.build.js b/priv/testrunner/vendor.build.js new file mode 100644 index 00000000..65b2d07d --- /dev/null +++ b/priv/testrunner/vendor.build.js @@ -0,0 +1,66 @@ +import os from'os';class Tuple{constructor(...a){this.values=Object.freeze(a),this.length=this.values.length}get(a){return this.values[a]}count(){return this.values.length}[Symbol.iterator](){return this.values[Symbol.iterator]()}toString(){let a,b='';for(a=0;a'}}let ref_counter=-1;class Reference{constructor(){++ref_counter,this.id=ref_counter,this.ref=Symbol()}toString(){return'Ref#<0.0.0.'+this.id+'>'}}class BitString{constructor(...a){this.value=Object.freeze(this.process(a)),this.length=this.value.length,this.bit_size=8*this.length,this.byte_size=this.length}get(a){return this.value[a]}count(){return this.value.length}slice(a,b=null){let c=this.value.slice(a,b),d=c.map((a)=>BitString.integer(a));return new BitString(...d)}[Symbol.iterator](){return this.value[Symbol.iterator]()}toString(){var a,b='';for(a=0;a>'}process(a){let b=[];var c;for(c=0;cb?c.push(b):2048>b?c.push(192|b>>6,128|63&b):55296>b||57344<=b?c.push(224|b>>12,128|63&b>>6,128|63&b):(d++,b=65536+((1023&b)<<10|1023&a.charCodeAt(d)),c.push(240|b>>18,128|63&b>>12,128|63&b>>6,128|63&b));return c}static toUTF16Array(a){for(var b,c=[],d=0;d=b?(c.push(0),c.push(b)):(c.push(255&b>>8),c.push(255&b));return c}static toUTF32Array(a){for(var b,c=[],d=0;d=b?(c.push(0),c.push(0),c.push(0),c.push(b)):(c.push(0),c.push(0),c.push(255&b>>8),c.push(255&b));return c}//http://stackoverflow.com/questions/2003493/javascript-float-from-to-bits +static float32ToBytes(a){var b=[],c=new ArrayBuffer(4);new Float32Array(c)[0]=a;let d=new Uint32Array(c)[0];return b.push(255&d>>24),b.push(255&d>>16),b.push(255&d>>8),b.push(255&d),b}static float64ToBytes(a){var b=[],c=new ArrayBuffer(8);new Float64Array(c)[0]=a;var d=new Uint32Array(c)[0],e=new Uint32Array(c)[1];return b.push(255&e>>24),b.push(255&e>>16),b.push(255&e>>8),b.push(255&e),b.push(255&d>>24),b.push(255&d>>16),b.push(255&d>>8),b.push(255&d),b}}var ErlangTypes={Tuple,PID,Reference,BitString};function createCommonjsModule(a,b){return b={exports:{}},a(b,b.exports),b.exports}var matchOperatorsRe=/[|\\{}()[\]^$+*?.]/g,escapeStringRegexp=function(a){if('string'!=typeof a)throw new TypeError('Expected a string');return a.replace(matchOperatorsRe,'\\$&')},colorName={aliceblue:[240,248,255],antiquewhite:[250,235,215],aqua:[0,255,255],aquamarine:[127,255,212],azure:[240,255,255],beige:[245,245,220],bisque:[255,228,196],black:[0,0,0],blanchedalmond:[255,235,205],blue:[0,0,255],blueviolet:[138,43,226],brown:[165,42,42],burlywood:[222,184,135],cadetblue:[95,158,160],chartreuse:[127,255,0],chocolate:[210,105,30],coral:[255,127,80],cornflowerblue:[100,149,237],cornsilk:[255,248,220],crimson:[220,20,60],cyan:[0,255,255],darkblue:[0,0,139],darkcyan:[0,139,139],darkgoldenrod:[184,134,11],darkgray:[169,169,169],darkgreen:[0,100,0],darkgrey:[169,169,169],darkkhaki:[189,183,107],darkmagenta:[139,0,139],darkolivegreen:[85,107,47],darkorange:[255,140,0],darkorchid:[153,50,204],darkred:[139,0,0],darksalmon:[233,150,122],darkseagreen:[143,188,143],darkslateblue:[72,61,139],darkslategray:[47,79,79],darkslategrey:[47,79,79],darkturquoise:[0,206,209],darkviolet:[148,0,211],deeppink:[255,20,147],deepskyblue:[0,191,255],dimgray:[105,105,105],dimgrey:[105,105,105],dodgerblue:[30,144,255],firebrick:[178,34,34],floralwhite:[255,250,240],forestgreen:[34,139,34],fuchsia:[255,0,255],gainsboro:[220,220,220],ghostwhite:[248,248,255],gold:[255,215,0],goldenrod:[218,165,32],gray:[128,128,128],green:[0,128,0],greenyellow:[173,255,47],grey:[128,128,128],honeydew:[240,255,240],hotpink:[255,105,180],indianred:[205,92,92],indigo:[75,0,130],ivory:[255,255,240],khaki:[240,230,140],lavender:[230,230,250],lavenderblush:[255,240,245],lawngreen:[124,252,0],lemonchiffon:[255,250,205],lightblue:[173,216,230],lightcoral:[240,128,128],lightcyan:[224,255,255],lightgoldenrodyellow:[250,250,210],lightgray:[211,211,211],lightgreen:[144,238,144],lightgrey:[211,211,211],lightpink:[255,182,193],lightsalmon:[255,160,122],lightseagreen:[32,178,170],lightskyblue:[135,206,250],lightslategray:[119,136,153],lightslategrey:[119,136,153],lightsteelblue:[176,196,222],lightyellow:[255,255,224],lime:[0,255,0],limegreen:[50,205,50],linen:[250,240,230],magenta:[255,0,255],maroon:[128,0,0],mediumaquamarine:[102,205,170],mediumblue:[0,0,205],mediumorchid:[186,85,211],mediumpurple:[147,112,219],mediumseagreen:[60,179,113],mediumslateblue:[123,104,238],mediumspringgreen:[0,250,154],mediumturquoise:[72,209,204],mediumvioletred:[199,21,133],midnightblue:[25,25,112],mintcream:[245,255,250],mistyrose:[255,228,225],moccasin:[255,228,181],navajowhite:[255,222,173],navy:[0,0,128],oldlace:[253,245,230],olive:[128,128,0],olivedrab:[107,142,35],orange:[255,165,0],orangered:[255,69,0],orchid:[218,112,214],palegoldenrod:[238,232,170],palegreen:[152,251,152],paleturquoise:[175,238,238],palevioletred:[219,112,147],papayawhip:[255,239,213],peachpuff:[255,218,185],peru:[205,133,63],pink:[255,192,203],plum:[221,160,221],powderblue:[176,224,230],purple:[128,0,128],rebeccapurple:[102,51,153],red:[255,0,0],rosybrown:[188,143,143],royalblue:[65,105,225],saddlebrown:[139,69,19],salmon:[250,128,114],sandybrown:[244,164,96],seagreen:[46,139,87],seashell:[255,245,238],sienna:[160,82,45],silver:[192,192,192],skyblue:[135,206,235],slateblue:[106,90,205],slategray:[112,128,144],slategrey:[112,128,144],snow:[255,250,250],springgreen:[0,255,127],steelblue:[70,130,180],tan:[210,180,140],teal:[0,128,128],thistle:[216,191,216],tomato:[255,99,71],turquoise:[64,224,208],violet:[238,130,238],wheat:[245,222,179],white:[255,255,255],whitesmoke:[245,245,245],yellow:[255,255,0],yellowgreen:[154,205,50]},conversions=createCommonjsModule(function(a){/** + * See https://en.m.wikipedia.org/wiki/Euclidean_distance#Squared_Euclidean_distance + * */function comparativeDistance(a,b){return f(a[0]-b[0],2)+f(a[1]-b[1],2)+f(a[2]-b[2],2)}var c=Math.round,d=Math.PI,e=Math.floor,f=Math.pow,i=Math.max,j=Math.min,b={};/* MIT license */// NOTE: conversions should only return primitive values (i.e. arrays, or +// values that give correct `typeof` results). +// do not use box values types (i.e. Number(), String(), etc.) +for(var g in colorName)colorName.hasOwnProperty(g)&&(b[colorName[g]]=g);var k=a.exports={rgb:{channels:3,labels:'rgb'},hsl:{channels:3,labels:'hsl'},hsv:{channels:3,labels:'hsv'},hwb:{channels:3,labels:'hwb'},cmyk:{channels:4,labels:'cmyk'},xyz:{channels:3,labels:'xyz'},lab:{channels:3,labels:'lab'},lch:{channels:3,labels:'lch'},hex:{channels:1,labels:['hex']},keyword:{channels:1,labels:['keyword']},ansi16:{channels:1,labels:['ansi16']},ansi256:{channels:1,labels:['ansi256']},hcg:{channels:3,labels:['h','c','g']},apple:{channels:3,labels:['r16','g16','b16']},gray:{channels:1,labels:['gray']}};// hide .channels and .labels properties +for(var h in k)if(k.hasOwnProperty(h)){if(!('channels'in k[h]))throw new Error('missing channels property: '+h);if(!('labels'in k[h]))throw new Error('missing channel labels property: '+h);if(k[h].labels.length!==k[h].channels)throw new Error('channel and label counts mismatch: '+h);var l=k[h].channels,m=k[h].labels;delete k[h].channels,delete k[h].labels,Object.defineProperty(k[h],'channels',{value:l}),Object.defineProperty(k[h],'labels',{value:m})}k.rgb.hsl=function(a){var c,d,e,f=a[0]/255,h=a[1]/255,g=a[2]/255,b=j(f,h,g),k=i(f,h,g),l=k-b;return k===b?c=0:f===k?c=(h-g)/l:h===k?c=2+(g-f)/l:g===k&&(c=4+(f-h)/l),c=j(60*c,360),0>c&&(c+=360),e=(b+k)/2,d=k===b?0:0.5>=e?l/(k+b):l/(2-k-b),[c,100*d,100*e]},k.rgb.hsv=function(a){var c,d,e,f=a[0],h=a[1],g=a[2],b=j(f,h,g),k=i(f,h,g),l=k-b;return d=0===k?0:1e3*(l/k)/10,k===b?c=0:f===k?c=(h-g)/l:h===k?c=2+(g-f)/l:g===k&&(c=4+(f-h)/l),c=j(60*c,360),0>c&&(c+=360),e=1e3*(k/255)/10,[c,d,e]},k.rgb.hwb=function(a){var c=a[0],d=a[1],e=a[2],b=k.rgb.hsl(a)[0],f=1/255*j(c,j(d,e));return e=1-1/255*i(c,i(d,e)),[b,100*f,100*e]},k.rgb.cmyk=function(a){var d,c,e,f,h=a[0]/255,i=a[1]/255,g=a[2]/255;return f=j(1-h,1-i,1-g),d=(1-h-f)/(1-f)||0,c=(1-i-f)/(1-f)||0,e=(1-g-f)/(1-f)||0,[100*d,100*c,100*e,100*f]},k.rgb.keyword=function(a){var c=b[a];if(c)return c;var d,e=Infinity;for(var f in colorName)if(colorName.hasOwnProperty(f)){var g=colorName[f],h=comparativeDistance(a,g);// Compute comparative distance +// Check if its less, if so set as closest +hj?j*(1+h):j+h-j*h,b=2*j-c,e=[0,0,0];for(var k=0;3>k;k++)d=g+1/3*-(k-1),0>d&&d++,16*d?b+6*(c-b)*d:1>2*d?c:2>3*d?b+6*((c-b)*(2/3-d)):b,e[k]=255*f;return e},k.hsl.hsv=function(a){var b,c,d=a[0],e=a[1]/100,f=a[2]/100,g=e,h=i(f,0.01);return f*=2,e*=1>=f?f:2-f,g*=1>=h?h:2-h,c=(f+e)/2,b=0==f?2*g/(h+g):2*e/(f+e),[d,100*b,100*c]},k.hsv.rgb=function(a){var b=a[0]/60,c=a[1]/100,d=a[2]/100,g=e(b)%6,h=b-e(b),f=255*d*(1-c),i=255*d*(1-c*h),j=255*d*(1-c*(1-h));return d*=255,0==g?[d,j,f]:1==g?[i,d,f]:2==g?[f,d,j]:3==g?[f,i,d]:4==g?[j,f,d]:5==g?[d,f,i]:void 0},k.hsv.hsl=function(a){var b,c,d,e=a[0],f=a[1]/100,g=a[2]/100,h=i(g,0.01);return d=(2-f)*g,b=(2-f)*h,c=f*h,c/=1>=b?b:2-b,c=c||0,d/=2,[e,100*c,100*d]},k.hwb.rgb=function(a){var c,d,i,f,j=a[0]/360,h=a[1]/100,k=a[2]/100,l=h+k;// wh + bl cant be > 1 +1g&&(g+=360),h=Math.sqrt(i*i+a*a),[c,h,g]},k.lch.lab=function(e){var f,a,b,g=e[0],i=e[1],c=e[2];return b=2*(c/360)*d,f=i*Math.cos(b),a=i*Math.sin(b),[g,f,a]},k.rgb.ansi16=function(a){var d=a[0],e=a[1],f=a[2],b=1 in arguments?arguments[1]:k.rgb.hsv(a)[2];// hsv -> ansi16 optimization +if(b=c(b/50),0===b)return 30;var g=30+(c(f/255)<<2|c(e/255)<<1|c(d/255));return 2===b&&(g+=60),g},k.hsv.ansi16=function(a){// optimization here; we already know the value and don't need to get +// it converted for us. +return k.rgb.ansi16(k.hsv.rgb(a),a[2])},k.rgb.ansi256=function(a){var d=a[0],e=a[1],f=a[2];// we use the extended greyscale palette here, with the exception of +// black and white. normal palette only has 4 greyscale shades. +if(d===e&&e===f)return 8>d?16:248>1)*d),g=255*((1&c>>2)*d);return[e,f,g]},k.ansi256.rgb=function(a){// handle greyscale +if(232<=a){var d=10*(a-232)+8;return[d,d,d]}a-=16;var c,f=255*(e(a/36)/5),h=255*(e((c=a%36)/6)/5),g=255*(c%6/5);return[f,h,g]},k.rgb.hex=function(a){var b=((255&c(a[0]))<<16)+((255&c(a[1]))<<8)+(255&c(a[2])),d=b.toString(16).toUpperCase();return'000000'.substring(d.length)+d},k.hex.rgb=function(a){var b=a.toString(16).match(/[a-f0-9]{6}|[a-f0-9]{3}/i);if(!b)return[0,0,0];var c=b[0];3===b[0].length&&(c=c.split('').map(function(a){return a+a}).join(''));var d=parseInt(c,16);return[255&d>>16,255&d>>8,255&d]},k.rgb.hcg=function(a){var c,d,e=a[0]/255,f=a[1]/255,g=a[2]/255,b=i(i(e,f),g),h=j(j(e,f),g),k=b-h;return c=1>k?h/(1-k):0,d=0>=k?0:b===e?(f-g)/k%6:b===f?2+(g-e)/k:4+(e-f)/k+4,d/=6,d%=1,[360*d,100*k,100*c]},k.hsl.hcg=function(a){var b=a[1]/100,d=a[2]/100,e=1,c=0;return e=0.5>d?2*b*d:2*b*(1-d),1>e&&(c=(d-0.5*e)/(1-e)),[a[0],100*e,100*c]},k.hsv.hcg=function(a){var b=a[1]/100,d=a[2]/100,e=b*d,c=0;return 1>e&&(c=(d-e)/(1-e)),[a[0],100*e,100*c]},k.hcg.rgb=function(a){var b=a[0]/360,d=a[1]/100,c=a[2]/100;if(0==d)return[255*c,255*c,255*c];var f=[0,0,0],g=6*(b%1),h=g%1,i=1-h,j=0;switch(e(g)){case 0:f[0]=1,f[1]=h,f[2]=0;break;case 1:f[0]=i,f[1]=1,f[2]=0;break;case 2:f[0]=0,f[1]=1,f[2]=h;break;case 3:f[0]=0,f[1]=i,f[2]=1;break;case 4:f[0]=h,f[1]=0,f[2]=1;break;default:f[0]=1,f[1]=0,f[2]=i;}return j=(1-d)*c,[255*(d*f[0]+j),255*(d*f[1]+j),255*(d*f[2]+j)]},k.hcg.hsv=function(a){var b=a[1]/100,c=a[2]/100,d=b+c*(1-b),e=0;return 0d?e=b/(2*d):0.5<=d&&1>d&&(e=b/(2*(1-d))),[a[0],100*e,100*d]},k.hcg.hwb=function(a){var b=a[1]/100,c=a[2]/100,d=b+c*(1-b);return[a[0],100*(d-b),100*(1-d)]},k.hwb.hcg=function(a){var d=a[1]/100,e=a[2]/100,b=1-e,f=b-d,c=0;return 1>f&&(c=(b-f)/(1-f)),[a[0],100*f,100*c]},k.apple.rgb=function(a){return[255*(a[0]/65535),255*(a[1]/65535),255*(a[2]/65535)]},k.rgb.apple=function(a){return[65535*(a[0]/255),65535*(a[1]/255),65535*(a[2]/255)]},k.gray.rgb=function(a){return[255*(a[0]/100),255*(a[0]/100),255*(a[0]/100)]},k.gray.hsl=k.gray.hsv=function(a){return[0,0,a[0]]},k.gray.hwb=function(a){return[0,100,a[0]]},k.gray.cmyk=function(a){return[0,0,0,a[0]]},k.gray.lab=function(a){return[a[0],0,0]},k.gray.hex=function(a){var b=255&c(255*(a[0]/100)),d=((b<<16)+(b<<8)+b).toString(16).toUpperCase();return'000000'.substring(d.length)+d},k.rgb.gray=function(a){var b=(a[0]+a[1]+a[2])/3;return[100*(b/255)]}}),models$1=Object.keys(conversions);/* + this function routes a model to all other models. + + all functions that are routed have a property `.conversion` attached + to the returned synthetic function. This property is an array + of strings, each with the steps in between the 'from' and 'to' + color models (inclusive). + + conversions that are not possible simply are not included. +*/// https://jsperf.com/object-keys-vs-for-in-with-closure/3 +function buildGraph(){for(var a={},b=models$1.length,c=0;c queue -> pop +for(b[a].distance=0;c.length;)for(var d=c.pop(),e=Object.keys(conversions[d]),f=e.length,g=0;gfunction(){const c=a.apply(colorConvert,arguments);return`\u001B[${c+b}m`},c=(a,b)=>function(){const c=a.apply(colorConvert,arguments);return`\u001B[${38+b};5;${c}m`},d=(a,b)=>function(){const c=a.apply(colorConvert,arguments);return`\u001B[${38+b};2;${c[0]};${c[1]};${c[2]}m`};Object.defineProperty(a,'exports',{enumerable:!0,get:function assembleStyles(){const a={modifier:{reset:[0,0],// 21 isn't widely supported and 22 does the same thing +bold:[1,22],dim:[2,22],italic:[3,23],underline:[4,24],inverse:[7,27],hidden:[8,28],strikethrough:[9,29]},color:{black:[30,39],red:[31,39],green:[32,39],yellow:[33,39],blue:[34,39],magenta:[35,39],cyan:[36,39],white:[37,39],gray:[90,39],// Bright color +redBright:[91,39],greenBright:[92,39],yellowBright:[93,39],blueBright:[94,39],magentaBright:[95,39],cyanBright:[96,39],whiteBright:[97,39]},bgColor:{bgBlack:[40,49],bgRed:[41,49],bgGreen:[42,49],bgYellow:[43,49],bgBlue:[44,49],bgMagenta:[45,49],bgCyan:[46,49],bgWhite:[47,49],// Bright color +bgBlackBright:[100,49],bgRedBright:[101,49],bgGreenBright:[102,49],bgYellowBright:[103,49],bgBlueBright:[104,49],bgMagentaBright:[105,49],bgCyanBright:[106,49],bgWhiteBright:[107,49]}};// Fix humans +a.color.grey=a.color.gray,Object.keys(a).forEach((b)=>{const c=a[b];Object.keys(c).forEach((b)=>{const d=c[b];a[b]={open:`\u001B[${d[0]}m`,close:`\u001B[${d[1]}m`},c[b]=a[b]}),Object.defineProperty(a,b,{value:c,enumerable:!1})});const e=(a,c,d)=>[a,c,d];a.color.close='\x1B[39m',a.bgColor.close='\x1B[49m',a.color.ansi={},a.color.ansi256={},a.color.ansi16m={rgb:d(e,0)},a.bgColor.ansi={},a.bgColor.ansi256={},a.bgColor.ansi16m={rgb:d(e,10)};for(const e of Object.keys(colorConvert)){if('object'!=typeof colorConvert[e])continue;const f=colorConvert[e];'ansi16'in f&&(a.color.ansi[e]=b(f.ansi16,0),a.bgColor.ansi[e]=b(f.ansi16,10)),'ansi256'in f&&(a.color.ansi256[e]=c(f.ansi256,0),a.bgColor.ansi256[e]=c(f.ansi256,10)),'rgb'in f&&(a.color.ansi16m[e]=d(f.rgb,0),a.bgColor.ansi16m[e]=d(f.rgb,10))}return a}})});var hasFlag=function(a,b){b=b||process.argv;var c=b.indexOf('--'),d=/^-{1,2}/.test(a)?'':'--',e=b.indexOf(d+a);return-1!==e&&(!(-1!==c)||e{if(hasFlag('no-color')||hasFlag('no-colors')||hasFlag('color=false'))return 0;if(hasFlag('color=16m')||hasFlag('color=full')||hasFlag('color=truecolor'))return 3;if(hasFlag('color=256'))return 2;if(hasFlag('color')||hasFlag('colors')||hasFlag('color=true')||hasFlag('color=always'))return 1;if(process.stdout&&!process.stdout.isTTY)return 0;if('win32'===process.platform){// Node.js 7.5.0 is the first version of Node.js to include a patch to +// libuv that enables 256 color output on Windows. Anything earlier and it +// won't work. However, here we target Node.js 8 at minimum as it is an LTS +// release, and Node.js 7 is not. Windows 10 build 10586 is the first Windows +// release that supports 256 colors. +const a=os.release().split('.');return 8<=+process.version.split('.')[0]&&10<=+a[0]&&10586<=+a[2]?2:1}if('CI'in b)return'TRAVIS'in b||'Travis'===b.CI||'CIRCLECI'in b?1:0;if('TEAMCITY_VERSION'in b)return /^(9\.(0*[1-9]\d*)\.|\d{2,}\.)/.test(b.TEAMCITY_VERSION)?1:0;if('TERM_PROGRAM'in b){const a=parseInt((b.TERM_PROGRAM_VERSION||'').split('.')[0],10);switch(b.TERM_PROGRAM){case'iTerm.app':return 3<=a?3:2;case'Hyper':return 3;case'Apple_Terminal':return 2;// No default +}}return /^(screen|xterm)-256(?:color)?/.test(b.TERM)?2:/^screen|^xterm|^vt100|color|ansi|cygwin|linux/i.test(b.TERM)?1:'COLORTERM'in b?1:'dumb'===b.TERM?0:0})();'FORCE_COLOR'in b&&(c=0===parseInt(b.FORCE_COLOR,10)?0:c||1),a.exports=process&&((a)=>0!==a&&{level:a,hasBasic:!0,has256:2<=a,has16m:3<=a})(c)}),templates=createCommonjsModule(function(a){'use strict';function unescape(a){return'u'===a[0]&&5===a.length||'x'===a[0]&&3===a.length?String.fromCharCode(parseInt(a.slice(1),16)):f.get(a)||a}function parseArguments(a,b){const c=[],f=b.trim().split(/\s*,\s*/g);let g;for(const h of f)if(!isNaN(h))c.push(+h);else if(g=h.match(d))c.push(g[2].replace(e,(a,b,c)=>b?unescape(b):c));else throw new Error(`Invalid Chalk template style argument: ${h} (in style '${a}')`);return c}function parseStyle(a){c.lastIndex=0;const b=[];for(let d;null!==(d=c.exec(a));){const a=d[1];if(d[2]){const c=parseArguments(a,d[2]);b.push([a].concat(c))}else b.push([a])}return b}function buildStyle(a,b){const c={};for(const d of b)for(const a of d.styles)c[a[0]]=d.inverse?null:a.slice(1);let d=a;for(const e of Object.keys(c))if(Array.isArray(c[e])){if(!(e in d))throw new Error(`Unknown Chalk style: ${e}`);d=0{const d=[],e=[];let f=[];// eslint-disable-next-line max-params +if(c.replace(b,(b,c,g,h,i,j)=>{if(c)f.push(unescape(c));else if(h){const b=f.join('');f=[],e.push(0===d.length?b:buildStyle(a,d)(b)),d.push({inverse:g,styles:parseStyle(h)})}else if(i){if(0===d.length)throw new Error('Found extraneous } in Chalk template literal');e.push(buildStyle(a,d)(f.join(''))),f=[],d.pop()}else f.push(j)}),e.push(f.join('')),0=this.level||!e)return this._empty?'':e;// Turns out that on Windows dimmed gray text becomes invisible in cmd.exe, +// see https://github.com/chalk/chalk/issues/58 +// If we're on Windows and we're dealing with a gray color, temporarily make 'dim' a noop. +const a=ansiStyles.dim.open;b&&this.hasGrey&&(ansiStyles.dim.open='');for(const a of this._styles.slice().reverse())e=a.open+e.replace(a.closeRe,a.open)+a.close,e=e.replace(/\r?\n/g,`${a.close}$&${a.open}`);// Reset the original `dim` if we changed it to work around the Windows dimmed gray issue +return ansiStyles.dim.open=a,e}function chalkTag(a,b){if(!Array.isArray(b))// If chalk() was called by itself or with a string, +// return the string itself as a string. +return[].slice.call(arguments,1).join(' ');const c=[].slice.call(arguments,2),d=[b.raw[0]];for(let e=1;e{},e);Object.defineProperties(Chalk.prototype,e),a.exports=Chalk(),a.exports.supportsColor=supportsColor,a.exports.default=a.exports}// For TypeScript +),vendor={ErlangTypes,Chalk:chalk};export default vendor; diff --git a/priv/testrunner/vendor.js b/priv/testrunner/vendor.js new file mode 100644 index 00000000..7e3cd354 --- /dev/null +++ b/priv/testrunner/vendor.js @@ -0,0 +1,7 @@ +import ErlangTypes from 'erlang-types'; +import Chalk from 'chalk'; + +export default { + ErlangTypes, + Chalk, +}; diff --git a/rollup.config.js b/rollup.config.js index ced74194..58a95b70 100644 --- a/rollup.config.js +++ b/rollup.config.js @@ -1,27 +1,49 @@ -import nodeResolve from 'rollup-plugin-node-resolve'; -import commonjs from 'rollup-plugin-commonjs'; -import babel from 'rollup-plugin-babel'; -import minify from 'rollup-plugin-babel-minify'; +const rollup = require('rollup'); +const babel = require('rollup-plugin-babel'); +const nodeResolve = require('rollup-plugin-node-resolve'); +const commonjs = require('rollup-plugin-commonjs'); +const minify = require('rollup-plugin-babel-minify'); -export default { - input: 'src/javascript/elixir.js', - name: 'ElixirScript', - plugins: [ - nodeResolve({ - jsnext: true, - main: true, - }), - commonjs(), - babel({ - babelrc: false, - }), - minify({ - keepFnName: true, - keepClassName: true, - }), - ], - output: [ - { file: 'priv/build/iife/ElixirScript.Core.js', format: 'iife' }, - { file: 'priv/build/es/ElixirScript.Core.js', format: 'es', sourcemap: 'inline' }, - ], -}; +const plugins = [ + nodeResolve({ + jsnext: true, + main: true, + }), + commonjs(), + babel({ + babelrc: false, + }), + minify({ + keepFnName: true, + keepClassName: true, + }), +]; + +rollup + .rollup({ + input: 'src/javascript/elixir.js', + output: 'priv/build/es/ElixirScript.Core.js', + sourcemap: 'inline', + format: 'es', + plugins, + }) + .then((bundle) => { + bundle.write({ + format: 'es', + file: 'priv/build/es/ElixirScript.Core.js', + }); + }); + +rollup + .rollup({ + input: 'priv/testrunner/vendor.js', + output: 'priv/testrunner/vendor.build.js', + format: 'es', + plugins, + }) + .then((bundle) => { + bundle.write({ + format: 'es', + file: 'priv/testrunner/vendor.build.js', + }); + }); diff --git a/test_elixir_script/integration_test.exs b/test_elixir_script/integration_test.exs index 550ac254..bdaa33b6 100644 --- a/test_elixir_script/integration_test.exs +++ b/test_elixir_script/integration_test.exs @@ -1,6 +1,10 @@ -defmodule ElixirScript.Test.Test do +defmodule ElixirScript.Integration.Test do use ElixirScript.Test + setup do + [item: true] + end + test "Something" do assert {:ok, 2} = {:ok, 1} end diff --git a/yarn.lock b/yarn.lock index 9aec577d..ec2b01e5 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1264,6 +1264,14 @@ chalk@^2.1.0: escape-string-regexp "^1.0.5" supports-color "^4.0.0" +chalk@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.3.0.tgz#b5ea48efc9c1793dccc9b4767c93914d3f2d52ba" + dependencies: + ansi-styles "^3.1.0" + escape-string-regexp "^1.0.5" + supports-color "^4.0.0" + chokidar@^1.4.2: version "1.7.0" resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-1.7.0.tgz#798e689778151c8076b4b360e5edd28cda2bb468" From 9ab8b441f282a201d3fdd0055bb8616427a7cc3c Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Sat, 28 Oct 2017 10:42:36 -0500 Subject: [PATCH 351/418] Add setup and setup_all --- test_elixir_script/integration_test.exs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test_elixir_script/integration_test.exs b/test_elixir_script/integration_test.exs index bdaa33b6..737997a5 100644 --- a/test_elixir_script/integration_test.exs +++ b/test_elixir_script/integration_test.exs @@ -6,7 +6,7 @@ defmodule ElixirScript.Integration.Test do end test "Something" do - assert {:ok, 2} = {:ok, 1} + assert {:ok, _} = {:ok, 1} end test "Atom.to_string" do From c86e3229a44f349c50d01e0c09ae4ce6a95c38fa Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Sat, 28 Oct 2017 13:14:14 -0500 Subject: [PATCH 352/418] Refactoring test macros. Add teardown and teardown_all --- lib/elixir_script_test/test.ex | 76 ++------------ .../test/assertion_error.ex | 3 - lib/elixir_script_test/test/assertions.ex | 7 -- lib/elixir_script_test/test/callbacks.ex | 99 +++++++++++++++++++ priv/testrunner/testRunner.js | 42 +++++--- test_elixir_script/integration_test.exs | 4 - 6 files changed, 139 insertions(+), 92 deletions(-) delete mode 100644 lib/elixir_script_test/test/assertion_error.ex delete mode 100644 lib/elixir_script_test/test/assertions.ex create mode 100644 lib/elixir_script_test/test/callbacks.ex diff --git a/lib/elixir_script_test/test.ex b/lib/elixir_script_test/test.ex index 0d7b95c6..96f82173 100644 --- a/lib/elixir_script_test/test.ex +++ b/lib/elixir_script_test/test.ex @@ -2,81 +2,23 @@ defmodule ElixirScript.Test do @doc false defmacro __using__(_opts) do quote do - import unquote(__MODULE__), only: [test: 2, test: 3, setup: 1, setup: 2, setup_all: 1, setup_all: 2] + import ElixirScript.Test.Callbacks, only: [ + test: 2, test: 3, + setup: 1, setup: 2, + setup_all: 1, setup_all: 2, + teardown: 1, teardown: 2, + teardown_all: 1, teardown_all: 2 + ] import ExUnit.Assertions - def __elixir_script_test_module__(), do: true - end - end - - defmacro setup_all(context \\ quote(do: _), contents) do - do_setup(context, contents, :__elixirscript_test_setup_all) - end - - defmacro setup(context \\ quote(do: _), contents) do - do_setup(context, contents, :__elixirscript_test_setup) - end - - defp do_setup(context, contents, name) do - contents = - case contents do - [do: block] -> - quote do - unquote(block) - end - _ -> - quote do - try(unquote(contents)) - end - end - - context = Macro.escape(context) - contents = Macro.escape(contents, unquote: true) - - quote bind_quoted: [context: context, contents: contents, name: name] do - def unquote(name)(unquote(context)) do - unquote(contents) - end - end - end - - defmacro test(message, context \\ quote(do: _), contents) do - contents = - case contents do - [do: block] -> - quote do - unquote(block) - :ok - end - _ -> - quote do - try(unquote(contents)) - :ok - end - end - - context = Macro.escape(context) - contents = Macro.escape(contents, unquote: true) - name = message - |> String.replace(" ", "_") - |> String.replace(~r/[^A-Za-z0-9]/, "") - - name = String.to_atom("__elixirscript_test_case_#{name}") - - quote bind_quoted: [context: context, contents: contents, message: message, name: name] do - def unquote(name)(unquote(context)) do - %{ - message: unquote(message), - test: fn(context) -> unquote(contents) end - } - end + def __elixirscript_test_module__(), do: true end end @doc """ Runs tests found in the given path. Accepts wildcards """ - def start(path, opts \\ %{}) do + def start(path, _opts \\ %{}) do output = Path.join([System.tmp_dir!(), "elixirscript_tests"]) File.mkdir_p!(output) diff --git a/lib/elixir_script_test/test/assertion_error.ex b/lib/elixir_script_test/test/assertion_error.ex deleted file mode 100644 index 3a88fde2..00000000 --- a/lib/elixir_script_test/test/assertion_error.ex +++ /dev/null @@ -1,3 +0,0 @@ -defmodule ElixirScript.Test.AssertionError do - defexception [:message] -end diff --git a/lib/elixir_script_test/test/assertions.ex b/lib/elixir_script_test/test/assertions.ex deleted file mode 100644 index 2d8496b6..00000000 --- a/lib/elixir_script_test/test/assertions.ex +++ /dev/null @@ -1,7 +0,0 @@ -defmodule ElixirScript.Test.Assertions do - def assert(value) do - if !value do - raise ElixirScript.Test.AssertionError, message: "failed" - end - end -end diff --git a/lib/elixir_script_test/test/callbacks.ex b/lib/elixir_script_test/test/callbacks.ex new file mode 100644 index 00000000..e124a649 --- /dev/null +++ b/lib/elixir_script_test/test/callbacks.ex @@ -0,0 +1,99 @@ +defmodule ElixirScript.Test.Callbacks do + + defmacro setup_all(context \\ quote(do: _), contents) do + do_setup(context, contents, :__elixirscript_test_setup_all) + end + + defmacro setup(context \\ quote(do: _), contents) do + do_setup(context, contents, :__elixirscript_test_setup) + end + + defp do_setup(context, contents, name) do + contents = + case contents do + [do: block] -> + quote do + unquote(block) + end + _ -> + quote do + try(unquote(contents)) + end + end + + context = Macro.escape(context) + contents = Macro.escape(contents, unquote: true) + + quote bind_quoted: [context: context, contents: contents, name: name] do + def unquote(name)(unquote(context)) do + unquote(contents) + end + end + end + + defmacro teardown_all(context \\ quote(do: _), contents) do + do_teardown(context, contents, :__elixirscript_test_teardown_all) + end + + defmacro teardown(context \\ quote(do: _), contents) do + do_teardown(context, contents, :__elixirscript_test_teardown) + end + + defp do_teardown(context, contents, name) do + contents = + case contents do + [do: block] -> + quote do + unquote(block) + :ok + end + _ -> + quote do + try(unquote(contents)) + :ok + end + end + + context = Macro.escape(context) + contents = Macro.escape(contents, unquote: true) + + quote bind_quoted: [context: context, contents: contents, name: name] do + def unquote(name)(unquote(context)) do + unquote(contents) + end + end + end + + defmacro test(message, context \\ quote(do: _), contents) do + contents = + case contents do + [do: block] -> + quote do + unquote(block) + :ok + end + _ -> + quote do + try(unquote(contents)) + :ok + end + end + + context = Macro.escape(context) + contents = Macro.escape(contents, unquote: true) + name = message + |> String.replace(" ", "_") + |> String.replace(~r/[^A-Za-z0-9]/, "") + + name = String.to_atom("__elixirscript_test_case_#{name}") + + quote bind_quoted: [context: context, contents: contents, message: message, name: name] do + def unquote(name)() do + %{ + message: unquote(message), + test: fn(context) -> unquote(contents) end + } + end + end + end +end diff --git a/priv/testrunner/testRunner.js b/priv/testrunner/testRunner.js index 60014c5b..b1856c5d 100644 --- a/priv/testrunner/testRunner.js +++ b/priv/testrunner/testRunner.js @@ -10,7 +10,7 @@ async function start(files) { for (const file of files) { const mod = await import(file); - if (mod.default.__elixir_script_test_module__) { + if (mod.default.__elixirscript_test_module__) { runTests(mod, results); } } @@ -28,6 +28,12 @@ function runSetup(mod, name, incomingContext = new Map()) { return incomingContext; } +function runTeardown(mod, name, incomingContext) { + if (mod.default[name]) { + const result = mod.default[name](incomingContext); + } +} + function resolveContext(context, parentContext) { if (context === Symbol.for('ok')) { return parentContext; @@ -56,22 +62,36 @@ function runTests(mod, results) { const contextSetupAll = runSetup(mod, '__elixirscript_test_setup_all'); for (const key of Object.keys(mod.default)) { - const context = runSetup(mod, '__elixirscript_test_setup', contextSetupAll); - if (key.startsWith('__elixirscript_test_case')) { results.tests++; - const test = mod.default[key](context); - try { - test.get(Symbol.for('test'))(context); + const test = mod.default[key](); + const result = runTest(mod, test, contextSetupAll, results); + + if (result) { results.success++; - process.stdout.write(Colors.fg.Green + '.' + Colors.Reset); - } catch (e) { - results.failed++; - process.stdout.write('\n'); - handleError(e, test, results, mod); + } else { + resuls.failed++; } } } + + runTeardown(mod, '__elixirscript_test_teardown_all', contextSetupAll); +} + +function runTest(mod, test, incomingContext, results) { + const context = runSetup(mod, '__elixirscript_test_setup', incomingContext); + const testPassed = true; + try { + test.get(Symbol.for('test'))(context); + process.stdout.write(Colors.fg.Green + '.' + Colors.Reset); + } catch (e) { + process.stdout.write('\n'); + handleError(e, test, results, mod); + testPassed = false; + } + + runTeardown(mod, '__elixirscript_test_teardown', context); + return testPassed; } function handleError(e, test, results, mod) { diff --git a/test_elixir_script/integration_test.exs b/test_elixir_script/integration_test.exs index 737997a5..491d88c7 100644 --- a/test_elixir_script/integration_test.exs +++ b/test_elixir_script/integration_test.exs @@ -1,10 +1,6 @@ defmodule ElixirScript.Integration.Test do use ElixirScript.Test - setup do - [item: true] - end - test "Something" do assert {:ok, _} = {:ok, 1} end From e6b447217ed2053ed2223a08878e9eecbcda1b16 Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Sat, 28 Oct 2017 16:19:21 -0500 Subject: [PATCH 353/418] Add documentation --- lib/elixir_script_test/test.ex | 146 +++++++++++++++++------ lib/elixir_script_test/test/callbacks.ex | 18 +++ lib/mix/tasks/elixirscript.test.ex | 2 +- mix.exs | 2 +- mix.lock | 10 +- package.json | 1 - priv/testrunner/vendor.build.js | 68 +---------- priv/testrunner/vendor.js | 2 - yarn.lock | 8 -- 9 files changed, 137 insertions(+), 120 deletions(-) diff --git a/lib/elixir_script_test/test.ex b/lib/elixir_script_test/test.ex index 96f82173..60a2dee3 100644 --- a/lib/elixir_script_test/test.ex +++ b/lib/elixir_script_test/test.ex @@ -1,50 +1,124 @@ defmodule ElixirScript.Test do - @doc false - defmacro __using__(_opts) do - quote do - import ElixirScript.Test.Callbacks, only: [ - test: 2, test: 3, - setup: 1, setup: 2, - setup_all: 1, setup_all: 2, - teardown: 1, teardown: 2, - teardown_all: 1, teardown_all: 2 - ] - import ExUnit.Assertions - - def __elixirscript_test_module__(), do: true + @moduledoc """ + Unit Testing Framework for ElixirScript. + + Requires node.js 8.3.0 and above + + Uses assertions from ExUnit as well as has a similar api to ExUnit with a few differences + + ## Example + + An basic setup of a test. Modified from ExUnit's example + + ```elixir + # File: assertion_test.exs + # 1) Create a new test module (test case) and use "ElixirScript.Test". + defmodule AssertionTest do + use ElixirScript.Test + + # 2) Use the "test" macro. + test "the truth" do + assert true end end + ``` + + To run the test above, use the `ElixirScript.Test.start/1` function, giving it the path to the test + ``` + ElixirScript.Test.start("assertion_test.exs") + ``` + + ## Integration with Mix + + To run tests using mix, run `mix elixirscript.test`. This will run all tests in the test_elixir_script directory. + + + ## Callbacks + + ElixirScript defines the following callbacks - @doc """ - Runs tests found in the given path. Accepts wildcards - """ - def start(path, _opts \\ %{}) do - output = Path.join([System.tmp_dir!(), "elixirscript_tests"]) - File.mkdir_p!(output) + * setup/1 + * setup/2 + * setup_all/1 + * setup_all/2 + * teardown/1 + * teardown/2 + * teardown_all/1 + * teardown_all/2 - ElixirScript.Compiler.compile(path, [output: output]) + The `setup` and `setup_all` callbacks work exactly as they would in ExUnit. Instead of having an `on_exit` callback, + ElixirScript.Test has `teardown` callbacks. `teardown` is called after each test and `teardown_all` after all tests + in the file have run. - js_files = output - |> Path.expand - |> Path.join("Elixir.*.js") - |> Path.wildcard() + ```elixir + defmodule AssertionTest do + use ElixirScript.Test - exit_status = node_test_runner(js_files) + # run before test + setup do + admin = create_admin_function() + [admin: admin] + end - # Delete directory at the end - File.rm_rf!(output) + test "the truth", %{admin: admin} do + assert admin.is_authenticated + end - case exit_status do - 0 -> - :ok - _ -> - :error + # run after test + teardown, %{admin: admin} do + destroy_admin_function(admin) end end + ``` + """ + + + defmacro __using__(_opts) do + quote do + import ElixirScript.Test.Callbacks, only: [ + test: 2, test: 3, + setup: 1, setup: 2, + setup_all: 1, setup_all: 2, + teardown: 1, teardown: 2, + teardown_all: 1, teardown_all: 2 + ] + import ExUnit.Assertions + + def __elixirscript_test_module__(), do: true + end + end - defp node_test_runner(js_files) do - test_script_path = Path.join([:code.priv_dir(:elixir_script), "testrunner", "index.js"]) - {_, exit_status} = System.cmd "node", [test_script_path] ++ js_files, into: IO.stream(:stdio, :line) - exit_status + @doc """ + Runs tests found in the given path. Accepts wildcards + """ + @spec start(binary(), map()) :: :ok | :error + def start(path, _opts \\ %{}) do + output = Path.join([System.tmp_dir!(), "elixirscript_tests"]) + File.mkdir_p!(output) + + ElixirScript.Compiler.compile(path, [output: output]) + + js_files = output + |> Path.expand + |> Path.join("Elixir.*.js") + |> Path.wildcard() + + exit_status = node_test_runner(js_files) + + # Delete directory at the end + File.rm_rf!(output) + + case exit_status do + 0 -> + :ok + _ -> + :error end + end + + defp node_test_runner(js_files) do + test_script_path = Path.join([:code.priv_dir(:elixir_script), "testrunner", "index.js"]) + {_, exit_status} = System.cmd "node", [test_script_path] ++ js_files, into: IO.stream(:stdio, :line) + exit_status + end end diff --git a/lib/elixir_script_test/test/callbacks.ex b/lib/elixir_script_test/test/callbacks.ex index e124a649..f314c1c1 100644 --- a/lib/elixir_script_test/test/callbacks.ex +++ b/lib/elixir_script_test/test/callbacks.ex @@ -1,9 +1,18 @@ defmodule ElixirScript.Test.Callbacks do + @moduledoc """ + Defines ElixirScript.Test callbacks + """ + @doc """ + Called before all tests are run in a test file + """ defmacro setup_all(context \\ quote(do: _), contents) do do_setup(context, contents, :__elixirscript_test_setup_all) end + @doc """ + Called before each test is run in a test file + """ defmacro setup(context \\ quote(do: _), contents) do do_setup(context, contents, :__elixirscript_test_setup) end @@ -31,10 +40,16 @@ defmodule ElixirScript.Test.Callbacks do end end + @doc """ + Called after all tests are run in a test file + """ defmacro teardown_all(context \\ quote(do: _), contents) do do_teardown(context, contents, :__elixirscript_test_teardown_all) end + @doc """ + Called after each test is run in a test file + """ defmacro teardown(context \\ quote(do: _), contents) do do_teardown(context, contents, :__elixirscript_test_teardown) end @@ -64,6 +79,9 @@ defmodule ElixirScript.Test.Callbacks do end end + @doc """ + Defines a test + """ defmacro test(message, context \\ quote(do: _), contents) do contents = case contents do diff --git a/lib/mix/tasks/elixirscript.test.ex b/lib/mix/tasks/elixirscript.test.ex index 23321491..e60899d6 100644 --- a/lib/mix/tasks/elixirscript.test.ex +++ b/lib/mix/tasks/elixirscript.test.ex @@ -7,7 +7,7 @@ defmodule Mix.Tasks.Elixirscript.Test do @shortdoc "Runs ElixirScript Tests" @preferred_cli_env :test - def run(args) do + def run(_args) do Mix.Task.run "app.start" path = Path.join([default_test_path(), "**", "*_test.exs"]) diff --git a/mix.exs b/mix.exs index 573b3cb0..0ecdc707 100644 --- a/mix.exs +++ b/mix.exs @@ -4,7 +4,7 @@ defmodule ElixirScript.Mixfile do def project do [ app: :elixir_script, - version: "0.31.1", + version: "0.32.0-dev", elixir: "~> 1.5", elixirc_paths: elixirc_paths(Mix.env), deps: deps(), diff --git a/mix.lock b/mix.lock index 7f3276cd..77645618 100644 --- a/mix.lock +++ b/mix.lock @@ -1,14 +1,14 @@ %{"bunt": {:hex, :bunt, "0.2.0", "951c6e801e8b1d2cbe58ebbd3e616a869061ddadcc4863d0a2182541acae9a38", [:mix], [], "hexpm"}, "certifi": {:hex, :certifi, "2.0.0", "a0c0e475107135f76b8c1d5bc7efb33cd3815cb3cf3dea7aefdd174dabead064", [:rebar3], [], "hexpm"}, - "credo": {:hex, :credo, "0.8.6", "335f723772d35da499b5ebfdaf6b426bfb73590b6fcbc8908d476b75f8cbca3f", [:mix], [{:bunt, "~> 0.2.0", [hex: :bunt, repo: "hexpm", optional: false]}], "hexpm"}, + "credo": {:hex, :credo, "0.8.8", "990e7844a8d06ebacd88744a55853a83b74270b8a8461c55a4d0334b8e1736c9", [:mix], [{:bunt, "~> 0.2.0", [hex: :bunt, repo: "hexpm", optional: false]}], "hexpm"}, "earmark": {:hex, :earmark, "1.2.3", "206eb2e2ac1a794aa5256f3982de7a76bf4579ff91cb28d0e17ea2c9491e46a4", [:mix], [], "hexpm"}, "estree": {:hex, :estree, "2.6.1", "0a17cc0e9e35315dc4fcd79d30a746b1f3e9ed654be6084ce882ab491165ae22", [:mix], [], "hexpm"}, - "ex_doc": {:hex, :ex_doc, "0.16.3", "cd2a4cfe5d26e37502d3ec776702c72efa1adfa24ed9ce723bb565f4c30bd31a", [:mix], [{:earmark, "~> 1.1", [hex: :earmark, repo: "hexpm", optional: false]}], "hexpm"}, - "excoveralls": {:hex, :excoveralls, "0.7.2", "f69ede8c122ccd3b60afc775348a53fc8c39fe4278aee2f538f0d81cc5e7ff3a", [:mix], [{:exjsx, ">= 3.0.0", [hex: :exjsx, repo: "hexpm", optional: false]}, {:hackney, ">= 0.12.0", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm"}, + "ex_doc": {:hex, :ex_doc, "0.18.1", "37c69d2ef62f24928c1f4fdc7c724ea04aecfdf500c4329185f8e3649c915baf", [:mix], [{:earmark, "~> 1.1", [hex: :earmark, repo: "hexpm", optional: false]}], "hexpm"}, + "excoveralls": {:hex, :excoveralls, "0.7.4", "3d84b2f15a0e593159f74b19f83794b464b34817183d27965bdc6c462de014f9", [:mix], [{:exjsx, ">= 3.0.0", [hex: :exjsx, repo: "hexpm", optional: false]}, {:hackney, ">= 0.12.0", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm"}, "exjsx": {:hex, :exjsx, "4.0.0", "60548841e0212df401e38e63c0078ec57b33e7ea49b032c796ccad8cde794b5c", [:mix], [{:jsx, "~> 2.8.0", [hex: :jsx, repo: "hexpm", optional: false]}], "hexpm"}, - "hackney": {:hex, :hackney, "1.9.0", "51c506afc0a365868469dcfc79a9d0b94d896ec741cfd5bd338f49a5ec515bfe", [:rebar3], [{:certifi, "2.0.0", [hex: :certifi, repo: "hexpm", optional: false]}, {:idna, "5.1.0", [hex: :idna, repo: "hexpm", optional: false]}, {:metrics, "1.0.1", [hex: :metrics, repo: "hexpm", optional: false]}, {:mimerl, "1.0.2", [hex: :mimerl, repo: "hexpm", optional: false]}, {:ssl_verify_fun, "1.1.1", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}], "hexpm"}, + "hackney": {:hex, :hackney, "1.10.1", "c38d0ca52ea80254936a32c45bb7eb414e7a96a521b4ce76d00a69753b157f21", [:rebar3], [{:certifi, "2.0.0", [hex: :certifi, repo: "hexpm", optional: false]}, {:idna, "5.1.0", [hex: :idna, repo: "hexpm", optional: false]}, {:metrics, "1.0.1", [hex: :metrics, repo: "hexpm", optional: false]}, {:mimerl, "1.0.2", [hex: :mimerl, repo: "hexpm", optional: false]}, {:ssl_verify_fun, "1.1.1", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}], "hexpm"}, "idna": {:hex, :idna, "5.1.0", "d72b4effeb324ad5da3cab1767cb16b17939004e789d8c0ad5b70f3cea20c89a", [:rebar3], [{:unicode_util_compat, "0.3.1", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm"}, - "jsx": {:hex, :jsx, "2.8.2", "7acc7d785b5abe8a6e9adbde926a24e481f29956dd8b4df49e3e4e7bcc92a018", [:mix, :rebar3], [], "hexpm"}, + "jsx": {:hex, :jsx, "2.8.3", "a05252d381885240744d955fbe3cf810504eb2567164824e19303ea59eef62cf", [:mix, :rebar3], [], "hexpm"}, "metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [:rebar3], [], "hexpm"}, "mimerl": {:hex, :mimerl, "1.0.2", "993f9b0e084083405ed8252b99460c4f0563e41729ab42d9074fd5e52439be88", [:rebar3], [], "hexpm"}, "poison": {:hex, :poison, "3.1.0", "d9eb636610e096f86f25d9a46f35a9facac35609a7591b3be3326e99a0484665", [:mix], [], "hexpm"}, diff --git a/package.json b/package.json index 1b4d76ef..e1e114c9 100644 --- a/package.json +++ b/package.json @@ -23,7 +23,6 @@ "author": "", "license": "MIT", "dependencies": { - "chalk": "^2.3.0", "erlang-types": "^1.0.1", "grapheme-splitter": "^1.0.2", "rollup-plugin-commonjs": "^8.2.1", diff --git a/priv/testrunner/vendor.build.js b/priv/testrunner/vendor.build.js index 65b2d07d..9d49e34d 100644 --- a/priv/testrunner/vendor.build.js +++ b/priv/testrunner/vendor.build.js @@ -1,66 +1,2 @@ -import os from'os';class Tuple{constructor(...a){this.values=Object.freeze(a),this.length=this.values.length}get(a){return this.values[a]}count(){return this.values.length}[Symbol.iterator](){return this.values[Symbol.iterator]()}toString(){let a,b='';for(a=0;a'}}let ref_counter=-1;class Reference{constructor(){++ref_counter,this.id=ref_counter,this.ref=Symbol()}toString(){return'Ref#<0.0.0.'+this.id+'>'}}class BitString{constructor(...a){this.value=Object.freeze(this.process(a)),this.length=this.value.length,this.bit_size=8*this.length,this.byte_size=this.length}get(a){return this.value[a]}count(){return this.value.length}slice(a,b=null){let c=this.value.slice(a,b),d=c.map((a)=>BitString.integer(a));return new BitString(...d)}[Symbol.iterator](){return this.value[Symbol.iterator]()}toString(){var a,b='';for(a=0;a>'}process(a){let b=[];var c;for(c=0;cb?c.push(b):2048>b?c.push(192|b>>6,128|63&b):55296>b||57344<=b?c.push(224|b>>12,128|63&b>>6,128|63&b):(d++,b=65536+((1023&b)<<10|1023&a.charCodeAt(d)),c.push(240|b>>18,128|63&b>>12,128|63&b>>6,128|63&b));return c}static toUTF16Array(a){for(var b,c=[],d=0;d=b?(c.push(0),c.push(b)):(c.push(255&b>>8),c.push(255&b));return c}static toUTF32Array(a){for(var b,c=[],d=0;d=b?(c.push(0),c.push(0),c.push(0),c.push(b)):(c.push(0),c.push(0),c.push(255&b>>8),c.push(255&b));return c}//http://stackoverflow.com/questions/2003493/javascript-float-from-to-bits -static float32ToBytes(a){var b=[],c=new ArrayBuffer(4);new Float32Array(c)[0]=a;let d=new Uint32Array(c)[0];return b.push(255&d>>24),b.push(255&d>>16),b.push(255&d>>8),b.push(255&d),b}static float64ToBytes(a){var b=[],c=new ArrayBuffer(8);new Float64Array(c)[0]=a;var d=new Uint32Array(c)[0],e=new Uint32Array(c)[1];return b.push(255&e>>24),b.push(255&e>>16),b.push(255&e>>8),b.push(255&e),b.push(255&d>>24),b.push(255&d>>16),b.push(255&d>>8),b.push(255&d),b}}var ErlangTypes={Tuple,PID,Reference,BitString};function createCommonjsModule(a,b){return b={exports:{}},a(b,b.exports),b.exports}var matchOperatorsRe=/[|\\{}()[\]^$+*?.]/g,escapeStringRegexp=function(a){if('string'!=typeof a)throw new TypeError('Expected a string');return a.replace(matchOperatorsRe,'\\$&')},colorName={aliceblue:[240,248,255],antiquewhite:[250,235,215],aqua:[0,255,255],aquamarine:[127,255,212],azure:[240,255,255],beige:[245,245,220],bisque:[255,228,196],black:[0,0,0],blanchedalmond:[255,235,205],blue:[0,0,255],blueviolet:[138,43,226],brown:[165,42,42],burlywood:[222,184,135],cadetblue:[95,158,160],chartreuse:[127,255,0],chocolate:[210,105,30],coral:[255,127,80],cornflowerblue:[100,149,237],cornsilk:[255,248,220],crimson:[220,20,60],cyan:[0,255,255],darkblue:[0,0,139],darkcyan:[0,139,139],darkgoldenrod:[184,134,11],darkgray:[169,169,169],darkgreen:[0,100,0],darkgrey:[169,169,169],darkkhaki:[189,183,107],darkmagenta:[139,0,139],darkolivegreen:[85,107,47],darkorange:[255,140,0],darkorchid:[153,50,204],darkred:[139,0,0],darksalmon:[233,150,122],darkseagreen:[143,188,143],darkslateblue:[72,61,139],darkslategray:[47,79,79],darkslategrey:[47,79,79],darkturquoise:[0,206,209],darkviolet:[148,0,211],deeppink:[255,20,147],deepskyblue:[0,191,255],dimgray:[105,105,105],dimgrey:[105,105,105],dodgerblue:[30,144,255],firebrick:[178,34,34],floralwhite:[255,250,240],forestgreen:[34,139,34],fuchsia:[255,0,255],gainsboro:[220,220,220],ghostwhite:[248,248,255],gold:[255,215,0],goldenrod:[218,165,32],gray:[128,128,128],green:[0,128,0],greenyellow:[173,255,47],grey:[128,128,128],honeydew:[240,255,240],hotpink:[255,105,180],indianred:[205,92,92],indigo:[75,0,130],ivory:[255,255,240],khaki:[240,230,140],lavender:[230,230,250],lavenderblush:[255,240,245],lawngreen:[124,252,0],lemonchiffon:[255,250,205],lightblue:[173,216,230],lightcoral:[240,128,128],lightcyan:[224,255,255],lightgoldenrodyellow:[250,250,210],lightgray:[211,211,211],lightgreen:[144,238,144],lightgrey:[211,211,211],lightpink:[255,182,193],lightsalmon:[255,160,122],lightseagreen:[32,178,170],lightskyblue:[135,206,250],lightslategray:[119,136,153],lightslategrey:[119,136,153],lightsteelblue:[176,196,222],lightyellow:[255,255,224],lime:[0,255,0],limegreen:[50,205,50],linen:[250,240,230],magenta:[255,0,255],maroon:[128,0,0],mediumaquamarine:[102,205,170],mediumblue:[0,0,205],mediumorchid:[186,85,211],mediumpurple:[147,112,219],mediumseagreen:[60,179,113],mediumslateblue:[123,104,238],mediumspringgreen:[0,250,154],mediumturquoise:[72,209,204],mediumvioletred:[199,21,133],midnightblue:[25,25,112],mintcream:[245,255,250],mistyrose:[255,228,225],moccasin:[255,228,181],navajowhite:[255,222,173],navy:[0,0,128],oldlace:[253,245,230],olive:[128,128,0],olivedrab:[107,142,35],orange:[255,165,0],orangered:[255,69,0],orchid:[218,112,214],palegoldenrod:[238,232,170],palegreen:[152,251,152],paleturquoise:[175,238,238],palevioletred:[219,112,147],papayawhip:[255,239,213],peachpuff:[255,218,185],peru:[205,133,63],pink:[255,192,203],plum:[221,160,221],powderblue:[176,224,230],purple:[128,0,128],rebeccapurple:[102,51,153],red:[255,0,0],rosybrown:[188,143,143],royalblue:[65,105,225],saddlebrown:[139,69,19],salmon:[250,128,114],sandybrown:[244,164,96],seagreen:[46,139,87],seashell:[255,245,238],sienna:[160,82,45],silver:[192,192,192],skyblue:[135,206,235],slateblue:[106,90,205],slategray:[112,128,144],slategrey:[112,128,144],snow:[255,250,250],springgreen:[0,255,127],steelblue:[70,130,180],tan:[210,180,140],teal:[0,128,128],thistle:[216,191,216],tomato:[255,99,71],turquoise:[64,224,208],violet:[238,130,238],wheat:[245,222,179],white:[255,255,255],whitesmoke:[245,245,245],yellow:[255,255,0],yellowgreen:[154,205,50]},conversions=createCommonjsModule(function(a){/** - * See https://en.m.wikipedia.org/wiki/Euclidean_distance#Squared_Euclidean_distance - * */function comparativeDistance(a,b){return f(a[0]-b[0],2)+f(a[1]-b[1],2)+f(a[2]-b[2],2)}var c=Math.round,d=Math.PI,e=Math.floor,f=Math.pow,i=Math.max,j=Math.min,b={};/* MIT license */// NOTE: conversions should only return primitive values (i.e. arrays, or -// values that give correct `typeof` results). -// do not use box values types (i.e. Number(), String(), etc.) -for(var g in colorName)colorName.hasOwnProperty(g)&&(b[colorName[g]]=g);var k=a.exports={rgb:{channels:3,labels:'rgb'},hsl:{channels:3,labels:'hsl'},hsv:{channels:3,labels:'hsv'},hwb:{channels:3,labels:'hwb'},cmyk:{channels:4,labels:'cmyk'},xyz:{channels:3,labels:'xyz'},lab:{channels:3,labels:'lab'},lch:{channels:3,labels:'lch'},hex:{channels:1,labels:['hex']},keyword:{channels:1,labels:['keyword']},ansi16:{channels:1,labels:['ansi16']},ansi256:{channels:1,labels:['ansi256']},hcg:{channels:3,labels:['h','c','g']},apple:{channels:3,labels:['r16','g16','b16']},gray:{channels:1,labels:['gray']}};// hide .channels and .labels properties -for(var h in k)if(k.hasOwnProperty(h)){if(!('channels'in k[h]))throw new Error('missing channels property: '+h);if(!('labels'in k[h]))throw new Error('missing channel labels property: '+h);if(k[h].labels.length!==k[h].channels)throw new Error('channel and label counts mismatch: '+h);var l=k[h].channels,m=k[h].labels;delete k[h].channels,delete k[h].labels,Object.defineProperty(k[h],'channels',{value:l}),Object.defineProperty(k[h],'labels',{value:m})}k.rgb.hsl=function(a){var c,d,e,f=a[0]/255,h=a[1]/255,g=a[2]/255,b=j(f,h,g),k=i(f,h,g),l=k-b;return k===b?c=0:f===k?c=(h-g)/l:h===k?c=2+(g-f)/l:g===k&&(c=4+(f-h)/l),c=j(60*c,360),0>c&&(c+=360),e=(b+k)/2,d=k===b?0:0.5>=e?l/(k+b):l/(2-k-b),[c,100*d,100*e]},k.rgb.hsv=function(a){var c,d,e,f=a[0],h=a[1],g=a[2],b=j(f,h,g),k=i(f,h,g),l=k-b;return d=0===k?0:1e3*(l/k)/10,k===b?c=0:f===k?c=(h-g)/l:h===k?c=2+(g-f)/l:g===k&&(c=4+(f-h)/l),c=j(60*c,360),0>c&&(c+=360),e=1e3*(k/255)/10,[c,d,e]},k.rgb.hwb=function(a){var c=a[0],d=a[1],e=a[2],b=k.rgb.hsl(a)[0],f=1/255*j(c,j(d,e));return e=1-1/255*i(c,i(d,e)),[b,100*f,100*e]},k.rgb.cmyk=function(a){var d,c,e,f,h=a[0]/255,i=a[1]/255,g=a[2]/255;return f=j(1-h,1-i,1-g),d=(1-h-f)/(1-f)||0,c=(1-i-f)/(1-f)||0,e=(1-g-f)/(1-f)||0,[100*d,100*c,100*e,100*f]},k.rgb.keyword=function(a){var c=b[a];if(c)return c;var d,e=Infinity;for(var f in colorName)if(colorName.hasOwnProperty(f)){var g=colorName[f],h=comparativeDistance(a,g);// Compute comparative distance -// Check if its less, if so set as closest -hj?j*(1+h):j+h-j*h,b=2*j-c,e=[0,0,0];for(var k=0;3>k;k++)d=g+1/3*-(k-1),0>d&&d++,16*d?b+6*(c-b)*d:1>2*d?c:2>3*d?b+6*((c-b)*(2/3-d)):b,e[k]=255*f;return e},k.hsl.hsv=function(a){var b,c,d=a[0],e=a[1]/100,f=a[2]/100,g=e,h=i(f,0.01);return f*=2,e*=1>=f?f:2-f,g*=1>=h?h:2-h,c=(f+e)/2,b=0==f?2*g/(h+g):2*e/(f+e),[d,100*b,100*c]},k.hsv.rgb=function(a){var b=a[0]/60,c=a[1]/100,d=a[2]/100,g=e(b)%6,h=b-e(b),f=255*d*(1-c),i=255*d*(1-c*h),j=255*d*(1-c*(1-h));return d*=255,0==g?[d,j,f]:1==g?[i,d,f]:2==g?[f,d,j]:3==g?[f,i,d]:4==g?[j,f,d]:5==g?[d,f,i]:void 0},k.hsv.hsl=function(a){var b,c,d,e=a[0],f=a[1]/100,g=a[2]/100,h=i(g,0.01);return d=(2-f)*g,b=(2-f)*h,c=f*h,c/=1>=b?b:2-b,c=c||0,d/=2,[e,100*c,100*d]},k.hwb.rgb=function(a){var c,d,i,f,j=a[0]/360,h=a[1]/100,k=a[2]/100,l=h+k;// wh + bl cant be > 1 -1g&&(g+=360),h=Math.sqrt(i*i+a*a),[c,h,g]},k.lch.lab=function(e){var f,a,b,g=e[0],i=e[1],c=e[2];return b=2*(c/360)*d,f=i*Math.cos(b),a=i*Math.sin(b),[g,f,a]},k.rgb.ansi16=function(a){var d=a[0],e=a[1],f=a[2],b=1 in arguments?arguments[1]:k.rgb.hsv(a)[2];// hsv -> ansi16 optimization -if(b=c(b/50),0===b)return 30;var g=30+(c(f/255)<<2|c(e/255)<<1|c(d/255));return 2===b&&(g+=60),g},k.hsv.ansi16=function(a){// optimization here; we already know the value and don't need to get -// it converted for us. -return k.rgb.ansi16(k.hsv.rgb(a),a[2])},k.rgb.ansi256=function(a){var d=a[0],e=a[1],f=a[2];// we use the extended greyscale palette here, with the exception of -// black and white. normal palette only has 4 greyscale shades. -if(d===e&&e===f)return 8>d?16:248>1)*d),g=255*((1&c>>2)*d);return[e,f,g]},k.ansi256.rgb=function(a){// handle greyscale -if(232<=a){var d=10*(a-232)+8;return[d,d,d]}a-=16;var c,f=255*(e(a/36)/5),h=255*(e((c=a%36)/6)/5),g=255*(c%6/5);return[f,h,g]},k.rgb.hex=function(a){var b=((255&c(a[0]))<<16)+((255&c(a[1]))<<8)+(255&c(a[2])),d=b.toString(16).toUpperCase();return'000000'.substring(d.length)+d},k.hex.rgb=function(a){var b=a.toString(16).match(/[a-f0-9]{6}|[a-f0-9]{3}/i);if(!b)return[0,0,0];var c=b[0];3===b[0].length&&(c=c.split('').map(function(a){return a+a}).join(''));var d=parseInt(c,16);return[255&d>>16,255&d>>8,255&d]},k.rgb.hcg=function(a){var c,d,e=a[0]/255,f=a[1]/255,g=a[2]/255,b=i(i(e,f),g),h=j(j(e,f),g),k=b-h;return c=1>k?h/(1-k):0,d=0>=k?0:b===e?(f-g)/k%6:b===f?2+(g-e)/k:4+(e-f)/k+4,d/=6,d%=1,[360*d,100*k,100*c]},k.hsl.hcg=function(a){var b=a[1]/100,d=a[2]/100,e=1,c=0;return e=0.5>d?2*b*d:2*b*(1-d),1>e&&(c=(d-0.5*e)/(1-e)),[a[0],100*e,100*c]},k.hsv.hcg=function(a){var b=a[1]/100,d=a[2]/100,e=b*d,c=0;return 1>e&&(c=(d-e)/(1-e)),[a[0],100*e,100*c]},k.hcg.rgb=function(a){var b=a[0]/360,d=a[1]/100,c=a[2]/100;if(0==d)return[255*c,255*c,255*c];var f=[0,0,0],g=6*(b%1),h=g%1,i=1-h,j=0;switch(e(g)){case 0:f[0]=1,f[1]=h,f[2]=0;break;case 1:f[0]=i,f[1]=1,f[2]=0;break;case 2:f[0]=0,f[1]=1,f[2]=h;break;case 3:f[0]=0,f[1]=i,f[2]=1;break;case 4:f[0]=h,f[1]=0,f[2]=1;break;default:f[0]=1,f[1]=0,f[2]=i;}return j=(1-d)*c,[255*(d*f[0]+j),255*(d*f[1]+j),255*(d*f[2]+j)]},k.hcg.hsv=function(a){var b=a[1]/100,c=a[2]/100,d=b+c*(1-b),e=0;return 0d?e=b/(2*d):0.5<=d&&1>d&&(e=b/(2*(1-d))),[a[0],100*e,100*d]},k.hcg.hwb=function(a){var b=a[1]/100,c=a[2]/100,d=b+c*(1-b);return[a[0],100*(d-b),100*(1-d)]},k.hwb.hcg=function(a){var d=a[1]/100,e=a[2]/100,b=1-e,f=b-d,c=0;return 1>f&&(c=(b-f)/(1-f)),[a[0],100*f,100*c]},k.apple.rgb=function(a){return[255*(a[0]/65535),255*(a[1]/65535),255*(a[2]/65535)]},k.rgb.apple=function(a){return[65535*(a[0]/255),65535*(a[1]/255),65535*(a[2]/255)]},k.gray.rgb=function(a){return[255*(a[0]/100),255*(a[0]/100),255*(a[0]/100)]},k.gray.hsl=k.gray.hsv=function(a){return[0,0,a[0]]},k.gray.hwb=function(a){return[0,100,a[0]]},k.gray.cmyk=function(a){return[0,0,0,a[0]]},k.gray.lab=function(a){return[a[0],0,0]},k.gray.hex=function(a){var b=255&c(255*(a[0]/100)),d=((b<<16)+(b<<8)+b).toString(16).toUpperCase();return'000000'.substring(d.length)+d},k.rgb.gray=function(a){var b=(a[0]+a[1]+a[2])/3;return[100*(b/255)]}}),models$1=Object.keys(conversions);/* - this function routes a model to all other models. - - all functions that are routed have a property `.conversion` attached - to the returned synthetic function. This property is an array - of strings, each with the steps in between the 'from' and 'to' - color models (inclusive). - - conversions that are not possible simply are not included. -*/// https://jsperf.com/object-keys-vs-for-in-with-closure/3 -function buildGraph(){for(var a={},b=models$1.length,c=0;c queue -> pop -for(b[a].distance=0;c.length;)for(var d=c.pop(),e=Object.keys(conversions[d]),f=e.length,g=0;gfunction(){const c=a.apply(colorConvert,arguments);return`\u001B[${c+b}m`},c=(a,b)=>function(){const c=a.apply(colorConvert,arguments);return`\u001B[${38+b};5;${c}m`},d=(a,b)=>function(){const c=a.apply(colorConvert,arguments);return`\u001B[${38+b};2;${c[0]};${c[1]};${c[2]}m`};Object.defineProperty(a,'exports',{enumerable:!0,get:function assembleStyles(){const a={modifier:{reset:[0,0],// 21 isn't widely supported and 22 does the same thing -bold:[1,22],dim:[2,22],italic:[3,23],underline:[4,24],inverse:[7,27],hidden:[8,28],strikethrough:[9,29]},color:{black:[30,39],red:[31,39],green:[32,39],yellow:[33,39],blue:[34,39],magenta:[35,39],cyan:[36,39],white:[37,39],gray:[90,39],// Bright color -redBright:[91,39],greenBright:[92,39],yellowBright:[93,39],blueBright:[94,39],magentaBright:[95,39],cyanBright:[96,39],whiteBright:[97,39]},bgColor:{bgBlack:[40,49],bgRed:[41,49],bgGreen:[42,49],bgYellow:[43,49],bgBlue:[44,49],bgMagenta:[45,49],bgCyan:[46,49],bgWhite:[47,49],// Bright color -bgBlackBright:[100,49],bgRedBright:[101,49],bgGreenBright:[102,49],bgYellowBright:[103,49],bgBlueBright:[104,49],bgMagentaBright:[105,49],bgCyanBright:[106,49],bgWhiteBright:[107,49]}};// Fix humans -a.color.grey=a.color.gray,Object.keys(a).forEach((b)=>{const c=a[b];Object.keys(c).forEach((b)=>{const d=c[b];a[b]={open:`\u001B[${d[0]}m`,close:`\u001B[${d[1]}m`},c[b]=a[b]}),Object.defineProperty(a,b,{value:c,enumerable:!1})});const e=(a,c,d)=>[a,c,d];a.color.close='\x1B[39m',a.bgColor.close='\x1B[49m',a.color.ansi={},a.color.ansi256={},a.color.ansi16m={rgb:d(e,0)},a.bgColor.ansi={},a.bgColor.ansi256={},a.bgColor.ansi16m={rgb:d(e,10)};for(const e of Object.keys(colorConvert)){if('object'!=typeof colorConvert[e])continue;const f=colorConvert[e];'ansi16'in f&&(a.color.ansi[e]=b(f.ansi16,0),a.bgColor.ansi[e]=b(f.ansi16,10)),'ansi256'in f&&(a.color.ansi256[e]=c(f.ansi256,0),a.bgColor.ansi256[e]=c(f.ansi256,10)),'rgb'in f&&(a.color.ansi16m[e]=d(f.rgb,0),a.bgColor.ansi16m[e]=d(f.rgb,10))}return a}})});var hasFlag=function(a,b){b=b||process.argv;var c=b.indexOf('--'),d=/^-{1,2}/.test(a)?'':'--',e=b.indexOf(d+a);return-1!==e&&(!(-1!==c)||e{if(hasFlag('no-color')||hasFlag('no-colors')||hasFlag('color=false'))return 0;if(hasFlag('color=16m')||hasFlag('color=full')||hasFlag('color=truecolor'))return 3;if(hasFlag('color=256'))return 2;if(hasFlag('color')||hasFlag('colors')||hasFlag('color=true')||hasFlag('color=always'))return 1;if(process.stdout&&!process.stdout.isTTY)return 0;if('win32'===process.platform){// Node.js 7.5.0 is the first version of Node.js to include a patch to -// libuv that enables 256 color output on Windows. Anything earlier and it -// won't work. However, here we target Node.js 8 at minimum as it is an LTS -// release, and Node.js 7 is not. Windows 10 build 10586 is the first Windows -// release that supports 256 colors. -const a=os.release().split('.');return 8<=+process.version.split('.')[0]&&10<=+a[0]&&10586<=+a[2]?2:1}if('CI'in b)return'TRAVIS'in b||'Travis'===b.CI||'CIRCLECI'in b?1:0;if('TEAMCITY_VERSION'in b)return /^(9\.(0*[1-9]\d*)\.|\d{2,}\.)/.test(b.TEAMCITY_VERSION)?1:0;if('TERM_PROGRAM'in b){const a=parseInt((b.TERM_PROGRAM_VERSION||'').split('.')[0],10);switch(b.TERM_PROGRAM){case'iTerm.app':return 3<=a?3:2;case'Hyper':return 3;case'Apple_Terminal':return 2;// No default -}}return /^(screen|xterm)-256(?:color)?/.test(b.TERM)?2:/^screen|^xterm|^vt100|color|ansi|cygwin|linux/i.test(b.TERM)?1:'COLORTERM'in b?1:'dumb'===b.TERM?0:0})();'FORCE_COLOR'in b&&(c=0===parseInt(b.FORCE_COLOR,10)?0:c||1),a.exports=process&&((a)=>0!==a&&{level:a,hasBasic:!0,has256:2<=a,has16m:3<=a})(c)}),templates=createCommonjsModule(function(a){'use strict';function unescape(a){return'u'===a[0]&&5===a.length||'x'===a[0]&&3===a.length?String.fromCharCode(parseInt(a.slice(1),16)):f.get(a)||a}function parseArguments(a,b){const c=[],f=b.trim().split(/\s*,\s*/g);let g;for(const h of f)if(!isNaN(h))c.push(+h);else if(g=h.match(d))c.push(g[2].replace(e,(a,b,c)=>b?unescape(b):c));else throw new Error(`Invalid Chalk template style argument: ${h} (in style '${a}')`);return c}function parseStyle(a){c.lastIndex=0;const b=[];for(let d;null!==(d=c.exec(a));){const a=d[1];if(d[2]){const c=parseArguments(a,d[2]);b.push([a].concat(c))}else b.push([a])}return b}function buildStyle(a,b){const c={};for(const d of b)for(const a of d.styles)c[a[0]]=d.inverse?null:a.slice(1);let d=a;for(const e of Object.keys(c))if(Array.isArray(c[e])){if(!(e in d))throw new Error(`Unknown Chalk style: ${e}`);d=0{const d=[],e=[];let f=[];// eslint-disable-next-line max-params -if(c.replace(b,(b,c,g,h,i,j)=>{if(c)f.push(unescape(c));else if(h){const b=f.join('');f=[],e.push(0===d.length?b:buildStyle(a,d)(b)),d.push({inverse:g,styles:parseStyle(h)})}else if(i){if(0===d.length)throw new Error('Found extraneous } in Chalk template literal');e.push(buildStyle(a,d)(f.join(''))),f=[],d.pop()}else f.push(j)}),e.push(f.join('')),0=this.level||!e)return this._empty?'':e;// Turns out that on Windows dimmed gray text becomes invisible in cmd.exe, -// see https://github.com/chalk/chalk/issues/58 -// If we're on Windows and we're dealing with a gray color, temporarily make 'dim' a noop. -const a=ansiStyles.dim.open;b&&this.hasGrey&&(ansiStyles.dim.open='');for(const a of this._styles.slice().reverse())e=a.open+e.replace(a.closeRe,a.open)+a.close,e=e.replace(/\r?\n/g,`${a.close}$&${a.open}`);// Reset the original `dim` if we changed it to work around the Windows dimmed gray issue -return ansiStyles.dim.open=a,e}function chalkTag(a,b){if(!Array.isArray(b))// If chalk() was called by itself or with a string, -// return the string itself as a string. -return[].slice.call(arguments,1).join(' ');const c=[].slice.call(arguments,2),d=[b.raw[0]];for(let e=1;e{},e);Object.defineProperties(Chalk.prototype,e),a.exports=Chalk(),a.exports.supportsColor=supportsColor,a.exports.default=a.exports}// For TypeScript -),vendor={ErlangTypes,Chalk:chalk};export default vendor; +class Tuple{constructor(...a){this.values=Object.freeze(a),this.length=this.values.length}get(a){return this.values[a]}count(){return this.values.length}[Symbol.iterator](){return this.values[Symbol.iterator]()}toString(){let a,b='';for(a=0;a'}}let ref_counter=-1;class Reference{constructor(){++ref_counter,this.id=ref_counter,this.ref=Symbol()}toString(){return'Ref#<0.0.0.'+this.id+'>'}}class BitString{constructor(...a){this.value=Object.freeze(this.process(a)),this.length=this.value.length,this.bit_size=8*this.length,this.byte_size=this.length}get(a){return this.value[a]}count(){return this.value.length}slice(a,b=null){let c=this.value.slice(a,b),d=c.map((a)=>BitString.integer(a));return new BitString(...d)}[Symbol.iterator](){return this.value[Symbol.iterator]()}toString(){var a,b='';for(a=0;a>'}process(a){let b=[];var c;for(c=0;cb?c.push(b):2048>b?c.push(192|b>>6,128|63&b):55296>b||57344<=b?c.push(224|b>>12,128|63&b>>6,128|63&b):(d++,b=65536+((1023&b)<<10|1023&a.charCodeAt(d)),c.push(240|b>>18,128|63&b>>12,128|63&b>>6,128|63&b));return c}static toUTF16Array(a){for(var b,c=[],d=0;d=b?(c.push(0),c.push(b)):(c.push(255&b>>8),c.push(255&b));return c}static toUTF32Array(a){for(var b,c=[],d=0;d=b?(c.push(0),c.push(0),c.push(0),c.push(b)):(c.push(0),c.push(0),c.push(255&b>>8),c.push(255&b));return c}//http://stackoverflow.com/questions/2003493/javascript-float-from-to-bits +static float32ToBytes(a){var b=[],c=new ArrayBuffer(4);new Float32Array(c)[0]=a;let d=new Uint32Array(c)[0];return b.push(255&d>>24),b.push(255&d>>16),b.push(255&d>>8),b.push(255&d),b}static float64ToBytes(a){var b=[],c=new ArrayBuffer(8);new Float64Array(c)[0]=a;var d=new Uint32Array(c)[0],e=new Uint32Array(c)[1];return b.push(255&e>>24),b.push(255&e>>16),b.push(255&e>>8),b.push(255&e),b.push(255&d>>24),b.push(255&d>>16),b.push(255&d>>8),b.push(255&d),b}}var ErlangTypes={Tuple,PID,Reference,BitString},vendor={ErlangTypes};export default vendor; diff --git a/priv/testrunner/vendor.js b/priv/testrunner/vendor.js index 7e3cd354..1d79bd80 100644 --- a/priv/testrunner/vendor.js +++ b/priv/testrunner/vendor.js @@ -1,7 +1,5 @@ import ErlangTypes from 'erlang-types'; -import Chalk from 'chalk'; export default { ErlangTypes, - Chalk, }; diff --git a/yarn.lock b/yarn.lock index ec2b01e5..9aec577d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1264,14 +1264,6 @@ chalk@^2.1.0: escape-string-regexp "^1.0.5" supports-color "^4.0.0" -chalk@^2.3.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.3.0.tgz#b5ea48efc9c1793dccc9b4767c93914d3f2d52ba" - dependencies: - ansi-styles "^3.1.0" - escape-string-regexp "^1.0.5" - supports-color "^4.0.0" - chokidar@^1.4.2: version "1.7.0" resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-1.7.0.tgz#798e689778151c8076b4b360e5edd28cda2bb468" From eedcd41f51cbfcb865c2ccfc9bd0386ef989b9e5 Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Sat, 28 Oct 2017 16:21:46 -0500 Subject: [PATCH 354/418] Increase timeout length on async_stream calls --- lib/elixir_script/passes/output.ex | 2 +- lib/elixir_script/passes/translate.ex | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/elixir_script/passes/output.ex b/lib/elixir_script/passes/output.ex index ce6ad187..baaf05ba 100644 --- a/lib/elixir_script/passes/output.ex +++ b/lib/elixir_script/passes/output.ex @@ -66,7 +66,7 @@ defmodule ElixirScript.Output do |> Generator.generate |> concat |> output(module, Map.get(opts, :output), js_modules) - end) + end, timeout: 10_000) |> Stream.map(fn {:ok, code} -> code end) |> Enum.to_list() end diff --git a/lib/elixir_script/passes/translate.ex b/lib/elixir_script/passes/translate.ex index 45f29204..0b6490fc 100644 --- a/lib/elixir_script/passes/translate.ex +++ b/lib/elixir_script/passes/translate.ex @@ -13,7 +13,7 @@ defmodule ElixirScript.Translate do |> Task.async_stream(fn {module, info} -> ElixirScript.Translate.Module.compile(module, info, pid) - end) + end, timeout: 10_000) |> Stream.run() end end From f39d2cafaa7eda60e6439282a3d1d9a8fbded3ad Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Sun, 29 Oct 2017 23:15:49 -0500 Subject: [PATCH 355/418] Updates to make sure try works correctly --- lib/elixir_script/passes/find_used_modules.ex | 5 +- .../passes/translate/forms/try.ex | 22 +- priv/testrunner/testRunner.js | 6 +- priv/testrunner/vendor.build.js | 406 +++++++++++++++++- src/javascript/lib/core/functions.js | 5 +- src/javascript/lib/core/special_forms.js | 1 - src/javascript/tests/try.spec.js | 3 +- test_elixir_script/try_test.exs | 48 +++ 8 files changed, 485 insertions(+), 11 deletions(-) create mode 100644 test_elixir_script/try_test.exs diff --git a/lib/elixir_script/passes/find_used_modules.ex b/lib/elixir_script/passes/find_used_modules.ex index 5b33127a..ae75d9e6 100644 --- a/lib/elixir_script/passes/find_used_modules.ex +++ b/lib/elixir_script/passes/find_used_modules.ex @@ -225,6 +225,8 @@ defmodule ElixirScript.FindUsedModules do end defp walk({:try, _, [blocks]}, state) do + walk(Enum, state) + try_block = Keyword.get(blocks, :do) rescue_block = Keyword.get(blocks, :rescue, nil) catch_block = Keyword.get(blocks, :catch, nil) @@ -236,7 +238,8 @@ defmodule ElixirScript.FindUsedModules do if rescue_block do Enum.each(rescue_block, fn {:->, _, [ [{:in, _, [param, names]}], body]} -> - walk({[], [param], [{{:., [], [Enum, :member?]}, [], [param, names]}], body}, state) + Enum.each(names, &walk(&1, state)) + walk({[], [param], [{{:., [], [Enum, :member?]}, [], [names, param]}], body}, state) {:->, _, [ [param], body]} -> walk({[], [param], [], body}, state) end) diff --git a/lib/elixir_script/passes/translate/forms/try.ex b/lib/elixir_script/passes/translate/forms/try.ex index 249d8f9b..e086d310 100644 --- a/lib/elixir_script/passes/translate/forms/try.ex +++ b/lib/elixir_script/passes/translate/forms/try.ex @@ -58,8 +58,24 @@ defmodule ElixirScript.Translate.Forms.Try do defp process_rescue_block(rescue_block, state) do processed_clauses = Enum.map(rescue_block, fn + {:->, _, [ [{:in, _, [{:_, context, atom}, names]}], body]} -> + names = Enum.map(names, &make_exception_ast(&1)) + + param = {:_e, context, atom} + reasonCall = {{:., [], [{:_e0, context, atom}, :__reason]}, [], []} + reasonCall = {{:., [], [reasonCall, :__struct__]}, [], []} + reasonCall = {{:., [], [reasonCall, :__MODULE__]}, [], []} + + {ast, _} = Clause.compile({[], [param], [{{:., [], [Enum, :member?]}, [], [names, reasonCall]}], body}, state) + ast {:->, _, [ [{:in, _, [param, names]}], body]} -> - {ast, _} = Clause.compile({[], [param], [{{:., [], [Enum, :member?]}, [], [param, names]}], body}, state) + names = Enum.map(names, &make_exception_ast(&1)) + + reasonCall = {{:., [], [param, :__reason]}, [], []} + reasonCall = {{:., [], [reasonCall, :__struct__]}, [], []} + reasonCall = {{:., [], [reasonCall, :__MODULE__]}, [], []} + + {ast, _} = Clause.compile({[], [param], [{{:., [], [Enum, :member?]}, [], [names, reasonCall]}], body}, state) ast {:->, _, [ [param], body]} -> {ast, _} = Clause.compile({[], [param], [], body}, state) @@ -77,6 +93,10 @@ defmodule ElixirScript.Translate.Forms.Try do end + defp make_exception_ast(name) do + {{:., [], [name, :__MODULE__]}, [], []} + end + defp process_after_block(after_block, state) do translated_body = prepare_function_body(after_block, state) translated_body = JS.block_statement(translated_body) diff --git a/priv/testrunner/testRunner.js b/priv/testrunner/testRunner.js index b1856c5d..b3d1eca9 100644 --- a/priv/testrunner/testRunner.js +++ b/priv/testrunner/testRunner.js @@ -70,7 +70,7 @@ function runTests(mod, results) { if (result) { results.success++; } else { - resuls.failed++; + results.failed++; } } } @@ -80,7 +80,7 @@ function runTests(mod, results) { function runTest(mod, test, incomingContext, results) { const context = runSetup(mod, '__elixirscript_test_setup', incomingContext); - const testPassed = true; + let testPassed = true; try { test.get(Symbol.for('test'))(context); process.stdout.write(Colors.fg.Green + '.' + Colors.Reset); @@ -116,7 +116,7 @@ function handleError(e, test, results, mod) { } function printErrorLine(value, label = null) { - if (value !== Symbol.for('ex_unit_no_meaningful_value')) { + if (value && value !== Symbol.for('ex_unit_no_meaningful_value')) { if (label) { console.log(Colors.fg.Cyan, `${label}:`, Colors.Reset, `${value}`); } else { diff --git a/priv/testrunner/vendor.build.js b/priv/testrunner/vendor.build.js index 9d49e34d..6e808208 100644 --- a/priv/testrunner/vendor.build.js +++ b/priv/testrunner/vendor.build.js @@ -1,2 +1,404 @@ -class Tuple{constructor(...a){this.values=Object.freeze(a),this.length=this.values.length}get(a){return this.values[a]}count(){return this.values.length}[Symbol.iterator](){return this.values[Symbol.iterator]()}toString(){let a,b='';for(a=0;a'}}let ref_counter=-1;class Reference{constructor(){++ref_counter,this.id=ref_counter,this.ref=Symbol()}toString(){return'Ref#<0.0.0.'+this.id+'>'}}class BitString{constructor(...a){this.value=Object.freeze(this.process(a)),this.length=this.value.length,this.bit_size=8*this.length,this.byte_size=this.length}get(a){return this.value[a]}count(){return this.value.length}slice(a,b=null){let c=this.value.slice(a,b),d=c.map((a)=>BitString.integer(a));return new BitString(...d)}[Symbol.iterator](){return this.value[Symbol.iterator]()}toString(){var a,b='';for(a=0;a>'}process(a){let b=[];var c;for(c=0;cb?c.push(b):2048>b?c.push(192|b>>6,128|63&b):55296>b||57344<=b?c.push(224|b>>12,128|63&b>>6,128|63&b):(d++,b=65536+((1023&b)<<10|1023&a.charCodeAt(d)),c.push(240|b>>18,128|63&b>>12,128|63&b>>6,128|63&b));return c}static toUTF16Array(a){for(var b,c=[],d=0;d=b?(c.push(0),c.push(b)):(c.push(255&b>>8),c.push(255&b));return c}static toUTF32Array(a){for(var b,c=[],d=0;d=b?(c.push(0),c.push(0),c.push(0),c.push(b)):(c.push(0),c.push(0),c.push(255&b>>8),c.push(255&b));return c}//http://stackoverflow.com/questions/2003493/javascript-float-from-to-bits -static float32ToBytes(a){var b=[],c=new ArrayBuffer(4);new Float32Array(c)[0]=a;let d=new Uint32Array(c)[0];return b.push(255&d>>24),b.push(255&d>>16),b.push(255&d>>8),b.push(255&d),b}static float64ToBytes(a){var b=[],c=new ArrayBuffer(8);new Float64Array(c)[0]=a;var d=new Uint32Array(c)[0],e=new Uint32Array(c)[1];return b.push(255&e>>24),b.push(255&e>>16),b.push(255&e>>8),b.push(255&e),b.push(255&d>>24),b.push(255&d>>16),b.push(255&d>>8),b.push(255&d),b}}var ErlangTypes={Tuple,PID,Reference,BitString},vendor={ErlangTypes};export default vendor; +class Tuple { + constructor(...args) { + this.values = Object.freeze(args); + this.length = this.values.length; + } + + get(index) { + return this.values[index]; + } + + count() { + return this.values.length; + } + + [Symbol.iterator]() { + return this.values[Symbol.iterator](); + } + + toString() { + let i, + s = ''; + for (i = 0; i < this.values.length; i++) { + if (s !== '') { + s += ', '; + } + + const stringToAppend = this.values[i] ? this.values[i].toString() : ''; + + s += stringToAppend; + } + + return '{' + s + '}'; + } + + put_elem(index, elem) { + if (index === this.length) { + let new_values = this.values.concat([elem]); + return new Tuple(...new_values); + } + + let new_values = this.values.concat([]); + new_values.splice(index, 0, elem); + return new Tuple(...new_values); + } + + remove_elem(index) { + let new_values = this.values.concat([]); + new_values.splice(index, 1); + return new Tuple(...new_values); + } +} + +let process_counter = -1; + +class PID { + constructor() { + process_counter = process_counter + 1; + this.id = process_counter; + } + + toString() { + return 'PID#<0.' + this.id + '.0>'; + } +} + +let ref_counter = -1; + +class Reference { + constructor() { + ref_counter = ref_counter + 1; + this.id = ref_counter; + this.ref = Symbol(); + } + + toString() { + return 'Ref#<0.0.0.' + this.id + '>'; + } +} + +class BitString { + constructor(...args) { + this.value = Object.freeze(this.process(args)); + this.length = this.value.length; + this.bit_size = this.length * 8; + this.byte_size = this.length; + } + + get(index) { + return this.value[index]; + } + + count() { + return this.value.length; + } + + slice(start, end = null) { + let s = this.value.slice(start, end); + let ms = s.map(elem => BitString.integer(elem)); + return new BitString(...ms); + } + + [Symbol.iterator]() { + return this.value[Symbol.iterator](); + } + + toString() { + var i, + s = ''; + for (i = 0; i < this.count(); i++) { + if (s !== '') { + s += ', '; + } + s += this.get(i).toString(); + } + + return '<<' + s + '>>'; + } + + process(bitStringParts) { + let processed_values = []; + + var i; + for (i = 0; i < bitStringParts.length; i++) { + let processed_value = this['process_' + bitStringParts[i].type](bitStringParts[i]); + + for (let attr of bitStringParts[i].attributes) { + processed_value = this['process_' + attr](processed_value); + } + + processed_values = processed_values.concat(processed_value); + } + + return processed_values; + } + + process_integer(value) { + return value.value; + } + + process_float(value) { + if (value.size === 64) { + return BitString.float64ToBytes(value.value); + } else if (value.size === 32) { + return BitString.float32ToBytes(value.value); + } + + throw new Error('Invalid size for float'); + } + + process_bitstring(value) { + return value.value.value; + } + + process_binary(value) { + return BitString.toUTF8Array(value.value); + } + + process_utf8(value) { + return BitString.toUTF8Array(value.value); + } + + process_utf16(value) { + return BitString.toUTF16Array(value.value); + } + + process_utf32(value) { + return BitString.toUTF32Array(value.value); + } + + process_signed(value) { + return new Uint8Array([value])[0]; + } + + process_unsigned(value) { + return value; + } + + process_native(value) { + return value; + } + + process_big(value) { + return value; + } + + process_little(value) { + return value.reverse(); + } + + process_size(value) { + return value; + } + + process_unit(value) { + return value; + } + + static integer(value) { + return BitString.wrap(value, { type: 'integer', unit: 1, size: 8 }); + } + + static float(value) { + return BitString.wrap(value, { type: 'float', unit: 1, size: 64 }); + } + + static bitstring(value) { + return BitString.wrap(value, { + type: 'bitstring', + unit: 1, + size: value.bit_size + }); + } + + static bits(value) { + return BitString.bitstring(value); + } + + static binary(value) { + return BitString.wrap(value, { + type: 'binary', + unit: 8, + size: value.length + }); + } + + static bytes(value) { + return BitString.binary(value); + } + + static utf8(value) { + return BitString.wrap(value, { type: 'utf8', unit: 1, size: value.length }); + } + + static utf16(value) { + return BitString.wrap(value, { + type: 'utf16', + unit: 1, + size: value.length * 2 + }); + } + + static utf32(value) { + return BitString.wrap(value, { + type: 'utf32', + unit: 1, + size: value.length * 4 + }); + } + + static signed(value) { + return BitString.wrap(value, {}, 'signed'); + } + + static unsigned(value) { + return BitString.wrap(value, {}, 'unsigned'); + } + + static native(value) { + return BitString.wrap(value, {}, 'native'); + } + + static big(value) { + return BitString.wrap(value, {}, 'big'); + } + + static little(value) { + return BitString.wrap(value, {}, 'little'); + } + + static size(value, count) { + return BitString.wrap(value, { size: count }); + } + + static unit(value, count) { + return BitString.wrap(value, { unit: count }); + } + + static wrap(value, opt, new_attribute = null) { + let the_value = value; + + if (!(value instanceof Object)) { + the_value = { value: value, attributes: [] }; + } + + the_value = Object.assign(the_value, opt); + + if (new_attribute) { + the_value.attributes.push(new_attribute); + } + + return the_value; + } + + static toUTF8Array(str) { + var utf8 = []; + for (var i = 0; i < str.length; i++) { + var charcode = str.charCodeAt(i); + if (charcode < 0x80) { + utf8.push(charcode); + } else if (charcode < 0x800) { + utf8.push(0xc0 | charcode >> 6, 0x80 | charcode & 0x3f); + } else if (charcode < 0xd800 || charcode >= 0xe000) { + utf8.push(0xe0 | charcode >> 12, 0x80 | charcode >> 6 & 0x3f, 0x80 | charcode & 0x3f); + } else { + // surrogate pair + i++; + // UTF-16 encodes 0x10000-0x10FFFF by + // subtracting 0x10000 and splitting the + // 20 bits of 0x0-0xFFFFF into two halves + charcode = 0x10000 + ((charcode & 0x3ff) << 10 | str.charCodeAt(i) & 0x3ff); + utf8.push(0xf0 | charcode >> 18, 0x80 | charcode >> 12 & 0x3f, 0x80 | charcode >> 6 & 0x3f, 0x80 | charcode & 0x3f); + } + } + return utf8; + } + + static toUTF16Array(str) { + var utf16 = []; + for (var i = 0; i < str.length; i++) { + var codePoint = str.codePointAt(i); + + if (codePoint <= 255) { + utf16.push(0); + utf16.push(codePoint); + } else { + utf16.push(codePoint >> 8 & 0xff); + utf16.push(codePoint & 0xff); + } + } + return utf16; + } + + static toUTF32Array(str) { + var utf32 = []; + for (var i = 0; i < str.length; i++) { + var codePoint = str.codePointAt(i); + + if (codePoint <= 255) { + utf32.push(0); + utf32.push(0); + utf32.push(0); + utf32.push(codePoint); + } else { + utf32.push(0); + utf32.push(0); + utf32.push(codePoint >> 8 & 0xff); + utf32.push(codePoint & 0xff); + } + } + return utf32; + } + + //http://stackoverflow.com/questions/2003493/javascript-float-from-to-bits + static float32ToBytes(f) { + var bytes = []; + + var buf = new ArrayBuffer(4); + new Float32Array(buf)[0] = f; + + let intVersion = new Uint32Array(buf)[0]; + + bytes.push(intVersion >> 24 & 0xff); + bytes.push(intVersion >> 16 & 0xff); + bytes.push(intVersion >> 8 & 0xff); + bytes.push(intVersion & 0xff); + + return bytes; + } + + static float64ToBytes(f) { + var bytes = []; + + var buf = new ArrayBuffer(8); + new Float64Array(buf)[0] = f; + + var intVersion1 = new Uint32Array(buf)[0]; + var intVersion2 = new Uint32Array(buf)[1]; + + bytes.push(intVersion2 >> 24 & 0xff); + bytes.push(intVersion2 >> 16 & 0xff); + bytes.push(intVersion2 >> 8 & 0xff); + bytes.push(intVersion2 & 0xff); + + bytes.push(intVersion1 >> 24 & 0xff); + bytes.push(intVersion1 >> 16 & 0xff); + bytes.push(intVersion1 >> 8 & 0xff); + bytes.push(intVersion1 & 0xff); + + return bytes; + } +} + +var ErlangTypes = { + Tuple, + PID, + Reference, + BitString +}; + +var vendor = { + ErlangTypes +}; + +export default vendor; diff --git a/src/javascript/lib/core/functions.js b/src/javascript/lib/core/functions.js index 86d84a65..91bf31e7 100644 --- a/src/javascript/lib/core/functions.js +++ b/src/javascript/lib/core/functions.js @@ -133,7 +133,10 @@ function object_to_map(object, options = []) { key2 = Symbol.for(key); } - if (value !== null && (value.constructor === Object || (value instanceof Array && opt_recurse_array))) { + if ( + value !== null && + (value.constructor === Object || (value instanceof Array && opt_recurse_array)) + ) { value = object_to_map(value, options); } map.set(key2, value); diff --git a/src/javascript/lib/core/special_forms.js b/src/javascript/lib/core/special_forms.js index 8caa2dfe..988d341f 100644 --- a/src/javascript/lib/core/special_forms.js +++ b/src/javascript/lib/core/special_forms.js @@ -60,7 +60,6 @@ function _try(do_fun, rescue_function, catch_fun, else_function, after_function) result = do_fun(); } catch (e) { let ex_result = null; - if (rescue_function) { try { ex_result = rescue_function(e); diff --git a/src/javascript/tests/try.spec.js b/src/javascript/tests/try.spec.js index 97150618..fdcbaefd 100644 --- a/src/javascript/tests/try.spec.js +++ b/src/javascript/tests/try.spec.js @@ -1,8 +1,7 @@ import test from 'ava'; import Core from '../lib/core'; -const Patterns = Core.Patterns; -const SpecialForms = Core.SpecialForms; +const { Patterns, SpecialForms } = Core; test('try', (t) => { /* diff --git a/test_elixir_script/try_test.exs b/test_elixir_script/try_test.exs new file mode 100644 index 00000000..0e73cd8b --- /dev/null +++ b/test_elixir_script/try_test.exs @@ -0,0 +1,48 @@ +defmodule ElixirScript.Try.Test do + use ElixirScript.Test + + test "returns value in try if no error" do + value = try do + 1 + 1 + rescue + _ -> + 3 + end + + assert value == 2 + end + + test "returns rescue value on error" do + value = try do + raise ArithmeticError + rescue + _ -> + 3 + end + + assert value == 3 + end + + test "returns rescue value from matching error" do + value = try do + raise ArithmeticError + rescue + ArithmeticError -> + 3 + end + + assert value == 3 + end + + test "returns rescue value from matching errors" do + value = try do + raise ArithmeticError + rescue + _ in [ArithmeticError, ArgumentError] -> + 3 + end + + assert value == 3 + end + +end From fb93e94af13443650c1f928021b229f7dc11cbe5 Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Wed, 1 Nov 2017 20:12:25 -0500 Subject: [PATCH 356/418] Add vendor.build.js to ebert config ignore --- .ebert.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.ebert.yml b/.ebert.yml index de120782..06a1d128 100644 --- a/.ebert.yml +++ b/.ebert.yml @@ -11,3 +11,4 @@ engines: exclude_paths: - config - test +- priv/testrunner/vendor.build.js From 55d745e8bacfb36f440fd6d2e09cb6b3a328571e Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Wed, 1 Nov 2017 20:14:41 -0500 Subject: [PATCH 357/418] Add esm folder to ebert ignore --- .ebert.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.ebert.yml b/.ebert.yml index 06a1d128..148907f7 100644 --- a/.ebert.yml +++ b/.ebert.yml @@ -12,3 +12,4 @@ exclude_paths: - config - test - priv/testrunner/vendor.build.js +- priv/testrunner/esm From 84d26e0ae9a4552b0e31d47fa1c05a5e239573de Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Wed, 1 Nov 2017 20:17:33 -0500 Subject: [PATCH 358/418] Fix lints --- .../passes/translate/forms/try.ex | 28 +++++++++++++------ 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/lib/elixir_script/passes/translate/forms/try.ex b/lib/elixir_script/passes/translate/forms/try.ex index e086d310..46add57f 100644 --- a/lib/elixir_script/passes/translate/forms/try.ex +++ b/lib/elixir_script/passes/translate/forms/try.ex @@ -62,20 +62,30 @@ defmodule ElixirScript.Translate.Forms.Try do names = Enum.map(names, &make_exception_ast(&1)) param = {:_e, context, atom} - reasonCall = {{:., [], [{:_e0, context, atom}, :__reason]}, [], []} - reasonCall = {{:., [], [reasonCall, :__struct__]}, [], []} - reasonCall = {{:., [], [reasonCall, :__MODULE__]}, [], []} - - {ast, _} = Clause.compile({[], [param], [{{:., [], [Enum, :member?]}, [], [names, reasonCall]}], body}, state) + reason_call = {{:., [], [{:_e0, context, atom}, :__reason]}, [], []} + reason_call = {{:., [], [reason_call, :__struct__]}, [], []} + reason_call = {{:., [], [reason_call, :__MODULE__]}, [], []} + + {ast, _} = Clause.compile({ + [], + [param], + [{{:., [], [Enum, :member?]}, [], [names, reason_call]}], + body}, + state) ast {:->, _, [ [{:in, _, [param, names]}], body]} -> names = Enum.map(names, &make_exception_ast(&1)) - reasonCall = {{:., [], [param, :__reason]}, [], []} - reasonCall = {{:., [], [reasonCall, :__struct__]}, [], []} - reasonCall = {{:., [], [reasonCall, :__MODULE__]}, [], []} + reason_call = {{:., [], [param, :__reason]}, [], []} + reason_call = {{:., [], [reason_call, :__struct__]}, [], []} + reason_call = {{:., [], [reason_call, :__MODULE__]}, [], []} - {ast, _} = Clause.compile({[], [param], [{{:., [], [Enum, :member?]}, [], [names, reasonCall]}], body}, state) + {ast, _} = Clause.compile({ + [], + [param], + [{{:., [], [Enum, :member?]}, [], [names, reason_call]}], + body}, + state) ast {:->, _, [ [param], body]} -> {ast, _} = Clause.compile({[], [param], [], body}, state) From 0335c44909f8d844d2e0511289c4b52316c00b26 Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Wed, 1 Nov 2017 20:22:22 -0500 Subject: [PATCH 359/418] Fix more lints --- lib/elixir_script_test/test.ex | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/lib/elixir_script_test/test.ex b/lib/elixir_script_test/test.ex index 60a2dee3..c1f5bb6a 100644 --- a/lib/elixir_script_test/test.ex +++ b/lib/elixir_script_test/test.ex @@ -72,7 +72,6 @@ defmodule ElixirScript.Test do ``` """ - defmacro __using__(_opts) do quote do import ElixirScript.Test.Callbacks, only: [ @@ -84,7 +83,7 @@ defmodule ElixirScript.Test do ] import ExUnit.Assertions - def __elixirscript_test_module__(), do: true + def __elixirscript_test_module__, do: true end end @@ -118,7 +117,13 @@ defmodule ElixirScript.Test do defp node_test_runner(js_files) do test_script_path = Path.join([:code.priv_dir(:elixir_script), "testrunner", "index.js"]) - {_, exit_status} = System.cmd "node", [test_script_path] ++ js_files, into: IO.stream(:stdio, :line) + test_script_path = [test_script_path] ++ js_files + {_, exit_status} = System.cmd( + "node", + test_script_path, + into: IO.stream(:stdio, :line) + ) + exit_status end end From 14670266b0afe6a1b9c67438eb81921687c41f62 Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Wed, 1 Nov 2017 20:24:56 -0500 Subject: [PATCH 360/418] Rebuild vendor.build.js --- priv/testrunner/vendor.build.js | 406 +------------------------------- 1 file changed, 2 insertions(+), 404 deletions(-) diff --git a/priv/testrunner/vendor.build.js b/priv/testrunner/vendor.build.js index 6e808208..9d49e34d 100644 --- a/priv/testrunner/vendor.build.js +++ b/priv/testrunner/vendor.build.js @@ -1,404 +1,2 @@ -class Tuple { - constructor(...args) { - this.values = Object.freeze(args); - this.length = this.values.length; - } - - get(index) { - return this.values[index]; - } - - count() { - return this.values.length; - } - - [Symbol.iterator]() { - return this.values[Symbol.iterator](); - } - - toString() { - let i, - s = ''; - for (i = 0; i < this.values.length; i++) { - if (s !== '') { - s += ', '; - } - - const stringToAppend = this.values[i] ? this.values[i].toString() : ''; - - s += stringToAppend; - } - - return '{' + s + '}'; - } - - put_elem(index, elem) { - if (index === this.length) { - let new_values = this.values.concat([elem]); - return new Tuple(...new_values); - } - - let new_values = this.values.concat([]); - new_values.splice(index, 0, elem); - return new Tuple(...new_values); - } - - remove_elem(index) { - let new_values = this.values.concat([]); - new_values.splice(index, 1); - return new Tuple(...new_values); - } -} - -let process_counter = -1; - -class PID { - constructor() { - process_counter = process_counter + 1; - this.id = process_counter; - } - - toString() { - return 'PID#<0.' + this.id + '.0>'; - } -} - -let ref_counter = -1; - -class Reference { - constructor() { - ref_counter = ref_counter + 1; - this.id = ref_counter; - this.ref = Symbol(); - } - - toString() { - return 'Ref#<0.0.0.' + this.id + '>'; - } -} - -class BitString { - constructor(...args) { - this.value = Object.freeze(this.process(args)); - this.length = this.value.length; - this.bit_size = this.length * 8; - this.byte_size = this.length; - } - - get(index) { - return this.value[index]; - } - - count() { - return this.value.length; - } - - slice(start, end = null) { - let s = this.value.slice(start, end); - let ms = s.map(elem => BitString.integer(elem)); - return new BitString(...ms); - } - - [Symbol.iterator]() { - return this.value[Symbol.iterator](); - } - - toString() { - var i, - s = ''; - for (i = 0; i < this.count(); i++) { - if (s !== '') { - s += ', '; - } - s += this.get(i).toString(); - } - - return '<<' + s + '>>'; - } - - process(bitStringParts) { - let processed_values = []; - - var i; - for (i = 0; i < bitStringParts.length; i++) { - let processed_value = this['process_' + bitStringParts[i].type](bitStringParts[i]); - - for (let attr of bitStringParts[i].attributes) { - processed_value = this['process_' + attr](processed_value); - } - - processed_values = processed_values.concat(processed_value); - } - - return processed_values; - } - - process_integer(value) { - return value.value; - } - - process_float(value) { - if (value.size === 64) { - return BitString.float64ToBytes(value.value); - } else if (value.size === 32) { - return BitString.float32ToBytes(value.value); - } - - throw new Error('Invalid size for float'); - } - - process_bitstring(value) { - return value.value.value; - } - - process_binary(value) { - return BitString.toUTF8Array(value.value); - } - - process_utf8(value) { - return BitString.toUTF8Array(value.value); - } - - process_utf16(value) { - return BitString.toUTF16Array(value.value); - } - - process_utf32(value) { - return BitString.toUTF32Array(value.value); - } - - process_signed(value) { - return new Uint8Array([value])[0]; - } - - process_unsigned(value) { - return value; - } - - process_native(value) { - return value; - } - - process_big(value) { - return value; - } - - process_little(value) { - return value.reverse(); - } - - process_size(value) { - return value; - } - - process_unit(value) { - return value; - } - - static integer(value) { - return BitString.wrap(value, { type: 'integer', unit: 1, size: 8 }); - } - - static float(value) { - return BitString.wrap(value, { type: 'float', unit: 1, size: 64 }); - } - - static bitstring(value) { - return BitString.wrap(value, { - type: 'bitstring', - unit: 1, - size: value.bit_size - }); - } - - static bits(value) { - return BitString.bitstring(value); - } - - static binary(value) { - return BitString.wrap(value, { - type: 'binary', - unit: 8, - size: value.length - }); - } - - static bytes(value) { - return BitString.binary(value); - } - - static utf8(value) { - return BitString.wrap(value, { type: 'utf8', unit: 1, size: value.length }); - } - - static utf16(value) { - return BitString.wrap(value, { - type: 'utf16', - unit: 1, - size: value.length * 2 - }); - } - - static utf32(value) { - return BitString.wrap(value, { - type: 'utf32', - unit: 1, - size: value.length * 4 - }); - } - - static signed(value) { - return BitString.wrap(value, {}, 'signed'); - } - - static unsigned(value) { - return BitString.wrap(value, {}, 'unsigned'); - } - - static native(value) { - return BitString.wrap(value, {}, 'native'); - } - - static big(value) { - return BitString.wrap(value, {}, 'big'); - } - - static little(value) { - return BitString.wrap(value, {}, 'little'); - } - - static size(value, count) { - return BitString.wrap(value, { size: count }); - } - - static unit(value, count) { - return BitString.wrap(value, { unit: count }); - } - - static wrap(value, opt, new_attribute = null) { - let the_value = value; - - if (!(value instanceof Object)) { - the_value = { value: value, attributes: [] }; - } - - the_value = Object.assign(the_value, opt); - - if (new_attribute) { - the_value.attributes.push(new_attribute); - } - - return the_value; - } - - static toUTF8Array(str) { - var utf8 = []; - for (var i = 0; i < str.length; i++) { - var charcode = str.charCodeAt(i); - if (charcode < 0x80) { - utf8.push(charcode); - } else if (charcode < 0x800) { - utf8.push(0xc0 | charcode >> 6, 0x80 | charcode & 0x3f); - } else if (charcode < 0xd800 || charcode >= 0xe000) { - utf8.push(0xe0 | charcode >> 12, 0x80 | charcode >> 6 & 0x3f, 0x80 | charcode & 0x3f); - } else { - // surrogate pair - i++; - // UTF-16 encodes 0x10000-0x10FFFF by - // subtracting 0x10000 and splitting the - // 20 bits of 0x0-0xFFFFF into two halves - charcode = 0x10000 + ((charcode & 0x3ff) << 10 | str.charCodeAt(i) & 0x3ff); - utf8.push(0xf0 | charcode >> 18, 0x80 | charcode >> 12 & 0x3f, 0x80 | charcode >> 6 & 0x3f, 0x80 | charcode & 0x3f); - } - } - return utf8; - } - - static toUTF16Array(str) { - var utf16 = []; - for (var i = 0; i < str.length; i++) { - var codePoint = str.codePointAt(i); - - if (codePoint <= 255) { - utf16.push(0); - utf16.push(codePoint); - } else { - utf16.push(codePoint >> 8 & 0xff); - utf16.push(codePoint & 0xff); - } - } - return utf16; - } - - static toUTF32Array(str) { - var utf32 = []; - for (var i = 0; i < str.length; i++) { - var codePoint = str.codePointAt(i); - - if (codePoint <= 255) { - utf32.push(0); - utf32.push(0); - utf32.push(0); - utf32.push(codePoint); - } else { - utf32.push(0); - utf32.push(0); - utf32.push(codePoint >> 8 & 0xff); - utf32.push(codePoint & 0xff); - } - } - return utf32; - } - - //http://stackoverflow.com/questions/2003493/javascript-float-from-to-bits - static float32ToBytes(f) { - var bytes = []; - - var buf = new ArrayBuffer(4); - new Float32Array(buf)[0] = f; - - let intVersion = new Uint32Array(buf)[0]; - - bytes.push(intVersion >> 24 & 0xff); - bytes.push(intVersion >> 16 & 0xff); - bytes.push(intVersion >> 8 & 0xff); - bytes.push(intVersion & 0xff); - - return bytes; - } - - static float64ToBytes(f) { - var bytes = []; - - var buf = new ArrayBuffer(8); - new Float64Array(buf)[0] = f; - - var intVersion1 = new Uint32Array(buf)[0]; - var intVersion2 = new Uint32Array(buf)[1]; - - bytes.push(intVersion2 >> 24 & 0xff); - bytes.push(intVersion2 >> 16 & 0xff); - bytes.push(intVersion2 >> 8 & 0xff); - bytes.push(intVersion2 & 0xff); - - bytes.push(intVersion1 >> 24 & 0xff); - bytes.push(intVersion1 >> 16 & 0xff); - bytes.push(intVersion1 >> 8 & 0xff); - bytes.push(intVersion1 & 0xff); - - return bytes; - } -} - -var ErlangTypes = { - Tuple, - PID, - Reference, - BitString -}; - -var vendor = { - ErlangTypes -}; - -export default vendor; +class Tuple{constructor(...a){this.values=Object.freeze(a),this.length=this.values.length}get(a){return this.values[a]}count(){return this.values.length}[Symbol.iterator](){return this.values[Symbol.iterator]()}toString(){let a,b='';for(a=0;a'}}let ref_counter=-1;class Reference{constructor(){++ref_counter,this.id=ref_counter,this.ref=Symbol()}toString(){return'Ref#<0.0.0.'+this.id+'>'}}class BitString{constructor(...a){this.value=Object.freeze(this.process(a)),this.length=this.value.length,this.bit_size=8*this.length,this.byte_size=this.length}get(a){return this.value[a]}count(){return this.value.length}slice(a,b=null){let c=this.value.slice(a,b),d=c.map((a)=>BitString.integer(a));return new BitString(...d)}[Symbol.iterator](){return this.value[Symbol.iterator]()}toString(){var a,b='';for(a=0;a>'}process(a){let b=[];var c;for(c=0;cb?c.push(b):2048>b?c.push(192|b>>6,128|63&b):55296>b||57344<=b?c.push(224|b>>12,128|63&b>>6,128|63&b):(d++,b=65536+((1023&b)<<10|1023&a.charCodeAt(d)),c.push(240|b>>18,128|63&b>>12,128|63&b>>6,128|63&b));return c}static toUTF16Array(a){for(var b,c=[],d=0;d=b?(c.push(0),c.push(b)):(c.push(255&b>>8),c.push(255&b));return c}static toUTF32Array(a){for(var b,c=[],d=0;d=b?(c.push(0),c.push(0),c.push(0),c.push(b)):(c.push(0),c.push(0),c.push(255&b>>8),c.push(255&b));return c}//http://stackoverflow.com/questions/2003493/javascript-float-from-to-bits +static float32ToBytes(a){var b=[],c=new ArrayBuffer(4);new Float32Array(c)[0]=a;let d=new Uint32Array(c)[0];return b.push(255&d>>24),b.push(255&d>>16),b.push(255&d>>8),b.push(255&d),b}static float64ToBytes(a){var b=[],c=new ArrayBuffer(8);new Float64Array(c)[0]=a;var d=new Uint32Array(c)[0],e=new Uint32Array(c)[1];return b.push(255&e>>24),b.push(255&e>>16),b.push(255&e>>8),b.push(255&e),b.push(255&d>>24),b.push(255&d>>16),b.push(255&d>>8),b.push(255&d),b}}var ErlangTypes={Tuple,PID,Reference,BitString},vendor={ErlangTypes};export default vendor; From a0f27a6e88e33a3eb97ce1c88271a567a0db2507 Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Sun, 5 Nov 2017 21:59:02 -0600 Subject: [PATCH 361/418] Using alias for FindUnusedFunctions --- lib/elixir_script/compiler.ex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/elixir_script/compiler.ex b/lib/elixir_script/compiler.ex index e254f943..ba0f869b 100644 --- a/lib/elixir_script/compiler.ex +++ b/lib/elixir_script/compiler.ex @@ -75,7 +75,7 @@ defmodule ElixirScript.Compiler do FindUsedModules.execute(entry_modules, pid) if opts.remove_unused_functions do - ElixirScript.FindUsedFunctions.execute(entry_modules, pid) + FindUsedFunctions.execute(entry_modules, pid) end modules = State.list_modules(pid) From c2fd9000b53bc1e1814cbb6102e2fd418068c35c Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Thu, 9 Nov 2017 19:08:54 -0600 Subject: [PATCH 362/418] Write to manifest --- .gitignore | 1 + lib/elixir_script/beam.ex | 10 +++++-- lib/elixir_script/manifest.ex | 28 +++++++++++++++++++ lib/elixir_script/passes/find_used_modules.ex | 10 ++++--- lib/elixir_script/passes/output.ex | 26 +++++++---------- test/beam_test.exs | 2 +- 6 files changed, 53 insertions(+), 24 deletions(-) create mode 100644 lib/elixir_script/manifest.ex diff --git a/.gitignore b/.gitignore index 77a9c54a..1a813296 100644 --- a/.gitignore +++ b/.gitignore @@ -24,3 +24,4 @@ cover /priv/build /tmp .esm-cache +.elixir_ls diff --git a/lib/elixir_script/beam.ex b/lib/elixir_script/beam.ex index 254cb803..b4ccb69d 100644 --- a/lib/elixir_script/beam.ex +++ b/lib/elixir_script/beam.ex @@ -59,7 +59,7 @@ defmodule ElixirScript.Beam do {:ok, {^module, attribute_info}} = :beam_lib.chunks(beam, [:attributes]) do if Keyword.get(attribute_info[:attributes], :protocol) do - get_protocol_implementations(module) + get_protocol_implementations(module, beam_path) else backend.debug_info(:elixir_v1, module, data, []) |> process_debug_info(beam_path) @@ -89,6 +89,8 @@ defmodule ElixirScript.Beam do Map.put(info, :last_modified, nil) end + info = Map.put(info, :beam_path, beam_path) + {:ok, info} end @@ -96,7 +98,9 @@ defmodule ElixirScript.Beam do error end - defp get_protocol_implementations(module) do + defp get_protocol_implementations(module, beam_path) do + {:ok, protocol_module_info} = process_debug_info({:ok, %{}}, beam_path) + implementations = module |> Protocol.extract_impls(:code.get_path()) |> Enum.map(fn(x) -> Module.concat([module, x]) end) @@ -109,7 +113,7 @@ defmodule ElixirScript.Beam do end end) - {:ok, module, implementations} + {:ok, module, protocol_module_info, implementations} end defp replace_definitions(original_definitions, replacement_definitions) do diff --git a/lib/elixir_script/manifest.ex b/lib/elixir_script/manifest.ex new file mode 100644 index 00000000..5904620a --- /dev/null +++ b/lib/elixir_script/manifest.ex @@ -0,0 +1,28 @@ +defmodule ElixirScript.Manifest do + @moduledoc false + + @spec read_manifest(binary) :: nil + def read_manifest(_manifest) do + + end + + @spec write_manifest(binary, [{atom, map}]) :: :ok + def write_manifest(manifest_path, modules) do + data = Enum.reduce(modules, %{}, fn {module, info}, current_data -> + info = %{ + references: info.used_modules, + last_modified: info.last_modified, + beam_path: Map.get(info, :beam_path), + source: Map.get(info, :file), + js_path: "Elixir.#{module}.js" + } + Map.put(current_data, module, info) + end) + + data = :erlang.term_to_binary(data, [:compressed]) + File.mkdir_p!(Path.dirname(manifest_path)) + File.write!(manifest_path, data) + + :ok + end +end diff --git a/lib/elixir_script/passes/find_used_modules.ex b/lib/elixir_script/passes/find_used_modules.ex index ae75d9e6..c37921b0 100644 --- a/lib/elixir_script/passes/find_used_modules.ex +++ b/lib/elixir_script/passes/find_used_modules.ex @@ -26,8 +26,8 @@ defmodule ElixirScript.FindUsedModules do case result do {:ok, info} -> walk_module(module, info, pid) - {:ok, module, implementations} -> - walk_protocol(module, implementations, pid) + {:ok, module, module_info, implementations} -> + walk_protocol(module, module_info, implementations, pid) {:error, "Unknown module"} -> Logger.warn fn() -> "ElixirScript: #{inspect module} is missing or unavailable" @@ -83,7 +83,7 @@ defmodule ElixirScript.FindUsedModules do end) end - defp walk_protocol(module, implementations, pid) do + defp walk_protocol(module, module_info, implementations, pid) do impls = Enum.map(implementations, fn {impl, %{attributes: attrs}} -> protocol_impl = Keyword.fetch!(attrs, :protocol_impl) impl_for = Keyword.fetch!(protocol_impl, :for) @@ -94,7 +94,9 @@ defmodule ElixirScript.FindUsedModules do functions = Enum.map(first_implementation_functions, fn { name, _, _, _} -> name end) - ModuleState.put_module(pid, module, %{protocol: true, impls: impls, functions: functions}) + module_info = Map.merge(module_info, %{protocol: true, impls: impls, functions: functions}) + + ModuleState.put_module(pid, module, module_info) Enum.each(implementations, fn {impl, info} -> ModuleState.add_used_module(pid, module, impl) diff --git a/lib/elixir_script/passes/output.ex b/lib/elixir_script/passes/output.ex index baaf05ba..0a2aa011 100644 --- a/lib/elixir_script/passes/output.ex +++ b/lib/elixir_script/passes/output.ex @@ -3,13 +3,14 @@ defmodule ElixirScript.Output do alias ElixirScript.State, as: ModuleState alias ESTree.Tools.{Builder, Generator} + alias ElixirScript.Manifest @doc """ Takes outputs the JavaScript code in the specified output """ - @spec execute([atom], pid, map) :: nil + @spec execute([atom], pid, map) :: any def execute(modules, pid, opts) do - modules = modules + prepared_modules = modules |> Enum.filter(fn {_, info} -> Map.has_key?(info, :js_ast) end) |> Enum.map(fn {module, info} -> {module, info.js_ast, info.used_modules} @@ -27,8 +28,13 @@ defmodule ElixirScript.Output do {module, name, path, import_path} end) - modules - |> create_modules(opts, js_modules) + + result = create_modules(prepared_modules, opts, js_modules) + + manifest_path = Path.join(Mix.Project.manifest_path(), ".compile.elixir_script") + Manifest.write_manifest(manifest_path, modules) + + result end defp concat(code) do @@ -39,17 +45,6 @@ defmodule ElixirScript.Output do """ end - defp prepare_js_ast(js_ast) do - case js_ast do - modules when is_list(modules) -> - modules - |> Enum.reduce([], &(&2 ++ &1.body)) - |> Builder.program - _ -> - js_ast - end - end - defp create_modules(modules, opts, js_modules) do modules |> Task.async_stream(fn({module, [body, exports], used_modules}) -> @@ -62,7 +57,6 @@ defmodule ElixirScript.Output do js_parts |> Builder.program - |> prepare_js_ast |> Generator.generate |> concat |> output(module, Map.get(opts, :output), js_modules) diff --git a/test/beam_test.exs b/test/beam_test.exs index bc6671a3..66369a94 100644 --- a/test/beam_test.exs +++ b/test/beam_test.exs @@ -10,6 +10,6 @@ defmodule ElixirScript.Beam.Test do end test "can get ast from beam that is protocol" do - assert {:ok, Enumerable, _} = ElixirScript.Beam.debug_info(Enumerable) + assert {:ok, Enumerable, _, _} = ElixirScript.Beam.debug_info(Enumerable) end end From 3ae89c6e650c4d918e6054b8556b3e6c6259c314 Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Thu, 9 Nov 2017 19:27:02 -0600 Subject: [PATCH 363/418] Move manifest writing to top level of compiler --- lib/elixir_script/compiler.ex | 8 ++++++-- lib/elixir_script/manifest.ex | 4 ++-- lib/elixir_script/passes/output.ex | 8 +------- lib/mix/tasks/compile.elixir_script.ex | 5 +++++ 4 files changed, 14 insertions(+), 11 deletions(-) diff --git a/lib/elixir_script/compiler.ex b/lib/elixir_script/compiler.ex index ba0f869b..833c19a5 100644 --- a/lib/elixir_script/compiler.ex +++ b/lib/elixir_script/compiler.ex @@ -31,12 +31,13 @@ defmodule ElixirScript.Compiler do Translate, FindUsedModules, FindUsedFunctions, - Output + Output, + Manifest, } alias ElixirScript.ModuleSystems.ES alias Kernel.ParallelCompiler - @spec compile(atom | [atom] | binary, []) :: nil + @spec compile(atom | [atom] | binary, []) :: [{atom, map}] def compile(path, opts \\ []) def compile(path, opts) when is_binary(path) do @@ -86,6 +87,9 @@ defmodule ElixirScript.Compiler do State.stop(pid) + manifest_path = Path.join(Mix.Project.manifest_path(), ".compile.elixir_script") + Manifest.write_manifest(manifest_path, modules, opts) + result end diff --git a/lib/elixir_script/manifest.ex b/lib/elixir_script/manifest.ex index 5904620a..89bae909 100644 --- a/lib/elixir_script/manifest.ex +++ b/lib/elixir_script/manifest.ex @@ -6,8 +6,8 @@ defmodule ElixirScript.Manifest do end - @spec write_manifest(binary, [{atom, map}]) :: :ok - def write_manifest(manifest_path, modules) do + @spec write_manifest(binary, [{atom, map}], map) :: :ok + def write_manifest(manifest_path, modules, _opts) do data = Enum.reduce(modules, %{}, fn {module, info}, current_data -> info = %{ references: info.used_modules, diff --git a/lib/elixir_script/passes/output.ex b/lib/elixir_script/passes/output.ex index 0a2aa011..2f54cb2c 100644 --- a/lib/elixir_script/passes/output.ex +++ b/lib/elixir_script/passes/output.ex @@ -3,7 +3,6 @@ defmodule ElixirScript.Output do alias ElixirScript.State, as: ModuleState alias ESTree.Tools.{Builder, Generator} - alias ElixirScript.Manifest @doc """ Takes outputs the JavaScript code in the specified output @@ -29,12 +28,7 @@ defmodule ElixirScript.Output do end) - result = create_modules(prepared_modules, opts, js_modules) - - manifest_path = Path.join(Mix.Project.manifest_path(), ".compile.elixir_script") - Manifest.write_manifest(manifest_path, modules) - - result + create_modules(prepared_modules, opts, js_modules) end defp concat(code) do diff --git a/lib/mix/tasks/compile.elixir_script.ex b/lib/mix/tasks/compile.elixir_script.ex index 617a92e4..ef353c04 100644 --- a/lib/mix/tasks/compile.elixir_script.ex +++ b/lib/mix/tasks/compile.elixir_script.ex @@ -2,6 +2,8 @@ defmodule Mix.Tasks.Compile.ElixirScript do use Mix.Task @recursive true + @manifest ".compile.elixir_script" + @manifest_vsn 1 @moduledoc """ Mix compiler to allow mix to compile Elixirscript source files into JavaScript @@ -48,6 +50,9 @@ defmodule Mix.Tasks.Compile.ElixirScript do :ok end + def manifests, do: [manifest()] + defp manifest, do: Path.join(Mix.Project.manifest_path(), @manifest) + @doc false def get_compiler_params() do elixirscript_config = get_elixirscript_config() From a9f15811eb2c76687f29d97e4915e7e23a100877 Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Thu, 9 Nov 2017 19:45:40 -0600 Subject: [PATCH 364/418] Fix lints --- lib/elixir_script/beam.ex | 2 +- lib/elixir_script/passes/find_used_modules.ex | 24 ++++++++++--------- lib/elixir_script/passes/output.ex | 1 - 3 files changed, 14 insertions(+), 13 deletions(-) diff --git a/lib/elixir_script/beam.ex b/lib/elixir_script/beam.ex index b4ccb69d..4473f221 100644 --- a/lib/elixir_script/beam.ex +++ b/lib/elixir_script/beam.ex @@ -7,7 +7,7 @@ defmodule ElixirScript.Beam do For protocols, this will return a list of all the protocol implementations """ - @spec debug_info(atom | bitstring) :: {:ok | :error, map | binary} + @spec debug_info(atom | bitstring) :: {:ok, map} | {:ok, atom, map, list} | {:error, binary} def debug_info(module) # We get debug info from String and then replace diff --git a/lib/elixir_script/passes/find_used_modules.ex b/lib/elixir_script/passes/find_used_modules.ex index c37921b0..d738a006 100644 --- a/lib/elixir_script/passes/find_used_modules.ex +++ b/lib/elixir_script/passes/find_used_modules.ex @@ -6,7 +6,7 @@ defmodule ElixirScript.FindUsedModules do @doc """ Takes a list of entry modules and finds modules they use. """ - @spec execute([atom], pid) :: nil + @spec execute([atom], pid) :: :ok def execute(modules, pid) do modules |> List.wrap @@ -94,7 +94,10 @@ defmodule ElixirScript.FindUsedModules do functions = Enum.map(first_implementation_functions, fn { name, _, _, _} -> name end) - module_info = Map.merge(module_info, %{protocol: true, impls: impls, functions: functions}) + module_info = Map.merge( + module_info, + %{protocol: true, impls: impls, functions: functions} + ) ModuleState.put_module(pid, module, module_info) @@ -305,15 +308,14 @@ defmodule ElixirScript.FindUsedModules do end defp walk({:., _, [module, function]}, state) do - cond do - ElixirScript.Translate.Module.is_elixir_module(module) -> - ModuleState.add_used_module(state.pid, state.module, module) - if ModuleState.get_module(state.pid, module) == nil do - do_execute(module, state.pid) - end - true -> - walk(module, state) - walk(function, state) + if ElixirScript.Translate.Module.is_elixir_module(module) do + ModuleState.add_used_module(state.pid, state.module, module) + if ModuleState.get_module(state.pid, module) == nil do + do_execute(module, state.pid) + end + else + walk(module, state) + walk(function, state) end end diff --git a/lib/elixir_script/passes/output.ex b/lib/elixir_script/passes/output.ex index 2f54cb2c..e03d5fe1 100644 --- a/lib/elixir_script/passes/output.ex +++ b/lib/elixir_script/passes/output.ex @@ -27,7 +27,6 @@ defmodule ElixirScript.Output do {module, name, path, import_path} end) - create_modules(prepared_modules, opts, js_modules) end From a0e5eb1e7c1ab8e14b46cee7928ac1ca74c044aa Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Thu, 9 Nov 2017 20:07:19 -0600 Subject: [PATCH 365/418] Add output path for js_path --- lib/elixir_script/manifest.ex | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/lib/elixir_script/manifest.ex b/lib/elixir_script/manifest.ex index 89bae909..b9a61f3f 100644 --- a/lib/elixir_script/manifest.ex +++ b/lib/elixir_script/manifest.ex @@ -7,15 +7,22 @@ defmodule ElixirScript.Manifest do end @spec write_manifest(binary, [{atom, map}], map) :: :ok - def write_manifest(manifest_path, modules, _opts) do + def write_manifest(manifest_path, modules, opts) do + output_path = if opts.output == nil or opts.output == :stdout do + "" + else + Path.dirname(opts.output) + end + data = Enum.reduce(modules, %{}, fn {module, info}, current_data -> info = %{ references: info.used_modules, last_modified: info.last_modified, beam_path: Map.get(info, :beam_path), source: Map.get(info, :file), - js_path: "Elixir.#{module}.js" + js_path: Path.join(output_path, "#{module}.js") } + Map.put(current_data, module, info) end) From cda84c3c5de070736f26f152de0e27d4d0d128f0 Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Thu, 9 Nov 2017 20:14:01 -0600 Subject: [PATCH 366/418] Update lint settings --- .credo.exs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.credo.exs b/.credo.exs index 74864ac4..ab405b15 100644 --- a/.credo.exs +++ b/.credo.exs @@ -61,7 +61,7 @@ {Credo.Check.Readability.FunctionNames}, {Credo.Check.Readability.LargeNumbers}, - {Credo.Check.Readability.MaxLineLength, priority: :low, max_length: 80}, + {Credo.Check.Readability.MaxLineLength, priority: :low, max_length: 80, ignore_specs: true}, {Credo.Check.Readability.ModuleAttributeNames}, {Credo.Check.Readability.ModuleDoc}, {Credo.Check.Readability.ModuleNames}, @@ -70,7 +70,7 @@ {Credo.Check.Readability.PredicateFunctionNames}, {Credo.Check.Readability.PreferImplicitTry}, {Credo.Check.Readability.RedundantBlankLines}, - {Credo.Check.Readability.Specs}, + {Credo.Check.Readability.Specs, false}, {Credo.Check.Readability.StringSigils}, {Credo.Check.Readability.TrailingBlankLine}, {Credo.Check.Readability.TrailingWhiteSpace}, From 3c8dcd19dbb01a5f59e1360e951cd7f5dba36ddb Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Thu, 9 Nov 2017 22:54:00 -0600 Subject: [PATCH 367/418] Move manifest writing to the mix compiler --- lib/elixir_script/compiler.ex | 29 ++++++++++++++++++++------ lib/elixir_script/manifest.ex | 20 +++--------------- lib/elixir_script/passes/output.ex | 12 +++++------ lib/mix/tasks/compile.elixir_script.ex | 5 ++++- test/compiler_test.exs | 6 +++--- 5 files changed, 39 insertions(+), 33 deletions(-) diff --git a/lib/elixir_script/compiler.ex b/lib/elixir_script/compiler.ex index 833c19a5..0621238e 100644 --- a/lib/elixir_script/compiler.ex +++ b/lib/elixir_script/compiler.ex @@ -32,12 +32,11 @@ defmodule ElixirScript.Compiler do FindUsedModules, FindUsedFunctions, Output, - Manifest, } alias ElixirScript.ModuleSystems.ES alias Kernel.ParallelCompiler - @spec compile(atom | [atom] | binary, []) :: [{atom, map}] + @spec compile(atom | [atom] | binary, []) :: map def compile(path, opts \\ []) def compile(path, opts) when is_binary(path) do @@ -87,10 +86,7 @@ defmodule ElixirScript.Compiler do State.stop(pid) - manifest_path = Path.join(Mix.Project.manifest_path(), ".compile.elixir_script") - Manifest.write_manifest(manifest_path, modules, opts) - - result + transform_output(modules, result, opts) end defp build_compiler_options(opts) do @@ -107,4 +103,25 @@ defmodule ElixirScript.Compiler do defp on_module_compile(pid, _file, module, beam) do State.put_in_memory_module(pid, module, beam) end + + defp transform_output(modules, compiled_js, opts) do + output_path = if opts.output == nil or opts.output == :stdout do + "" + else + Path.dirname(opts.output) + end + + Enum.reduce(modules, %{}, fn {module, info}, current_data -> + info = %{ + references: info.used_modules, + last_modified: info.last_modified, + beam_path: Map.get(info, :beam_path), + source: Map.get(info, :file), + js_path: Path.join(output_path, "#{module}.js"), + js_code: Keyword.get(compiled_js, module) + } + + Map.put(current_data, module, info) + end) + end end diff --git a/lib/elixir_script/manifest.ex b/lib/elixir_script/manifest.ex index b9a61f3f..d0380610 100644 --- a/lib/elixir_script/manifest.ex +++ b/lib/elixir_script/manifest.ex @@ -6,24 +6,10 @@ defmodule ElixirScript.Manifest do end - @spec write_manifest(binary, [{atom, map}], map) :: :ok - def write_manifest(manifest_path, modules, opts) do - output_path = if opts.output == nil or opts.output == :stdout do - "" - else - Path.dirname(opts.output) - end - + @spec write_manifest(binary, map) :: :ok + def write_manifest(manifest_path, modules) do data = Enum.reduce(modules, %{}, fn {module, info}, current_data -> - info = %{ - references: info.used_modules, - last_modified: info.last_modified, - beam_path: Map.get(info, :beam_path), - source: Map.get(info, :file), - js_path: Path.join(output_path, "#{module}.js") - } - - Map.put(current_data, module, info) + Map.put(current_data, module, Map.drop(info, :js_code)) end) data = :erlang.term_to_binary(data, [:compressed]) diff --git a/lib/elixir_script/passes/output.ex b/lib/elixir_script/passes/output.ex index e03d5fe1..26ccc96b 100644 --- a/lib/elixir_script/passes/output.ex +++ b/lib/elixir_script/passes/output.ex @@ -7,7 +7,7 @@ defmodule ElixirScript.Output do @doc """ Takes outputs the JavaScript code in the specified output """ - @spec execute([atom], pid, map) :: any + @spec execute([atom], pid, map) :: [{atom, binary}] def execute(modules, pid, opts) do prepared_modules = modules |> Enum.filter(fn {_, info} -> Map.has_key?(info, :js_ast) end) @@ -71,12 +71,10 @@ defmodule ElixirScript.Output do |> String.replace(".", "$") end - defp output(code, _, nil, _) do - code - end - - defp output(code, _, :stdout, _) do + defp output(code, module, nil, _), do: {module, code} + defp output(code, module, :stdout, _) do IO.puts(code) + {module, code} end defp output(code, module, path, js_modules) do @@ -99,6 +97,8 @@ defmodule ElixirScript.Output do copy_bootstrap_js(output_dir) File.write!(file_name, code) + + {module, code} end defp copy_bootstrap_js(directory) do diff --git a/lib/mix/tasks/compile.elixir_script.ex b/lib/mix/tasks/compile.elixir_script.ex index ef353c04..cdb05da9 100644 --- a/lib/mix/tasks/compile.elixir_script.ex +++ b/lib/mix/tasks/compile.elixir_script.ex @@ -1,5 +1,6 @@ defmodule Mix.Tasks.Compile.ElixirScript do use Mix.Task + alias ElixirScript.Manifest @recursive true @manifest ".compile.elixir_script" @@ -43,7 +44,9 @@ defmodule Mix.Tasks.Compile.ElixirScript do defp do_compile() do {input, opts} = get_compiler_params() - ElixirScript.Compiler.compile(input, opts) + result = ElixirScript.Compiler.compile(input, opts) + + Manifest.write_manifest(manifest(), result) end def clean do diff --git a/test/compiler_test.exs b/test/compiler_test.exs index b4d82ec5..439975f5 100644 --- a/test/compiler_test.exs +++ b/test/compiler_test.exs @@ -3,17 +3,17 @@ defmodule ElixirScript.Compiler.Test do test "Can compile one entry module" do result = ElixirScript.Compiler.compile(Version) - assert is_binary(hd(result)) + assert result |> Map.to_list |> hd |> elem(1) |> Map.get(:js_code) |> is_binary end test "Can compile multiple entry modules" do result = ElixirScript.Compiler.compile([Atom, String, Agent]) - assert is_binary(hd(result)) + assert result |> Map.to_list |> hd |> elem(1) |> Map.get(:js_code) |> is_binary end test "Output" do result = ElixirScript.Compiler.compile(Atom, []) - assert hd(result) =~ "export default" + assert result |> Map.to_list |> hd |> elem(1) |> Map.get(:js_code) =~ "export default" end test "compile file" do From cf0b415c270430d5bc69274d03a033344fa878a8 Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Fri, 10 Nov 2017 08:56:00 -0600 Subject: [PATCH 368/418] Fix lint --- .credo.exs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.credo.exs b/.credo.exs index ab405b15..f7a2bbb3 100644 --- a/.credo.exs +++ b/.credo.exs @@ -61,7 +61,9 @@ {Credo.Check.Readability.FunctionNames}, {Credo.Check.Readability.LargeNumbers}, - {Credo.Check.Readability.MaxLineLength, priority: :low, max_length: 80, ignore_specs: true}, + {Credo.Check.Readability.MaxLineLength, + priority: :low, max_length: 80, ignore_specs: true + }, {Credo.Check.Readability.ModuleAttributeNames}, {Credo.Check.Readability.ModuleDoc}, {Credo.Check.Readability.ModuleNames}, From 016c77497ede3a0d14d5ece2260a275e6dcba294 Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Sat, 11 Nov 2017 07:52:57 -0600 Subject: [PATCH 369/418] Add manifest test --- lib/elixir_script/manifest.ex | 2 +- test/manifest_test.exs | 12 ++++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) create mode 100644 test/manifest_test.exs diff --git a/lib/elixir_script/manifest.ex b/lib/elixir_script/manifest.ex index d0380610..5ed1915f 100644 --- a/lib/elixir_script/manifest.ex +++ b/lib/elixir_script/manifest.ex @@ -9,7 +9,7 @@ defmodule ElixirScript.Manifest do @spec write_manifest(binary, map) :: :ok def write_manifest(manifest_path, modules) do data = Enum.reduce(modules, %{}, fn {module, info}, current_data -> - Map.put(current_data, module, Map.drop(info, :js_code)) + Map.put(current_data, module, Map.drop(info, [:js_code])) end) data = :erlang.term_to_binary(data, [:compressed]) diff --git a/test/manifest_test.exs b/test/manifest_test.exs new file mode 100644 index 00000000..52efd044 --- /dev/null +++ b/test/manifest_test.exs @@ -0,0 +1,12 @@ +defmodule ElixirScript.Manifest.Test do + use ExUnit.Case + alias ElixirScript.Manifest + + test "write manifest" do + result = ElixirScript.Compiler.compile(Atom) + path = Path.join([System.tmp_dir(), "write_manifest_test", ".compile.elixir_script"]) + Manifest.write_manifest(path, result) + assert File.exists?(path) + end + +end From 874f9b06568a77a33283e5daa6665faa5ad5603e Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Sun, 3 Dec 2017 21:54:00 -0600 Subject: [PATCH 370/418] Making sure global ffi aren't added to imports. Make sure remove_unused_functions is respected --- .tool-versions | 6 +++--- lib/elixir_script/compiler.ex | 4 ++-- lib/elixir_script/module_systems/es.ex | 4 ++++ lib/elixir_script/passes/output.ex | 19 ++++++++++++------- lib/elixir_script/passes/translate/module.ex | 8 +++++++- lib/elixir_script/state.ex | 19 +++++++++++++++++-- lib/elixir_script_test/test.ex | 4 ++-- lib/elixir_script_test/test/callbacks.ex | 13 +++++++++++++ 8 files changed, 60 insertions(+), 17 deletions(-) diff --git a/.tool-versions b/.tool-versions index cb49a042..eb307d7d 100644 --- a/.tool-versions +++ b/.tool-versions @@ -1,3 +1,3 @@ -erlang 20.0 -elixir 1.5.0-otp-20 -nodejs 8.3.0 +erlang 20.1 +elixir 1.5.2-otp-20 +nodejs 8.9.1 diff --git a/lib/elixir_script/compiler.ex b/lib/elixir_script/compiler.ex index 0621238e..47136068 100644 --- a/lib/elixir_script/compiler.ex +++ b/lib/elixir_script/compiler.ex @@ -41,7 +41,7 @@ defmodule ElixirScript.Compiler do def compile(path, opts) when is_binary(path) do opts = build_compiler_options(opts) - {:ok, pid} = State.start_link() + {:ok, pid} = State.start_link(opts) path = if String.ends_with?(path, [".ex", ".exs"]) do path @@ -64,7 +64,7 @@ defmodule ElixirScript.Compiler do def compile(entry_modules, opts) do opts = build_compiler_options(opts) - {:ok, pid} = State.start_link() + {:ok, pid} = State.start_link(opts) entry_modules = List.wrap(entry_modules) diff --git a/lib/elixir_script/module_systems/es.ex b/lib/elixir_script/module_systems/es.ex index 123656c7..c5c9ef9d 100644 --- a/lib/elixir_script/module_systems/es.ex +++ b/lib/elixir_script/module_systems/es.ex @@ -4,6 +4,10 @@ defmodule ElixirScript.ModuleSystems.ES do def build(js_imports, body, exports) do imports = js_imports + |> Enum.filter(fn + {_module, _name, nil, _import_path} -> false + _ -> true + end) |> Enum.map(fn {_module, name, _path, import_path} -> import_module(name, import_path) end) diff --git a/lib/elixir_script/passes/output.ex b/lib/elixir_script/passes/output.ex index 26ccc96b..20b6e063 100644 --- a/lib/elixir_script/passes/output.ex +++ b/lib/elixir_script/passes/output.ex @@ -9,13 +9,6 @@ defmodule ElixirScript.Output do """ @spec execute([atom], pid, map) :: [{atom, binary}] def execute(modules, pid, opts) do - prepared_modules = modules - |> Enum.filter(fn {_, info} -> Map.has_key?(info, :js_ast) end) - |> Enum.map(fn {module, info} -> - {module, info.js_ast, info.used_modules} - end - ) - js_modules = ModuleState.js_modules(pid) |> Enum.filter(fn {_module, _name, nil} -> false @@ -27,9 +20,21 @@ defmodule ElixirScript.Output do {module, name, path, import_path} end) + prepared_modules = modules + |> Enum.filter(fn {_, info} -> Map.has_key?(info, :js_ast) end) + |> Enum.map(fn {module, info} -> + {module, info.js_ast, filter_used_modules(info.used_modules, pid)} + end + ) + create_modules(prepared_modules, opts, js_modules) end + defp filter_used_modules(used_modules, pid) do + used_modules + |> Enum.filter(fn module -> ModuleState.is_global_module(pid, module) == false end) + end + defp concat(code) do """ 'use strict'; diff --git a/lib/elixir_script/passes/translate/module.ex b/lib/elixir_script/passes/translate/module.ex index e39daadc..ebe68bec 100644 --- a/lib/elixir_script/passes/translate/module.ex +++ b/lib/elixir_script/passes/translate/module.ex @@ -30,6 +30,7 @@ defmodule ElixirScript.Translate.Module do } = info used = Map.get(info, :used) + remove_unused_functions = ModuleState.remove_unused_functions(pid) state = %{ module: module, @@ -50,7 +51,12 @@ defmodule ElixirScript.Translate.Module do Enum.filter(reachable_defs, fn { {:start, 2}, _, _, _ } -> true { {:__struct__, _}, _, _, _ } -> true - { name, _, _, _} -> name in used + { name, _, _, _} -> + if remove_unused_functions do + name in used + else + true + end _ -> false end) end diff --git a/lib/elixir_script/state.ex b/lib/elixir_script/state.ex index 7a4e03e6..b211a4e8 100644 --- a/lib/elixir_script/state.ex +++ b/lib/elixir_script/state.ex @@ -3,12 +3,13 @@ defmodule ElixirScript.State do # Holds the state for the ElixirScript compiler - def start_link() do + def start_link(compiler_opts) do Agent.start_link(fn -> %{ modules: Keyword.new, js_modules: [], - in_memory_modules: [] + in_memory_modules: [], + compiler_opts: compiler_opts, } end) end @@ -95,6 +96,20 @@ defmodule ElixirScript.State do end) end + def is_global_module(pid, module) do + Agent.get(pid, fn(state) -> + result = Enum.find(state.js_modules, fn {mod, _, _} -> mod == module end) + + if result == nil, do: false, else: true + end) + end + + def remove_unused_functions(pid) do + Agent.get(pid, fn(state) -> + state.compiler_opts.remove_unused_functions + end) + end + def get_js_module_name(pid, module) do Agent.get(pid, fn(state) -> {_, name, _} = state.js_modules diff --git a/lib/elixir_script_test/test.ex b/lib/elixir_script_test/test.ex index c1f5bb6a..3c8fb99b 100644 --- a/lib/elixir_script_test/test.ex +++ b/lib/elixir_script_test/test.ex @@ -79,9 +79,9 @@ defmodule ElixirScript.Test do setup: 1, setup: 2, setup_all: 1, setup_all: 2, teardown: 1, teardown: 2, - teardown_all: 1, teardown_all: 2 + teardown_all: 1, teardown_all: 2, + assert: 1, assert: 2 ] - import ExUnit.Assertions def __elixirscript_test_module__, do: true end diff --git a/lib/elixir_script_test/test/callbacks.ex b/lib/elixir_script_test/test/callbacks.ex index f314c1c1..1f310e39 100644 --- a/lib/elixir_script_test/test/callbacks.ex +++ b/lib/elixir_script_test/test/callbacks.ex @@ -2,6 +2,7 @@ defmodule ElixirScript.Test.Callbacks do @moduledoc """ Defines ElixirScript.Test callbacks """ + require ExUnit.Assertions @doc """ Called before all tests are run in a test file @@ -114,4 +115,16 @@ defmodule ElixirScript.Test.Callbacks do end end end + + defmacro assert(assertion) do + quote do + ExUnit.Assertions.assert(unquote(assertion)) + end + end + + defmacro assert(value, message) do + quote do + ExUnit.Assertions.assert(unquote(value), unquote(message)) + end + end end From a5b3f42ba113eebb1a20617f98109c8c06aa1b77 Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Sat, 9 Dec 2017 16:43:32 -0600 Subject: [PATCH 371/418] Fix some compiler errors --- lib/elixir_script/passes/translate/form.ex | 15 ++++++++++++- .../passes/translate/forms/for.ex | 7 ++----- .../passes/translate/forms/match.ex | 21 ++++++++----------- .../passes/translate/function.ex | 2 +- 4 files changed, 26 insertions(+), 19 deletions(-) diff --git a/lib/elixir_script/passes/translate/form.ex b/lib/elixir_script/passes/translate/form.ex index 3f580783..475b4e02 100644 --- a/lib/elixir_script/passes/translate/form.ex +++ b/lib/elixir_script/passes/translate/form.ex @@ -392,13 +392,26 @@ defmodule ElixirScript.Translate.Form do defp compile_params(params, state) do {params, var_decs} = Enum.map_reduce(params, [], fn + ({:=, _, [{left_var, _, atom} = left, right]} = ast, acc) when is_atom(atom) -> + case Atom.to_string(left_var) do + "_" <> _ -> + {compile!(right, state), acc} + _ -> + {ast, state} = compile(ast, state) + left = compile!(left, state) + + {left, acc ++ List.wrap(ast)} + end + ({:=, _, [left, _]} = ast, acc) -> {ast, state} = compile(ast, state) left = compile!(left, state) {left, acc ++ List.wrap(ast)} (x, acc) -> - {compile!(x, state), acc} + compiled = compile!(x, state) + + {compiled, acc} end) {var_decs, params} diff --git a/lib/elixir_script/passes/translate/forms/for.ex b/lib/elixir_script/passes/translate/forms/for.ex index d037e3f9..dcbbded8 100644 --- a/lib/elixir_script/passes/translate/forms/for.ex +++ b/lib/elixir_script/passes/translate/forms/for.ex @@ -96,12 +96,9 @@ defmodule ElixirScript.Translate.Forms.For do defp create_function_expression(ast, state, module_state) do - { ast, _ } = Enum.map_reduce(List.wrap(ast), module_state, fn x, acc_state -> - Form.compile(x, acc_state) - end) - ast = ast - |> List.flatten + |> ElixirScript.Translate.Function.compile_block(module_state) + |> elem(0) |> Clause.return_last_statement Helpers.arrow_function( diff --git a/lib/elixir_script/passes/translate/forms/match.ex b/lib/elixir_script/passes/translate/forms/match.ex index db146339..f09a3259 100644 --- a/lib/elixir_script/passes/translate/forms/match.ex +++ b/lib/elixir_script/passes/translate/forms/match.ex @@ -56,11 +56,15 @@ defmodule ElixirScript.Translate.Forms.Match do defp compile_match(%{patterns: [left], expression: right}, state) do { right_ast, state } = Form.compile(right, state) - {var_dec, right_ast} = case right_ast do - [variable_declaration, x] -> - {variable_declaration, x} + {var_decs, right_ast} = case right_ast do + x when is_list(x) -> + l = Enum.reverse(x) + [head | tail] = l + l = Enum.reverse(tail) + + {l, head} x -> - {nil, x} + {[], x} end { patterns, params, state } = Pattern.compile([left], state) @@ -84,14 +88,7 @@ defmodule ElixirScript.Translate.Forms.Match do List.wrap(array_pattern) end - js_ast = case var_dec do - nil -> - js_ast - x -> - [x] ++ js_ast - end - - { js_ast, state } + { var_decs ++ js_ast, state } end defp compile_match(%{patterns: lefts, expression: right}, state) do diff --git a/lib/elixir_script/passes/translate/function.ex b/lib/elixir_script/passes/translate/function.ex index 23888453..dc0ff282 100644 --- a/lib/elixir_script/passes/translate/function.ex +++ b/lib/elixir_script/passes/translate/function.ex @@ -173,7 +173,7 @@ defmodule ElixirScript.Translate.Function do {ast, state} end - @spec update_last_call([ESTree.Node.t], map) :: ESTree.Node.t + @spec update_last_call([ESTree.Node.t], map) :: list def update_last_call(clause_body, %{function: {name, _}, anonymous_fn: anonymous?}) do last_item = List.last(clause_body) function_name = ElixirScript.Translate.Identifier.make_function_name(name) From 25ada67d57f4ce986501a51577afa40a687a0cad Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Sat, 9 Dec 2017 21:39:16 -0600 Subject: [PATCH 372/418] test fixes --- lib/elixir_script/compiler.ex | 2 +- .../passes/translate/forms/for.ex | 5 + .../passes/translate/forms/remote.ex | 10 + .../passes/translate/forms/try.ex | 2 +- lib/elixir_script/passes/translate/module.ex | 6 + lib/elixir_script_test/test.ex | 2 +- .../test/assertion_error.ex | 14 + lib/elixir_script_test/test/callbacks.ex | 39 +- priv/testrunner/index.js | 35 +- priv/testrunner/testRunner.js | 5 + priv/testrunner/vendor.build.js | 406 +++++++++++++++++- .../lib/core/erlang_compat/erlang.js | 10 + src/javascript/lib/core/special_forms.js | 16 +- test/passes/translate/form_test.exs | 2 +- .../passes/translate/forms/bitstring_test.exs | 2 +- test/passes/translate/forms/js_test.exs | 2 +- test/passes/translate/forms/map_test.exs | 2 +- 17 files changed, 524 insertions(+), 36 deletions(-) create mode 100644 lib/elixir_script_test/test/assertion_error.ex diff --git a/lib/elixir_script/compiler.ex b/lib/elixir_script/compiler.ex index 47136068..3c420f60 100644 --- a/lib/elixir_script/compiler.ex +++ b/lib/elixir_script/compiler.ex @@ -94,7 +94,7 @@ defmodule ElixirScript.Compiler do |> Map.put(:output, Keyword.get(opts, :output)) |> Map.put(:format, :es) |> Map.put(:root, Keyword.get(opts, :root, ".")) - |> Map.put(:remove_unused_functions, Keyword.get(opts, :remove_unused_functions, Mix.env == :prod)) + |> Map.put(:remove_unused_functions, Keyword.get(opts, :remove_unused_functions, true)) options = default_options Map.put(options, :module_formatter, ES) diff --git a/lib/elixir_script/passes/translate/forms/for.ex b/lib/elixir_script/passes/translate/forms/for.ex index dcbbded8..a641d480 100644 --- a/lib/elixir_script/passes/translate/forms/for.ex +++ b/lib/elixir_script/passes/translate/forms/for.ex @@ -78,6 +78,11 @@ defmodule ElixirScript.Translate.Forms.For do ([into: expression], state) -> %{state | into: Form.compile!(expression, module_state)} + ([do: expression2, into: expression], state) -> + fun = create_function_expression(expression2, state, module_state) + + %{state | into: Form.compile!(expression, module_state), fun: fun} + ([into: expression, do: expression2], state) -> fun = create_function_expression(expression2, state, module_state) diff --git a/lib/elixir_script/passes/translate/forms/remote.ex b/lib/elixir_script/passes/translate/forms/remote.ex index e39f381f..97c3decd 100644 --- a/lib/elixir_script/passes/translate/forms/remote.ex +++ b/lib/elixir_script/passes/translate/forms/remote.ex @@ -54,6 +54,16 @@ defmodule ElixirScript.Translate.Forms.Remote do { ast, state } end + def compile({:., _, [:erlang, :"=<"]}, state) do + ast = erlang_compat_function("erlang", "lessThanEqualTo") + { ast, state } + end + + def compile({:., _, [:erlang, :+]}, state) do + ast = erlang_compat_function("erlang", "add") + { ast, state } + end + def compile({:., _, [module, function]}, state) when module in @erlang_modules do ast = J.member_expression( Helpers.core_module(module), diff --git a/lib/elixir_script/passes/translate/forms/try.ex b/lib/elixir_script/passes/translate/forms/try.ex index 46add57f..3d3c1283 100644 --- a/lib/elixir_script/passes/translate/forms/try.ex +++ b/lib/elixir_script/passes/translate/forms/try.ex @@ -62,7 +62,7 @@ defmodule ElixirScript.Translate.Forms.Try do names = Enum.map(names, &make_exception_ast(&1)) param = {:_e, context, atom} - reason_call = {{:., [], [{:_e0, context, atom}, :__reason]}, [], []} + reason_call = {{:., [], [param, :__reason]}, [], []} reason_call = {{:., [], [reason_call, :__struct__]}, [], []} reason_call = {{:., [], [reason_call, :__MODULE__]}, [], []} diff --git a/lib/elixir_script/passes/translate/module.ex b/lib/elixir_script/passes/translate/module.ex index ebe68bec..58638e02 100644 --- a/lib/elixir_script/passes/translate/module.ex +++ b/lib/elixir_script/passes/translate/module.ex @@ -6,6 +6,11 @@ defmodule ElixirScript.Translate.Module do alias ElixirScript.State, as: ModuleState alias ElixirScript.Translate.Form + @operators [ + :+, :-, :*, :/, :!=, :==, :===, :<=, :>=, :=~, :++, + :!==, :--, :<, :> + ] + @doc """ Translate the given module's ast to JavaScript AST @@ -51,6 +56,7 @@ defmodule ElixirScript.Translate.Module do Enum.filter(reachable_defs, fn { {:start, 2}, _, _, _ } -> true { {:__struct__, _}, _, _, _ } -> true + { {name, _}, _, _, _ } when name in @operators -> false { name, _, _, _} -> if remove_unused_functions do name in used diff --git a/lib/elixir_script_test/test.ex b/lib/elixir_script_test/test.ex index 3c8fb99b..d78d0778 100644 --- a/lib/elixir_script_test/test.ex +++ b/lib/elixir_script_test/test.ex @@ -105,7 +105,7 @@ defmodule ElixirScript.Test do exit_status = node_test_runner(js_files) # Delete directory at the end - File.rm_rf!(output) + # File.rm_rf!(output) case exit_status do 0 -> diff --git a/lib/elixir_script_test/test/assertion_error.ex b/lib/elixir_script_test/test/assertion_error.ex new file mode 100644 index 00000000..c591a95d --- /dev/null +++ b/lib/elixir_script_test/test/assertion_error.ex @@ -0,0 +1,14 @@ +defmodule ElixirScript.Test.AssertionError do + @moduledoc """ + Raised to signal an assertion error. + """ + + @no_value :ex_unit_no_meaningful_value + + defexception left: @no_value, + right: @no_value, + message: @no_value, + expr: @no_value, + file: @no_value, + line: @no_value +end diff --git a/lib/elixir_script_test/test/callbacks.ex b/lib/elixir_script_test/test/callbacks.ex index 1f310e39..c6edc51b 100644 --- a/lib/elixir_script_test/test/callbacks.ex +++ b/lib/elixir_script_test/test/callbacks.ex @@ -2,7 +2,6 @@ defmodule ElixirScript.Test.Callbacks do @moduledoc """ Defines ElixirScript.Test callbacks """ - require ExUnit.Assertions @doc """ Called before all tests are run in a test file @@ -117,14 +116,44 @@ defmodule ElixirScript.Test.Callbacks do end defmacro assert(assertion) do - quote do - ExUnit.Assertions.assert(unquote(assertion)) + %{file: file, line: line} = __CALLER__ + + quote [file: file, line: line] do + require ExUnit.Assertions + try do + ExUnit.Assertions.assert(unquote(assertion)) + rescue + x in [ExUnit.AssertionError] -> + raise(ElixirScript.Test.AssertionError, [ + left: x.left, + right: x.right, + message: x.message, + expr: x.expr, + file: unquote(file), + line: unquote(line) + ]) + end end end defmacro assert(value, message) do - quote do - ExUnit.Assertions.assert(unquote(value), unquote(message)) + %{file: file, line: line} = __CALLER__ + + quote [file: file, line: line] do + require ExUnit.Assertions + try do + ExUnit.Assertions.assert(unquote(value), unquote(message)) + rescue + x in [ExUnit.AssertionError] -> + raise(ElixirScript.Test.AssertionError, [ + left: x.left, + right: x.right, + message: x.message, + expr: x.expr, + file: unquote(file), + line: unquote(line) + ]) + end end end end diff --git a/priv/testrunner/index.js b/priv/testrunner/index.js index 3096fa41..9dddc392 100644 --- a/priv/testrunner/index.js +++ b/priv/testrunner/index.js @@ -4,20 +4,25 @@ const Colors = require('./colors.js').default; const testFiles = process.argv.slice(2); console.time('Finished in'); -runner.start(testFiles).then((results) => { - const testsFailed = results.failed > 0; +runner + .start(testFiles) + .then((results) => { + const testsFailed = results.failed > 0; - process.stdout.write('\n\n'); - console.timeEnd('Finished in'); - console.log( - testsFailed ? Colors.fg.Red : Colors.fg.Green, - `${results.tests} tests, ${results.success} succeeded, ${results.failed} failed\n`, - Colors.Reset, - ); + process.stdout.write('\n\n'); + console.timeEnd('Finished in'); + console.log( + testsFailed ? Colors.fg.Red : Colors.fg.Green, + `${results.tests} tests, ${results.success} succeeded, ${results.failed} failed\n`, + Colors.Reset, + ); - if (testsFailed) { - process.exit(1); - } else { - process.exit(0); - } -}); + if (testsFailed) { + process.exit(1); + } else { + process.exit(0); + } + }) + .catch((e) => { + console.log(e); + }); diff --git a/priv/testrunner/testRunner.js b/priv/testrunner/testRunner.js index b3d1eca9..1b9eb7ae 100644 --- a/priv/testrunner/testRunner.js +++ b/priv/testrunner/testRunner.js @@ -97,10 +97,13 @@ function runTest(mod, test, incomingContext, results) { function handleError(e, test, results, mod) { if (e.__reason) { if (e.__reason instanceof Map && e.__reason.get(Symbol.for('message'))) { + console.log(e.__reason); const errorMessage = e.__reason.get(Symbol.for('message')); const expr = e.__reason.get(Symbol.for('expr')); const left = e.__reason.get(Symbol.for('left')); const right = e.__reason.get(Symbol.for('right')); + const file = e.__reason.get(Symbol.for('file')); + const line = e.__reason.get(Symbol.for('line')); const moduleName = Symbol.keyFor(mod.default.__MODULE__).replace('Elixir.', ''); let testMessage = test.get(Symbol.for('message')); testMessage = `${results.failed}) ${testMessage} (${moduleName})`; @@ -109,6 +112,8 @@ function handleError(e, test, results, mod) { console.log(Colors.fg.Red, errorMessage, Colors.Reset); printErrorLine(left, 'left'); printErrorLine(right, 'right'); + printErrorLine(file, 'file'); + printErrorLine(line, 'line'); } } else { console.log(e); diff --git a/priv/testrunner/vendor.build.js b/priv/testrunner/vendor.build.js index 9d49e34d..6e808208 100644 --- a/priv/testrunner/vendor.build.js +++ b/priv/testrunner/vendor.build.js @@ -1,2 +1,404 @@ -class Tuple{constructor(...a){this.values=Object.freeze(a),this.length=this.values.length}get(a){return this.values[a]}count(){return this.values.length}[Symbol.iterator](){return this.values[Symbol.iterator]()}toString(){let a,b='';for(a=0;a'}}let ref_counter=-1;class Reference{constructor(){++ref_counter,this.id=ref_counter,this.ref=Symbol()}toString(){return'Ref#<0.0.0.'+this.id+'>'}}class BitString{constructor(...a){this.value=Object.freeze(this.process(a)),this.length=this.value.length,this.bit_size=8*this.length,this.byte_size=this.length}get(a){return this.value[a]}count(){return this.value.length}slice(a,b=null){let c=this.value.slice(a,b),d=c.map((a)=>BitString.integer(a));return new BitString(...d)}[Symbol.iterator](){return this.value[Symbol.iterator]()}toString(){var a,b='';for(a=0;a>'}process(a){let b=[];var c;for(c=0;cb?c.push(b):2048>b?c.push(192|b>>6,128|63&b):55296>b||57344<=b?c.push(224|b>>12,128|63&b>>6,128|63&b):(d++,b=65536+((1023&b)<<10|1023&a.charCodeAt(d)),c.push(240|b>>18,128|63&b>>12,128|63&b>>6,128|63&b));return c}static toUTF16Array(a){for(var b,c=[],d=0;d=b?(c.push(0),c.push(b)):(c.push(255&b>>8),c.push(255&b));return c}static toUTF32Array(a){for(var b,c=[],d=0;d=b?(c.push(0),c.push(0),c.push(0),c.push(b)):(c.push(0),c.push(0),c.push(255&b>>8),c.push(255&b));return c}//http://stackoverflow.com/questions/2003493/javascript-float-from-to-bits -static float32ToBytes(a){var b=[],c=new ArrayBuffer(4);new Float32Array(c)[0]=a;let d=new Uint32Array(c)[0];return b.push(255&d>>24),b.push(255&d>>16),b.push(255&d>>8),b.push(255&d),b}static float64ToBytes(a){var b=[],c=new ArrayBuffer(8);new Float64Array(c)[0]=a;var d=new Uint32Array(c)[0],e=new Uint32Array(c)[1];return b.push(255&e>>24),b.push(255&e>>16),b.push(255&e>>8),b.push(255&e),b.push(255&d>>24),b.push(255&d>>16),b.push(255&d>>8),b.push(255&d),b}}var ErlangTypes={Tuple,PID,Reference,BitString},vendor={ErlangTypes};export default vendor; +class Tuple { + constructor(...args) { + this.values = Object.freeze(args); + this.length = this.values.length; + } + + get(index) { + return this.values[index]; + } + + count() { + return this.values.length; + } + + [Symbol.iterator]() { + return this.values[Symbol.iterator](); + } + + toString() { + let i, + s = ''; + for (i = 0; i < this.values.length; i++) { + if (s !== '') { + s += ', '; + } + + const stringToAppend = this.values[i] ? this.values[i].toString() : ''; + + s += stringToAppend; + } + + return '{' + s + '}'; + } + + put_elem(index, elem) { + if (index === this.length) { + let new_values = this.values.concat([elem]); + return new Tuple(...new_values); + } + + let new_values = this.values.concat([]); + new_values.splice(index, 0, elem); + return new Tuple(...new_values); + } + + remove_elem(index) { + let new_values = this.values.concat([]); + new_values.splice(index, 1); + return new Tuple(...new_values); + } +} + +let process_counter = -1; + +class PID { + constructor() { + process_counter = process_counter + 1; + this.id = process_counter; + } + + toString() { + return 'PID#<0.' + this.id + '.0>'; + } +} + +let ref_counter = -1; + +class Reference { + constructor() { + ref_counter = ref_counter + 1; + this.id = ref_counter; + this.ref = Symbol(); + } + + toString() { + return 'Ref#<0.0.0.' + this.id + '>'; + } +} + +class BitString { + constructor(...args) { + this.value = Object.freeze(this.process(args)); + this.length = this.value.length; + this.bit_size = this.length * 8; + this.byte_size = this.length; + } + + get(index) { + return this.value[index]; + } + + count() { + return this.value.length; + } + + slice(start, end = null) { + let s = this.value.slice(start, end); + let ms = s.map(elem => BitString.integer(elem)); + return new BitString(...ms); + } + + [Symbol.iterator]() { + return this.value[Symbol.iterator](); + } + + toString() { + var i, + s = ''; + for (i = 0; i < this.count(); i++) { + if (s !== '') { + s += ', '; + } + s += this.get(i).toString(); + } + + return '<<' + s + '>>'; + } + + process(bitStringParts) { + let processed_values = []; + + var i; + for (i = 0; i < bitStringParts.length; i++) { + let processed_value = this['process_' + bitStringParts[i].type](bitStringParts[i]); + + for (let attr of bitStringParts[i].attributes) { + processed_value = this['process_' + attr](processed_value); + } + + processed_values = processed_values.concat(processed_value); + } + + return processed_values; + } + + process_integer(value) { + return value.value; + } + + process_float(value) { + if (value.size === 64) { + return BitString.float64ToBytes(value.value); + } else if (value.size === 32) { + return BitString.float32ToBytes(value.value); + } + + throw new Error('Invalid size for float'); + } + + process_bitstring(value) { + return value.value.value; + } + + process_binary(value) { + return BitString.toUTF8Array(value.value); + } + + process_utf8(value) { + return BitString.toUTF8Array(value.value); + } + + process_utf16(value) { + return BitString.toUTF16Array(value.value); + } + + process_utf32(value) { + return BitString.toUTF32Array(value.value); + } + + process_signed(value) { + return new Uint8Array([value])[0]; + } + + process_unsigned(value) { + return value; + } + + process_native(value) { + return value; + } + + process_big(value) { + return value; + } + + process_little(value) { + return value.reverse(); + } + + process_size(value) { + return value; + } + + process_unit(value) { + return value; + } + + static integer(value) { + return BitString.wrap(value, { type: 'integer', unit: 1, size: 8 }); + } + + static float(value) { + return BitString.wrap(value, { type: 'float', unit: 1, size: 64 }); + } + + static bitstring(value) { + return BitString.wrap(value, { + type: 'bitstring', + unit: 1, + size: value.bit_size + }); + } + + static bits(value) { + return BitString.bitstring(value); + } + + static binary(value) { + return BitString.wrap(value, { + type: 'binary', + unit: 8, + size: value.length + }); + } + + static bytes(value) { + return BitString.binary(value); + } + + static utf8(value) { + return BitString.wrap(value, { type: 'utf8', unit: 1, size: value.length }); + } + + static utf16(value) { + return BitString.wrap(value, { + type: 'utf16', + unit: 1, + size: value.length * 2 + }); + } + + static utf32(value) { + return BitString.wrap(value, { + type: 'utf32', + unit: 1, + size: value.length * 4 + }); + } + + static signed(value) { + return BitString.wrap(value, {}, 'signed'); + } + + static unsigned(value) { + return BitString.wrap(value, {}, 'unsigned'); + } + + static native(value) { + return BitString.wrap(value, {}, 'native'); + } + + static big(value) { + return BitString.wrap(value, {}, 'big'); + } + + static little(value) { + return BitString.wrap(value, {}, 'little'); + } + + static size(value, count) { + return BitString.wrap(value, { size: count }); + } + + static unit(value, count) { + return BitString.wrap(value, { unit: count }); + } + + static wrap(value, opt, new_attribute = null) { + let the_value = value; + + if (!(value instanceof Object)) { + the_value = { value: value, attributes: [] }; + } + + the_value = Object.assign(the_value, opt); + + if (new_attribute) { + the_value.attributes.push(new_attribute); + } + + return the_value; + } + + static toUTF8Array(str) { + var utf8 = []; + for (var i = 0; i < str.length; i++) { + var charcode = str.charCodeAt(i); + if (charcode < 0x80) { + utf8.push(charcode); + } else if (charcode < 0x800) { + utf8.push(0xc0 | charcode >> 6, 0x80 | charcode & 0x3f); + } else if (charcode < 0xd800 || charcode >= 0xe000) { + utf8.push(0xe0 | charcode >> 12, 0x80 | charcode >> 6 & 0x3f, 0x80 | charcode & 0x3f); + } else { + // surrogate pair + i++; + // UTF-16 encodes 0x10000-0x10FFFF by + // subtracting 0x10000 and splitting the + // 20 bits of 0x0-0xFFFFF into two halves + charcode = 0x10000 + ((charcode & 0x3ff) << 10 | str.charCodeAt(i) & 0x3ff); + utf8.push(0xf0 | charcode >> 18, 0x80 | charcode >> 12 & 0x3f, 0x80 | charcode >> 6 & 0x3f, 0x80 | charcode & 0x3f); + } + } + return utf8; + } + + static toUTF16Array(str) { + var utf16 = []; + for (var i = 0; i < str.length; i++) { + var codePoint = str.codePointAt(i); + + if (codePoint <= 255) { + utf16.push(0); + utf16.push(codePoint); + } else { + utf16.push(codePoint >> 8 & 0xff); + utf16.push(codePoint & 0xff); + } + } + return utf16; + } + + static toUTF32Array(str) { + var utf32 = []; + for (var i = 0; i < str.length; i++) { + var codePoint = str.codePointAt(i); + + if (codePoint <= 255) { + utf32.push(0); + utf32.push(0); + utf32.push(0); + utf32.push(codePoint); + } else { + utf32.push(0); + utf32.push(0); + utf32.push(codePoint >> 8 & 0xff); + utf32.push(codePoint & 0xff); + } + } + return utf32; + } + + //http://stackoverflow.com/questions/2003493/javascript-float-from-to-bits + static float32ToBytes(f) { + var bytes = []; + + var buf = new ArrayBuffer(4); + new Float32Array(buf)[0] = f; + + let intVersion = new Uint32Array(buf)[0]; + + bytes.push(intVersion >> 24 & 0xff); + bytes.push(intVersion >> 16 & 0xff); + bytes.push(intVersion >> 8 & 0xff); + bytes.push(intVersion & 0xff); + + return bytes; + } + + static float64ToBytes(f) { + var bytes = []; + + var buf = new ArrayBuffer(8); + new Float64Array(buf)[0] = f; + + var intVersion1 = new Uint32Array(buf)[0]; + var intVersion2 = new Uint32Array(buf)[1]; + + bytes.push(intVersion2 >> 24 & 0xff); + bytes.push(intVersion2 >> 16 & 0xff); + bytes.push(intVersion2 >> 8 & 0xff); + bytes.push(intVersion2 & 0xff); + + bytes.push(intVersion1 >> 24 & 0xff); + bytes.push(intVersion1 >> 16 & 0xff); + bytes.push(intVersion1 >> 8 & 0xff); + bytes.push(intVersion1 & 0xff); + + return bytes; + } +} + +var ErlangTypes = { + Tuple, + PID, + Reference, + BitString +}; + +var vendor = { + ErlangTypes +}; + +export default vendor; diff --git a/src/javascript/lib/core/erlang_compat/erlang.js b/src/javascript/lib/core/erlang_compat/erlang.js index 18ec72d9..ddece09d 100644 --- a/src/javascript/lib/core/erlang_compat/erlang.js +++ b/src/javascript/lib/core/erlang_compat/erlang.js @@ -521,6 +521,14 @@ function function_exported(module, _function) { return module[_function] != null; } +function lessThanEqualTo(one, two) { + return one <= two; +} + +function add(one, two) { + return one + two; +} + export default { atom_to_binary, binary_to_atom, @@ -589,4 +597,6 @@ export default { nodes, function_exported, equals, + lessThanEqualTo, + add, }; diff --git a/src/javascript/lib/core/special_forms.js b/src/javascript/lib/core/special_forms.js index 988d341f..7964bf3d 100644 --- a/src/javascript/lib/core/special_forms.js +++ b/src/javascript/lib/core/special_forms.js @@ -62,12 +62,16 @@ function _try(do_fun, rescue_function, catch_fun, else_function, after_function) let ex_result = null; if (rescue_function) { try { - ex_result = rescue_function(e); + let value = e; + if (e.__reason) { + value = e.__reason; + value.set('__reason', e.__reason); + } + + ex_result = rescue_function(value); return ex_result; } catch (ex) { - if (ex instanceof Core.Patterns.MatchError) { - throw ex; - } + throw ex; } } @@ -76,9 +80,7 @@ function _try(do_fun, rescue_function, catch_fun, else_function, after_function) ex_result = catch_fun(e); return ex_result; } catch (ex) { - if (ex instanceof Core.Patterns.MatchError) { - throw ex; - } + throw ex; } } diff --git a/test/passes/translate/form_test.exs b/test/passes/translate/form_test.exs index d40f4e30..6b8bae94 100644 --- a/test/passes/translate/form_test.exs +++ b/test/passes/translate/form_test.exs @@ -7,7 +7,7 @@ defmodule ElixirScript.Translate.Forms.Test do setup_all do - {:ok, pid} = ElixirScript.State.start_link() + {:ok, pid} = ElixirScript.State.start_link(%{}) state = %{ pid: pid, diff --git a/test/passes/translate/forms/bitstring_test.exs b/test/passes/translate/forms/bitstring_test.exs index e7e76ccd..1d62517d 100644 --- a/test/passes/translate/forms/bitstring_test.exs +++ b/test/passes/translate/forms/bitstring_test.exs @@ -4,7 +4,7 @@ defmodule ElixirScript.Translate.Forms.Bitstring.Test do alias ESTree.Tools.Builder, as: J setup_all do - {:ok, pid} = ElixirScript.State.start_link() + {:ok, pid} = ElixirScript.State.start_link(%{}) state = %{ pid: pid, diff --git a/test/passes/translate/forms/js_test.exs b/test/passes/translate/forms/js_test.exs index d1eef57f..d3989cb9 100644 --- a/test/passes/translate/forms/js_test.exs +++ b/test/passes/translate/forms/js_test.exs @@ -4,7 +4,7 @@ defmodule ElixirScript.Translate.Forms.JS.Test do alias ESTree.Tools.Builder, as: J setup_all do - {:ok, pid} = ElixirScript.State.start_link() + {:ok, pid} = ElixirScript.State.start_link(%{}) state = %{ pid: pid, diff --git a/test/passes/translate/forms/map_test.exs b/test/passes/translate/forms/map_test.exs index ec181caf..79454147 100644 --- a/test/passes/translate/forms/map_test.exs +++ b/test/passes/translate/forms/map_test.exs @@ -5,7 +5,7 @@ defmodule ElixirScript.Translate.Forms.Map.Test do use ExUnitProperties setup_all do - {:ok, pid} = ElixirScript.State.start_link() + {:ok, pid} = ElixirScript.State.start_link(%{}) state = %{ pid: pid From a21e0037c2b8cd2f1123b432faa2b6f2e23e85f3 Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Sun, 10 Dec 2017 13:42:27 -0600 Subject: [PATCH 373/418] Fix lints --- lib/elixir_script/compiler.ex | 4 +++- lib/elixir_script/passes/output.ex | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/lib/elixir_script/compiler.ex b/lib/elixir_script/compiler.ex index 3c420f60..06000df4 100644 --- a/lib/elixir_script/compiler.ex +++ b/lib/elixir_script/compiler.ex @@ -90,11 +90,13 @@ defmodule ElixirScript.Compiler do end defp build_compiler_options(opts) do + remove_used_functions? = Keyword.get(opts, :remove_unused_functions, true) + default_options = Map.new |> Map.put(:output, Keyword.get(opts, :output)) |> Map.put(:format, :es) |> Map.put(:root, Keyword.get(opts, :root, ".")) - |> Map.put(:remove_unused_functions, Keyword.get(opts, :remove_unused_functions, true)) + |> Map.put(:remove_unused_functions, remove_used_functions?) options = default_options Map.put(options, :module_formatter, ES) diff --git a/lib/elixir_script/passes/output.ex b/lib/elixir_script/passes/output.ex index 20b6e063..9a519fff 100644 --- a/lib/elixir_script/passes/output.ex +++ b/lib/elixir_script/passes/output.ex @@ -32,7 +32,9 @@ defmodule ElixirScript.Output do defp filter_used_modules(used_modules, pid) do used_modules - |> Enum.filter(fn module -> ModuleState.is_global_module(pid, module) == false end) + |> Enum.filter(fn module -> + ModuleState.is_global_module(pid, module) == false + end) end defp concat(code) do From 313605cf8eae7500ea5329a179d39691e42c046c Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Sun, 10 Dec 2017 13:48:09 -0600 Subject: [PATCH 374/418] Remove extra console.log for debugging. Use reraise for raising test errors --- lib/elixir_script_test/test/callbacks.ex | 8 ++++---- priv/testrunner/testRunner.js | 1 - test_elixir_script/integration_test.exs | 2 +- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/lib/elixir_script_test/test/callbacks.ex b/lib/elixir_script_test/test/callbacks.ex index c6edc51b..a516737d 100644 --- a/lib/elixir_script_test/test/callbacks.ex +++ b/lib/elixir_script_test/test/callbacks.ex @@ -124,14 +124,14 @@ defmodule ElixirScript.Test.Callbacks do ExUnit.Assertions.assert(unquote(assertion)) rescue x in [ExUnit.AssertionError] -> - raise(ElixirScript.Test.AssertionError, [ + reraise(ElixirScript.Test.AssertionError, [ left: x.left, right: x.right, message: x.message, expr: x.expr, file: unquote(file), line: unquote(line) - ]) + ], []) end end end @@ -145,14 +145,14 @@ defmodule ElixirScript.Test.Callbacks do ExUnit.Assertions.assert(unquote(value), unquote(message)) rescue x in [ExUnit.AssertionError] -> - raise(ElixirScript.Test.AssertionError, [ + reraise(ElixirScript.Test.AssertionError, [ left: x.left, right: x.right, message: x.message, expr: x.expr, file: unquote(file), line: unquote(line) - ]) + ], []) end end end diff --git a/priv/testrunner/testRunner.js b/priv/testrunner/testRunner.js index 1b9eb7ae..3bdd9a7c 100644 --- a/priv/testrunner/testRunner.js +++ b/priv/testrunner/testRunner.js @@ -97,7 +97,6 @@ function runTest(mod, test, incomingContext, results) { function handleError(e, test, results, mod) { if (e.__reason) { if (e.__reason instanceof Map && e.__reason.get(Symbol.for('message'))) { - console.log(e.__reason); const errorMessage = e.__reason.get(Symbol.for('message')); const expr = e.__reason.get(Symbol.for('expr')); const left = e.__reason.get(Symbol.for('left')); diff --git a/test_elixir_script/integration_test.exs b/test_elixir_script/integration_test.exs index 491d88c7..ca30430f 100644 --- a/test_elixir_script/integration_test.exs +++ b/test_elixir_script/integration_test.exs @@ -16,7 +16,7 @@ defmodule ElixirScript.Integration.Test do end test "shorthand failure" do - orders = [%{email: "test@hotmail.com"},%{email: "test2@hotmail.com"}] + orders = [%{email: "test@hotmail.com"}, %{email: "test2@hotmail.com"}] val = Enum.reduce(orders, [], &(&2 ++ [ [:option, %{value: &1.email}, &1.email] ])) From d904909c66daeddce7b6cf499a8cb81b3d5cfd19 Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Sun, 10 Dec 2017 17:40:07 -0600 Subject: [PATCH 375/418] Add more test assertions. Make behaviour for test runners --- lib/elixir_script_test/test.ex | 27 +--- lib/elixir_script_test/test/assertions.ex | 161 +++++++++++++++++++++ lib/elixir_script_test/test/callbacks.ex | 42 ------ lib/elixir_script_test/test/runner.ex | 14 ++ lib/elixir_script_test/test/runner/node.ex | 18 +++ 5 files changed, 198 insertions(+), 64 deletions(-) create mode 100644 lib/elixir_script_test/test/assertions.ex create mode 100644 lib/elixir_script_test/test/runner.ex create mode 100644 lib/elixir_script_test/test/runner/node.ex diff --git a/lib/elixir_script_test/test.ex b/lib/elixir_script_test/test.ex index d78d0778..b49de509 100644 --- a/lib/elixir_script_test/test.ex +++ b/lib/elixir_script_test/test.ex @@ -74,14 +74,9 @@ defmodule ElixirScript.Test do defmacro __using__(_opts) do quote do - import ElixirScript.Test.Callbacks, only: [ - test: 2, test: 3, - setup: 1, setup: 2, - setup_all: 1, setup_all: 2, - teardown: 1, teardown: 2, - teardown_all: 1, teardown_all: 2, - assert: 1, assert: 2 - ] + require ExUnit.Assertions + import ElixirScript.Test.Callbacks + import ElixirScript.Test.Assertions def __elixirscript_test_module__, do: true end @@ -102,10 +97,10 @@ defmodule ElixirScript.Test do |> Path.join("Elixir.*.js") |> Path.wildcard() - exit_status = node_test_runner(js_files) + exit_status = ElixirScript.Test.Runner.Node.run(js_files) # Delete directory at the end - # File.rm_rf!(output) + File.rm_rf!(output) case exit_status do 0 -> @@ -114,16 +109,4 @@ defmodule ElixirScript.Test do :error end end - - defp node_test_runner(js_files) do - test_script_path = Path.join([:code.priv_dir(:elixir_script), "testrunner", "index.js"]) - test_script_path = [test_script_path] ++ js_files - {_, exit_status} = System.cmd( - "node", - test_script_path, - into: IO.stream(:stdio, :line) - ) - - exit_status - end end diff --git a/lib/elixir_script_test/test/assertions.ex b/lib/elixir_script_test/test/assertions.ex new file mode 100644 index 00000000..662a8704 --- /dev/null +++ b/lib/elixir_script_test/test/assertions.ex @@ -0,0 +1,161 @@ +defmodule ElixirScript.Test.Assertions do + @moduledoc """ + Defines assertions for use in ElixirScript test. + These are a subset of [ExUnit.Assertions](https://hexdocs.pm/ex_unit/ExUnit.Assertions.html) + """ + + @doc false + def raise_elixir_script_assert(error, file, line) do + reraise(ElixirScript.Test.AssertionError, [ + left: error.left, + right: error.right, + message: error.message, + expr: error.expr, + file: file, + line: line + ], []) + end + + @doc """ + Asserts its argument is a truthy value + """ + defmacro assert(assertion) do + %{file: file, line: line} = __CALLER__ + + quote [file: file, line: line] do + try do + ExUnit.Assertions.assert(unquote(assertion)) + rescue + error in [ExUnit.AssertionError] -> + ElixirScript.Test.Assertions.raise_elixir_script_assert( + error, + unquote(file), + unquote(line) + ) + end + end + end + + @doc """ + Asserts `value` is `true`, displaying the given `message` otherwise. + """ + defmacro assert(value, message) do + %{file: file, line: line} = __CALLER__ + + quote [file: file, line: line] do + try do + ExUnit.Assertions.assert(unquote(value), unquote(message)) + rescue + error in [ExUnit.AssertionError] -> + ElixirScript.Test.Assertions.raise_elixir_script_assert( + error, + unquote(file), + unquote(line) + ) + end + end + end + + @doc """ + Asserts the `exception` is raised during `function` execution. + Returns the rescued exception, fails otherwise. + """ + defmacro assert_raise(exception, function) do + %{file: file, line: line} = __CALLER__ + + quote [file: file, line: line] do + try do + ExUnit.Assertions.assert(unquote(exception), unquote(function)) + rescue + error in [ExUnit.AssertionError] -> + ElixirScript.Test.Assertions.raise_elixir_script_assert( + error, + unquote(file), + unquote(line) + ) + end + end + end + + @doc """ + Asserts the `exception` is raised during `function` execution with + the expected `message`, which can be a `Regex` or an exact `String`. + Returns the rescued exception, fails otherwise. + """ + defmacro assert_raise(exception, message, function) do + %{file: file, line: line} = __CALLER__ + + quote [file: file, line: line] do + try do + ExUnit.Assertions.assert(unquote(exception), unquote(message), unquote(function)) + rescue + error in [ExUnit.AssertionError] -> + ElixirScript.Test.Assertions.raise_elixir_script_assert( + error, + unquote(file), + unquote(line) + ) + end + end + end + + @doc """ + A negative assertion, expects the expression to be `false` or `nil`. + """ + defmacro refute(assertion) do + %{file: file, line: line} = __CALLER__ + + quote [file: file, line: line] do + try do + ExUnit.Assertions.assert(unquote(assertion)) + rescue + error in [ExUnit.AssertionError] -> + ElixirScript.Test.Assertions.raise_elixir_script_assert( + error, + unquote(file), + unquote(line) + ) + end + end + end + + @doc """ + Asserts `value` is `nil` or `false` (that is, `value` is not truthy). + """ + defmacro refute(value, message) do + %{file: file, line: line} = __CALLER__ + + quote [file: file, line: line] do + try do + ExUnit.Assertions.assert(unquote(value), unquote(message)) + rescue + error in [ExUnit.AssertionError] -> + ElixirScript.Test.Assertions.raise_elixir_script_assert( + error, + unquote(file), + unquote(line) + ) + end + end + end + + @doc """ + Fails with a message. + """ + defmacro flunk(message \\ "Flunked!") do + %{file: file, line: line} = __CALLER__ + + quote [file: file, line: line] do + try do + ExUnit.Assertions.flunk(unquote(message)) + rescue + error in [ExUnit.AssertionError] -> + ElixirScript.Test.Assertions.raise_elixir_script_assert( + error, + unquote(file), + unquote(line) + ) + end + end + end +end diff --git a/lib/elixir_script_test/test/callbacks.ex b/lib/elixir_script_test/test/callbacks.ex index a516737d..f314c1c1 100644 --- a/lib/elixir_script_test/test/callbacks.ex +++ b/lib/elixir_script_test/test/callbacks.ex @@ -114,46 +114,4 @@ defmodule ElixirScript.Test.Callbacks do end end end - - defmacro assert(assertion) do - %{file: file, line: line} = __CALLER__ - - quote [file: file, line: line] do - require ExUnit.Assertions - try do - ExUnit.Assertions.assert(unquote(assertion)) - rescue - x in [ExUnit.AssertionError] -> - reraise(ElixirScript.Test.AssertionError, [ - left: x.left, - right: x.right, - message: x.message, - expr: x.expr, - file: unquote(file), - line: unquote(line) - ], []) - end - end - end - - defmacro assert(value, message) do - %{file: file, line: line} = __CALLER__ - - quote [file: file, line: line] do - require ExUnit.Assertions - try do - ExUnit.Assertions.assert(unquote(value), unquote(message)) - rescue - x in [ExUnit.AssertionError] -> - reraise(ElixirScript.Test.AssertionError, [ - left: x.left, - right: x.right, - message: x.message, - expr: x.expr, - file: unquote(file), - line: unquote(line) - ], []) - end - end - end end diff --git a/lib/elixir_script_test/test/runner.ex b/lib/elixir_script_test/test/runner.ex new file mode 100644 index 00000000..e746292b --- /dev/null +++ b/lib/elixir_script_test/test/runner.ex @@ -0,0 +1,14 @@ +defmodule ElixirScript.Test.Runner do + @moduledoc """ + Defines a behaviour for an ElixirScript Test runner + """ + + @doc """ + Callback for running the test runner. + Receives a list of JavaScript files from the + compiled Elixir code. Expects an exit status + representing the success or failure of the + tests + """ + @callback run([binary]) :: integer +end diff --git a/lib/elixir_script_test/test/runner/node.ex b/lib/elixir_script_test/test/runner/node.ex new file mode 100644 index 00000000..31e83667 --- /dev/null +++ b/lib/elixir_script_test/test/runner/node.ex @@ -0,0 +1,18 @@ +defmodule ElixirScript.Test.Runner.Node do + @moduledoc """ + Defines an ElixirScript Test runner using node + """ + @behaviour ElixirScript.Test.Runner + + def run(js_files) do + test_script_path = Path.join([:code.priv_dir(:elixir_script), "testrunner", "index.js"]) + test_script_path = [test_script_path] ++ js_files + {_, exit_status} = System.cmd( + "node", + test_script_path, + into: IO.stream(:stdio, :line) + ) + + exit_status + end +end From 64f9bfe7ff698da4f52ff2c5f1b47ec66a7f4395 Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Sun, 10 Dec 2017 17:42:36 -0600 Subject: [PATCH 376/418] Remove doc for remove_unused --- lib/elixir_script/compiler.ex | 2 -- 1 file changed, 2 deletions(-) diff --git a/lib/elixir_script/compiler.ex b/lib/elixir_script/compiler.ex index 06000df4..36c6de61 100644 --- a/lib/elixir_script/compiler.ex +++ b/lib/elixir_script/compiler.ex @@ -23,8 +23,6 @@ defmodule ElixirScript.Compiler do If a directory is given, file will be named `elixirscript.build.js` * `root`: Optional root for imports of FFI JavaScript modules. Defaults to `.`. - * `remove_unused_functions`: Removed unused functions in output. Defaults to - removing unused functions when Mix.env == :prod """ alias ElixirScript.{ State, From 0a66d2d37420470ce110a7cd1afd453c5e32e9fa Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Sun, 10 Dec 2017 17:44:19 -0600 Subject: [PATCH 377/418] Fix lints --- lib/elixir_script_test/test.ex | 3 +-- lib/elixir_script_test/test/assertions.ex | 6 +++++- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/lib/elixir_script_test/test.ex b/lib/elixir_script_test/test.ex index b49de509..b531b700 100644 --- a/lib/elixir_script_test/test.ex +++ b/lib/elixir_script_test/test.ex @@ -75,8 +75,7 @@ defmodule ElixirScript.Test do defmacro __using__(_opts) do quote do require ExUnit.Assertions - import ElixirScript.Test.Callbacks - import ElixirScript.Test.Assertions + import ElixirScript.Test.{Callbacks, Assertions} def __elixirscript_test_module__, do: true end diff --git a/lib/elixir_script_test/test/assertions.ex b/lib/elixir_script_test/test/assertions.ex index 662a8704..fe61c581 100644 --- a/lib/elixir_script_test/test/assertions.ex +++ b/lib/elixir_script_test/test/assertions.ex @@ -87,7 +87,11 @@ defmodule ElixirScript.Test.Assertions do quote [file: file, line: line] do try do - ExUnit.Assertions.assert(unquote(exception), unquote(message), unquote(function)) + ExUnit.Assertions.assert( + unquote(exception), + unquote(message), + unquote(function) + ) rescue error in [ExUnit.AssertionError] -> ElixirScript.Test.Assertions.raise_elixir_script_assert( From 8e1b987f9e9d97e81e21b895e64aec1c905014e9 Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Sun, 10 Dec 2017 19:20:14 -0600 Subject: [PATCH 378/418] Add delta assertions --- lib/elixir_script_test/test/assertions.ex | 50 +++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/lib/elixir_script_test/test/assertions.ex b/lib/elixir_script_test/test/assertions.ex index fe61c581..7e8e53fe 100644 --- a/lib/elixir_script_test/test/assertions.ex +++ b/lib/elixir_script_test/test/assertions.ex @@ -103,6 +103,31 @@ defmodule ElixirScript.Test.Assertions do end end + @doc """ + Asserts that `value1` and `value2` differ by no more than `delta` + """ + defmacro assert_in_delta(value1, value2, delta, message \\ nil) do + %{file: file, line: line} = __CALLER__ + + quote [file: file, line: line] do + try do + ExUnit.Assertions.assert_in_delta( + unquote(value1), + unquote(value2), + unquote(delta), + unquote(message) + ) + rescue + error in [ExUnit.AssertionError] -> + ElixirScript.Test.Assertions.raise_elixir_script_assert( + error, + unquote(file), + unquote(line) + ) + end + end + end + @doc """ A negative assertion, expects the expression to be `false` or `nil`. """ @@ -143,6 +168,31 @@ defmodule ElixirScript.Test.Assertions do end end + @doc """ + Asserts that `value1` and `value2` are not within `delta` + """ + defmacro refute_in_delta(value1, value2, delta, message \\ nil) do + %{file: file, line: line} = __CALLER__ + + quote [file: file, line: line] do + try do + ExUnit.Assertions.refute_in_delta( + unquote(value1), + unquote(value2), + unquote(delta), + unquote(message) + ) + rescue + error in [ExUnit.AssertionError] -> + ElixirScript.Test.Assertions.raise_elixir_script_assert( + error, + unquote(file), + unquote(line) + ) + end + end + end + @doc """ Fails with a message. """ From d4696fe01f2bf4cc6af3d0d85eb4c01f12599aef Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Tue, 26 Dec 2017 21:00:07 -0600 Subject: [PATCH 379/418] Update version of elixir to 1.6.0-rc.0 --- .tool-versions | 2 +- lib/elixir_script/cli.ex | 51 +++++++++++++++--------------- lib/elixir_script/state.ex | 63 +++++++++++++++++++------------------- 3 files changed, 60 insertions(+), 56 deletions(-) diff --git a/.tool-versions b/.tool-versions index eb307d7d..a9580d64 100644 --- a/.tool-versions +++ b/.tool-versions @@ -1,3 +1,3 @@ erlang 20.1 -elixir 1.5.2-otp-20 +elixir 1.6.0-rc.0-otp-20 nodejs 8.9.1 diff --git a/lib/elixir_script/cli.ex b/lib/elixir_script/cli.ex index 75791304..1eedfc37 100644 --- a/lib/elixir_script/cli.ex +++ b/lib/elixir_script/cli.ex @@ -17,51 +17,54 @@ defmodule ElixirScript.CLI do ] def parse_args(args) do - { options, input, errors } = OptionParser.parse(args, switches: @switches, aliases: @aliases) + {options, input, errors} = OptionParser.parse(args, switches: @switches, aliases: @aliases) cond do length(errors) > 0 -> :help + Keyword.get(options, :help, false) -> :help + Keyword.get(options, :version, false) -> :version + length(input) == 0 -> :help + true -> - { input, options } + {input, options} end - end defp help_message do - """ - usage: elixirscript [options] - the entry module of your application - the path to .ex(s) files to compile - - options: - -o --output [path] places output at the given path. - Can be a directory or filename. - -v --version the current version number - -h --help this message - --root The root import path for FFI imports - """ + """ + usage: elixirscript [options] + the entry module of your application + the path to .ex(s) files to compile + + options: + -o --output [path] places output at the given path. + Can be a directory or filename. + -v --version the current version number + -h --help this message + --root The root import path for FFI imports + """ end def process(:help) do - IO.write help_message() + IO.write(help_message()) end def process(:version) do - IO.write @app_version + IO.write(@app_version) end - def process({ input, options }) do + def process({input, options}) do if options_contains_unknown_values(options) do - process(:help) + process(:help) else - do_process(input, options) + do_process(input, options) end end @@ -76,7 +79,7 @@ defmodule ElixirScript.CLI do end defp options_contains_unknown_values(options) do - Enum.any?(options, fn({key, _value}) -> + Enum.any?(options, fn {key, _value} -> if key in Keyword.keys(@switches) do false else @@ -87,8 +90,8 @@ defmodule ElixirScript.CLI do defp handle_input(input) do input - |> Enum.map(fn(x) -> String.split(x, [" ", ","], trim: true) end) - |> List.flatten - |> Enum.map(fn(x) -> Module.concat([x]) end) + |> Enum.map(fn x -> String.split(x, [" ", ","], trim: true) end) + |> List.flatten() + |> Enum.map(fn x -> Module.concat([x]) end) end end diff --git a/lib/elixir_script/state.ex b/lib/elixir_script/state.ex index b211a4e8..73208ec6 100644 --- a/lib/elixir_script/state.ex +++ b/lib/elixir_script/state.ex @@ -6,10 +6,10 @@ defmodule ElixirScript.State do def start_link(compiler_opts) do Agent.start_link(fn -> %{ - modules: Keyword.new, + modules: Keyword.new(), js_modules: [], in_memory_modules: [], - compiler_opts: compiler_opts, + compiler_opts: compiler_opts } end) end @@ -19,23 +19,24 @@ defmodule ElixirScript.State do end def get_module(pid, module) do - Agent.get(pid, fn(state) -> + Agent.get(pid, fn state -> Keyword.get(state.modules, module) end) end def put_module(pid, module, value) do - Agent.update(pid, fn(state) -> - value = Map.put_new(value, :used, []) - |> Map.put_new(:used_modules, []) + Agent.update(pid, fn state -> + value = + Map.put_new(value, :used, []) + |> Map.put_new(:used_modules, []) modules = Keyword.put(state.modules, module, value) - %{ state | modules: modules } + %{state | modules: modules} end) end def add_used_module(pid, module, used_module) do - Agent.update(pid, fn(state) -> + Agent.update(pid, fn state -> module_info = Keyword.get(state.modules, module) used_modules = Map.get(module_info, :used_modules, []) @@ -44,22 +45,21 @@ defmodule ElixirScript.State do module_info = Map.put(module_info, :used_modules, used_modules) modules = Keyword.put(state.modules, module, module_info) - %{ state | modules: modules } + %{state | modules: modules} end) end - def has_used?(pid, module, func) do - Agent.get(pid, fn(state) -> + Agent.get(pid, fn state -> module_info = Keyword.get(state.modules, module) used = Map.get(module_info, :used, []) - Enum.find(used, fn(x) -> x == func end) != nil + Enum.find(used, fn x -> x == func end) != nil end) end def add_used(pid, module, {_function, _arity} = func) do - Agent.update(pid, fn(state) -> + Agent.update(pid, fn state -> module_info = Keyword.get(state.modules, module) used = Map.get(module_info, :used, []) @@ -68,36 +68,35 @@ defmodule ElixirScript.State do module_info = Map.put(module_info, :used, used) modules = Keyword.put(state.modules, module, module_info) - %{ state | modules: modules } + %{state | modules: modules} end) end def put_javascript_module(pid, module, name, path) do - Agent.update(pid, fn(state) -> + Agent.update(pid, fn state -> js_modules = Map.get(state, :js_modules, []) js_modules = [{module, name, path} | js_modules] - %{ state | js_modules: js_modules } + %{state | js_modules: js_modules} end) end def list_javascript_modules(pid) do - Agent.get(pid, fn(state) -> + Agent.get(pid, fn state -> state.js_modules - |> Enum.map(fn - {module, _name, _path} -> - module + |> Enum.map(fn {module, _name, _path} -> + module end) end) end def js_modules(pid) do - Agent.get(pid, fn(state) -> + Agent.get(pid, fn state -> state.js_modules end) end def is_global_module(pid, module) do - Agent.get(pid, fn(state) -> + Agent.get(pid, fn state -> result = Enum.find(state.js_modules, fn {mod, _, _} -> mod == module end) if result == nil, do: false, else: true @@ -105,42 +104,44 @@ defmodule ElixirScript.State do end def remove_unused_functions(pid) do - Agent.get(pid, fn(state) -> + Agent.get(pid, fn state -> state.compiler_opts.remove_unused_functions end) end def get_js_module_name(pid, module) do - Agent.get(pid, fn(state) -> - {_, name, _} = state.js_modules - |> Enum.find(fn {m, _, _} -> module == m end) + Agent.get(pid, fn state -> + {_, name, _} = + state.js_modules + |> Enum.find(fn {m, _, _} -> module == m end) + name end) end def list_modules(pid) do - Agent.get(pid, fn(state) -> + Agent.get(pid, fn state -> state.modules end) end def get_in_memory_module(pid, module) do - Agent.get(pid, fn(state) -> + Agent.get(pid, fn state -> Keyword.get(state.in_memory_modules, module) end) end def get_in_memory_modules(pid) do - Agent.get(pid, fn(state) -> + Agent.get(pid, fn state -> state.in_memory_modules end) end def put_in_memory_module(pid, module, beam) do - Agent.update(pid, fn(state) -> + Agent.update(pid, fn state -> in_memory_modules = Map.get(state, :in_memory_modules, []) in_memory_modules = Keyword.put(in_memory_modules, module, beam) - %{ state | in_memory_modules: in_memory_modules } + %{state | in_memory_modules: in_memory_modules} end) end end From ed729249c80eb17c0cb13b4fa74604aa0459b97c Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Tue, 26 Dec 2017 21:01:41 -0600 Subject: [PATCH 380/418] Update travis elixir version to 1.6.0-rc.0 --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 3acd9398..78d59677 100644 --- a/.travis.yml +++ b/.travis.yml @@ -9,8 +9,8 @@ install: - npm install -g yarn - yarn before_script: - - wget https://repo.hex.pm/builds/elixir/v1.5.1-otp-20.zip - - unzip -d elixir v1.5.1-otp-20.zip + - wget https://repo.hex.pm/builds/elixir/v1.6.0-rc.0-otp-20.zip + - unzip -d elixir v1.6.0-rc.0-otp-20.zip - export PATH=$(pwd)/elixir/bin:${PATH} - mix local.rebar --force - mix local.hex --force From b15cf00b479667b817ce7e673ed4dcbaf4ed1620 Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Tue, 2 Jan 2018 15:10:56 -0600 Subject: [PATCH 381/418] Require elixir 1.6 --- CHANGELOG.md | 691 ++++++++++++++++++++++++++++++--------------------- mix.exs | 2 +- 2 files changed, 403 insertions(+), 290 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 91b3f895..9c619292 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,26 +1,33 @@ # Change Log + All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/) and this project adheres to [Semantic Versioning](http://semver.org/). ## Unreleased + ## Changed -- Compiler now returns a file per module instead of just one file + +* Compiler now returns a file per module instead of just one file +* Requires Elixir 1.6 ## [0.31.1] - 2017-09-27 + ### Fixed -- Compiler error when `receive` is used as variable name +* Compiler error when `receive` is used as variable name ## [0.31.0] - 2017-09-24 + ### Added -- [Compiler will now accept a path to Elixir Files to compile](https://github.com/elixirscript/elixirscript/issues/420) -- [Added `ElixirScript.JS.map_to_object/2` with options [keys: :string, symbols: false]](https://github.com/elixirscript/elixirscript/issues/362) -- [Added `ElixirScript.JS.object_to_map/1|2` with options [keys: :atom, recurse_array: true]](https://github.com/elixirscript/elixirscript/issues/381) -- [Fully implement `__info__` on modules](https://github.com/elixirscript/elixirscript/pull/378) -- [Concurrent Compilation](https://github.com/elixirscript/elixirscript/issues/376) -- [The following erlang functions have been implemented](https://github.com/elixirscript/elixirscript/issues/306): + +* [Compiler will now accept a path to Elixir Files to compile](https://github.com/elixirscript/elixirscript/issues/420) +* [Added `ElixirScript.JS.map_to_object/2` with options [keys: :string, symbols: false]](https://github.com/elixirscript/elixirscript/issues/362) +* [Added `ElixirScript.JS.object_to_map/1|2` with options [keys: :atom, recurse_array: true]](https://github.com/elixirscript/elixirscript/issues/381) +* [Fully implement `__info__` on modules](https://github.com/elixirscript/elixirscript/pull/378) +* [Concurrent Compilation](https://github.com/elixirscript/elixirscript/issues/376) +* [The following erlang functions have been implemented](https://github.com/elixirscript/elixirscript/issues/306): * :erlang.nodes/0 * :erlang.nodes/1 * :math.log2/1 @@ -32,51 +39,57 @@ and this project adheres to [Semantic Versioning](http://semver.org/). * :binary.replace/4 (some options still missing) ### Fixed -- Make sure not to add underscores to erlang functions -- [Make sure any variable names that are javascript keywords are handled properly](https://github.com/elixirscript/elixirscript/issues/355) -- [Make sure variables that begin with `_` are available](https://github.com/elixirscript/elixirscript/issues/356) -- [Finding the use of functions within anonymous functions](https://github.com/elixirscript/elixirscript/issues/358) -- [Reimplement `String.split_at/2` to make sure Unicode library isn't compiled](https://github.com/elixirscript/elixirscript/issues/353) -- [byte_size does not work on binaries that started via "" elixir string syntax](https://github.com/elixirscript/elixirscript/issues/384) -- [using . (dot) reference syntax on a map fails when value is a function](https://github.com/elixirscript/elixirscript/issues/380) -- [Make sure that remote ast works correctly with variables](https://github.com/elixirscript/elixirscript/issues/390) -- [Make sure == works as expected](https://github.com/elixirscript/elixirscript/issues/382) -- [Make sure that erlang function names that are also JavaScript keywords are not filters](https://github.com/elixirscript/elixirscript/issues/359) -- [erlang.error now throws errors resembling those in Elixir](https://github.com/elixirscript/elixirscript/pull/397) -- [Map.get fails if key is tuple or list](https://github.com/elixirscript/elixirscript/issues/406) + +* Make sure not to add underscores to erlang functions +* [Make sure any variable names that are javascript keywords are handled properly](https://github.com/elixirscript/elixirscript/issues/355) +* [Make sure variables that begin with `_` are available](https://github.com/elixirscript/elixirscript/issues/356) +* [Finding the use of functions within anonymous functions](https://github.com/elixirscript/elixirscript/issues/358) +* [Reimplement `String.split_at/2` to make sure Unicode library isn't compiled](https://github.com/elixirscript/elixirscript/issues/353) +* [byte_size does not work on binaries that started via "" elixir string syntax](https://github.com/elixirscript/elixirscript/issues/384) +* [using . (dot) reference syntax on a map fails when value is a function](https://github.com/elixirscript/elixirscript/issues/380) +* [Make sure that remote ast works correctly with variables](https://github.com/elixirscript/elixirscript/issues/390) +* [Make sure == works as expected](https://github.com/elixirscript/elixirscript/issues/382) +* [Make sure that erlang function names that are also JavaScript keywords are not filters](https://github.com/elixirscript/elixirscript/issues/359) +* [erlang.error now throws errors resembling those in Elixir](https://github.com/elixirscript/elixirscript/pull/397) +* [Map.get fails if key is tuple or list](https://github.com/elixirscript/elixirscript/issues/406) ## [0.30.0] - 2017-08-15 ### Added -- ElixirScript now has a Foreign Function Interface (FFI) for interoperability with JavaScript. For more details, see documentation at `ElixirScript.FFI` -- `ElixirScript.JS.mutate/3` -- `ElixirScript.JS.map_to_object/1` -- `root` option for specifying the root import path for FFI JavaScript modules. Defaults to `"."` + +* ElixirScript now has a Foreign Function Interface (FFI) for interoperability with JavaScript. For more details, see documentation at `ElixirScript.FFI` +* `ElixirScript.JS.mutate/3` +* `ElixirScript.JS.map_to_object/1` +* `root` option for specifying the root import path for FFI JavaScript modules. Defaults to `"."` ### Changed -- Compiler has been completely rewritten. ElixirScript now requires Erlang 20+ and Elixir 1.5+ -- `JS` module renamed to `ElixirScript.JS` -- Default output path is now `priv/elixir_script/build` + +* Compiler has been completely rewritten. ElixirScript now requires Erlang 20+ and Elixir 1.5+ +* `JS` module renamed to `ElixirScript.JS` +* Default output path is now `priv/elixir_script/build` ### Removed -- Support for CommonJS and UMD output formats has been removed. Output will be in ES module format -- The `js_modules` option has been removed in favor of the new FFI -- ElixirScript.Watcher has been removed + +* Support for CommonJS and UMD output formats has been removed. Output will be in ES module format +* The `js_modules` option has been removed in favor of the new FFI +* ElixirScript.Watcher has been removed ## [0.28.0] - 2017-06-11 ### Added -- `remove-unused` option that will remove all unused modules from output -- reimplemented structs to avoid creating JavaScript classes + +* `remove-unused` option that will remove all unused modules from output +* reimplemented structs to avoid creating JavaScript classes ## [0.27.0] - 2017-03-17 ### Added -- `super` -- `defoverridable` -- `IO.inspect\1`, `IO.puts\1`, `IO.puts\2`, `IO.warn\1` -- `Elixir.load` for loading generated JavaScript modules in bundled output. -Unlike `Elixir.start`, this will only call `__load` on the module and return the functions on it + +* `super` +* `defoverridable` +* `IO.inspect\1`, `IO.puts\1`, `IO.puts\2`, `IO.warn\1` +* `Elixir.load` for loading generated JavaScript modules in bundled output. + Unlike `Elixir.start`, this will only call `__load` on the module and return the functions on it ```javascript const exports = Elixir.load(Elixir.MyApp); @@ -84,9 +97,11 @@ exports.hello(); ``` ### Changed -- `-ex` alias is now `-e` -- A filename can be specified for output -- To access global JavaScript functions, modules, and properties, use the `JS` module + +* `-ex` alias is now `-e` +* A filename can be specified for output +* To access global JavaScript functions, modules, and properties, use the `JS` module + ```elixir JS.length # translates to 'length' JS.alert() # translates to 'alert()' @@ -95,20 +110,24 @@ JS.console.log("hi") # translates to console.log('hi') ``` ### Fixed -- Make sure mix compiler works in umbrella apps + +* Make sure mix compiler works in umbrella apps ## [0.26.1] - 2017-02-27 ### Fixed -- Fixed `for` translation -- Updated documentation + +* Fixed `for` translation +* Updated documentation ## [0.26.0] - 2017-02-27 ### Added -- Multiple `when` clauses in guards -- Kernel.defdelegate/2 -- `js_modules` configuration option has been added. This is a list of JavaScript modules that will be used. + +* Multiple `when` clauses in guards +* Kernel.defdelegate/2 +* `js_modules` configuration option has been added. This is a list of JavaScript modules that will be used. + ``` js_modules: [ {React, "react"}, @@ -116,17 +135,20 @@ JS.console.log("hi") # translates to console.log('hi') ] ``` -- `js-module` flag has been added to the CLI in order to pass js modules. +* `js-module` flag has been added to the CLI in order to pass js modules. + ``` elixirscript "app/elixirscript" -o dist --js-module React:react --js-module ReactDOM:react-dom ``` ### Removed -- `@on_js_load` has been removed in favor of having a `start/2` function defined. More info below -- `JS.import` has been removed in favor of defining JavaScript modules used in configuration + +* `@on_js_load` has been removed in favor of having a `start/2` function defined. More info below +* `JS.import` has been removed in favor of defining JavaScript modules used in configuration ### Changed -- Now bundles all output, including the boostrap code. + +* Now bundles all output, including the boostrap code. The exported object has Elixir modules in JavaScript namespaces that are lazily loaded when called. To start your application import the bundle according to whichever module format was selected and @@ -134,78 +156,82 @@ elixirscript "app/elixirscript" -o dist --js-module React:react --js-module Reac ```javascript //ES module example - import Elixir from './Elixir.App' - Elixir.start(Elixir.App, []) + import Elixir from './Elixir.App'; + Elixir.start(Elixir.App, []); ``` The `start` function will look for a `start/2` function there. This is analogous to a [Application module callback](https://hexdocs.pm/elixir/Application.html#module-application-module-callback) - - - ## [0.25.0] - 2017-02-19 ### Added -- Updated elixir_script mix compiler to support compiling elixir_script paths in dependencies if dependency has mix compiler defined as well -- Add `Collectable` protocol implementations -- Updated `for` implementation to use `Collectable` -- `format` option. Can now specify the module format of output. - Choices are: - * `:es` (default) for ES Modules - * `:umd` for UMD - * `:common` for CommonJS -- Default input, output and format for elixirscript mix compiler. In a mix project by default the elixirscript compiler will look in `lib/elixirscript` and input and place output in `priv/elixirscript`. The default format is `:es` +* Updated elixir_script mix compiler to support compiling elixir_script paths in dependencies if dependency has mix compiler defined as well +* Add `Collectable` protocol implementations +* Updated `for` implementation to use `Collectable` +* `format` option. Can now specify the module format of output. + Choices are: + _ `:es` (default) for ES Modules + _ `:umd` for UMD \* `:common` for CommonJS + +* Default input, output and format for elixirscript mix compiler. In a mix project by default the elixirscript compiler will look in `lib/elixirscript` and input and place output in `priv/elixirscript`. The default format is `:es` ### Removed -- `receive` -- `Process` module + +* `receive` +* `Process` module ### Fixed -- JS module functions not translated properly when imported -- Update fs dependency to 2.12 -- Incorrect handling of function heads with guards + +* JS module functions not translated properly when imported +* Update fs dependency to 2.12 +* Incorrect handling of function heads with guards ## [0.24.0] - 2017-01-15 ### Added -- Support for `sigil_r` -- `Regex` module -- Better JavaScript formatting + +* Support for `sigil_r` +* `Regex` module +* Better JavaScript formatting ### Fixed -- CLI now allows a comma-separated or space-separated list of paths -- Struct not properly referenced -- Tail call optimization + +* CLI now allows a comma-separated or space-separated list of paths +* Struct not properly referenced +* Tail call optimization ## [0.23.3] - 2016-11-18 ### Added -- `@load_only`: lets the compiler know to load in the module, but not to compile it +* `@load_only`: lets the compiler know to load in the module, but not to compile it ## [0.23.2] - 2016-11-17 ### Fixed -- Agent not functioning properly. Now uses internal store instead of making a process and using that to put data in store -- Protocol incorrectly handling strings -- `defgen` and `defgenp` functions not being recognized by Elixir compiler. +* Agent not functioning properly. Now uses internal store instead of making a process and using that to put data in store +* Protocol incorrectly handling strings +* `defgen` and `defgenp` functions not being recognized by Elixir compiler. ## [0.23.1] - 2016-11-16 ### Fixed -- Incorrectly sending standard lib when using compile or compile_path by default + +* Incorrectly sending standard lib when using compile or compile_path by default ## [0.23.0] - 2016-11-15 ### Added -- [`with` now supports `else`](https://github.com/bryanjos/elixirscript/pull/207) -- [Implement `context` option on `quote`](https://github.com/bryanjos/elixirscript/pull/208) -- New compiler pipeline -- `@on_js_load`. Expects a 0 arity function. This function will be called when the compiled module is loaded in JavaScript -- `JS.import\3`. Just like `JS.import\2` but expects options to decide if the import should be a default one or a namespace on. Only option allowed is `default`. Set to `true` by default + +* [`with` now supports `else`](https://github.com/bryanjos/elixirscript/pull/207) +* [Implement `context` option on `quote`](https://github.com/bryanjos/elixirscript/pull/208) +* New compiler pipeline +* `@on_js_load`. Expects a 0 arity function. This function will be called when the compiled module is loaded in JavaScript +* `JS.import\3`. Just like `JS.import\2` but expects options to decide if the import should be a default one or a namespace on. Only option allowed is `default`. Set to `true` by default + ```elixir # translates to "import A from 'a'" JS.import A, "a" @@ -215,351 +241,438 @@ elixirscript "app/elixirscript" -o dist --js-module React:react --js-module Reac ``` ### Removed -- The form of `JS.import` that accepted a list of atoms as the first arg. Used `JS.import\3` with `default: false` instead to create a namespace import -- `env` and `root` are no longer options for `ElixirScript`'s compile functions and cli -- Syntax once supported by Elixirscript `JQuery.("#element")`, is no longer supported + +* The form of `JS.import` that accepted a list of atoms as the first arg. Used `JS.import\3` with `default: false` instead to create a namespace import +* `env` and `root` are no longer options for `ElixirScript`'s compile functions and cli +* Syntax once supported by Elixirscript `JQuery.("#element")`, is no longer supported ### Changed -- [Changed CHANGELOG.md to adhere the format from Keep a Changelog](https://github.com/bryanjos/elixirscript/pull/205) -- `defmacro` now supported. No longer have to separate macros from functions in separate files. `defmacrop` still unsupported -- To use anything in the `JS` module, you must `require` the `JS` module first -- Elixirscript files must now contain valid Elixir syntax. -- Now compiles `exjs` and `ex` files within the path can be compiled all the same. Dependencies from hex are still unsupported so these files must not rely on any code outside of the path. What this does mean is that it is now possible to share code between Elixir and Elixirscript as long as the Elixir files functionality fall within what Elixirscript currently supports. -- `defgen`, `defgenp`, `yield`, `yield_to`, and `object` are now in the `JS` module -- To access functions in the global JavaScript scope, either use `JS.global\0` or use the erlang module call syntax - ```elixir - #calling alert - JS.global().alert("hi") - - #calling alert - :window.alert("hi") - ``` - Calling JavaScript modules in the global scope works without using the above methods - ```elixir - #calls window.Date.now() - Date.now() - ``` + +* [Changed CHANGELOG.md to adhere the format from Keep a Changelog](https://github.com/bryanjos/elixirscript/pull/205) +* `defmacro` now supported. No longer have to separate macros from functions in separate files. `defmacrop` still unsupported +* To use anything in the `JS` module, you must `require` the `JS` module first +* Elixirscript files must now contain valid Elixir syntax. +* Now compiles `exjs` and `ex` files within the path can be compiled all the same. Dependencies from hex are still unsupported so these files must not rely on any code outside of the path. What this does mean is that it is now possible to share code between Elixir and Elixirscript as long as the Elixir files functionality fall within what Elixirscript currently supports. +* `defgen`, `defgenp`, `yield`, `yield_to`, and `object` are now in the `JS` module +* To access functions in the global JavaScript scope, either use `JS.global\0` or use the erlang module call syntax + + ```elixir + #calling alert + JS.global().alert("hi") + + #calling alert + :window.alert("hi") + ``` + + Calling JavaScript modules in the global scope works without using the above methods + + ```elixir + #calls window.Date.now() + Date.now() + ``` ## [0.22.0] - 2016-10-16 + ### Added -- `defgen` and `defgenp` for defining public and private generators -- `yield/0`, `yield/1`, and `yield_to\1` to `Kernel` + +* `defgen` and `defgenp` for defining public and private generators +* `yield/0`, `yield/1`, and `yield_to\1` to `Kernel` ### Changed -- Updated output folder structure. stdlib code will now go in an `elxiir` folder under the output paths while generated app code will go into an `app` folder under the output path -- All process macros and functions now expect to receive and/or work using generators as entry points. Using functions defined with `def` or `defp` will not work correctly with them + +* Updated output folder structure. stdlib code will now go in an `elxiir` folder under the output paths while generated app code will go into an `app` folder under the output path +* All process macros and functions now expect to receive and/or work using generators as entry points. Using functions defined with `def` or `defp` will not work correctly with them ### Fixed -- Correctly returning list if list is only item in body + +* Correctly returning list if list is only item in body ## [0.21.0] - 2016-06-28 + ### Added -- This is the first release with early support for processes in elixirscript. Creating a process only works currently using `spawn/1`, `spawn_link/1`, and `spawn_monitor/1`. Inside of a process, you can use functions such as `send` and `receive`, along with some defined in the `Process` module. From outside of a process, you can send messages to a process, but you cannot receive a message from a process. Eventually all code will run inside processes and this restriction will naturally lift. -- The `Process` module has been implemented with the following functions: - * `alive?/1` - * `delete/1` - * `demonitor/1` - * `exit/2` - * `flag/2` - * `flag/3` - * `get/0` - * `get_keys/0` - * `get_keys/1` - * `link/1` - * `list/0` - * `monitor/1` - * `put/2` - * `register/2` - * `registered/0` - * `send/3` - * `sleep/1` - * `unlink/1` - * `unregister/1` - * `whereis/1` -- The `receive` special form has been implemented with the above caveat -- The following have been implemented on `Kernel`: - * `spawn/1` - * `spawn_link/1` - * `spawn_monitor/1` - * `send/2` - * `make_ref/0` + +* This is the first release with early support for processes in elixirscript. Creating a process only works currently using `spawn/1`, `spawn_link/1`, and `spawn_monitor/1`. Inside of a process, you can use functions such as `send` and `receive`, along with some defined in the `Process` module. From outside of a process, you can send messages to a process, but you cannot receive a message from a process. Eventually all code will run inside processes and this restriction will naturally lift. +* The `Process` module has been implemented with the following functions: + * `alive?/1` + * `delete/1` + * `demonitor/1` + * `exit/2` + * `flag/2` + * `flag/3` + * `get/0` + * `get_keys/0` + * `get_keys/1` + * `link/1` + * `list/0` + * `monitor/1` + * `put/2` + * `register/2` + * `registered/0` + * `send/3` + * `sleep/1` + * `unlink/1` + * `unregister/1` + * `whereis/1` +* The `receive` special form has been implemented with the above caveat +* The following have been implemented on `Kernel`: + * `spawn/1` + * `spawn_link/1` + * `spawn_monitor/1` + * `send/2` + * `make_ref/0` ## Fixed -- Scoping on `fn` and `def` + +* Scoping on `fn` and `def` ## [0.20.0] - 2016-05-14 + ### Added -- `ElixirScript.Watcher` module and `elixirscript.watch` mix task -- logging MatchError exceptions to better show terms that don't match + +* `ElixirScript.Watcher` module and `elixirscript.watch` mix task +* logging MatchError exceptions to better show terms that don't match ## [0.19.0] - 2016-04-30 + ### Added -- elixir_script mix compiler + +* elixir_script mix compiler ### Removed -- `Html`, `View`, and `VDom` modules have been removed + +* `Html`, `View`, and `VDom` modules have been removed ## [0.18.0] - 2016-04-08 + ### Changed -- Better support for macros. Macros should be defined in .ex or .exs files. ElixirScript code should be in .exjs files + +* Better support for macros. Macros should be defined in .ex or .exs files. ElixirScript code should be in .exjs files **NOTE**: The above functionality will cause either compiler errors or no output. Please change extensions of ElixirScript code to .exjs ### Deprecated -- `Html`, `View`, and `VDom` modules will be removed in the next version as they can now be replicated using macros + +* `Html`, `View`, and `VDom` modules will be removed in the next version as they can now be replicated using macros ## [0.17.0] - 2016-03-31 + ### Added -- `output` as an option for compiler functions. This controls whether output is returned as a list of tuples, send to stdout, or saved to a file path -- `:full_build` as an option for compiler functions and `--full-build` option to CLI. These force the compiler to perform a full build -- `--version` option to CLI. Outputs current version of elixirscript -- `--std-lib` option to CLI. Takes a path and adds the stdlib to that path + +* `output` as an option for compiler functions. This controls whether output is returned as a list of tuples, send to stdout, or saved to a file path +* `:full_build` as an option for compiler functions and `--full-build` option to CLI. These force the compiler to perform a full build +* `--version` option to CLI. Outputs current version of elixirscript +* `--std-lib` option to CLI. Takes a path and adds the stdlib to that path ### Changed -- Renamed `copy_core_to_destination` to `copy_stdlib_to_destination` -- Incremental Compilation: ElixirScript will now only build files and modules that have changed since the last build + +* Renamed `copy_core_to_destination` to `copy_stdlib_to_destination` +* Incremental Compilation: ElixirScript will now only build files and modules that have changed since the last build ### Removed -- `--core` option from CLI and `:core` compiler option. + +* `--core` option from CLI and `:core` compiler option. ## [0.16.0] 2016-02-27 + ### Added -- Bitstring pattern matching -- Bitstrings in for comprehensions -- Functions with catch, after, else clauses -- `with` special form -- Pin operator in map keys and function clauses -- Added `Kernel.object/1` function to make it more natural to create a JavaScript object with string keys. Elixirscript, by default turns the following, `%{a:"b"}` into `{[Symbol.for("a")]: "b"}` in JavaScript. In order to get string keys, one would have to do `%{"a" => "b"}` which turns into `{a: "b"}` in JavaScript. With `Kernel.object`, you can create string keyed maps conveniently, `object(a: "b")` which turns into `{a: "b"}`. - **NOTE**: when updating the created by, you still have to use the string form `%{ my_map | "a" => "c" }` +* Bitstring pattern matching +* Bitstrings in for comprehensions +* Functions with catch, after, else clauses +* `with` special form +* Pin operator in map keys and function clauses +* Added `Kernel.object/1` function to make it more natural to create a JavaScript object with string keys. Elixirscript, by default turns the following, `%{a:"b"}` into `{[Symbol.for("a")]: "b"}` in JavaScript. In order to get string keys, one would have to do `%{"a" => "b"}` which turns into `{a: "b"}` in JavaScript. With `Kernel.object`, you can create string keyed maps conveniently, `object(a: "b")` which turns into `{a: "b"}`. + + **NOTE**: when updating the created by, you still have to use the string form `%{ my_map | "a" => "c" }` ### Removed -- `JS.update(object, property, value)` has been removed and replaced with `JS.update(object, map)`. This allows you to update multiple values on a javascript object at once. + +* `JS.update(object, property, value)` has been removed and replaced with `JS.update(object, map)`. This allows you to update multiple values on a javascript object at once. ### Fixed -- Optional parameters should now work as expected + +* Optional parameters should now work as expected ## [0.15.2] - 2016-02-21 + ### Addded -- Support for variables as map keys + +* Support for variables as map keys ### Fixed -- Protocol implementations for Integer and Float which where not recognized -- Calling properties on non-objects + +* Protocol implementations for Integer and Float which where not recognized +* Calling properties on non-objects ## [0.15.1] - 2016-02-19 + ### Removed -- Removed `catch` as a javascript keyword to filter + +* Removed `catch` as a javascript keyword to filter ### Fixed -- Fixed View module so that an element can have multiple elements within -- struct implementation so that lists of atoms for fields are compiled correctly -- head-tail pattern match to allow for more complicated scenarios -- ModuleCollector to properly alias inner modules -- Raise translation to properly translate when string messages are given + +* Fixed View module so that an element can have multiple elements within +* struct implementation so that lists of atoms for fields are compiled correctly +* head-tail pattern match to allow for more complicated scenarios +* ModuleCollector to properly alias inner modules +* Raise translation to properly translate when string messages are given ## [0.15.0] - 2016-01-26 + ### Added -- `__ENV__` and `__CALLER__` are now supported -- `JS.import/1`, `JS.typeof/1`,`JS.instanceof/1`, and `JS.global/1` -- Support for multi alias/require/imports statements + +* `__ENV__` and `__CALLER__` are now supported +* `JS.import/1`, `JS.typeof/1`,`JS.instanceof/1`, and `JS.global/1` +* Support for multi alias/require/imports statements ### Changed -- `alias`, `require`, and `import` now work inside lexical scopes -- Some of the standard library originally written in JavaScript has been rewritten in Elixir. -- Generated JavaScript export statements are now default exports -- When output is sent to standard out, there are now markers to specify where each module begins as well as what the file name would be. For the end of a file, `//:ENDFILE` is used. For the file name, `//:ENDFILENAME` is used where `` is the name of the file -- `compile`, `compile_path`, and `compile_quoted` opts parameter now expects a map -- The `stdlib` compiler option is now `core`. The `stdlib_path` compiler options is now `core_path` + +* `alias`, `require`, and `import` now work inside lexical scopes +* Some of the standard library originally written in JavaScript has been rewritten in Elixir. +* Generated JavaScript export statements are now default exports +* When output is sent to standard out, there are now markers to specify where each module begins as well as what the file name would be. For the end of a file, `//:ENDFILE` is used. For the file name, `//:ENDFILENAME` is used where `` is the name of the file +* `compile`, `compile_path`, and `compile_quoted` opts parameter now expects a map +* The `stdlib` compiler option is now `core`. The `stdlib_path` compiler options is now `core_path` ## [0.14.1] - 2015-12-07 + ### Removed -- .DS_Store and LICENSE from output + +* .DS_Store and LICENSE from output ## [0.14.0] - 2015-12-06 + ### Added -- Can now implement protocols using JavaScript types + +* Can now implement protocols using JavaScript types ```elixir defimpl MyProtocol, for: HTMLElement ``` -- virtual-dom JavaScript library -- ElixirScript.Html module for defining a virtual-dom tree -- ElixirScript.VDom module for manipulating the virtual-dom tree created using the ElixirScript.Html module -- Added ElixirScript.View module for handling view state and rendering virtual-dom -- Added `stdlib_path` compiler option to specify the es6 path to the standard library. If used, elixir.js will not be exported with the compiled modules +* virtual-dom JavaScript library +* ElixirScript.Html module for defining a virtual-dom tree +* ElixirScript.VDom module for manipulating the virtual-dom tree created using the ElixirScript.Html module +* Added ElixirScript.View module for handling view state and rendering virtual-dom +* Added `stdlib_path` compiler option to specify the es6 path to the standard library. If used, elixir.js will not be exported with the compiled modules ### Changed -- Renamed `ex2js` to `elixirscript`. This effects the escript as well as the + +* Renamed `ex2js` to `elixirscript`. This effects the escript as well as the mix task -- Structs are now translated into classes -- Structs and Tuples now match on their types -- Can now match on JavaScript classes. Works just like matching on structs: +* Structs are now translated into classes +* Structs and Tuples now match on their types +* Can now match on JavaScript classes. Works just like matching on structs: ```elixir def my_func(%HTMLElement{id: "myId"}) ``` -- Moved non-elixir JavaScript code into `core` es6 module. This will hopefully +* Moved non-elixir JavaScript code into `core` es6 module. This will hopefully make it so ElixirScript Standard Library modules can be defined in Elixir soon. ## [0.13.0] - 2015-10-26 + ### Added -- `Base` module with function: encode64, decode64, and decode64! -- `String` module -- `Bitwise` module -- `Map` module -- `MapSet` module -- `Set` module -- Protocol support -- Added `Collectable`, `Enumerable`, `Inspect`, `List.Chars`, and `String.Chars` protocols. The only one currently being used in the Standard Library, however, is String.Chars + +* `Base` module with function: encode64, decode64, and decode64! +* `String` module +* `Bitwise` module +* `Map` module +* `MapSet` module +* `Set` module +* Protocol support +* Added `Collectable`, `Enumerable`, `Inspect`, `List.Chars`, and `String.Chars` protocols. The only one currently being used in the Standard Library, however, is String.Chars ## [0.12.0] - 2015-09-23 + ### Added -- Added PostOffice. Only thing that current uses it is Agent + +* Added PostOffice. Only thing that current uses it is Agent ### Changed -- Updated tuple implementation. It's now a class. -- Replaced pattern matching library with custom one -- Moved data types to Kernel.SpecialForms -- `else` now works for try expressions -- for now works with `into` for lists + +* Updated tuple implementation. It's now a class. +* Replaced pattern matching library with custom one +* Moved data types to Kernel.SpecialForms +* `else` now works for try expressions +* for now works with `into` for lists ### Removed -- Removed erlang.js. + +* Removed erlang.js. ## [0.11.0] - 2015-09-17 + ### Added -- Added `JS` module with `new`, `mutate`, `import` macros -- Added `Keyword` module with functions, `has_key?` and `get` -- Added `Agent` module with functions, `start`, `get`, `update`, and `get_and_update` + +* Added `JS` module with `new`, `mutate`, `import` macros +* Added `Keyword` module with functions, `has_key?` and `get` +* Added `Agent` module with functions, `start`, `get`, `update`, and `get_and_update` ### Changed -- Map keys are now correctly turned into their atom counterparts if atom keys are used -- `import` works with all options -- `Mutable.update` has been replaced by `JS.update` -- `transpile`, `transpile_quoted`, and `transpile_path` are now `compile`, `compile_quoted`, and `compile_path` -- All Standard libraries are rolled up into one elixir.js file and imported from that -- Modules no longer export a default object -- `alias` now translates to a namespace import unless `default` option is given + +* Map keys are now correctly turned into their atom counterparts if atom keys are used +* `import` works with all options +* `Mutable.update` has been replaced by `JS.update` +* `transpile`, `transpile_quoted`, and `transpile_path` are now `compile`, `compile_quoted`, and `compile_path` +* All Standard libraries are rolled up into one elixir.js file and imported from that +* Modules no longer export a default object +* `alias` now translates to a namespace import unless `default` option is given ## [0.10.0] - 2015-09-02 + ### Added -- Added `env` option for `ElixirScript.transpile` adding macros for compilation -- Added `Logger` that translates Logger functions to console + +* Added `env` option for `ElixirScript.transpile` adding macros for compilation +* Added `Logger` that translates Logger functions to console ### Changed -- Updated `Kernel` module to translate some functions to it's JavaScript equivalent + +* Updated `Kernel` module to translate some functions to it's JavaScript equivalent ### Fixed -- Fixed `case` implementation to add `this` to call + +* Fixed `case` implementation to add `this` to call ## [0.9.0] - 2015-08-30 + ### Added -- an implementation for quote. Currently ignores `:location` and `:context` options -- an implementation for unquote and unquote_splicing + +* an implementation for quote. Currently ignores `:location` and `:context` options +* an implementation for unquote and unquote_splicing ## [0.8.0] - 2015-08-15 + ### Added -- Can now support catch blocks in try expressions -- Added receive + +* Can now support catch blocks in try expressions +* Added receive ### Changed -- Updated pattern matching implementation -- Wrapped try's in function closure to make sure they return a value; + +* Updated pattern matching implementation +* Wrapped try's in function closure to make sure they return a value; ## [0.7.0] - 2015-08-01 + ### Added -- Can now support rescue and after blocks in try expressions + +* Can now support rescue and after blocks in try expressions ## [0.6.5] - 2015-07-13 + ### Changed -- Now using the JS code generator from elixir-estree for code generation, improving speed of transpilation -- the parse functions in the ElixirScript module have been renamed to transpile + +* Now using the JS code generator from elixir-estree for code generation, improving speed of transpilation +* the parse functions in the ElixirScript module have been renamed to transpile ## [0.6.0] - 2015-07-02 + ### Added -- Added iterators for Range and BitString -- Now replacing characters that can't be used in variable and function names in JavaScript with something that it (i.e. `match?` -> `match__qmark__`) -- Implemented Integer module + +* Added iterators for Range and BitString +* Now replacing characters that can't be used in variable and function names in JavaScript with something that it (i.e. `match?` -> `match__qmark__`) +* Implemented Integer module ### Changed -- Made the Tuple, Range and BitString data structures more immutable -- Atom now translates to an ES6 Symbol -- List now translates to a frozen JS Array -- Updated the pattern match binding to use ES6 destructuring for lists and tuples -- Inner modules are now split out into their own files - * Standard lib is now exported with file output from cli - * Standard lib modules are now automatically imported - * No longer have to define modules via aliases ahead of time. They will be automatically be resolved - and made into JavaScript import statements + +* Made the Tuple, Range and BitString data structures more immutable +* Atom now translates to an ES6 Symbol +* List now translates to a frozen JS Array +* Updated the pattern match binding to use ES6 destructuring for lists and tuples +* Inner modules are now split out into their own files + * Standard lib is now exported with file output from cli + * Standard lib modules are now automatically imported + * No longer have to define modules via aliases ahead of time. They will be automatically be resolved + and made into JavaScript import statements ## [0.5.0] - 2015-05-31 + ### Added -- added `from` clause to `import`, `alias`, and `require` so that the import path can be overridden + +* added `from` clause to `import`, `alias`, and `require` so that the import path can be overridden ### Changed -- For statements now work with pattern matching tuples -- Improved function chaining -- `alias` now acts like `require` in that it is translated into an import default statement -- modules now export a default object with def functions added as properties on it. -- for function closures, now calling by using `.call(this)` so that `this` is available inside of it + +* For statements now work with pattern matching tuples +* Improved function chaining +* `alias` now acts like `require` in that it is translated into an import default statement +* modules now export a default object with def functions added as properties on it. +* for function closures, now calling by using `.call(this)` so that `this` is available inside of it ## [0.4.0] - 2015-05-05 + ### Added -- bitstrings -- Better Pattern Matching (Does not support bitstrings yet) -- Capture Operator -- Added more functions from the list standard library + +* bitstrings +* Better Pattern Matching (Does not support bitstrings yet) +* Capture Operator +* Added more functions from the list standard library ### Changed -- Updated variable implementation to match Elixir's (i.e. Reusing the same variable name creates a new one in the background) + +* Updated variable implementation to match Elixir's (i.e. Reusing the same variable name creates a new one in the background) ### Fixed -- Fixed multi arity implementation + +* Fixed multi arity implementation ## [0.3.0] - 2015-04-23 + ### Added -- function and case guards -- function and case pattern matching + +* function and case guards +* function and case pattern matching ### Changed -- Can now use ^ on a variable during assignment + +* Can now use ^ on a variable during assignment ## [0.2.1] - 2015-04-14 + ### Changed -- Renamed project to ElixirScript -- Reduced escript file size + +* Renamed project to ElixirScript +* Reduced escript file size ## [0.2.0] - 2015-04-12 + ### Added -- Pipe operator -- String interpolation -- Adding more functions to the Kernel module -- Fully implemented Tuple module -- Fully implemented Atom module -- Fully implemented Range module + +* Pipe operator +* String interpolation +* Adding more functions to the Kernel module +* Fully implemented Tuple module +* Fully implemented Atom module +* Fully implemented Range module ### Changed -- Now checking to see if a function is a Kernel function and prepending Kernel to it -- Now turning Atoms into an Atom javascript object instead of a Symbol -- Now turning tuples into a Tuple javascript object -- Can now call properties and zero parameter functions correctly -- case, cond, and if are now turned into if statements wrapped in function closures -- Anonymous functions are now turned into anonymous functions in javascript insteed of arrow functions + +* Now checking to see if a function is a Kernel function and prepending Kernel to it +* Now turning Atoms into an Atom javascript object instead of a Symbol +* Now turning tuples into a Tuple javascript object +* Can now call properties and zero parameter functions correctly +* case, cond, and if are now turned into if statements wrapped in function closures +* Anonymous functions are now turned into anonymous functions in javascript insteed of arrow functions ## [0.1.0] - 2015-04-04 + ### Added -- From standard library implemented: - * Enum.map - * Kernel.tl - * Kernel.hd - * Logger -- Implemented language features: - * All primitives except bitstrings - * defmodule - * import, alias, and require - * case, cond, if - * def, defp - * defstruct, defexception - * raise - * multiple arity functions - * basic binary operations - * for without into + +* From standard library implemented: + +- Enum.map +- Kernel.tl +- Kernel.hd +- Logger + +* Implemented language features: + +- All primitives except bitstrings +- defmodule +- import, alias, and require +- case, cond, if +- def, defp +- defstruct, defexception +- raise +- multiple arity functions +- basic binary operations +- for without into diff --git a/mix.exs b/mix.exs index 0ecdc707..ba7fe071 100644 --- a/mix.exs +++ b/mix.exs @@ -5,7 +5,7 @@ defmodule ElixirScript.Mixfile do [ app: :elixir_script, version: "0.32.0-dev", - elixir: "~> 1.5", + elixir: "~> 1.6", elixirc_paths: elixirc_paths(Mix.env), deps: deps(), description: description(), From 2faa3f32e8c096429cb7540db1f4e05368edbad2 Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Tue, 2 Jan 2018 15:48:36 -0600 Subject: [PATCH 382/418] Update Elixir version requirement --- mix.exs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mix.exs b/mix.exs index ba7fe071..11c588f1 100644 --- a/mix.exs +++ b/mix.exs @@ -5,7 +5,7 @@ defmodule ElixirScript.Mixfile do [ app: :elixir_script, version: "0.32.0-dev", - elixir: "~> 1.6", + elixir: "~> 1.6-rc", elixirc_paths: elixirc_paths(Mix.env), deps: deps(), description: description(), From e03df899c66809ea17b8f178b2d4cd22dae95256 Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Wed, 3 Jan 2018 05:30:44 -0600 Subject: [PATCH 383/418] Add ffi module info to manifest. Add diagnostic info as well --- lib/elixir_script/compiler.ex | 105 +++-- .../passes/find_used_functions.ex | 78 ++-- lib/elixir_script/passes/find_used_modules.ex | 145 ++++--- lib/elixir_script/passes/output.ex | 126 +++--- lib/elixir_script/passes/translate/form.ex | 381 ++++++++++-------- lib/elixir_script/passes/translate/module.ex | 282 +++++++------ lib/elixir_script/state.ex | 22 +- lib/mix/tasks/compile.elixir_script.ex | 27 +- test/compiler_test.exs | 10 +- test/passes/translate/forms/receive_test.exs | 30 +- 10 files changed, 711 insertions(+), 495 deletions(-) diff --git a/lib/elixir_script/compiler.ex b/lib/elixir_script/compiler.ex index 36c6de61..61a95201 100644 --- a/lib/elixir_script/compiler.ex +++ b/lib/elixir_script/compiler.ex @@ -29,33 +29,39 @@ defmodule ElixirScript.Compiler do Translate, FindUsedModules, FindUsedFunctions, - Output, + Output } + alias ElixirScript.ModuleSystems.ES alias Kernel.ParallelCompiler - @spec compile(atom | [atom] | binary, []) :: map + @type compiler_input :: + atom + | [atom] + | binary + + @spec compile(compiler_input, []) :: map def compile(path, opts \\ []) def compile(path, opts) when is_binary(path) do opts = build_compiler_options(opts) {:ok, pid} = State.start_link(opts) - path = if String.ends_with?(path, [".ex", ".exs"]) do - path - else - Path.join([path, "**", "*.{ex,exs}"]) - end + path = + if String.ends_with?(path, [".ex", ".exs"]) do + path + else + Path.join([path, "**", "*.{ex,exs}"]) + end files = Path.wildcard(path) - ParallelCompiler.files(files, [ - each_module: &on_module_compile(pid, &1, &2, &3) - ]) + ParallelCompiler.files(files, each_module: &on_module_compile(pid, &1, &2, &3)) - entry_modules = pid - |> State.get_in_memory_modules - |> Keyword.keys + entry_modules = + pid + |> State.get_in_memory_modules() + |> Keyword.keys() do_compile(entry_modules, pid, opts) end @@ -90,11 +96,12 @@ defmodule ElixirScript.Compiler do defp build_compiler_options(opts) do remove_used_functions? = Keyword.get(opts, :remove_unused_functions, true) - default_options = Map.new - |> Map.put(:output, Keyword.get(opts, :output)) - |> Map.put(:format, :es) - |> Map.put(:root, Keyword.get(opts, :root, ".")) - |> Map.put(:remove_unused_functions, remove_used_functions?) + default_options = + Map.new() + |> Map.put(:output, Keyword.get(opts, :output)) + |> Map.put(:format, :es) + |> Map.put(:root, Keyword.get(opts, :root, ".")) + |> Map.put(:remove_unused_functions, remove_used_functions?) options = default_options Map.put(options, :module_formatter, ES) @@ -105,23 +112,51 @@ defmodule ElixirScript.Compiler do end defp transform_output(modules, compiled_js, opts) do - output_path = if opts.output == nil or opts.output == :stdout do - "" - else - Path.dirname(opts.output) - end - - Enum.reduce(modules, %{}, fn {module, info}, current_data -> - info = %{ - references: info.used_modules, - last_modified: info.last_modified, - beam_path: Map.get(info, :beam_path), - source: Map.get(info, :file), - js_path: Path.join(output_path, "#{module}.js"), - js_code: Keyword.get(compiled_js, module) - } - - Map.put(current_data, module, info) + output_path = + if opts.output == nil or opts.output == :stdout do + "" + else + Path.dirname(opts.output) + end + + Enum.reduce(modules, %{}, fn + {module, info}, current_data -> + info = %{ + references: info.used_modules, + last_modified: info.last_modified, + beam_path: Map.get(info, :beam_path), + source: Map.get(info, :file), + js_path: Path.join(output_path, "#{module}.js"), + js_code: Keyword.get(compiled_js, module), + diagnostics: Map.get(info, :diagnostics, []), + type: :module + } + + Map.put(current_data, module, info) + + {module, js_input_path, js_output_path}, current_data -> + last_modified = + case File.stat(js_input_path, time: :posix) do + {:ok, file_info} -> + file_info.mtime + + _ -> + nil + end + + info = %{ + references: [], + last_modified: last_modified, + beam_path: nil, + source: nil, + js_input_path: js_input_path, + js_path: js_output_path, + js_code: nil, + diagnostics: [], + type: :ffi + } + + Map.put(current_data, module, info) end) end end diff --git a/lib/elixir_script/passes/find_used_functions.ex b/lib/elixir_script/passes/find_used_functions.ex index 90d00435..861d7c44 100644 --- a/lib/elixir_script/passes/find_used_functions.ex +++ b/lib/elixir_script/passes/find_used_functions.ex @@ -10,19 +10,17 @@ defmodule ElixirScript.FindUsedFunctions do @spec execute([atom], pid) :: nil def execute(entry_modules, pid) do entry_modules - |> List.wrap - |> Enum.each(fn - module -> - walk_module(module, pid) + |> List.wrap() + |> Enum.each(fn module -> + walk_module(module, pid) end) pid - |> ElixirScript.State.list_modules - |> Enum.each(fn - {module, info} -> - if get_in(info, [:attributes, :protocol_impl]) do - walk_module(module, pid) - end + |> ElixirScript.State.list_modules() + |> Enum.each(fn {module, info} -> + if get_in(info, [:attributes, :protocol_impl]) do + walk_module(module, pid) + end end) end @@ -37,20 +35,25 @@ defmodule ElixirScript.FindUsedFunctions do unreachable: unreachable } = ModuleState.get_module(pid, module) - reachable_defs = Enum.filter(defs, fn - { _, type, _, _} when type in [:defmacro, :defmacrop] -> false - { name, _, _, _} -> - not(name in unreachable) - _ -> true - end) + reachable_defs = + Enum.filter(defs, fn + {_, type, _, _} when type in [:defmacro, :defmacrop] -> + false + + {name, _, _, _} -> + name not in unreachable + + _ -> + true + end) state = %{ pid: pid, module: module } - Enum.each(reachable_defs, fn({name, _type, _, _clauses}) -> - ModuleState.add_used(state.pid, module, name) + Enum.each(reachable_defs, fn {name, _type, _, _clauses} -> + ModuleState.put_used(state.pid, module, name) end) Enum.each(reachable_defs, &walk(&1, state)) @@ -58,6 +61,7 @@ defmodule ElixirScript.FindUsedFunctions do defp walk_module(module, function, arity, pid) do function = {function, arity} + unless ModuleState.has_used?(pid, module, function) do info = ModuleState.get_module(pid, module) @@ -66,13 +70,15 @@ defmodule ElixirScript.FindUsedFunctions do module: module } - reachable_def = Enum.find(Map.get(info, :definitions, []), fn { name, _, _, _} -> name == function end) + reachable_def = + Enum.find(Map.get(info, :definitions, []), fn {name, _, _, _} -> name == function end) case reachable_def do nil -> nil + {name, _type, _, _clauses} = func -> - ModuleState.add_used(state.pid, module, name) + ModuleState.put_used(state.pid, module, name) walk(func, state) end end @@ -82,13 +88,13 @@ defmodule ElixirScript.FindUsedFunctions do Enum.each(clauses, &walk(&1, state)) end - defp walk({ _, _args, _guards, body}, state) do + defp walk({_, _args, _guards, body}, state) do walk_block(body, state) end - defp walk({:->, _, [[{:when, _, params}], body ]}, state) do + defp walk({:->, _, [[{:when, _, params}], body]}, state) do guards = List.last(params) - params = params |> Enum.reverse |> tl |> Enum.reverse + params = params |> Enum.reverse() |> tl |> Enum.reverse() walk({[], params, guards, body}, state) end @@ -119,11 +125,11 @@ defmodule ElixirScript.FindUsedFunctions do end defp walk({:%{}, _, properties}, state) do - Enum.each(properties, fn (val) -> walk(val, state) end) + Enum.each(properties, fn val -> walk(val, state) end) end defp walk({:<<>>, _, elements}, state) do - Enum.each(elements, fn (val) -> walk(val, state) end) + Enum.each(elements, fn val -> walk(val, state) end) end defp walk({:=, _, [left, right]}, state) do @@ -167,7 +173,7 @@ defmodule ElixirScript.FindUsedFunctions do end defp walk({:cond, _, [[do: clauses]]}, state) do - Enum.each(clauses, fn({:->, _, [clause, clause_body]}) -> + Enum.each(clauses, fn {:->, _, [clause, clause_body]} -> Enum.each(List.wrap(clause_body), &walk(&1, state)) walk(hd(clause), state) end) @@ -195,9 +201,10 @@ defmodule ElixirScript.FindUsedFunctions do if rescue_block do Enum.each(rescue_block, fn - {:->, _, [ [{:in, _, [param, names]}], body]} -> + {:->, _, [[{:in, _, [param, names]}], body]} -> walk({[], [param], [{{:., [], [Enum, :member?]}, [], [param, names]}], body}, state) - {:->, _, [ [param], body]} -> + + {:->, _, [[param], body]} -> walk({[], [param], [], body}, state) end) end @@ -234,10 +241,10 @@ defmodule ElixirScript.FindUsedFunctions do [do: expression, else: elses] -> walk_block(expression, state) - Enum.each(elses, fn - {:->, _, [left, right]} -> - walk(left, state) - walk(right, state) + + Enum.each(elses, fn {:->, _, [left, right]} -> + walk(left, state) + walk(right, state) end) end) end @@ -258,10 +265,13 @@ defmodule ElixirScript.FindUsedFunctions do cond do ElixirScript.Translate.Module.is_js_module(module, state) -> nil + ElixirScript.Translate.Module.is_elixir_module(module) -> walk_module(module, function, length(params), state.pid) + is_tuple(module) -> walk(module, state) + true -> nil end @@ -292,13 +302,15 @@ defmodule ElixirScript.FindUsedFunctions do case block do nil -> nil + {:__block__, _, block_body} -> Enum.each(block_body, &walk(&1, state)) + b when is_list(b) -> Enum.each(b, &walk(&1, state)) + _ -> walk(block, state) end end - end diff --git a/lib/elixir_script/passes/find_used_modules.ex b/lib/elixir_script/passes/find_used_modules.ex index d738a006..c111c249 100644 --- a/lib/elixir_script/passes/find_used_modules.ex +++ b/lib/elixir_script/passes/find_used_modules.ex @@ -9,44 +9,65 @@ defmodule ElixirScript.FindUsedModules do @spec execute([atom], pid) :: :ok def execute(modules, pid) do modules - |> List.wrap - |> Enum.each(fn(module) -> + |> List.wrap() + |> Enum.each(fn module -> do_execute(module, pid) end) end defp do_execute(module, pid) do - result = case ModuleState.get_in_memory_module(pid, module) do - nil -> - ElixirScript.Beam.debug_info(module) - beam -> - ElixirScript.Beam.debug_info(beam) - end + result = + case ModuleState.get_in_memory_module(pid, module) do + nil -> + ElixirScript.Beam.debug_info(module) + + beam -> + ElixirScript.Beam.debug_info(beam) + end case result do {:ok, info} -> walk_module(module, info, pid) + {:ok, module, module_info, implementations} -> walk_protocol(module, module_info, implementations, pid) + {:error, "Unknown module"} -> - Logger.warn fn() -> - "ElixirScript: #{inspect module} is missing or unavailable" - end + Logger.warn(fn -> + "ElixirScript: #{inspect(module)} is missing or unavailable" + end) + + ModuleState.put_diagnostic(pid, module, %{ + severity: :warning, + message: "#{inspect(module)} is missing or unavailable" + }) + {:error, error} -> - raise ElixirScript.CompileError, "An error occurred while compiling #{inspect module}: #{error}" + ModuleState.put_diagnostic(pid, module, %{ + severity: :error, + message: "An error occurred while compiling #{inspect(module)}: #{error}" + }) + + raise ElixirScript.CompileError, + "An error occurred while compiling #{inspect(module)}: #{error}" end end - defp walk_module(module, %{attributes: [__foreign_info__: %{path: path, name: name, global: global}]} = info, pid) do - {name, path} = if global do - name = if name, do: name, else: module - path = nil - {name, path} - else - name = Enum.join(Module.split(module), "_") - path = path <> ".js" - {name, path} - end + defp walk_module( + module, + %{attributes: [__foreign_info__: %{path: path, name: name, global: global}]} = info, + pid + ) do + {name, path} = + if global do + name = if name, do: name, else: module + path = nil + {name, path} + else + name = Enum.join(Module.split(module), "_") + path = path <> ".js" + {name, path} + end ModuleState.put_javascript_module(pid, module, name, path) ModuleState.put_module(pid, module, info) @@ -67,42 +88,41 @@ defmodule ElixirScript.FindUsedModules do ModuleState.put_module(pid, module, info) - reachable_defs = Enum.filter(defs, fn - { _, type, _, _} when type in [:defmacro, :defmacrop] -> false - { name, _, _, _} -> not(name in unreachable) - _ -> true - end) + reachable_defs = + Enum.filter(defs, fn + {_, type, _, _} when type in [:defmacro, :defmacrop] -> false + {name, _, _, _} -> name not in unreachable + _ -> true + end) state = %{ pid: pid, module: module } - Enum.each(reachable_defs, fn(x) -> + Enum.each(reachable_defs, fn x -> walk(x, state) end) end defp walk_protocol(module, module_info, implementations, pid) do - impls = Enum.map(implementations, fn {impl, %{attributes: attrs}} -> - protocol_impl = Keyword.fetch!(attrs, :protocol_impl) - impl_for = Keyword.fetch!(protocol_impl, :for) - {impl, impl_for} - end) + impls = + Enum.map(implementations, fn {impl, %{attributes: attrs}} -> + protocol_impl = Keyword.fetch!(attrs, :protocol_impl) + impl_for = Keyword.fetch!(protocol_impl, :for) + {impl, impl_for} + end) first_implementation_functions = implementations |> hd |> elem(1) |> Map.get(:definitions) - functions = Enum.map(first_implementation_functions, fn { name, _, _, _} -> name end) + functions = Enum.map(first_implementation_functions, fn {name, _, _, _} -> name end) - module_info = Map.merge( - module_info, - %{protocol: true, impls: impls, functions: functions} - ) + module_info = Map.merge(module_info, %{protocol: true, impls: impls, functions: functions}) ModuleState.put_module(pid, module, module_info) Enum.each(implementations, fn {impl, info} -> - ModuleState.add_used_module(pid, module, impl) + ModuleState.put_used_module(pid, module, impl) walk_module(impl, info, pid) end) end @@ -111,13 +131,13 @@ defmodule ElixirScript.FindUsedModules do Enum.each(clauses, &walk(&1, state)) end - defp walk({ _, _args, _guards, body}, state) do + defp walk({_, _args, _guards, body}, state) do walk_block(body, state) end - defp walk({:->, _, [[{:when, _, params}], body ]}, state) do + defp walk({:->, _, [[{:when, _, params}], body]}, state) do guards = List.last(params) - params = params |> Enum.reverse |> tl |> Enum.reverse + params = params |> Enum.reverse() |> tl |> Enum.reverse() walk({[], params, guards, body}, state) end @@ -139,9 +159,12 @@ defmodule ElixirScript.FindUsedModules do Enum.each(form, &walk(&1, state)) end - defp walk(form, state) when is_atom(form) and form not in [BitString, Function, PID, Port, Reference, Any, Elixir] do - if ElixirScript.Translate.Module.is_elixir_module(form) and !ElixirScript.Translate.Module.is_js_module(form, state) do - ModuleState.add_used_module(state.pid, state.module, form) + defp walk(form, state) + when is_atom(form) and form not in [BitString, Function, PID, Port, Reference, Any, Elixir] do + if ElixirScript.Translate.Module.is_elixir_module(form) and + !ElixirScript.Translate.Module.is_js_module(form, state) do + ModuleState.put_used_module(state.pid, state.module, form) + if ModuleState.get_module(state.pid, form) == nil do do_execute(form, state.pid) end @@ -157,11 +180,11 @@ defmodule ElixirScript.FindUsedModules do end defp walk({:%{}, _, properties}, state) do - Enum.each(properties, fn (val) -> walk(val, state) end) + Enum.each(properties, fn val -> walk(val, state) end) end defp walk({:<<>>, _, elements}, state) do - Enum.each(elements, fn (val) -> walk(val, state) end) + Enum.each(elements, fn val -> walk(val, state) end) end defp walk({:=, _, [left, right]}, state) do @@ -170,8 +193,10 @@ defmodule ElixirScript.FindUsedModules do end defp walk({:%, _, [module, params]}, state) do - if ElixirScript.Translate.Module.is_elixir_module(module) and !ElixirScript.Translate.Module.is_js_module(module, state) do - ModuleState.add_used_module(state.pid, state.module, module) + if ElixirScript.Translate.Module.is_elixir_module(module) and + !ElixirScript.Translate.Module.is_js_module(module, state) do + ModuleState.put_used_module(state.pid, state.module, module) + if ModuleState.get_module(state.pid, module) == nil do do_execute(module, state.pid) end @@ -212,7 +237,7 @@ defmodule ElixirScript.FindUsedModules do end defp walk({:cond, _, [[do: clauses]]}, state) do - Enum.each(clauses, fn({:->, _, [clause, clause_body]}) -> + Enum.each(clauses, fn {:->, _, [clause, clause_body]} -> Enum.each(List.wrap(clause_body), &walk(&1, state)) walk(hd(clause), state) end) @@ -242,10 +267,11 @@ defmodule ElixirScript.FindUsedModules do if rescue_block do Enum.each(rescue_block, fn - {:->, _, [ [{:in, _, [param, names]}], body]} -> + {:->, _, [[{:in, _, [param, names]}], body]} -> Enum.each(names, &walk(&1, state)) walk({[], [param], [{{:., [], [Enum, :member?]}, [], [names, param]}], body}, state) - {:->, _, [ [param], body]} -> + + {:->, _, [[param], body]} -> walk({[], [param], [], body}, state) end) end @@ -282,10 +308,10 @@ defmodule ElixirScript.FindUsedModules do [do: expression, else: elses] -> walk_block(expression, state) - Enum.each(elses, fn - {:->, _, [left, right]} -> - walk(left, state) - walk(right, state) + + Enum.each(elses, fn {:->, _, [left, right]} -> + walk(left, state) + walk(right, state) end) end) end @@ -309,7 +335,8 @@ defmodule ElixirScript.FindUsedModules do defp walk({:., _, [module, function]}, state) do if ElixirScript.Translate.Module.is_elixir_module(module) do - ModuleState.add_used_module(state.pid, state.module, module) + ModuleState.put_used_module(state.pid, state.module, module) + if ModuleState.get_module(state.pid, module) == nil do do_execute(module, state.pid) end @@ -336,13 +363,15 @@ defmodule ElixirScript.FindUsedModules do case block do nil -> nil + {:__block__, _, block_body} -> Enum.each(block_body, &walk(&1, state)) + b when is_list(b) -> Enum.each(b, &walk(&1, state)) + _ -> walk(block, state) end end - end diff --git a/lib/elixir_script/passes/output.ex b/lib/elixir_script/passes/output.ex index 9a519fff..961b3d3b 100644 --- a/lib/elixir_script/passes/output.ex +++ b/lib/elixir_script/passes/output.ex @@ -9,23 +9,23 @@ defmodule ElixirScript.Output do """ @spec execute([atom], pid, map) :: [{atom, binary}] def execute(modules, pid, opts) do - js_modules = ModuleState.js_modules(pid) - |> Enum.filter(fn - {_module, _name, nil} -> false - _ -> true - end) - |> Enum.map(fn - {module, name, path} -> + js_modules = + ModuleState.js_modules(pid) + |> Enum.filter(fn + {_module, _name, nil} -> false + _ -> true + end) + |> Enum.map(fn {module, name, path} -> import_path = Path.join(opts.root, path) {module, name, path, import_path} - end) + end) - prepared_modules = modules - |> Enum.filter(fn {_, info} -> Map.has_key?(info, :js_ast) end) - |> Enum.map(fn {module, info} -> + prepared_modules = + modules + |> Enum.filter(fn {_, info} -> Map.has_key?(info, :js_ast) end) + |> Enum.map(fn {module, info} -> {module, info.js_ast, filter_used_modules(info.used_modules, pid)} - end - ) + end) create_modules(prepared_modules, opts, js_modules) end @@ -47,22 +47,27 @@ defmodule ElixirScript.Output do defp create_modules(modules, opts, js_modules) do modules - |> Task.async_stream(fn({module, [body, exports], used_modules}) -> - modules = modules_to_import(used_modules) ++ js_modules - - imports = opts.module_formatter.build_imports(modules) - exports = opts.module_formatter.build_export(exports) - - js_parts = List.wrap(imports) ++ body ++ List.wrap(exports) - - js_parts - |> Builder.program - |> Generator.generate - |> concat - |> output(module, Map.get(opts, :output), js_modules) - end, timeout: 10_000) + |> Task.async_stream( + fn {module, [body, exports], used_modules} -> + modules = modules_to_import(used_modules) ++ js_modules + + imports = opts.module_formatter.build_imports(modules) + exports = opts.module_formatter.build_export(exports) + + js_parts = List.wrap(imports) ++ body ++ List.wrap(exports) + + js_parts + |> Builder.program() + |> Generator.generate() + |> concat + |> output(module, Map.get(opts, :output), js_modules) + end, + timeout: 10_000 + ) |> Stream.map(fn {:ok, code} -> code end) |> Enum.to_list() + |> List.flatten() + |> Enum.uniq() end defp modules_to_import(modules) do @@ -70,79 +75,92 @@ defmodule ElixirScript.Output do end defp module_to_import(module) do - {module, module_to_name(module), "", "./Elixir.#{inspect module}.js"} + {module, module_to_name(module), "", "./Elixir.#{inspect(module)}.js"} end def module_to_name(module) do - "$#{inspect module}$" + "$#{inspect(module)}$" |> String.replace(".", "$") end - defp output(code, module, nil, _), do: {module, code} + defp output(code, module, nil, _), do: [{module, code}] + defp output(code, module, :stdout, _) do IO.puts(code) - {module, code} + [{module, code}] end defp output(code, module, path, js_modules) do - output_dir = if File.dir?(path) do - path - else - Path.dirname(path) - end + output_dir = + if File.dir?(path) do + path + else + Path.dirname(path) + end - file_name = Path.join(output_dir, "Elixir.#{inspect module}.js") + file_name = Path.join(output_dir, "Elixir.#{inspect(module)}.js") if !File.exists?(output_dir) do File.mkdir_p!(output_dir) end apps = get_app_names() - Enum.each(js_modules, fn({_, _, path, _}) -> - copy_javascript_module(apps, output_dir, path) - end) + + ffi_modules = + Enum.reduce(js_modules, [], fn {module, _, path, _}, acc -> + acc ++ copy_javascript_module(apps, output_dir, module, path) + end) copy_bootstrap_js(output_dir) File.write!(file_name, code) - {module, code} + [{module, code}] ++ ffi_modules end defp copy_bootstrap_js(directory) do - operating_path = Path.join([Mix.Project.build_path, "lib", "elixir_script", "priv"]) + operating_path = Path.join([Mix.Project.build_path(), "lib", "elixir_script", "priv"]) path = Path.join([operating_path, "build", "es", "ElixirScript.Core.js"]) File.cp!(path, Path.join([directory, "ElixirScript.Core.js"])) end defp get_app_names() do Mix.Project.config()[:app] - deps = Mix.Project.deps_paths() - |> Map.keys + + deps = + Mix.Project.deps_paths() + |> Map.keys() [Mix.Project.config()[:app]] ++ deps end - defp copy_javascript_module(apps, output_dir, js_module_path) do - Enum.each(apps, fn(app) -> + defp copy_javascript_module(apps, output_dir, module, js_module_path) do + Enum.reduce(apps, [], fn app, acc -> base_path = Path.join([:code.priv_dir(app), "elixir_script"]) - js_input_path = cond do - File.exists?(Path.join([base_path, js_module_path])) -> - Path.join([base_path, js_module_path]) - File.exists?(Path.join([base_path, slashes_to_dots(js_module_path)])) -> - Path.join([base_path, slashes_to_dots(js_module_path)]) - true -> - nil - end + js_input_path = + cond do + File.exists?(Path.join([base_path, js_module_path])) -> + Path.join([base_path, js_module_path]) + + File.exists?(Path.join([base_path, slashes_to_dots(js_module_path)])) -> + Path.join([base_path, slashes_to_dots(js_module_path)]) + + true -> + nil + end if js_input_path != nil do js_output_path = Path.join(output_dir, js_module_path) js_output_dir = Path.dirname(js_output_path) + if !File.exists?(js_output_dir) do File.mkdir_p!(js_output_dir) end File.cp(js_input_path, js_output_path) + acc ++ [{module, js_input_path, js_output_path}] + else + [] end end) end diff --git a/lib/elixir_script/passes/translate/form.ex b/lib/elixir_script/passes/translate/form.ex index 475b4e02..c14a4361 100644 --- a/lib/elixir_script/passes/translate/form.ex +++ b/lib/elixir_script/passes/translate/form.ex @@ -7,29 +7,31 @@ defmodule ElixirScript.Translate.Form do alias ElixirScript.Translate.Helpers alias ElixirScript.Translate.Forms.{Bitstring, Match, Try, For, Receive, Remote, Pattern, With} alias ElixirScript.Translate.Clause + alias ElixirScript.State, as: ModuleState require Logger - @spec compile!(any, map) :: ESTree.Node.t + @spec compile!(any, map) :: ESTree.Node.t() def compile!(ast, state) do {js_ast, _} = compile(ast, state) js_ast end - @spec compile(any, map) :: {ESTree.Node.t, map} + @spec compile(any, map) :: {ESTree.Node.t(), map} def compile(ast, state) def compile(nil, state) do - { J.identifier("null"), state } + {J.identifier("null"), state} end def compile(map, state) when is_map(map) do - quoted = Code.string_to_quoted!("#{inspect map}") + quoted = Code.string_to_quoted!("#{inspect(map)}") compile(quoted, state) end - def compile(form, state) when is_boolean(form) or is_integer(form) or is_float(form) or is_binary(form) do - { J.literal(form), state } + def compile(form, state) + when is_boolean(form) or is_integer(form) or is_float(form) or is_binary(form) do + {J.literal(form), state} end def compile([{:|, _, [_head, _tail]} = ast], state) do @@ -37,33 +39,33 @@ defmodule ElixirScript.Translate.Form do end def compile({:|, _, [head, tail]}, state) do - ast = Helpers.call( - J.member_expression( - Helpers.functions(), - J.identifier("concat") - ), - [compile!(head, state), compile!(tail, state)] - ) + ast = + Helpers.call( + J.member_expression( + Helpers.functions(), + J.identifier("concat") + ), + [compile!(head, state), compile!(tail, state)] + ) - { ast, state } + {ast, state} end def compile(form, state) when is_list(form) do - ast = J.array_expression( - Enum.map(form, &compile!(&1, state)) - ) + ast = J.array_expression(Enum.map(form, &compile!(&1, state))) - { ast, state } + {ast, state} end def compile(form, state) when is_atom(form) do - ast = if ElixirScript.Translate.Module.is_elixir_module(form) do - Remote.process_module_name(form, state) - else - Helpers.symbol(form) - end + ast = + if ElixirScript.Translate.Module.is_elixir_module(form) do + Remote.process_module_name(form, state) + else + Helpers.symbol(form) + end - { ast, state } + {ast, state} end def compile({a, b}, state) do @@ -71,10 +73,11 @@ defmodule ElixirScript.Translate.Form do end def compile({:{}, _, elements}, state) do - ast = Helpers.new( - Helpers.tuple(), - Enum.map(elements, &compile!(&1, state)) |> List.flatten - ) + ast = + Helpers.new( + Helpers.tuple(), + Enum.map(elements, &compile!(&1, state)) |> List.flatten() + ) {ast, state} end @@ -97,16 +100,19 @@ defmodule ElixirScript.Translate.Form do end def compile({:<<>>, _, elements} = bitstring, state) do - is_interpolated_string = Enum.all?(elements, fn(x) -> - case x do - b when is_binary(b) -> - true - {:::, _, [_target, {:binary, _, _}]} -> - true - _ -> - false - end - end) + is_interpolated_string = + Enum.all?(elements, fn x -> + case x do + b when is_binary(b) -> + true + + {:::, _, [_target, {:binary, _, _}]} -> + true + + _ -> + false + end + end) if is_interpolated_string do Bitstring.make_interpolated_string(elements, state) @@ -120,15 +126,16 @@ defmodule ElixirScript.Translate.Form do end def compile({:%, _, [module, params]}, state) do - ast = Helpers.call( - J.member_expression( - Remote.process_module_name(module, state), - J.identifier("__struct__") - ), - [compile!(params, state)] - ) + ast = + Helpers.call( + J.member_expression( + Remote.process_module_name(module, state), + J.identifier("__struct__") + ), + [compile!(params, state)] + ) - { ast, state } + {ast, state} end def compile({:for, _, generators} = ast, state) when is_list(generators) do @@ -141,61 +148,78 @@ defmodule ElixirScript.Translate.Form do match_ast = List.wrap(match_ast) - { match_ast ++ [case_ast], state } + {match_ast ++ [case_ast], state} end def compile({:case, _, [condition, [do: clauses]]}, state) do - func = Helpers.call( - J.member_expression( - Helpers.patterns(), - J.identifier("defmatch") - ), - Enum.map(clauses, fn x -> Clause.compile(x, state) |> elem(0) end) |> List.flatten - ) - - ast = Helpers.call( - J.member_expression( func, J.identifier("call")), - [J.identifier(:this), compile!(condition, state)] - ) + func = + Helpers.call( + J.member_expression( + Helpers.patterns(), + J.identifier("defmatch") + ), + Enum.map(clauses, fn x -> Clause.compile(x, state) |> elem(0) end) |> List.flatten() + ) + + ast = + Helpers.call(J.member_expression(func, J.identifier("call")), [ + J.identifier(:this), + compile!(condition, state) + ]) - { ast, state } + {ast, state} end def compile({:cond, _, [[do: clauses]]}, state) do - processed_clauses = Enum.map(clauses, fn({:->, _, [clause, clause_body]}) -> - { translated_body, state } = ElixirScript.Translate.Function.compile_block(clause_body, state) - - translated_body = translated_body - |> Clause.return_last_statement + processed_clauses = + Enum.map(clauses, fn {:->, _, [clause, clause_body]} -> + {translated_body, state} = + ElixirScript.Translate.Function.compile_block(clause_body, state) - translated_body = Helpers.arrow_function([], J.block_statement(translated_body)) + translated_body = + translated_body + |> Clause.return_last_statement() - { translated_clause, _ } = compile(hd(clause), state) + translated_body = Helpers.arrow_function([], J.block_statement(translated_body)) + {translated_clause, _} = compile(hd(clause), state) - J.array_expression([translated_clause, translated_body]) - end) - + J.array_expression([translated_clause, translated_body]) + end) - cond_function = J.member_expression( - Helpers.special_forms(), - J.identifier("cond") - ) + cond_function = + J.member_expression( + Helpers.special_forms(), + J.identifier("cond") + ) - ast = Helpers.call( - cond_function, - processed_clauses - ) + ast = + Helpers.call( + cond_function, + processed_clauses + ) - { ast, state } + {ast, state} end def compile({:receive, context, [blocks]}, state) do line = Keyword.get(context, :line, 1) + module = Map.get(state, :module) + pid = Map.get(state, :pid) {function, _arity} = Map.get(state, :function) - Logger.warn fn() -> - "ElixirScript: receive not supported, Module: #{inspect state.module}, Function: #{function}, Line: #{line}" - end + + ModuleState.put_diagnostic(pid, module, %{ + severity: :warning, + message: "receive not supported, Module: #{inspect(state.module)}, Function: #{function}", + position: line + }) + + Logger.warn(fn -> + "ElixirScript: receive not supported, Module: #{inspect(state.module)}, Function: #{ + function + }, Line: #{line}" + end) + Receive.compile(blocks, state) end @@ -212,102 +236,113 @@ defmodule ElixirScript.Translate.Form do end def compile({{:., _, [:erlang, op]}, _, [item]}, state) when op in [:+, :-] do - ast = J.unary_expression( - op, - true, - compile!(item, state) - ) + ast = + J.unary_expression( + op, + true, + compile!(item, state) + ) {ast, state} end def compile({{:., _, [:erlang, op]}, _, [left, right]}, state) when op in [:==, :===] do - ast = Helpers.call( - J.member_expression( - Helpers.core_module("erlang"), - J.identifier("equals") - ), - [compile!(left, state), compile!(right, state)] - ) + ast = + Helpers.call( + J.member_expression( + Helpers.core_module("erlang"), + J.identifier("equals") + ), + [compile!(left, state), compile!(right, state)] + ) {ast, state} end - def compile({{:., _, [:erlang, op]}, _, [left, right]}, state) when op in [:+, :-, :*, :/, :>, :<, :>=] do - ast = J.binary_expression( - op, - compile!(left, state), - compile!(right, state) - ) + def compile({{:., _, [:erlang, op]}, _, [left, right]}, state) + when op in [:+, :-, :*, :/, :>, :<, :>=] do + ast = + J.binary_expression( + op, + compile!(left, state), + compile!(right, state) + ) {ast, state} end def compile({{:., _, [:erlang, :"=<"]}, _, [left, right]}, state) do - ast = J.binary_expression( - :<=, - compile!(left, state), - compile!(right, state) - ) + ast = + J.binary_expression( + :<=, + compile!(left, state), + compile!(right, state) + ) {ast, state} end def compile({{:., _, [:erlang, :"=:="]}, _, [left, right]}, state) do - ast = J.binary_expression( - :===, - compile!(left, state), - compile!(right, state) - ) + ast = + J.binary_expression( + :===, + compile!(left, state), + compile!(right, state) + ) {ast, state} end def compile({{:., _, [:erlang, :"=/="]}, _, [left, right]}, state) do - ast = J.binary_expression( - :!==, - compile!(left, state), - compile!(right, state) - ) + ast = + J.binary_expression( + :!==, + compile!(left, state), + compile!(right, state) + ) {ast, state} end def compile({{:., _, [:erlang, :"/="]}, _, [left, right]}, state) do - ast = J.binary_expression( - :!=, - compile!(left, state), - compile!(right, state) - ) + ast = + J.binary_expression( + :!=, + compile!(left, state), + compile!(right, state) + ) {ast, state} end def compile({{:., _, [:erlang, op]}, _, [left, right]}, state) when op in [:andalso, :and] do - ast = J.binary_expression( - :&&, - compile!(left, state), - compile!(right, state) - ) + ast = + J.binary_expression( + :&&, + compile!(left, state), + compile!(right, state) + ) {ast, state} end def compile({{:., _, [:erlang, op]}, _, [left, right]}, state) when op in [:orelse, :or] do - ast = J.binary_expression( - :||, - compile!(left, state), - compile!(right, state) - ) + ast = + J.binary_expression( + :||, + compile!(left, state), + compile!(right, state) + ) {ast, state} end def compile({{:., _, [var, func_or_prop]}, _, []}, state) when not is_atom(var) do - ast = Helpers.call( - ElixirScript.Translate.Forms.JS.call_property(), - [compile!(var, state), J.literal(to_string(func_or_prop))] - ) + ast = + Helpers.call(ElixirScript.Translate.Forms.JS.call_property(), [ + compile!(var, state), + J.literal(to_string(func_or_prop)) + ]) {ast, state} end @@ -324,14 +359,16 @@ defmodule ElixirScript.Translate.Form do {function_name, _} = Map.get(state, :function) {var_decs, params} = compile_params(params, state) - ast = Helpers.call( - ElixirScript.Translate.Identifier.make_function_name(function_name), - params - ) + ast = + Helpers.call( + ElixirScript.Translate.Identifier.make_function_name(function_name), + params + ) case var_decs do [] -> {ast, state} + _ -> {var_decs ++ List.wrap(ast), state} end @@ -344,24 +381,24 @@ defmodule ElixirScript.Translate.Form do def compile({var, _, params}, state) when is_list(params) and is_atom(var) do {var_decs, params} = compile_params(params, state) - ast = Helpers.call( - ElixirScript.Translate.Identifier.make_function_name(var), - params - ) + ast = + Helpers.call( + ElixirScript.Translate.Identifier.make_function_name(var), + params + ) case var_decs do [] -> {ast, state} + _ -> {var_decs ++ List.wrap(ast), state} end end def compile({function, _, []}, state) do - ast = Helpers.call( - ElixirScript.Translate.Forms.JS.call_property(), - [compile!(function, state)] - ) + ast = + Helpers.call(ElixirScript.Translate.Forms.JS.call_property(), [compile!(function, state)]) {ast, state} end @@ -369,14 +406,16 @@ defmodule ElixirScript.Translate.Form do def compile({function, _, params}, state) when is_list(params) do {var_decs, params} = compile_params(params, state) - ast = Helpers.call( - compile!(function, state), - params - ) + ast = + Helpers.call( + compile!(function, state), + params + ) case var_decs do [] -> {ast, state} + _ -> {var_decs ++ List.wrap(ast), state} end @@ -387,34 +426,36 @@ defmodule ElixirScript.Translate.Form do var = ElixirScript.Translate.Identifier.filter_name(var) var = Pattern.get_variable_name(var <> counter, state) - { ElixirScript.Translate.Identifier.make_identifier(var), state } + {ElixirScript.Translate.Identifier.make_identifier(var), state} end defp compile_params(params, state) do - {params, var_decs} = Enum.map_reduce(params, [], fn - ({:=, _, [{left_var, _, atom} = left, right]} = ast, acc) when is_atom(atom) -> - case Atom.to_string(left_var) do - "_" <> _ -> - {compile!(right, state), acc} - _ -> - {ast, state} = compile(ast, state) - left = compile!(left, state) + {params, var_decs} = + Enum.map_reduce(params, [], fn + {:=, _, [{left_var, _, atom} = left, right]} = ast, acc when is_atom(atom) -> + case Atom.to_string(left_var) do + "_" <> _ -> + {compile!(right, state), acc} - {left, acc ++ List.wrap(ast)} - end + _ -> + {ast, state} = compile(ast, state) + left = compile!(left, state) - ({:=, _, [left, _]} = ast, acc) -> - {ast, state} = compile(ast, state) - left = compile!(left, state) + {left, acc ++ List.wrap(ast)} + end - {left, acc ++ List.wrap(ast)} - (x, acc) -> - compiled = compile!(x, state) + {:=, _, [left, _]} = ast, acc -> + {ast, state} = compile(ast, state) + left = compile!(left, state) - {compiled, acc} - end) + {left, acc ++ List.wrap(ast)} + + x, acc -> + compiled = compile!(x, state) + + {compiled, acc} + end) {var_decs, params} end - end diff --git a/lib/elixir_script/passes/translate/module.ex b/lib/elixir_script/passes/translate/module.ex index 58638e02..831c6848 100644 --- a/lib/elixir_script/passes/translate/module.ex +++ b/lib/elixir_script/passes/translate/module.ex @@ -7,8 +7,22 @@ defmodule ElixirScript.Translate.Module do alias ElixirScript.Translate.Form @operators [ - :+, :-, :*, :/, :!=, :==, :===, :<=, :>=, :=~, :++, - :!==, :--, :<, :> + :+, + :-, + :*, + :/, + :!=, + :==, + :===, + :<=, + :>=, + :=~, + :++, + :!==, + :--, + :<, + :>, + :=~ ] @doc """ @@ -31,7 +45,7 @@ defmodule ElixirScript.Translate.Module do file: _file, line: _line, module: ^module, - unreachable: unreachable, + unreachable: unreachable } = info used = Map.get(info, :used) @@ -44,34 +58,44 @@ defmodule ElixirScript.Translate.Module do # Filter so that we only have the # Used functions to compile - reachable_defs = Enum.filter(defs, fn - { _, type, _, _} when type in [:defmacro, :defmacrop] -> false - { name, _, _, _} -> not(name in unreachable) + reachable_defs = + Enum.filter(defs, fn + {_, type, _, _} when type in [:defmacro, :defmacrop] -> false + {name, _, _, _} -> name not in unreachable _ -> true end) - used_defs = if Keyword.has_key?(attrs, :protocol_impl) or used == nil do - reachable_defs - else - Enum.filter(reachable_defs, fn - { {:start, 2}, _, _, _ } -> true - { {:__struct__, _}, _, _, _ } -> true - { {name, _}, _, _, _ } when name in @operators -> false - { name, _, _, _} -> - if remove_unused_functions do - name in used - else + used_defs = + if Keyword.has_key?(attrs, :protocol_impl) or used == nil do + reachable_defs + else + Enum.filter(reachable_defs, fn + {{:start, 2}, _, _, _} -> true - end - _ -> false - end) - end - #we combine our function arities + {{:__struct__, _}, _, _, _} -> + true + + {{name, _}, _, _, _} when name in @operators -> + false + + {name, _, _, _} -> + if remove_unused_functions do + name in used + else + true + end + + _ -> + false + end) + end + + # we combine our function arities combined_defs = combine_defs(used_defs) exports = make_exports(module, combined_defs) - { compiled_functions, _ } = Enum.map_reduce(combined_defs, state, &Function.compile(&1, &2)) + {compiled_functions, _} = Enum.map_reduce(combined_defs, state, &Function.compile(&1, &2)) info_function = make_info_function(module, state) compiled_functions = [info_function] ++ compiled_functions @@ -83,37 +107,47 @@ defmodule ElixirScript.Translate.Module do defp combine_defs(used_defs) do used_defs - |> Enum.sort(fn { {name1, arity1}, _, _, _ }, { {name2, arity2}, _, _, _ } -> "#{name1}#{arity1}" < "#{name2}#{arity2}" end) - |> Enum.group_by(fn {{name, _}, _, _, _ } -> name end) + |> Enum.sort(fn {{name1, arity1}, _, _, _}, {{name2, arity2}, _, _, _} -> + "#{name1}#{arity1}" < "#{name2}#{arity2}" + end) + |> Enum.group_by(fn {{name, _}, _, _, _} -> name end) |> Enum.map(fn {group, funs} -> - {_, type, _, _} = hd(funs) - Enum.reduce(funs, {{group, nil}, type, [], []}, fn {_, _, _, clauses}, {name, type, context, acc_clauses} -> - {name, type, context, acc_clauses ++ clauses} - end) + {_, type, _, _} = hd(funs) + + Enum.reduce(funs, {{group, nil}, type, [], []}, fn {_, _, _, clauses}, + {name, type, context, acc_clauses} -> + {name, type, context, acc_clauses ++ clauses} end) + end) end defp make_exports(module, reachable_defs) do - exports = Enum.reduce(reachable_defs, [], fn - {{name, _arity}, :def, _, _}, list -> - function_name = ElixirScript.Translate.Identifier.make_identifier(name) + exports = + Enum.reduce(reachable_defs, [], fn + {{name, _arity}, :def, _, _}, list -> + function_name = ElixirScript.Translate.Identifier.make_identifier(name) list ++ [J.property(function_name, function_name, :init, true)] - _, list -> - list - end) + + _, list -> + list + end) # Add an attribute to use to determine if this is a module # Will be used by the is_atom implementation - exports = exports ++ [%ESTree.Property{ - key: J.identifier("__MODULE__"), - value: Helpers.symbol(to_string(module)) - }, - J.property( - J.identifier("__info__"), - J.identifier("__info__"), - :init, - true - )] + exports = + exports ++ + [ + %ESTree.Property{ + key: J.identifier("__MODULE__"), + value: Helpers.symbol(to_string(module)) + }, + J.property( + J.identifier("__info__"), + J.identifier("__info__"), + :init, + true + ) + ] J.object_expression(exports) end @@ -128,6 +162,7 @@ defmodule ElixirScript.Translate.Module do case str_module do "Elixir" <> _ -> true + _ -> false end @@ -147,67 +182,73 @@ defmodule ElixirScript.Translate.Module do cond do module in ModuleState.list_javascript_modules(state.pid) -> true + module === Elixir -> false + true -> false end end defp make_info_map(module, state) do - functions = module.__info__(:functions) - |> Form.compile!(state) + functions = + module.__info__(:functions) + |> Form.compile!(state) - macros = module.__info__(:macros) - |> Form.compile!(state) + macros = + module.__info__(:macros) + |> Form.compile!(state) - attributes = module.__info__(:attributes) - |> Form.compile!(state) + attributes = + module.__info__(:attributes) + |> Form.compile!(state) - compile = module.__info__(:compile) - |> Keyword.update(:source, "", fn(x) -> :erlang.list_to_binary(x) end) - |> Form.compile!(state) + compile = + module.__info__(:compile) + |> Keyword.update(:source, "", fn x -> :erlang.list_to_binary(x) end) + |> Form.compile!(state) - md5 = module.__info__(:md5) - |> :erlang.binary_to_list + md5 = + module.__info__(:md5) + |> :erlang.binary_to_list() md5 = Form.compile!({:<<>>, [], md5}, state) module = Helpers.symbol(to_string(module)) - map_entries = J.array_expression([ + map_entries = J.array_expression([ - Helpers.symbol("functions"), - functions - ]), - J.array_expression([ - Helpers.symbol("macros"), - macros - ]), - J.array_expression([ - Helpers.symbol("attributes"), - attributes - ]), - J.array_expression([ - Helpers.symbol("compile"), - compile - ]), - J.array_expression([ - Helpers.symbol("md5"), - md5 - ]), - J.array_expression([ - Helpers.symbol("module"), - module - ]), - ]) - - map = Helpers.new( - J.identifier("Map"), - [ + J.array_expression([ + Helpers.symbol("functions"), + functions + ]), + J.array_expression([ + Helpers.symbol("macros"), + macros + ]), + J.array_expression([ + Helpers.symbol("attributes"), + attributes + ]), + J.array_expression([ + Helpers.symbol("compile"), + compile + ]), + J.array_expression([ + Helpers.symbol("md5"), + md5 + ]), + J.array_expression([ + Helpers.symbol("module"), + module + ]) + ]) + + map = + Helpers.new(J.identifier("Map"), [ map_entries - ] - ) + ]) Helpers.declare("__info__map__", map) end @@ -217,43 +258,46 @@ defmodule ElixirScript.Translate.Module do defp make_info_function(module, state) do info_map = make_info_map(module, state) - get_call = Helpers.call( - J.member_expression( - J.identifier("__info__map__"), - J.identifier("get") - ), - [ - J.identifier("kind") - ] - ) + get_call = + Helpers.call( + J.member_expression( + J.identifier("__info__map__"), + J.identifier("get") + ), + [ + J.identifier("kind") + ] + ) value = Helpers.declare("value", get_call) - body = J.if_statement( - J.binary_expression( - :!==, - J.identifier("value"), - J.identifier("null") - ), - J.block_statement([ - J.return_statement(J.identifier("value")) - ]) - ) + body = + J.if_statement( + J.binary_expression( + :!==, + J.identifier("value"), + J.identifier("null") + ), + J.block_statement([ + J.return_statement(J.identifier("value")) + ]) + ) - body = J.block_statement([ - info_map, - value, - body, - J.throw_statement( - Helpers.new( - J.member_expression( - Helpers.patterns(), - J.identifier("MatchError") - ), - [J.identifier("kind")] + body = + J.block_statement([ + info_map, + value, + body, + J.throw_statement( + Helpers.new( + J.member_expression( + Helpers.patterns(), + J.identifier("MatchError") + ), + [J.identifier("kind")] + ) ) - ) - ]) + ]) Helpers.function( "__info__", diff --git a/lib/elixir_script/state.ex b/lib/elixir_script/state.ex index 73208ec6..3a45f745 100644 --- a/lib/elixir_script/state.ex +++ b/lib/elixir_script/state.ex @@ -35,7 +35,7 @@ defmodule ElixirScript.State do end) end - def add_used_module(pid, module, used_module) do + def put_used_module(pid, module, used_module) do Agent.update(pid, fn state -> module_info = Keyword.get(state.modules, module) @@ -58,7 +58,7 @@ defmodule ElixirScript.State do end) end - def add_used(pid, module, {_function, _arity} = func) do + def put_used(pid, module, {_function, _arity} = func) do Agent.update(pid, fn state -> module_info = Keyword.get(state.modules, module) @@ -80,6 +80,24 @@ defmodule ElixirScript.State do end) end + def put_diagnostic(pid, module, diagnostic) do + Agent.update(pid, fn state -> + module_info = Keyword.get(state.modules, module) + + if module_info do + diagnostics = Map.get(module_info, :diagnostics, []) + diagnostics = [diagnostic | diagnostics] + + module_info = Map.put(module_info, :diagnostics, diagnostics) + modules = Keyword.put(state.modules, module, module_info) + + %{state | modules: modules} + else + state + end + end) + end + def list_javascript_modules(pid) do Agent.get(pid, fn state -> state.js_modules diff --git a/lib/mix/tasks/compile.elixir_script.ex b/lib/mix/tasks/compile.elixir_script.ex index cdb05da9..a5ab2046 100644 --- a/lib/mix/tasks/compile.elixir_script.ex +++ b/lib/mix/tasks/compile.elixir_script.ex @@ -1,5 +1,5 @@ defmodule Mix.Tasks.Compile.ElixirScript do - use Mix.Task + use Mix.Task.Compiler alias ElixirScript.Manifest @recursive true @@ -35,7 +35,6 @@ defmodule Mix.Tasks.Compile.ElixirScript do The mix compiler will also compile any dependencies that have the elixirscript compiler in its mix compilers as well """ - @spec run(any()) :: :ok def run(_) do do_compile() @@ -60,6 +59,7 @@ defmodule Mix.Tasks.Compile.ElixirScript do def get_compiler_params() do elixirscript_config = get_elixirscript_config() input = Keyword.fetch!(elixirscript_config, :input) + opts = [ output: Keyword.get(elixirscript_config, :output) ] @@ -68,15 +68,19 @@ defmodule Mix.Tasks.Compile.ElixirScript do end defp get_elixirscript_config() do - config = Mix.Project.config - exjs_config = cond do - Keyword.has_key?(config, :elixir_script) -> - Keyword.get(config, :elixir_script, []) - Keyword.has_key?(config, :elixirscript) -> - Keyword.get(config, :elixirscript, []) - true -> - defaults() - end + config = Mix.Project.config() + + exjs_config = + cond do + Keyword.has_key?(config, :elixir_script) -> + Keyword.get(config, :elixir_script, []) + + Keyword.has_key?(config, :elixirscript) -> + Keyword.get(config, :elixirscript, []) + + true -> + defaults() + end Keyword.merge(defaults(), exjs_config) end @@ -86,5 +90,4 @@ defmodule Mix.Tasks.Compile.ElixirScript do output: "priv/elixir_script/build" ] end - end diff --git a/test/compiler_test.exs b/test/compiler_test.exs index 439975f5..b7b05dd3 100644 --- a/test/compiler_test.exs +++ b/test/compiler_test.exs @@ -3,17 +3,17 @@ defmodule ElixirScript.Compiler.Test do test "Can compile one entry module" do result = ElixirScript.Compiler.compile(Version) - assert result |> Map.to_list |> hd |> elem(1) |> Map.get(:js_code) |> is_binary + assert result |> Map.to_list() |> hd |> elem(1) |> Map.get(:js_code) |> is_binary end test "Can compile multiple entry modules" do result = ElixirScript.Compiler.compile([Atom, String, Agent]) - assert result |> Map.to_list |> hd |> elem(1) |> Map.get(:js_code) |> is_binary + assert result |> Map.to_list() |> hd |> elem(1) |> Map.get(:js_code) |> is_binary end test "Output" do result = ElixirScript.Compiler.compile(Atom, []) - assert result |> Map.to_list |> hd |> elem(1) |> Map.get(:js_code) =~ "export default" + assert result |> Map.to_list() |> hd |> elem(1) |> Map.get(:js_code) =~ "export default" end test "compile file" do @@ -22,7 +22,7 @@ defmodule ElixirScript.Compiler.Test do input_path = Path.join([File.cwd!(), "test", "beam_test.exs"]) - ElixirScript.Compiler.compile(input_path, [output: path]) + ElixirScript.Compiler.compile(input_path, output: path) assert File.exists?(path) assert String.contains?(File.read!(path), "export default") end @@ -33,7 +33,7 @@ defmodule ElixirScript.Compiler.Test do input_path = Path.join([File.cwd!(), "test", "*fi_test.exs"]) - ElixirScript.Compiler.compile(input_path, [output: path]) + ElixirScript.Compiler.compile(input_path, output: path) assert File.exists?(file) assert String.contains?(File.read!(file), "export default") end diff --git a/test/passes/translate/forms/receive_test.exs b/test/passes/translate/forms/receive_test.exs index f265962a..9f8496a7 100644 --- a/test/passes/translate/forms/receive_test.exs +++ b/test/passes/translate/forms/receive_test.exs @@ -3,16 +3,32 @@ defmodule ElixirScript.Translate.Forms.Receive.Test do alias ElixirScript.Translate.{Form, Helpers} alias ESTree.Tools.Builder, as: J - test "receive translation" do + setup_all do + {:ok, pid} = ElixirScript.State.start_link(%{}) + + state = %{ + pid: pid, + module: __MODULE__ + } + + [state: state] + end + + test "receive translation", %{state: state} do clause = {:->, [line: 644], [[], [{:__block__, [], [1]}]]} ast = {:receive, [line: 644], [[do: [clause], after: nil]]} - state = %{function: {:each, nil}, module: __MODULE__, anonymous_fn: false} + + state = + state + |> Map.put(:function, {:each, nil}) + |> Map.put(:anonymous_fn, false) {js_ast, _} = Form.compile(ast, state) - assert js_ast.callee == J.member_expression( - Helpers.special_forms(), - J.identifier("receive") - ) - end + assert js_ast.callee == + J.member_expression( + Helpers.special_forms(), + J.identifier("receive") + ) + end end From 9078aed8ba05ed65d0a6e27a6d564e85ebc44a33 Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Wed, 3 Jan 2018 15:58:59 -0600 Subject: [PATCH 384/418] Outputting diagnostic information from elixirscript compiler --- lib/elixir_script/beam.ex | 88 +++++++++++-------- lib/elixir_script/compile_error.ex | 2 +- lib/elixir_script/compiler.ex | 11 ++- lib/elixir_script/passes/find_used_modules.ex | 8 +- lib/mix/tasks/compile.elixir_script.ex | 41 +++++++-- 5 files changed, 93 insertions(+), 57 deletions(-) diff --git a/lib/elixir_script/beam.ex b/lib/elixir_script/beam.ex index 4473f221..0a727ef1 100644 --- a/lib/elixir_script/beam.ex +++ b/lib/elixir_script/beam.ex @@ -30,6 +30,7 @@ defmodule ElixirScript.Beam do case do_debug_info(Module.concat(ElixirScript, module)) do {:ok, info} -> {:ok, Map.put(info, :module, module)} + e -> e end @@ -49,28 +50,32 @@ defmodule ElixirScript.Beam do case :code.get_object_code(module) do {_, beam, beam_path} -> do_debug_info(beam, beam_path) + :error -> {:error, "Unknown module"} end end defp do_debug_info(beam, beam_path) do - with {:ok, {module, [debug_info: {:debug_info_v1, backend, data}]}} <- :beam_lib.chunks(beam, [:debug_info]), - {:ok, {^module, attribute_info}} = :beam_lib.chunks(beam, [:attributes]) do - - if Keyword.get(attribute_info[:attributes], :protocol) do - get_protocol_implementations(module, beam_path) - else - backend.debug_info(:elixir_v1, module, data, []) - |> process_debug_info(beam_path) - end + with {:ok, {module, [debug_info: {:debug_info_v1, backend, data}]}} <- + :beam_lib.chunks(beam, [:debug_info]), + {:ok, {^module, attribute_info}} = :beam_lib.chunks(beam, [:attributes]) do + if Keyword.get(attribute_info[:attributes], :protocol) do + get_protocol_implementations(module, beam_path) + else + backend.debug_info(:elixir_v1, module, data, []) + |> process_debug_info(beam_path) + end else :error -> {:error, "Unknown module"} + {:error, :beam_lib, {:unknown_chunk, "non_existing.beam", :debug_info}} -> {:error, "Unsupported version of Erlang"} - {:error, :beam_lib, {:missing_chunk, _ , _}} -> + + {:error, :beam_lib, {:missing_chunk, _, _}} -> {:error, "Debug info not available"} + {:error, :beam_lib, {:file_error, "non_existing.beam", :enoent}} -> {:error, "Debug info not available"} end @@ -82,12 +87,14 @@ defmodule ElixirScript.Beam do end defp process_debug_info({:ok, info}, beam_path) do - info = case File.stat(beam_path, time: :posix) do - {:ok, file_info} -> - Map.put(info, :last_modified, file_info.mtime) - _ -> - Map.put(info, :last_modified, nil) - end + info = + case File.stat(beam_path, time: :posix) do + {:ok, file_info} -> + Map.put(info, :last_modified, file_info.mtime) + + _ -> + Map.put(info, :last_modified, nil) + end info = Map.put(info, :beam_path, beam_path) @@ -101,36 +108,39 @@ defmodule ElixirScript.Beam do defp get_protocol_implementations(module, beam_path) do {:ok, protocol_module_info} = process_debug_info({:ok, %{}}, beam_path) - implementations = module - |> Protocol.extract_impls(:code.get_path()) - |> Enum.map(fn(x) -> Module.concat([module, x]) end) - |> Enum.map(fn(x) -> - case debug_info(x) do - {:ok, info} -> - {x, info} - _ -> - raise "Unable to compile protocol implementation #{inspect x}" - end - end) + implementations = + module + |> Protocol.extract_impls(:code.get_path()) + |> Enum.map(fn x -> Module.concat([module, x]) end) + |> Enum.map(fn x -> + case debug_info(x) do + {:ok, info} -> + {x, info} + + _ -> + raise ElixirScript.CompileError, + message: "Unable to compile protocol implementation #{inspect(x)}", + severity: :error + end + end) {:ok, module, protocol_module_info, implementations} end defp replace_definitions(original_definitions, replacement_definitions) do - Enum.map(original_definitions, fn - {{function, arity}, type, _, _} = ast -> - ex_ast = Enum.find(replacement_definitions, fn - {{ex_function, ex_arity}, ex_type, _, _} -> - ex_function == function and ex_arity == arity and ex_type == type + Enum.map(original_definitions, fn {{function, arity}, type, _, _} = ast -> + ex_ast = + Enum.find(replacement_definitions, fn {{ex_function, ex_arity}, ex_type, _, _} -> + ex_function == function and ex_arity == arity and ex_type == type end) - case ex_ast do - nil -> - ast - _ -> - ex_ast - end + case ex_ast do + nil -> + ast + + _ -> + ex_ast + end end) end - end diff --git a/lib/elixir_script/compile_error.ex b/lib/elixir_script/compile_error.ex index fea01237..d670552b 100644 --- a/lib/elixir_script/compile_error.ex +++ b/lib/elixir_script/compile_error.ex @@ -1,3 +1,3 @@ defmodule ElixirScript.CompileError do - defexception [:message] + defexception [:message, :severity] end diff --git a/lib/elixir_script/compiler.ex b/lib/elixir_script/compiler.ex index 61a95201..1b12d37b 100644 --- a/lib/elixir_script/compiler.ex +++ b/lib/elixir_script/compiler.ex @@ -121,6 +121,12 @@ defmodule ElixirScript.Compiler do Enum.reduce(modules, %{}, fn {module, info}, current_data -> + diagnostics = + Map.get(info, :diagnostics, []) + |> Enum.map(fn x -> + Map.put(x, :file, Map.get(info, :file)) + end) + info = %{ references: info.used_modules, last_modified: info.last_modified, @@ -128,7 +134,7 @@ defmodule ElixirScript.Compiler do source: Map.get(info, :file), js_path: Path.join(output_path, "#{module}.js"), js_code: Keyword.get(compiled_js, module), - diagnostics: Map.get(info, :diagnostics, []), + diagnostics: diagnostics, type: :module } @@ -148,8 +154,7 @@ defmodule ElixirScript.Compiler do references: [], last_modified: last_modified, beam_path: nil, - source: nil, - js_input_path: js_input_path, + source: js_input_path, js_path: js_output_path, js_code: nil, diagnostics: [], diff --git a/lib/elixir_script/passes/find_used_modules.ex b/lib/elixir_script/passes/find_used_modules.ex index c111c249..4befed2e 100644 --- a/lib/elixir_script/passes/find_used_modules.ex +++ b/lib/elixir_script/passes/find_used_modules.ex @@ -43,13 +43,9 @@ defmodule ElixirScript.FindUsedModules do }) {:error, error} -> - ModuleState.put_diagnostic(pid, module, %{ - severity: :error, - message: "An error occurred while compiling #{inspect(module)}: #{error}" - }) - raise ElixirScript.CompileError, - "An error occurred while compiling #{inspect(module)}: #{error}" + message: "An error occurred while compiling #{inspect(module)}: #{error}", + severity: :error end end diff --git a/lib/mix/tasks/compile.elixir_script.ex b/lib/mix/tasks/compile.elixir_script.ex index a5ab2046..36607e07 100644 --- a/lib/mix/tasks/compile.elixir_script.ex +++ b/lib/mix/tasks/compile.elixir_script.ex @@ -1,6 +1,7 @@ defmodule Mix.Tasks.Compile.ElixirScript do use Mix.Task.Compiler alias ElixirScript.Manifest + alias ElixirScript.Compiler @recursive true @manifest ".compile.elixir_script" @@ -35,17 +36,41 @@ defmodule Mix.Tasks.Compile.ElixirScript do The mix compiler will also compile any dependencies that have the elixirscript compiler in its mix compilers as well """ - @spec run(any()) :: :ok + @spec run([binary()]) :: + :ok | :noop | {:ok | :noop | :error, [Mix.Task.Compiler.Diagnostic.t()]} def run(_) do - do_compile() - :ok - end - - defp do_compile() do {input, opts} = get_compiler_params() - result = ElixirScript.Compiler.compile(input, opts) - Manifest.write_manifest(manifest(), result) + try do + result = Compiler.compile(input, opts) + Manifest.write_manifest(manifest(), result) + + result + |> Enum.map(fn {_module, info} -> + info.diagnositcs + end) + |> List.flatten() + |> Enum.map(fn x -> + %Mix.Task.Compiler.Diagnostic{ + compiler_name: "elixir_script", + file: x.file, + message: x.message, + position: x.position, + severity: x.severity + } + end) + rescue + x in [ElixirScript.CompileError] -> + [ + %Mix.Task.Compiler.Diagnostic{ + compiler_name: "elixir_script", + message: x.message, + severity: x.severity, + position: nil, + file: nil + } + ] + end end def clean do From adc39f82dc7f7fca3149ef94e99da07e69ae084c Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Wed, 3 Jan 2018 19:33:28 -0600 Subject: [PATCH 385/418] compiler can now clean up after itself --- lib/elixir_script/compiler.ex | 113 +++++++++++++++---------- lib/elixir_script/manifest.ex | 17 ++-- lib/elixir_script/passes/output.ex | 14 +-- lib/mix/tasks/compile.elixir_script.ex | 62 ++++++++------ 4 files changed, 123 insertions(+), 83 deletions(-) diff --git a/lib/elixir_script/compiler.ex b/lib/elixir_script/compiler.ex index 1b12d37b..35f7b8ec 100644 --- a/lib/elixir_script/compiler.ex +++ b/lib/elixir_script/compiler.ex @@ -113,55 +113,74 @@ defmodule ElixirScript.Compiler do defp transform_output(modules, compiled_js, opts) do output_path = - if opts.output == nil or opts.output == :stdout do - "" - else - Path.dirname(opts.output) + cond do + opts.output == nil or opts.output == :stdout -> + "" + + File.dir?(opts.output) -> + opts.output + + true -> + Path.dirname(opts.output) end - Enum.reduce(modules, %{}, fn - {module, info}, current_data -> - diagnostics = - Map.get(info, :diagnostics, []) - |> Enum.map(fn x -> - Map.put(x, :file, Map.get(info, :file)) - end) - - info = %{ - references: info.used_modules, - last_modified: info.last_modified, - beam_path: Map.get(info, :beam_path), - source: Map.get(info, :file), - js_path: Path.join(output_path, "#{module}.js"), - js_code: Keyword.get(compiled_js, module), - diagnostics: diagnostics, - type: :module - } - - Map.put(current_data, module, info) - - {module, js_input_path, js_output_path}, current_data -> - last_modified = - case File.stat(js_input_path, time: :posix) do - {:ok, file_info} -> - file_info.mtime - - _ -> - nil - end - - info = %{ - references: [], - last_modified: last_modified, - beam_path: nil, - source: js_input_path, - js_path: js_output_path, - js_code: nil, - diagnostics: [], - type: :ffi - } - - Map.put(current_data, module, info) + data = %{ + ElixirScript.Core => %{ + references: [], + last_modified: nil, + beam_path: nil, + source: nil, + js_path: Path.join(output_path, "ElixirScript.Core.js"), + diagnostics: [], + js_code: nil, + type: :ffi + } + } + + Enum.reduce(modules, data, fn {module, info}, current_data -> + diagnostics = + Map.get(info, :diagnostics, []) + |> Enum.map(fn x -> + Map.put(x, :file, Map.get(info, :file)) + end) + + info = %{ + references: Map.get(info, :used_modules, []), + last_modified: Map.get(info, :last_modified, nil), + beam_path: Map.get(info, :beam_path), + source: Map.get(info, :file), + js_path: Path.join(output_path, "#{module}.js"), + diagnostics: diagnostics + } + + info = + case Keyword.get(compiled_js, module) do + [js_input_path, js_output_path] -> + last_modified = + case File.stat(js_input_path, time: :posix) do + {:ok, file_info} -> + file_info.mtime + + _ -> + nil + end + + info + |> Map.put(:last_modified, last_modified) + |> Map.put(:beam_path, nil) + |> Map.put(:source, js_input_path) + |> Map.put(:js_path, js_output_path) + |> Map.put(:js_code, nil) + |> Map.put(:type, :ffi) + + js_code -> + info + |> Map.put(:js_path, Path.join(output_path, "#{module}.js")) + |> Map.put(:js_code, js_code) + |> Map.put(:type, :module) + end + + Map.put(current_data, module, info) end) end end diff --git a/lib/elixir_script/manifest.ex b/lib/elixir_script/manifest.ex index 5ed1915f..a7974cb1 100644 --- a/lib/elixir_script/manifest.ex +++ b/lib/elixir_script/manifest.ex @@ -2,15 +2,22 @@ defmodule ElixirScript.Manifest do @moduledoc false @spec read_manifest(binary) :: nil - def read_manifest(_manifest) do - + def read_manifest(manifest_path) do + if File.exists?(manifest_path) do + manifest_path + |> File.read!() + |> :erlang.binary_to_term() + else + %{} + end end @spec write_manifest(binary, map) :: :ok def write_manifest(manifest_path, modules) do - data = Enum.reduce(modules, %{}, fn {module, info}, current_data -> - Map.put(current_data, module, Map.drop(info, [:js_code])) - end) + data = + Enum.reduce(modules, %{}, fn {module, info}, current_data -> + Map.put(current_data, module, Map.drop(info, [:js_code])) + end) data = :erlang.term_to_binary(data, [:compressed]) File.mkdir_p!(Path.dirname(manifest_path)) diff --git a/lib/elixir_script/passes/output.ex b/lib/elixir_script/passes/output.ex index 961b3d3b..89a6fdfd 100644 --- a/lib/elixir_script/passes/output.ex +++ b/lib/elixir_script/passes/output.ex @@ -92,10 +92,12 @@ defmodule ElixirScript.Output do defp output(code, module, path, js_modules) do output_dir = - if File.dir?(path) do - path - else - Path.dirname(path) + case Path.extname(path) do + "" -> + path + + _ -> + Path.dirname(path) end file_name = Path.join(output_dir, "Elixir.#{inspect(module)}.js") @@ -158,9 +160,9 @@ defmodule ElixirScript.Output do end File.cp(js_input_path, js_output_path) - acc ++ [{module, js_input_path, js_output_path}] + acc ++ [{module, [js_input_path, js_output_path]}] else - [] + acc end end) end diff --git a/lib/mix/tasks/compile.elixir_script.ex b/lib/mix/tasks/compile.elixir_script.ex index 36607e07..b529251e 100644 --- a/lib/mix/tasks/compile.elixir_script.ex +++ b/lib/mix/tasks/compile.elixir_script.ex @@ -41,39 +41,51 @@ defmodule Mix.Tasks.Compile.ElixirScript do def run(_) do {input, opts} = get_compiler_params() - try do - result = Compiler.compile(input, opts) - Manifest.write_manifest(manifest(), result) - - result - |> Enum.map(fn {_module, info} -> - info.diagnositcs - end) - |> List.flatten() - |> Enum.map(fn x -> - %Mix.Task.Compiler.Diagnostic{ - compiler_name: "elixir_script", - file: x.file, - message: x.message, - position: x.position, - severity: x.severity - } - end) - rescue - x in [ElixirScript.CompileError] -> - [ + diagnostics = + try do + result = Compiler.compile(input, opts) + Manifest.write_manifest(manifest(), result) + + result + |> Enum.map(fn {_module, info} -> + Map.get(info, :diagnostics, []) + end) + |> List.flatten() + |> Enum.map(fn x -> %Mix.Task.Compiler.Diagnostic{ compiler_name: "elixir_script", + file: x.file, message: x.message, - severity: x.severity, - position: nil, - file: nil + position: x.position, + severity: x.severity } - ] + end) + rescue + x in [ElixirScript.CompileError] -> + [ + %Mix.Task.Compiler.Diagnostic{ + compiler_name: "elixir_script", + message: x.message, + severity: x.severity, + position: nil, + file: nil + } + ] + end + + case diagnostics do + [] -> :ok + x -> x end end def clean do + manifest() + |> Manifest.read_manifest() + |> Enum.each(fn {_module, info} -> + File.rm(info.js_path) + end) + :ok end From cb976fa88298a19ccb5054d7be3637fba8999f24 Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Wed, 17 Jan 2018 19:29:44 -0600 Subject: [PATCH 386/418] Update travis --- .tool-versions | 2 +- .travis.yml | 12 +- lib/elixir_script/passes/translate/form.ex | 14 +- mix.exs | 7 +- test/passes/translate/form_test.exs | 153 +++++++++++++-------- 5 files changed, 111 insertions(+), 77 deletions(-) diff --git a/.tool-versions b/.tool-versions index a9580d64..e5a7616f 100644 --- a/.tool-versions +++ b/.tool-versions @@ -1,3 +1,3 @@ erlang 20.1 -elixir 1.6.0-rc.0-otp-20 +elixir 1.6.0-otp-20 nodejs 8.9.1 diff --git a/.travis.yml b/.travis.yml index 78d59677..aa389e22 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,19 +1,17 @@ sudo: false -language: erlang +language: elixir +elixir: + - 1.6.0-otp-20 otp_release: - - 20.0 + - 20.2 env: - TRAVIS_NODE_VERSION="8" install: - rm -rf ~/.nvm && git clone https://github.com/creationix/nvm.git ~/.nvm && (cd ~/.nvm && git checkout `git describe --abbrev=0 --tags`) && source ~/.nvm/nvm.sh && nvm install $TRAVIS_NODE_VERSION - npm install -g yarn - yarn -before_script: - - wget https://repo.hex.pm/builds/elixir/v1.6.0-rc.0-otp-20.zip - - unzip -d elixir v1.6.0-rc.0-otp-20.zip - - export PATH=$(pwd)/elixir/bin:${PATH} - - mix local.rebar --force - mix local.hex --force + - mix local.rebar --force - mix deps.get script: - make diff --git a/lib/elixir_script/passes/translate/form.ex b/lib/elixir_script/passes/translate/form.ex index c14a4361..129d1723 100644 --- a/lib/elixir_script/passes/translate/form.ex +++ b/lib/elixir_script/passes/translate/form.ex @@ -59,10 +59,16 @@ defmodule ElixirScript.Translate.Form do def compile(form, state) when is_atom(form) do ast = - if ElixirScript.Translate.Module.is_elixir_module(form) do - Remote.process_module_name(form, state) - else - Helpers.symbol(form) + cond do + ElixirScript.Translate.Module.is_elixir_module(form) and + ModuleState.get_module(state.pid, form) != nil -> + Remote.process_module_name(form, state) + + ElixirScript.Translate.Module.is_elixir_module(form) -> + J.object_expression([]) + + true -> + Helpers.symbol(form) end {ast, state} diff --git a/mix.exs b/mix.exs index 11c588f1..befc1d9c 100644 --- a/mix.exs +++ b/mix.exs @@ -5,8 +5,8 @@ defmodule ElixirScript.Mixfile do [ app: :elixir_script, version: "0.32.0-dev", - elixir: "~> 1.6-rc", - elixirc_paths: elixirc_paths(Mix.env), + elixir: "~> 1.6", + elixirc_paths: elixirc_paths(Mix.env()), deps: deps(), description: description(), package: package(), @@ -37,7 +37,7 @@ defmodule ElixirScript.Mixfile do end defp elixirc_paths(:test), do: ["lib", "test/support"] - defp elixirc_paths(_), do: ["lib"] + defp elixirc_paths(_), do: ["lib"] defp description do """ @@ -56,5 +56,4 @@ defmodule ElixirScript.Mixfile do build_tools: ["mix"] ] end - end diff --git a/test/passes/translate/form_test.exs b/test/passes/translate/form_test.exs index 6b8bae94..7626edee 100644 --- a/test/passes/translate/form_test.exs +++ b/test/passes/translate/form_test.exs @@ -5,7 +5,6 @@ defmodule ElixirScript.Translate.Forms.Test do alias ESTree.Tools.Builder, as: J use ExUnitProperties - setup_all do {:ok, pid} = ElixirScript.State.start_link(%{}) @@ -17,13 +16,15 @@ defmodule ElixirScript.Translate.Forms.Test do [state: state] end - property "integers, floats, binaries, and booleans translates to a literal JavaScript AST node", %{state: state} do - check all value <- StreamData.one_of([ - StreamData.integer(), - StreamData.boolean(), - StreamData.binary(), - StreamData.uniform_float() - ]) do + property "integers, floats, binaries, and booleans translates to a literal JavaScript AST node", + %{state: state} do + check all value <- + StreamData.one_of([ + StreamData.integer(), + StreamData.boolean(), + StreamData.binary(), + StreamData.uniform_float() + ]) do {js_ast, _} = Form.compile(value, state) assert js_ast == J.literal(value) end @@ -32,29 +33,33 @@ defmodule ElixirScript.Translate.Forms.Test do property "atom translates to Symbol.for call", %{state: state} do check all atom <- StreamData.unquoted_atom() do {js_ast, _} = Form.compile(atom, state) - assert js_ast == J.call_expression( - J.member_expression( - J.identifier("Symbol"), - J.identifier("for") - ), - [J.literal(atom)] - ) + + assert js_ast == + J.call_expression( + J.member_expression( + J.identifier("Symbol"), + J.identifier("for") + ), + [J.literal(atom)] + ) end end property "tuple translates to new Tuple object", %{state: state} do check all tuple <- StreamData.tuple({StreamData.integer(), StreamData.binary()}) do {js_ast, _} = Form.compile(tuple, state) - assert js_ast == J.new_expression( - J.member_expression( - J.member_expression( - J.identifier("ElixirScript"), - J.identifier("Core") - ), - J.identifier("Tuple") - ), - [J.literal(elem(tuple, 0)), J.literal(elem(tuple, 1))] - ) + + assert js_ast == + J.new_expression( + J.member_expression( + J.member_expression( + J.identifier("ElixirScript"), + J.identifier("Core") + ), + J.identifier("Tuple") + ), + [J.literal(elem(tuple, 0)), J.literal(elem(tuple, 1))] + ) end end @@ -72,16 +77,16 @@ defmodule ElixirScript.Translate.Forms.Test do end property "local function call translates to local JavaScript function call", %{state: state} do - check all func <- StreamData.filter(StreamData.unquoted_atom(), fn(x) -> not(x in [:fn]) end), + check all func <- StreamData.filter(StreamData.unquoted_atom(), fn x -> x not in [:fn] end), params <- StreamData.list_of(StreamData.binary()) do - ast = {func, [], params} - str_func = if func in ElixirScript.Translate.Identifier.js_reserved_words() do - "__#{to_string(func)}__" - else - to_string(func) - end + str_func = + if func in ElixirScript.Translate.Identifier.js_reserved_words() do + "__#{to_string(func)}__" + else + to_string(func) + end {js_ast, _} = Form.compile(ast, state) assert js_ast.type == "CallExpression" @@ -99,15 +104,15 @@ defmodule ElixirScript.Translate.Forms.Test do property "super function call translates to local JavaScript function call" do check all func <- StreamData.unquoted_atom(), params <- StreamData.list_of(StreamData.binary()) do - ast = {:super, [], [{:def, func}] ++ params} state = %{function: {func, nil}, vars: %{}} - str_func = if func in ElixirScript.Translate.Identifier.js_reserved_words() do - "__#{to_string(func)}__" - else - to_string(func) - end + str_func = + if func in ElixirScript.Translate.Identifier.js_reserved_words() do + "__#{to_string(func)}__" + else + to_string(func) + end {js_ast, _} = Form.compile(ast, state) assert js_ast.type == "CallExpression" @@ -125,10 +130,24 @@ defmodule ElixirScript.Translate.Forms.Test do test "module", %{state: state} do ast = IO + ElixirScript.State.put_module(state.pid, IO, %{}) + {js_ast, _} = Form.compile(ast, state) assert js_ast == %ESTree.Identifier{loc: nil, name: "$IO$", type: "Identifier"} end + test "unknown module", %{state: state} do + ast = Enum + + {js_ast, _} = Form.compile(ast, state) + + assert js_ast == %ESTree.ObjectExpression{ + loc: nil, + properties: [], + type: "ObjectExpression" + } + end + test "function returning an array" do ast = {:fn, [], [{:foo, [], [], [1, 2, 3]}]} state = %{function: {:something, nil}} @@ -137,37 +156,48 @@ defmodule ElixirScript.Translate.Forms.Test do return_statement = Enum.at(Enum.at(hd(js_ast.body.body).body.body, 1).consequent.body, 1) - assert return_statement.argument == J.array_expression([ - J.literal(1), - J.literal(2), - J.literal(3) - ]) + assert return_statement.argument == + J.array_expression([ + J.literal(1), + J.literal(2), + J.literal(3) + ]) end test "calling field on field" do - ast = {{:., [line: 16], - [{{:., [line: 16], [{:map, [line: 16], nil}, :token_count]}, [line: 16], - []}, :toLocaleString]}, [line: 16], []} + ast = + { + {:., [line: 16], [ + {{:., [line: 16], [{:map, [line: 16], nil}, :token_count]}, [line: 16], []}, + :toLocaleString + ]}, + [line: 16], + [] + } state = %{function: {:something, nil}, vars: %{}} {js_ast, _} = Form.compile(ast, state) - assert js_ast == Helpers.call( - ElixirScript.Translate.Forms.JS.call_property(), - [ - Helpers.call( - ElixirScript.Translate.Forms.JS.call_property(), - [J.identifier("map"), J.literal("token_count")] - ), - J.literal("toLocaleString") - ] - ) + assert js_ast == + Helpers.call(ElixirScript.Translate.Forms.JS.call_property(), [ + Helpers.call(ElixirScript.Translate.Forms.JS.call_property(), [ + J.identifier("map"), + J.literal("token_count") + ]), + J.literal("toLocaleString") + ]) end test "make sure counter used in guard", %{state: state} do - state = Map.merge(state, %{anonymous_fn: false, function: {:filter_names_in_guards, nil}, in_guard: true, - module: Integration, vars: %{"has__qmark__" => 0}}) + state = + Map.merge(state, %{ + anonymous_fn: false, + function: {:filter_names_in_guards, nil}, + in_guard: true, + module: Integration, + vars: %{"has__qmark__" => 0} + }) ast = {{:., [], [:erlang, :==]}, [line: 29], [{:has?, [line: 29], nil}, 5]} @@ -177,9 +207,10 @@ defmodule ElixirScript.Translate.Forms.Test do test "multi bind", %{state: state} do ast = - {:=, [line: 35], - [[{:|, [line: 35], [{:a, [line: 35], nil}, {:_, [line: 35], nil}]}], - {:=, [line: 35], [{:b, [line: 35], nil}, [1, 2, 3, 4, 5]]}]} + {:=, [line: 35], [ + [{:|, [line: 35], [{:a, [line: 35], nil}, {:_, [line: 35], nil}]}], + {:=, [line: 35], [{:b, [line: 35], nil}, [1, 2, 3, 4, 5]]} + ]} {js_ast, _} = Form.compile(ast, state) From a3d1a76096dd52e10ee4e8838bd6f143496f48cf Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Wed, 17 Jan 2018 19:33:20 -0600 Subject: [PATCH 387/418] Update elixir version in travis config --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index aa389e22..5dbed2d0 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,7 +1,7 @@ sudo: false language: elixir elixir: - - 1.6.0-otp-20 + - 1.6.0 otp_release: - 20.2 env: From eaf5b2a60bbf859b8401a0d6efe4a3c8de671c3d Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Wed, 17 Jan 2018 20:05:44 -0600 Subject: [PATCH 388/418] Some more bug fixes. Have to figure out module resolution issues still --- lib/elixir_script/passes/find_used_modules.ex | 65 +++++++++++++------ 1 file changed, 46 insertions(+), 19 deletions(-) diff --git a/lib/elixir_script/passes/find_used_modules.ex b/lib/elixir_script/passes/find_used_modules.ex index 4befed2e..0bd09fdc 100644 --- a/lib/elixir_script/passes/find_used_modules.ex +++ b/lib/elixir_script/passes/find_used_modules.ex @@ -15,16 +15,7 @@ defmodule ElixirScript.FindUsedModules do end) end - defp do_execute(module, pid) do - result = - case ModuleState.get_in_memory_module(pid, module) do - nil -> - ElixirScript.Beam.debug_info(module) - - beam -> - ElixirScript.Beam.debug_info(beam) - end - + defp do_execute(module, result, pid) do case result do {:ok, info} -> walk_module(module, info, pid) @@ -49,6 +40,21 @@ defmodule ElixirScript.FindUsedModules do end end + defp do_execute(module, pid) do + result = get_debug_info(module, pid) + do_execute(module, result, pid) + end + + defp get_debug_info(module, pid) do + case ModuleState.get_in_memory_module(pid, module) do + nil -> + ElixirScript.Beam.debug_info(module) + + beam -> + ElixirScript.Beam.debug_info(beam) + end + end + defp walk_module( module, %{attributes: [__foreign_info__: %{path: path, name: name, global: global}]} = info, @@ -159,10 +165,17 @@ defmodule ElixirScript.FindUsedModules do when is_atom(form) and form not in [BitString, Function, PID, Port, Reference, Any, Elixir] do if ElixirScript.Translate.Module.is_elixir_module(form) and !ElixirScript.Translate.Module.is_js_module(form, state) do - ModuleState.put_used_module(state.pid, state.module, form) - if ModuleState.get_module(state.pid, form) == nil do - do_execute(form, state.pid) + case get_debug_info(form, state.pid) do + {:ok, _} = result -> + ModuleState.put_used_module(state.pid, state.module, form) + do_execute(form, result, state.pid) + + result -> + do_execute(form, result, state.pid) + end + else + ModuleState.put_used_module(state.pid, state.module, form) end end end @@ -191,10 +204,17 @@ defmodule ElixirScript.FindUsedModules do defp walk({:%, _, [module, params]}, state) do if ElixirScript.Translate.Module.is_elixir_module(module) and !ElixirScript.Translate.Module.is_js_module(module, state) do - ModuleState.put_used_module(state.pid, state.module, module) - if ModuleState.get_module(state.pid, module) == nil do - do_execute(module, state.pid) + case get_debug_info(module, state.pid) do + {:ok, _} = result -> + ModuleState.put_used_module(state.pid, state.module, module) + do_execute(module, result, state.pid) + + result -> + do_execute(module, result, state.pid) + end + else + ModuleState.put_used_module(state.pid, state.module, module) end end @@ -331,10 +351,17 @@ defmodule ElixirScript.FindUsedModules do defp walk({:., _, [module, function]}, state) do if ElixirScript.Translate.Module.is_elixir_module(module) do - ModuleState.put_used_module(state.pid, state.module, module) - if ModuleState.get_module(state.pid, module) == nil do - do_execute(module, state.pid) + case get_debug_info(module, state.pid) do + {:ok, _} = result -> + ModuleState.put_used_module(state.pid, state.module, module) + do_execute(module, result, state.pid) + + result -> + do_execute(module, result, state.pid) + end + else + ModuleState.put_used_module(state.pid, state.module, module) end else walk(module, state) From e2348b2ae48dbc16060fc09ace279d79cc443677 Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Sat, 20 Jan 2018 10:10:38 -0600 Subject: [PATCH 389/418] Fix used module reference bugs --- lib/elixir_script/passes/find_used_modules.ex | 4 +- lib/elixir_script/passes/output.ex | 2 +- .../passes/translate/forms/remote.ex | 48 ++++++++++++------- .../passes/translate/identifier.ex | 10 ++-- lib/elixir_script/state.ex | 3 +- 5 files changed, 41 insertions(+), 26 deletions(-) diff --git a/lib/elixir_script/passes/find_used_modules.ex b/lib/elixir_script/passes/find_used_modules.ex index 0bd09fdc..e294c7c1 100644 --- a/lib/elixir_script/passes/find_used_modules.ex +++ b/lib/elixir_script/passes/find_used_modules.ex @@ -133,7 +133,9 @@ defmodule ElixirScript.FindUsedModules do Enum.each(clauses, &walk(&1, state)) end - defp walk({_, _args, _guards, body}, state) do + defp walk({_, args, guards, body}, state) do + walk(args, state) + walk(guards, state) walk_block(body, state) end diff --git a/lib/elixir_script/passes/output.ex b/lib/elixir_script/passes/output.ex index 89a6fdfd..2953ae0f 100644 --- a/lib/elixir_script/passes/output.ex +++ b/lib/elixir_script/passes/output.ex @@ -33,7 +33,7 @@ defmodule ElixirScript.Output do defp filter_used_modules(used_modules, pid) do used_modules |> Enum.filter(fn module -> - ModuleState.is_global_module(pid, module) == false + module in ModuleState.list_javascript_modules(pid) == false end) end diff --git a/lib/elixir_script/passes/translate/forms/remote.ex b/lib/elixir_script/passes/translate/forms/remote.ex index 97c3decd..6e945a49 100644 --- a/lib/elixir_script/passes/translate/forms/remote.ex +++ b/lib/elixir_script/passes/translate/forms/remote.ex @@ -33,7 +33,7 @@ defmodule ElixirScript.Translate.Forms.Remote do :orddict, :filelib, :net_adm, - :net_kernel, + :net_kernel ] @doc """ @@ -46,31 +46,32 @@ defmodule ElixirScript.Translate.Forms.Remote do def compile({:., _, [:erlang, :++]}, state) do ast = erlang_compat_function("erlang", "list_concatenation") - { ast, state } + {ast, state} end def compile({:., _, [:erlang, :--]}, state) do ast = erlang_compat_function("erlang", "list_substraction") - { ast, state } + {ast, state} end def compile({:., _, [:erlang, :"=<"]}, state) do ast = erlang_compat_function("erlang", "lessThanEqualTo") - { ast, state } + {ast, state} end def compile({:., _, [:erlang, :+]}, state) do ast = erlang_compat_function("erlang", "add") - { ast, state } + {ast, state} end def compile({:., _, [module, function]}, state) when module in @erlang_modules do - ast = J.member_expression( - Helpers.core_module(module), - J.identifier(function) - ) + ast = + J.member_expression( + Helpers.core_module(module), + J.identifier(function) + ) - { ast, state } + {ast, state} end def compile({:., _, [function_name]}, state) do @@ -80,30 +81,39 @@ defmodule ElixirScript.Translate.Forms.Remote do def compile({:., _, [module, function]}, state) do function_name = ElixirScript.Translate.Identifier.make_function_name(function) - ast = J.member_expression( - process_module_name(module, state), - function_name - ) + ast = + J.member_expression( + process_module_name(module, state), + function_name + ) {ast, state} end def process_module_name(module, state) when is_atom(module) do cond do + ElixirScript.Translate.Module.is_js_module(module, state) and + ModuleState.is_global_module(state.pid, module) -> + ElixirScript.Translate.Identifier.make_alias(Module.split(module) |> Enum.reverse()) + ElixirScript.Translate.Module.is_js_module(module, state) -> process_js_module_name(module, state) + module === Elixir -> module |> ElixirScript.Output.module_to_name() - |> J.identifier + |> J.identifier() + module === :ElixirScript -> module |> ElixirScript.Output.module_to_name() - |> J.identifier + |> J.identifier() + ElixirScript.Translate.Module.is_elixir_module(module) -> module |> ElixirScript.Output.module_to_name() - |> J.identifier + |> J.identifier() + true -> ElixirScript.Translate.Identifier.make_identifier(module) end @@ -117,12 +127,14 @@ defmodule ElixirScript.Translate.Forms.Remote do case ModuleState.get_js_module_name(state.pid, module) do name when is_binary(name) -> J.identifier(name) + name when is_atom(name) -> case to_string(name) do "Elixir." <> _ -> module |> ElixirScript.Output.module_to_name() - |> J.identifier + |> J.identifier() + x -> J.identifier(x) end diff --git a/lib/elixir_script/passes/translate/identifier.ex b/lib/elixir_script/passes/translate/identifier.ex index 092bd093..a04f35b8 100644 --- a/lib/elixir_script/passes/translate/identifier.ex +++ b/lib/elixir_script/passes/translate/identifier.ex @@ -38,7 +38,7 @@ defmodule ElixirScript.Translate.Identifier do def make_identifier(ast) do ast |> filter_name - |> J.identifier + |> J.identifier() end def filter_name(reserved_word) when reserved_word in @js_reserved_words do @@ -57,11 +57,11 @@ defmodule ElixirScript.Translate.Identifier do end end - defp make_alias([x]) do + def make_alias([x]) do make_identifier(x) end - defp make_alias([h|t]) do + def make_alias([h | t]) do J.member_expression(make_alias(t), make_identifier(h)) end @@ -69,10 +69,11 @@ defmodule ElixirScript.Translate.Identifier do case module_name do m when is_list(m) -> m + m when is_atom(m) -> Module.split(m) end - |> Enum.reverse + |> Enum.reverse() |> make_alias end @@ -84,5 +85,4 @@ defmodule ElixirScript.Translate.Identifier do def js_reserved_words() do @js_reserved_words end - end diff --git a/lib/elixir_script/state.ex b/lib/elixir_script/state.ex index 3a45f745..79bd6eda 100644 --- a/lib/elixir_script/state.ex +++ b/lib/elixir_script/state.ex @@ -115,7 +115,8 @@ defmodule ElixirScript.State do def is_global_module(pid, module) do Agent.get(pid, fn state -> - result = Enum.find(state.js_modules, fn {mod, _, _} -> mod == module end) + result = + Enum.find(state.js_modules, fn {mod, _name, path} -> mod == module and path == nil end) if result == nil, do: false, else: true end) From 288f19b67f33f62745f146200f8229996c12b5a5 Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Sun, 28 Jan 2018 17:52:24 -0600 Subject: [PATCH 390/418] Update changelog --- CHANGELOG.md | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9c619292..5fb3edde 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,12 +5,29 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/) and this project adheres to [Semantic Versioning](http://semver.org/). -## Unreleased +## [0.32.0] - Unreleased -## Changed +### Added + +* `ElixirScript.Test` for testing ElixirScript modules in JavaScript. ElixirScript.Test is for unit testing modules that interact with JavaScript in some way. For modules that are can be used in both Elixir and ElixirScript, ExUnit is still preferred. Tests that use ElixirScript.Test must be placed in a `test_elixir_script` folder in the root of your project. These tests are run using node.js. The API for ElixirScript.Test is meant to be as close to ExUnit as possible. + +### Changed + +* ElixirScript now requires Elixir 1.6. This is so that ElixirScript can use the new `Mix.Task.Compiler` behaviour. +* `mix clean` will now correctly clean up ElixirScript output. +* Compiler will now output a JavaScript file per Elixir module. +* Modules with a start function **must** be started directly. -* Compiler now returns a file per module instead of just one file -* Requires Elixir 1.6 + ```elixir + # Before ElixirScript 0.32.0: + import Elixir from './elixirscript.build.js' + Elixir.start(Elixir.Main, [1, 2, 3]) + + + # ElixirScript 0.32.0 and later: + import Main from './Elixir.Main.js' + Main.start(Symbol.for('normal'), [1, 2, 3]) + ``` ## [0.31.1] - 2017-09-27 From 3e04fcef4e396a9784be1741527a06b59659511c Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Sat, 10 Feb 2018 10:33:39 -0600 Subject: [PATCH 391/418] Prep for release --- CHANGELOG.md | 21 +- mix.exs | 2 +- priv/testrunner/vendor.build.js | 406 +------------------------------- 3 files changed, 13 insertions(+), 416 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5fb3edde..8b589479 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,7 +5,7 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/) and this project adheres to [Semantic Versioning](http://semver.org/). -## [0.32.0] - Unreleased +## [0.32.0] - 2018-02-10 ### Added @@ -23,7 +23,6 @@ and this project adheres to [Semantic Versioning](http://semver.org/). import Elixir from './elixirscript.build.js' Elixir.start(Elixir.Main, [1, 2, 3]) - # ElixirScript 0.32.0 and later: import Main from './Elixir.Main.js' Main.start(Symbol.for('normal'), [1, 2, 3]) @@ -45,15 +44,15 @@ and this project adheres to [Semantic Versioning](http://semver.org/). * [Fully implement `__info__` on modules](https://github.com/elixirscript/elixirscript/pull/378) * [Concurrent Compilation](https://github.com/elixirscript/elixirscript/issues/376) * [The following erlang functions have been implemented](https://github.com/elixirscript/elixirscript/issues/306): - * :erlang.nodes/0 - * :erlang.nodes/1 - * :math.log2/1 - * :binary.copy/1 - * :binary.copy/2 - * :binary.part/2 - * :binary.part/3 - * :binary.replace/3 - * :binary.replace/4 (some options still missing) +* :erlang.nodes/0 +* :erlang.nodes/1 +* :math.log2/1 +* :binary.copy/1 +* :binary.copy/2 +* :binary.part/2 +* :binary.part/3 +* :binary.replace/3 +* :binary.replace/4 (some options still missing) ### Fixed diff --git a/mix.exs b/mix.exs index befc1d9c..c4841a2c 100644 --- a/mix.exs +++ b/mix.exs @@ -4,7 +4,7 @@ defmodule ElixirScript.Mixfile do def project do [ app: :elixir_script, - version: "0.32.0-dev", + version: "0.32.0", elixir: "~> 1.6", elixirc_paths: elixirc_paths(Mix.env()), deps: deps(), diff --git a/priv/testrunner/vendor.build.js b/priv/testrunner/vendor.build.js index 6e808208..9d49e34d 100644 --- a/priv/testrunner/vendor.build.js +++ b/priv/testrunner/vendor.build.js @@ -1,404 +1,2 @@ -class Tuple { - constructor(...args) { - this.values = Object.freeze(args); - this.length = this.values.length; - } - - get(index) { - return this.values[index]; - } - - count() { - return this.values.length; - } - - [Symbol.iterator]() { - return this.values[Symbol.iterator](); - } - - toString() { - let i, - s = ''; - for (i = 0; i < this.values.length; i++) { - if (s !== '') { - s += ', '; - } - - const stringToAppend = this.values[i] ? this.values[i].toString() : ''; - - s += stringToAppend; - } - - return '{' + s + '}'; - } - - put_elem(index, elem) { - if (index === this.length) { - let new_values = this.values.concat([elem]); - return new Tuple(...new_values); - } - - let new_values = this.values.concat([]); - new_values.splice(index, 0, elem); - return new Tuple(...new_values); - } - - remove_elem(index) { - let new_values = this.values.concat([]); - new_values.splice(index, 1); - return new Tuple(...new_values); - } -} - -let process_counter = -1; - -class PID { - constructor() { - process_counter = process_counter + 1; - this.id = process_counter; - } - - toString() { - return 'PID#<0.' + this.id + '.0>'; - } -} - -let ref_counter = -1; - -class Reference { - constructor() { - ref_counter = ref_counter + 1; - this.id = ref_counter; - this.ref = Symbol(); - } - - toString() { - return 'Ref#<0.0.0.' + this.id + '>'; - } -} - -class BitString { - constructor(...args) { - this.value = Object.freeze(this.process(args)); - this.length = this.value.length; - this.bit_size = this.length * 8; - this.byte_size = this.length; - } - - get(index) { - return this.value[index]; - } - - count() { - return this.value.length; - } - - slice(start, end = null) { - let s = this.value.slice(start, end); - let ms = s.map(elem => BitString.integer(elem)); - return new BitString(...ms); - } - - [Symbol.iterator]() { - return this.value[Symbol.iterator](); - } - - toString() { - var i, - s = ''; - for (i = 0; i < this.count(); i++) { - if (s !== '') { - s += ', '; - } - s += this.get(i).toString(); - } - - return '<<' + s + '>>'; - } - - process(bitStringParts) { - let processed_values = []; - - var i; - for (i = 0; i < bitStringParts.length; i++) { - let processed_value = this['process_' + bitStringParts[i].type](bitStringParts[i]); - - for (let attr of bitStringParts[i].attributes) { - processed_value = this['process_' + attr](processed_value); - } - - processed_values = processed_values.concat(processed_value); - } - - return processed_values; - } - - process_integer(value) { - return value.value; - } - - process_float(value) { - if (value.size === 64) { - return BitString.float64ToBytes(value.value); - } else if (value.size === 32) { - return BitString.float32ToBytes(value.value); - } - - throw new Error('Invalid size for float'); - } - - process_bitstring(value) { - return value.value.value; - } - - process_binary(value) { - return BitString.toUTF8Array(value.value); - } - - process_utf8(value) { - return BitString.toUTF8Array(value.value); - } - - process_utf16(value) { - return BitString.toUTF16Array(value.value); - } - - process_utf32(value) { - return BitString.toUTF32Array(value.value); - } - - process_signed(value) { - return new Uint8Array([value])[0]; - } - - process_unsigned(value) { - return value; - } - - process_native(value) { - return value; - } - - process_big(value) { - return value; - } - - process_little(value) { - return value.reverse(); - } - - process_size(value) { - return value; - } - - process_unit(value) { - return value; - } - - static integer(value) { - return BitString.wrap(value, { type: 'integer', unit: 1, size: 8 }); - } - - static float(value) { - return BitString.wrap(value, { type: 'float', unit: 1, size: 64 }); - } - - static bitstring(value) { - return BitString.wrap(value, { - type: 'bitstring', - unit: 1, - size: value.bit_size - }); - } - - static bits(value) { - return BitString.bitstring(value); - } - - static binary(value) { - return BitString.wrap(value, { - type: 'binary', - unit: 8, - size: value.length - }); - } - - static bytes(value) { - return BitString.binary(value); - } - - static utf8(value) { - return BitString.wrap(value, { type: 'utf8', unit: 1, size: value.length }); - } - - static utf16(value) { - return BitString.wrap(value, { - type: 'utf16', - unit: 1, - size: value.length * 2 - }); - } - - static utf32(value) { - return BitString.wrap(value, { - type: 'utf32', - unit: 1, - size: value.length * 4 - }); - } - - static signed(value) { - return BitString.wrap(value, {}, 'signed'); - } - - static unsigned(value) { - return BitString.wrap(value, {}, 'unsigned'); - } - - static native(value) { - return BitString.wrap(value, {}, 'native'); - } - - static big(value) { - return BitString.wrap(value, {}, 'big'); - } - - static little(value) { - return BitString.wrap(value, {}, 'little'); - } - - static size(value, count) { - return BitString.wrap(value, { size: count }); - } - - static unit(value, count) { - return BitString.wrap(value, { unit: count }); - } - - static wrap(value, opt, new_attribute = null) { - let the_value = value; - - if (!(value instanceof Object)) { - the_value = { value: value, attributes: [] }; - } - - the_value = Object.assign(the_value, opt); - - if (new_attribute) { - the_value.attributes.push(new_attribute); - } - - return the_value; - } - - static toUTF8Array(str) { - var utf8 = []; - for (var i = 0; i < str.length; i++) { - var charcode = str.charCodeAt(i); - if (charcode < 0x80) { - utf8.push(charcode); - } else if (charcode < 0x800) { - utf8.push(0xc0 | charcode >> 6, 0x80 | charcode & 0x3f); - } else if (charcode < 0xd800 || charcode >= 0xe000) { - utf8.push(0xe0 | charcode >> 12, 0x80 | charcode >> 6 & 0x3f, 0x80 | charcode & 0x3f); - } else { - // surrogate pair - i++; - // UTF-16 encodes 0x10000-0x10FFFF by - // subtracting 0x10000 and splitting the - // 20 bits of 0x0-0xFFFFF into two halves - charcode = 0x10000 + ((charcode & 0x3ff) << 10 | str.charCodeAt(i) & 0x3ff); - utf8.push(0xf0 | charcode >> 18, 0x80 | charcode >> 12 & 0x3f, 0x80 | charcode >> 6 & 0x3f, 0x80 | charcode & 0x3f); - } - } - return utf8; - } - - static toUTF16Array(str) { - var utf16 = []; - for (var i = 0; i < str.length; i++) { - var codePoint = str.codePointAt(i); - - if (codePoint <= 255) { - utf16.push(0); - utf16.push(codePoint); - } else { - utf16.push(codePoint >> 8 & 0xff); - utf16.push(codePoint & 0xff); - } - } - return utf16; - } - - static toUTF32Array(str) { - var utf32 = []; - for (var i = 0; i < str.length; i++) { - var codePoint = str.codePointAt(i); - - if (codePoint <= 255) { - utf32.push(0); - utf32.push(0); - utf32.push(0); - utf32.push(codePoint); - } else { - utf32.push(0); - utf32.push(0); - utf32.push(codePoint >> 8 & 0xff); - utf32.push(codePoint & 0xff); - } - } - return utf32; - } - - //http://stackoverflow.com/questions/2003493/javascript-float-from-to-bits - static float32ToBytes(f) { - var bytes = []; - - var buf = new ArrayBuffer(4); - new Float32Array(buf)[0] = f; - - let intVersion = new Uint32Array(buf)[0]; - - bytes.push(intVersion >> 24 & 0xff); - bytes.push(intVersion >> 16 & 0xff); - bytes.push(intVersion >> 8 & 0xff); - bytes.push(intVersion & 0xff); - - return bytes; - } - - static float64ToBytes(f) { - var bytes = []; - - var buf = new ArrayBuffer(8); - new Float64Array(buf)[0] = f; - - var intVersion1 = new Uint32Array(buf)[0]; - var intVersion2 = new Uint32Array(buf)[1]; - - bytes.push(intVersion2 >> 24 & 0xff); - bytes.push(intVersion2 >> 16 & 0xff); - bytes.push(intVersion2 >> 8 & 0xff); - bytes.push(intVersion2 & 0xff); - - bytes.push(intVersion1 >> 24 & 0xff); - bytes.push(intVersion1 >> 16 & 0xff); - bytes.push(intVersion1 >> 8 & 0xff); - bytes.push(intVersion1 & 0xff); - - return bytes; - } -} - -var ErlangTypes = { - Tuple, - PID, - Reference, - BitString -}; - -var vendor = { - ErlangTypes -}; - -export default vendor; +class Tuple{constructor(...a){this.values=Object.freeze(a),this.length=this.values.length}get(a){return this.values[a]}count(){return this.values.length}[Symbol.iterator](){return this.values[Symbol.iterator]()}toString(){let a,b='';for(a=0;a'}}let ref_counter=-1;class Reference{constructor(){++ref_counter,this.id=ref_counter,this.ref=Symbol()}toString(){return'Ref#<0.0.0.'+this.id+'>'}}class BitString{constructor(...a){this.value=Object.freeze(this.process(a)),this.length=this.value.length,this.bit_size=8*this.length,this.byte_size=this.length}get(a){return this.value[a]}count(){return this.value.length}slice(a,b=null){let c=this.value.slice(a,b),d=c.map((a)=>BitString.integer(a));return new BitString(...d)}[Symbol.iterator](){return this.value[Symbol.iterator]()}toString(){var a,b='';for(a=0;a>'}process(a){let b=[];var c;for(c=0;cb?c.push(b):2048>b?c.push(192|b>>6,128|63&b):55296>b||57344<=b?c.push(224|b>>12,128|63&b>>6,128|63&b):(d++,b=65536+((1023&b)<<10|1023&a.charCodeAt(d)),c.push(240|b>>18,128|63&b>>12,128|63&b>>6,128|63&b));return c}static toUTF16Array(a){for(var b,c=[],d=0;d=b?(c.push(0),c.push(b)):(c.push(255&b>>8),c.push(255&b));return c}static toUTF32Array(a){for(var b,c=[],d=0;d=b?(c.push(0),c.push(0),c.push(0),c.push(b)):(c.push(0),c.push(0),c.push(255&b>>8),c.push(255&b));return c}//http://stackoverflow.com/questions/2003493/javascript-float-from-to-bits +static float32ToBytes(a){var b=[],c=new ArrayBuffer(4);new Float32Array(c)[0]=a;let d=new Uint32Array(c)[0];return b.push(255&d>>24),b.push(255&d>>16),b.push(255&d>>8),b.push(255&d),b}static float64ToBytes(a){var b=[],c=new ArrayBuffer(8);new Float64Array(c)[0]=a;var d=new Uint32Array(c)[0],e=new Uint32Array(c)[1];return b.push(255&e>>24),b.push(255&e>>16),b.push(255&e>>8),b.push(255&e),b.push(255&d>>24),b.push(255&d>>16),b.push(255&d>>8),b.push(255&d),b}}var ErlangTypes={Tuple,PID,Reference,BitString},vendor={ErlangTypes};export default vendor; From 25989dfbbaac327434071a39e0d322c20cb1b486 Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Sat, 17 Mar 2018 15:07:19 -0500 Subject: [PATCH 392/418] Fix bug with global js modules --- .../passes/translate/forms/remote.ex | 18 +++++++++++++++++- lib/elixir_script/state.ex | 9 +++++++++ 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/lib/elixir_script/passes/translate/forms/remote.ex b/lib/elixir_script/passes/translate/forms/remote.ex index 6e945a49..fda121fe 100644 --- a/lib/elixir_script/passes/translate/forms/remote.ex +++ b/lib/elixir_script/passes/translate/forms/remote.ex @@ -94,7 +94,7 @@ defmodule ElixirScript.Translate.Forms.Remote do cond do ElixirScript.Translate.Module.is_js_module(module, state) and ModuleState.is_global_module(state.pid, module) -> - ElixirScript.Translate.Identifier.make_alias(Module.split(module) |> Enum.reverse()) + process_global_js_module_name(module, state) ElixirScript.Translate.Module.is_js_module(module, state) -> process_js_module_name(module, state) @@ -123,6 +123,22 @@ defmodule ElixirScript.Translate.Forms.Remote do Form.compile!(module, state) end + defp process_global_js_module_name(module, state) do + case ModuleState.get_js_module_name(state.pid, module) do + name when is_binary(name) -> + J.identifier(name) + + name when is_atom(name) -> + case to_string(name) do + "Elixir." <> _ -> + ElixirScript.Translate.Identifier.make_alias(Module.split(name) |> Enum.reverse()) + + x -> + J.identifier(x) + end + end + end + defp process_js_module_name(module, state) do case ModuleState.get_js_module_name(state.pid, module) do name when is_binary(name) -> diff --git a/lib/elixir_script/state.ex b/lib/elixir_script/state.ex index 79bd6eda..37d0473f 100644 --- a/lib/elixir_script/state.ex +++ b/lib/elixir_script/state.ex @@ -122,6 +122,15 @@ defmodule ElixirScript.State do end) end + def get_global_module_name(pid, module) do + Agent.get(pid, fn state -> + result = + Enum.find(state.js_modules, fn {mod, _name, path} -> mod == module and path == nil end) + + if result == nil, do: nil, else: elem(result, 1) + end) + end + def remove_unused_functions(pid) do Agent.get(pid, fn state -> state.compiler_opts.remove_unused_functions From 95e3c30eb8457b7d100b5a1be9cf8c90a478f098 Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Sat, 17 Mar 2018 15:13:22 -0500 Subject: [PATCH 393/418] Update changelog --- CHANGELOG.md | 6 ++++++ mix.exs | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8b589479..89d3cd1e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/) and this project adheres to [Semantic Versioning](http://semver.org/). +## [0.32.1] - 2018-03-17 + +### Fixed + +* Global JavaScript modules not compiling correctly + ## [0.32.0] - 2018-02-10 ### Added diff --git a/mix.exs b/mix.exs index c4841a2c..29674176 100644 --- a/mix.exs +++ b/mix.exs @@ -4,7 +4,7 @@ defmodule ElixirScript.Mixfile do def project do [ app: :elixir_script, - version: "0.32.0", + version: "0.32.1", elixir: "~> 1.6", elixirc_paths: elixirc_paths(Mix.env()), deps: deps(), From 212aec2b0ea4d1ee03a61c9eb5eba299415105c3 Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Sun, 20 May 2018 13:34:13 -0500 Subject: [PATCH 394/418] Add CompilerInternals.md --- .tool-versions | 4 ++-- CompilerInternals.md | 51 ++++++++++++++++++++++++++++++++++++++++++++ mix.exs | 2 +- 3 files changed, 54 insertions(+), 3 deletions(-) create mode 100644 CompilerInternals.md diff --git a/.tool-versions b/.tool-versions index e5a7616f..fee73d5a 100644 --- a/.tool-versions +++ b/.tool-versions @@ -1,3 +1,3 @@ -erlang 20.1 -elixir 1.6.0-otp-20 +erlang 20.3 +elixir 1.6.5-otp-20 nodejs 8.9.1 diff --git a/CompilerInternals.md b/CompilerInternals.md new file mode 100644 index 00000000..c729ee09 --- /dev/null +++ b/CompilerInternals.md @@ -0,0 +1,51 @@ +# Compiler Internals + +This is a document describing how ElixirScript works. This is intended for those who would like to contribute to ElixirScript or those who are curious how it works. + +## Input + +[ElixrScript.Compiler](https://github.com/elixirscript/elixirscript/blob/master/lib/elixir_script/compiler.ex) is the entry point of the compiler. It takes in either a module or a list of modules. These are what are called the `entry modules` or the entry points into your application. These are the places ElixirScript will start it's compilation process. It will traverse what is used and only compile those things. This is the first step in the compilation process. Finding used modules to compile. + +## Finding Used Modules + +[ElixirScript.FindUsedModules](https://github.com/elixirscript/elixirscript/blob/master/lib/elixir_script/passes/find_used_modules.ex) looks at our entry modules and recursively crawls them to find all the modules used. It firsts exacts the Abstract Syntax Tree (AST) from the Beam file and then looks for references to modules that haven't been crawled yet. This information is stored in [ElixirScript.State](https://github.com/elixirscript/elixirscript/blob/master/lib/elixir_script/state.ex) + +## AST Extraction from Beam Files + +ElixirScript requires at Erlang 20+ and Elixir 1.6+. The reason why is that in Erlang 20 there is a new feature that allows for debug information to be stored in beam files. Any of the beam languages can use this. Elixir uses it by storing the AST for the module in there. This is a special version of the AST where all of the macros are expanded. This means ElixirScript does not have to worry about macro expansion itself. This AST is what ElixirScript works with. + +The code for this is in the [ElixirScript.Beam](https://github.com/elixirscript/elixirscript/blob/master/lib/elixir_script/beam.ex) module. + +`ElixirScript.debug_info/1` takes in a module name and returns the AST for that module. For a normal module, `{:ok, map}` are returned. If a protocol is given, `{:ok, atom, map, list}` is returned. The `atom` is the name of the protocol, The `map` is the protocol's AST and the `list` is the list of all of the implementation modules. + +This module handles the `String` and `Agent` modules a little bit differenly. Because of how Elixir compiles the unicode library, ElixirScript has to be careful not to compile the entire unicode library in JavaScript. So here, `debug_info` will get the AST from `String`, but replace some functions with the AST from `ElixirScript.String`. This ensures ElixirScript uses versions of functions in the standard lib that won't bring in the unicode module. The ame thing happens for `Agent` for different reasons. `Agent` is the only OTP module ElixirScript supports. ElixirScript hacks together a version of `Agent` that stores state in a way that allows ElixirScript users to use `Agent` just like they would with Elixir. + +## Finding Used Functions + +[ElixirScript.FindUsedFunctions](https://github.com/elixirscript/elixirscript/blob/master/lib/elixir_script/passes/find_used_functions.ex) is our second process in shrinking our compilation suface. In this process, we crawl through the modules we have found for compilation and see which functions are actually being called. This information is also stored in [ElixirScript.State](https://github.com/elixirscript/elixirscript/blob/master/lib/elixir_script/state.ex) for each module. + +**Note**: Because of the way protocols work, it is impossible to know what is used and what isn't. So for protocols and their implementations, we have to take in everything. + +Now we have what we need to compile to the JavaScript AST. + +## JavaScript AST (ESTree) + +Before going further, here is a brief intro into the JavaScript AST we use. The [ESTree spec](https://github.com/estree/estree) is a specification based on SpiderMonkey's JavaScript AST. This is used by several tools in the JavaScript ecosystem. There are many other versions of JavaScript ASTs, but the reason ElixirScript uses this one is because there are popular tools in the JavaScript ecosystem that understand it. ElixirScript uses the [ESTree](https://github.com/elixirscript/elixir-estree) Hex package. This package has structs that represent ESTree Nodes. It can also turn those into JavaScript code. + +## Translation + +[ElixirScript.Translate](https://github.com/elixirscript/elixirscript/blob/master/lib/elixir_script/passes/translate.ex) starts off the translation process. All this module does though is call [ElixirScript.Translate.Module](https://github.com/elixirscript/elixirscript/blob/master/lib/elixir_script/passes/translate/module.ex) on each of our modules. Here is where we take in the module info for each module and start translating to JavaScript AST. We compile the function definitions into JavaScript. Here is where we process the information gained from `ElixirScript.FindUsedFunctions` to remove any unused functions. In Elixir, function names are made up of the name and the arity. In JavaScript, that is not the case. ElixirScript combines function arities here into one definition. From here, ElixirScript compiles each function and places the translated AST back into `ElixirScript.State`. + +Functions comprise of clauses. Clauses have guards and blocks. Blocks being the blocks of code that make up the implementation. + +[ElixirScript.Translate.Function](https://github.com/elixirscript/elixirscript/blob/master/lib/elixir_script/passes/translate/function.ex) handles function translation. `ElixirScript.Translate.Function.compile_block\2` handles compilation of blocks. for each item in the block, `ElixirScript.Translate.Form.compile\2` is called. This is what is responsible for a bulk of the translation. + +Another aside to talk about function translation. Elixir supports tail call recursion. JavaScript does not. To allow our ElixirScript-translated functions to do so, we use a technique called `trampolining`. ElixirScript implementation still has some bugs, but it works for the most part. + +## Pattern Matching Translation + +Patterns are processed using [ElixirScript.Translate.Forms.Pattern](https://github.com/elixirscript/elixirscript/blob/master/lib/elixir_script/passes/translate/forms/pattern.ex). It takes all the forms of patterns and compiles them into JavaScript AST. The AST represents calls to the [Tailored](https://github.com/elixirscript/tailored) JavaScript library. This library is responsible for pattern matching at run time. + +## Output + +[ElixirScript.Output](https://github.com/elixirscript/elixirscript/blob/master/lib/elixir_script/passes/output.ex) is the last step in compilation. This modules is responsible for creating JavaScript modules and writing them to the file system. Each Elixir module is translated into a JavaScript module. diff --git a/mix.exs b/mix.exs index 29674176..067dac57 100644 --- a/mix.exs +++ b/mix.exs @@ -14,7 +14,7 @@ defmodule ElixirScript.Mixfile do test_coverage: [tool: ExCoveralls], docs: [ main: "ElixirScript", - extras: ["JavaScriptInterop.md"] + extras: ["JavaScriptInterop.md", "CompilerInternals.md"] ] ] end From 12fcc1bed6c30185c66899c0bacd25b04cfbcc22 Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Sun, 20 May 2018 13:36:32 -0500 Subject: [PATCH 395/418] Update README.md --- README.md | 30 ++++++++++++------------------ 1 file changed, 12 insertions(+), 18 deletions(-) diff --git a/README.md b/README.md index e48ed370..93e6bd41 100644 --- a/README.md +++ b/README.md @@ -1,21 +1,20 @@ -## ElixirScript [![Documentation](https://img.shields.io/badge/docs-hexpm-blue.svg)](http://hexdocs.pm/elixir_script/) [![Build](https://travis-ci.org/elixirscript/elixirscript.svg?branch=master)](https://travis-ci.org/elixirscript/elixirscript) [![Deps Status](https://beta.hexfaktor.org/badge/all/github/bryanjos/elixirscript.svg)](https://beta.hexfaktor.org/github/bryanjos/elixirscript) [![Join the chat at https://gitter.im/elixirscript/elixirscript](https://badges.gitter.im/elixirscript/elixirscript.svg)](https://gitter.im/elixirscript/elixirscript?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) +## ElixirScript [![Documentation](https://img.shields.io/badge/docs-hexpm-blue.svg)](http://hexdocs.pm/elixir_script/) [![Build](https://travis-ci.org/elixirscript/elixirscript.svg?branch=master)](https://travis-ci.org/elixirscript/elixirscript) The goal is to convert a subset (or full set) of Elixir code to JavaScript, providing the ability to write JavaScript in Elixir. This is done by taking the Elixir AST and converting it into JavaScript AST and then to JavaScript code. This is done using the [Elixir-ESTree](https://github.com/elixirscript/elixir-estree) library. [Documentation for current release](http://hexdocs.pm/elixir_script/) -Requirements -=========== +# Requirements + * Erlang 20 or greater -* Elixir 1.5 or greater (must be compiled with Erlang 20 or greater) +* Elixir 1.6 or greater (must be compiled with Erlang 20 or greater) * Node 8.2.1 or greater (only for development) -Usage -======== +# Usage Add dependency to your deps in mix.exs: -``` elixir +```elixir {:elixir_script, "~> x.x"} ``` @@ -42,18 +41,17 @@ Also add `elixir_script` configuration Run `mix compile` - -Examples -========== +# Examples ### Application + [ElixirScript Todo Example](https://github.com/elixirscript/todo-elixirscript) ### Library + [ElixirScript React](https://github.com/elixirscript/elixirscript_react) -Development -=========== +# Development ```bash # Clone the repo @@ -69,14 +67,10 @@ make make test ``` -Communication -======== - -[gitter room](https://gitter.im/elixirscript/elixirscript) +# Communication [#elixirscript](https://elixir-lang.slack.com/messages/elixirscript/) on the elixir-lang Slack -Contributing -======== +# Contributing Please check the [CONTRIBUTING.md](CONTRIBUTING.md) From 16ded7503f96fed269e2aecf0c355dda561c2306 Mon Sep 17 00:00:00 2001 From: Harlan T Wood Date: Sat, 30 Jun 2018 17:38:26 -1000 Subject: [PATCH 396/418] Fix broken link --- lib/elixir_script.ex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/elixir_script.ex b/lib/elixir_script.ex index 9bd48428..b5cd9a03 100644 --- a/lib/elixir_script.ex +++ b/lib/elixir_script.ex @@ -60,7 +60,7 @@ defmodule ElixirScript do ### JavaScript Interop - Check out the [JavaScript Interoperability](JavascriptInterop.html) documentation + Check out the [JavaScript Interoperability](javascriptinterop.html) documentation ### Dependencies From 770c8346af12baf5633dc18d4b31438d7a24e6c4 Mon Sep 17 00:00:00 2001 From: Harlan T Wood Date: Sat, 30 Jun 2018 23:34:08 -1000 Subject: [PATCH 397/418] Fix sample code indentation --- lib/elixir_script.ex | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/lib/elixir_script.ex b/lib/elixir_script.ex index 9bd48428..c605df22 100644 --- a/lib/elixir_script.ex +++ b/lib/elixir_script.ex @@ -17,21 +17,21 @@ defmodule ElixirScript do ``` elixir def project do - [ - app: :my_app, - version: "0.1.0", - elixir: "~> 1.0", - deps: deps, - # Add elixir_script as a compilter - compilers: Mix.compilers ++ [:elixir_script], - # Our elixir_script configuration - elixir_script: [ - # Entry module. Can also be a list of modules - input: MyEntryModule, - # Output path. Either a path to a js file or a directory - output: "priv/elixir_script/build" - ] - ] + [ + app: :my_app, + version: "0.1.0", + elixir: "~> 1.0", + deps: deps, + # Add elixir_script as a compilter + compilers: Mix.compilers() ++ [:elixir_script], + # Our elixir_script configuration + elixir_script: [ + # Entry module. Can also be a list of modules + input: MyEntryModule, + # Output path. Either a path to a js file or a directory + output: "priv/elixir_script/build" + ] + ] end ``` From aaaff732a0721f4f4a15f4ed1608a7e87f7cfe73 Mon Sep 17 00:00:00 2001 From: Harlan T Wood Date: Sun, 1 Jul 2018 00:15:28 -1000 Subject: [PATCH 398/418] Add link to "starter kit" --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index 93e6bd41..6d464386 100644 --- a/README.md +++ b/README.md @@ -51,6 +51,10 @@ Run `mix compile` [ElixirScript React](https://github.com/elixirscript/elixirscript_react) +### Starter kit + +[Elixirscript Starter Kit](https://github.com/harlantwood/elixirscript-starter-kit) + # Development ```bash From 196ebe0b6349ae5ea8979caefc93e8c7b6015ea3 Mon Sep 17 00:00:00 2001 From: Harlan T Wood Date: Sun, 1 Jul 2018 00:28:51 -1000 Subject: [PATCH 399/418] Fix typo --- lib/elixir_script/ffi.ex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/elixir_script/ffi.ex b/lib/elixir_script/ffi.ex index 7fb701ef..71249fe0 100644 --- a/lib/elixir_script/ffi.ex +++ b/lib/elixir_script/ffi.ex @@ -2,7 +2,7 @@ defmodule ElixirScript.FFI do @moduledoc """ The Foreign Function Interface (FFI) for interacting with JavaScript - To define a foreign module, make a new module and add `use ElixirScript.FFI`. to it + To define a foreign module, make a new module and add `use ElixirScript.FFI` to it. To define external functions, use the `defexternal` macro. Here is an example of a foreign module for a JSON module From d590871ede7407f50782a4f265fa62ecbf3fd861 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" Date: Thu, 21 Mar 2019 14:34:19 +0000 Subject: [PATCH 400/418] Bump poison from 3.1.0 to 4.0.1 Bumps [poison](https://github.com/devinus/poison) from 3.1.0 to 4.0.1. - [Release notes](https://github.com/devinus/poison/releases) - [Commits](https://github.com/devinus/poison/compare/3.1.0...4.0.1) Signed-off-by: dependabot[bot] --- mix.exs | 2 +- mix.lock | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/mix.exs b/mix.exs index 067dac57..61afeaa1 100644 --- a/mix.exs +++ b/mix.exs @@ -32,7 +32,7 @@ defmodule ElixirScript.Mixfile do {:excoveralls, "~> 0.7", only: :test}, {:credo, "~> 0.8", only: [:dev, :test]}, {:stream_data, "~> 0.3", only: :test}, - {:poison, "~> 3.1", only: :test} + {:poison, "~> 4.0", only: :test} ] end diff --git a/mix.lock b/mix.lock index 77645618..2c7118e7 100644 --- a/mix.lock +++ b/mix.lock @@ -11,7 +11,7 @@ "jsx": {:hex, :jsx, "2.8.3", "a05252d381885240744d955fbe3cf810504eb2567164824e19303ea59eef62cf", [:mix, :rebar3], [], "hexpm"}, "metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [:rebar3], [], "hexpm"}, "mimerl": {:hex, :mimerl, "1.0.2", "993f9b0e084083405ed8252b99460c4f0563e41729ab42d9074fd5e52439be88", [:rebar3], [], "hexpm"}, - "poison": {:hex, :poison, "3.1.0", "d9eb636610e096f86f25d9a46f35a9facac35609a7591b3be3326e99a0484665", [:mix], [], "hexpm"}, + "poison": {:hex, :poison, "4.0.1", "bcb755a16fac91cad79bfe9fc3585bb07b9331e50cfe3420a24bcc2d735709ae", [:mix], [], "hexpm"}, "ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.1", "28a4d65b7f59893bc2c7de786dec1e1555bd742d336043fe644ae956c3497fbe", [:make, :rebar], [], "hexpm"}, "stream_data": {:hex, :stream_data, "0.3.0", "cbfc8e3212f64683615657ea27804126a42ded634adfdfee258bf087ee605d46", [:mix], [], "hexpm"}, "unicode_util_compat": {:hex, :unicode_util_compat, "0.3.1", "a1f612a7b512638634a603c8f401892afbf99b8ce93a45041f8aaca99cadb85e", [:rebar3], [], "hexpm"}} From 8669ff5d15b6c71332bab942f385f975cb6b17ec Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" Date: Mon, 25 Mar 2019 07:21:39 +0000 Subject: [PATCH 401/418] Bump credo from 0.8.8 to 1.0.4 Bumps [credo](https://github.com/rrrene/credo) from 0.8.8 to 1.0.4. - [Release notes](https://github.com/rrrene/credo/releases) - [Changelog](https://github.com/rrrene/credo/blob/master/CHANGELOG.md) - [Commits](https://github.com/rrrene/credo/compare/v0.8.8...v1.0.4) Signed-off-by: dependabot[bot] --- mix.exs | 2 +- mix.lock | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/mix.exs b/mix.exs index 067dac57..93a540cd 100644 --- a/mix.exs +++ b/mix.exs @@ -30,7 +30,7 @@ defmodule ElixirScript.Mixfile do {:estree, "~> 2.6"}, {:ex_doc, "~> 0.16", only: :dev}, {:excoveralls, "~> 0.7", only: :test}, - {:credo, "~> 0.8", only: [:dev, :test]}, + {:credo, "~> 1.0", only: [:dev, :test]}, {:stream_data, "~> 0.3", only: :test}, {:poison, "~> 3.1", only: :test} ] diff --git a/mix.lock b/mix.lock index 77645618..86e15fc8 100644 --- a/mix.lock +++ b/mix.lock @@ -1,6 +1,6 @@ %{"bunt": {:hex, :bunt, "0.2.0", "951c6e801e8b1d2cbe58ebbd3e616a869061ddadcc4863d0a2182541acae9a38", [:mix], [], "hexpm"}, "certifi": {:hex, :certifi, "2.0.0", "a0c0e475107135f76b8c1d5bc7efb33cd3815cb3cf3dea7aefdd174dabead064", [:rebar3], [], "hexpm"}, - "credo": {:hex, :credo, "0.8.8", "990e7844a8d06ebacd88744a55853a83b74270b8a8461c55a4d0334b8e1736c9", [:mix], [{:bunt, "~> 0.2.0", [hex: :bunt, repo: "hexpm", optional: false]}], "hexpm"}, + "credo": {:hex, :credo, "1.0.4", "d2214d4cc88c07f54004ffd5a2a27408208841be5eca9f5a72ce9e8e835f7ede", [:mix], [{:bunt, "~> 0.2.0", [hex: :bunt, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm"}, "earmark": {:hex, :earmark, "1.2.3", "206eb2e2ac1a794aa5256f3982de7a76bf4579ff91cb28d0e17ea2c9491e46a4", [:mix], [], "hexpm"}, "estree": {:hex, :estree, "2.6.1", "0a17cc0e9e35315dc4fcd79d30a746b1f3e9ed654be6084ce882ab491165ae22", [:mix], [], "hexpm"}, "ex_doc": {:hex, :ex_doc, "0.18.1", "37c69d2ef62f24928c1f4fdc7c724ea04aecfdf500c4329185f8e3649c915baf", [:mix], [{:earmark, "~> 1.1", [hex: :earmark, repo: "hexpm", optional: false]}], "hexpm"}, @@ -8,6 +8,7 @@ "exjsx": {:hex, :exjsx, "4.0.0", "60548841e0212df401e38e63c0078ec57b33e7ea49b032c796ccad8cde794b5c", [:mix], [{:jsx, "~> 2.8.0", [hex: :jsx, repo: "hexpm", optional: false]}], "hexpm"}, "hackney": {:hex, :hackney, "1.10.1", "c38d0ca52ea80254936a32c45bb7eb414e7a96a521b4ce76d00a69753b157f21", [:rebar3], [{:certifi, "2.0.0", [hex: :certifi, repo: "hexpm", optional: false]}, {:idna, "5.1.0", [hex: :idna, repo: "hexpm", optional: false]}, {:metrics, "1.0.1", [hex: :metrics, repo: "hexpm", optional: false]}, {:mimerl, "1.0.2", [hex: :mimerl, repo: "hexpm", optional: false]}, {:ssl_verify_fun, "1.1.1", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}], "hexpm"}, "idna": {:hex, :idna, "5.1.0", "d72b4effeb324ad5da3cab1767cb16b17939004e789d8c0ad5b70f3cea20c89a", [:rebar3], [{:unicode_util_compat, "0.3.1", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm"}, + "jason": {:hex, :jason, "1.1.2", "b03dedea67a99223a2eaf9f1264ce37154564de899fd3d8b9a21b1a6fd64afe7", [:mix], [{:decimal, "~> 1.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm"}, "jsx": {:hex, :jsx, "2.8.3", "a05252d381885240744d955fbe3cf810504eb2567164824e19303ea59eef62cf", [:mix, :rebar3], [], "hexpm"}, "metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [:rebar3], [], "hexpm"}, "mimerl": {:hex, :mimerl, "1.0.2", "993f9b0e084083405ed8252b99460c4f0563e41729ab42d9074fd5e52439be88", [:rebar3], [], "hexpm"}, From 3c7e3c03b6d24e40989a1c41f20e6b9c1be2edac Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" Date: Mon, 22 Apr 2019 07:09:48 +0000 Subject: [PATCH 402/418] Bump credo from 1.0.4 to 1.0.5 Bumps [credo](https://github.com/rrrene/credo) from 1.0.4 to 1.0.5. - [Release notes](https://github.com/rrrene/credo/releases) - [Changelog](https://github.com/rrrene/credo/blob/master/CHANGELOG.md) - [Commits](https://github.com/rrrene/credo/compare/v1.0.4...v1.0.5) Signed-off-by: dependabot[bot] --- mix.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mix.lock b/mix.lock index 40ed581c..0d0beb4e 100644 --- a/mix.lock +++ b/mix.lock @@ -1,6 +1,6 @@ %{"bunt": {:hex, :bunt, "0.2.0", "951c6e801e8b1d2cbe58ebbd3e616a869061ddadcc4863d0a2182541acae9a38", [:mix], [], "hexpm"}, "certifi": {:hex, :certifi, "2.0.0", "a0c0e475107135f76b8c1d5bc7efb33cd3815cb3cf3dea7aefdd174dabead064", [:rebar3], [], "hexpm"}, - "credo": {:hex, :credo, "1.0.4", "d2214d4cc88c07f54004ffd5a2a27408208841be5eca9f5a72ce9e8e835f7ede", [:mix], [{:bunt, "~> 0.2.0", [hex: :bunt, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm"}, + "credo": {:hex, :credo, "1.0.5", "fdea745579f8845315fe6a3b43e2f9f8866839cfbc8562bb72778e9fdaa94214", [:mix], [{:bunt, "~> 0.2.0", [hex: :bunt, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm"}, "earmark": {:hex, :earmark, "1.2.3", "206eb2e2ac1a794aa5256f3982de7a76bf4579ff91cb28d0e17ea2c9491e46a4", [:mix], [], "hexpm"}, "estree": {:hex, :estree, "2.6.1", "0a17cc0e9e35315dc4fcd79d30a746b1f3e9ed654be6084ce882ab491165ae22", [:mix], [], "hexpm"}, "ex_doc": {:hex, :ex_doc, "0.18.1", "37c69d2ef62f24928c1f4fdc7c724ea04aecfdf500c4329185f8e3649c915baf", [:mix], [{:earmark, "~> 1.1", [hex: :earmark, repo: "hexpm", optional: false]}], "hexpm"}, From e750be1b1f264a9ded31124b84f4fd612fcc41e4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" Date: Mon, 22 Apr 2019 13:27:09 +0000 Subject: [PATCH 403/418] Bump excoveralls from 0.7.4 to 0.10.6 Bumps [excoveralls](https://github.com/parroty/excoveralls) from 0.7.4 to 0.10.6. - [Release notes](https://github.com/parroty/excoveralls/releases) - [Changelog](https://github.com/parroty/excoveralls/blob/master/CHANGELOG.md) - [Commits](https://github.com/parroty/excoveralls/compare/v0.7.4...v0.10.6) Signed-off-by: dependabot[bot] --- mix.lock | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/mix.lock b/mix.lock index 0d0beb4e..78d35758 100644 --- a/mix.lock +++ b/mix.lock @@ -1,18 +1,19 @@ %{"bunt": {:hex, :bunt, "0.2.0", "951c6e801e8b1d2cbe58ebbd3e616a869061ddadcc4863d0a2182541acae9a38", [:mix], [], "hexpm"}, - "certifi": {:hex, :certifi, "2.0.0", "a0c0e475107135f76b8c1d5bc7efb33cd3815cb3cf3dea7aefdd174dabead064", [:rebar3], [], "hexpm"}, + "certifi": {:hex, :certifi, "2.5.1", "867ce347f7c7d78563450a18a6a28a8090331e77fa02380b4a21962a65d36ee5", [:rebar3], [{:parse_trans, "~>3.3", [hex: :parse_trans, repo: "hexpm", optional: false]}], "hexpm"}, "credo": {:hex, :credo, "1.0.5", "fdea745579f8845315fe6a3b43e2f9f8866839cfbc8562bb72778e9fdaa94214", [:mix], [{:bunt, "~> 0.2.0", [hex: :bunt, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm"}, "earmark": {:hex, :earmark, "1.2.3", "206eb2e2ac1a794aa5256f3982de7a76bf4579ff91cb28d0e17ea2c9491e46a4", [:mix], [], "hexpm"}, "estree": {:hex, :estree, "2.6.1", "0a17cc0e9e35315dc4fcd79d30a746b1f3e9ed654be6084ce882ab491165ae22", [:mix], [], "hexpm"}, "ex_doc": {:hex, :ex_doc, "0.18.1", "37c69d2ef62f24928c1f4fdc7c724ea04aecfdf500c4329185f8e3649c915baf", [:mix], [{:earmark, "~> 1.1", [hex: :earmark, repo: "hexpm", optional: false]}], "hexpm"}, - "excoveralls": {:hex, :excoveralls, "0.7.4", "3d84b2f15a0e593159f74b19f83794b464b34817183d27965bdc6c462de014f9", [:mix], [{:exjsx, ">= 3.0.0", [hex: :exjsx, repo: "hexpm", optional: false]}, {:hackney, ">= 0.12.0", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm"}, + "excoveralls": {:hex, :excoveralls, "0.10.6", "e2b9718c9d8e3ef90bc22278c3f76c850a9f9116faf4ebe9678063310742edc2", [:mix], [{:hackney, "~> 1.13", [hex: :hackney, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm"}, "exjsx": {:hex, :exjsx, "4.0.0", "60548841e0212df401e38e63c0078ec57b33e7ea49b032c796ccad8cde794b5c", [:mix], [{:jsx, "~> 2.8.0", [hex: :jsx, repo: "hexpm", optional: false]}], "hexpm"}, - "hackney": {:hex, :hackney, "1.10.1", "c38d0ca52ea80254936a32c45bb7eb414e7a96a521b4ce76d00a69753b157f21", [:rebar3], [{:certifi, "2.0.0", [hex: :certifi, repo: "hexpm", optional: false]}, {:idna, "5.1.0", [hex: :idna, repo: "hexpm", optional: false]}, {:metrics, "1.0.1", [hex: :metrics, repo: "hexpm", optional: false]}, {:mimerl, "1.0.2", [hex: :mimerl, repo: "hexpm", optional: false]}, {:ssl_verify_fun, "1.1.1", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}], "hexpm"}, - "idna": {:hex, :idna, "5.1.0", "d72b4effeb324ad5da3cab1767cb16b17939004e789d8c0ad5b70f3cea20c89a", [:rebar3], [{:unicode_util_compat, "0.3.1", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm"}, + "hackney": {:hex, :hackney, "1.15.1", "9f8f471c844b8ce395f7b6d8398139e26ddca9ebc171a8b91342ee15a19963f4", [:rebar3], [{:certifi, "2.5.1", [hex: :certifi, repo: "hexpm", optional: false]}, {:idna, "6.0.0", [hex: :idna, repo: "hexpm", optional: false]}, {:metrics, "1.0.1", [hex: :metrics, repo: "hexpm", optional: false]}, {:mimerl, "~>1.1", [hex: :mimerl, repo: "hexpm", optional: false]}, {:ssl_verify_fun, "1.1.4", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}], "hexpm"}, + "idna": {:hex, :idna, "6.0.0", "689c46cbcdf3524c44d5f3dde8001f364cd7608a99556d8fbd8239a5798d4c10", [:rebar3], [{:unicode_util_compat, "0.4.1", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm"}, "jason": {:hex, :jason, "1.1.2", "b03dedea67a99223a2eaf9f1264ce37154564de899fd3d8b9a21b1a6fd64afe7", [:mix], [{:decimal, "~> 1.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm"}, "jsx": {:hex, :jsx, "2.8.3", "a05252d381885240744d955fbe3cf810504eb2567164824e19303ea59eef62cf", [:mix, :rebar3], [], "hexpm"}, "metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [:rebar3], [], "hexpm"}, - "mimerl": {:hex, :mimerl, "1.0.2", "993f9b0e084083405ed8252b99460c4f0563e41729ab42d9074fd5e52439be88", [:rebar3], [], "hexpm"}, + "mimerl": {:hex, :mimerl, "1.2.0", "67e2d3f571088d5cfd3e550c383094b47159f3eee8ffa08e64106cdf5e981be3", [:rebar3], [], "hexpm"}, + "parse_trans": {:hex, :parse_trans, "3.3.0", "09765507a3c7590a784615cfd421d101aec25098d50b89d7aa1d66646bc571c1", [:rebar3], [], "hexpm"}, "poison": {:hex, :poison, "4.0.1", "bcb755a16fac91cad79bfe9fc3585bb07b9331e50cfe3420a24bcc2d735709ae", [:mix], [], "hexpm"}, - "ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.1", "28a4d65b7f59893bc2c7de786dec1e1555bd742d336043fe644ae956c3497fbe", [:make, :rebar], [], "hexpm"}, + "ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.4", "f0eafff810d2041e93f915ef59899c923f4568f4585904d010387ed74988e77b", [:make, :mix, :rebar3], [], "hexpm"}, "stream_data": {:hex, :stream_data, "0.3.0", "cbfc8e3212f64683615657ea27804126a42ded634adfdfee258bf087ee605d46", [:mix], [], "hexpm"}, - "unicode_util_compat": {:hex, :unicode_util_compat, "0.3.1", "a1f612a7b512638634a603c8f401892afbf99b8ce93a45041f8aaca99cadb85e", [:rebar3], [], "hexpm"}} + "unicode_util_compat": {:hex, :unicode_util_compat, "0.4.1", "d869e4c68901dd9531385bb0c8c40444ebf624e60b6962d95952775cac5e90cd", [:rebar3], [], "hexpm"}} From 4d780666978c784149d17793913fc7d914359f3c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" Date: Mon, 22 Apr 2019 13:35:10 +0000 Subject: [PATCH 404/418] Bump ex_doc from 0.18.1 to 0.20.2 Bumps [ex_doc](https://github.com/elixir-lang/ex_doc) from 0.18.1 to 0.20.2. - [Release notes](https://github.com/elixir-lang/ex_doc/releases) - [Changelog](https://github.com/elixir-lang/ex_doc/blob/master/CHANGELOG.md) - [Commits](https://github.com/elixir-lang/ex_doc/compare/v0.18.1...v0.20.2) Signed-off-by: dependabot[bot] --- mix.lock | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/mix.lock b/mix.lock index 78d35758..b055040d 100644 --- a/mix.lock +++ b/mix.lock @@ -1,17 +1,20 @@ %{"bunt": {:hex, :bunt, "0.2.0", "951c6e801e8b1d2cbe58ebbd3e616a869061ddadcc4863d0a2182541acae9a38", [:mix], [], "hexpm"}, "certifi": {:hex, :certifi, "2.5.1", "867ce347f7c7d78563450a18a6a28a8090331e77fa02380b4a21962a65d36ee5", [:rebar3], [{:parse_trans, "~>3.3", [hex: :parse_trans, repo: "hexpm", optional: false]}], "hexpm"}, "credo": {:hex, :credo, "1.0.5", "fdea745579f8845315fe6a3b43e2f9f8866839cfbc8562bb72778e9fdaa94214", [:mix], [{:bunt, "~> 0.2.0", [hex: :bunt, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm"}, - "earmark": {:hex, :earmark, "1.2.3", "206eb2e2ac1a794aa5256f3982de7a76bf4579ff91cb28d0e17ea2c9491e46a4", [:mix], [], "hexpm"}, + "earmark": {:hex, :earmark, "1.3.2", "b840562ea3d67795ffbb5bd88940b1bed0ed9fa32834915125ea7d02e35888a5", [:mix], [], "hexpm"}, "estree": {:hex, :estree, "2.6.1", "0a17cc0e9e35315dc4fcd79d30a746b1f3e9ed654be6084ce882ab491165ae22", [:mix], [], "hexpm"}, - "ex_doc": {:hex, :ex_doc, "0.18.1", "37c69d2ef62f24928c1f4fdc7c724ea04aecfdf500c4329185f8e3649c915baf", [:mix], [{:earmark, "~> 1.1", [hex: :earmark, repo: "hexpm", optional: false]}], "hexpm"}, + "ex_doc": {:hex, :ex_doc, "0.20.2", "1bd0dfb0304bade58beb77f20f21ee3558cc3c753743ae0ddbb0fd7ba2912331", [:mix], [{:earmark, "~> 1.3", [hex: :earmark, repo: "hexpm", optional: false]}, {:makeup_elixir, "~> 0.10", [hex: :makeup_elixir, repo: "hexpm", optional: false]}], "hexpm"}, "excoveralls": {:hex, :excoveralls, "0.10.6", "e2b9718c9d8e3ef90bc22278c3f76c850a9f9116faf4ebe9678063310742edc2", [:mix], [{:hackney, "~> 1.13", [hex: :hackney, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm"}, "exjsx": {:hex, :exjsx, "4.0.0", "60548841e0212df401e38e63c0078ec57b33e7ea49b032c796ccad8cde794b5c", [:mix], [{:jsx, "~> 2.8.0", [hex: :jsx, repo: "hexpm", optional: false]}], "hexpm"}, "hackney": {:hex, :hackney, "1.15.1", "9f8f471c844b8ce395f7b6d8398139e26ddca9ebc171a8b91342ee15a19963f4", [:rebar3], [{:certifi, "2.5.1", [hex: :certifi, repo: "hexpm", optional: false]}, {:idna, "6.0.0", [hex: :idna, repo: "hexpm", optional: false]}, {:metrics, "1.0.1", [hex: :metrics, repo: "hexpm", optional: false]}, {:mimerl, "~>1.1", [hex: :mimerl, repo: "hexpm", optional: false]}, {:ssl_verify_fun, "1.1.4", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}], "hexpm"}, "idna": {:hex, :idna, "6.0.0", "689c46cbcdf3524c44d5f3dde8001f364cd7608a99556d8fbd8239a5798d4c10", [:rebar3], [{:unicode_util_compat, "0.4.1", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm"}, "jason": {:hex, :jason, "1.1.2", "b03dedea67a99223a2eaf9f1264ce37154564de899fd3d8b9a21b1a6fd64afe7", [:mix], [{:decimal, "~> 1.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm"}, "jsx": {:hex, :jsx, "2.8.3", "a05252d381885240744d955fbe3cf810504eb2567164824e19303ea59eef62cf", [:mix, :rebar3], [], "hexpm"}, + "makeup": {:hex, :makeup, "0.8.0", "9cf32aea71c7fe0a4b2e9246c2c4978f9070257e5c9ce6d4a28ec450a839b55f", [:mix], [{:nimble_parsec, "~> 0.5.0", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm"}, + "makeup_elixir": {:hex, :makeup_elixir, "0.13.0", "be7a477997dcac2e48a9d695ec730b2d22418292675c75aa2d34ba0909dcdeda", [:mix], [{:makeup, "~> 0.8", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm"}, "metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [:rebar3], [], "hexpm"}, "mimerl": {:hex, :mimerl, "1.2.0", "67e2d3f571088d5cfd3e550c383094b47159f3eee8ffa08e64106cdf5e981be3", [:rebar3], [], "hexpm"}, + "nimble_parsec": {:hex, :nimble_parsec, "0.5.0", "90e2eca3d0266e5c53f8fbe0079694740b9c91b6747f2b7e3c5d21966bba8300", [:mix], [], "hexpm"}, "parse_trans": {:hex, :parse_trans, "3.3.0", "09765507a3c7590a784615cfd421d101aec25098d50b89d7aa1d66646bc571c1", [:rebar3], [], "hexpm"}, "poison": {:hex, :poison, "4.0.1", "bcb755a16fac91cad79bfe9fc3585bb07b9331e50cfe3420a24bcc2d735709ae", [:mix], [], "hexpm"}, "ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.4", "f0eafff810d2041e93f915ef59899c923f4568f4585904d010387ed74988e77b", [:make, :mix, :rebar3], [], "hexpm"}, From ef2474e9af1e5c45043be342f97febce74416b48 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" Date: Mon, 6 May 2019 07:24:36 +0000 Subject: [PATCH 405/418] Bump excoveralls from 0.10.6 to 0.11.0 Bumps [excoveralls](https://github.com/parroty/excoveralls) from 0.10.6 to 0.11.0. - [Release notes](https://github.com/parroty/excoveralls/releases) - [Changelog](https://github.com/parroty/excoveralls/blob/master/CHANGELOG.md) - [Commits](https://github.com/parroty/excoveralls/compare/v0.10.6...v0.11.0) Signed-off-by: dependabot[bot] --- mix.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mix.lock b/mix.lock index b055040d..578cdf32 100644 --- a/mix.lock +++ b/mix.lock @@ -4,7 +4,7 @@ "earmark": {:hex, :earmark, "1.3.2", "b840562ea3d67795ffbb5bd88940b1bed0ed9fa32834915125ea7d02e35888a5", [:mix], [], "hexpm"}, "estree": {:hex, :estree, "2.6.1", "0a17cc0e9e35315dc4fcd79d30a746b1f3e9ed654be6084ce882ab491165ae22", [:mix], [], "hexpm"}, "ex_doc": {:hex, :ex_doc, "0.20.2", "1bd0dfb0304bade58beb77f20f21ee3558cc3c753743ae0ddbb0fd7ba2912331", [:mix], [{:earmark, "~> 1.3", [hex: :earmark, repo: "hexpm", optional: false]}, {:makeup_elixir, "~> 0.10", [hex: :makeup_elixir, repo: "hexpm", optional: false]}], "hexpm"}, - "excoveralls": {:hex, :excoveralls, "0.10.6", "e2b9718c9d8e3ef90bc22278c3f76c850a9f9116faf4ebe9678063310742edc2", [:mix], [{:hackney, "~> 1.13", [hex: :hackney, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm"}, + "excoveralls": {:hex, :excoveralls, "0.11.0", "1427780f327902f099ef948bbc107b06a200a14a80e5badc1f9624d0f059235f", [:mix], [{:hackney, "~> 1.0", [hex: :hackney, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm"}, "exjsx": {:hex, :exjsx, "4.0.0", "60548841e0212df401e38e63c0078ec57b33e7ea49b032c796ccad8cde794b5c", [:mix], [{:jsx, "~> 2.8.0", [hex: :jsx, repo: "hexpm", optional: false]}], "hexpm"}, "hackney": {:hex, :hackney, "1.15.1", "9f8f471c844b8ce395f7b6d8398139e26ddca9ebc171a8b91342ee15a19963f4", [:rebar3], [{:certifi, "2.5.1", [hex: :certifi, repo: "hexpm", optional: false]}, {:idna, "6.0.0", [hex: :idna, repo: "hexpm", optional: false]}, {:metrics, "1.0.1", [hex: :metrics, repo: "hexpm", optional: false]}, {:mimerl, "~>1.1", [hex: :mimerl, repo: "hexpm", optional: false]}, {:ssl_verify_fun, "1.1.4", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}], "hexpm"}, "idna": {:hex, :idna, "6.0.0", "689c46cbcdf3524c44d5f3dde8001f364cd7608a99556d8fbd8239a5798d4c10", [:rebar3], [{:unicode_util_compat, "0.4.1", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm"}, From ae34eebedefe981e29da7ca593b36e4de7d33bd5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" Date: Mon, 13 May 2019 07:26:54 +0000 Subject: [PATCH 406/418] Bump excoveralls from 0.11.0 to 0.11.1 Bumps [excoveralls](https://github.com/parroty/excoveralls) from 0.11.0 to 0.11.1. - [Release notes](https://github.com/parroty/excoveralls/releases) - [Changelog](https://github.com/parroty/excoveralls/blob/master/CHANGELOG.md) - [Commits](https://github.com/parroty/excoveralls/compare/v0.11.0...v0.11.1) Signed-off-by: dependabot[bot] --- mix.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mix.lock b/mix.lock index 578cdf32..183fb2a2 100644 --- a/mix.lock +++ b/mix.lock @@ -4,7 +4,7 @@ "earmark": {:hex, :earmark, "1.3.2", "b840562ea3d67795ffbb5bd88940b1bed0ed9fa32834915125ea7d02e35888a5", [:mix], [], "hexpm"}, "estree": {:hex, :estree, "2.6.1", "0a17cc0e9e35315dc4fcd79d30a746b1f3e9ed654be6084ce882ab491165ae22", [:mix], [], "hexpm"}, "ex_doc": {:hex, :ex_doc, "0.20.2", "1bd0dfb0304bade58beb77f20f21ee3558cc3c753743ae0ddbb0fd7ba2912331", [:mix], [{:earmark, "~> 1.3", [hex: :earmark, repo: "hexpm", optional: false]}, {:makeup_elixir, "~> 0.10", [hex: :makeup_elixir, repo: "hexpm", optional: false]}], "hexpm"}, - "excoveralls": {:hex, :excoveralls, "0.11.0", "1427780f327902f099ef948bbc107b06a200a14a80e5badc1f9624d0f059235f", [:mix], [{:hackney, "~> 1.0", [hex: :hackney, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm"}, + "excoveralls": {:hex, :excoveralls, "0.11.1", "dd677fbdd49114fdbdbf445540ec735808250d56b011077798316505064edb2c", [:mix], [{:hackney, "~> 1.0", [hex: :hackney, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm"}, "exjsx": {:hex, :exjsx, "4.0.0", "60548841e0212df401e38e63c0078ec57b33e7ea49b032c796ccad8cde794b5c", [:mix], [{:jsx, "~> 2.8.0", [hex: :jsx, repo: "hexpm", optional: false]}], "hexpm"}, "hackney": {:hex, :hackney, "1.15.1", "9f8f471c844b8ce395f7b6d8398139e26ddca9ebc171a8b91342ee15a19963f4", [:rebar3], [{:certifi, "2.5.1", [hex: :certifi, repo: "hexpm", optional: false]}, {:idna, "6.0.0", [hex: :idna, repo: "hexpm", optional: false]}, {:metrics, "1.0.1", [hex: :metrics, repo: "hexpm", optional: false]}, {:mimerl, "~>1.1", [hex: :mimerl, repo: "hexpm", optional: false]}, {:ssl_verify_fun, "1.1.4", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}], "hexpm"}, "idna": {:hex, :idna, "6.0.0", "689c46cbcdf3524c44d5f3dde8001f364cd7608a99556d8fbd8239a5798d4c10", [:rebar3], [{:unicode_util_compat, "0.4.1", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm"}, From bb44d1ab20af37c08fbe0afbb15d0251e20f4eb7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" Date: Tue, 14 May 2019 15:41:46 +0000 Subject: [PATCH 407/418] Bump estree from 2.6.1 to 2.7.0 Bumps [estree](https://github.com/bryanjos/elixir-estree) from 2.6.1 to 2.7.0. - [Release notes](https://github.com/bryanjos/elixir-estree/releases) - [Changelog](https://github.com/elixirscript/elixir-estree/blob/master/CHANGELOG.md) - [Commits](https://github.com/bryanjos/elixir-estree/commits) Signed-off-by: dependabot[bot] --- mix.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mix.lock b/mix.lock index 183fb2a2..9881ee42 100644 --- a/mix.lock +++ b/mix.lock @@ -2,7 +2,7 @@ "certifi": {:hex, :certifi, "2.5.1", "867ce347f7c7d78563450a18a6a28a8090331e77fa02380b4a21962a65d36ee5", [:rebar3], [{:parse_trans, "~>3.3", [hex: :parse_trans, repo: "hexpm", optional: false]}], "hexpm"}, "credo": {:hex, :credo, "1.0.5", "fdea745579f8845315fe6a3b43e2f9f8866839cfbc8562bb72778e9fdaa94214", [:mix], [{:bunt, "~> 0.2.0", [hex: :bunt, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm"}, "earmark": {:hex, :earmark, "1.3.2", "b840562ea3d67795ffbb5bd88940b1bed0ed9fa32834915125ea7d02e35888a5", [:mix], [], "hexpm"}, - "estree": {:hex, :estree, "2.6.1", "0a17cc0e9e35315dc4fcd79d30a746b1f3e9ed654be6084ce882ab491165ae22", [:mix], [], "hexpm"}, + "estree": {:hex, :estree, "2.7.0", "32cb6ff05c85a93bf6c646b3b184e131f699fc1e7157d2b5be148c17f43ae566", [:mix], [], "hexpm"}, "ex_doc": {:hex, :ex_doc, "0.20.2", "1bd0dfb0304bade58beb77f20f21ee3558cc3c753743ae0ddbb0fd7ba2912331", [:mix], [{:earmark, "~> 1.3", [hex: :earmark, repo: "hexpm", optional: false]}, {:makeup_elixir, "~> 0.10", [hex: :makeup_elixir, repo: "hexpm", optional: false]}], "hexpm"}, "excoveralls": {:hex, :excoveralls, "0.11.1", "dd677fbdd49114fdbdbf445540ec735808250d56b011077798316505064edb2c", [:mix], [{:hackney, "~> 1.0", [hex: :hackney, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm"}, "exjsx": {:hex, :exjsx, "4.0.0", "60548841e0212df401e38e63c0078ec57b33e7ea49b032c796ccad8cde794b5c", [:mix], [{:jsx, "~> 2.8.0", [hex: :jsx, repo: "hexpm", optional: false]}], "hexpm"}, From 5b3aa851085becdf9131b7191f1ce530dd6128d0 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" Date: Mon, 3 Jun 2019 22:15:45 +0000 Subject: [PATCH 408/418] [Security] Bump sshpk from 1.13.1 to 1.16.1 Bumps [sshpk](https://github.com/joyent/node-sshpk) from 1.13.1 to 1.16.1. **This update includes security fixes.** - [Release notes](https://github.com/joyent/node-sshpk/releases) - [Commits](https://github.com/joyent/node-sshpk/compare/v1.13.1...v1.16.1) --- yarn.lock | 29 ++++++++++++++++++----------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/yarn.lock b/yarn.lock index 9aec577d..2cfcf27c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -209,8 +209,10 @@ arrify@^1.0.0, arrify@^1.0.1: resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d" asn1@~0.2.3: - version "0.2.3" - resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.3.tgz#dac8787713c9966849fc8180777ebe9c1ddf3b86" + version "0.2.4" + resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.4.tgz#8d2475dfab553bb33e77b54e59e880bb8ce23136" + dependencies: + safer-buffer "~2.1.0" assert-plus@1.0.0, assert-plus@^1.0.0: version "1.0.0" @@ -1084,8 +1086,8 @@ balanced-match@^1.0.0: resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" bcrypt-pbkdf@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz#63bc5dcb61331b92bc05fd528953c33462a06f8d" + version "1.0.2" + resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz#a4301d389b6a43f9b67ff3ca11a3f6637e360e9e" dependencies: tweetnacl "^0.14.3" @@ -1601,10 +1603,11 @@ duplexer3@^0.1.4: resolved "https://registry.yarnpkg.com/duplexer3/-/duplexer3-0.1.4.tgz#ee01dd1cac0ed3cbc7fdbea37dc0a8f1ce002ce2" ecc-jsbn@~0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz#0fc73a9ed5f0d53c38193398523ef7e543777505" + version "0.1.2" + resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz#3a83a904e54353287874c564b7549386849a98c9" dependencies: jsbn "~0.1.0" + safer-buffer "^2.1.0" electron-to-chromium@^1.3.14: version "1.3.14" @@ -3608,6 +3611,10 @@ safe-buffer@^5.0.1, safe-buffer@^5.1.1, safe-buffer@~5.1.0: version "5.1.1" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.1.tgz#893312af69b2123def71f57889001671eeb2c853" +safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0: + version "2.1.2" + resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" + semver-diff@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/semver-diff/-/semver-diff-2.1.0.tgz#4bbb8437c8d37e4b0cf1a68fd726ec6d645d6d36" @@ -3716,17 +3723,17 @@ sprintf-js@~1.0.2: resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" sshpk@^1.7.0: - version "1.13.1" - resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.13.1.tgz#512df6da6287144316dc4c18fe1cf1d940739be3" + version "1.16.1" + resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.16.1.tgz#fb661c0bef29b39db40769ee39fa70093d6f6877" dependencies: asn1 "~0.2.3" assert-plus "^1.0.0" - dashdash "^1.12.0" - getpass "^0.1.1" - optionalDependencies: bcrypt-pbkdf "^1.0.0" + dashdash "^1.12.0" ecc-jsbn "~0.1.1" + getpass "^0.1.1" jsbn "~0.1.0" + safer-buffer "^2.0.2" tweetnacl "~0.14.0" stack-utils@^1.0.0: From 41721f2f8b375abafde32209e7941e35ab175663 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" Date: Mon, 3 Jun 2019 22:16:12 +0000 Subject: [PATCH 409/418] [Security] Bump stringstream from 0.0.5 to 0.0.6 Bumps [stringstream](https://github.com/mhart/StringStream) from 0.0.5 to 0.0.6. **This update includes security fixes.** - [Release notes](https://github.com/mhart/StringStream/releases) - [Commits](https://github.com/mhart/StringStream/compare/v0.0.5...v0.0.6) --- yarn.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/yarn.lock b/yarn.lock index 9aec577d..3c14f2b6 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3762,8 +3762,8 @@ string_decoder@~1.0.0: safe-buffer "~5.1.0" stringstream@~0.0.4: - version "0.0.5" - resolved "https://registry.yarnpkg.com/stringstream/-/stringstream-0.0.5.tgz#4e484cd4de5a0bbbee18e46307710a8a81621878" + version "0.0.6" + resolved "https://registry.yarnpkg.com/stringstream/-/stringstream-0.0.6.tgz#7880225b0d4ad10e30927d167a1d6f2fd3b33a72" strip-ansi@^3.0.0, strip-ansi@^3.0.1: version "3.0.1" From 6bfe65c2764d5f390c218fd1dabaf7a150509fac Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" Date: Mon, 3 Jun 2019 22:16:40 +0000 Subject: [PATCH 410/418] [Security] Bump tar from 2.2.1 to 2.2.2 Bumps [tar](https://github.com/npm/node-tar) from 2.2.1 to 2.2.2. **This update includes security fixes.** - [Release notes](https://github.com/npm/node-tar/releases) - [Commits](https://github.com/npm/node-tar/compare/v2.2.1...v2.2.2) --- yarn.lock | 41 +++++++++++++++++++++++++++++++---------- 1 file changed, 31 insertions(+), 10 deletions(-) diff --git a/yarn.lock b/yarn.lock index 9aec577d..fa642e61 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1122,8 +1122,8 @@ boxen@^1.0.0: widest-line "^1.0.0" brace-expansion@^1.1.7: - version "1.1.8" - resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.8.tgz#c07b211c7c952ec1f8efd51a77ef0d1d3990a292" + version "1.1.11" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" dependencies: balanced-match "^1.0.0" concat-map "0.0.1" @@ -1976,9 +1976,9 @@ fstream-ignore@^1.0.5: inherits "2" minimatch "^3.0.0" -fstream@^1.0.0, fstream@^1.0.10, fstream@^1.0.2: - version "1.0.11" - resolved "https://registry.yarnpkg.com/fstream/-/fstream-1.0.11.tgz#5c1fb1f117477114f0632a0eb4b71b3cb0fd3171" +fstream@^1.0.0, fstream@^1.0.10, fstream@^1.0.12: + version "1.0.12" + resolved "https://registry.yarnpkg.com/fstream/-/fstream-1.0.12.tgz#4e8ba8ee2d48be4f7d0de505455548eae5932045" dependencies: graceful-fs "^4.1.2" inherits "~2.0.0" @@ -2063,6 +2063,17 @@ glob@^7.0.3, glob@^7.0.5, glob@^7.0.6, glob@^7.1.2: once "^1.3.0" path-is-absolute "^1.0.0" +glob@^7.1.3: + version "7.1.4" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.4.tgz#aa608a2f6c577ad357e1ae5a5c26d9a8d1969255" + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.0.4" + once "^1.3.0" + path-is-absolute "^1.0.0" + globals@^9.0.0, globals@^9.17.0, globals@^9.18.0: version "9.18.0" resolved "https://registry.yarnpkg.com/globals/-/globals-9.18.0.tgz#aa3896b3e69b487f17e31ed2143d69a8e30c2d8a" @@ -2104,10 +2115,14 @@ got@^6.7.1: unzip-response "^2.0.1" url-parse-lax "^1.0.0" -graceful-fs@^4.1.11, graceful-fs@^4.1.2: +graceful-fs@^4.1.11: version "4.1.11" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.11.tgz#0e8bdfe4d1ddb8854d64e04ea7c00e2a026e5658" +graceful-fs@^4.1.2: + version "4.1.15" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.15.tgz#ffb703e1066e8a0eeaa4c8b80ba9253eeefbfb00" + grapheme-splitter@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/grapheme-splitter/-/grapheme-splitter-1.0.2.tgz#639e9dc1bf065892c643de31daa27cf58b1068e2" @@ -3531,7 +3546,13 @@ right-align@^0.1.1: dependencies: align-text "^0.1.1" -rimraf@2, rimraf@^2.2.8, rimraf@^2.3.3, rimraf@^2.5.1, rimraf@^2.5.4, rimraf@^2.6.1: +rimraf@2: + version "2.6.3" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.3.tgz#b2d104fe0d8fb27cf9e0a1cda8262dd3833c6cab" + dependencies: + glob "^7.1.3" + +rimraf@^2.2.8, rimraf@^2.3.3, rimraf@^2.5.1, rimraf@^2.5.4, rimraf@^2.6.1: version "2.6.1" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.1.tgz#c2338ec643df7a1b7fe5c54fa86f57428a55f33d" dependencies: @@ -3866,11 +3887,11 @@ tar-pack@^3.4.0: uid-number "^0.0.6" tar@^2.2.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/tar/-/tar-2.2.1.tgz#8e4d2a256c0e2185c6b18ad694aec968b83cb1d1" + version "2.2.2" + resolved "https://registry.yarnpkg.com/tar/-/tar-2.2.2.tgz#0ca8848562c7299b8b446ff6a4d60cdbb23edc40" dependencies: block-stream "*" - fstream "^1.0.2" + fstream "^1.0.12" inherits "2" term-size@^0.1.0: From 7e42592a400f02937eaad02fbc1c7a3020ca3393 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" Date: Mon, 3 Jun 2019 22:17:02 +0000 Subject: [PATCH 411/418] [Security] Bump tough-cookie from 2.3.2 to 2.3.4 Bumps [tough-cookie](https://github.com/salesforce/tough-cookie) from 2.3.2 to 2.3.4. **This update includes security fixes.** - [Release notes](https://github.com/salesforce/tough-cookie/releases) - [Commits](https://github.com/salesforce/tough-cookie/compare/v2.3.2...v2.3.4) --- yarn.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/yarn.lock b/yarn.lock index 9aec577d..57e6aee8 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3932,8 +3932,8 @@ to-fast-properties@^1.0.1, to-fast-properties@^1.0.3: resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-1.0.3.tgz#b83571fa4d8c25b82e231b06e3a3055de4ca1a47" tough-cookie@~2.3.0: - version "2.3.2" - resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.3.2.tgz#f081f76e4c85720e6c37a5faced737150d84072a" + version "2.3.4" + resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.3.4.tgz#ec60cee38ac675063ffc97a5c18970578ee83655" dependencies: punycode "^1.4.1" From ecd3c0a39684c2ac9e4f8043bc9c7bdf20b8cab2 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" Date: Tue, 4 Jun 2019 00:01:24 +0000 Subject: [PATCH 412/418] Bump eslint from 4.6.1 to 4.19.1 Bumps [eslint](https://github.com/eslint/eslint) from 4.6.1 to 4.19.1. - [Release notes](https://github.com/eslint/eslint/releases) - [Changelog](https://github.com/eslint/eslint/blob/master/CHANGELOG.md) - [Commits](https://github.com/eslint/eslint/compare/v4.6.1...v4.19.1) --- yarn.lock | 179 ++++++++++++++++++++++++++++-------------------------- 1 file changed, 94 insertions(+), 85 deletions(-) diff --git a/yarn.lock b/yarn.lock index 052816ce..08569965 100644 --- a/yarn.lock +++ b/yarn.lock @@ -70,25 +70,29 @@ acorn@^5.1.1: version "5.1.2" resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.1.2.tgz#911cb53e036807cf0fa778dc5d370fbd864246d7" -ajv-keywords@^1.0.0: - version "1.5.1" - resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-1.5.1.tgz#314dd0a4b3368fad3dfcdc54ede6171b886daf3c" +acorn@^5.5.0: + version "5.7.3" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.7.3.tgz#67aa231bf8812974b85235a96771eb6bd07ea279" -ajv@^4.7.0, ajv@^4.9.1: +ajv-keywords@^2.1.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-2.1.1.tgz#617997fc5f60576894c435f940d819e135b80762" + +ajv@^4.9.1: version "4.11.8" resolved "https://registry.yarnpkg.com/ajv/-/ajv-4.11.8.tgz#82ffb02b29e662ae53bdc20af15947706739c536" dependencies: co "^4.6.0" json-stable-stringify "^1.0.1" -ajv@^5.2.0: - version "5.2.2" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-5.2.2.tgz#47c68d69e86f5d953103b0074a9430dc63da5e39" +ajv@^5.2.3, ajv@^5.3.0: + version "5.5.2" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-5.5.2.tgz#73b5eeca3fab653e3d3f9422b341ad42205dc965" dependencies: co "^4.6.0" fast-deep-equal "^1.0.0" + fast-json-stable-stringify "^2.0.0" json-schema-traverse "^0.3.0" - json-stable-stringify "^1.0.1" align-text@^0.1.1, align-text@^0.1.3: version "0.1.4" @@ -339,15 +343,7 @@ aws4@^1.2.1: version "1.6.0" resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.6.0.tgz#83ef5ca860b2b32e4a0deedee8c771b9db57471e" -babel-code-frame@^6.22.0: - version "6.22.0" - resolved "https://registry.yarnpkg.com/babel-code-frame/-/babel-code-frame-6.22.0.tgz#027620bee567a88c32561574e7fd0801d33118e4" - dependencies: - chalk "^1.1.0" - esutils "^2.0.2" - js-tokens "^3.0.0" - -babel-code-frame@^6.26.0: +babel-code-frame@^6.22.0, babel-code-frame@^6.26.0: version "6.26.0" resolved "https://registry.yarnpkg.com/babel-code-frame/-/babel-code-frame-6.26.0.tgz#63fd43f7dc1e3bb7ce35947db8fe369a3f58c74b" dependencies: @@ -1238,7 +1234,7 @@ chalk@^0.4.0: has-color "~0.1.0" strip-ansi "~0.1.0" -chalk@^1.0.0, chalk@^1.1.0, chalk@^1.1.1, chalk@^1.1.3: +chalk@^1.0.0, chalk@^1.1.1, chalk@^1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" dependencies: @@ -1248,15 +1244,7 @@ chalk@^1.0.0, chalk@^1.1.0, chalk@^1.1.1, chalk@^1.1.3: strip-ansi "^3.0.0" supports-color "^2.0.0" -chalk@^2.0.0, chalk@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.0.1.tgz#dbec49436d2ae15f536114e76d14656cdbc0f44d" - dependencies: - ansi-styles "^3.1.0" - escape-string-regexp "^1.0.5" - supports-color "^4.0.0" - -chalk@^2.1.0: +chalk@^2.0.0, chalk@^2.0.1, chalk@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.1.0.tgz#ac5becf14fa21b99c6c92ca7a7d7cfd5b17e743e" dependencies: @@ -1524,6 +1512,12 @@ debug@^2.1.1, debug@^2.2.0, debug@^2.6.3, debug@^2.6.8: dependencies: ms "2.0.0" +debug@^3.1.0: + version "3.2.6" + resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.6.tgz#e83d17de16d8a7efb7717edbe5fb10135eee629b" + dependencies: + ms "^2.1.1" + decamelize@^1.0.0, decamelize@^1.1.1, decamelize@^1.1.2: version "1.2.0" resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" @@ -1583,12 +1577,11 @@ doctrine@1.5.0: esutils "^2.0.2" isarray "^1.0.0" -doctrine@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-2.0.0.tgz#c73d8d2909d22291e1a007a395804da8b665fe63" +doctrine@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-2.1.0.tgz#5cd01fc101621b42c4cd7f5d1a66243716d3f39d" dependencies: esutils "^2.0.2" - isarray "^1.0.0" dot-prop@^4.1.0: version "4.1.1" @@ -1685,32 +1678,36 @@ eslint-scope@^3.7.1: esrecurse "^4.1.0" estraverse "^4.1.1" +eslint-visitor-keys@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz#3f3180fb2e291017716acb4c9d6d5b5c34a6a81d" + eslint@^4.6.1: - version "4.6.1" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-4.6.1.tgz#ddc7fc7fd70bf93205b0b3449bb16a1e9e7d4950" + version "4.19.1" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-4.19.1.tgz#32d1d653e1d90408854bfb296f076ec7e186a300" dependencies: - ajv "^5.2.0" + ajv "^5.3.0" babel-code-frame "^6.22.0" chalk "^2.1.0" concat-stream "^1.6.0" cross-spawn "^5.1.0" - debug "^2.6.8" - doctrine "^2.0.0" + debug "^3.1.0" + doctrine "^2.1.0" eslint-scope "^3.7.1" - espree "^3.5.0" + eslint-visitor-keys "^1.0.0" + espree "^3.5.4" esquery "^1.0.0" - estraverse "^4.2.0" esutils "^2.0.2" file-entry-cache "^2.0.0" functional-red-black-tree "^1.0.1" glob "^7.1.2" - globals "^9.17.0" + globals "^11.0.1" ignore "^3.3.3" imurmurhash "^0.1.4" inquirer "^3.0.6" is-resolvable "^1.0.0" js-yaml "^3.9.1" - json-stable-stringify "^1.0.1" + json-stable-stringify-without-jsonify "^1.0.1" levn "^0.3.0" lodash "^4.17.4" minimatch "^3.0.2" @@ -1718,13 +1715,14 @@ eslint@^4.6.1: natural-compare "^1.4.0" optionator "^0.8.2" path-is-inside "^1.0.2" - pluralize "^4.0.0" + pluralize "^7.0.0" progress "^2.0.0" + regexpp "^1.0.1" require-uncached "^1.0.3" semver "^5.3.0" strip-ansi "^4.0.0" strip-json-comments "~2.0.1" - table "^4.0.1" + table "4.0.2" text-table "~0.2.0" espower-location-detector@^1.0.0: @@ -1736,17 +1734,13 @@ espower-location-detector@^1.0.0: source-map "^0.5.0" xtend "^4.0.0" -espree@^3.5.0: - version "3.5.0" - resolved "https://registry.yarnpkg.com/espree/-/espree-3.5.0.tgz#98358625bdd055861ea27e2867ea729faf463d8d" +espree@^3.5.4: + version "3.5.4" + resolved "https://registry.yarnpkg.com/espree/-/espree-3.5.4.tgz#b0f447187c8a8bed944b815a660bddf5deb5d1a7" dependencies: - acorn "^5.1.1" + acorn "^5.5.0" acorn-jsx "^3.0.0" -esprima@^3.1.1: - version "3.1.3" - resolved "https://registry.yarnpkg.com/esprima/-/esprima-3.1.3.tgz#fdca51cee6133895e3c88d535ce49dbff62a4633" - esprima@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.0.tgz#4499eddcd1110e0b218bacf2fa7f7f59f55ca804" @@ -1770,7 +1764,7 @@ esrecurse@^4.1.0: estraverse "^4.1.0" object-assign "^4.0.1" -estraverse@^4.0.0, estraverse@^4.1.0, estraverse@^4.1.1, estraverse@^4.2.0: +estraverse@^4.0.0, estraverse@^4.1.0, estraverse@^4.1.1: version "4.2.0" resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.2.0.tgz#0dee3fed31fcd469618ce7342099fc1afa0bdb13" @@ -1855,6 +1849,10 @@ fast-diff@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/fast-diff/-/fast-diff-1.1.1.tgz#0aea0e4e605b6a2189f0e936d4b7fbaf1b7cfd9b" +fast-json-stable-stringify@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz#d5142c0caee6b1189f87d3a76111064f86c8bbf2" + fast-levenshtein@~2.0.4: version "2.0.6" resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" @@ -2052,18 +2050,7 @@ glob-parent@^2.0.0: dependencies: is-glob "^2.0.0" -glob@^7.0.3, glob@^7.0.5, glob@^7.0.6, glob@^7.1.2: - version "7.1.2" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.2.tgz#c19c9df9a028702d678612384a6552404c636d15" - dependencies: - fs.realpath "^1.0.0" - inflight "^1.0.4" - inherits "2" - minimatch "^3.0.4" - once "^1.3.0" - path-is-absolute "^1.0.0" - -glob@^7.1.3: +glob@^7.0.3, glob@^7.0.5, glob@^7.0.6, glob@^7.1.2, glob@^7.1.3: version "7.1.4" resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.4.tgz#aa608a2f6c577ad357e1ae5a5c26d9a8d1969255" dependencies: @@ -2074,7 +2061,11 @@ glob@^7.1.3: once "^1.3.0" path-is-absolute "^1.0.0" -globals@^9.0.0, globals@^9.17.0, globals@^9.18.0: +globals@^11.0.1: + version "11.12.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e" + +globals@^9.0.0, globals@^9.18.0: version "9.18.0" resolved "https://registry.yarnpkg.com/globals/-/globals-9.18.0.tgz#aa3896b3e69b487f17e31ed2143d69a8e30c2d8a" @@ -2559,14 +2550,7 @@ js-tokens@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b" -js-yaml@^3.8.2: - version "3.8.4" - resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.8.4.tgz#520b4564f86573ba96662af85a8cafa7b4b5a6f6" - dependencies: - argparse "^1.0.7" - esprima "^3.1.1" - -js-yaml@^3.9.1: +js-yaml@^3.8.2, js-yaml@^3.9.1: version "3.9.1" resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.9.1.tgz#08775cebdfdd359209f0d2acd383c8f86a6904a0" dependencies: @@ -2597,6 +2581,10 @@ json-schema@0.2.3: version "0.2.3" resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13" +json-stable-stringify-without-jsonify@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" + json-stable-stringify@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz#9a759d39c5f2ff503fd5300646ed445f88c4f9af" @@ -2735,7 +2723,7 @@ lodash.some@^4.6.0: version "4.6.0" resolved "https://registry.yarnpkg.com/lodash.some/-/lodash.some-4.6.0.tgz#1bb9f314ef6b8baded13b549169b2a945eb68e4d" -lodash@^4.0.0, lodash@^4.17.4, lodash@^4.2.0, lodash@^4.3.0: +lodash@^4.17.4, lodash@^4.2.0, lodash@^4.3.0: version "4.17.4" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.4.tgz#78203a4d1c328ae1d86dca6460e369b57f4055ae" @@ -2888,6 +2876,10 @@ ms@2.0.0, ms@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" +ms@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.1.tgz#30a5864eb3ebb0a66f2ebe6d727af06a09d86e0a" + multimatch@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/multimatch/-/multimatch-2.1.0.tgz#9c7906a22fb4c02919e2f5f75161b4cdbd4b2a2b" @@ -3243,9 +3235,9 @@ plur@^2.0.0: dependencies: irregular-plurals "^1.0.0" -pluralize@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/pluralize/-/pluralize-4.0.0.tgz#59b708c1c0190a2f692f1c7618c446b052fd1762" +pluralize@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/pluralize/-/pluralize-7.0.0.tgz#298b89df8b93b0221dbf421ad2b1b1ea23fc6777" prelude-ls@~1.1.2: version "1.1.2" @@ -3398,6 +3390,10 @@ regex-cache@^0.4.2: is-equal-shallow "^0.1.3" is-primitive "^2.0.0" +regexpp@^1.0.1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-1.1.0.tgz#0e3516dd0b7904f413d2d4193dce4618c3a689ab" + regexpu-core@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-2.0.0.tgz#49d038837b8dcf8bfa5b9a42139938e6ea2ae240" @@ -3669,6 +3665,12 @@ slice-ansi@0.0.4: version "0.0.4" resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-0.0.4.tgz#edbf8903f66f7ce2f8eafd6ceed65e264c831b35" +slice-ansi@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-1.0.0.tgz#044f1a49d8842ff307aad6b505ed178bd950134d" + dependencies: + is-fullwidth-code-point "^2.0.0" + slide@^1.1.5: version "1.1.6" resolved "https://registry.yarnpkg.com/slide/-/slide-1.1.6.tgz#56eb027d65b4d2dce6cb2e2d32c4d4afc9e1d707" @@ -3776,6 +3778,13 @@ string-width@^2.1.0: is-fullwidth-code-point "^2.0.0" strip-ansi "^4.0.0" +string-width@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" + dependencies: + is-fullwidth-code-point "^2.0.0" + strip-ansi "^4.0.0" + string_decoder@~1.0.0: version "1.0.3" resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.0.3.tgz#0fc67d7c141825de94282dd536bec6b9bce860ab" @@ -3856,16 +3865,16 @@ symbol-observable@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.0.4.tgz#29bf615d4aa7121bdd898b22d4b3f9bc4e2aa03d" -table@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/table/-/table-4.0.1.tgz#a8116c133fac2c61f4a420ab6cdf5c4d61f0e435" +table@4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/table/-/table-4.0.2.tgz#a33447375391e766ad34d3486e6e2aedc84d2e36" dependencies: - ajv "^4.7.0" - ajv-keywords "^1.0.0" - chalk "^1.1.1" - lodash "^4.0.0" - slice-ansi "0.0.4" - string-width "^2.0.0" + ajv "^5.2.3" + ajv-keywords "^2.1.0" + chalk "^2.1.0" + lodash "^4.17.4" + slice-ansi "1.0.0" + string-width "^2.1.1" tailored@^2.7.4: version "2.7.4" From b9ceea03ca066e6233b92983aa3dd45c83e89a73 Mon Sep 17 00:00:00 2001 From: workingjubilee Date: Sun, 18 Aug 2019 15:55:54 -0700 Subject: [PATCH 413/418] Solves easy lints --- src/javascript/tests/core/erlang_compat/maps_spec.js | 4 +--- src/javascript/tests/with.spec.js | 4 ++-- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/src/javascript/tests/core/erlang_compat/maps_spec.js b/src/javascript/tests/core/erlang_compat/maps_spec.js index 1a504227..31a20dcd 100644 --- a/src/javascript/tests/core/erlang_compat/maps_spec.js +++ b/src/javascript/tests/core/erlang_compat/maps_spec.js @@ -67,9 +67,7 @@ test('put/3', (t) => { test('take/2', (t) => { const myMap = new Map([['a', 1], ['b', 2]]); - let a; - let result; - [a, result] = Core.maps.take('a', myMap); + const [a, result] = Core.maps.take('a', myMap); t.is(a, 1); t.is(result.has('a'), false); }); diff --git a/src/javascript/tests/with.spec.js b/src/javascript/tests/with.spec.js index 0ac09ced..31fb2c49 100644 --- a/src/javascript/tests/with.spec.js +++ b/src/javascript/tests/with.spec.js @@ -1,5 +1,5 @@ -import Core from '../lib/core'; import test from 'ava'; +import Core from '../lib/core'; const Patterns = Core.Patterns; const SpecialForms = Core.SpecialForms; @@ -31,7 +31,7 @@ test('with', (t) => { const value = SpecialForms._with( [new Tuple(Symbol.for('ok'), $), () => map_fetch(opts, 'width')], - [new Tuple(Symbol.for('ok'), $), width => map_fetch(opts, 'height')], + [new Tuple(Symbol.for('ok'), $), () => map_fetch(opts, 'height')], (width, height) => new Tuple(Symbol.for('ok'), width * height), ); From d8db026eb453bbd2547c1d89777540e314c66d6e Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Mon, 19 Aug 2019 12:56:40 -0500 Subject: [PATCH 414/418] Update .travis.yml --- .travis.yml | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/.travis.yml b/.travis.yml index 5dbed2d0..86b63471 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,13 +1,16 @@ sudo: false language: elixir elixir: - - 1.6.0 + - 1.9 otp_release: - - 20.2 -env: - - TRAVIS_NODE_VERSION="8" + - 22.0 +cache: + directories: + - _build + - deps + - node_modules install: - - rm -rf ~/.nvm && git clone https://github.com/creationix/nvm.git ~/.nvm && (cd ~/.nvm && git checkout `git describe --abbrev=0 --tags`) && source ~/.nvm/nvm.sh && nvm install $TRAVIS_NODE_VERSION + - nvm install 12.8.0 && nvm use 12.8.0 - npm install -g yarn - yarn - mix local.hex --force From 44cb70c49615261267fba374347ecf4d50c7e01d Mon Sep 17 00:00:00 2001 From: workingjubilee Date: Mon, 19 Aug 2019 23:54:53 -0700 Subject: [PATCH 415/418] Disables "no-console" linting in extant test files --- .eslintrc.js | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/.eslintrc.js b/.eslintrc.js index 3b27e64a..24dfa7ae 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -8,6 +8,14 @@ module.exports = { 'import/extensions': 'off', 'import/no-extraneous-dependencies': ['error', { devDependencies: true }], }, + 'overrides': [ + { + 'files': ['*spec.js', 'priv/testrunner/**/*'], + 'rules': { + 'no-console': 'off' + } + } + ], extends: 'airbnb-base', plugins: ['import'], env: { From fab74b8b187c9700415bb5501fa11b783edb4c91 Mon Sep 17 00:00:00 2001 From: workingjubilee Date: Mon, 19 Aug 2019 23:55:53 -0700 Subject: [PATCH 416/418] Disable "no-console" linting for specific console.warns These all are exceptional cases of warnings where the warning is far more important than adhering to a style guide on lints, even if some of them might potentially show up in the browser. Each is a hand-picked exception, so these use in-file comment overrides. Rationales are included in preceding comments. --- src/javascript/lib/core.js | 5 +++++ src/javascript/lib/core/erlang_compat/elixir_errors.js | 4 ++++ src/javascript/lib/core/erlang_compat/io.js | 2 ++ src/javascript/lib/core/special_forms.js | 3 +++ 4 files changed, 14 insertions(+) diff --git a/src/javascript/lib/core.js b/src/javascript/lib/core.js index 093816c2..7f87d1da 100644 --- a/src/javascript/lib/core.js +++ b/src/javascript/lib/core.js @@ -27,7 +27,12 @@ function get_global() { return global; } + /* As long as the window check precedes this, it won't display in a browser, + unless the ground cracks open and swallows JavaScript whole. */ + /* eslint-disable no-console */ console.warn('No global state found'); + /* eslint-enable no-console */ + return null; } diff --git a/src/javascript/lib/core/erlang_compat/elixir_errors.js b/src/javascript/lib/core/erlang_compat/elixir_errors.js index 9e68f5dc..c6b5d22b 100644 --- a/src/javascript/lib/core/erlang_compat/elixir_errors.js +++ b/src/javascript/lib/core/erlang_compat/elixir_errors.js @@ -1,7 +1,11 @@ +/* It is far too "meta" to warn about including a warning in a warning */ +/* eslint-disable no-console */ + function warn(message) { const messageString = message.join(''); console.warn(`warning: ${messageString}`); + return Symbol.for('ok'); } diff --git a/src/javascript/lib/core/erlang_compat/io.js b/src/javascript/lib/core/erlang_compat/io.js index bf1d49dc..abff3f57 100644 --- a/src/javascript/lib/core/erlang_compat/io.js +++ b/src/javascript/lib/core/erlang_compat/io.js @@ -1,3 +1,5 @@ +/* The purpose of this module is, in fact, to do IO. */ +/* eslint-disable no-console */ import erlang from './erlang'; function put_chars(ioDevice, charData) { diff --git a/src/javascript/lib/core/special_forms.js b/src/javascript/lib/core/special_forms.js index 7964bf3d..7721612b 100644 --- a/src/javascript/lib/core/special_forms.js +++ b/src/javascript/lib/core/special_forms.js @@ -138,7 +138,10 @@ function _with(...args) { } function receive(clauses, timeout = 0, timeoutFn = () => true) { + /* It's more important to warn developers than follow style guides */ + /* eslint-disable no-console */ console.warn('Receive not supported'); + /* eslint-enable no-console */ const messages = []; // this.mailbox.get(); const NOMATCH = Symbol('NOMATCH'); From 3ccd8e04267de15613a49813b8b75ff23d1798d4 Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Tue, 20 Aug 2019 09:01:45 -0500 Subject: [PATCH 417/418] Update js deps --- .eslintrc.js | 4 +- .formatter.exs | 4 + .tool-versions | 6 +- .travis.yml | 11 +- CONTRIBUTING.md | 112 +- Makefile | 6 +- package-lock.json | 6511 +++++++++++++++++++++++++++++++ package.json | 18 +- priv/testrunner/esm/index.js | 59 +- priv/testrunner/vendor.build.js | 4 +- rollup.config.js | 41 +- yarn.lock | 4242 -------------------- 12 files changed, 6646 insertions(+), 4372 deletions(-) create mode 100644 .formatter.exs create mode 100644 package-lock.json delete mode 100644 yarn.lock diff --git a/.eslintrc.js b/.eslintrc.js index 3b27e64a..f7b15d25 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -6,7 +6,7 @@ module.exports = { 'no-restricted-syntax': 'off', 'no-underscore-dangle': 'off', 'import/extensions': 'off', - 'import/no-extraneous-dependencies': ['error', { devDependencies: true }], + 'import/no-extraneous-dependencies': ['error', {devDependencies: true}], }, extends: 'airbnb-base', plugins: ['import'], @@ -15,4 +15,4 @@ module.exports = { node: true, mocha: true, }, -}; +} diff --git a/.formatter.exs b/.formatter.exs new file mode 100644 index 00000000..562e8863 --- /dev/null +++ b/.formatter.exs @@ -0,0 +1,4 @@ +[ + import_deps: [:phoenix], + inputs: ["*.{ex,exs}", "{config,lib,priv,test}/**/*.{ex,exs}"] +] diff --git a/.tool-versions b/.tool-versions index fee73d5a..000eeb3e 100644 --- a/.tool-versions +++ b/.tool-versions @@ -1,3 +1,3 @@ -erlang 20.3 -elixir 1.6.5-otp-20 -nodejs 8.9.1 +erlang 22.0 +elixir 1.9.1-otp-22 +nodejs 12.8.1 diff --git a/.travis.yml b/.travis.yml index 86b63471..43916696 100644 --- a/.travis.yml +++ b/.travis.yml @@ -10,9 +10,8 @@ cache: - deps - node_modules install: - - nvm install 12.8.0 && nvm use 12.8.0 - - npm install -g yarn - - yarn + - nvm install 12.8.1 && nvm use 12.8.1 + - npm install - mix local.hex --force - mix local.rebar --force - mix deps.get @@ -23,6 +22,6 @@ notifications: webhooks: urls: - https://webhooks.gitter.im/e/fbd8944d285c0696dc41 - on_success: always # options: [always|never|change] default: always - on_failure: always # options: [always|never|change] default: always - on_start: never # options: [always|never|change] default: always + on_success: always # options: [always|never|change] default: always + on_failure: always # options: [always|never|change] default: always + on_start: never # options: [always|never|change] default: always diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 9be626f1..56fcb028 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -6,9 +6,9 @@ This contributing guide is based on the contributing for Elixir with changes sui Use the issues tracker for: -* [bug reports](#bug-reports) -* [submitting pull requests](#pull-requests) -* [feature requests](#feature-requests) +- [bug reports](#bug-reports) +- [submitting pull requests](#pull-requests) +- [feature requests](#feature-requests) ## Bug reports @@ -51,7 +51,7 @@ Example: ## Feature requests Feature requests are welcome. But take a moment to find -out whether your idea fits with the scope and aims of the project. It's up to *you* +out whether your idea fits with the scope and aims of the project. It's up to _you_ to make a strong case to convince the community of the merits of this feature. Please provide as much detail and context as possible. @@ -63,18 +63,18 @@ found in Elixir in ElixirScript. ElixirScript is broken up into the following parts: -* The compiler, written in Elixir -* The JavaScript core +- The compiler, written in Elixir +- The JavaScript core -The ElixirScript compiler is in the `lib` folder of the project. +The ElixirScript compiler is in the `lib` folder of the project. Here is where Elixir code is converted into JavaScript. -The JavaScript code is in the `src/javascript`. +The JavaScript code is in the `src/javascript`. This is where the special forms and the Erlang Compatibility Layer are defined -The ElixirScript tests can be run using `mix test` +The ElixirScript tests are ran using `mix test` -The JavaScript tests can be run using `yarn test` +The JavaScript tests are ran using `npm test` Please make sure all tests pass after making changes. Also make sure to include tests for the changes you made. @@ -104,72 +104,72 @@ documentation. When working with Git, we recommend the following process in order to craft an excellent pull request: 1. [Fork](https://help.github.com/fork-a-repo/) the project, clone your fork, - and configure the remotes: + and configure the remotes: - ```sh - # Clone your fork of the repo into the current directory - git clone https://github.com//elixirscript - # Navigate to the newly cloned directory - cd elixirscript - # Assign the original repo to a remote called "upstream" - git remote add upstream https://github.com/elixirscript/elixirscript - ``` +```sh +# Clone your fork of the repo into the current directory +git clone https://github.com//elixirscript +# Navigate to the newly cloned directory +cd elixirscript +# Assign the original repo to a remote called "upstream" +git remote add upstream https://github.com/elixirscript/elixirscript +``` 2. If you cloned a while ago, get the latest changes from upstream: - ```sh - git checkout master - git pull upstream master - ``` +```sh +git checkout master +git pull upstream master +``` 3. Create a new topic branch (off of `master`) to contain your feature, change, - or fix. + or fix. - **IMPORTANT**: Making changes in `master` is discouraged. You should always - keep your local `master` in sync with upstream `master` and make your - changes in topic branches. + **IMPORTANT**: Making changes in `master` is discouraged. You should always + keep your local `master` in sync with upstream `master` and make your + changes in topic branches. - ```sh - git checkout -b - ``` +```sh +git checkout -b +``` 4. Commit your changes in logical chunks. Keep your commit messages organized, - with a short description in the first line and more detailed information on - the following lines. Feel free to use Git's - [interactive rebase](https://help.github.com/articles/interactive-rebase) - feature to tidy up your commits before making them public. + with a short description in the first line and more detailed information on + the following lines. Feel free to use Git's + [interactive rebase](https://help.github.com/articles/interactive-rebase) + feature to tidy up your commits before making them public. 5. Make sure all the tests are still passing. - ```sh - mix test - yarn test - ``` +```sh +mix test +npm test +``` - This is needed to ensure your changes can - pass all the tests. +This is needed to ensure your changes can +pass all the tests. 6. Push your topic branch up to your fork: - ```sh - git push origin - ``` +```sh +git push origin +``` 7. [Open a Pull Request](https://help.github.com/articles/using-pull-requests/) - with a clear title and description. + with a clear title and description. 8. If you haven't updated your pull request for a while, you should consider - rebasing on master and resolving any conflicts. - - **IMPORTANT**: _Never ever_ merge upstream `master` into your branches. You - should always `git rebase` on `master` to bring your changes up to date when - necessary. - - ```sh - git checkout master - git pull upstream master - git checkout - git rebase master - ``` + rebasing on master and resolving any conflicts. + + **IMPORTANT**: _Never ever_ merge upstream `master` into your branches. You + should always `git rebase` on `master` to bring your changes up to date when + necessary. + +```sh +git checkout master +git pull upstream master +git checkout +git rebase master +``` Thank you for your contributions! diff --git a/Makefile b/Makefile index d717c5c5..9ede1be1 100644 --- a/Makefile +++ b/Makefile @@ -5,7 +5,7 @@ default: deps compile compile: js_compile elixir_compile js_compile: - yarn build + npm run build elixir_compile: mix compile @@ -13,7 +13,7 @@ elixir_compile: test: js_compile elixir_test js_test js_test: - yarn test + npm test elixir_test: mix test --cover @@ -29,4 +29,4 @@ elixir_deps: mix deps.get js_deps: - yarn + npm install diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 00000000..58a35a9a --- /dev/null +++ b/package-lock.json @@ -0,0 +1,6511 @@ +{ + "name": "elixirscript", + "version": "0.26.1", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "@ava/babel-plugin-throws-helper": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@ava/babel-plugin-throws-helper/-/babel-plugin-throws-helper-4.0.0.tgz", + "integrity": "sha512-3diBLIVBPPh3j4+hb5lo0I1D+S/O/VDJPI4Y502apBxmwEqjyXG4gTSPFUlm41sSZeZzMarT/Gzovw9kV7An0w==", + "dev": true + }, + "@ava/babel-preset-stage-4": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@ava/babel-preset-stage-4/-/babel-preset-stage-4-4.0.0.tgz", + "integrity": "sha512-lZEV1ZANzfzSYBU6WHSErsy7jLPbD1iIgAboASPMcKo7woVni5/5IKWeT0RxC8rY802MFktur3OKEw2JY1Tv2w==", + "dev": true, + "requires": { + "@babel/plugin-proposal-async-generator-functions": "^7.2.0", + "@babel/plugin-proposal-dynamic-import": "^7.5.0", + "@babel/plugin-proposal-optional-catch-binding": "^7.2.0", + "@babel/plugin-transform-dotall-regex": "^7.4.4", + "@babel/plugin-transform-modules-commonjs": "^7.5.0" + } + }, + "@ava/babel-preset-transform-test-files": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/@ava/babel-preset-transform-test-files/-/babel-preset-transform-test-files-6.0.0.tgz", + "integrity": "sha512-8eKhFzZp7Qcq1VLfoC75ggGT8nQs9q8fIxltU47yCB7Wi7Y8Qf6oqY1Bm0z04fIec24vEgr0ENhDHEOUGVDqnA==", + "dev": true, + "requires": { + "@ava/babel-plugin-throws-helper": "^4.0.0", + "babel-plugin-espower": "^3.0.1" + } + }, + "@babel/code-frame": { + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.5.5.tgz", + "integrity": "sha512-27d4lZoomVyo51VegxI20xZPuSHusqbQag/ztrBC7wegWoQ1nLREPVSKSW8byhTlzTKyNE4ifaTA6lCp7JjpFw==", + "dev": true, + "requires": { + "@babel/highlight": "^7.0.0" + } + }, + "@babel/core": { + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.5.5.tgz", + "integrity": "sha512-i4qoSr2KTtce0DmkuuQBV4AuQgGPUcPXMr9L5MyYAtk06z068lQ10a4O009fe5OB/DfNV+h+qqT7ddNV8UnRjg==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.5.5", + "@babel/generator": "^7.5.5", + "@babel/helpers": "^7.5.5", + "@babel/parser": "^7.5.5", + "@babel/template": "^7.4.4", + "@babel/traverse": "^7.5.5", + "@babel/types": "^7.5.5", + "convert-source-map": "^1.1.0", + "debug": "^4.1.0", + "json5": "^2.1.0", + "lodash": "^4.17.13", + "resolve": "^1.3.2", + "semver": "^5.4.1", + "source-map": "^0.5.0" + }, + "dependencies": { + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "json5": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.0.tgz", + "integrity": "sha512-8Mh9h6xViijj36g7Dxi+Y4S6hNGV96vcJZr/SrlHh1LR/pEn/8j/+qIBbs44YKl69Lrfctp4QD+AdWLTMqEZAQ==", + "dev": true, + "requires": { + "minimist": "^1.2.0" + } + }, + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "dev": true + } + } + }, + "@babel/generator": { + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.5.5.tgz", + "integrity": "sha512-ETI/4vyTSxTzGnU2c49XHv2zhExkv9JHLTwDAFz85kmcwuShvYG2H08FwgIguQf4JC75CBnXAUM5PqeF4fj0nQ==", + "dev": true, + "requires": { + "@babel/types": "^7.5.5", + "jsesc": "^2.5.1", + "lodash": "^4.17.13", + "source-map": "^0.5.0", + "trim-right": "^1.0.1" + }, + "dependencies": { + "jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "dev": true + } + } + }, + "@babel/helper-annotate-as-pure": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.0.0.tgz", + "integrity": "sha512-3UYcJUj9kvSLbLbUIfQTqzcy5VX7GRZ/CCDrnOaZorFFM01aXp1+GJwuFGV4NDDoAS+mOUyHcO6UD/RfqOks3Q==", + "dev": true, + "requires": { + "@babel/types": "^7.0.0" + } + }, + "@babel/helper-function-name": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.1.0.tgz", + "integrity": "sha512-A95XEoCpb3TO+KZzJ4S/5uW5fNe26DjBGqf1o9ucyLyCmi1dXq/B3c8iaWTfBk3VvetUxl16e8tIrd5teOCfGw==", + "dev": true, + "requires": { + "@babel/helper-get-function-arity": "^7.0.0", + "@babel/template": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "@babel/helper-get-function-arity": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.0.0.tgz", + "integrity": "sha512-r2DbJeg4svYvt3HOS74U4eWKsUAMRH01Z1ds1zx8KNTPtpTL5JAsdFv8BNyOpVqdFhHkkRDIg5B4AsxmkjAlmQ==", + "dev": true, + "requires": { + "@babel/types": "^7.0.0" + } + }, + "@babel/helper-module-imports": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.0.0.tgz", + "integrity": "sha512-aP/hlLq01DWNEiDg4Jn23i+CXxW/owM4WpDLFUbpjxe4NS3BhLVZQ5i7E0ZrxuQ/vwekIeciyamgB1UIYxxM6A==", + "dev": true, + "requires": { + "@babel/types": "^7.0.0" + } + }, + "@babel/helper-module-transforms": { + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.5.5.tgz", + "integrity": "sha512-jBeCvETKuJqeiaCdyaheF40aXnnU1+wkSiUs/IQg3tB85up1LyL8x77ClY8qJpuRJUcXQo+ZtdNESmZl4j56Pw==", + "dev": true, + "requires": { + "@babel/helper-module-imports": "^7.0.0", + "@babel/helper-simple-access": "^7.1.0", + "@babel/helper-split-export-declaration": "^7.4.4", + "@babel/template": "^7.4.4", + "@babel/types": "^7.5.5", + "lodash": "^4.17.13" + } + }, + "@babel/helper-plugin-utils": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.0.0.tgz", + "integrity": "sha512-CYAOUCARwExnEixLdB6sDm2dIJ/YgEAKDM1MOeMeZu9Ld/bDgVo8aiWrXwcY7OBh+1Ea2uUcVRcxKk0GJvW7QA==", + "dev": true + }, + "@babel/helper-regex": { + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/@babel/helper-regex/-/helper-regex-7.5.5.tgz", + "integrity": "sha512-CkCYQLkfkiugbRDO8eZn6lRuR8kzZoGXCg3149iTk5se7g6qykSpy3+hELSwquhu+TgHn8nkLiBwHvNX8Hofcw==", + "dev": true, + "requires": { + "lodash": "^4.17.13" + } + }, + "@babel/helper-remap-async-to-generator": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.1.0.tgz", + "integrity": "sha512-3fOK0L+Fdlg8S5al8u/hWE6vhufGSn0bN09xm2LXMy//REAF8kDCrYoOBKYmA8m5Nom+sV9LyLCwrFynA8/slg==", + "dev": true, + "requires": { + "@babel/helper-annotate-as-pure": "^7.0.0", + "@babel/helper-wrap-function": "^7.1.0", + "@babel/template": "^7.1.0", + "@babel/traverse": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "@babel/helper-simple-access": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.1.0.tgz", + "integrity": "sha512-Vk+78hNjRbsiu49zAPALxTb+JUQCz1aolpd8osOF16BGnLtseD21nbHgLPGUwrXEurZgiCOUmvs3ExTu4F5x6w==", + "dev": true, + "requires": { + "@babel/template": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "@babel/helper-split-export-declaration": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.4.4.tgz", + "integrity": "sha512-Ro/XkzLf3JFITkW6b+hNxzZ1n5OQ80NvIUdmHspih1XAhtN3vPTuUFT4eQnela+2MaZ5ulH+iyP513KJrxbN7Q==", + "dev": true, + "requires": { + "@babel/types": "^7.4.4" + } + }, + "@babel/helper-wrap-function": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.2.0.tgz", + "integrity": "sha512-o9fP1BZLLSrYlxYEYyl2aS+Flun5gtjTIG8iln+XuEzQTs0PLagAGSXUcqruJwD5fM48jzIEggCKpIfWTcR7pQ==", + "dev": true, + "requires": { + "@babel/helper-function-name": "^7.1.0", + "@babel/template": "^7.1.0", + "@babel/traverse": "^7.1.0", + "@babel/types": "^7.2.0" + } + }, + "@babel/helpers": { + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.5.5.tgz", + "integrity": "sha512-nRq2BUhxZFnfEn/ciJuhklHvFOqjJUD5wpx+1bxUF2axL9C+v4DE/dmp5sT2dKnpOs4orZWzpAZqlCy8QqE/7g==", + "dev": true, + "requires": { + "@babel/template": "^7.4.4", + "@babel/traverse": "^7.5.5", + "@babel/types": "^7.5.5" + } + }, + "@babel/highlight": { + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.5.0.tgz", + "integrity": "sha512-7dV4eu9gBxoM0dAnj/BCFDW9LFU0zvTrkq0ugM7pnHEgguOEeOz1so2ZghEdzviYzQEED0r4EAgpsBChKy1TRQ==", + "dev": true, + "requires": { + "chalk": "^2.0.0", + "esutils": "^2.0.2", + "js-tokens": "^4.0.0" + }, + "dependencies": { + "js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + } + } + }, + "@babel/parser": { + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.5.5.tgz", + "integrity": "sha512-E5BN68cqR7dhKan1SfqgPGhQ178bkVKpXTPEXnFJBrEt8/DKRZlybmy+IgYLTeN7tp1R5Ccmbm2rBk17sHYU3g==", + "dev": true + }, + "@babel/plugin-proposal-async-generator-functions": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.2.0.tgz", + "integrity": "sha512-+Dfo/SCQqrwx48ptLVGLdE39YtWRuKc/Y9I5Fy0P1DDBB9lsAHpjcEJQt+4IifuSOSTLBKJObJqMvaO1pIE8LQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/helper-remap-async-to-generator": "^7.1.0", + "@babel/plugin-syntax-async-generators": "^7.2.0" + } + }, + "@babel/plugin-proposal-dynamic-import": { + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.5.0.tgz", + "integrity": "sha512-x/iMjggsKTFHYC6g11PL7Qy58IK8H5zqfm9e6hu4z1iH2IRyAp9u9dL80zA6R76yFovETFLKz2VJIC2iIPBuFw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/plugin-syntax-dynamic-import": "^7.2.0" + } + }, + "@babel/plugin-proposal-optional-catch-binding": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.2.0.tgz", + "integrity": "sha512-mgYj3jCcxug6KUcX4OBoOJz3CMrwRfQELPQ5560F70YQUBZB7uac9fqaWamKR1iWUzGiK2t0ygzjTScZnVz75g==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/plugin-syntax-optional-catch-binding": "^7.2.0" + } + }, + "@babel/plugin-syntax-async-generators": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.2.0.tgz", + "integrity": "sha512-1ZrIRBv2t0GSlcwVoQ6VgSLpLgiN/FVQUzt9znxo7v2Ov4jJrs8RY8tv0wvDmFN3qIdMKWrmMMW6yZ0G19MfGg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-syntax-dynamic-import": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.2.0.tgz", + "integrity": "sha512-mVxuJ0YroI/h/tbFTPGZR8cv6ai+STMKNBq0f8hFxsxWjl94qqhsb+wXbpNMDPU3cfR1TIsVFzU3nXyZMqyK4w==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-syntax-optional-catch-binding": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.2.0.tgz", + "integrity": "sha512-bDe4xKNhb0LI7IvZHiA13kff0KEfaGX/Hv4lMA9+7TEc63hMNvfKo6ZFpXhKuEp+II/q35Gc4NoMeDZyaUbj9w==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-transform-dotall-regex": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.4.4.tgz", + "integrity": "sha512-P05YEhRc2h53lZDjRPk/OektxCVevFzZs2Gfjd545Wde3k+yFDbXORgl2e0xpbq8mLcKJ7Idss4fAg0zORN/zg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/helper-regex": "^7.4.4", + "regexpu-core": "^4.5.4" + }, + "dependencies": { + "regexpu-core": { + "version": "4.5.5", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-4.5.5.tgz", + "integrity": "sha512-FpI67+ky9J+cDizQUJlIlNZFKual/lUkFr1AG6zOCpwZ9cLrg8UUVakyUQJD7fCDIe9Z2nwTQJNPyonatNmDFQ==", + "dev": true, + "requires": { + "regenerate": "^1.4.0", + "regenerate-unicode-properties": "^8.1.0", + "regjsgen": "^0.5.0", + "regjsparser": "^0.6.0", + "unicode-match-property-ecmascript": "^1.0.4", + "unicode-match-property-value-ecmascript": "^1.1.0" + } + }, + "regjsgen": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.5.0.tgz", + "integrity": "sha512-RnIrLhrXCX5ow/E5/Mh2O4e/oa1/jW0eaBKTSy3LaCj+M3Bqvm97GWDp2yUtzIs4LEn65zR2yiYGFqb2ApnzDA==", + "dev": true + }, + "regjsparser": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.6.0.tgz", + "integrity": "sha512-RQ7YyokLiQBomUJuUG8iGVvkgOLxwyZM8k6d3q5SAXpg4r5TZJZigKFvC6PpD+qQ98bCDC5YelPeA3EucDoNeQ==", + "dev": true, + "requires": { + "jsesc": "~0.5.0" + } + } + } + }, + "@babel/plugin-transform-modules-commonjs": { + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.5.0.tgz", + "integrity": "sha512-xmHq0B+ytyrWJvQTc5OWAC4ii6Dhr0s22STOoydokG51JjWhyYo5mRPXoi+ZmtHQhZZwuXNN+GG5jy5UZZJxIQ==", + "dev": true, + "requires": { + "@babel/helper-module-transforms": "^7.4.4", + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/helper-simple-access": "^7.1.0", + "babel-plugin-dynamic-import-node": "^2.3.0" + } + }, + "@babel/template": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.4.4.tgz", + "integrity": "sha512-CiGzLN9KgAvgZsnivND7rkA+AeJ9JB0ciPOD4U59GKbQP2iQl+olF1l76kJOupqidozfZ32ghwBEJDhnk9MEcw==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "@babel/parser": "^7.4.4", + "@babel/types": "^7.4.4" + } + }, + "@babel/traverse": { + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.5.5.tgz", + "integrity": "sha512-MqB0782whsfffYfSjH4TM+LMjrJnhCNEDMDIjeTpl+ASaUvxcjoiVCo/sM1GhS1pHOXYfWVCYneLjMckuUxDaQ==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.5.5", + "@babel/generator": "^7.5.5", + "@babel/helper-function-name": "^7.1.0", + "@babel/helper-split-export-declaration": "^7.4.4", + "@babel/parser": "^7.5.5", + "@babel/types": "^7.5.5", + "debug": "^4.1.0", + "globals": "^11.1.0", + "lodash": "^4.17.13" + }, + "dependencies": { + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true + } + } + }, + "@babel/types": { + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.5.5.tgz", + "integrity": "sha512-s63F9nJioLqOlW3UkyMd+BYhXt44YuaFm/VV0VwuteqjYwRrObkU7ra9pY4wAJR3oXi8hJrMcrcJdO/HH33vtw==", + "dev": true, + "requires": { + "esutils": "^2.0.2", + "lodash": "^4.17.13", + "to-fast-properties": "^2.0.0" + }, + "dependencies": { + "to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", + "dev": true + } + } + }, + "@comandeer/babel-plugin-banner": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@comandeer/babel-plugin-banner/-/babel-plugin-banner-5.0.0.tgz", + "integrity": "sha512-sR9Go0U6puXoXyW9UgIiIQhRcJ8jVOvGl4BptUiXAtheMs72WcakZ1udh6J0ZOivr3o8jAM+MTCHLP8FZMbVpQ==", + "dev": true + }, + "@concordance/react": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@concordance/react/-/react-2.0.0.tgz", + "integrity": "sha512-huLSkUuM2/P+U0uy2WwlKuixMsTODD8p4JVQBI4VKeopkiN0C7M3N9XYVawb4M+4spN5RrO/eLhk7KoQX6nsfA==", + "dev": true, + "requires": { + "arrify": "^1.0.1" + }, + "dependencies": { + "arrify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", + "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", + "dev": true + } + } + }, + "@nodelib/fs.scandir": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.1.tgz", + "integrity": "sha512-NT/skIZjgotDSiXs0WqYhgcuBKhUMgfekCmCGtkUAiLqZdOnrdjmZr9wRl3ll64J9NF79uZ4fk16Dx0yMc/Xbg==", + "dev": true, + "requires": { + "@nodelib/fs.stat": "2.0.1", + "run-parallel": "^1.1.9" + } + }, + "@nodelib/fs.stat": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.1.tgz", + "integrity": "sha512-+RqhBlLn6YRBGOIoVYthsG0J9dfpO79eJyN7BYBkZJtfqrBwf2KK+rD/M/yjZR6WBmIhAgOV7S60eCgaSWtbFw==", + "dev": true + }, + "@nodelib/fs.walk": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.2.tgz", + "integrity": "sha512-J/DR3+W12uCzAJkw7niXDcqcKBg6+5G5Q/ZpThpGNzAUz70eOR6RV4XnnSN01qHZiVl0eavoxJsBypQoKsV2QQ==", + "dev": true, + "requires": { + "@nodelib/fs.scandir": "2.1.1", + "fastq": "^1.6.0" + } + }, + "@sindresorhus/is": { + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz", + "integrity": "sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ==", + "dev": true + }, + "@std/esm": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/@std/esm/-/esm-0.8.3.tgz", + "integrity": "sha512-JZigVxIuy2mCkBZWxwS3Wu9eL0lJzR176Rmzb6hLjGIg3yBVBEK4XhEiFX6k5lXDY+e69XAvEVbp59PfUpfpBA==", + "dev": true + }, + "@szmarczak/http-timer": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-1.1.2.tgz", + "integrity": "sha512-XIB2XbzHTN6ieIjfIMV9hlVcfPU26s2vafYWQcZHWXHOxiaRZYEDKEwdl129Zyg50+foYV2jCgtrqSA6qNuNSA==", + "dev": true, + "requires": { + "defer-to-connect": "^1.0.1" + } + }, + "@types/estree": { + "version": "0.0.39", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.39.tgz", + "integrity": "sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==" + }, + "@types/events": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/events/-/events-3.0.0.tgz", + "integrity": "sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g==", + "dev": true + }, + "@types/glob": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.1.tgz", + "integrity": "sha512-1Bh06cbWJUHMC97acuD6UMG29nMt0Aqz1vF3guLfG+kHHJhy3AyohZFFxYk2f7Q1SQIrNwvncxAE0N/9s70F2w==", + "dev": true, + "requires": { + "@types/events": "*", + "@types/minimatch": "*", + "@types/node": "*" + } + }, + "@types/minimatch": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz", + "integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==", + "dev": true + }, + "@types/node": { + "version": "12.7.2", + "resolved": "https://registry.npmjs.org/@types/node/-/node-12.7.2.tgz", + "integrity": "sha512-dyYO+f6ihZEtNPDcWNR1fkoTDf3zAK3lAABDze3mz6POyIercH0lEUawUFXlG8xaQZmm1yEBON/4TsYv/laDYg==", + "dev": true + }, + "@types/resolve": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-0.0.8.tgz", + "integrity": "sha512-auApPaJf3NPfe18hSoJkp8EbZzer2ISk7o8mCC3M9he/a04+gbMF97NkpD2S8riMGvm4BMRI59/SZQSaLTKpsQ==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "acorn": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.0.0.tgz", + "integrity": "sha512-PaF/MduxijYYt7unVGRuds1vBC9bFxbNf+VWqhOClfdgy7RlVkQqt610ig1/yxTgsDIfW1cWDel5EBbOy3jdtQ==", + "dev": true + }, + "acorn-jsx": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.0.1.tgz", + "integrity": "sha512-HJ7CfNHrfJLlNTzIEUTj43LNWGkqpRLxm3YjAlcD0ACydk9XynzYsCBHxut+iqt+1aBXkx9UP/w/ZqMr13XIzg==", + "dev": true + }, + "ajv": { + "version": "6.10.2", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.2.tgz", + "integrity": "sha512-TXtUUEYHuaTEbLZWIKUr5pmBuhDLy+8KYtPYdcV8qC+pOZL+NKqYwvWSRrVXHn+ZmRRAu8vJTAznH7Oag6RVRw==", + "dev": true, + "requires": { + "fast-deep-equal": "^2.0.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "ansi-align": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.0.tgz", + "integrity": "sha512-ZpClVKqXN3RGBmKibdfWzqCY4lnjEuoNzU5T0oEFpfd/z5qJHVarukridD4juLO2FXMiwUQxr9WqQtaYa8XRYw==", + "dev": true, + "requires": { + "string-width": "^3.0.0" + }, + "dependencies": { + "emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "dev": true + }, + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dev": true, + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + } + } + } + }, + "ansi-escapes": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.2.1.tgz", + "integrity": "sha512-Cg3ymMAdN10wOk/VYfLV7KCQyv7EDirJ64500sU7n9UlmioEtDuU5Gd+hj73hXSU/ex7tHJSssmyftDdkMLO8Q==", + "dev": true, + "requires": { + "type-fest": "^0.5.2" + } + }, + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true + }, + "ansi-styles": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.0.0.tgz", + "integrity": "sha512-8zjUtFJ3db/QoPXuuEMloS2AUf79/yeyttJ7Abr3hteopJu9HK8vsgGviGUMq+zyA6cZZO6gAyZoMTF6TgaEjA==", + "dev": true, + "requires": { + "color-convert": "^2.0.0" + }, + "dependencies": { + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + } + } + }, + "anymatch": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.0.3.tgz", + "integrity": "sha512-c6IvoeBECQlMVuYUjSwimnhmztImpErfxJzWZhIQinIvQWoGOnB0dLIgifbPHQt5heS6mNlaZG16f06H3C8t1g==", + "dev": true, + "requires": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + } + }, + "append-transform": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/append-transform/-/append-transform-1.0.0.tgz", + "integrity": "sha512-P009oYkeHyU742iSZJzZZywj4QRJdnTWffaKuJQLablCZ1uz6/cW4yaRgcDaoQ+uwOxxnt0gRUcwfsNP2ri0gw==", + "dev": true, + "requires": { + "default-require-extensions": "^2.0.0" + } + }, + "archy": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz", + "integrity": "sha1-+cjBN1fMHde8N5rHeyxipcKGjEA=", + "dev": true + }, + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "arr-flatten": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", + "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", + "dev": true + }, + "array-find-index": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz", + "integrity": "sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E=", + "dev": true + }, + "array-includes": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.0.3.tgz", + "integrity": "sha1-GEtI9i2S10UrsxsyMWXH+L0CJm0=", + "dev": true, + "requires": { + "define-properties": "^1.1.2", + "es-abstract": "^1.7.0" + } + }, + "array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true + }, + "array-uniq": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-2.1.0.tgz", + "integrity": "sha512-bdHxtev7FN6+MXI1YFW0Q8mQ8dTJc2S8AMfju+ZR77pbg2yAdVyDlwkaUI7Har0LyOMRFPHrJ9lYdyjZZswdlQ==", + "dev": true + }, + "arrify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-2.0.1.tgz", + "integrity": "sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==", + "dev": true + }, + "astral-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz", + "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==", + "dev": true + }, + "ava": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/ava/-/ava-2.3.0.tgz", + "integrity": "sha512-4VaaSnl13vpTZmqW3aMqioSolT0/ozRkjQxTLi3p8wtyRONuX/uLKL3uF0j50w2BNRoLsJqztnkX2h8xeVp2lg==", + "dev": true, + "requires": { + "@ava/babel-preset-stage-4": "^4.0.0", + "@ava/babel-preset-transform-test-files": "^6.0.0", + "@babel/core": "^7.5.5", + "@babel/generator": "^7.5.5", + "@concordance/react": "^2.0.0", + "ansi-escapes": "^4.2.1", + "ansi-styles": "^4.0.0", + "arr-flatten": "^1.1.0", + "array-union": "^2.1.0", + "array-uniq": "^2.1.0", + "arrify": "^2.0.1", + "bluebird": "^3.5.5", + "chalk": "^2.4.2", + "chokidar": "^3.0.2", + "chunkd": "^1.0.0", + "ci-parallel-vars": "^1.0.0", + "clean-stack": "^2.2.0", + "clean-yaml-object": "^0.1.0", + "cli-cursor": "^3.1.0", + "cli-truncate": "^2.0.0", + "code-excerpt": "^2.1.1", + "common-path-prefix": "^1.0.0", + "concordance": "^4.0.0", + "convert-source-map": "^1.6.0", + "currently-unhandled": "^0.4.1", + "debug": "^4.1.1", + "del": "^4.1.1", + "dot-prop": "^5.1.0", + "emittery": "^0.4.1", + "empower-core": "^1.2.0", + "equal-length": "^1.0.0", + "escape-string-regexp": "^2.0.0", + "esm": "^3.2.25", + "figures": "^3.0.0", + "find-up": "^4.1.0", + "get-port": "^5.0.0", + "globby": "^10.0.1", + "ignore-by-default": "^1.0.0", + "import-local": "^3.0.2", + "indent-string": "^4.0.0", + "is-ci": "^2.0.0", + "is-error": "^2.2.2", + "is-observable": "^2.0.0", + "is-plain-object": "^3.0.0", + "is-promise": "^2.1.0", + "lodash": "^4.17.15", + "loud-rejection": "^2.1.0", + "make-dir": "^3.0.0", + "matcher": "^2.0.0", + "md5-hex": "^3.0.1", + "meow": "^5.0.0", + "micromatch": "^4.0.2", + "ms": "^2.1.2", + "observable-to-promise": "^1.0.0", + "ora": "^3.4.0", + "package-hash": "^4.0.0", + "pkg-conf": "^3.1.0", + "plur": "^3.1.1", + "pretty-ms": "^5.0.0", + "require-precompiled": "^0.1.0", + "resolve-cwd": "^3.0.0", + "slash": "^3.0.0", + "source-map-support": "^0.5.13", + "stack-utils": "^1.0.2", + "strip-ansi": "^5.2.0", + "strip-bom-buf": "^2.0.0", + "supertap": "^1.0.0", + "supports-color": "^7.0.0", + "trim-off-newlines": "^1.0.1", + "trim-right": "^1.0.1", + "unique-temp-dir": "^1.0.0", + "update-notifier": "^3.0.1", + "write-file-atomic": "^3.0.0" + }, + "dependencies": { + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "dev": true + }, + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "requires": { + "p-locate": "^4.1.0" + } + }, + "p-limit": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.1.tgz", + "integrity": "sha512-85Tk+90UCVWvbDavCLKPOLC9vvY8OwEX/RtKF+/1OADJMVlFfEHOiMTPVyxg7mk/dKa+ipdHm0OUkTvCpMTuwg==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "requires": { + "p-limit": "^2.2.0" + } + }, + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true + }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true + }, + "slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "source-map-support": { + "version": "0.5.13", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz", + "integrity": "sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==", + "dev": true, + "requires": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + } + } + }, + "babel-code-frame": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", + "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=", + "dev": true, + "requires": { + "chalk": "^1.1.3", + "esutils": "^2.0.2", + "js-tokens": "^3.0.2" + }, + "dependencies": { + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "dev": true + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "requires": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true + } + } + }, + "babel-core": { + "version": "6.26.3", + "resolved": "https://registry.npmjs.org/babel-core/-/babel-core-6.26.3.tgz", + "integrity": "sha512-6jyFLuDmeidKmUEb3NM+/yawG0M2bDZ9Z1qbZP59cyHLz8kYGKYwpJP0UwUKKUiTRNvxfLesJnTedqczP7cTDA==", + "dev": true, + "requires": { + "babel-code-frame": "^6.26.0", + "babel-generator": "^6.26.0", + "babel-helpers": "^6.24.1", + "babel-messages": "^6.23.0", + "babel-register": "^6.26.0", + "babel-runtime": "^6.26.0", + "babel-template": "^6.26.0", + "babel-traverse": "^6.26.0", + "babel-types": "^6.26.0", + "babylon": "^6.18.0", + "convert-source-map": "^1.5.1", + "debug": "^2.6.9", + "json5": "^0.5.1", + "lodash": "^4.17.4", + "minimatch": "^3.0.4", + "path-is-absolute": "^1.0.1", + "private": "^0.1.8", + "slash": "^1.0.0", + "source-map": "^0.5.7" + } + }, + "babel-generator": { + "version": "6.26.1", + "resolved": "https://registry.npmjs.org/babel-generator/-/babel-generator-6.26.1.tgz", + "integrity": "sha512-HyfwY6ApZj7BYTcJURpM5tznulaBvyio7/0d4zFOeMPUmfxkCjHocCuoLa2SAGzBI8AREcH3eP3758F672DppA==", + "dev": true, + "requires": { + "babel-messages": "^6.23.0", + "babel-runtime": "^6.26.0", + "babel-types": "^6.26.0", + "detect-indent": "^4.0.0", + "jsesc": "^1.3.0", + "lodash": "^4.17.4", + "source-map": "^0.5.7", + "trim-right": "^1.0.1" + }, + "dependencies": { + "jsesc": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-1.3.0.tgz", + "integrity": "sha1-RsP+yMGJKxKwgz25vHYiF226s0s=", + "dev": true + } + } + }, + "babel-helper-builder-binary-assignment-operator-visitor": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-builder-binary-assignment-operator-visitor/-/babel-helper-builder-binary-assignment-operator-visitor-6.24.1.tgz", + "integrity": "sha1-zORReto1b0IgvK6KAsKzRvmlZmQ=", + "dev": true, + "requires": { + "babel-helper-explode-assignable-expression": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" + } + }, + "babel-helper-call-delegate": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-call-delegate/-/babel-helper-call-delegate-6.24.1.tgz", + "integrity": "sha1-7Oaqzdx25Bw0YfiL/Fdb0Nqi340=", + "dev": true, + "requires": { + "babel-helper-hoist-variables": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" + } + }, + "babel-helper-define-map": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-helper-define-map/-/babel-helper-define-map-6.26.0.tgz", + "integrity": "sha1-pfVtq0GiX5fstJjH66ypgZ+Vvl8=", + "dev": true, + "requires": { + "babel-helper-function-name": "^6.24.1", + "babel-runtime": "^6.26.0", + "babel-types": "^6.26.0", + "lodash": "^4.17.4" + } + }, + "babel-helper-evaluate-path": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/babel-helper-evaluate-path/-/babel-helper-evaluate-path-0.5.0.tgz", + "integrity": "sha512-mUh0UhS607bGh5wUMAQfOpt2JX2ThXMtppHRdRU1kL7ZLRWIXxoV2UIV1r2cAeeNeU1M5SB5/RSUgUxrK8yOkA==", + "dev": true + }, + "babel-helper-explode-assignable-expression": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-explode-assignable-expression/-/babel-helper-explode-assignable-expression-6.24.1.tgz", + "integrity": "sha1-8luCz33BBDPFX3BZLVdGQArCLKo=", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" + } + }, + "babel-helper-flip-expressions": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/babel-helper-flip-expressions/-/babel-helper-flip-expressions-0.4.3.tgz", + "integrity": "sha1-NpZzahKKwYvCUlS19AoizrPB0/0=", + "dev": true + }, + "babel-helper-function-name": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-function-name/-/babel-helper-function-name-6.24.1.tgz", + "integrity": "sha1-00dbjAPtmCQqJbSDUasYOZ01gKk=", + "dev": true, + "requires": { + "babel-helper-get-function-arity": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" + } + }, + "babel-helper-get-function-arity": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-get-function-arity/-/babel-helper-get-function-arity-6.24.1.tgz", + "integrity": "sha1-j3eCqpNAfEHTqlCQj4mwMbG2hT0=", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" + } + }, + "babel-helper-hoist-variables": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-hoist-variables/-/babel-helper-hoist-variables-6.24.1.tgz", + "integrity": "sha1-HssnaJydJVE+rbyZFKc/VAi+enY=", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" + } + }, + "babel-helper-is-nodes-equiv": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/babel-helper-is-nodes-equiv/-/babel-helper-is-nodes-equiv-0.0.1.tgz", + "integrity": "sha1-NOmzALFHnd2Y7HfqC76TQt/jloQ=", + "dev": true + }, + "babel-helper-is-void-0": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/babel-helper-is-void-0/-/babel-helper-is-void-0-0.4.3.tgz", + "integrity": "sha1-fZwBtFYee5Xb2g9u7kj1tg5nMT4=", + "dev": true + }, + "babel-helper-mark-eval-scopes": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/babel-helper-mark-eval-scopes/-/babel-helper-mark-eval-scopes-0.4.3.tgz", + "integrity": "sha1-0kSjvvmESHJgP/tG4izorN9VFWI=", + "dev": true + }, + "babel-helper-optimise-call-expression": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-optimise-call-expression/-/babel-helper-optimise-call-expression-6.24.1.tgz", + "integrity": "sha1-96E0J7qfc/j0+pk8VKl4gtEkQlc=", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" + } + }, + "babel-helper-regex": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-helper-regex/-/babel-helper-regex-6.26.0.tgz", + "integrity": "sha1-MlxZ+QL4LyS3T6zu0DY5VPZJXnI=", + "dev": true, + "requires": { + "babel-runtime": "^6.26.0", + "babel-types": "^6.26.0", + "lodash": "^4.17.4" + } + }, + "babel-helper-remap-async-to-generator": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-remap-async-to-generator/-/babel-helper-remap-async-to-generator-6.24.1.tgz", + "integrity": "sha1-XsWBgnrXI/7N04HxySg5BnbkVRs=", + "dev": true, + "requires": { + "babel-helper-function-name": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" + } + }, + "babel-helper-remove-or-void": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/babel-helper-remove-or-void/-/babel-helper-remove-or-void-0.4.3.tgz", + "integrity": "sha1-pPA7QAd6D/6I5F0HAQ3uJB/1rmA=", + "dev": true + }, + "babel-helper-replace-supers": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-replace-supers/-/babel-helper-replace-supers-6.24.1.tgz", + "integrity": "sha1-v22/5Dk40XNpohPKiov3S2qQqxo=", + "dev": true, + "requires": { + "babel-helper-optimise-call-expression": "^6.24.1", + "babel-messages": "^6.23.0", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" + } + }, + "babel-helper-to-multiple-sequence-expressions": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/babel-helper-to-multiple-sequence-expressions/-/babel-helper-to-multiple-sequence-expressions-0.5.0.tgz", + "integrity": "sha512-m2CvfDW4+1qfDdsrtf4dwOslQC3yhbgyBFptncp4wvtdrDHqueW7slsYv4gArie056phvQFhT2nRcGS4bnm6mA==", + "dev": true + }, + "babel-helpers": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helpers/-/babel-helpers-6.24.1.tgz", + "integrity": "sha1-NHHenK7DiOXIUOWX5Yom3fN2ArI=", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1" + } + }, + "babel-messages": { + "version": "6.23.0", + "resolved": "https://registry.npmjs.org/babel-messages/-/babel-messages-6.23.0.tgz", + "integrity": "sha1-8830cDhYA1sqKVHG7F7fbGLyYw4=", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-check-es2015-constants": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-check-es2015-constants/-/babel-plugin-check-es2015-constants-6.22.0.tgz", + "integrity": "sha1-NRV7EBQm/S/9PaP3XH0ekYNbv4o=", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-dynamic-import-node": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.0.tgz", + "integrity": "sha512-o6qFkpeQEBxcqt0XYlWzAVxNCSCZdUgcR8IRlhD/8DylxjjO4foPcvTW0GGKa/cVt3rvxZ7o5ippJ+/0nvLhlQ==", + "dev": true, + "requires": { + "object.assign": "^4.1.0" + } + }, + "babel-plugin-espower": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/babel-plugin-espower/-/babel-plugin-espower-3.0.1.tgz", + "integrity": "sha512-Ms49U7VIAtQ/TtcqRbD6UBmJBUCSxiC3+zPc+eGqxKUIFO1lTshyEDRUjhoAbd2rWfwYf3cZ62oXozrd8W6J0A==", + "dev": true, + "requires": { + "@babel/generator": "^7.0.0", + "@babel/parser": "^7.0.0", + "call-matcher": "^1.0.0", + "core-js": "^2.0.0", + "espower-location-detector": "^1.0.0", + "espurify": "^1.6.0", + "estraverse": "^4.1.1" + } + }, + "babel-plugin-minify-builtins": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/babel-plugin-minify-builtins/-/babel-plugin-minify-builtins-0.5.0.tgz", + "integrity": "sha512-wpqbN7Ov5hsNwGdzuzvFcjgRlzbIeVv1gMIlICbPj0xkexnfoIDe7q+AZHMkQmAE/F9R5jkrB6TLfTegImlXag==", + "dev": true + }, + "babel-plugin-minify-constant-folding": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/babel-plugin-minify-constant-folding/-/babel-plugin-minify-constant-folding-0.5.0.tgz", + "integrity": "sha512-Vj97CTn/lE9hR1D+jKUeHfNy+m1baNiJ1wJvoGyOBUx7F7kJqDZxr9nCHjO/Ad+irbR3HzR6jABpSSA29QsrXQ==", + "dev": true, + "requires": { + "babel-helper-evaluate-path": "^0.5.0" + } + }, + "babel-plugin-minify-dead-code-elimination": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/babel-plugin-minify-dead-code-elimination/-/babel-plugin-minify-dead-code-elimination-0.5.1.tgz", + "integrity": "sha512-x8OJOZIrRmQBcSqxBcLbMIK8uPmTvNWPXH2bh5MDCW1latEqYiRMuUkPImKcfpo59pTUB2FT7HfcgtG8ZlR5Qg==", + "dev": true, + "requires": { + "babel-helper-evaluate-path": "^0.5.0", + "babel-helper-mark-eval-scopes": "^0.4.3", + "babel-helper-remove-or-void": "^0.4.3", + "lodash": "^4.17.11" + } + }, + "babel-plugin-minify-flip-comparisons": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/babel-plugin-minify-flip-comparisons/-/babel-plugin-minify-flip-comparisons-0.4.3.tgz", + "integrity": "sha1-AMqHDLjxO0XAOLPB68DyJyk8llo=", + "dev": true, + "requires": { + "babel-helper-is-void-0": "^0.4.3" + } + }, + "babel-plugin-minify-guarded-expressions": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/babel-plugin-minify-guarded-expressions/-/babel-plugin-minify-guarded-expressions-0.4.4.tgz", + "integrity": "sha512-RMv0tM72YuPPfLT9QLr3ix9nwUIq+sHT6z8Iu3sLbqldzC1Dls8DPCywzUIzkTx9Zh1hWX4q/m9BPoPed9GOfA==", + "dev": true, + "requires": { + "babel-helper-evaluate-path": "^0.5.0", + "babel-helper-flip-expressions": "^0.4.3" + } + }, + "babel-plugin-minify-infinity": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/babel-plugin-minify-infinity/-/babel-plugin-minify-infinity-0.4.3.tgz", + "integrity": "sha1-37h2obCKBldjhO8/kuZTumB7Oco=", + "dev": true + }, + "babel-plugin-minify-mangle-names": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/babel-plugin-minify-mangle-names/-/babel-plugin-minify-mangle-names-0.5.0.tgz", + "integrity": "sha512-3jdNv6hCAw6fsX1p2wBGPfWuK69sfOjfd3zjUXkbq8McbohWy23tpXfy5RnToYWggvqzuMOwlId1PhyHOfgnGw==", + "dev": true, + "requires": { + "babel-helper-mark-eval-scopes": "^0.4.3" + } + }, + "babel-plugin-minify-numeric-literals": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/babel-plugin-minify-numeric-literals/-/babel-plugin-minify-numeric-literals-0.4.3.tgz", + "integrity": "sha1-jk/VYcefeAEob/YOjF/Z3u6TwLw=", + "dev": true + }, + "babel-plugin-minify-replace": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/babel-plugin-minify-replace/-/babel-plugin-minify-replace-0.5.0.tgz", + "integrity": "sha512-aXZiaqWDNUbyNNNpWs/8NyST+oU7QTpK7J9zFEFSA0eOmtUNMU3fczlTTTlnCxHmq/jYNFEmkkSG3DDBtW3Y4Q==", + "dev": true + }, + "babel-plugin-minify-simplify": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/babel-plugin-minify-simplify/-/babel-plugin-minify-simplify-0.5.1.tgz", + "integrity": "sha512-OSYDSnoCxP2cYDMk9gxNAed6uJDiDz65zgL6h8d3tm8qXIagWGMLWhqysT6DY3Vs7Fgq7YUDcjOomhVUb+xX6A==", + "dev": true, + "requires": { + "babel-helper-evaluate-path": "^0.5.0", + "babel-helper-flip-expressions": "^0.4.3", + "babel-helper-is-nodes-equiv": "^0.0.1", + "babel-helper-to-multiple-sequence-expressions": "^0.5.0" + } + }, + "babel-plugin-minify-type-constructors": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/babel-plugin-minify-type-constructors/-/babel-plugin-minify-type-constructors-0.4.3.tgz", + "integrity": "sha1-G8bxW4f3qxCF1CszC3F2V6IVZQA=", + "dev": true, + "requires": { + "babel-helper-is-void-0": "^0.4.3" + } + }, + "babel-plugin-syntax-async-functions": { + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-async-functions/-/babel-plugin-syntax-async-functions-6.13.0.tgz", + "integrity": "sha1-ytnK0RkbWtY0vzCuCHI5HgZHvpU=", + "dev": true + }, + "babel-plugin-syntax-exponentiation-operator": { + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-exponentiation-operator/-/babel-plugin-syntax-exponentiation-operator-6.13.0.tgz", + "integrity": "sha1-nufoM3KQ2pUoggGmpX9BcDF4MN4=", + "dev": true + }, + "babel-plugin-syntax-trailing-function-commas": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-trailing-function-commas/-/babel-plugin-syntax-trailing-function-commas-6.22.0.tgz", + "integrity": "sha1-ugNgk3+NBuQBgKQ/4NVhb/9TLPM=", + "dev": true + }, + "babel-plugin-transform-async-to-generator": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-async-to-generator/-/babel-plugin-transform-async-to-generator-6.24.1.tgz", + "integrity": "sha1-ZTbjeK/2yx1VF6wOQOs+n8jQh2E=", + "dev": true, + "requires": { + "babel-helper-remap-async-to-generator": "^6.24.1", + "babel-plugin-syntax-async-functions": "^6.8.0", + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-transform-es2015-arrow-functions": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-arrow-functions/-/babel-plugin-transform-es2015-arrow-functions-6.22.0.tgz", + "integrity": "sha1-RSaSy3EdX3ncf4XkQM5BufJE0iE=", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-transform-es2015-block-scoped-functions": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-block-scoped-functions/-/babel-plugin-transform-es2015-block-scoped-functions-6.22.0.tgz", + "integrity": "sha1-u8UbSflk1wy42OC5ToICRs46YUE=", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-transform-es2015-block-scoping": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-block-scoping/-/babel-plugin-transform-es2015-block-scoping-6.26.0.tgz", + "integrity": "sha1-1w9SmcEwjQXBL0Y4E7CgnnOxiV8=", + "dev": true, + "requires": { + "babel-runtime": "^6.26.0", + "babel-template": "^6.26.0", + "babel-traverse": "^6.26.0", + "babel-types": "^6.26.0", + "lodash": "^4.17.4" + } + }, + "babel-plugin-transform-es2015-classes": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-classes/-/babel-plugin-transform-es2015-classes-6.24.1.tgz", + "integrity": "sha1-WkxYpQyclGHlZLSyo7+ryXolhNs=", + "dev": true, + "requires": { + "babel-helper-define-map": "^6.24.1", + "babel-helper-function-name": "^6.24.1", + "babel-helper-optimise-call-expression": "^6.24.1", + "babel-helper-replace-supers": "^6.24.1", + "babel-messages": "^6.23.0", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" + } + }, + "babel-plugin-transform-es2015-computed-properties": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-computed-properties/-/babel-plugin-transform-es2015-computed-properties-6.24.1.tgz", + "integrity": "sha1-b+Ko0WiV1WNPTNmZttNICjCBWbM=", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1" + } + }, + "babel-plugin-transform-es2015-destructuring": { + "version": "6.23.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-destructuring/-/babel-plugin-transform-es2015-destructuring-6.23.0.tgz", + "integrity": "sha1-mXux8auWf2gtKwh2/jWNYOdlxW0=", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-transform-es2015-duplicate-keys": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-duplicate-keys/-/babel-plugin-transform-es2015-duplicate-keys-6.24.1.tgz", + "integrity": "sha1-c+s9MQypaePvnskcU3QabxV2Qj4=", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" + } + }, + "babel-plugin-transform-es2015-for-of": { + "version": "6.23.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-for-of/-/babel-plugin-transform-es2015-for-of-6.23.0.tgz", + "integrity": "sha1-9HyVsrYT3x0+zC/bdXNiPHUkhpE=", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-transform-es2015-function-name": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-function-name/-/babel-plugin-transform-es2015-function-name-6.24.1.tgz", + "integrity": "sha1-g0yJhTvDaxrw86TF26qU/Y6sqos=", + "dev": true, + "requires": { + "babel-helper-function-name": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" + } + }, + "babel-plugin-transform-es2015-literals": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-literals/-/babel-plugin-transform-es2015-literals-6.22.0.tgz", + "integrity": "sha1-T1SgLWzWbPkVKAAZox0xklN3yi4=", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-transform-es2015-modules-amd": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-amd/-/babel-plugin-transform-es2015-modules-amd-6.24.1.tgz", + "integrity": "sha1-Oz5UAXI5hC1tGcMBHEvS8AoA0VQ=", + "dev": true, + "requires": { + "babel-plugin-transform-es2015-modules-commonjs": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1" + } + }, + "babel-plugin-transform-es2015-modules-commonjs": { + "version": "6.26.2", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-commonjs/-/babel-plugin-transform-es2015-modules-commonjs-6.26.2.tgz", + "integrity": "sha512-CV9ROOHEdrjcwhIaJNBGMBCodN+1cfkwtM1SbUHmvyy35KGT7fohbpOxkE2uLz1o6odKK2Ck/tz47z+VqQfi9Q==", + "dev": true, + "requires": { + "babel-plugin-transform-strict-mode": "^6.24.1", + "babel-runtime": "^6.26.0", + "babel-template": "^6.26.0", + "babel-types": "^6.26.0" + } + }, + "babel-plugin-transform-es2015-modules-systemjs": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-systemjs/-/babel-plugin-transform-es2015-modules-systemjs-6.24.1.tgz", + "integrity": "sha1-/4mhQrkRmpBhlfXxBuzzBdlAfSM=", + "dev": true, + "requires": { + "babel-helper-hoist-variables": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1" + } + }, + "babel-plugin-transform-es2015-modules-umd": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-umd/-/babel-plugin-transform-es2015-modules-umd-6.24.1.tgz", + "integrity": "sha1-rJl+YoXNGO1hdq22B9YCNErThGg=", + "dev": true, + "requires": { + "babel-plugin-transform-es2015-modules-amd": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1" + } + }, + "babel-plugin-transform-es2015-object-super": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-object-super/-/babel-plugin-transform-es2015-object-super-6.24.1.tgz", + "integrity": "sha1-JM72muIcuDp/hgPa0CH1cusnj40=", + "dev": true, + "requires": { + "babel-helper-replace-supers": "^6.24.1", + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-transform-es2015-parameters": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-parameters/-/babel-plugin-transform-es2015-parameters-6.24.1.tgz", + "integrity": "sha1-V6w1GrScrxSpfNE7CfZv3wpiXys=", + "dev": true, + "requires": { + "babel-helper-call-delegate": "^6.24.1", + "babel-helper-get-function-arity": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" + } + }, + "babel-plugin-transform-es2015-shorthand-properties": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-shorthand-properties/-/babel-plugin-transform-es2015-shorthand-properties-6.24.1.tgz", + "integrity": "sha1-JPh11nIch2YbvZmkYi5R8U3jiqA=", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" + } + }, + "babel-plugin-transform-es2015-spread": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-spread/-/babel-plugin-transform-es2015-spread-6.22.0.tgz", + "integrity": "sha1-1taKmfia7cRTbIGlQujdnxdG+NE=", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-transform-es2015-sticky-regex": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-sticky-regex/-/babel-plugin-transform-es2015-sticky-regex-6.24.1.tgz", + "integrity": "sha1-AMHNsaynERLN8M9hJsLta0V8zbw=", + "dev": true, + "requires": { + "babel-helper-regex": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" + } + }, + "babel-plugin-transform-es2015-template-literals": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-template-literals/-/babel-plugin-transform-es2015-template-literals-6.22.0.tgz", + "integrity": "sha1-qEs0UPfp+PH2g51taH2oS7EjbY0=", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-transform-es2015-typeof-symbol": { + "version": "6.23.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-typeof-symbol/-/babel-plugin-transform-es2015-typeof-symbol-6.23.0.tgz", + "integrity": "sha1-3sCfHN3/lLUqxz1QXITfWdzOs3I=", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-transform-es2015-unicode-regex": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-unicode-regex/-/babel-plugin-transform-es2015-unicode-regex-6.24.1.tgz", + "integrity": "sha1-04sS9C6nMj9yk4fxinxa4frrNek=", + "dev": true, + "requires": { + "babel-helper-regex": "^6.24.1", + "babel-runtime": "^6.22.0", + "regexpu-core": "^2.0.0" + } + }, + "babel-plugin-transform-exponentiation-operator": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-exponentiation-operator/-/babel-plugin-transform-exponentiation-operator-6.24.1.tgz", + "integrity": "sha1-KrDJx/MJj6SJB3cruBP+QejeOg4=", + "dev": true, + "requires": { + "babel-helper-builder-binary-assignment-operator-visitor": "^6.24.1", + "babel-plugin-syntax-exponentiation-operator": "^6.8.0", + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-transform-inline-consecutive-adds": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-inline-consecutive-adds/-/babel-plugin-transform-inline-consecutive-adds-0.4.3.tgz", + "integrity": "sha1-Mj1Ho+pjqDp6w8gRro5pQfrysNE=", + "dev": true + }, + "babel-plugin-transform-member-expression-literals": { + "version": "6.9.4", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-member-expression-literals/-/babel-plugin-transform-member-expression-literals-6.9.4.tgz", + "integrity": "sha1-NwOcmgwzE6OUlfqsL/OmtbnQOL8=", + "dev": true + }, + "babel-plugin-transform-merge-sibling-variables": { + "version": "6.9.4", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-merge-sibling-variables/-/babel-plugin-transform-merge-sibling-variables-6.9.4.tgz", + "integrity": "sha1-hbQi/DN3tEnJ0c3kQIcgNTJAHa4=", + "dev": true + }, + "babel-plugin-transform-minify-booleans": { + "version": "6.9.4", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-minify-booleans/-/babel-plugin-transform-minify-booleans-6.9.4.tgz", + "integrity": "sha1-rLs+VqNVXdI5KOS1gtKFFi3SsZg=", + "dev": true + }, + "babel-plugin-transform-property-literals": { + "version": "6.9.4", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-property-literals/-/babel-plugin-transform-property-literals-6.9.4.tgz", + "integrity": "sha1-mMHSHiVXNlc/k+zlRFn2ziSYXTk=", + "dev": true, + "requires": { + "esutils": "^2.0.2" + } + }, + "babel-plugin-transform-regenerator": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-regenerator/-/babel-plugin-transform-regenerator-6.26.0.tgz", + "integrity": "sha1-4HA2lvveJ/Cj78rPi03KL3s6jy8=", + "dev": true, + "requires": { + "regenerator-transform": "^0.10.0" + } + }, + "babel-plugin-transform-regexp-constructors": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-regexp-constructors/-/babel-plugin-transform-regexp-constructors-0.4.3.tgz", + "integrity": "sha1-WLd3W2OvzzMyj66aX4j71PsLSWU=", + "dev": true + }, + "babel-plugin-transform-remove-console": { + "version": "6.9.4", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-remove-console/-/babel-plugin-transform-remove-console-6.9.4.tgz", + "integrity": "sha1-uYA2DAZzhOJLNXpYjYB9PINSd4A=", + "dev": true + }, + "babel-plugin-transform-remove-debugger": { + "version": "6.9.4", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-remove-debugger/-/babel-plugin-transform-remove-debugger-6.9.4.tgz", + "integrity": "sha1-QrcnYxyXl44estGZp67IShgznvI=", + "dev": true + }, + "babel-plugin-transform-remove-undefined": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-remove-undefined/-/babel-plugin-transform-remove-undefined-0.5.0.tgz", + "integrity": "sha512-+M7fJYFaEE/M9CXa0/IRkDbiV3wRELzA1kKQFCJ4ifhrzLKn/9VCCgj9OFmYWwBd8IB48YdgPkHYtbYq+4vtHQ==", + "dev": true, + "requires": { + "babel-helper-evaluate-path": "^0.5.0" + } + }, + "babel-plugin-transform-simplify-comparison-operators": { + "version": "6.9.4", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-simplify-comparison-operators/-/babel-plugin-transform-simplify-comparison-operators-6.9.4.tgz", + "integrity": "sha1-9ir+CWyrDh9ootdT/fKDiIRxzrk=", + "dev": true + }, + "babel-plugin-transform-strict-mode": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-strict-mode/-/babel-plugin-transform-strict-mode-6.24.1.tgz", + "integrity": "sha1-1fr3qleKZbvlkc9e2uBKDGcCB1g=", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" + } + }, + "babel-plugin-transform-undefined-to-void": { + "version": "6.9.4", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-undefined-to-void/-/babel-plugin-transform-undefined-to-void-6.9.4.tgz", + "integrity": "sha1-viQcqBQEAwZ4t0hxcyK4nQyP4oA=", + "dev": true + }, + "babel-preset-env": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/babel-preset-env/-/babel-preset-env-1.7.0.tgz", + "integrity": "sha512-9OR2afuKDneX2/q2EurSftUYM0xGu4O2D9adAhVfADDhrYDaxXV0rBbevVYoY9n6nyX1PmQW/0jtpJvUNr9CHg==", + "dev": true, + "requires": { + "babel-plugin-check-es2015-constants": "^6.22.0", + "babel-plugin-syntax-trailing-function-commas": "^6.22.0", + "babel-plugin-transform-async-to-generator": "^6.22.0", + "babel-plugin-transform-es2015-arrow-functions": "^6.22.0", + "babel-plugin-transform-es2015-block-scoped-functions": "^6.22.0", + "babel-plugin-transform-es2015-block-scoping": "^6.23.0", + "babel-plugin-transform-es2015-classes": "^6.23.0", + "babel-plugin-transform-es2015-computed-properties": "^6.22.0", + "babel-plugin-transform-es2015-destructuring": "^6.23.0", + "babel-plugin-transform-es2015-duplicate-keys": "^6.22.0", + "babel-plugin-transform-es2015-for-of": "^6.23.0", + "babel-plugin-transform-es2015-function-name": "^6.22.0", + "babel-plugin-transform-es2015-literals": "^6.22.0", + "babel-plugin-transform-es2015-modules-amd": "^6.22.0", + "babel-plugin-transform-es2015-modules-commonjs": "^6.23.0", + "babel-plugin-transform-es2015-modules-systemjs": "^6.23.0", + "babel-plugin-transform-es2015-modules-umd": "^6.23.0", + "babel-plugin-transform-es2015-object-super": "^6.22.0", + "babel-plugin-transform-es2015-parameters": "^6.23.0", + "babel-plugin-transform-es2015-shorthand-properties": "^6.22.0", + "babel-plugin-transform-es2015-spread": "^6.22.0", + "babel-plugin-transform-es2015-sticky-regex": "^6.22.0", + "babel-plugin-transform-es2015-template-literals": "^6.22.0", + "babel-plugin-transform-es2015-typeof-symbol": "^6.23.0", + "babel-plugin-transform-es2015-unicode-regex": "^6.22.0", + "babel-plugin-transform-exponentiation-operator": "^6.22.0", + "babel-plugin-transform-regenerator": "^6.22.0", + "browserslist": "^3.2.6", + "invariant": "^2.2.2", + "semver": "^5.3.0" + } + }, + "babel-preset-minify": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/babel-preset-minify/-/babel-preset-minify-0.5.1.tgz", + "integrity": "sha512-1IajDumYOAPYImkHbrKeiN5AKKP9iOmRoO2IPbIuVp0j2iuCcj0n7P260z38siKMZZ+85d3mJZdtW8IgOv+Tzg==", + "dev": true, + "requires": { + "babel-plugin-minify-builtins": "^0.5.0", + "babel-plugin-minify-constant-folding": "^0.5.0", + "babel-plugin-minify-dead-code-elimination": "^0.5.1", + "babel-plugin-minify-flip-comparisons": "^0.4.3", + "babel-plugin-minify-guarded-expressions": "^0.4.4", + "babel-plugin-minify-infinity": "^0.4.3", + "babel-plugin-minify-mangle-names": "^0.5.0", + "babel-plugin-minify-numeric-literals": "^0.4.3", + "babel-plugin-minify-replace": "^0.5.0", + "babel-plugin-minify-simplify": "^0.5.1", + "babel-plugin-minify-type-constructors": "^0.4.3", + "babel-plugin-transform-inline-consecutive-adds": "^0.4.3", + "babel-plugin-transform-member-expression-literals": "^6.9.4", + "babel-plugin-transform-merge-sibling-variables": "^6.9.4", + "babel-plugin-transform-minify-booleans": "^6.9.4", + "babel-plugin-transform-property-literals": "^6.9.4", + "babel-plugin-transform-regexp-constructors": "^0.4.3", + "babel-plugin-transform-remove-console": "^6.9.4", + "babel-plugin-transform-remove-debugger": "^6.9.4", + "babel-plugin-transform-remove-undefined": "^0.5.0", + "babel-plugin-transform-simplify-comparison-operators": "^6.9.4", + "babel-plugin-transform-undefined-to-void": "^6.9.4", + "lodash": "^4.17.11" + } + }, + "babel-register": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-register/-/babel-register-6.26.0.tgz", + "integrity": "sha1-btAhFz4vy0htestFxgCahW9kcHE=", + "dev": true, + "requires": { + "babel-core": "^6.26.0", + "babel-runtime": "^6.26.0", + "core-js": "^2.5.0", + "home-or-tmp": "^2.0.0", + "lodash": "^4.17.4", + "mkdirp": "^0.5.1", + "source-map-support": "^0.4.15" + } + }, + "babel-runtime": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", + "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", + "dev": true, + "requires": { + "core-js": "^2.4.0", + "regenerator-runtime": "^0.11.0" + } + }, + "babel-template": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-template/-/babel-template-6.26.0.tgz", + "integrity": "sha1-3gPi0WOWsGn0bdn/+FIfsaDjXgI=", + "dev": true, + "requires": { + "babel-runtime": "^6.26.0", + "babel-traverse": "^6.26.0", + "babel-types": "^6.26.0", + "babylon": "^6.18.0", + "lodash": "^4.17.4" + } + }, + "babel-traverse": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-traverse/-/babel-traverse-6.26.0.tgz", + "integrity": "sha1-RqnL1+3MYsjlwGTi0tjQ9ANXZu4=", + "dev": true, + "requires": { + "babel-code-frame": "^6.26.0", + "babel-messages": "^6.23.0", + "babel-runtime": "^6.26.0", + "babel-types": "^6.26.0", + "babylon": "^6.18.0", + "debug": "^2.6.8", + "globals": "^9.18.0", + "invariant": "^2.2.2", + "lodash": "^4.17.4" + } + }, + "babel-types": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-types/-/babel-types-6.26.0.tgz", + "integrity": "sha1-o7Bz+Uq0nrb6Vc1lInozQ4BjJJc=", + "dev": true, + "requires": { + "babel-runtime": "^6.26.0", + "esutils": "^2.0.2", + "lodash": "^4.17.4", + "to-fast-properties": "^1.0.3" + } + }, + "babylon": { + "version": "6.18.0", + "resolved": "https://registry.npmjs.org/babylon/-/babylon-6.18.0.tgz", + "integrity": "sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ==", + "dev": true + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", + "dev": true + }, + "binary-extensions": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.0.0.tgz", + "integrity": "sha512-Phlt0plgpIIBOGTT/ehfFnbNlfsDEiqmzE2KRXoX1bLIlir4X/MR+zSyBEkL05ffWgnRSf/DXv+WrUAVr93/ow==", + "dev": true + }, + "bluebird": { + "version": "3.5.5", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.5.tgz", + "integrity": "sha512-5am6HnnfN+urzt4yfg7IgTbotDjIT/u8AJpEt0sIU9FtXfVeezXAPKswrG+xKUCOYAINpSdgZVDU6QFh+cuH3w==", + "dev": true + }, + "blueimp-md5": { + "version": "2.11.1", + "resolved": "https://registry.npmjs.org/blueimp-md5/-/blueimp-md5-2.11.1.tgz", + "integrity": "sha512-4UiOAmql2XO0Sws07OVzYdCKK0K2Va5g6AVgYXoGhEQiKrdSOefjUCm1frPk6E+xiIOHRqaFg+TUGo7cClKg5g==", + "dev": true + }, + "boxen": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/boxen/-/boxen-3.2.0.tgz", + "integrity": "sha512-cU4J/+NodM3IHdSL2yN8bqYqnmlBTidDR4RC7nJs61ZmtGz8VZzM3HLQX0zY5mrSmPtR3xWwsq2jOUQqFZN8+A==", + "dev": true, + "requires": { + "ansi-align": "^3.0.0", + "camelcase": "^5.3.1", + "chalk": "^2.4.2", + "cli-boxes": "^2.2.0", + "string-width": "^3.0.0", + "term-size": "^1.2.0", + "type-fest": "^0.3.0", + "widest-line": "^2.0.0" + }, + "dependencies": { + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true + }, + "emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "dev": true + }, + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dev": true, + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + } + }, + "type-fest": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.3.1.tgz", + "integrity": "sha512-cUGJnCdr4STbePCgqNFbpVNCepa+kAVohJs1sLhxzdH+gnEoOd8VhbYa7pD3zZYGiURWM2xzEII3fQcRizDkYQ==", + "dev": true + } + } + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "requires": { + "fill-range": "^7.0.1" + } + }, + "browserslist": { + "version": "3.2.8", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-3.2.8.tgz", + "integrity": "sha512-WHVocJYavUwVgVViC0ORikPHQquXwVh939TaelZ4WDqpWgTX/FsGhl/+P4qBUAGcRvtOgDgC+xftNWWp2RUTAQ==", + "dev": true, + "requires": { + "caniuse-lite": "^1.0.30000844", + "electron-to-chromium": "^1.3.47" + } + }, + "buffer-from": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", + "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", + "dev": true + }, + "builtin-modules": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.1.0.tgz", + "integrity": "sha512-k0KL0aWZuBt2lrxrcASWDfwOLMnodeQjodT/1SxEQAXsHANgo6ZC/VEaSEHCXt7aSTZ4/4H5LKa+tBXmW7Vtvw==", + "dev": true + }, + "cacheable-request": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-6.1.0.tgz", + "integrity": "sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg==", + "dev": true, + "requires": { + "clone-response": "^1.0.2", + "get-stream": "^5.1.0", + "http-cache-semantics": "^4.0.0", + "keyv": "^3.0.0", + "lowercase-keys": "^2.0.0", + "normalize-url": "^4.1.0", + "responselike": "^1.0.2" + }, + "dependencies": { + "get-stream": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.1.0.tgz", + "integrity": "sha512-EXr1FOzrzTfGeL0gQdeFEvOMm2mzMOglyiOXSTpPC+iAjAKftbr3jpCMWynogwYnM+eSj9sHGc6wjIcDvYiygw==", + "dev": true, + "requires": { + "pump": "^3.0.0" + } + }, + "lowercase-keys": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", + "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", + "dev": true + } + } + }, + "caching-transform": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/caching-transform/-/caching-transform-3.0.2.tgz", + "integrity": "sha512-Mtgcv3lh3U0zRii/6qVgQODdPA4G3zhG+jtbCWj39RXuUFTMzH0vcdMtaJS1jPowd+It2Pqr6y3NJMQqOqCE2w==", + "dev": true, + "requires": { + "hasha": "^3.0.0", + "make-dir": "^2.0.0", + "package-hash": "^3.0.0", + "write-file-atomic": "^2.4.2" + }, + "dependencies": { + "hasha": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/hasha/-/hasha-3.0.0.tgz", + "integrity": "sha1-UqMvq4Vp1BymmmH/GiFPjrfIvTk=", + "dev": true, + "requires": { + "is-stream": "^1.0.1" + } + }, + "make-dir": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", + "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", + "dev": true, + "requires": { + "pify": "^4.0.1", + "semver": "^5.6.0" + } + }, + "package-hash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/package-hash/-/package-hash-3.0.0.tgz", + "integrity": "sha512-lOtmukMDVvtkL84rJHI7dpTYq+0rli8N2wlnqUcBuDWCfVhRUfOmnR9SsoHFMLpACvEV60dX7rd0rFaYDZI+FA==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.15", + "hasha": "^3.0.0", + "lodash.flattendeep": "^4.4.0", + "release-zalgo": "^1.0.0" + } + }, + "pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "dev": true + }, + "write-file-atomic": { + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-2.4.3.tgz", + "integrity": "sha512-GaETH5wwsX+GcnzhPgKcKjJ6M2Cq3/iZp1WyY/X1CSqrW+jVNM9Y7D8EC2sM4ZG/V8wZlSniJnCKWPmBYAucRQ==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.11", + "imurmurhash": "^0.1.4", + "signal-exit": "^3.0.2" + } + } + } + }, + "call-matcher": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/call-matcher/-/call-matcher-1.1.0.tgz", + "integrity": "sha512-IoQLeNwwf9KTNbtSA7aEBb1yfDbdnzwjCetjkC8io5oGeOmK2CBNdg0xr+tadRYKO0p7uQyZzvon0kXlZbvGrw==", + "dev": true, + "requires": { + "core-js": "^2.0.0", + "deep-equal": "^1.0.0", + "espurify": "^1.6.0", + "estraverse": "^4.0.0" + } + }, + "call-signature": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/call-signature/-/call-signature-0.0.2.tgz", + "integrity": "sha1-qEq8glpV70yysCi9dOIFpluaSZY=", + "dev": true + }, + "callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true + }, + "camelcase": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", + "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=", + "dev": true + }, + "camelcase-keys": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-4.2.0.tgz", + "integrity": "sha1-oqpfsa9oh1glnDLBQUJteJI7m3c=", + "dev": true, + "requires": { + "camelcase": "^4.1.0", + "map-obj": "^2.0.0", + "quick-lru": "^1.0.0" + } + }, + "caniuse-lite": { + "version": "1.0.30000989", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000989.tgz", + "integrity": "sha512-vrMcvSuMz16YY6GSVZ0dWDTJP8jqk3iFQ/Aq5iqblPwxSVVZI+zxDyTX0VPqtQsDnfdrBDcsmhgTEOh5R8Lbpw==", + "dev": true + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "chardet": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", + "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", + "dev": true + }, + "chokidar": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.0.2.tgz", + "integrity": "sha512-c4PR2egjNjI1um6bamCQ6bUNPDiyofNQruHvKgHQ4gDUP/ITSVSzNsiI5OWtHOsX323i5ha/kk4YmOZ1Ktg7KA==", + "dev": true, + "requires": { + "anymatch": "^3.0.1", + "braces": "^3.0.2", + "fsevents": "^2.0.6", + "glob-parent": "^5.0.0", + "is-binary-path": "^2.1.0", + "is-glob": "^4.0.1", + "normalize-path": "^3.0.0", + "readdirp": "^3.1.1" + } + }, + "chunkd": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/chunkd/-/chunkd-1.0.0.tgz", + "integrity": "sha512-xx3Pb5VF9QaqCotolyZ1ywFBgyuJmu6+9dLiqBxgelEse9Xsr3yUlpoX3O4Oh11M00GT2kYMsRByTKIMJW2Lkg==", + "dev": true + }, + "ci-info": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", + "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==", + "dev": true + }, + "ci-parallel-vars": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/ci-parallel-vars/-/ci-parallel-vars-1.0.0.tgz", + "integrity": "sha512-u6dx20FBXm+apMi+5x7UVm6EH7BL1gc4XrcnQewjcB7HWRcor/V5qWc3RG2HwpgDJ26gIi2DSEu3B7sXynAw/g==", + "dev": true + }, + "clean-stack": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", + "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", + "dev": true + }, + "clean-yaml-object": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/clean-yaml-object/-/clean-yaml-object-0.1.0.tgz", + "integrity": "sha1-Y/sRDcLOGoTcIfbZM0h20BCui2g=", + "dev": true + }, + "cli-boxes": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-2.2.0.tgz", + "integrity": "sha512-gpaBrMAizVEANOpfZp/EEUixTXDyGt7DFzdK5hU+UbWt/J0lB0w20ncZj59Z9a93xHb9u12zF5BS6i9RKbtg4w==", + "dev": true + }, + "cli-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", + "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", + "dev": true, + "requires": { + "restore-cursor": "^3.1.0" + } + }, + "cli-spinners": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.2.0.tgz", + "integrity": "sha512-tgU3fKwzYjiLEQgPMD9Jt+JjHVL9kW93FiIMX/l7rivvOD4/LL0Mf7gda3+4U2KJBloybwgj5KEoQgGRioMiKQ==", + "dev": true + }, + "cli-truncate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-2.0.0.tgz", + "integrity": "sha512-C4hp+8GCIFVsUUiXcw+ce+7wexVWImw8rQrgMBFsqerx9LvvcGlwm6sMjQYAEmV/Xb87xc1b5Ttx505MSpZVqg==", + "dev": true, + "requires": { + "slice-ansi": "^2.1.0", + "string-width": "^4.1.0" + } + }, + "cli-width": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz", + "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=", + "dev": true + }, + "cliui": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", + "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", + "dev": true, + "requires": { + "string-width": "^3.1.0", + "strip-ansi": "^5.2.0", + "wrap-ansi": "^5.1.0" + }, + "dependencies": { + "emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "dev": true + }, + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dev": true, + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + } + } + } + }, + "clone": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", + "integrity": "sha1-2jCcwmPfFZlMaIypAheco8fNfH4=", + "dev": true + }, + "clone-response": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.2.tgz", + "integrity": "sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws=", + "dev": true, + "requires": { + "mimic-response": "^1.0.0" + } + }, + "code-excerpt": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/code-excerpt/-/code-excerpt-2.1.1.tgz", + "integrity": "sha512-tJLhH3EpFm/1x7heIW0hemXJTUU5EWl2V0EIX558jp05Mt1U6DVryCgkp3l37cxqs+DNbNgxG43SkwJXpQ14Jw==", + "dev": true, + "requires": { + "convert-to-spaces": "^1.0.1" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "commander": { + "version": "2.20.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.0.tgz", + "integrity": "sha512-7j2y+40w61zy6YC2iRNpUe/NwhNyoXrYpHMrSunaMG64nRnaf96zO/KMQR4OyN/UnE5KLyEBnKHd4aG3rskjpQ==", + "dev": true, + "optional": true + }, + "common-path-prefix": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/common-path-prefix/-/common-path-prefix-1.0.0.tgz", + "integrity": "sha1-zVL28HEuC6q5fW+XModPIvR3UsA=", + "dev": true + }, + "commondir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", + "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", + "dev": true + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true + }, + "concordance": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/concordance/-/concordance-4.0.0.tgz", + "integrity": "sha512-l0RFuB8RLfCS0Pt2Id39/oCPykE01pyxgAFypWTlaGRgvLkZrtczZ8atEHpTeEIW+zYWXTBuA9cCSeEOScxReQ==", + "dev": true, + "requires": { + "date-time": "^2.1.0", + "esutils": "^2.0.2", + "fast-diff": "^1.1.2", + "js-string-escape": "^1.0.1", + "lodash.clonedeep": "^4.5.0", + "lodash.flattendeep": "^4.4.0", + "lodash.islength": "^4.0.1", + "lodash.merge": "^4.6.1", + "md5-hex": "^2.0.0", + "semver": "^5.5.1", + "well-known-symbols": "^2.0.0" + }, + "dependencies": { + "md5-hex": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/md5-hex/-/md5-hex-2.0.0.tgz", + "integrity": "sha1-0FiOnxx0lUSS7NJKwKxs6ZfZLjM=", + "dev": true, + "requires": { + "md5-o-matic": "^0.1.1" + } + } + } + }, + "configstore": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/configstore/-/configstore-4.0.0.tgz", + "integrity": "sha512-CmquAXFBocrzaSM8mtGPMM/HiWmyIpr4CcJl/rgY2uCObZ/S7cKU0silxslqJejl+t/T9HS8E0PUNQD81JGUEQ==", + "dev": true, + "requires": { + "dot-prop": "^4.1.0", + "graceful-fs": "^4.1.2", + "make-dir": "^1.0.0", + "unique-string": "^1.0.0", + "write-file-atomic": "^2.0.0", + "xdg-basedir": "^3.0.0" + }, + "dependencies": { + "dot-prop": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-4.2.0.tgz", + "integrity": "sha512-tUMXrxlExSW6U2EXiiKGSBVdYgtV8qlHL+C10TsW4PURY/ic+eaysnSkwB4kA/mBlCyy/IKDJ+Lc3wbWeaXtuQ==", + "dev": true, + "requires": { + "is-obj": "^1.0.0" + } + }, + "is-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz", + "integrity": "sha1-PkcprB9f3gJc19g6iW2rn09n2w8=", + "dev": true + }, + "make-dir": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.3.0.tgz", + "integrity": "sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==", + "dev": true, + "requires": { + "pify": "^3.0.0" + } + }, + "pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", + "dev": true + }, + "write-file-atomic": { + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-2.4.3.tgz", + "integrity": "sha512-GaETH5wwsX+GcnzhPgKcKjJ6M2Cq3/iZp1WyY/X1CSqrW+jVNM9Y7D8EC2sM4ZG/V8wZlSniJnCKWPmBYAucRQ==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.11", + "imurmurhash": "^0.1.4", + "signal-exit": "^3.0.2" + } + } + } + }, + "confusing-browser-globals": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/confusing-browser-globals/-/confusing-browser-globals-1.0.8.tgz", + "integrity": "sha512-lI7asCibVJ6Qd3FGU7mu4sfG4try4LX3+GVS+Gv8UlrEf2AeW57piecapnog2UHZSbcX/P/1UDWVaTsblowlZg==", + "dev": true + }, + "contains-path": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/contains-path/-/contains-path-0.1.0.tgz", + "integrity": "sha1-/ozxhP9mcLa67wGp1IYaXL7EEgo=", + "dev": true + }, + "convert-source-map": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.6.0.tgz", + "integrity": "sha512-eFu7XigvxdZ1ETfbgPBohgyQ/Z++C0eEhTor0qRwBw9unw+L0/6V8wkSuGgzdThkiS5lSpdptOQPD8Ak40a+7A==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.1" + }, + "dependencies": { + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + } + } + }, + "convert-to-spaces": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/convert-to-spaces/-/convert-to-spaces-1.0.2.tgz", + "integrity": "sha1-fj5Iu+bZl7FBfdyihoIEtNPYVxU=", + "dev": true + }, + "core-js": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.9.tgz", + "integrity": "sha512-HOpZf6eXmnl7la+cUdMnLvUxKNqLUzJvgIziQ0DiF3JwSImNphIqdGqzj6hIKyX04MmV0poclQ7+wjWvxQyR2A==", + "dev": true + }, + "cp-file": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/cp-file/-/cp-file-6.2.0.tgz", + "integrity": "sha512-fmvV4caBnofhPe8kOcitBwSn2f39QLjnAnGq3gO9dfd75mUytzKNZB1hde6QHunW2Rt+OwuBOMc3i1tNElbszA==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "make-dir": "^2.0.0", + "nested-error-stacks": "^2.0.0", + "pify": "^4.0.1", + "safe-buffer": "^5.0.1" + }, + "dependencies": { + "make-dir": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", + "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", + "dev": true, + "requires": { + "pify": "^4.0.1", + "semver": "^5.6.0" + } + }, + "pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "dev": true + } + } + }, + "cross-spawn": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", + "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=", + "dev": true, + "requires": { + "lru-cache": "^4.0.1", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + } + }, + "crypto-random-string": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-1.0.0.tgz", + "integrity": "sha1-ojD2T1aDEOFJgAmUB5DsmVRbyn4=", + "dev": true + }, + "currently-unhandled": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz", + "integrity": "sha1-mI3zP+qxke95mmE2nddsF635V+o=", + "dev": true, + "requires": { + "array-find-index": "^1.0.1" + } + }, + "date-time": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/date-time/-/date-time-2.1.0.tgz", + "integrity": "sha512-/9+C44X7lot0IeiyfgJmETtRMhBidBYM2QFFIkGa0U1k+hSyY87Nw7PY3eDqpvCBm7I3WCSfPeZskW/YYq6m4g==", + "dev": true, + "requires": { + "time-zone": "^1.0.0" + } + }, + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + }, + "dependencies": { + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + } + } + }, + "decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", + "dev": true + }, + "decamelize-keys": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/decamelize-keys/-/decamelize-keys-1.1.0.tgz", + "integrity": "sha1-0XGoeTMlKAfrPLYdwcFEXQeN8tk=", + "dev": true, + "requires": { + "decamelize": "^1.1.0", + "map-obj": "^1.0.0" + }, + "dependencies": { + "map-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", + "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=", + "dev": true + } + } + }, + "decompress-response": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz", + "integrity": "sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=", + "dev": true, + "requires": { + "mimic-response": "^1.0.0" + } + }, + "deep-equal": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.0.1.tgz", + "integrity": "sha1-9dJgKStmDghO/0zbyfCK0yR0SLU=", + "dev": true + }, + "deep-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", + "dev": true + }, + "deep-is": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", + "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", + "dev": true + }, + "default-require-extensions": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/default-require-extensions/-/default-require-extensions-2.0.0.tgz", + "integrity": "sha1-9fj7sYp9bVCyH2QfZJ67Uiz+JPc=", + "dev": true, + "requires": { + "strip-bom": "^3.0.0" + } + }, + "defaults": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.3.tgz", + "integrity": "sha1-xlYFHpgX2f8I7YgUd/P+QBnz730=", + "dev": true, + "requires": { + "clone": "^1.0.2" + } + }, + "defer-to-connect": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-1.0.2.tgz", + "integrity": "sha512-k09hcQcTDY+cwgiwa6PYKLm3jlagNzQ+RSvhjzESOGOx+MNOuXkxTfEvPrO1IOQ81tArCFYQgi631clB70RpQw==", + "dev": true + }, + "define-properties": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", + "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", + "dev": true, + "requires": { + "object-keys": "^1.0.12" + } + }, + "del": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/del/-/del-4.1.1.tgz", + "integrity": "sha512-QwGuEUouP2kVwQenAsOof5Fv8K9t3D8Ca8NxcXKrIpEHjTXK5J2nXLdP+ALI1cgv8wj7KuwBhTwBkOZSJKM5XQ==", + "dev": true, + "requires": { + "@types/glob": "^7.1.1", + "globby": "^6.1.0", + "is-path-cwd": "^2.0.0", + "is-path-in-cwd": "^2.0.0", + "p-map": "^2.0.0", + "pify": "^4.0.1", + "rimraf": "^2.6.3" + }, + "dependencies": { + "array-union": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", + "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", + "dev": true, + "requires": { + "array-uniq": "^1.0.1" + } + }, + "array-uniq": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", + "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=", + "dev": true + }, + "globby": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-6.1.0.tgz", + "integrity": "sha1-9abXDoOV4hyFj7BInWTfAkJNUGw=", + "dev": true, + "requires": { + "array-union": "^1.0.1", + "glob": "^7.0.3", + "object-assign": "^4.0.1", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0" + }, + "dependencies": { + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + } + } + }, + "pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "dev": true + } + } + }, + "detect-indent": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-4.0.0.tgz", + "integrity": "sha1-920GQ1LN9Docts5hnE7jqUdd4gg=", + "dev": true, + "requires": { + "repeating": "^2.0.0" + } + }, + "dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, + "requires": { + "path-type": "^4.0.0" + }, + "dependencies": { + "path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true + } + } + }, + "doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, + "requires": { + "esutils": "^2.0.2" + } + }, + "dot-prop": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.1.0.tgz", + "integrity": "sha512-n1oC6NBF+KM9oVXtjmen4Yo7HyAVWV2UUl50dCYJdw2924K6dX9bf9TTTWaKtYlRn0FEtxG27KS80ayVLixxJA==", + "dev": true, + "requires": { + "is-obj": "^2.0.0" + } + }, + "duplexer3": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz", + "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=", + "dev": true + }, + "electron-to-chromium": { + "version": "1.3.236", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.236.tgz", + "integrity": "sha512-LWOvuJ80pLO3FtFqTcGuXB0dxdMtzSCkRmbXdY5mHUvXRQGor3sTVmyfU70aD2yF5i+fbHz52ncWr5T3xUYHlA==", + "dev": true + }, + "emittery": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.4.1.tgz", + "integrity": "sha512-r4eRSeStEGf6M5SKdrQhhLK5bOwOBxQhIE3YSTnZE3GpKiLfnnhE+tPtrJE79+eDJgm39BM6LSoI8SCx4HbwlQ==", + "dev": true + }, + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "empower-core": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/empower-core/-/empower-core-1.2.0.tgz", + "integrity": "sha512-g6+K6Geyc1o6FdXs9HwrXleCFan7d66G5xSCfSF7x1mJDCes6t0om9lFQG3zOrzh3Bkb/45N0cZ5Gqsf7YrzGQ==", + "dev": true, + "requires": { + "call-signature": "0.0.2", + "core-js": "^2.0.0" + } + }, + "end-of-stream": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz", + "integrity": "sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==", + "dev": true, + "requires": { + "once": "^1.4.0" + } + }, + "equal-length": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/equal-length/-/equal-length-1.0.1.tgz", + "integrity": "sha1-IcoRLUirJLTh5//A5TOdMf38J0w=", + "dev": true + }, + "erlang-types": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/erlang-types/-/erlang-types-1.1.3.tgz", + "integrity": "sha512-HZWcirSqKIdasr04DT9NnYgVyqvUaefDPp2LhNgtBnM2ovOkUhJ4DEKVQZ71POKsu4wiR64EWhahA8AE9r796g==" + }, + "error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dev": true, + "requires": { + "is-arrayish": "^0.2.1" + } + }, + "es-abstract": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.13.0.tgz", + "integrity": "sha512-vDZfg/ykNxQVwup/8E1BZhVzFfBxs9NqMzGcvIJrqg5k2/5Za2bWo40dK2J1pgLngZ7c+Shh8lwYtLGyrwPutg==", + "dev": true, + "requires": { + "es-to-primitive": "^1.2.0", + "function-bind": "^1.1.1", + "has": "^1.0.3", + "is-callable": "^1.1.4", + "is-regex": "^1.0.4", + "object-keys": "^1.0.12" + } + }, + "es-to-primitive": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.0.tgz", + "integrity": "sha512-qZryBOJjV//LaxLTV6UC//WewneB3LcXOL9NP++ozKVXsIIIpm/2c13UDiD9Jp2eThsecw9m3jPqDwTyobcdbg==", + "dev": true, + "requires": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + } + }, + "es6-error": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz", + "integrity": "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==", + "dev": true + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true + }, + "eslint": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-6.2.1.tgz", + "integrity": "sha512-ES7BzEzr0Q6m5TK9i+/iTpKjclXitOdDK4vT07OqbkBT2/VcN/gO9EL1C4HlK3TAOXYv2ItcmbVR9jO1MR0fJg==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "ajv": "^6.10.0", + "chalk": "^2.1.0", + "cross-spawn": "^6.0.5", + "debug": "^4.0.1", + "doctrine": "^3.0.0", + "eslint-scope": "^5.0.0", + "eslint-utils": "^1.4.2", + "eslint-visitor-keys": "^1.1.0", + "espree": "^6.1.0", + "esquery": "^1.0.1", + "esutils": "^2.0.2", + "file-entry-cache": "^5.0.1", + "functional-red-black-tree": "^1.0.1", + "glob-parent": "^5.0.0", + "globals": "^11.7.0", + "ignore": "^4.0.6", + "import-fresh": "^3.0.0", + "imurmurhash": "^0.1.4", + "inquirer": "^6.4.1", + "is-glob": "^4.0.0", + "js-yaml": "^3.13.1", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.3.0", + "lodash": "^4.17.14", + "minimatch": "^3.0.4", + "mkdirp": "^0.5.1", + "natural-compare": "^1.4.0", + "optionator": "^0.8.2", + "progress": "^2.0.0", + "regexpp": "^2.0.1", + "semver": "^6.1.2", + "strip-ansi": "^5.2.0", + "strip-json-comments": "^3.0.1", + "table": "^5.2.3", + "text-table": "^0.2.0", + "v8-compile-cache": "^2.0.3" + }, + "dependencies": { + "cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "dev": true, + "requires": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + }, + "dependencies": { + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + } + } + }, + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true + }, + "ignore": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", + "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", + "dev": true + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + }, + "strip-json-comments": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.0.1.tgz", + "integrity": "sha512-VTyMAUfdm047mwKl+u79WIdrZxtFtn+nBxHeb844XBQ9uMNTuTHdx2hc5RiAJYqwTj3wc/xe5HLSdJSkJ+WfZw==", + "dev": true + } + } + }, + "eslint-config-airbnb-base": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/eslint-config-airbnb-base/-/eslint-config-airbnb-base-14.0.0.tgz", + "integrity": "sha512-2IDHobw97upExLmsebhtfoD3NAKhV4H0CJWP3Uprd/uk+cHuWYOczPVxQ8PxLFUAw7o3Th1RAU8u1DoUpr+cMA==", + "dev": true, + "requires": { + "confusing-browser-globals": "^1.0.7", + "object.assign": "^4.1.0", + "object.entries": "^1.1.0" + } + }, + "eslint-import-resolver-node": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.2.tgz", + "integrity": "sha512-sfmTqJfPSizWu4aymbPr4Iidp5yKm8yDkHp+Ir3YiTHiiDfxh69mOUsmiqW6RZ9zRXFaF64GtYmN7e+8GHBv6Q==", + "dev": true, + "requires": { + "debug": "^2.6.9", + "resolve": "^1.5.0" + } + }, + "eslint-module-utils": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.4.1.tgz", + "integrity": "sha512-H6DOj+ejw7Tesdgbfs4jeS4YMFrT8uI8xwd1gtQqXssaR0EQ26L+2O/w6wkYFy2MymON0fTwHmXBvvfLNZVZEw==", + "dev": true, + "requires": { + "debug": "^2.6.8", + "pkg-dir": "^2.0.0" + } + }, + "eslint-plugin-import": { + "version": "2.18.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.18.2.tgz", + "integrity": "sha512-5ohpsHAiUBRNaBWAF08izwUGlbrJoJJ+W9/TBwsGoR1MnlgfwMIKrFeSjWbt6moabiXW9xNvtFz+97KHRfI4HQ==", + "dev": true, + "requires": { + "array-includes": "^3.0.3", + "contains-path": "^0.1.0", + "debug": "^2.6.9", + "doctrine": "1.5.0", + "eslint-import-resolver-node": "^0.3.2", + "eslint-module-utils": "^2.4.0", + "has": "^1.0.3", + "minimatch": "^3.0.4", + "object.values": "^1.1.0", + "read-pkg-up": "^2.0.0", + "resolve": "^1.11.0" + }, + "dependencies": { + "doctrine": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-1.5.0.tgz", + "integrity": "sha1-N53Ocw9hZvds76TmcHoVmwLFpvo=", + "dev": true, + "requires": { + "esutils": "^2.0.2", + "isarray": "^1.0.0" + } + } + } + }, + "eslint-scope": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.0.0.tgz", + "integrity": "sha512-oYrhJW7S0bxAFDvWqzvMPRm6pcgcnWc4QnofCAqRTRfQC0JcwenzGglTtsLyIuuWFfkqDG9vz67cnttSd53djw==", + "dev": true, + "requires": { + "esrecurse": "^4.1.0", + "estraverse": "^4.1.1" + } + }, + "eslint-utils": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.4.2.tgz", + "integrity": "sha512-eAZS2sEUMlIeCjBeubdj45dmBHQwPHWyBcT1VSYB7o9x9WRRqKxyUoiXlRjyAwzN7YEzHJlYg0NmzDRWx6GP4Q==", + "dev": true, + "requires": { + "eslint-visitor-keys": "^1.0.0" + } + }, + "eslint-visitor-keys": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.1.0.tgz", + "integrity": "sha512-8y9YjtM1JBJU/A9Kc+SbaOV4y29sSWckBwMHa+FGtVj5gN/sbnKDf6xJUl+8g7FAij9LVaP8C24DUiH/f/2Z9A==", + "dev": true + }, + "esm": { + "version": "3.2.25", + "resolved": "https://registry.npmjs.org/esm/-/esm-3.2.25.tgz", + "integrity": "sha512-U1suiZ2oDVWv4zPO56S0NcR5QriEahGtdN2OR6FiOG4WJvcjBVFB0qI4+eKoWFH483PKGuLuu6V8Z4T5g63UVA==", + "dev": true + }, + "espower-location-detector": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/espower-location-detector/-/espower-location-detector-1.0.0.tgz", + "integrity": "sha1-oXt+zFnTDheeK+9z+0E3cEyzMbU=", + "dev": true, + "requires": { + "is-url": "^1.2.1", + "path-is-absolute": "^1.0.0", + "source-map": "^0.5.0", + "xtend": "^4.0.0" + } + }, + "espree": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-6.1.0.tgz", + "integrity": "sha512-boA7CHRLlVWUSg3iL5Kmlt/xT3Q+sXnKoRYYzj1YeM10A76TEJBbotV5pKbnK42hEUIr121zTv+QLRM5LsCPXQ==", + "dev": true, + "requires": { + "acorn": "^7.0.0", + "acorn-jsx": "^5.0.0", + "eslint-visitor-keys": "^1.1.0" + } + }, + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true + }, + "espurify": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/espurify/-/espurify-1.8.1.tgz", + "integrity": "sha512-ZDko6eY/o+D/gHCWyHTU85mKDgYcS4FJj7S+YD6WIInm7GQ6AnOjmcL4+buFV/JOztVLELi/7MmuGU5NHta0Mg==", + "dev": true, + "requires": { + "core-js": "^2.0.0" + } + }, + "esquery": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.0.1.tgz", + "integrity": "sha512-SmiyZ5zIWH9VM+SRUReLS5Q8a7GxtRdxEBVZpm98rJM7Sb+A9DVCndXfkeFUd3byderg+EbDkfnevfCwynWaNA==", + "dev": true, + "requires": { + "estraverse": "^4.0.0" + } + }, + "esrecurse": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz", + "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==", + "dev": true, + "requires": { + "estraverse": "^4.1.0" + } + }, + "estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true + }, + "estree-walker": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-0.6.1.tgz", + "integrity": "sha512-SqmZANLWS0mnatqbSfRP5g8OXZC12Fgg1IwNtLsyHDzJizORW4khDfjPqJZsemPWBB2uqykUah5YpQ6epsqC/w==" + }, + "esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true + }, + "execa": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-0.7.0.tgz", + "integrity": "sha1-lEvs00zEHuMqY6n68nrVpl/Fl3c=", + "dev": true, + "requires": { + "cross-spawn": "^5.0.1", + "get-stream": "^3.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" + } + }, + "external-editor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", + "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", + "dev": true, + "requires": { + "chardet": "^0.7.0", + "iconv-lite": "^0.4.24", + "tmp": "^0.0.33" + } + }, + "fast-deep-equal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", + "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=", + "dev": true + }, + "fast-diff": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.2.0.tgz", + "integrity": "sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==", + "dev": true + }, + "fast-glob": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.0.4.tgz", + "integrity": "sha512-wkIbV6qg37xTJwqSsdnIphL1e+LaGz4AIQqr00mIubMaEhv1/HEmJ0uuCGZRNRUkZZmOB5mJKO0ZUTVq+SxMQg==", + "dev": true, + "requires": { + "@nodelib/fs.stat": "^2.0.1", + "@nodelib/fs.walk": "^1.2.1", + "glob-parent": "^5.0.0", + "is-glob": "^4.0.1", + "merge2": "^1.2.3", + "micromatch": "^4.0.2" + } + }, + "fast-json-stable-stringify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", + "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=", + "dev": true + }, + "fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", + "dev": true + }, + "fastq": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.6.0.tgz", + "integrity": "sha512-jmxqQ3Z/nXoeyDmWAzF9kH1aGZSis6e/SbfPmJpUnyZ0ogr6iscHQaml4wsEepEWSdtmpy+eVXmCRIMpxaXqOA==", + "dev": true, + "requires": { + "reusify": "^1.0.0" + } + }, + "figures": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-3.0.0.tgz", + "integrity": "sha512-HKri+WoWoUgr83pehn/SIgLOMZ9nAWC6dcGj26RY2R4F50u4+RTUz0RCrUlOV3nKRAICW1UGzyb+kcX2qK1S/g==", + "dev": true, + "requires": { + "escape-string-regexp": "^1.0.5" + } + }, + "file-entry-cache": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-5.0.1.tgz", + "integrity": "sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g==", + "dev": true, + "requires": { + "flat-cache": "^2.0.1" + } + }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "find-cache-dir": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz", + "integrity": "sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==", + "dev": true, + "requires": { + "commondir": "^1.0.1", + "make-dir": "^2.0.0", + "pkg-dir": "^3.0.0" + }, + "dependencies": { + "find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "dev": true, + "requires": { + "locate-path": "^3.0.0" + } + }, + "locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "dev": true, + "requires": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + } + }, + "make-dir": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", + "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", + "dev": true, + "requires": { + "pify": "^4.0.1", + "semver": "^5.6.0" + } + }, + "p-limit": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.1.tgz", + "integrity": "sha512-85Tk+90UCVWvbDavCLKPOLC9vvY8OwEX/RtKF+/1OADJMVlFfEHOiMTPVyxg7mk/dKa+ipdHm0OUkTvCpMTuwg==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "dev": true, + "requires": { + "p-limit": "^2.0.0" + } + }, + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true + }, + "pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "dev": true + }, + "pkg-dir": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", + "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", + "dev": true, + "requires": { + "find-up": "^3.0.0" + } + } + } + }, + "find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "dev": true, + "requires": { + "locate-path": "^2.0.0" + } + }, + "flat-cache": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-2.0.1.tgz", + "integrity": "sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA==", + "dev": true, + "requires": { + "flatted": "^2.0.0", + "rimraf": "2.6.3", + "write": "1.0.3" + }, + "dependencies": { + "rimraf": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", + "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + } + } + }, + "flatted": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.1.tgz", + "integrity": "sha512-a1hQMktqW9Nmqr5aktAux3JMNqaucxGcjtjWnZLHX7yyPCmlSV3M54nGYbqT8K+0GhF3NBgmJCc3ma+WOgX8Jg==", + "dev": true + }, + "foreground-child": { + "version": "1.5.6", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-1.5.6.tgz", + "integrity": "sha1-T9ca0t/elnibmApcCilZN8svXOk=", + "dev": true, + "requires": { + "cross-spawn": "^4", + "signal-exit": "^3.0.0" + }, + "dependencies": { + "cross-spawn": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-4.0.2.tgz", + "integrity": "sha1-e5JHYhwjrf3ThWAEqCPL45dCTUE=", + "dev": true, + "requires": { + "lru-cache": "^4.0.1", + "which": "^1.2.9" + } + } + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "fsevents": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.0.7.tgz", + "integrity": "sha512-a7YT0SV3RB+DjYcppwVDLtn13UQnmg0SWZS7ezZD0UjnLwXmy8Zm21GMVGLaFGimIqcvyMQaOJBrop8MyOp1kQ==", + "dev": true, + "optional": true + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, + "functional-red-black-tree": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", + "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", + "dev": true + }, + "get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true + }, + "get-port": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/get-port/-/get-port-5.0.0.tgz", + "integrity": "sha512-imzMU0FjsZqNa6BqOjbbW6w5BivHIuQKopjpPqcnx0AVHJQKCxK1O+Ab3OrVXhrekqfVMjwA9ZYu062R+KcIsQ==", + "dev": true, + "requires": { + "type-fest": "^0.3.0" + }, + "dependencies": { + "type-fest": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.3.1.tgz", + "integrity": "sha512-cUGJnCdr4STbePCgqNFbpVNCepa+kAVohJs1sLhxzdH+gnEoOd8VhbYa7pD3zZYGiURWM2xzEII3fQcRizDkYQ==", + "dev": true + } + } + }, + "get-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", + "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=", + "dev": true + }, + "glob": { + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.4.tgz", + "integrity": "sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "glob-parent": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.0.0.tgz", + "integrity": "sha512-Z2RwiujPRGluePM6j699ktJYxmPpJKCfpGA13jz2hmFZC7gKetzrWvg5KN3+OsIFmydGyZ1AVwERCq1w/ZZwRg==", + "dev": true, + "requires": { + "is-glob": "^4.0.1" + } + }, + "global-dirs": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-0.1.1.tgz", + "integrity": "sha1-sxnA3UYH81PzvpzKTHL8FIxJ9EU=", + "dev": true, + "requires": { + "ini": "^1.3.4" + } + }, + "globals": { + "version": "9.18.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-9.18.0.tgz", + "integrity": "sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ==", + "dev": true + }, + "globby": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/globby/-/globby-10.0.1.tgz", + "integrity": "sha512-sSs4inE1FB2YQiymcmTv6NWENryABjUNPeWhOvmn4SjtKybglsyPZxFB3U1/+L1bYi0rNZDqCLlHyLYDl1Pq5A==", + "dev": true, + "requires": { + "@types/glob": "^7.1.1", + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.0.3", + "glob": "^7.1.3", + "ignore": "^5.1.1", + "merge2": "^1.2.3", + "slash": "^3.0.0" + }, + "dependencies": { + "slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true + } + } + }, + "got": { + "version": "9.6.0", + "resolved": "https://registry.npmjs.org/got/-/got-9.6.0.tgz", + "integrity": "sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q==", + "dev": true, + "requires": { + "@sindresorhus/is": "^0.14.0", + "@szmarczak/http-timer": "^1.1.2", + "cacheable-request": "^6.0.0", + "decompress-response": "^3.3.0", + "duplexer3": "^0.1.4", + "get-stream": "^4.1.0", + "lowercase-keys": "^1.0.1", + "mimic-response": "^1.0.1", + "p-cancelable": "^1.0.0", + "to-readable-stream": "^1.0.0", + "url-parse-lax": "^3.0.0" + }, + "dependencies": { + "get-stream": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", + "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", + "dev": true, + "requires": { + "pump": "^3.0.0" + } + } + } + }, + "graceful-fs": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.2.tgz", + "integrity": "sha512-IItsdsea19BoLC7ELy13q1iJFNmd7ofZH5+X/pJr90/nRoPEX0DJo1dHDbgtYWOhJhcCgMDTOw84RZ72q6lB+Q==", + "dev": true + }, + "grapheme-splitter": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz", + "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==" + }, + "handlebars": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.1.2.tgz", + "integrity": "sha512-nvfrjqvt9xQ8Z/w0ijewdD/vvWDTOweBUm96NTr66Wfvo1mJenBLwcYmPs3TIBP5ruzYGD7Hx/DaM9RmhroGPw==", + "dev": true, + "requires": { + "neo-async": "^2.6.0", + "optimist": "^0.6.1", + "source-map": "^0.6.1", + "uglify-js": "^3.1.4" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } + } + }, + "has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, + "requires": { + "function-bind": "^1.1.1" + } + }, + "has-ansi": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "has-symbols": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.0.tgz", + "integrity": "sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q=", + "dev": true + }, + "has-yarn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/has-yarn/-/has-yarn-2.1.0.tgz", + "integrity": "sha512-UqBRqi4ju7T+TqGNdqAO0PaSVGsDGJUBQvk9eUWNGRY1CFGDzYhLWoM7JQEemnlvVcv/YEmc2wNW8BC24EnUsw==", + "dev": true + }, + "hasha": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/hasha/-/hasha-5.0.0.tgz", + "integrity": "sha512-PqWdhnQhq6tqD32hZv+l1e5mJHNSudjnaAzgAHfkGiU0ABN6lmbZF8abJIulQHbZ7oiHhP8yL6O910ICMc+5pw==", + "dev": true, + "requires": { + "is-stream": "^1.1.0", + "type-fest": "^0.3.0" + }, + "dependencies": { + "type-fest": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.3.1.tgz", + "integrity": "sha512-cUGJnCdr4STbePCgqNFbpVNCepa+kAVohJs1sLhxzdH+gnEoOd8VhbYa7pD3zZYGiURWM2xzEII3fQcRizDkYQ==", + "dev": true + } + } + }, + "home-or-tmp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/home-or-tmp/-/home-or-tmp-2.0.0.tgz", + "integrity": "sha1-42w/LSyufXRqhX440Y1fMqeILbg=", + "dev": true, + "requires": { + "os-homedir": "^1.0.0", + "os-tmpdir": "^1.0.1" + } + }, + "hosted-git-info": { + "version": "2.8.4", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.4.tgz", + "integrity": "sha512-pzXIvANXEFrc5oFFXRMkbLPQ2rXRoDERwDLyrcUxGhaZhgP54BBSl9Oheh7Vv0T090cszWBxPjkQQ5Sq1PbBRQ==", + "dev": true + }, + "http-cache-semantics": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.0.3.tgz", + "integrity": "sha512-TcIMG3qeVLgDr1TEd2XvHaTnMPwYQUQMIBLy+5pLSDKYFc7UIqj39w8EGzZkaxoLv/l2K8HaI0t5AVA+YYgUew==", + "dev": true + }, + "iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "ignore": { + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.4.tgz", + "integrity": "sha512-MzbUSahkTW1u7JpKKjY7LCARd1fU5W2rLdxlM4kdkayuCwZImjkpluF9CM1aLewYJguPDqewLam18Y6AU69A8A==", + "dev": true + }, + "ignore-by-default": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz", + "integrity": "sha1-SMptcvbGo68Aqa1K5odr44ieKwk=", + "dev": true + }, + "import-fresh": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.1.0.tgz", + "integrity": "sha512-PpuksHKGt8rXfWEr9m9EHIpgyyaltBy8+eF6GJM0QCAxMgxCfucMF3mjecK2QsJr0amJW7gTqh5/wht0z2UhEQ==", + "dev": true, + "requires": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "dependencies": { + "resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true + } + } + }, + "import-lazy": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-2.1.0.tgz", + "integrity": "sha1-BWmOPUXIjo1+nZLLBYTnfwlvPkM=", + "dev": true + }, + "import-local": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.0.2.tgz", + "integrity": "sha512-vjL3+w0oulAVZ0hBHnxa/Nm5TAurf9YLQJDhqRZyqb+VKGOB6LU8t9H1Nr5CIo16vh9XfJTOoHwU0B71S557gA==", + "dev": true, + "requires": { + "pkg-dir": "^4.2.0", + "resolve-cwd": "^3.0.0" + }, + "dependencies": { + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "requires": { + "p-locate": "^4.1.0" + } + }, + "p-limit": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.1.tgz", + "integrity": "sha512-85Tk+90UCVWvbDavCLKPOLC9vvY8OwEX/RtKF+/1OADJMVlFfEHOiMTPVyxg7mk/dKa+ipdHm0OUkTvCpMTuwg==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "requires": { + "p-limit": "^2.2.0" + } + }, + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true + }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true + }, + "pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "dev": true, + "requires": { + "find-up": "^4.0.0" + } + } + } + }, + "imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "dev": true + }, + "indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "dev": true + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "ini": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", + "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==", + "dev": true + }, + "inquirer": { + "version": "6.5.1", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-6.5.1.tgz", + "integrity": "sha512-uxNHBeQhRXIoHWTSNYUFhQVrHYFThIt6IVo2fFmSe8aBwdR3/w6b58hJpiL/fMukFkvGzjg+hSxFtwvVmKZmXw==", + "dev": true, + "requires": { + "ansi-escapes": "^4.2.1", + "chalk": "^2.4.2", + "cli-cursor": "^3.1.0", + "cli-width": "^2.0.0", + "external-editor": "^3.0.3", + "figures": "^3.0.0", + "lodash": "^4.17.15", + "mute-stream": "0.0.8", + "run-async": "^2.2.0", + "rxjs": "^6.4.0", + "string-width": "^4.1.0", + "strip-ansi": "^5.1.0", + "through": "^2.3.6" + } + }, + "invariant": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", + "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", + "dev": true, + "requires": { + "loose-envify": "^1.0.0" + } + }, + "irregular-plurals": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/irregular-plurals/-/irregular-plurals-2.0.0.tgz", + "integrity": "sha512-Y75zBYLkh0lJ9qxeHlMjQ7bSbyiSqNW/UOPWDmzC7cXskL1hekSITh1Oc6JV0XCWWZ9DE8VYSB71xocLk3gmGw==", + "dev": true + }, + "is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", + "dev": true + }, + "is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "requires": { + "binary-extensions": "^2.0.0" + } + }, + "is-callable": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.4.tgz", + "integrity": "sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA==", + "dev": true + }, + "is-ci": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz", + "integrity": "sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==", + "dev": true, + "requires": { + "ci-info": "^2.0.0" + } + }, + "is-date-object": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.1.tgz", + "integrity": "sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY=", + "dev": true + }, + "is-error": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/is-error/-/is-error-2.2.2.tgz", + "integrity": "sha512-IOQqts/aHWbiisY5DuPJQ0gcbvaLFCa7fBa9xoLfxBZvQ+ZI/Zh9xoI7Gk+G64N0FdK4AbibytHht2tWgpJWLg==", + "dev": true + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "dev": true + }, + "is-finite": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.0.2.tgz", + "integrity": "sha1-zGZ3aVYCvlUO8R6LSqYwU0K20Ko=", + "dev": true, + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + }, + "is-glob": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", + "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", + "dev": true, + "requires": { + "is-extglob": "^2.1.1" + } + }, + "is-installed-globally": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.1.0.tgz", + "integrity": "sha1-Df2Y9akRFxbdU13aZJL2e/PSWoA=", + "dev": true, + "requires": { + "global-dirs": "^0.1.0", + "is-path-inside": "^1.0.0" + }, + "dependencies": { + "is-path-inside": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-1.0.1.tgz", + "integrity": "sha1-jvW33lBDej/cprToZe96pVy0gDY=", + "dev": true, + "requires": { + "path-is-inside": "^1.0.1" + } + } + } + }, + "is-module": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz", + "integrity": "sha1-Mlj7afeMFNW4FdZkM2tM/7ZEFZE=", + "dev": true + }, + "is-npm": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-npm/-/is-npm-3.0.0.tgz", + "integrity": "sha512-wsigDr1Kkschp2opC4G3yA6r9EgVA6NjRpWzIi9axXqeIaAATPRJc4uLujXe3Nd9uO8KoDyA4MD6aZSeXTADhA==", + "dev": true + }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true + }, + "is-obj": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", + "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==", + "dev": true + }, + "is-observable": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-observable/-/is-observable-2.0.0.tgz", + "integrity": "sha512-fhBZv3eFKUbyHXZ1oHujdo2tZ+CNbdpdzzlENgCGZUC8keoGxUew2jYFLYcUB4qo7LDD03o4KK11m/QYD7kEjg==", + "dev": true + }, + "is-path-cwd": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-2.2.0.tgz", + "integrity": "sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ==", + "dev": true + }, + "is-path-in-cwd": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-2.1.0.tgz", + "integrity": "sha512-rNocXHgipO+rvnP6dk3zI20RpOtrAM/kzbB258Uw5BWr3TpXi861yzjo16Dn4hUox07iw5AyeMLHWsujkjzvRQ==", + "dev": true, + "requires": { + "is-path-inside": "^2.1.0" + } + }, + "is-path-inside": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-2.1.0.tgz", + "integrity": "sha512-wiyhTzfDWsvwAW53OBWF5zuvaOGlZ6PwYxAbPVDhpm+gM09xKQGjBq/8uYN12aDvMxnAnq3dxTyoSoRNmg5YFg==", + "dev": true, + "requires": { + "path-is-inside": "^1.0.2" + } + }, + "is-plain-obj": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", + "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=", + "dev": true + }, + "is-plain-object": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-3.0.0.tgz", + "integrity": "sha512-tZIpofR+P05k8Aocp7UI/2UTa9lTJSebCXpFFoR9aibpokDj/uXBsJ8luUu0tTVYKkMU6URDUuOfJZ7koewXvg==", + "dev": true, + "requires": { + "isobject": "^4.0.0" + } + }, + "is-promise": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz", + "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=", + "dev": true + }, + "is-reference": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/is-reference/-/is-reference-1.1.3.tgz", + "integrity": "sha512-W1iHHv/oyBb2pPxkBxtaewxa1BC58Pn5J0hogyCdefwUIvb6R+TGbAcIa4qPNYLqLhb3EnOgUf2MQkkF76BcKw==", + "requires": { + "@types/estree": "0.0.39" + } + }, + "is-regex": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.4.tgz", + "integrity": "sha1-VRdIm1RwkbCTDglWVM7SXul+lJE=", + "dev": true, + "requires": { + "has": "^1.0.1" + } + }, + "is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", + "dev": true + }, + "is-symbol": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.2.tgz", + "integrity": "sha512-HS8bZ9ox60yCJLH9snBpIwv9pYUAkcuLhSA1oero1UB5y9aiQpRA8y2ex945AOtCZL1lJDeIk3G5LthswI46Lw==", + "dev": true, + "requires": { + "has-symbols": "^1.0.0" + } + }, + "is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", + "dev": true + }, + "is-url": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/is-url/-/is-url-1.2.4.tgz", + "integrity": "sha512-ITvGim8FhRiYe4IQ5uHSkj7pVaPDrCTkNd3yq3cV7iZAcJdHTUMPMEHcqSOy9xZ9qFenQCvi+2wjH9a1nXqHww==", + "dev": true + }, + "is-utf8": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", + "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=", + "dev": true + }, + "is-yarn-global": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/is-yarn-global/-/is-yarn-global-0.3.0.tgz", + "integrity": "sha512-VjSeb/lHmkoyd8ryPVIKvOCn4D1koMqY+vqyjjUfc3xyKtP4dYOxM44sZrnqQSzSds3xyOrUTLTC9LVCVgLngw==", + "dev": true + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true + }, + "isobject": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-4.0.0.tgz", + "integrity": "sha512-S/2fF5wH8SJA/kmwr6HYhK/RI/OkhD84k8ntalo0iJjZikgq1XFvR5M8NPT1x5F7fBwCG3qHfnzeP/Vh/ZxCUA==", + "dev": true + }, + "istanbul-lib-coverage": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.5.tgz", + "integrity": "sha512-8aXznuEPCJvGnMSRft4udDRDtb1V3pkQkMMI5LI+6HuQz5oQ4J2UFn1H82raA3qJtyOLkkwVqICBQkjnGtn5mA==", + "dev": true + }, + "istanbul-lib-hook": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/istanbul-lib-hook/-/istanbul-lib-hook-2.0.7.tgz", + "integrity": "sha512-vrRztU9VRRFDyC+aklfLoeXyNdTfga2EI3udDGn4cZ6fpSXpHLV9X6CHvfoMCPtggg8zvDDmC4b9xfu0z6/llA==", + "dev": true, + "requires": { + "append-transform": "^1.0.0" + } + }, + "istanbul-lib-instrument": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-3.3.0.tgz", + "integrity": "sha512-5nnIN4vo5xQZHdXno/YDXJ0G+I3dAm4XgzfSVTPLQpj/zAV2dV6Juy0yaf10/zrJOJeHoN3fraFe+XRq2bFVZA==", + "dev": true, + "requires": { + "@babel/generator": "^7.4.0", + "@babel/parser": "^7.4.3", + "@babel/template": "^7.4.0", + "@babel/traverse": "^7.4.3", + "@babel/types": "^7.4.0", + "istanbul-lib-coverage": "^2.0.5", + "semver": "^6.0.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } + } + }, + "istanbul-lib-report": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-2.0.8.tgz", + "integrity": "sha512-fHBeG573EIihhAblwgxrSenp0Dby6tJMFR/HvlerBsrCTD5bkUuoNtn3gVh29ZCS824cGGBPn7Sg7cNk+2xUsQ==", + "dev": true, + "requires": { + "istanbul-lib-coverage": "^2.0.5", + "make-dir": "^2.1.0", + "supports-color": "^6.1.0" + }, + "dependencies": { + "make-dir": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", + "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", + "dev": true, + "requires": { + "pify": "^4.0.1", + "semver": "^5.6.0" + } + }, + "pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "dev": true + }, + "supports-color": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", + "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "istanbul-lib-source-maps": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-3.0.6.tgz", + "integrity": "sha512-R47KzMtDJH6X4/YW9XTx+jrLnZnscW4VpNN+1PViSYTejLVPWv7oov+Duf8YQSPyVRUvueQqz1TcsC6mooZTXw==", + "dev": true, + "requires": { + "debug": "^4.1.1", + "istanbul-lib-coverage": "^2.0.5", + "make-dir": "^2.1.0", + "rimraf": "^2.6.3", + "source-map": "^0.6.1" + }, + "dependencies": { + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "make-dir": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", + "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", + "dev": true, + "requires": { + "pify": "^4.0.1", + "semver": "^5.6.0" + } + }, + "pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "dev": true + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } + } + }, + "istanbul-reports": { + "version": "2.2.6", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-2.2.6.tgz", + "integrity": "sha512-SKi4rnMyLBKe0Jy2uUdx28h8oG7ph2PPuQPvIAh31d+Ci+lSiEu4C+h3oBPuJ9+mPKhOyW0M8gY4U5NM1WLeXA==", + "dev": true, + "requires": { + "handlebars": "^4.1.2" + } + }, + "js-string-escape": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/js-string-escape/-/js-string-escape-1.0.1.tgz", + "integrity": "sha1-4mJbrbwNZ8dTPp7cEGjFh65BN+8=", + "dev": true + }, + "js-tokens": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", + "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=", + "dev": true + }, + "js-yaml": { + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", + "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", + "dev": true, + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, + "jsesc": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", + "integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=", + "dev": true + }, + "json-buffer": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.0.tgz", + "integrity": "sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg=", + "dev": true + }, + "json-parse-better-errors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", + "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", + "dev": true + }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", + "dev": true + }, + "json5": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-0.5.1.tgz", + "integrity": "sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE=", + "dev": true + }, + "keyv": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-3.1.0.tgz", + "integrity": "sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA==", + "dev": true, + "requires": { + "json-buffer": "3.0.0" + } + }, + "latest-version": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/latest-version/-/latest-version-5.1.0.tgz", + "integrity": "sha512-weT+r0kTkRQdCdYCNtkMwWXQTMEswKrFBkm4ckQOMVhhqhIMI1UT2hMj+1iigIhgSZm5gTmrRXBNoGUgaTY1xA==", + "dev": true, + "requires": { + "package-json": "^6.3.0" + } + }, + "levn": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", + "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", + "dev": true, + "requires": { + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2" + } + }, + "load-json-file": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz", + "integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "parse-json": "^2.2.0", + "pify": "^2.0.0", + "strip-bom": "^3.0.0" + } + }, + "locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "dev": true, + "requires": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + } + }, + "lodash": { + "version": "4.17.15", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", + "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==", + "dev": true + }, + "lodash.clonedeep": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", + "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=", + "dev": true + }, + "lodash.flattendeep": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz", + "integrity": "sha1-+wMJF/hqMTTlvJvsDWngAT3f7bI=", + "dev": true + }, + "lodash.islength": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/lodash.islength/-/lodash.islength-4.0.1.tgz", + "integrity": "sha1-Tpho1FJXXXUK/9NYyXlUPcIO1Xc=", + "dev": true + }, + "lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true + }, + "log-symbols": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-2.2.0.tgz", + "integrity": "sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg==", + "dev": true, + "requires": { + "chalk": "^2.0.1" + } + }, + "loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "dev": true, + "requires": { + "js-tokens": "^3.0.0 || ^4.0.0" + } + }, + "loud-rejection": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/loud-rejection/-/loud-rejection-2.1.0.tgz", + "integrity": "sha512-g/6MQxUXYHeVqZ4PGpPL1fS1fOvlXoi7bay0pizmjAd/3JhyXwxzwrnr74yzdmhuerlslbRJ3x7IOXzFz0cE5w==", + "dev": true, + "requires": { + "currently-unhandled": "^0.4.1", + "signal-exit": "^3.0.2" + } + }, + "lowercase-keys": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz", + "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==", + "dev": true + }, + "lru-cache": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", + "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", + "dev": true, + "requires": { + "pseudomap": "^1.0.2", + "yallist": "^2.1.2" + } + }, + "magic-string": { + "version": "0.25.3", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.3.tgz", + "integrity": "sha512-6QK0OpF/phMz0Q2AxILkX2mFhi7m+WMwTRg0LQKq/WBB0cDP4rYH3Wp4/d3OTXlrPLVJT/RFqj8tFeAR4nk8AA==", + "requires": { + "sourcemap-codec": "^1.4.4" + } + }, + "make-dir": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.0.0.tgz", + "integrity": "sha512-grNJDhb8b1Jm1qeqW5R/O63wUo4UXo2v2HMic6YT9i/HBlF93S8jkMgH7yugvY9ABDShH4VZMn8I+U8+fCNegw==", + "dev": true, + "requires": { + "semver": "^6.0.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } + } + }, + "map-obj": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-2.0.0.tgz", + "integrity": "sha1-plzSkIepJZi4eRJXpSPgISIqwfk=", + "dev": true + }, + "matcher": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/matcher/-/matcher-2.0.0.tgz", + "integrity": "sha512-nlmfSlgHBFx36j/Pl/KQPbIaqE8Zf0TqmSMjsuddHDg6PMSVgmyW9HpkLs0o0M1n2GIZ/S2BZBLIww/xjhiGng==", + "dev": true, + "requires": { + "escape-string-regexp": "^2.0.0" + }, + "dependencies": { + "escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "dev": true + } + } + }, + "md5-hex": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/md5-hex/-/md5-hex-3.0.1.tgz", + "integrity": "sha512-BUiRtTtV39LIJwinWBjqVsU9xhdnz7/i889V859IBFpuqGAj6LuOvHv5XLbgZ2R7ptJoJaEcxkv88/h25T7Ciw==", + "dev": true, + "requires": { + "blueimp-md5": "^2.10.0" + } + }, + "md5-o-matic": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/md5-o-matic/-/md5-o-matic-0.1.1.tgz", + "integrity": "sha1-givM1l4RfFFPqxdrJZRdVBAKA8M=", + "dev": true + }, + "meow": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/meow/-/meow-5.0.0.tgz", + "integrity": "sha512-CbTqYU17ABaLefO8vCU153ZZlprKYWDljcndKKDCFcYQITzWCXZAVk4QMFZPgvzrnUQ3uItnIE/LoUOwrT15Ig==", + "dev": true, + "requires": { + "camelcase-keys": "^4.0.0", + "decamelize-keys": "^1.0.0", + "loud-rejection": "^1.0.0", + "minimist-options": "^3.0.1", + "normalize-package-data": "^2.3.4", + "read-pkg-up": "^3.0.0", + "redent": "^2.0.0", + "trim-newlines": "^2.0.0", + "yargs-parser": "^10.0.0" + }, + "dependencies": { + "load-json-file": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", + "integrity": "sha1-L19Fq5HjMhYjT9U62rZo607AmTs=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "parse-json": "^4.0.0", + "pify": "^3.0.0", + "strip-bom": "^3.0.0" + } + }, + "loud-rejection": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/loud-rejection/-/loud-rejection-1.6.0.tgz", + "integrity": "sha1-W0b4AUft7leIcPCG0Eghz5mOVR8=", + "dev": true, + "requires": { + "currently-unhandled": "^0.4.1", + "signal-exit": "^3.0.0" + } + }, + "parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", + "dev": true, + "requires": { + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" + } + }, + "path-type": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", + "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", + "dev": true, + "requires": { + "pify": "^3.0.0" + } + }, + "pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", + "dev": true + }, + "read-pkg": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", + "integrity": "sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k=", + "dev": true, + "requires": { + "load-json-file": "^4.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^3.0.0" + } + }, + "read-pkg-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-3.0.0.tgz", + "integrity": "sha1-PtSWaF26D4/hGNBpHcUfSh/5bwc=", + "dev": true, + "requires": { + "find-up": "^2.0.0", + "read-pkg": "^3.0.0" + } + } + } + }, + "merge-source-map": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/merge-source-map/-/merge-source-map-1.1.0.tgz", + "integrity": "sha512-Qkcp7P2ygktpMPh2mCQZaf3jhN6D3Z/qVZHSdWvQ+2Ef5HgRAPBO57A77+ENm0CPx2+1Ce/MYKi3ymqdfuqibw==", + "dev": true, + "requires": { + "source-map": "^0.6.1" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } + } + }, + "merge2": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.2.4.tgz", + "integrity": "sha512-FYE8xI+6pjFOhokZu0We3S5NKCirLbCzSh2Usf3qEyr4X8U+0jNg9P8RZ4qz+V2UoECLVwSyzU3LxXBaLGtD3A==", + "dev": true + }, + "micromatch": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz", + "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==", + "dev": true, + "requires": { + "braces": "^3.0.1", + "picomatch": "^2.0.5" + } + }, + "mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true + }, + "mimic-response": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", + "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==", + "dev": true + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", + "dev": true + }, + "minimist-options": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/minimist-options/-/minimist-options-3.0.2.tgz", + "integrity": "sha512-FyBrT/d0d4+uiZRbqznPXqw3IpZZG3gl3wKWiX784FycUKVwBt0uLBFkQrtE4tZOrgo78nZp2jnKz3L65T5LdQ==", + "dev": true, + "requires": { + "arrify": "^1.0.1", + "is-plain-obj": "^1.1.0" + }, + "dependencies": { + "arrify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", + "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", + "dev": true + } + } + }, + "mkdirp": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "dev": true, + "requires": { + "minimist": "0.0.8" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "mute-stream": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", + "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==", + "dev": true + }, + "natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", + "dev": true + }, + "neo-async": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.1.tgz", + "integrity": "sha512-iyam8fBuCUpWeKPGpaNMetEocMt364qkCsfL9JuhjXX6dRnguRVOfk2GZaDpPjcOKiiXCPINZC1GczQ7iTq3Zw==", + "dev": true + }, + "nested-error-stacks": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/nested-error-stacks/-/nested-error-stacks-2.1.0.tgz", + "integrity": "sha512-AO81vsIO1k1sM4Zrd6Hu7regmJN1NSiAja10gc4bX3F0wd+9rQmcuHQaHVQCYIEC8iFXnE+mavh23GOt7wBgug==", + "dev": true + }, + "nice-try": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", + "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", + "dev": true + }, + "normalize-package-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "dev": true, + "requires": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + } + }, + "normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true + }, + "normalize-url": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.3.0.tgz", + "integrity": "sha512-0NLtR71o4k6GLP+mr6Ty34c5GA6CMoEsncKJxvQd8NzPxaHRJNnb5gZE8R1XF4CPIS7QPHLJ74IFszwtNVAHVQ==", + "dev": true + }, + "npm-run-path": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", + "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", + "dev": true, + "requires": { + "path-key": "^2.0.0" + } + }, + "number-is-nan": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", + "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", + "dev": true + }, + "nyc": { + "version": "14.1.1", + "resolved": "https://registry.npmjs.org/nyc/-/nyc-14.1.1.tgz", + "integrity": "sha512-OI0vm6ZGUnoGZv/tLdZ2esSVzDwUC88SNs+6JoSOMVxA+gKMB8Tk7jBwgemLx4O40lhhvZCVw1C+OYLOBOPXWw==", + "dev": true, + "requires": { + "archy": "^1.0.0", + "caching-transform": "^3.0.2", + "convert-source-map": "^1.6.0", + "cp-file": "^6.2.0", + "find-cache-dir": "^2.1.0", + "find-up": "^3.0.0", + "foreground-child": "^1.5.6", + "glob": "^7.1.3", + "istanbul-lib-coverage": "^2.0.5", + "istanbul-lib-hook": "^2.0.7", + "istanbul-lib-instrument": "^3.3.0", + "istanbul-lib-report": "^2.0.8", + "istanbul-lib-source-maps": "^3.0.6", + "istanbul-reports": "^2.2.4", + "js-yaml": "^3.13.1", + "make-dir": "^2.1.0", + "merge-source-map": "^1.1.0", + "resolve-from": "^4.0.0", + "rimraf": "^2.6.3", + "signal-exit": "^3.0.2", + "spawn-wrap": "^1.4.2", + "test-exclude": "^5.2.3", + "uuid": "^3.3.2", + "yargs": "^13.2.2", + "yargs-parser": "^13.0.0" + }, + "dependencies": { + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true + }, + "find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "dev": true, + "requires": { + "locate-path": "^3.0.0" + } + }, + "locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "dev": true, + "requires": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + } + }, + "make-dir": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", + "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", + "dev": true, + "requires": { + "pify": "^4.0.1", + "semver": "^5.6.0" + } + }, + "p-limit": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.1.tgz", + "integrity": "sha512-85Tk+90UCVWvbDavCLKPOLC9vvY8OwEX/RtKF+/1OADJMVlFfEHOiMTPVyxg7mk/dKa+ipdHm0OUkTvCpMTuwg==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "dev": true, + "requires": { + "p-limit": "^2.0.0" + } + }, + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true + }, + "pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "dev": true + }, + "resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true + }, + "yargs-parser": { + "version": "13.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.1.tgz", + "integrity": "sha512-oVAVsHz6uFrg3XQheFII8ESO2ssAf9luWuAd6Wexsu4F3OtIW0o8IribPXYrD4WC24LWtPrJlGy87y5udK+dxQ==", + "dev": true, + "requires": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } + } + } + }, + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", + "dev": true + }, + "object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true + }, + "object.assign": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", + "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", + "dev": true, + "requires": { + "define-properties": "^1.1.2", + "function-bind": "^1.1.1", + "has-symbols": "^1.0.0", + "object-keys": "^1.0.11" + } + }, + "object.entries": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.0.tgz", + "integrity": "sha512-l+H6EQ8qzGRxbkHOd5I/aHRhHDKoQXQ8g0BYt4uSweQU1/J6dZUOyWh9a2Vky35YCKjzmgxOzta2hH6kf9HuXA==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.12.0", + "function-bind": "^1.1.1", + "has": "^1.0.3" + } + }, + "object.values": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.0.tgz", + "integrity": "sha512-8mf0nKLAoFX6VlNVdhGj31SVYpaNFtUnuoOXWyFEstsWRgU837AK+JYM0iAxwkSzGRbwn8cbFmgbyxj1j4VbXg==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.12.0", + "function-bind": "^1.1.1", + "has": "^1.0.3" + } + }, + "observable-to-promise": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/observable-to-promise/-/observable-to-promise-1.0.0.tgz", + "integrity": "sha512-cqnGUrNsE6vdVDTPAX9/WeVzwy/z37vdxupdQXU8vgTXRFH72KCZiZga8aca2ulRPIeem8W3vW9rQHBwfIl2WA==", + "dev": true, + "requires": { + "is-observable": "^2.0.0", + "symbol-observable": "^1.0.4" + } + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "requires": { + "wrappy": "1" + } + }, + "onetime": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.0.tgz", + "integrity": "sha512-5NcSkPHhwTVFIQN+TUqXoS5+dlElHXdpAWu9I0HP20YOtIi+aZ0Ct82jdlILDxjLEAWwvm+qj1m6aEtsDVmm6Q==", + "dev": true, + "requires": { + "mimic-fn": "^2.1.0" + } + }, + "optimist": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz", + "integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=", + "dev": true, + "requires": { + "minimist": "~0.0.1", + "wordwrap": "~0.0.2" + }, + "dependencies": { + "wordwrap": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz", + "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc=", + "dev": true + } + } + }, + "optionator": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz", + "integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=", + "dev": true, + "requires": { + "deep-is": "~0.1.3", + "fast-levenshtein": "~2.0.4", + "levn": "~0.3.0", + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2", + "wordwrap": "~1.0.0" + } + }, + "ora": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/ora/-/ora-3.4.0.tgz", + "integrity": "sha512-eNwHudNbO1folBP3JsZ19v9azXWtQZjICdr3Q0TDPIaeBQ3mXLrh54wM+er0+hSp+dWKf+Z8KM58CYzEyIYxYg==", + "dev": true, + "requires": { + "chalk": "^2.4.2", + "cli-cursor": "^2.1.0", + "cli-spinners": "^2.0.0", + "log-symbols": "^2.2.0", + "strip-ansi": "^5.2.0", + "wcwidth": "^1.0.1" + }, + "dependencies": { + "cli-cursor": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", + "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=", + "dev": true, + "requires": { + "restore-cursor": "^2.0.0" + } + }, + "mimic-fn": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz", + "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==", + "dev": true + }, + "onetime": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", + "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=", + "dev": true, + "requires": { + "mimic-fn": "^1.0.0" + } + }, + "restore-cursor": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", + "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=", + "dev": true, + "requires": { + "onetime": "^2.0.0", + "signal-exit": "^3.0.2" + } + } + } + }, + "os-homedir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", + "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", + "dev": true + }, + "os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", + "dev": true + }, + "p-cancelable": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-1.1.0.tgz", + "integrity": "sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw==", + "dev": true + }, + "p-finally": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", + "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", + "dev": true + }, + "p-limit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "dev": true, + "requires": { + "p-try": "^1.0.0" + } + }, + "p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "dev": true, + "requires": { + "p-limit": "^1.1.0" + } + }, + "p-map": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-2.1.0.tgz", + "integrity": "sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==", + "dev": true + }, + "p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", + "dev": true + }, + "package-hash": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/package-hash/-/package-hash-4.0.0.tgz", + "integrity": "sha512-whdkPIooSu/bASggZ96BWVvZTRMOFxnyUG5PnTSGKoJE2gd5mbVNmR2Nj20QFzxYYgAXpoqC+AiXzl+UMRh7zQ==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.15", + "hasha": "^5.0.0", + "lodash.flattendeep": "^4.4.0", + "release-zalgo": "^1.0.0" + } + }, + "package-json": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/package-json/-/package-json-6.5.0.tgz", + "integrity": "sha512-k3bdm2n25tkyxcjSKzB5x8kfVxlMdgsbPr0GkZcwHsLpba6cBjqCt1KlcChKEvxHIcTB1FVMuwoijZ26xex5MQ==", + "dev": true, + "requires": { + "got": "^9.6.0", + "registry-auth-token": "^4.0.0", + "registry-url": "^5.0.0", + "semver": "^6.2.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } + } + }, + "parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "requires": { + "callsites": "^3.0.0" + } + }, + "parse-json": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", + "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", + "dev": true, + "requires": { + "error-ex": "^1.2.0" + } + }, + "parse-ms": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/parse-ms/-/parse-ms-2.1.0.tgz", + "integrity": "sha512-kHt7kzLoS9VBZfUsiKjv43mr91ea+U05EyKkEtqp7vNbHxmaVuEqN7XxeEVnGrMtYOAxGrDElSi96K7EgO1zCA==", + "dev": true + }, + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "dev": true + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true + }, + "path-is-inside": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", + "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", + "dev": true + }, + "path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", + "dev": true + }, + "path-parse": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", + "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==" + }, + "path-type": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz", + "integrity": "sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM=", + "dev": true, + "requires": { + "pify": "^2.0.0" + } + }, + "picomatch": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.0.7.tgz", + "integrity": "sha512-oLHIdio3tZ0qH76NybpeneBhYVj0QFTfXEFTc/B3zKQspYfYYkWYgFsmzo+4kvId/bQRcNkVeguI3y+CD22BtA==", + "dev": true + }, + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + }, + "pinkie": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", + "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", + "dev": true + }, + "pinkie-promise": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", + "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", + "dev": true, + "requires": { + "pinkie": "^2.0.0" + } + }, + "pkg-conf": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/pkg-conf/-/pkg-conf-3.1.0.tgz", + "integrity": "sha512-m0OTbR/5VPNPqO1ph6Fqbj7Hv6QU7gR/tQW40ZqrL1rjgCU85W6C1bJn0BItuJqnR98PWzw7Z8hHeChD1WrgdQ==", + "dev": true, + "requires": { + "find-up": "^3.0.0", + "load-json-file": "^5.2.0" + }, + "dependencies": { + "find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "dev": true, + "requires": { + "locate-path": "^3.0.0" + } + }, + "load-json-file": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-5.3.0.tgz", + "integrity": "sha512-cJGP40Jc/VXUsp8/OrnyKyTZ1y6v/dphm3bioS+RrKXjK2BB6wHUd6JptZEFDGgGahMT+InnZO5i1Ei9mpC8Bw==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.15", + "parse-json": "^4.0.0", + "pify": "^4.0.1", + "strip-bom": "^3.0.0", + "type-fest": "^0.3.0" + } + }, + "locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "dev": true, + "requires": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + } + }, + "p-limit": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.1.tgz", + "integrity": "sha512-85Tk+90UCVWvbDavCLKPOLC9vvY8OwEX/RtKF+/1OADJMVlFfEHOiMTPVyxg7mk/dKa+ipdHm0OUkTvCpMTuwg==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "dev": true, + "requires": { + "p-limit": "^2.0.0" + } + }, + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true + }, + "parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", + "dev": true, + "requires": { + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" + } + }, + "pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "dev": true + }, + "type-fest": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.3.1.tgz", + "integrity": "sha512-cUGJnCdr4STbePCgqNFbpVNCepa+kAVohJs1sLhxzdH+gnEoOd8VhbYa7pD3zZYGiURWM2xzEII3fQcRizDkYQ==", + "dev": true + } + } + }, + "pkg-dir": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-2.0.0.tgz", + "integrity": "sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s=", + "dev": true, + "requires": { + "find-up": "^2.1.0" + } + }, + "plur": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/plur/-/plur-3.1.1.tgz", + "integrity": "sha512-t1Ax8KUvV3FFII8ltczPn2tJdjqbd1sIzu6t4JL7nQ3EyeL/lTrj5PWKb06ic5/6XYDr65rQ4uzQEGN70/6X5w==", + "dev": true, + "requires": { + "irregular-plurals": "^2.0.0" + } + }, + "prelude-ls": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", + "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", + "dev": true + }, + "prepend-http": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz", + "integrity": "sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc=", + "dev": true + }, + "pretty-ms": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/pretty-ms/-/pretty-ms-5.0.0.tgz", + "integrity": "sha512-94VRYjL9k33RzfKiGokPBPpsmloBYSf5Ri+Pq19zlsEcUKFob+admeXr5eFDRuPjFmEOcjJvPGdillYOJyvZ7Q==", + "dev": true, + "requires": { + "parse-ms": "^2.1.0" + } + }, + "private": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/private/-/private-0.1.8.tgz", + "integrity": "sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg==", + "dev": true + }, + "progress": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", + "dev": true + }, + "pseudomap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", + "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=", + "dev": true + }, + "pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "dev": true, + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "dev": true + }, + "quick-lru": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-1.1.0.tgz", + "integrity": "sha1-Q2CxfGETatOAeDl/8RQW4Ybc+7g=", + "dev": true + }, + "rc": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", + "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "dev": true, + "requires": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + }, + "dependencies": { + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "dev": true + } + } + }, + "read-pkg": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz", + "integrity": "sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg=", + "dev": true, + "requires": { + "load-json-file": "^2.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^2.0.0" + } + }, + "read-pkg-up": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz", + "integrity": "sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4=", + "dev": true, + "requires": { + "find-up": "^2.0.0", + "read-pkg": "^2.0.0" + } + }, + "readdirp": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.1.2.tgz", + "integrity": "sha512-8rhl0xs2cxfVsqzreYCvs8EwBfn/DhVdqtoLmw19uI3SC5avYX9teCurlErfpPXGmYtMHReGaP2RsLnFvz/lnw==", + "dev": true, + "requires": { + "picomatch": "^2.0.4" + } + }, + "redent": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/redent/-/redent-2.0.0.tgz", + "integrity": "sha1-wbIAe0LVfrE4kHmzyDM2OdXhzKo=", + "dev": true, + "requires": { + "indent-string": "^3.0.0", + "strip-indent": "^2.0.0" + }, + "dependencies": { + "indent-string": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-3.2.0.tgz", + "integrity": "sha1-Sl/W0nzDMvN+VBmlBNu4NxBckok=", + "dev": true + } + } + }, + "regenerate": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.0.tgz", + "integrity": "sha512-1G6jJVDWrt0rK99kBjvEtziZNCICAuvIPkSiUFIQxVP06RCVpq3dmDo2oi6ABpYaDYaTRr67BEhL8r1wgEZZKg==", + "dev": true + }, + "regenerate-unicode-properties": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-8.1.0.tgz", + "integrity": "sha512-LGZzkgtLY79GeXLm8Dp0BVLdQlWICzBnJz/ipWUgo59qBaZ+BHtq51P2q1uVZlppMuUAT37SDk39qUbjTWB7bA==", + "dev": true, + "requires": { + "regenerate": "^1.4.0" + } + }, + "regenerator-runtime": { + "version": "0.11.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz", + "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==", + "dev": true + }, + "regenerator-transform": { + "version": "0.10.1", + "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.10.1.tgz", + "integrity": "sha512-PJepbvDbuK1xgIgnau7Y90cwaAmO/LCLMI2mPvaXq2heGMR3aWW5/BQvYrhJ8jgmQjXewXvBjzfqKcVOmhjZ6Q==", + "dev": true, + "requires": { + "babel-runtime": "^6.18.0", + "babel-types": "^6.19.0", + "private": "^0.1.6" + } + }, + "regexpp": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-2.0.1.tgz", + "integrity": "sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw==", + "dev": true + }, + "regexpu-core": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-2.0.0.tgz", + "integrity": "sha1-SdA4g3uNz4v6W5pCE5k45uoq4kA=", + "dev": true, + "requires": { + "regenerate": "^1.2.1", + "regjsgen": "^0.2.0", + "regjsparser": "^0.1.4" + } + }, + "registry-auth-token": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-4.0.0.tgz", + "integrity": "sha512-lpQkHxd9UL6tb3k/aHAVfnVtn+Bcs9ob5InuFLLEDqSqeq+AljB8GZW9xY0x7F+xYwEcjKe07nyoxzEYz6yvkw==", + "dev": true, + "requires": { + "rc": "^1.2.8", + "safe-buffer": "^5.0.1" + } + }, + "registry-url": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-5.1.0.tgz", + "integrity": "sha512-8acYXXTI0AkQv6RAOjE3vOaIXZkT9wo4LOFbBKYQEEnnMNBpKqdUrI6S4NT0KPIo/WVvJ5tE/X5LF/TQUf0ekw==", + "dev": true, + "requires": { + "rc": "^1.2.8" + } + }, + "regjsgen": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.2.0.tgz", + "integrity": "sha1-bAFq3qxVT3WCP+N6wFuS1aTtsfc=", + "dev": true + }, + "regjsparser": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.1.5.tgz", + "integrity": "sha1-fuj4Tcb6eS0/0K4ijSS9lJ6tIFw=", + "dev": true, + "requires": { + "jsesc": "~0.5.0" + } + }, + "release-zalgo": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/release-zalgo/-/release-zalgo-1.0.0.tgz", + "integrity": "sha1-CXALflB0Mpc5Mw5TXFqQ+2eFFzA=", + "dev": true, + "requires": { + "es6-error": "^4.0.1" + } + }, + "repeating": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz", + "integrity": "sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo=", + "dev": true, + "requires": { + "is-finite": "^1.0.0" + } + }, + "require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", + "dev": true + }, + "require-main-filename": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", + "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", + "dev": true + }, + "require-precompiled": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/require-precompiled/-/require-precompiled-0.1.0.tgz", + "integrity": "sha1-WhtS63Dr7UPrmC6XTIWrWVceVvo=", + "dev": true + }, + "resolve": { + "version": "1.12.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.12.0.tgz", + "integrity": "sha512-B/dOmuoAik5bKcD6s6nXDCjzUKnaDvdkRyAk6rsmsKLipWj4797iothd7jmmUhWTfinVMU+wc56rYKsit2Qy4w==", + "requires": { + "path-parse": "^1.0.6" + } + }, + "resolve-cwd": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", + "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", + "dev": true, + "requires": { + "resolve-from": "^5.0.0" + } + }, + "resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true + }, + "responselike": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz", + "integrity": "sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec=", + "dev": true, + "requires": { + "lowercase-keys": "^1.0.0" + } + }, + "restore-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", + "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", + "dev": true, + "requires": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + } + }, + "reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true + }, + "rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + }, + "rollup": { + "version": "1.19.4", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-1.19.4.tgz", + "integrity": "sha512-G24w409GNj7i/Yam2cQla6qV2k6Nug8bD2DZg9v63QX/cH/dEdbNJg8H4lUm5M1bRpPKRUC465Rm9H51JTKOfQ==", + "dev": true, + "requires": { + "@types/estree": "0.0.39", + "@types/node": "^12.6.9", + "acorn": "^6.2.1" + }, + "dependencies": { + "acorn": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.3.0.tgz", + "integrity": "sha512-/czfa8BwS88b9gWQVhc8eknunSA2DoJpJyTQkhheIf5E48u1N0R4q/YxxsAeqRrmK9TQ/uYfgLDfZo91UlANIA==", + "dev": true + } + } + }, + "rollup-plugin-babel": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/rollup-plugin-babel/-/rollup-plugin-babel-4.3.3.tgz", + "integrity": "sha512-tKzWOCmIJD/6aKNz0H1GMM+lW1q9KyFubbWzGiOG540zxPPifnEAHTZwjo0g991Y+DyOZcLqBgqOdqazYE5fkw==", + "dev": true, + "requires": { + "@babel/helper-module-imports": "^7.0.0", + "rollup-pluginutils": "^2.8.1" + } + }, + "rollup-plugin-babel-minify": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/rollup-plugin-babel-minify/-/rollup-plugin-babel-minify-9.0.0.tgz", + "integrity": "sha512-5aJVWpuoZUbQrIaRF7Jvjo7bBnYqaChOhrhsGtz72wJ3lyo7ygIL85hsuPkvrk/3Fj5AUlNZV3IaSZ98fHyoTw==", + "dev": true, + "requires": { + "@babel/core": "^7.4.5", + "@babel/plugin-syntax-dynamic-import": "^7.2.0", + "@comandeer/babel-plugin-banner": "^5.0.0", + "babel-preset-minify": "^0.5.0", + "sourcemap-codec": "^1.4.4" + } + }, + "rollup-plugin-commonjs": { + "version": "10.0.2", + "resolved": "https://registry.npmjs.org/rollup-plugin-commonjs/-/rollup-plugin-commonjs-10.0.2.tgz", + "integrity": "sha512-DxeR4QXTgTOFseYls1V7vgKbrSJmPYNdEMOs0OvH+7+89C3GiIonU9gFrE0u39Vv1KWm3wepq8KAvKugtoM2Zw==", + "requires": { + "estree-walker": "^0.6.1", + "is-reference": "^1.1.2", + "magic-string": "^0.25.2", + "resolve": "^1.11.0", + "rollup-pluginutils": "^2.8.1" + } + }, + "rollup-plugin-node-resolve": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/rollup-plugin-node-resolve/-/rollup-plugin-node-resolve-5.2.0.tgz", + "integrity": "sha512-jUlyaDXts7TW2CqQ4GaO5VJ4PwwaV8VUGA7+km3n6k6xtOEacf61u0VXwN80phY/evMcaS+9eIeJ9MOyDxt5Zw==", + "dev": true, + "requires": { + "@types/resolve": "0.0.8", + "builtin-modules": "^3.1.0", + "is-module": "^1.0.0", + "resolve": "^1.11.1", + "rollup-pluginutils": "^2.8.1" + } + }, + "rollup-pluginutils": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/rollup-pluginutils/-/rollup-pluginutils-2.8.1.tgz", + "integrity": "sha512-J5oAoysWar6GuZo0s+3bZ6sVZAC0pfqKz68De7ZgDi5z63jOVZn1uJL/+z1jeKHNbGII8kAyHF5q8LnxSX5lQg==", + "requires": { + "estree-walker": "^0.6.1" + } + }, + "run-async": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.3.0.tgz", + "integrity": "sha1-A3GrSuC91yDUFm19/aZP96RFpsA=", + "dev": true, + "requires": { + "is-promise": "^2.1.0" + } + }, + "run-parallel": { + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.1.9.tgz", + "integrity": "sha512-DEqnSRTDw/Tc3FXf49zedI638Z9onwUotBMiUFKmrO2sdFKIbXamXGQ3Axd4qgphxKB4kw/qP1w5kTxnfU1B9Q==", + "dev": true + }, + "rxjs": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.2.tgz", + "integrity": "sha512-HUb7j3kvb7p7eCUHE3FqjoDsC1xfZQ4AHFWfTKSpZ+sAhhz5X1WX0ZuUqWbzB2QhSLp3DoLUG+hMdEDKqWo2Zg==", + "dev": true, + "requires": { + "tslib": "^1.9.0" + } + }, + "safe-buffer": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.0.tgz", + "integrity": "sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg==", + "dev": true + }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + }, + "semver-diff": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/semver-diff/-/semver-diff-2.1.0.tgz", + "integrity": "sha1-S7uEN8jTfksM8aaP1ybsbWRdbTY=", + "dev": true, + "requires": { + "semver": "^5.0.3" + } + }, + "serialize-error": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/serialize-error/-/serialize-error-2.1.0.tgz", + "integrity": "sha1-ULZ51WNc34Rme9yOWa9OW4HV9go=", + "dev": true + }, + "set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", + "dev": true + }, + "shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", + "dev": true, + "requires": { + "shebang-regex": "^1.0.0" + } + }, + "shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", + "dev": true + }, + "signal-exit": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", + "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", + "dev": true + }, + "slash": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-1.0.0.tgz", + "integrity": "sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU=", + "dev": true + }, + "slice-ansi": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz", + "integrity": "sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.0", + "astral-regex": "^1.0.0", + "is-fullwidth-code-point": "^2.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + } + } + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true + }, + "source-map-support": { + "version": "0.4.18", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.4.18.tgz", + "integrity": "sha512-try0/JqxPLF9nOjvSta7tVondkP5dwgyLDjVoyMDlmjugT2lRZ1OfsrYTkCd2hkDnJTKRbO/Rl3orm8vlsUzbA==", + "dev": true, + "requires": { + "source-map": "^0.5.6" + } + }, + "sourcemap-codec": { + "version": "1.4.6", + "resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.6.tgz", + "integrity": "sha512-1ZooVLYFxC448piVLBbtOxFcXwnymH9oUF8nRd3CuYDVvkRBxRl6pB4Mtas5a4drtL+E8LDgFkQNcgIw6tc8Hg==" + }, + "spawn-wrap": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/spawn-wrap/-/spawn-wrap-1.4.2.tgz", + "integrity": "sha512-vMwR3OmmDhnxCVxM8M+xO/FtIp6Ju/mNaDfCMMW7FDcLRTPFWUswec4LXJHTJE2hwTI9O0YBfygu4DalFl7Ylg==", + "dev": true, + "requires": { + "foreground-child": "^1.5.6", + "mkdirp": "^0.5.0", + "os-homedir": "^1.0.1", + "rimraf": "^2.6.2", + "signal-exit": "^3.0.2", + "which": "^1.3.0" + } + }, + "spdx-correct": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.0.tgz", + "integrity": "sha512-lr2EZCctC2BNR7j7WzJ2FpDznxky1sjfxvvYEyzxNyb6lZXHODmEoJeFu4JupYlkfha1KZpJyoqiJ7pgA1qq8Q==", + "dev": true, + "requires": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-exceptions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.2.0.tgz", + "integrity": "sha512-2XQACfElKi9SlVb1CYadKDXvoajPgBVPn/gOQLrTvHdElaVhr7ZEbqJaRnJLVNeaI4cMEAgVCeBMKF6MWRDCRA==", + "dev": true + }, + "spdx-expression-parse": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz", + "integrity": "sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg==", + "dev": true, + "requires": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-license-ids": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.5.tgz", + "integrity": "sha512-J+FWzZoynJEXGphVIS+XEh3kFSjZX/1i9gFBaWQcB+/tmpe2qUsSBABpcxqxnAxFdiUFEgAX1bjYGQvIZmoz9Q==", + "dev": true + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "dev": true + }, + "stack-utils": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-1.0.2.tgz", + "integrity": "sha512-MTX+MeG5U994cazkjd/9KNAapsHnibjMLnfXodlkXw76JEea0UiNzrqidzo1emMwk7w5Qhc9jd4Bn9TBb1MFwA==", + "dev": true + }, + "string-width": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.1.0.tgz", + "integrity": "sha512-NrX+1dVVh+6Y9dnQ19pR0pP4FiEIlUvdTGn8pw6CKTNq5sgib2nIhmUNT5TAmhWmvKr3WcxBcP3E8nWezuipuQ==", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^5.2.0" + }, + "dependencies": { + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true + } + } + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true + } + } + }, + "strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "dev": true + }, + "strip-bom-buf": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-bom-buf/-/strip-bom-buf-2.0.0.tgz", + "integrity": "sha512-gLFNHucd6gzb8jMsl5QmZ3QgnUJmp7qn4uUSHNwEXumAp7YizoGYw19ZUVfuq4aBOQUtyn2k8X/CwzWB73W2lQ==", + "dev": true, + "requires": { + "is-utf8": "^0.2.1" + } + }, + "strip-eof": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", + "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=", + "dev": true + }, + "strip-indent": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-2.0.0.tgz", + "integrity": "sha1-XvjbKV0B5u1sv3qrlpmNeCJSe2g=", + "dev": true + }, + "strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", + "dev": true + }, + "supertap": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supertap/-/supertap-1.0.0.tgz", + "integrity": "sha512-HZJ3geIMPgVwKk2VsmO5YHqnnJYl6bV5A9JW2uzqV43WmpgliNEYbuvukfor7URpaqpxuw3CfZ3ONdVbZjCgIA==", + "dev": true, + "requires": { + "arrify": "^1.0.1", + "indent-string": "^3.2.0", + "js-yaml": "^3.10.0", + "serialize-error": "^2.1.0", + "strip-ansi": "^4.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true + }, + "arrify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", + "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", + "dev": true + }, + "indent-string": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-3.2.0.tgz", + "integrity": "sha1-Sl/W0nzDMvN+VBmlBNu4NxBckok=", + "dev": true + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "requires": { + "ansi-regex": "^3.0.0" + } + } + } + }, + "supports-color": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.0.0.tgz", + "integrity": "sha512-WRt32iTpYEZWYOpcetGm0NPeSvaebccx7hhS/5M6sAiqnhedtFCHFxkjzZlJvFNCPowiKSFGiZk5USQDFy83vQ==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + }, + "dependencies": { + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + } + } + }, + "symbol-observable": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.2.0.tgz", + "integrity": "sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ==", + "dev": true + }, + "table": { + "version": "5.4.6", + "resolved": "https://registry.npmjs.org/table/-/table-5.4.6.tgz", + "integrity": "sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug==", + "dev": true, + "requires": { + "ajv": "^6.10.2", + "lodash": "^4.17.14", + "slice-ansi": "^2.1.0", + "string-width": "^3.0.0" + }, + "dependencies": { + "emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "dev": true + }, + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dev": true, + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + } + } + } + }, + "tailored": { + "version": "2.7.5", + "resolved": "https://registry.npmjs.org/tailored/-/tailored-2.7.5.tgz", + "integrity": "sha512-5zLODXUWx3P8SPVbFA9RgaUrpTGJMXg67jMaZJmJJwE9jQXuCfJb7bnO/1FuTsrFFZTDDmkYR/PPz9gAN26CmQ==", + "requires": { + "erlang-types": "^1.0.1" + } + }, + "term-size": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/term-size/-/term-size-1.2.0.tgz", + "integrity": "sha1-RYuDiH8oj8Vtb/+/rSYuJmOO+mk=", + "dev": true, + "requires": { + "execa": "^0.7.0" + } + }, + "test-exclude": { + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-5.2.3.tgz", + "integrity": "sha512-M+oxtseCFO3EDtAaGH7iiej3CBkzXqFMbzqYAACdzKui4eZA+pq3tZEwChvOdNfa7xxy8BfbmgJSIr43cC/+2g==", + "dev": true, + "requires": { + "glob": "^7.1.3", + "minimatch": "^3.0.4", + "read-pkg-up": "^4.0.0", + "require-main-filename": "^2.0.0" + }, + "dependencies": { + "find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "dev": true, + "requires": { + "locate-path": "^3.0.0" + } + }, + "load-json-file": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", + "integrity": "sha1-L19Fq5HjMhYjT9U62rZo607AmTs=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "parse-json": "^4.0.0", + "pify": "^3.0.0", + "strip-bom": "^3.0.0" + } + }, + "locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "dev": true, + "requires": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + } + }, + "p-limit": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.1.tgz", + "integrity": "sha512-85Tk+90UCVWvbDavCLKPOLC9vvY8OwEX/RtKF+/1OADJMVlFfEHOiMTPVyxg7mk/dKa+ipdHm0OUkTvCpMTuwg==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "dev": true, + "requires": { + "p-limit": "^2.0.0" + } + }, + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true + }, + "parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", + "dev": true, + "requires": { + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" + } + }, + "path-type": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", + "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", + "dev": true, + "requires": { + "pify": "^3.0.0" + } + }, + "pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", + "dev": true + }, + "read-pkg": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", + "integrity": "sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k=", + "dev": true, + "requires": { + "load-json-file": "^4.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^3.0.0" + } + }, + "read-pkg-up": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-4.0.0.tgz", + "integrity": "sha512-6etQSH7nJGsK0RbG/2TeDzZFa8shjQ1um+SwQQ5cwKy0dhSXdOncEhb1CPpvQG4h7FyOV6EB6YlV0yJvZQNAkA==", + "dev": true, + "requires": { + "find-up": "^3.0.0", + "read-pkg": "^3.0.0" + } + } + } + }, + "text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", + "dev": true + }, + "through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", + "dev": true + }, + "time-zone": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/time-zone/-/time-zone-1.0.0.tgz", + "integrity": "sha1-mcW/VZWJZq9tBtg73zgA3IL67F0=", + "dev": true + }, + "tmp": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", + "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "dev": true, + "requires": { + "os-tmpdir": "~1.0.2" + } + }, + "to-fast-properties": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-1.0.3.tgz", + "integrity": "sha1-uDVx+k2MJbguIxsG46MFXeTKGkc=", + "dev": true + }, + "to-readable-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/to-readable-stream/-/to-readable-stream-1.0.0.tgz", + "integrity": "sha512-Iq25XBt6zD5npPhlLVXGFN3/gyR2/qODcKNNyTMd4vbm39HUaOiAM4PMq0eMVC/Tkxz+Zjdsc55g9yyz+Yq00Q==", + "dev": true + }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "requires": { + "is-number": "^7.0.0" + } + }, + "trim-newlines": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-2.0.0.tgz", + "integrity": "sha1-tAPQuRvlDDMd/EuC7s6yLD3hbSA=", + "dev": true + }, + "trim-off-newlines": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/trim-off-newlines/-/trim-off-newlines-1.0.1.tgz", + "integrity": "sha1-n5up2e+odkw4dpi8v+sshI8RrbM=", + "dev": true + }, + "trim-right": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/trim-right/-/trim-right-1.0.1.tgz", + "integrity": "sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM=", + "dev": true + }, + "tslib": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.10.0.tgz", + "integrity": "sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ==", + "dev": true + }, + "type-check": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", + "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", + "dev": true, + "requires": { + "prelude-ls": "~1.1.2" + } + }, + "type-fest": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.5.2.tgz", + "integrity": "sha512-DWkS49EQKVX//Tbupb9TFa19c7+MK1XmzkrZUR8TAktmE/DizXoaoJV6TZ/tSIPXipqNiRI6CyAe7x69Jb6RSw==", + "dev": true + }, + "typedarray-to-buffer": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", + "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", + "dev": true, + "requires": { + "is-typedarray": "^1.0.0" + } + }, + "uglify-js": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.6.0.tgz", + "integrity": "sha512-W+jrUHJr3DXKhrsS7NUVxn3zqMOFn0hL/Ei6v0anCIMoKC93TjcflTagwIHLW7SfMFfiQuktQyFVCFHGUE0+yg==", + "dev": true, + "optional": true, + "requires": { + "commander": "~2.20.0", + "source-map": "~0.6.1" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "optional": true + } + } + }, + "uid2": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/uid2/-/uid2-0.0.3.tgz", + "integrity": "sha1-SDEm4Rd03y9xuLY53NeZw3YWK4I=", + "dev": true + }, + "unicode-canonical-property-names-ecmascript": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-1.0.4.tgz", + "integrity": "sha512-jDrNnXWHd4oHiTZnx/ZG7gtUTVp+gCcTTKr8L0HjlwphROEW3+Him+IpvC+xcJEFegapiMZyZe02CyuOnRmbnQ==", + "dev": true + }, + "unicode-match-property-ecmascript": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-1.0.4.tgz", + "integrity": "sha512-L4Qoh15vTfntsn4P1zqnHulG0LdXgjSO035fEpdtp6YxXhMT51Q6vgM5lYdG/5X3MjS+k/Y9Xw4SFCY9IkR0rg==", + "dev": true, + "requires": { + "unicode-canonical-property-names-ecmascript": "^1.0.4", + "unicode-property-aliases-ecmascript": "^1.0.4" + } + }, + "unicode-match-property-value-ecmascript": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-1.1.0.tgz", + "integrity": "sha512-hDTHvaBk3RmFzvSl0UVrUmC3PuW9wKVnpoUDYH0JDkSIovzw+J5viQmeYHxVSBptubnr7PbH2e0fnpDRQnQl5g==", + "dev": true + }, + "unicode-property-aliases-ecmascript": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-1.0.5.tgz", + "integrity": "sha512-L5RAqCfXqAwR3RriF8pM0lU0w4Ryf/GgzONwi6KnL1taJQa7x1TCxdJnILX59WIGOwR57IVxn7Nej0fz1Ny6fw==", + "dev": true + }, + "unique-string": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-1.0.0.tgz", + "integrity": "sha1-nhBXzKhRq7kzmPizOuGHuZyuwRo=", + "dev": true, + "requires": { + "crypto-random-string": "^1.0.0" + } + }, + "unique-temp-dir": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unique-temp-dir/-/unique-temp-dir-1.0.0.tgz", + "integrity": "sha1-bc6VsmgcoAPuv7MEpBX5y6vMU4U=", + "dev": true, + "requires": { + "mkdirp": "^0.5.1", + "os-tmpdir": "^1.0.1", + "uid2": "0.0.3" + } + }, + "update-notifier": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-3.0.1.tgz", + "integrity": "sha512-grrmrB6Zb8DUiyDIaeRTBCkgISYUgETNe7NglEbVsrLWXeESnlCSP50WfRSj/GmzMPl6Uchj24S/p80nP/ZQrQ==", + "dev": true, + "requires": { + "boxen": "^3.0.0", + "chalk": "^2.0.1", + "configstore": "^4.0.0", + "has-yarn": "^2.1.0", + "import-lazy": "^2.1.0", + "is-ci": "^2.0.0", + "is-installed-globally": "^0.1.0", + "is-npm": "^3.0.0", + "is-yarn-global": "^0.3.0", + "latest-version": "^5.0.0", + "semver-diff": "^2.0.0", + "xdg-basedir": "^3.0.0" + } + }, + "uri-js": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", + "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", + "dev": true, + "requires": { + "punycode": "^2.1.0" + } + }, + "url-parse-lax": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-3.0.0.tgz", + "integrity": "sha1-FrXK/Afb42dsGxmZF3gj1lA6yww=", + "dev": true, + "requires": { + "prepend-http": "^2.0.0" + } + }, + "uuid": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.3.tgz", + "integrity": "sha512-pW0No1RGHgzlpHJO1nsVrHKpOEIxkGg1xB+v0ZmdNH5OAeAwzAVrCnI2/6Mtx+Uys6iaylxa+D3g4j63IKKjSQ==", + "dev": true + }, + "v8-compile-cache": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.1.0.tgz", + "integrity": "sha512-usZBT3PW+LOjM25wbqIlZwPeJV+3OSz3M1k1Ws8snlW39dZyYL9lOGC5FgPVHfk0jKmjiDV8Z0mIbVQPiwFs7g==", + "dev": true + }, + "validate-npm-package-license": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", + "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "dev": true, + "requires": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "wcwidth": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", + "integrity": "sha1-8LDc+RW8X/FSivrbLA4XtTLaL+g=", + "dev": true, + "requires": { + "defaults": "^1.0.3" + } + }, + "well-known-symbols": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/well-known-symbols/-/well-known-symbols-2.0.0.tgz", + "integrity": "sha512-ZMjC3ho+KXo0BfJb7JgtQ5IBuvnShdlACNkKkdsqBmYw3bPAaJfPeYUo6tLUaT5tG/Gkh7xkpBhKRQ9e7pyg9Q==", + "dev": true + }, + "which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + }, + "which-module": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", + "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", + "dev": true + }, + "widest-line": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-2.0.1.tgz", + "integrity": "sha512-Ba5m9/Fa4Xt9eb2ELXt77JxVDV8w7qQrH0zS/TWSJdLyAwQjWoOzpzj5lwVftDz6n/EOu3tNACS84v509qwnJA==", + "dev": true, + "requires": { + "string-width": "^2.1.1" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true + }, + "string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "dev": true, + "requires": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + } + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "requires": { + "ansi-regex": "^3.0.0" + } + } + } + }, + "wordwrap": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", + "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=", + "dev": true + }, + "wrap-ansi": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", + "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.0", + "string-width": "^3.0.0", + "strip-ansi": "^5.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "dev": true + }, + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dev": true, + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + } + } + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + }, + "write": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/write/-/write-1.0.3.tgz", + "integrity": "sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig==", + "dev": true, + "requires": { + "mkdirp": "^0.5.1" + } + }, + "write-file-atomic": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.0.tgz", + "integrity": "sha512-EIgkf60l2oWsffja2Sf2AL384dx328c0B+cIYPTQq5q2rOYuDV00/iPFBOUiDKKwKMOhkymH8AidPaRvzfxY+Q==", + "dev": true, + "requires": { + "imurmurhash": "^0.1.4", + "is-typedarray": "^1.0.0", + "signal-exit": "^3.0.2", + "typedarray-to-buffer": "^3.1.5" + } + }, + "xdg-basedir": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-3.0.0.tgz", + "integrity": "sha1-SWsswQnsqNus/i3HK2A8F8WHCtQ=", + "dev": true + }, + "xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "dev": true + }, + "y18n": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", + "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==", + "dev": true + }, + "yallist": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", + "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", + "dev": true + }, + "yargs": { + "version": "13.3.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.0.tgz", + "integrity": "sha512-2eehun/8ALW8TLoIl7MVaRUrg+yCnenu8B4kBlRxj3GJGDKU1Og7sMXPNm1BYyM1DOJmTZ4YeN/Nwxv+8XJsUA==", + "dev": true, + "requires": { + "cliui": "^5.0.0", + "find-up": "^3.0.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^3.0.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^13.1.1" + }, + "dependencies": { + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true + }, + "emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "dev": true + }, + "find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "dev": true, + "requires": { + "locate-path": "^3.0.0" + } + }, + "locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "dev": true, + "requires": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + } + }, + "p-limit": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.1.tgz", + "integrity": "sha512-85Tk+90UCVWvbDavCLKPOLC9vvY8OwEX/RtKF+/1OADJMVlFfEHOiMTPVyxg7mk/dKa+ipdHm0OUkTvCpMTuwg==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "dev": true, + "requires": { + "p-limit": "^2.0.0" + } + }, + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true + }, + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dev": true, + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + } + }, + "yargs-parser": { + "version": "13.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.1.tgz", + "integrity": "sha512-oVAVsHz6uFrg3XQheFII8ESO2ssAf9luWuAd6Wexsu4F3OtIW0o8IribPXYrD4WC24LWtPrJlGy87y5udK+dxQ==", + "dev": true, + "requires": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } + } + } + }, + "yargs-parser": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-10.1.0.tgz", + "integrity": "sha512-VCIyR1wJoEBZUqk5PA+oOBF6ypbwh5aNB3I50guxAL/quggdfs4TtNHQrSazFA3fYZ+tEqfs0zIGlv0c/rgjbQ==", + "dev": true, + "requires": { + "camelcase": "^4.1.0" + } + } + } +} diff --git a/package.json b/package.json index e1e114c9..3acb3b42 100644 --- a/package.json +++ b/package.json @@ -25,23 +25,23 @@ "dependencies": { "erlang-types": "^1.0.1", "grapheme-splitter": "^1.0.2", - "rollup-plugin-commonjs": "^8.2.1", + "rollup-plugin-commonjs": "^10.0.2", "tailored": "^2.7.4" }, "devDependencies": { "@std/esm": "^0.8.3", - "ava": "^0.22.0", + "ava": "^2.3.0", "babel-core": "^6.26.0", "babel-preset-env": "^1.6.0", "babel-register": "^6.26.0", - "eslint": "^4.6.1", - "eslint-config-airbnb-base": "^12.0.0", + "eslint": "^6.2.1", + "eslint-config-airbnb-base": "^14.0.0", "eslint-plugin-import": "^2.7.0", - "nyc": "^11.2.1", - "rollup": "^0.49.3", - "rollup-plugin-babel": "^3.0.2", - "rollup-plugin-babel-minify": "^3.1.2", - "rollup-plugin-node-resolve": "^3.0.0" + "nyc": "^14.1.1", + "rollup": "^1.19.4", + "rollup-plugin-babel": "^4.3.3", + "rollup-plugin-babel-minify": "^9.0.0", + "rollup-plugin-node-resolve": "^5.2.0" }, "ava": { "require": [ diff --git a/priv/testrunner/esm/index.js b/priv/testrunner/esm/index.js index 7f6018cd..5eb27ed1 100644 --- a/priv/testrunner/esm/index.js +++ b/priv/testrunner/esm/index.js @@ -1,49 +1,48 @@ /* eslint strict: off, node/no-unsupported-features: ["error", { version: 4 }] */ -"use strict" -const fs = require("fs") -const path = require("path") -const util = require("util") -const vm = require("vm") -const zlib = require("zlib") +'use strict'; -const esmPath = path.resolve(__dirname, "esm.js.gz") -const inspectKey = util.inspect.custom || "inspect" +const fs = require('fs'); +const path = require('path'); +const util = require('util'); +const vm = require('vm'); +const zlib = require('zlib'); -const descriptor = Object.create(null) -descriptor.value = () => "@std/esm enabled" +const esmPath = path.resolve(__dirname, 'esm.js.gz'); +const inspectKey = util.inspect.custom || 'inspect'; -const mod = new module.constructor(module.id) -mod.filename = __filename -mod.parent = module.parent +const descriptor = Object.create(null); +descriptor.value = () => '@std/esm enabled'; -const scriptOptions = Object.create(null) -scriptOptions.filename = __filename +const mod = new module.constructor(module.id); +mod.filename = __filename; +mod.parent = module.parent; + +const scriptOptions = Object.create(null); +scriptOptions.filename = __filename; const content = - "(function(require,module,__filename){" + - zlib.gunzipSync(fs.readFileSync(esmPath)).toString() + - "\n})" + `(function(require,module,__filename){${ + zlib.gunzipSync(fs.readFileSync(esmPath)).toString() + }\n})`; -const compiled = vm.runInThisContext(content, scriptOptions) +const compiled = vm.runInThisContext(content, scriptOptions); function makeLoaderFunction() { - compiled(require, mod, __filename) - return mod.exports + compiled(require, mod, __filename); + return mod.exports; } -const loader = makeLoaderFunction() +const loader = makeLoaderFunction(); module.exports = (mod, options) => { - const type = typeof options + const type = typeof options; - if (options === true || - type === "function" || - (type === "object" && options !== null)) { - return makeLoaderFunction()(mod, options) + if (options === true || type === 'function' || (type === 'object' && options !== null)) { + return makeLoaderFunction()(mod, options); } - return loader(mod, options) -} + return loader(mod, options); +}; -Object.freeze(Object.defineProperty(module.exports, inspectKey, descriptor)) +Object.freeze(Object.defineProperty(module.exports, inspectKey, descriptor)); diff --git a/priv/testrunner/vendor.build.js b/priv/testrunner/vendor.build.js index 9d49e34d..f83931bf 100644 --- a/priv/testrunner/vendor.build.js +++ b/priv/testrunner/vendor.build.js @@ -1,2 +1,2 @@ -class Tuple{constructor(...a){this.values=Object.freeze(a),this.length=this.values.length}get(a){return this.values[a]}count(){return this.values.length}[Symbol.iterator](){return this.values[Symbol.iterator]()}toString(){let a,b='';for(a=0;a'}}let ref_counter=-1;class Reference{constructor(){++ref_counter,this.id=ref_counter,this.ref=Symbol()}toString(){return'Ref#<0.0.0.'+this.id+'>'}}class BitString{constructor(...a){this.value=Object.freeze(this.process(a)),this.length=this.value.length,this.bit_size=8*this.length,this.byte_size=this.length}get(a){return this.value[a]}count(){return this.value.length}slice(a,b=null){let c=this.value.slice(a,b),d=c.map((a)=>BitString.integer(a));return new BitString(...d)}[Symbol.iterator](){return this.value[Symbol.iterator]()}toString(){var a,b='';for(a=0;a>'}process(a){let b=[];var c;for(c=0;cb?c.push(b):2048>b?c.push(192|b>>6,128|63&b):55296>b||57344<=b?c.push(224|b>>12,128|63&b>>6,128|63&b):(d++,b=65536+((1023&b)<<10|1023&a.charCodeAt(d)),c.push(240|b>>18,128|63&b>>12,128|63&b>>6,128|63&b));return c}static toUTF16Array(a){for(var b,c=[],d=0;d=b?(c.push(0),c.push(b)):(c.push(255&b>>8),c.push(255&b));return c}static toUTF32Array(a){for(var b,c=[],d=0;d=b?(c.push(0),c.push(0),c.push(0),c.push(b)):(c.push(0),c.push(0),c.push(255&b>>8),c.push(255&b));return c}//http://stackoverflow.com/questions/2003493/javascript-float-from-to-bits -static float32ToBytes(a){var b=[],c=new ArrayBuffer(4);new Float32Array(c)[0]=a;let d=new Uint32Array(c)[0];return b.push(255&d>>24),b.push(255&d>>16),b.push(255&d>>8),b.push(255&d),b}static float64ToBytes(a){var b=[],c=new ArrayBuffer(8);new Float64Array(c)[0]=a;var d=new Uint32Array(c)[0],e=new Uint32Array(c)[1];return b.push(255&e>>24),b.push(255&e>>16),b.push(255&e>>8),b.push(255&e),b.push(255&d>>24),b.push(255&d>>16),b.push(255&d>>8),b.push(255&d),b}}var ErlangTypes={Tuple,PID,Reference,BitString},vendor={ErlangTypes};export default vendor; +function unwrapExports(a){return a&&a.__esModule&&Object.prototype.hasOwnProperty.call(a,"default")?a["default"]:a}function createCommonjsModule(a,b){return b={exports:{}},a(b,b.exports),b.exports}var tuple=createCommonjsModule(function(a,b){Object.defineProperty(b,"__esModule",{value:!0});class Tuple{constructor(...a){this.values=Object.freeze(a),this.length=this.values.length}get(a){return this.values[a]}count(){return this.values.length}[Symbol.iterator](){return this.values[Symbol.iterator]()}toString(){let a,b="";for(a=0;a"}}});unwrapExports(pid);var pid_1=pid.PID,reference=createCommonjsModule(function(a,b){Object.defineProperty(b,"__esModule",{value:!0});let c=-1;b.Reference=class Reference{constructor(){++c,this.id=c,this.ref=Symbol()}toString(){return"Ref#<0.0.0."+this.id+">"}}});unwrapExports(reference);var reference_1=reference.Reference,bit_string=createCommonjsModule(function(a,b){Object.defineProperty(b,"__esModule",{value:!0});class BitString{constructor(...a){this.value=Object.freeze(this.process(a)),this.length=this.value.length,this.bit_size=8*this.length,this.byte_size=this.length}get(a){return this.value[a]}count(){return this.value.length}slice(a,b=void 0){let c=this.value.slice(a,b),d=c.map(a=>BitString.integer(a));return new BitString(...d)}[Symbol.iterator](){return this.value[Symbol.iterator]()}toString(){var a,b="";for(a=0;a>"}process(a){let b=[];var c;for(c=0;cb?c.push(b):2048>b?c.push(192|b>>6,128|63&b):55296>b||57344<=b?c.push(224|b>>12,128|63&b>>6,128|63&b):(d++,b=65536+((1023&b)<<10|1023&a.charCodeAt(d)),c.push(240|b>>18,128|63&b>>12,128|63&b>>6,128|63&b));return c}static toUTF16Array(a){for(var b,c=[],d=0;d=b?(c.push(0),c.push(b)):(c.push(255&b>>8),c.push(255&b)));return c}static toUTF32Array(a){for(var b,c=[],d=0;d=b?(c.push(0),c.push(0),c.push(0),c.push(b)):(c.push(0),c.push(0),c.push(255&b>>8),c.push(255&b)));return c}//http://stackoverflow.com/questions/2003493/javascript-float-from-to-bits +static float32ToBytes(a){var b=[],c=new ArrayBuffer(4);new Float32Array(c)[0]=a;let d=new Uint32Array(c)[0];return b.push(255&d>>24),b.push(255&d>>16),b.push(255&d>>8),b.push(255&d),b}static float64ToBytes(a){var b=[],c=new ArrayBuffer(8);new Float64Array(c)[0]=a;var d=new Uint32Array(c)[0],e=new Uint32Array(c)[1];return b.push(255&e>>24),b.push(255&e>>16),b.push(255&e>>8),b.push(255&e),b.push(255&d>>24),b.push(255&d>>16),b.push(255&d>>8),b.push(255&d),b}}b.BitString=BitString});unwrapExports(bit_string);var bit_string_1=bit_string.BitString,lib=createCommonjsModule(function(a,b){Object.defineProperty(b,"__esModule",{value:!0}),b.Tuple=tuple.Tuple,b.PID=pid.PID,b.Reference=reference.Reference,b.BitString=bit_string.BitString}),ErlangTypes=unwrapExports(lib),lib_1=lib.Tuple,lib_2=lib.PID,lib_3=lib.Reference,lib_4=lib.BitString,vendor={ErlangTypes};export default vendor; diff --git a/rollup.config.js b/rollup.config.js index 58a95b70..dbdce767 100644 --- a/rollup.config.js +++ b/rollup.config.js @@ -1,13 +1,12 @@ -const rollup = require('rollup'); -const babel = require('rollup-plugin-babel'); -const nodeResolve = require('rollup-plugin-node-resolve'); -const commonjs = require('rollup-plugin-commonjs'); -const minify = require('rollup-plugin-babel-minify'); +const rollup = require('rollup') +const babel = require('rollup-plugin-babel') +const nodeResolve = require('rollup-plugin-node-resolve') +const commonjs = require('rollup-plugin-commonjs') +const minify = require('rollup-plugin-babel-minify') const plugins = [ nodeResolve({ - jsnext: true, - main: true, + mainFields: ['jsnext', 'main'], }), commonjs(), babel({ @@ -17,33 +16,37 @@ const plugins = [ keepFnName: true, keepClassName: true, }), -]; +] rollup .rollup({ input: 'src/javascript/elixir.js', - output: 'priv/build/es/ElixirScript.Core.js', - sourcemap: 'inline', - format: 'es', + output: { + file: 'priv/build/es/ElixirScript.Core.js', + format: 'es', + }, plugins, }) - .then((bundle) => { + .then(bundle => { bundle.write({ format: 'es', file: 'priv/build/es/ElixirScript.Core.js', - }); - }); + sourcemap: 'inline', + }) + }) rollup .rollup({ input: 'priv/testrunner/vendor.js', - output: 'priv/testrunner/vendor.build.js', - format: 'es', + output: { + file: 'priv/testrunner/vendor.build.js', + format: 'es', + }, plugins, }) - .then((bundle) => { + .then(bundle => { bundle.write({ format: 'es', file: 'priv/testrunner/vendor.build.js', - }); - }); + }) + }) diff --git a/yarn.lock b/yarn.lock deleted file mode 100644 index 2772e27d..00000000 --- a/yarn.lock +++ /dev/null @@ -1,4242 +0,0 @@ -# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. -# yarn lockfile v1 - - -"@ava/babel-plugin-throws-helper@^2.0.0": - version "2.0.0" - resolved "https://registry.yarnpkg.com/@ava/babel-plugin-throws-helper/-/babel-plugin-throws-helper-2.0.0.tgz#2fc1fe3c211a71071a4eca7b8f7af5842cd1ae7c" - -"@ava/babel-preset-stage-4@^1.1.0": - version "1.1.0" - resolved "https://registry.yarnpkg.com/@ava/babel-preset-stage-4/-/babel-preset-stage-4-1.1.0.tgz#ae60be881a0babf7d35f52aba770d1f6194f76bd" - dependencies: - babel-plugin-check-es2015-constants "^6.8.0" - babel-plugin-syntax-trailing-function-commas "^6.20.0" - babel-plugin-transform-async-to-generator "^6.16.0" - babel-plugin-transform-es2015-destructuring "^6.19.0" - babel-plugin-transform-es2015-function-name "^6.9.0" - babel-plugin-transform-es2015-modules-commonjs "^6.18.0" - babel-plugin-transform-es2015-parameters "^6.21.0" - babel-plugin-transform-es2015-spread "^6.8.0" - babel-plugin-transform-es2015-sticky-regex "^6.8.0" - babel-plugin-transform-es2015-unicode-regex "^6.11.0" - babel-plugin-transform-exponentiation-operator "^6.8.0" - package-hash "^1.2.0" - -"@ava/babel-preset-transform-test-files@^3.0.0": - version "3.0.0" - resolved "https://registry.yarnpkg.com/@ava/babel-preset-transform-test-files/-/babel-preset-transform-test-files-3.0.0.tgz#cded1196a8d8d9381a509240ab92e91a5ec069f7" - dependencies: - "@ava/babel-plugin-throws-helper" "^2.0.0" - babel-plugin-espower "^2.3.2" - -"@ava/write-file-atomic@^2.2.0": - version "2.2.0" - resolved "https://registry.yarnpkg.com/@ava/write-file-atomic/-/write-file-atomic-2.2.0.tgz#d625046f3495f1f5e372135f473909684b429247" - dependencies: - graceful-fs "^4.1.11" - imurmurhash "^0.1.4" - slide "^1.1.5" - -"@comandeer/babel-plugin-banner@^1.0.0": - version "1.0.0" - resolved "https://registry.yarnpkg.com/@comandeer/babel-plugin-banner/-/babel-plugin-banner-1.0.0.tgz#40bcce0bbee084b5b02545a33635d053c248356f" - -"@concordance/react@^1.0.0": - version "1.0.0" - resolved "https://registry.yarnpkg.com/@concordance/react/-/react-1.0.0.tgz#fcf3cad020e5121bfd1c61d05bc3516aac25f734" - dependencies: - arrify "^1.0.1" - -"@std/esm@^0.8.3": - version "0.8.3" - resolved "https://registry.yarnpkg.com/@std/esm/-/esm-0.8.3.tgz#7a3c3144ca0905c9b92d82b79987503ecb58a193" - -abbrev@1: - version "1.1.0" - resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.0.tgz#d0554c2256636e2f56e7c2e5ad183f859428d81f" - -acorn-jsx@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-3.0.1.tgz#afdf9488fb1ecefc8348f6fb22f464e32a58b36b" - dependencies: - acorn "^3.0.4" - -acorn@^3.0.4: - version "3.3.0" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-3.3.0.tgz#45e37fb39e8da3f25baee3ff5369e2bb5f22017a" - -acorn@^5.1.1: - version "5.1.2" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.1.2.tgz#911cb53e036807cf0fa778dc5d370fbd864246d7" - -acorn@^5.5.0: - version "5.7.3" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.7.3.tgz#67aa231bf8812974b85235a96771eb6bd07ea279" - -ajv-keywords@^2.1.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-2.1.1.tgz#617997fc5f60576894c435f940d819e135b80762" - -ajv@^4.9.1: - version "4.11.8" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-4.11.8.tgz#82ffb02b29e662ae53bdc20af15947706739c536" - dependencies: - co "^4.6.0" - json-stable-stringify "^1.0.1" - -ajv@^5.2.3, ajv@^5.3.0: - version "5.5.2" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-5.5.2.tgz#73b5eeca3fab653e3d3f9422b341ad42205dc965" - dependencies: - co "^4.6.0" - fast-deep-equal "^1.0.0" - fast-json-stable-stringify "^2.0.0" - json-schema-traverse "^0.3.0" - -align-text@^0.1.1, align-text@^0.1.3: - version "0.1.4" - resolved "https://registry.yarnpkg.com/align-text/-/align-text-0.1.4.tgz#0cd90a561093f35d0a99256c22b7069433fad117" - dependencies: - kind-of "^3.0.2" - longest "^1.0.1" - repeat-string "^1.5.2" - -amdefine@>=0.0.4: - version "1.0.1" - resolved "https://registry.yarnpkg.com/amdefine/-/amdefine-1.0.1.tgz#4a5282ac164729e93619bcfd3ad151f817ce91f5" - -ansi-align@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/ansi-align/-/ansi-align-2.0.0.tgz#c36aeccba563b89ceb556f3690f0b1d9e3547f7f" - dependencies: - string-width "^2.0.0" - -ansi-escapes@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-2.0.0.tgz#5bae52be424878dd9783e8910e3fc2922e83c81b" - -ansi-regex@^2.0.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" - -ansi-regex@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998" - -ansi-styles@^2.2.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe" - -ansi-styles@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.1.0.tgz#09c202d5c917ec23188caa5c9cb9179cd9547750" - dependencies: - color-convert "^1.0.0" - -ansi-styles@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-1.0.0.tgz#cb102df1c56f5123eab8b67cd7b98027a0279178" - -anymatch@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-1.3.0.tgz#a3e52fa39168c825ff57b0248126ce5a8ff95507" - dependencies: - arrify "^1.0.0" - micromatch "^2.1.5" - -append-transform@^0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/append-transform/-/append-transform-0.4.0.tgz#d76ebf8ca94d276e247a36bad44a4b74ab611991" - dependencies: - default-require-extensions "^1.0.0" - -aproba@^1.0.3: - version "1.1.2" - resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.1.2.tgz#45c6629094de4e96f693ef7eab74ae079c240fc1" - -archy@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/archy/-/archy-1.0.0.tgz#f9c8c13757cc1dd7bc379ac77b2c62a5c2868c40" - -are-we-there-yet@~1.1.2: - version "1.1.4" - resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-1.1.4.tgz#bb5dca382bb94f05e15194373d16fd3ba1ca110d" - dependencies: - delegates "^1.0.0" - readable-stream "^2.0.6" - -argparse@^1.0.7: - version "1.0.9" - resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.9.tgz#73d83bc263f86e97f8cc4f6bae1b0e90a7d22c86" - dependencies: - sprintf-js "~1.0.2" - -arr-diff@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-2.0.0.tgz#8f3b827f955a8bd669697e4a4256ac3ceae356cf" - dependencies: - arr-flatten "^1.0.1" - -arr-exclude@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/arr-exclude/-/arr-exclude-1.0.0.tgz#dfc7c2e552a270723ccda04cf3128c8cbfe5c631" - -arr-flatten@^1.0.1: - version "1.0.3" - resolved "https://registry.yarnpkg.com/arr-flatten/-/arr-flatten-1.0.3.tgz#a274ed85ac08849b6bd7847c4580745dc51adfb1" - -array-differ@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/array-differ/-/array-differ-1.0.0.tgz#eff52e3758249d33be402b8bb8e564bb2b5d4031" - -array-find-index@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/array-find-index/-/array-find-index-1.0.2.tgz#df010aa1287e164bbda6f9723b0a96a1ec4187a1" - -array-union@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/array-union/-/array-union-1.0.2.tgz#9a34410e4f4e3da23dea375be5be70f24778ec39" - dependencies: - array-uniq "^1.0.1" - -array-uniq@^1.0.1, array-uniq@^1.0.2: - version "1.0.3" - resolved "https://registry.yarnpkg.com/array-uniq/-/array-uniq-1.0.3.tgz#af6ac877a25cc7f74e058894753858dfdb24fdb6" - -array-unique@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.2.1.tgz#a1d97ccafcbc2625cc70fadceb36a50c58b01a53" - -arrify@^1.0.0, arrify@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d" - -asn1@~0.2.3: - version "0.2.4" - resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.4.tgz#8d2475dfab553bb33e77b54e59e880bb8ce23136" - dependencies: - safer-buffer "~2.1.0" - -assert-plus@1.0.0, assert-plus@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" - -assert-plus@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-0.2.0.tgz#d74e1b87e7affc0db8aadb7021f3fe48101ab234" - -async-each@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/async-each/-/async-each-1.0.1.tgz#19d386a1d9edc6e7c1c85d388aedbcc56d33602d" - -async@^1.4.0: - version "1.5.2" - resolved "https://registry.yarnpkg.com/async/-/async-1.5.2.tgz#ec6a61ae56480c0c3cb241c95618e20892f9672a" - -asynckit@^0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" - -auto-bind@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/auto-bind/-/auto-bind-1.1.0.tgz#93b864dc7ee01a326281775d5c75ca0a751e5961" - -ava-init@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/ava-init/-/ava-init-0.2.0.tgz#9304c8b4c357d66e3dfdae1fbff47b1199d5c55d" - dependencies: - arr-exclude "^1.0.0" - execa "^0.5.0" - has-yarn "^1.0.0" - read-pkg-up "^2.0.0" - write-pkg "^2.0.0" - -ava@^0.22.0: - version "0.22.0" - resolved "https://registry.yarnpkg.com/ava/-/ava-0.22.0.tgz#4c28a1fdef7e749ba0c8131ac18a7ca489eef049" - dependencies: - "@ava/babel-preset-stage-4" "^1.1.0" - "@ava/babel-preset-transform-test-files" "^3.0.0" - "@ava/write-file-atomic" "^2.2.0" - "@concordance/react" "^1.0.0" - ansi-escapes "^2.0.0" - ansi-styles "^3.1.0" - arr-flatten "^1.0.1" - array-union "^1.0.1" - array-uniq "^1.0.2" - arrify "^1.0.0" - auto-bind "^1.1.0" - ava-init "^0.2.0" - babel-core "^6.17.0" - bluebird "^3.0.0" - caching-transform "^1.0.0" - chalk "^2.0.1" - chokidar "^1.4.2" - clean-stack "^1.1.1" - clean-yaml-object "^0.1.0" - cli-cursor "^2.1.0" - cli-spinners "^1.0.0" - cli-truncate "^1.0.0" - co-with-promise "^4.6.0" - code-excerpt "^2.1.0" - common-path-prefix "^1.0.0" - concordance "^3.0.0" - convert-source-map "^1.2.0" - core-assert "^0.2.0" - currently-unhandled "^0.4.1" - debug "^2.2.0" - dot-prop "^4.1.0" - empower-core "^0.6.1" - equal-length "^1.0.0" - figures "^2.0.0" - find-cache-dir "^1.0.0" - fn-name "^2.0.0" - get-port "^3.0.0" - globby "^6.0.0" - has-flag "^2.0.0" - hullabaloo-config-manager "^1.1.0" - ignore-by-default "^1.0.0" - import-local "^0.1.1" - indent-string "^3.0.0" - is-ci "^1.0.7" - is-generator-fn "^1.0.0" - is-obj "^1.0.0" - is-observable "^0.2.0" - is-promise "^2.1.0" - js-yaml "^3.8.2" - last-line-stream "^1.0.0" - lodash.clonedeepwith "^4.5.0" - lodash.debounce "^4.0.3" - lodash.difference "^4.3.0" - lodash.flatten "^4.2.0" - loud-rejection "^1.2.0" - make-dir "^1.0.0" - matcher "^1.0.0" - md5-hex "^2.0.0" - meow "^3.7.0" - ms "^2.0.0" - multimatch "^2.1.0" - observable-to-promise "^0.5.0" - option-chain "^1.0.0" - package-hash "^2.0.0" - pkg-conf "^2.0.0" - plur "^2.0.0" - pretty-ms "^2.0.0" - require-precompiled "^0.1.0" - resolve-cwd "^2.0.0" - safe-buffer "^5.1.1" - slash "^1.0.0" - source-map-support "^0.4.0" - stack-utils "^1.0.0" - strip-ansi "^4.0.0" - strip-bom-buf "^1.0.0" - supports-color "^4.0.0" - time-require "^0.1.2" - trim-off-newlines "^1.0.1" - unique-temp-dir "^1.0.0" - update-notifier "^2.1.0" - -aws-sign2@~0.6.0: - version "0.6.0" - resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.6.0.tgz#14342dd38dbcc94d0e5b87d763cd63612c0e794f" - -aws4@^1.2.1: - version "1.6.0" - resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.6.0.tgz#83ef5ca860b2b32e4a0deedee8c771b9db57471e" - -babel-code-frame@^6.22.0, babel-code-frame@^6.26.0: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-code-frame/-/babel-code-frame-6.26.0.tgz#63fd43f7dc1e3bb7ce35947db8fe369a3f58c74b" - dependencies: - chalk "^1.1.3" - esutils "^2.0.2" - js-tokens "^3.0.2" - -babel-core@^6.17.0, babel-core@^6.21.0, babel-core@^6.24.1: - version "6.25.0" - resolved "https://registry.yarnpkg.com/babel-core/-/babel-core-6.25.0.tgz#7dd42b0463c742e9d5296deb3ec67a9322dad729" - dependencies: - babel-code-frame "^6.22.0" - babel-generator "^6.25.0" - babel-helpers "^6.24.1" - babel-messages "^6.23.0" - babel-register "^6.24.1" - babel-runtime "^6.22.0" - babel-template "^6.25.0" - babel-traverse "^6.25.0" - babel-types "^6.25.0" - babylon "^6.17.2" - convert-source-map "^1.1.0" - debug "^2.1.1" - json5 "^0.5.0" - lodash "^4.2.0" - minimatch "^3.0.2" - path-is-absolute "^1.0.0" - private "^0.1.6" - slash "^1.0.0" - source-map "^0.5.0" - -babel-core@^6.26.0: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-core/-/babel-core-6.26.0.tgz#af32f78b31a6fcef119c87b0fd8d9753f03a0bb8" - dependencies: - babel-code-frame "^6.26.0" - babel-generator "^6.26.0" - babel-helpers "^6.24.1" - babel-messages "^6.23.0" - babel-register "^6.26.0" - babel-runtime "^6.26.0" - babel-template "^6.26.0" - babel-traverse "^6.26.0" - babel-types "^6.26.0" - babylon "^6.18.0" - convert-source-map "^1.5.0" - debug "^2.6.8" - json5 "^0.5.1" - lodash "^4.17.4" - minimatch "^3.0.4" - path-is-absolute "^1.0.1" - private "^0.1.7" - slash "^1.0.0" - source-map "^0.5.6" - -babel-generator@^6.1.0, babel-generator@^6.18.0, babel-generator@^6.25.0: - version "6.25.0" - resolved "https://registry.yarnpkg.com/babel-generator/-/babel-generator-6.25.0.tgz#33a1af70d5f2890aeb465a4a7793c1df6a9ea9fc" - dependencies: - babel-messages "^6.23.0" - babel-runtime "^6.22.0" - babel-types "^6.25.0" - detect-indent "^4.0.0" - jsesc "^1.3.0" - lodash "^4.2.0" - source-map "^0.5.0" - trim-right "^1.0.1" - -babel-generator@^6.26.0: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-generator/-/babel-generator-6.26.0.tgz#ac1ae20070b79f6e3ca1d3269613053774f20dc5" - dependencies: - babel-messages "^6.23.0" - babel-runtime "^6.26.0" - babel-types "^6.26.0" - detect-indent "^4.0.0" - jsesc "^1.3.0" - lodash "^4.17.4" - source-map "^0.5.6" - trim-right "^1.0.1" - -babel-helper-builder-binary-assignment-operator-visitor@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-helper-builder-binary-assignment-operator-visitor/-/babel-helper-builder-binary-assignment-operator-visitor-6.24.1.tgz#cce4517ada356f4220bcae8a02c2b346f9a56664" - dependencies: - babel-helper-explode-assignable-expression "^6.24.1" - babel-runtime "^6.22.0" - babel-types "^6.24.1" - -babel-helper-call-delegate@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-helper-call-delegate/-/babel-helper-call-delegate-6.24.1.tgz#ece6aacddc76e41c3461f88bfc575bd0daa2df8d" - dependencies: - babel-helper-hoist-variables "^6.24.1" - babel-runtime "^6.22.0" - babel-traverse "^6.24.1" - babel-types "^6.24.1" - -babel-helper-define-map@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-helper-define-map/-/babel-helper-define-map-6.24.1.tgz#7a9747f258d8947d32d515f6aa1c7bd02204a080" - dependencies: - babel-helper-function-name "^6.24.1" - babel-runtime "^6.22.0" - babel-types "^6.24.1" - lodash "^4.2.0" - -babel-helper-evaluate-path@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/babel-helper-evaluate-path/-/babel-helper-evaluate-path-0.2.0.tgz#0bb2eb01996c0cef53c5e8405e999fe4a0244c08" - -babel-helper-explode-assignable-expression@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-helper-explode-assignable-expression/-/babel-helper-explode-assignable-expression-6.24.1.tgz#f25b82cf7dc10433c55f70592d5746400ac22caa" - dependencies: - babel-runtime "^6.22.0" - babel-traverse "^6.24.1" - babel-types "^6.24.1" - -babel-helper-flip-expressions@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/babel-helper-flip-expressions/-/babel-helper-flip-expressions-0.2.0.tgz#160d2090a3d9f9c64a750905321a0bc218f884ec" - -babel-helper-function-name@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-helper-function-name/-/babel-helper-function-name-6.24.1.tgz#d3475b8c03ed98242a25b48351ab18399d3580a9" - dependencies: - babel-helper-get-function-arity "^6.24.1" - babel-runtime "^6.22.0" - babel-template "^6.24.1" - babel-traverse "^6.24.1" - babel-types "^6.24.1" - -babel-helper-get-function-arity@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-helper-get-function-arity/-/babel-helper-get-function-arity-6.24.1.tgz#8f7782aa93407c41d3aa50908f89b031b1b6853d" - dependencies: - babel-runtime "^6.22.0" - babel-types "^6.24.1" - -babel-helper-hoist-variables@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-helper-hoist-variables/-/babel-helper-hoist-variables-6.24.1.tgz#1ecb27689c9d25513eadbc9914a73f5408be7a76" - dependencies: - babel-runtime "^6.22.0" - babel-types "^6.24.1" - -babel-helper-is-nodes-equiv@^0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/babel-helper-is-nodes-equiv/-/babel-helper-is-nodes-equiv-0.0.1.tgz#34e9b300b1479ddd98ec77ea0bbe9342dfe39684" - -babel-helper-is-void-0@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/babel-helper-is-void-0/-/babel-helper-is-void-0-0.2.0.tgz#6ed0ada8a9b1c5b6e88af6b47c1b3b5c080860eb" - -babel-helper-mark-eval-scopes@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/babel-helper-mark-eval-scopes/-/babel-helper-mark-eval-scopes-0.2.0.tgz#7648aaf2ec92aae9b09a20ad91e8df5e1fcc94b2" - -babel-helper-optimise-call-expression@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-helper-optimise-call-expression/-/babel-helper-optimise-call-expression-6.24.1.tgz#f7a13427ba9f73f8f4fa993c54a97882d1244257" - dependencies: - babel-runtime "^6.22.0" - babel-types "^6.24.1" - -babel-helper-regex@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-helper-regex/-/babel-helper-regex-6.24.1.tgz#d36e22fab1008d79d88648e32116868128456ce8" - dependencies: - babel-runtime "^6.22.0" - babel-types "^6.24.1" - lodash "^4.2.0" - -babel-helper-remap-async-to-generator@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-helper-remap-async-to-generator/-/babel-helper-remap-async-to-generator-6.24.1.tgz#5ec581827ad723fecdd381f1c928390676e4551b" - dependencies: - babel-helper-function-name "^6.24.1" - babel-runtime "^6.22.0" - babel-template "^6.24.1" - babel-traverse "^6.24.1" - babel-types "^6.24.1" - -babel-helper-remove-or-void@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/babel-helper-remove-or-void/-/babel-helper-remove-or-void-0.2.0.tgz#8e46ad5b30560d57d7510b3fd93f332ee7c67386" - -babel-helper-replace-supers@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-helper-replace-supers/-/babel-helper-replace-supers-6.24.1.tgz#bf6dbfe43938d17369a213ca8a8bf74b6a90ab1a" - dependencies: - babel-helper-optimise-call-expression "^6.24.1" - babel-messages "^6.23.0" - babel-runtime "^6.22.0" - babel-template "^6.24.1" - babel-traverse "^6.24.1" - babel-types "^6.24.1" - -babel-helper-to-multiple-sequence-expressions@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/babel-helper-to-multiple-sequence-expressions/-/babel-helper-to-multiple-sequence-expressions-0.2.0.tgz#d1a419634c6cb301f27858c659167cfee0a9d318" - -babel-helpers@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-helpers/-/babel-helpers-6.24.1.tgz#3471de9caec388e5c850e597e58a26ddf37602b2" - dependencies: - babel-runtime "^6.22.0" - babel-template "^6.24.1" - -babel-messages@^6.23.0: - version "6.23.0" - resolved "https://registry.yarnpkg.com/babel-messages/-/babel-messages-6.23.0.tgz#f3cdf4703858035b2a2951c6ec5edf6c62f2630e" - dependencies: - babel-runtime "^6.22.0" - -babel-plugin-check-es2015-constants@^6.22.0, babel-plugin-check-es2015-constants@^6.8.0: - version "6.22.0" - resolved "https://registry.yarnpkg.com/babel-plugin-check-es2015-constants/-/babel-plugin-check-es2015-constants-6.22.0.tgz#35157b101426fd2ffd3da3f75c7d1e91835bbf8a" - dependencies: - babel-runtime "^6.22.0" - -babel-plugin-espower@^2.3.2: - version "2.3.2" - resolved "https://registry.yarnpkg.com/babel-plugin-espower/-/babel-plugin-espower-2.3.2.tgz#5516b8fcdb26c9f0e1d8160749f6e4c65e71271e" - dependencies: - babel-generator "^6.1.0" - babylon "^6.1.0" - call-matcher "^1.0.0" - core-js "^2.0.0" - espower-location-detector "^1.0.0" - espurify "^1.6.0" - estraverse "^4.1.1" - -babel-plugin-minify-builtins@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/babel-plugin-minify-builtins/-/babel-plugin-minify-builtins-0.2.0.tgz#317f824b0907210b6348671bb040ca072e2e0c82" - dependencies: - babel-helper-evaluate-path "^0.2.0" - -babel-plugin-minify-constant-folding@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/babel-plugin-minify-constant-folding/-/babel-plugin-minify-constant-folding-0.2.0.tgz#8c70b528b2eb7c13e94d95c8789077d4cdbc3970" - dependencies: - babel-helper-evaluate-path "^0.2.0" - -babel-plugin-minify-dead-code-elimination@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/babel-plugin-minify-dead-code-elimination/-/babel-plugin-minify-dead-code-elimination-0.2.0.tgz#e8025ee10a1e5e4f202633a6928ce892c33747e3" - dependencies: - babel-helper-evaluate-path "^0.2.0" - babel-helper-mark-eval-scopes "^0.2.0" - babel-helper-remove-or-void "^0.2.0" - lodash.some "^4.6.0" - -babel-plugin-minify-flip-comparisons@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/babel-plugin-minify-flip-comparisons/-/babel-plugin-minify-flip-comparisons-0.2.0.tgz#0c9c8e93155c8f09dedad8118b634c259f709ef5" - dependencies: - babel-helper-is-void-0 "^0.2.0" - -babel-plugin-minify-guarded-expressions@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/babel-plugin-minify-guarded-expressions/-/babel-plugin-minify-guarded-expressions-0.2.0.tgz#8a8c950040fce3e258a12e6eb21eab94ad7235ab" - dependencies: - babel-helper-flip-expressions "^0.2.0" - -babel-plugin-minify-infinity@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/babel-plugin-minify-infinity/-/babel-plugin-minify-infinity-0.2.0.tgz#30960c615ddbc657c045bb00a1d8eb4af257cf03" - -babel-plugin-minify-mangle-names@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/babel-plugin-minify-mangle-names/-/babel-plugin-minify-mangle-names-0.2.0.tgz#719892297ff0106a6ec1a4b0fc062f1f8b6a8529" - dependencies: - babel-helper-mark-eval-scopes "^0.2.0" - -babel-plugin-minify-numeric-literals@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/babel-plugin-minify-numeric-literals/-/babel-plugin-minify-numeric-literals-0.2.0.tgz#5746e851700167a380c05e93f289a7070459a0d1" - -babel-plugin-minify-replace@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/babel-plugin-minify-replace/-/babel-plugin-minify-replace-0.2.0.tgz#3c1f06bc4e6d3e301eacb763edc1be611efc39b0" - -babel-plugin-minify-simplify@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/babel-plugin-minify-simplify/-/babel-plugin-minify-simplify-0.2.0.tgz#21ceec4857100c5476d7cef121f351156e5c9bc0" - dependencies: - babel-helper-flip-expressions "^0.2.0" - babel-helper-is-nodes-equiv "^0.0.1" - babel-helper-to-multiple-sequence-expressions "^0.2.0" - -babel-plugin-minify-type-constructors@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/babel-plugin-minify-type-constructors/-/babel-plugin-minify-type-constructors-0.2.0.tgz#7f3b6458be0863cfd59e9985bed6d134aa7a2e17" - dependencies: - babel-helper-is-void-0 "^0.2.0" - -babel-plugin-syntax-async-functions@^6.8.0: - version "6.13.0" - resolved "https://registry.yarnpkg.com/babel-plugin-syntax-async-functions/-/babel-plugin-syntax-async-functions-6.13.0.tgz#cad9cad1191b5ad634bf30ae0872391e0647be95" - -babel-plugin-syntax-exponentiation-operator@^6.8.0: - version "6.13.0" - resolved "https://registry.yarnpkg.com/babel-plugin-syntax-exponentiation-operator/-/babel-plugin-syntax-exponentiation-operator-6.13.0.tgz#9ee7e8337290da95288201a6a57f4170317830de" - -babel-plugin-syntax-trailing-function-commas@^6.20.0, babel-plugin-syntax-trailing-function-commas@^6.22.0: - version "6.22.0" - resolved "https://registry.yarnpkg.com/babel-plugin-syntax-trailing-function-commas/-/babel-plugin-syntax-trailing-function-commas-6.22.0.tgz#ba0360937f8d06e40180a43fe0d5616fff532cf3" - -babel-plugin-transform-async-to-generator@^6.16.0, babel-plugin-transform-async-to-generator@^6.22.0: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-async-to-generator/-/babel-plugin-transform-async-to-generator-6.24.1.tgz#6536e378aff6cb1d5517ac0e40eb3e9fc8d08761" - dependencies: - babel-helper-remap-async-to-generator "^6.24.1" - babel-plugin-syntax-async-functions "^6.8.0" - babel-runtime "^6.22.0" - -babel-plugin-transform-es2015-arrow-functions@^6.22.0: - version "6.22.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-arrow-functions/-/babel-plugin-transform-es2015-arrow-functions-6.22.0.tgz#452692cb711d5f79dc7f85e440ce41b9f244d221" - dependencies: - babel-runtime "^6.22.0" - -babel-plugin-transform-es2015-block-scoped-functions@^6.22.0: - version "6.22.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-block-scoped-functions/-/babel-plugin-transform-es2015-block-scoped-functions-6.22.0.tgz#bbc51b49f964d70cb8d8e0b94e820246ce3a6141" - dependencies: - babel-runtime "^6.22.0" - -babel-plugin-transform-es2015-block-scoping@^6.23.0: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-block-scoping/-/babel-plugin-transform-es2015-block-scoping-6.24.1.tgz#76c295dc3a4741b1665adfd3167215dcff32a576" - dependencies: - babel-runtime "^6.22.0" - babel-template "^6.24.1" - babel-traverse "^6.24.1" - babel-types "^6.24.1" - lodash "^4.2.0" - -babel-plugin-transform-es2015-classes@^6.23.0: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-classes/-/babel-plugin-transform-es2015-classes-6.24.1.tgz#5a4c58a50c9c9461e564b4b2a3bfabc97a2584db" - dependencies: - babel-helper-define-map "^6.24.1" - babel-helper-function-name "^6.24.1" - babel-helper-optimise-call-expression "^6.24.1" - babel-helper-replace-supers "^6.24.1" - babel-messages "^6.23.0" - babel-runtime "^6.22.0" - babel-template "^6.24.1" - babel-traverse "^6.24.1" - babel-types "^6.24.1" - -babel-plugin-transform-es2015-computed-properties@^6.22.0: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-computed-properties/-/babel-plugin-transform-es2015-computed-properties-6.24.1.tgz#6fe2a8d16895d5634f4cd999b6d3480a308159b3" - dependencies: - babel-runtime "^6.22.0" - babel-template "^6.24.1" - -babel-plugin-transform-es2015-destructuring@^6.19.0, babel-plugin-transform-es2015-destructuring@^6.23.0: - version "6.23.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-destructuring/-/babel-plugin-transform-es2015-destructuring-6.23.0.tgz#997bb1f1ab967f682d2b0876fe358d60e765c56d" - dependencies: - babel-runtime "^6.22.0" - -babel-plugin-transform-es2015-duplicate-keys@^6.22.0: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-duplicate-keys/-/babel-plugin-transform-es2015-duplicate-keys-6.24.1.tgz#73eb3d310ca969e3ef9ec91c53741a6f1576423e" - dependencies: - babel-runtime "^6.22.0" - babel-types "^6.24.1" - -babel-plugin-transform-es2015-for-of@^6.23.0: - version "6.23.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-for-of/-/babel-plugin-transform-es2015-for-of-6.23.0.tgz#f47c95b2b613df1d3ecc2fdb7573623c75248691" - dependencies: - babel-runtime "^6.22.0" - -babel-plugin-transform-es2015-function-name@^6.22.0, babel-plugin-transform-es2015-function-name@^6.9.0: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-function-name/-/babel-plugin-transform-es2015-function-name-6.24.1.tgz#834c89853bc36b1af0f3a4c5dbaa94fd8eacaa8b" - dependencies: - babel-helper-function-name "^6.24.1" - babel-runtime "^6.22.0" - babel-types "^6.24.1" - -babel-plugin-transform-es2015-literals@^6.22.0: - version "6.22.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-literals/-/babel-plugin-transform-es2015-literals-6.22.0.tgz#4f54a02d6cd66cf915280019a31d31925377ca2e" - dependencies: - babel-runtime "^6.22.0" - -babel-plugin-transform-es2015-modules-amd@^6.22.0, babel-plugin-transform-es2015-modules-amd@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-amd/-/babel-plugin-transform-es2015-modules-amd-6.24.1.tgz#3b3e54017239842d6d19c3011c4bd2f00a00d154" - dependencies: - babel-plugin-transform-es2015-modules-commonjs "^6.24.1" - babel-runtime "^6.22.0" - babel-template "^6.24.1" - -babel-plugin-transform-es2015-modules-commonjs@^6.18.0, babel-plugin-transform-es2015-modules-commonjs@^6.23.0, babel-plugin-transform-es2015-modules-commonjs@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-commonjs/-/babel-plugin-transform-es2015-modules-commonjs-6.24.1.tgz#d3e310b40ef664a36622200097c6d440298f2bfe" - dependencies: - babel-plugin-transform-strict-mode "^6.24.1" - babel-runtime "^6.22.0" - babel-template "^6.24.1" - babel-types "^6.24.1" - -babel-plugin-transform-es2015-modules-systemjs@^6.23.0: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-systemjs/-/babel-plugin-transform-es2015-modules-systemjs-6.24.1.tgz#ff89a142b9119a906195f5f106ecf305d9407d23" - dependencies: - babel-helper-hoist-variables "^6.24.1" - babel-runtime "^6.22.0" - babel-template "^6.24.1" - -babel-plugin-transform-es2015-modules-umd@^6.23.0: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-umd/-/babel-plugin-transform-es2015-modules-umd-6.24.1.tgz#ac997e6285cd18ed6176adb607d602344ad38468" - dependencies: - babel-plugin-transform-es2015-modules-amd "^6.24.1" - babel-runtime "^6.22.0" - babel-template "^6.24.1" - -babel-plugin-transform-es2015-object-super@^6.22.0: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-object-super/-/babel-plugin-transform-es2015-object-super-6.24.1.tgz#24cef69ae21cb83a7f8603dad021f572eb278f8d" - dependencies: - babel-helper-replace-supers "^6.24.1" - babel-runtime "^6.22.0" - -babel-plugin-transform-es2015-parameters@^6.21.0, babel-plugin-transform-es2015-parameters@^6.23.0: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-parameters/-/babel-plugin-transform-es2015-parameters-6.24.1.tgz#57ac351ab49caf14a97cd13b09f66fdf0a625f2b" - dependencies: - babel-helper-call-delegate "^6.24.1" - babel-helper-get-function-arity "^6.24.1" - babel-runtime "^6.22.0" - babel-template "^6.24.1" - babel-traverse "^6.24.1" - babel-types "^6.24.1" - -babel-plugin-transform-es2015-shorthand-properties@^6.22.0: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-shorthand-properties/-/babel-plugin-transform-es2015-shorthand-properties-6.24.1.tgz#24f875d6721c87661bbd99a4622e51f14de38aa0" - dependencies: - babel-runtime "^6.22.0" - babel-types "^6.24.1" - -babel-plugin-transform-es2015-spread@^6.22.0, babel-plugin-transform-es2015-spread@^6.8.0: - version "6.22.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-spread/-/babel-plugin-transform-es2015-spread-6.22.0.tgz#d6d68a99f89aedc4536c81a542e8dd9f1746f8d1" - dependencies: - babel-runtime "^6.22.0" - -babel-plugin-transform-es2015-sticky-regex@^6.22.0, babel-plugin-transform-es2015-sticky-regex@^6.8.0: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-sticky-regex/-/babel-plugin-transform-es2015-sticky-regex-6.24.1.tgz#00c1cdb1aca71112cdf0cf6126c2ed6b457ccdbc" - dependencies: - babel-helper-regex "^6.24.1" - babel-runtime "^6.22.0" - babel-types "^6.24.1" - -babel-plugin-transform-es2015-template-literals@^6.22.0: - version "6.22.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-template-literals/-/babel-plugin-transform-es2015-template-literals-6.22.0.tgz#a84b3450f7e9f8f1f6839d6d687da84bb1236d8d" - dependencies: - babel-runtime "^6.22.0" - -babel-plugin-transform-es2015-typeof-symbol@^6.23.0: - version "6.23.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-typeof-symbol/-/babel-plugin-transform-es2015-typeof-symbol-6.23.0.tgz#dec09f1cddff94b52ac73d505c84df59dcceb372" - dependencies: - babel-runtime "^6.22.0" - -babel-plugin-transform-es2015-unicode-regex@^6.11.0, babel-plugin-transform-es2015-unicode-regex@^6.22.0: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-unicode-regex/-/babel-plugin-transform-es2015-unicode-regex-6.24.1.tgz#d38b12f42ea7323f729387f18a7c5ae1faeb35e9" - dependencies: - babel-helper-regex "^6.24.1" - babel-runtime "^6.22.0" - regexpu-core "^2.0.0" - -babel-plugin-transform-exponentiation-operator@^6.22.0, babel-plugin-transform-exponentiation-operator@^6.8.0: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-exponentiation-operator/-/babel-plugin-transform-exponentiation-operator-6.24.1.tgz#2ab0c9c7f3098fa48907772bb813fe41e8de3a0e" - dependencies: - babel-helper-builder-binary-assignment-operator-visitor "^6.24.1" - babel-plugin-syntax-exponentiation-operator "^6.8.0" - babel-runtime "^6.22.0" - -babel-plugin-transform-inline-consecutive-adds@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-inline-consecutive-adds/-/babel-plugin-transform-inline-consecutive-adds-0.2.0.tgz#15dae78921057f4004f8eafd79e15ddc5f12f426" - -babel-plugin-transform-member-expression-literals@^6.8.5: - version "6.8.5" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-member-expression-literals/-/babel-plugin-transform-member-expression-literals-6.8.5.tgz#e06ae305cf48d819822e93a70d79269f04d89eec" - -babel-plugin-transform-merge-sibling-variables@^6.8.6: - version "6.8.6" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-merge-sibling-variables/-/babel-plugin-transform-merge-sibling-variables-6.8.6.tgz#6d21efa5ee4981f71657fae716f9594bb2622aef" - -babel-plugin-transform-minify-booleans@^6.8.3: - version "6.8.3" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-minify-booleans/-/babel-plugin-transform-minify-booleans-6.8.3.tgz#5906ed776d3718250519abf1bace44b0b613ddf9" - -babel-plugin-transform-property-literals@^6.8.5: - version "6.8.5" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-property-literals/-/babel-plugin-transform-property-literals-6.8.5.tgz#67ed5930b34805443452c8b9690c7ebe1e206c40" - dependencies: - esutils "^2.0.2" - -babel-plugin-transform-regenerator@^6.22.0: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-regenerator/-/babel-plugin-transform-regenerator-6.24.1.tgz#b8da305ad43c3c99b4848e4fe4037b770d23c418" - dependencies: - regenerator-transform "0.9.11" - -babel-plugin-transform-regexp-constructors@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-regexp-constructors/-/babel-plugin-transform-regexp-constructors-0.2.0.tgz#6aa5dd0acc515db4be929bbcec4ed4c946c534a3" - -babel-plugin-transform-remove-console@^6.8.5: - version "6.8.5" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-remove-console/-/babel-plugin-transform-remove-console-6.8.5.tgz#fde9d2d3d725530b0fadd8d31078402410386810" - -babel-plugin-transform-remove-debugger@^6.8.5: - version "6.8.5" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-remove-debugger/-/babel-plugin-transform-remove-debugger-6.8.5.tgz#809584d412bf918f071fdf41e1fdb15ea89cdcd5" - -babel-plugin-transform-remove-undefined@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-remove-undefined/-/babel-plugin-transform-remove-undefined-0.2.0.tgz#94f052062054c707e8d094acefe79416b63452b1" - dependencies: - babel-helper-evaluate-path "^0.2.0" - -babel-plugin-transform-simplify-comparison-operators@^6.8.5: - version "6.8.5" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-simplify-comparison-operators/-/babel-plugin-transform-simplify-comparison-operators-6.8.5.tgz#a838786baf40cc33a93b95ae09e05591227e43bf" - -babel-plugin-transform-strict-mode@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-strict-mode/-/babel-plugin-transform-strict-mode-6.24.1.tgz#d5faf7aa578a65bbe591cf5edae04a0c67020758" - dependencies: - babel-runtime "^6.22.0" - babel-types "^6.24.1" - -babel-plugin-transform-undefined-to-void@^6.8.3: - version "6.8.3" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-undefined-to-void/-/babel-plugin-transform-undefined-to-void-6.8.3.tgz#fc52707f6ee1ddc71bb91b0d314fbefdeef9beb4" - -babel-preset-env@^1.6.0: - version "1.6.0" - resolved "https://registry.yarnpkg.com/babel-preset-env/-/babel-preset-env-1.6.0.tgz#2de1c782a780a0a5d605d199c957596da43c44e4" - dependencies: - babel-plugin-check-es2015-constants "^6.22.0" - babel-plugin-syntax-trailing-function-commas "^6.22.0" - babel-plugin-transform-async-to-generator "^6.22.0" - babel-plugin-transform-es2015-arrow-functions "^6.22.0" - babel-plugin-transform-es2015-block-scoped-functions "^6.22.0" - babel-plugin-transform-es2015-block-scoping "^6.23.0" - babel-plugin-transform-es2015-classes "^6.23.0" - babel-plugin-transform-es2015-computed-properties "^6.22.0" - babel-plugin-transform-es2015-destructuring "^6.23.0" - babel-plugin-transform-es2015-duplicate-keys "^6.22.0" - babel-plugin-transform-es2015-for-of "^6.23.0" - babel-plugin-transform-es2015-function-name "^6.22.0" - babel-plugin-transform-es2015-literals "^6.22.0" - babel-plugin-transform-es2015-modules-amd "^6.22.0" - babel-plugin-transform-es2015-modules-commonjs "^6.23.0" - babel-plugin-transform-es2015-modules-systemjs "^6.23.0" - babel-plugin-transform-es2015-modules-umd "^6.23.0" - babel-plugin-transform-es2015-object-super "^6.22.0" - babel-plugin-transform-es2015-parameters "^6.23.0" - babel-plugin-transform-es2015-shorthand-properties "^6.22.0" - babel-plugin-transform-es2015-spread "^6.22.0" - babel-plugin-transform-es2015-sticky-regex "^6.22.0" - babel-plugin-transform-es2015-template-literals "^6.22.0" - babel-plugin-transform-es2015-typeof-symbol "^6.23.0" - babel-plugin-transform-es2015-unicode-regex "^6.22.0" - babel-plugin-transform-exponentiation-operator "^6.22.0" - babel-plugin-transform-regenerator "^6.22.0" - browserslist "^2.1.2" - invariant "^2.2.2" - semver "^5.3.0" - -babel-preset-minify@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/babel-preset-minify/-/babel-preset-minify-0.2.0.tgz#006566552d9b83834472273f306c0131062a0acc" - dependencies: - babel-plugin-minify-builtins "^0.2.0" - babel-plugin-minify-constant-folding "^0.2.0" - babel-plugin-minify-dead-code-elimination "^0.2.0" - babel-plugin-minify-flip-comparisons "^0.2.0" - babel-plugin-minify-guarded-expressions "^0.2.0" - babel-plugin-minify-infinity "^0.2.0" - babel-plugin-minify-mangle-names "^0.2.0" - babel-plugin-minify-numeric-literals "^0.2.0" - babel-plugin-minify-replace "^0.2.0" - babel-plugin-minify-simplify "^0.2.0" - babel-plugin-minify-type-constructors "^0.2.0" - babel-plugin-transform-inline-consecutive-adds "^0.2.0" - babel-plugin-transform-member-expression-literals "^6.8.5" - babel-plugin-transform-merge-sibling-variables "^6.8.6" - babel-plugin-transform-minify-booleans "^6.8.3" - babel-plugin-transform-property-literals "^6.8.5" - babel-plugin-transform-regexp-constructors "^0.2.0" - babel-plugin-transform-remove-console "^6.8.5" - babel-plugin-transform-remove-debugger "^6.8.5" - babel-plugin-transform-remove-undefined "^0.2.0" - babel-plugin-transform-simplify-comparison-operators "^6.8.5" - babel-plugin-transform-undefined-to-void "^6.8.3" - lodash.isplainobject "^4.0.6" - -babel-register@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-register/-/babel-register-6.24.1.tgz#7e10e13a2f71065bdfad5a1787ba45bca6ded75f" - dependencies: - babel-core "^6.24.1" - babel-runtime "^6.22.0" - core-js "^2.4.0" - home-or-tmp "^2.0.0" - lodash "^4.2.0" - mkdirp "^0.5.1" - source-map-support "^0.4.2" - -babel-register@^6.26.0: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-register/-/babel-register-6.26.0.tgz#6ed021173e2fcb486d7acb45c6009a856f647071" - dependencies: - babel-core "^6.26.0" - babel-runtime "^6.26.0" - core-js "^2.5.0" - home-or-tmp "^2.0.0" - lodash "^4.17.4" - mkdirp "^0.5.1" - source-map-support "^0.4.15" - -babel-runtime@^6.18.0, babel-runtime@^6.22.0: - version "6.23.0" - resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-6.23.0.tgz#0a9489f144de70efb3ce4300accdb329e2fc543b" - dependencies: - core-js "^2.4.0" - regenerator-runtime "^0.10.0" - -babel-runtime@^6.26.0: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-6.26.0.tgz#965c7058668e82b55d7bfe04ff2337bc8b5647fe" - dependencies: - core-js "^2.4.0" - regenerator-runtime "^0.11.0" - -babel-template@^6.16.0, babel-template@^6.24.1, babel-template@^6.25.0: - version "6.25.0" - resolved "https://registry.yarnpkg.com/babel-template/-/babel-template-6.25.0.tgz#665241166b7c2aa4c619d71e192969552b10c071" - dependencies: - babel-runtime "^6.22.0" - babel-traverse "^6.25.0" - babel-types "^6.25.0" - babylon "^6.17.2" - lodash "^4.2.0" - -babel-template@^6.26.0: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-template/-/babel-template-6.26.0.tgz#de03e2d16396b069f46dd9fff8521fb1a0e35e02" - dependencies: - babel-runtime "^6.26.0" - babel-traverse "^6.26.0" - babel-types "^6.26.0" - babylon "^6.18.0" - lodash "^4.17.4" - -babel-traverse@^6.18.0, babel-traverse@^6.24.1, babel-traverse@^6.25.0: - version "6.25.0" - resolved "https://registry.yarnpkg.com/babel-traverse/-/babel-traverse-6.25.0.tgz#2257497e2fcd19b89edc13c4c91381f9512496f1" - dependencies: - babel-code-frame "^6.22.0" - babel-messages "^6.23.0" - babel-runtime "^6.22.0" - babel-types "^6.25.0" - babylon "^6.17.2" - debug "^2.2.0" - globals "^9.0.0" - invariant "^2.2.0" - lodash "^4.2.0" - -babel-traverse@^6.26.0: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-traverse/-/babel-traverse-6.26.0.tgz#46a9cbd7edcc62c8e5c064e2d2d8d0f4035766ee" - dependencies: - babel-code-frame "^6.26.0" - babel-messages "^6.23.0" - babel-runtime "^6.26.0" - babel-types "^6.26.0" - babylon "^6.18.0" - debug "^2.6.8" - globals "^9.18.0" - invariant "^2.2.2" - lodash "^4.17.4" - -babel-types@^6.18.0, babel-types@^6.19.0, babel-types@^6.24.1, babel-types@^6.25.0: - version "6.25.0" - resolved "https://registry.yarnpkg.com/babel-types/-/babel-types-6.25.0.tgz#70afb248d5660e5d18f811d91c8303b54134a18e" - dependencies: - babel-runtime "^6.22.0" - esutils "^2.0.2" - lodash "^4.2.0" - to-fast-properties "^1.0.1" - -babel-types@^6.26.0: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-types/-/babel-types-6.26.0.tgz#a3b073f94ab49eb6fa55cd65227a334380632497" - dependencies: - babel-runtime "^6.26.0" - esutils "^2.0.2" - lodash "^4.17.4" - to-fast-properties "^1.0.3" - -babylon@^6.1.0, babylon@^6.17.2: - version "6.17.4" - resolved "https://registry.yarnpkg.com/babylon/-/babylon-6.17.4.tgz#3e8b7402b88d22c3423e137a1577883b15ff869a" - -babylon@^6.18.0: - version "6.18.0" - resolved "https://registry.yarnpkg.com/babylon/-/babylon-6.18.0.tgz#af2f3b88fa6f5c1e4c634d1a0f8eac4f55b395e3" - -balanced-match@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" - -bcrypt-pbkdf@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz#a4301d389b6a43f9b67ff3ca11a3f6637e360e9e" - dependencies: - tweetnacl "^0.14.3" - -binary-extensions@^1.0.0: - version "1.8.0" - resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-1.8.0.tgz#48ec8d16df4377eae5fa5884682480af4d95c774" - -block-stream@*: - version "0.0.9" - resolved "https://registry.yarnpkg.com/block-stream/-/block-stream-0.0.9.tgz#13ebfe778a03205cfe03751481ebb4b3300c126a" - dependencies: - inherits "~2.0.0" - -bluebird@^3.0.0: - version "3.5.0" - resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.5.0.tgz#791420d7f551eea2897453a8a77653f96606d67c" - -boom@2.x.x: - version "2.10.1" - resolved "https://registry.yarnpkg.com/boom/-/boom-2.10.1.tgz#39c8918ceff5799f83f9492a848f625add0c766f" - dependencies: - hoek "2.x.x" - -boxen@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/boxen/-/boxen-1.1.0.tgz#b1b69dd522305e807a99deee777dbd6e5167b102" - dependencies: - ansi-align "^2.0.0" - camelcase "^4.0.0" - chalk "^1.1.1" - cli-boxes "^1.0.0" - string-width "^2.0.0" - term-size "^0.1.0" - widest-line "^1.0.0" - -brace-expansion@^1.1.7: - version "1.1.11" - resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" - dependencies: - balanced-match "^1.0.0" - concat-map "0.0.1" - -braces@^1.8.2: - version "1.8.5" - resolved "https://registry.yarnpkg.com/braces/-/braces-1.8.5.tgz#ba77962e12dff969d6b76711e914b737857bf6a7" - dependencies: - expand-range "^1.8.1" - preserve "^0.2.0" - repeat-element "^1.1.2" - -browser-resolve@^1.11.0: - version "1.11.2" - resolved "https://registry.yarnpkg.com/browser-resolve/-/browser-resolve-1.11.2.tgz#8ff09b0a2c421718a1051c260b32e48f442938ce" - dependencies: - resolve "1.1.7" - -browserslist@^2.1.2: - version "2.1.5" - resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-2.1.5.tgz#e882550df3d1cd6d481c1a3e0038f2baf13a4711" - dependencies: - caniuse-lite "^1.0.30000684" - electron-to-chromium "^1.3.14" - -buf-compare@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/buf-compare/-/buf-compare-1.0.1.tgz#fef28da8b8113a0a0db4430b0b6467b69730b34a" - -builtin-modules@^1.0.0, builtin-modules@^1.1.0, builtin-modules@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-1.1.1.tgz#270f076c5a72c02f5b65a47df94c5fe3a278892f" - -caching-transform@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/caching-transform/-/caching-transform-1.0.1.tgz#6dbdb2f20f8d8fbce79f3e94e9d1742dcdf5c0a1" - dependencies: - md5-hex "^1.2.0" - mkdirp "^0.5.1" - write-file-atomic "^1.1.4" - -call-matcher@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/call-matcher/-/call-matcher-1.0.1.tgz#5134d077984f712a54dad3cbf62de28dce416ca8" - dependencies: - core-js "^2.0.0" - deep-equal "^1.0.0" - espurify "^1.6.0" - estraverse "^4.0.0" - -call-signature@0.0.2: - version "0.0.2" - resolved "https://registry.yarnpkg.com/call-signature/-/call-signature-0.0.2.tgz#a84abc825a55ef4cb2b028bd74e205a65b9a4996" - -caller-path@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/caller-path/-/caller-path-0.1.0.tgz#94085ef63581ecd3daa92444a8fe94e82577751f" - dependencies: - callsites "^0.2.0" - -callsites@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/callsites/-/callsites-0.2.0.tgz#afab96262910a7f33c19a5775825c69f34e350ca" - -camelcase-keys@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/camelcase-keys/-/camelcase-keys-2.1.0.tgz#308beeaffdf28119051efa1d932213c91b8f92e7" - dependencies: - camelcase "^2.0.0" - map-obj "^1.0.0" - -camelcase@^1.0.2: - version "1.2.1" - resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-1.2.1.tgz#9bb5304d2e0b56698b2c758b08a3eaa9daa58a39" - -camelcase@^2.0.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-2.1.1.tgz#7c1d16d679a1bbe59ca02cacecfb011e201f5a1f" - -camelcase@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-3.0.0.tgz#32fc4b9fcdaf845fcdf7e73bb97cac2261f0ab0a" - -camelcase@^4.0.0, camelcase@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-4.1.0.tgz#d545635be1e33c542649c69173e5de6acfae34dd" - -caniuse-lite@^1.0.30000684: - version "1.0.30000693" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000693.tgz#c9c6298697c71fdf6cb13eefe8aa93926f2f8613" - -capture-stack-trace@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/capture-stack-trace/-/capture-stack-trace-1.0.0.tgz#4a6fa07399c26bba47f0b2496b4d0fb408c5550d" - -caseless@~0.12.0: - version "0.12.0" - resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" - -center-align@^0.1.1: - version "0.1.3" - resolved "https://registry.yarnpkg.com/center-align/-/center-align-0.1.3.tgz#aa0d32629b6ee972200411cbd4461c907bc2b7ad" - dependencies: - align-text "^0.1.3" - lazy-cache "^1.0.3" - -chalk@^0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-0.4.0.tgz#5199a3ddcd0c1efe23bc08c1b027b06176e0c64f" - dependencies: - ansi-styles "~1.0.0" - has-color "~0.1.0" - strip-ansi "~0.1.0" - -chalk@^1.0.0, chalk@^1.1.1, chalk@^1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" - dependencies: - ansi-styles "^2.2.1" - escape-string-regexp "^1.0.2" - has-ansi "^2.0.0" - strip-ansi "^3.0.0" - supports-color "^2.0.0" - -chalk@^2.0.0, chalk@^2.0.1, chalk@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.1.0.tgz#ac5becf14fa21b99c6c92ca7a7d7cfd5b17e743e" - dependencies: - ansi-styles "^3.1.0" - escape-string-regexp "^1.0.5" - supports-color "^4.0.0" - -chokidar@^1.4.2: - version "1.7.0" - resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-1.7.0.tgz#798e689778151c8076b4b360e5edd28cda2bb468" - dependencies: - anymatch "^1.3.0" - async-each "^1.0.0" - glob-parent "^2.0.0" - inherits "^2.0.1" - is-binary-path "^1.0.0" - is-glob "^2.0.0" - path-is-absolute "^1.0.0" - readdirp "^2.0.0" - optionalDependencies: - fsevents "^1.0.0" - -ci-info@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-1.0.0.tgz#dc5285f2b4e251821683681c381c3388f46ec534" - -circular-json@^0.3.1: - version "0.3.1" - resolved "https://registry.yarnpkg.com/circular-json/-/circular-json-0.3.1.tgz#be8b36aefccde8b3ca7aa2d6afc07a37242c0d2d" - -clean-stack@^1.1.1: - version "1.3.0" - resolved "https://registry.yarnpkg.com/clean-stack/-/clean-stack-1.3.0.tgz#9e821501ae979986c46b1d66d2d432db2fd4ae31" - -clean-yaml-object@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/clean-yaml-object/-/clean-yaml-object-0.1.0.tgz#63fb110dc2ce1a84dc21f6d9334876d010ae8b68" - -cli-boxes@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/cli-boxes/-/cli-boxes-1.0.0.tgz#4fa917c3e59c94a004cd61f8ee509da651687143" - -cli-cursor@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-2.1.0.tgz#b35dac376479facc3e94747d41d0d0f5238ffcb5" - dependencies: - restore-cursor "^2.0.0" - -cli-spinners@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/cli-spinners/-/cli-spinners-1.0.0.tgz#ef987ed3d48391ac3dab9180b406a742180d6e6a" - -cli-truncate@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/cli-truncate/-/cli-truncate-1.0.0.tgz#21eb91f47b3f6560f004db77a769b4668d9c5518" - dependencies: - slice-ansi "0.0.4" - string-width "^2.0.0" - -cli-width@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-2.1.0.tgz#b234ca209b29ef66fc518d9b98d5847b00edf00a" - -cliui@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/cliui/-/cliui-2.1.0.tgz#4b475760ff80264c762c3a1719032e91c7fea0d1" - dependencies: - center-align "^0.1.1" - right-align "^0.1.1" - wordwrap "0.0.2" - -cliui@^3.2.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/cliui/-/cliui-3.2.0.tgz#120601537a916d29940f934da3b48d585a39213d" - dependencies: - string-width "^1.0.1" - strip-ansi "^3.0.1" - wrap-ansi "^2.0.0" - -co-with-promise@^4.6.0: - version "4.6.0" - resolved "https://registry.yarnpkg.com/co-with-promise/-/co-with-promise-4.6.0.tgz#413e7db6f5893a60b942cf492c4bec93db415ab7" - dependencies: - pinkie-promise "^1.0.0" - -co@^4.6.0: - version "4.6.0" - resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184" - -code-excerpt@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/code-excerpt/-/code-excerpt-2.1.0.tgz#5dcc081e88f4a7e3b554e9e35d7ef232d47f8147" - dependencies: - convert-to-spaces "^1.0.1" - -code-point-at@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" - -color-convert@^1.0.0: - version "1.9.0" - resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.0.tgz#1accf97dd739b983bf994d56fec8f95853641b7a" - dependencies: - color-name "^1.1.1" - -color-name@^1.1.1: - version "1.1.2" - resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.2.tgz#5c8ab72b64bd2215d617ae9559ebb148475cf98d" - -combined-stream@^1.0.5, combined-stream@~1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.5.tgz#938370a57b4a51dea2c77c15d5c5fdf895164009" - dependencies: - delayed-stream "~1.0.0" - -common-path-prefix@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/common-path-prefix/-/common-path-prefix-1.0.0.tgz#cd52f6f0712e0baab97d6f9732874f22f47752c0" - -commondir@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b" - -concat-map@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" - -concat-stream@^1.6.0: - version "1.6.0" - resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.0.tgz#0aac662fd52be78964d5532f694784e70110acf7" - dependencies: - inherits "^2.0.3" - readable-stream "^2.2.2" - typedarray "^0.0.6" - -concordance@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/concordance/-/concordance-3.0.0.tgz#b2286af54405fc995fc7345b0b106d8dd073cb29" - dependencies: - date-time "^2.1.0" - esutils "^2.0.2" - fast-diff "^1.1.1" - function-name-support "^0.2.0" - js-string-escape "^1.0.1" - lodash.clonedeep "^4.5.0" - lodash.flattendeep "^4.4.0" - lodash.merge "^4.6.0" - md5-hex "^2.0.0" - semver "^5.3.0" - well-known-symbols "^1.0.0" - -configstore@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/configstore/-/configstore-3.1.0.tgz#45df907073e26dfa1cf4b2d52f5b60545eaa11d1" - dependencies: - dot-prop "^4.1.0" - graceful-fs "^4.1.2" - make-dir "^1.0.0" - unique-string "^1.0.0" - write-file-atomic "^2.0.0" - xdg-basedir "^3.0.0" - -console-control-strings@^1.0.0, console-control-strings@~1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e" - -contains-path@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/contains-path/-/contains-path-0.1.0.tgz#fe8cf184ff6670b6baef01a9d4861a5cbec4120a" - -convert-source-map@^1.1.0, convert-source-map@^1.2.0, convert-source-map@^1.3.0, convert-source-map@^1.5.0: - version "1.5.0" - resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.5.0.tgz#9acd70851c6d5dfdd93d9282e5edf94a03ff46b5" - -convert-to-spaces@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/convert-to-spaces/-/convert-to-spaces-1.0.2.tgz#7e3e48bbe6d997b1417ddca2868204b4d3d85715" - -core-assert@^0.2.0: - version "0.2.1" - resolved "https://registry.yarnpkg.com/core-assert/-/core-assert-0.2.1.tgz#f85e2cf9bfed28f773cc8b3fa5c5b69bdc02fe3f" - dependencies: - buf-compare "^1.0.0" - is-error "^2.2.0" - -core-js@^2.0.0, core-js@^2.4.0: - version "2.4.1" - resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.4.1.tgz#4de911e667b0eae9124e34254b53aea6fc618d3e" - -core-js@^2.5.0: - version "2.5.1" - resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.5.1.tgz#ae6874dc66937789b80754ff5428df66819ca50b" - -core-util-is@~1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" - -create-error-class@^3.0.0: - version "3.0.2" - resolved "https://registry.yarnpkg.com/create-error-class/-/create-error-class-3.0.2.tgz#06be7abef947a3f14a30fd610671d401bca8b7b6" - dependencies: - capture-stack-trace "^1.0.0" - -cross-spawn-async@^2.1.1: - version "2.2.5" - resolved "https://registry.yarnpkg.com/cross-spawn-async/-/cross-spawn-async-2.2.5.tgz#845ff0c0834a3ded9d160daca6d390906bb288cc" - dependencies: - lru-cache "^4.0.0" - which "^1.2.8" - -cross-spawn@^4, cross-spawn@^4.0.0: - version "4.0.2" - resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-4.0.2.tgz#7b9247621c23adfdd3856004a823cbe397424d41" - dependencies: - lru-cache "^4.0.1" - which "^1.2.9" - -cross-spawn@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-5.1.0.tgz#e8bd0efee58fcff6f8f94510a0a554bbfa235449" - dependencies: - lru-cache "^4.0.1" - shebang-command "^1.2.0" - which "^1.2.9" - -cryptiles@2.x.x: - version "2.0.5" - resolved "https://registry.yarnpkg.com/cryptiles/-/cryptiles-2.0.5.tgz#3bdfecdc608147c1c67202fa291e7dca59eaa3b8" - dependencies: - boom "2.x.x" - -crypto-random-string@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/crypto-random-string/-/crypto-random-string-1.0.0.tgz#a230f64f568310e1498009940790ec99545bca7e" - -currently-unhandled@^0.4.1: - version "0.4.1" - resolved "https://registry.yarnpkg.com/currently-unhandled/-/currently-unhandled-0.4.1.tgz#988df33feab191ef799a61369dd76c17adf957ea" - dependencies: - array-find-index "^1.0.1" - -dashdash@^1.12.0: - version "1.14.1" - resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0" - dependencies: - assert-plus "^1.0.0" - -date-time@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/date-time/-/date-time-0.1.1.tgz#ed2f6d93d9790ce2fd66d5b5ff3edd5bbcbf3b07" - -date-time@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/date-time/-/date-time-2.1.0.tgz#0286d1b4c769633b3ca13e1e62558d2dbdc2eba2" - dependencies: - time-zone "^1.0.0" - -debug-log@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/debug-log/-/debug-log-1.0.1.tgz#2307632d4c04382b8df8a32f70b895046d52745f" - -debug@^2.1.1, debug@^2.2.0, debug@^2.6.3, debug@^2.6.8: - version "2.6.8" - resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.8.tgz#e731531ca2ede27d188222427da17821d68ff4fc" - dependencies: - ms "2.0.0" - -debug@^3.1.0: - version "3.2.6" - resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.6.tgz#e83d17de16d8a7efb7717edbe5fb10135eee629b" - dependencies: - ms "^2.1.1" - -decamelize@^1.0.0, decamelize@^1.1.1, decamelize@^1.1.2: - version "1.2.0" - resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" - -deep-equal@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-1.0.1.tgz#f5d260292b660e084eff4cdbc9f08ad3247448b5" - -deep-extend@~0.4.0: - version "0.4.2" - resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.4.2.tgz#48b699c27e334bf89f10892be432f6e4c7d34a7f" - -deep-is@~0.1.3: - version "0.1.3" - resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34" - -default-require-extensions@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/default-require-extensions/-/default-require-extensions-1.0.0.tgz#f37ea15d3e13ffd9b437d33e1a75b5fb97874cb8" - dependencies: - strip-bom "^2.0.0" - -del@^2.0.2: - version "2.2.2" - resolved "https://registry.yarnpkg.com/del/-/del-2.2.2.tgz#c12c981d067846c84bcaf862cff930d907ffd1a8" - dependencies: - globby "^5.0.0" - is-path-cwd "^1.0.0" - is-path-in-cwd "^1.0.0" - object-assign "^4.0.1" - pify "^2.0.0" - pinkie-promise "^2.0.0" - rimraf "^2.2.8" - -delayed-stream@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" - -delegates@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" - -detect-indent@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-4.0.0.tgz#f76d064352cdf43a1cb6ce619c4ee3a9475de208" - dependencies: - repeating "^2.0.0" - -detect-indent@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-5.0.0.tgz#3871cc0a6a002e8c3e5b3cf7f336264675f06b9d" - -doctrine@1.5.0: - version "1.5.0" - resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-1.5.0.tgz#379dce730f6166f76cefa4e6707a159b02c5a6fa" - dependencies: - esutils "^2.0.2" - isarray "^1.0.0" - -doctrine@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-2.1.0.tgz#5cd01fc101621b42c4cd7f5d1a66243716d3f39d" - dependencies: - esutils "^2.0.2" - -dot-prop@^4.1.0: - version "4.1.1" - resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-4.1.1.tgz#a8493f0b7b5eeec82525b5c7587fa7de7ca859c1" - dependencies: - is-obj "^1.0.0" - -duplexer3@^0.1.4: - version "0.1.4" - resolved "https://registry.yarnpkg.com/duplexer3/-/duplexer3-0.1.4.tgz#ee01dd1cac0ed3cbc7fdbea37dc0a8f1ce002ce2" - -ecc-jsbn@~0.1.1: - version "0.1.2" - resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz#3a83a904e54353287874c564b7549386849a98c9" - dependencies: - jsbn "~0.1.0" - safer-buffer "^2.1.0" - -electron-to-chromium@^1.3.14: - version "1.3.14" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.14.tgz#64af0f9efd3c3c6acd57d71f83b49ca7ee9c4b43" - -empower-core@^0.6.1: - version "0.6.2" - resolved "https://registry.yarnpkg.com/empower-core/-/empower-core-0.6.2.tgz#5adef566088e31fba80ba0a36df47d7094169144" - dependencies: - call-signature "0.0.2" - core-js "^2.0.0" - -equal-length@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/equal-length/-/equal-length-1.0.1.tgz#21ca112d48ab24b4e1e7ffc0e5339d31fdfc274c" - -erlang-types@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/erlang-types/-/erlang-types-1.0.1.tgz#943a57a9324e0d0edc0273690a8c702686d9b780" - -error-ex@^1.2.0: - version "1.3.1" - resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.1.tgz#f855a86ce61adc4e8621c3cda21e7a7612c3a8dc" - dependencies: - is-arrayish "^0.2.1" - -es6-error@^4.0.1, es6-error@^4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/es6-error/-/es6-error-4.0.2.tgz#eec5c726eacef51b7f6b73c20db6e1b13b069c98" - -escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.4, escape-string-regexp@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" - -eslint-config-airbnb-base@^12.0.0: - version "12.0.0" - resolved "https://registry.yarnpkg.com/eslint-config-airbnb-base/-/eslint-config-airbnb-base-12.0.0.tgz#99063aaef4b8698083481a00e165cbe15e82d615" - dependencies: - eslint-restricted-globals "^0.1.1" - -eslint-import-resolver-node@^0.3.1: - version "0.3.1" - resolved "https://registry.yarnpkg.com/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.1.tgz#4422574cde66a9a7b099938ee4d508a199e0e3cc" - dependencies: - debug "^2.6.8" - resolve "^1.2.0" - -eslint-module-utils@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.1.1.tgz#abaec824177613b8a95b299639e1b6facf473449" - dependencies: - debug "^2.6.8" - pkg-dir "^1.0.0" - -eslint-plugin-import@^2.7.0: - version "2.7.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.7.0.tgz#21de33380b9efb55f5ef6d2e210ec0e07e7fa69f" - dependencies: - builtin-modules "^1.1.1" - contains-path "^0.1.0" - debug "^2.6.8" - doctrine "1.5.0" - eslint-import-resolver-node "^0.3.1" - eslint-module-utils "^2.1.1" - has "^1.0.1" - lodash.cond "^4.3.0" - minimatch "^3.0.3" - read-pkg-up "^2.0.0" - -eslint-restricted-globals@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/eslint-restricted-globals/-/eslint-restricted-globals-0.1.1.tgz#35f0d5cbc64c2e3ed62e93b4b1a7af05ba7ed4d7" - -eslint-scope@^3.7.1: - version "3.7.1" - resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-3.7.1.tgz#3d63c3edfda02e06e01a452ad88caacc7cdcb6e8" - dependencies: - esrecurse "^4.1.0" - estraverse "^4.1.1" - -eslint-visitor-keys@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz#3f3180fb2e291017716acb4c9d6d5b5c34a6a81d" - -eslint@^4.6.1: - version "4.19.1" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-4.19.1.tgz#32d1d653e1d90408854bfb296f076ec7e186a300" - dependencies: - ajv "^5.3.0" - babel-code-frame "^6.22.0" - chalk "^2.1.0" - concat-stream "^1.6.0" - cross-spawn "^5.1.0" - debug "^3.1.0" - doctrine "^2.1.0" - eslint-scope "^3.7.1" - eslint-visitor-keys "^1.0.0" - espree "^3.5.4" - esquery "^1.0.0" - esutils "^2.0.2" - file-entry-cache "^2.0.0" - functional-red-black-tree "^1.0.1" - glob "^7.1.2" - globals "^11.0.1" - ignore "^3.3.3" - imurmurhash "^0.1.4" - inquirer "^3.0.6" - is-resolvable "^1.0.0" - js-yaml "^3.9.1" - json-stable-stringify-without-jsonify "^1.0.1" - levn "^0.3.0" - lodash "^4.17.4" - minimatch "^3.0.2" - mkdirp "^0.5.1" - natural-compare "^1.4.0" - optionator "^0.8.2" - path-is-inside "^1.0.2" - pluralize "^7.0.0" - progress "^2.0.0" - regexpp "^1.0.1" - require-uncached "^1.0.3" - semver "^5.3.0" - strip-ansi "^4.0.0" - strip-json-comments "~2.0.1" - table "4.0.2" - text-table "~0.2.0" - -espower-location-detector@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/espower-location-detector/-/espower-location-detector-1.0.0.tgz#a17b7ecc59d30e179e2bef73fb4137704cb331b5" - dependencies: - is-url "^1.2.1" - path-is-absolute "^1.0.0" - source-map "^0.5.0" - xtend "^4.0.0" - -espree@^3.5.4: - version "3.5.4" - resolved "https://registry.yarnpkg.com/espree/-/espree-3.5.4.tgz#b0f447187c8a8bed944b815a660bddf5deb5d1a7" - dependencies: - acorn "^5.5.0" - acorn-jsx "^3.0.0" - -esprima@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.0.tgz#4499eddcd1110e0b218bacf2fa7f7f59f55ca804" - -espurify@^1.6.0: - version "1.7.0" - resolved "https://registry.yarnpkg.com/espurify/-/espurify-1.7.0.tgz#1c5cf6cbccc32e6f639380bd4f991fab9ba9d226" - dependencies: - core-js "^2.0.0" - -esquery@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.0.0.tgz#cfba8b57d7fba93f17298a8a006a04cda13d80fa" - dependencies: - estraverse "^4.0.0" - -esrecurse@^4.1.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.2.0.tgz#fa9568d98d3823f9a41d91e902dcab9ea6e5b163" - dependencies: - estraverse "^4.1.0" - object-assign "^4.0.1" - -estraverse@^4.0.0, estraverse@^4.1.0, estraverse@^4.1.1: - version "4.2.0" - resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.2.0.tgz#0dee3fed31fcd469618ce7342099fc1afa0bdb13" - -estree-walker@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-0.2.1.tgz#bdafe8095383d8414d5dc2ecf4c9173b6db9412e" - -estree-walker@^0.3.0: - version "0.3.1" - resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-0.3.1.tgz#e6b1a51cf7292524e7237c312e5fe6660c1ce1aa" - -estree-walker@^0.5.0: - version "0.5.0" - resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-0.5.0.tgz#aae3b57c42deb8010e349c892462f0e71c5dd1aa" - -esutils@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.2.tgz#0abf4f1caa5bcb1f7a9d8acc6dea4faaa04bac9b" - -execa@^0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/execa/-/execa-0.4.0.tgz#4eb6467a36a095fabb2970ff9d5e3fb7bce6ebc3" - dependencies: - cross-spawn-async "^2.1.1" - is-stream "^1.1.0" - npm-run-path "^1.0.0" - object-assign "^4.0.1" - path-key "^1.0.0" - strip-eof "^1.0.0" - -execa@^0.5.0: - version "0.5.1" - resolved "https://registry.yarnpkg.com/execa/-/execa-0.5.1.tgz#de3fb85cb8d6e91c85bcbceb164581785cb57b36" - dependencies: - cross-spawn "^4.0.0" - get-stream "^2.2.0" - is-stream "^1.1.0" - npm-run-path "^2.0.0" - p-finally "^1.0.0" - signal-exit "^3.0.0" - strip-eof "^1.0.0" - -expand-brackets@^0.1.4: - version "0.1.5" - resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-0.1.5.tgz#df07284e342a807cd733ac5af72411e581d1177b" - dependencies: - is-posix-bracket "^0.1.0" - -expand-range@^1.8.1: - version "1.8.2" - resolved "https://registry.yarnpkg.com/expand-range/-/expand-range-1.8.2.tgz#a299effd335fe2721ebae8e257ec79644fc85337" - dependencies: - fill-range "^2.1.0" - -extend@~3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.1.tgz#a755ea7bc1adfcc5a31ce7e762dbaadc5e636444" - -external-editor@^2.0.4: - version "2.0.4" - resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-2.0.4.tgz#1ed9199da9cbfe2ef2f7a31b2fde8b0d12368972" - dependencies: - iconv-lite "^0.4.17" - jschardet "^1.4.2" - tmp "^0.0.31" - -extglob@^0.3.1: - version "0.3.2" - resolved "https://registry.yarnpkg.com/extglob/-/extglob-0.3.2.tgz#2e18ff3d2f49ab2765cec9023f011daa8d8349a1" - dependencies: - is-extglob "^1.0.0" - -extsprintf@1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.0.2.tgz#e1080e0658e300b06294990cc70e1502235fd550" - -fast-deep-equal@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-1.0.0.tgz#96256a3bc975595eb36d82e9929d060d893439ff" - -fast-diff@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/fast-diff/-/fast-diff-1.1.1.tgz#0aea0e4e605b6a2189f0e936d4b7fbaf1b7cfd9b" - -fast-json-stable-stringify@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz#d5142c0caee6b1189f87d3a76111064f86c8bbf2" - -fast-levenshtein@~2.0.4: - version "2.0.6" - resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" - -figures@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/figures/-/figures-2.0.0.tgz#3ab1a2d2a62c8bfb431a0c94cb797a2fce27c962" - dependencies: - escape-string-regexp "^1.0.5" - -file-entry-cache@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-2.0.0.tgz#c392990c3e684783d838b8c84a45d8a048458361" - dependencies: - flat-cache "^1.2.1" - object-assign "^4.0.1" - -filename-regex@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/filename-regex/-/filename-regex-2.0.1.tgz#c1c4b9bee3e09725ddb106b75c1e301fe2f18b26" - -fill-range@^2.1.0: - version "2.2.3" - resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-2.2.3.tgz#50b77dfd7e469bc7492470963699fe7a8485a723" - dependencies: - is-number "^2.1.0" - isobject "^2.0.0" - randomatic "^1.1.3" - repeat-element "^1.1.2" - repeat-string "^1.5.2" - -find-cache-dir@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-0.1.1.tgz#c8defae57c8a52a8a784f9e31c57c742e993a0b9" - dependencies: - commondir "^1.0.1" - mkdirp "^0.5.1" - pkg-dir "^1.0.0" - -find-cache-dir@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-1.0.0.tgz#9288e3e9e3cc3748717d39eade17cf71fc30ee6f" - dependencies: - commondir "^1.0.1" - make-dir "^1.0.0" - pkg-dir "^2.0.0" - -find-up@^1.0.0: - version "1.1.2" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-1.1.2.tgz#6b2e9822b1a2ce0a60ab64d610eccad53cb24d0f" - dependencies: - path-exists "^2.0.0" - pinkie-promise "^2.0.0" - -find-up@^2.0.0, find-up@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-2.1.0.tgz#45d1b7e506c717ddd482775a2b77920a3c0c57a7" - dependencies: - locate-path "^2.0.0" - -flat-cache@^1.2.1: - version "1.2.2" - resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-1.2.2.tgz#fa86714e72c21db88601761ecf2f555d1abc6b96" - dependencies: - circular-json "^0.3.1" - del "^2.0.2" - graceful-fs "^4.1.2" - write "^0.2.1" - -fn-name@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/fn-name/-/fn-name-2.0.1.tgz#5214d7537a4d06a4a301c0cc262feb84188002e7" - -for-in@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" - -for-own@^0.1.4: - version "0.1.5" - resolved "https://registry.yarnpkg.com/for-own/-/for-own-0.1.5.tgz#5265c681a4f294dabbf17c9509b6763aa84510ce" - dependencies: - for-in "^1.0.1" - -foreground-child@^1.5.3, foreground-child@^1.5.6: - version "1.5.6" - resolved "https://registry.yarnpkg.com/foreground-child/-/foreground-child-1.5.6.tgz#4fd71ad2dfde96789b980a5c0a295937cb2f5ce9" - dependencies: - cross-spawn "^4" - signal-exit "^3.0.0" - -forever-agent@~0.6.1: - version "0.6.1" - resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" - -form-data@~2.1.1: - version "2.1.4" - resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.1.4.tgz#33c183acf193276ecaa98143a69e94bfee1750d1" - dependencies: - asynckit "^0.4.0" - combined-stream "^1.0.5" - mime-types "^2.1.12" - -fs.realpath@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" - -fsevents@^1.0.0: - version "1.1.2" - resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-1.1.2.tgz#3282b713fb3ad80ede0e9fcf4611b5aa6fc033f4" - dependencies: - nan "^2.3.0" - node-pre-gyp "^0.6.36" - -fstream-ignore@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/fstream-ignore/-/fstream-ignore-1.0.5.tgz#9c31dae34767018fe1d249b24dada67d092da105" - dependencies: - fstream "^1.0.0" - inherits "2" - minimatch "^3.0.0" - -fstream@^1.0.0, fstream@^1.0.10, fstream@^1.0.12: - version "1.0.12" - resolved "https://registry.yarnpkg.com/fstream/-/fstream-1.0.12.tgz#4e8ba8ee2d48be4f7d0de505455548eae5932045" - dependencies: - graceful-fs "^4.1.2" - inherits "~2.0.0" - mkdirp ">=0.5 0" - rimraf "2" - -function-bind@^1.0.2: - version "1.1.0" - resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.0.tgz#16176714c801798e4e8f2cf7f7529467bb4a5771" - -function-name-support@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/function-name-support/-/function-name-support-0.2.0.tgz#55d3bfaa6eafd505a50f9bc81fdf57564a0bb071" - -functional-red-black-tree@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327" - -gauge@~2.7.3: - version "2.7.4" - resolved "https://registry.yarnpkg.com/gauge/-/gauge-2.7.4.tgz#2c03405c7538c39d7eb37b317022e325fb018bf7" - dependencies: - aproba "^1.0.3" - console-control-strings "^1.0.0" - has-unicode "^2.0.0" - object-assign "^4.1.0" - signal-exit "^3.0.0" - string-width "^1.0.1" - strip-ansi "^3.0.1" - wide-align "^1.1.0" - -get-caller-file@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-1.0.2.tgz#f702e63127e7e231c160a80c1554acb70d5047e5" - -get-port@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/get-port/-/get-port-3.1.0.tgz#ef01b18a84ca6486970ff99e54446141a73ffd3e" - -get-stdin@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-4.0.1.tgz#b968c6b0a04384324902e8bf1a5df32579a450fe" - -get-stream@^2.2.0: - version "2.3.1" - resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-2.3.1.tgz#5f38f93f346009666ee0150a054167f91bdd95de" - dependencies: - object-assign "^4.0.1" - pinkie-promise "^2.0.0" - -get-stream@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-3.0.0.tgz#8e943d1358dc37555054ecbe2edb05aa174ede14" - -getpass@^0.1.1: - version "0.1.7" - resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa" - dependencies: - assert-plus "^1.0.0" - -glob-base@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/glob-base/-/glob-base-0.3.0.tgz#dbb164f6221b1c0b1ccf82aea328b497df0ea3c4" - dependencies: - glob-parent "^2.0.0" - is-glob "^2.0.0" - -glob-parent@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-2.0.0.tgz#81383d72db054fcccf5336daa902f182f6edbb28" - dependencies: - is-glob "^2.0.0" - -glob@^7.0.3, glob@^7.0.5, glob@^7.0.6, glob@^7.1.2, glob@^7.1.3: - version "7.1.4" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.4.tgz#aa608a2f6c577ad357e1ae5a5c26d9a8d1969255" - dependencies: - fs.realpath "^1.0.0" - inflight "^1.0.4" - inherits "2" - minimatch "^3.0.4" - once "^1.3.0" - path-is-absolute "^1.0.0" - -globals@^11.0.1: - version "11.12.0" - resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e" - -globals@^9.0.0, globals@^9.18.0: - version "9.18.0" - resolved "https://registry.yarnpkg.com/globals/-/globals-9.18.0.tgz#aa3896b3e69b487f17e31ed2143d69a8e30c2d8a" - -globby@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/globby/-/globby-5.0.0.tgz#ebd84667ca0dbb330b99bcfc68eac2bc54370e0d" - dependencies: - array-union "^1.0.1" - arrify "^1.0.0" - glob "^7.0.3" - object-assign "^4.0.1" - pify "^2.0.0" - pinkie-promise "^2.0.0" - -globby@^6.0.0: - version "6.1.0" - resolved "https://registry.yarnpkg.com/globby/-/globby-6.1.0.tgz#f5a6d70e8395e21c858fb0489d64df02424d506c" - dependencies: - array-union "^1.0.1" - glob "^7.0.3" - object-assign "^4.0.1" - pify "^2.0.0" - pinkie-promise "^2.0.0" - -got@^6.7.1: - version "6.7.1" - resolved "https://registry.yarnpkg.com/got/-/got-6.7.1.tgz#240cd05785a9a18e561dc1b44b41c763ef1e8db0" - dependencies: - create-error-class "^3.0.0" - duplexer3 "^0.1.4" - get-stream "^3.0.0" - is-redirect "^1.0.0" - is-retry-allowed "^1.0.0" - is-stream "^1.0.0" - lowercase-keys "^1.0.0" - safe-buffer "^5.0.1" - timed-out "^4.0.0" - unzip-response "^2.0.1" - url-parse-lax "^1.0.0" - -graceful-fs@^4.1.11: - version "4.1.11" - resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.11.tgz#0e8bdfe4d1ddb8854d64e04ea7c00e2a026e5658" - -graceful-fs@^4.1.2: - version "4.1.15" - resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.15.tgz#ffb703e1066e8a0eeaa4c8b80ba9253eeefbfb00" - -grapheme-splitter@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/grapheme-splitter/-/grapheme-splitter-1.0.2.tgz#639e9dc1bf065892c643de31daa27cf58b1068e2" - -handlebars@^4.0.3: - version "4.0.10" - resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.0.10.tgz#3d30c718b09a3d96f23ea4cc1f403c4d3ba9ff4f" - dependencies: - async "^1.4.0" - optimist "^0.6.1" - source-map "^0.4.4" - optionalDependencies: - uglify-js "^2.6" - -har-schema@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-1.0.5.tgz#d263135f43307c02c602afc8fe95970c0151369e" - -har-validator@~4.2.1: - version "4.2.1" - resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-4.2.1.tgz#33481d0f1bbff600dd203d75812a6a5fba002e2a" - dependencies: - ajv "^4.9.1" - har-schema "^1.0.5" - -has-ansi@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91" - dependencies: - ansi-regex "^2.0.0" - -has-color@~0.1.0: - version "0.1.7" - resolved "https://registry.yarnpkg.com/has-color/-/has-color-0.1.7.tgz#67144a5260c34fc3cca677d041daf52fe7b78b2f" - -has-flag@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-1.0.0.tgz#9d9e793165ce017a00f00418c43f942a7b1d11fa" - -has-flag@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-2.0.0.tgz#e8207af1cc7b30d446cc70b734b5e8be18f88d51" - -has-unicode@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9" - -has-yarn@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/has-yarn/-/has-yarn-1.0.0.tgz#89e25db604b725c8f5976fff0addc921b828a5a7" - -has@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/has/-/has-1.0.1.tgz#8461733f538b0837c9361e39a9ab9e9704dc2f28" - dependencies: - function-bind "^1.0.2" - -hawk@~3.1.3: - version "3.1.3" - resolved "https://registry.yarnpkg.com/hawk/-/hawk-3.1.3.tgz#078444bd7c1640b0fe540d2c9b73d59678e8e1c4" - dependencies: - boom "2.x.x" - cryptiles "2.x.x" - hoek "2.x.x" - sntp "1.x.x" - -hoek@2.x.x: - version "2.16.3" - resolved "https://registry.yarnpkg.com/hoek/-/hoek-2.16.3.tgz#20bb7403d3cea398e91dc4710a8ff1b8274a25ed" - -home-or-tmp@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/home-or-tmp/-/home-or-tmp-2.0.0.tgz#e36c3f2d2cae7d746a857e38d18d5f32a7882db8" - dependencies: - os-homedir "^1.0.0" - os-tmpdir "^1.0.1" - -hosted-git-info@^2.1.4: - version "2.4.2" - resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.4.2.tgz#0076b9f46a270506ddbaaea56496897460612a67" - -http-signature@~1.1.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.1.1.tgz#df72e267066cd0ac67fb76adf8e134a8fbcf91bf" - dependencies: - assert-plus "^0.2.0" - jsprim "^1.2.2" - sshpk "^1.7.0" - -hullabaloo-config-manager@^1.1.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/hullabaloo-config-manager/-/hullabaloo-config-manager-1.1.1.tgz#1d9117813129ad035fd9e8477eaf066911269fe3" - dependencies: - dot-prop "^4.1.0" - es6-error "^4.0.2" - graceful-fs "^4.1.11" - indent-string "^3.1.0" - json5 "^0.5.1" - lodash.clonedeep "^4.5.0" - lodash.clonedeepwith "^4.5.0" - lodash.isequal "^4.5.0" - lodash.merge "^4.6.0" - md5-hex "^2.0.0" - package-hash "^2.0.0" - pkg-dir "^2.0.0" - resolve-from "^3.0.0" - safe-buffer "^5.0.1" - -iconv-lite@^0.4.17: - version "0.4.18" - resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.18.tgz#23d8656b16aae6742ac29732ea8f0336a4789cf2" - -ignore-by-default@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/ignore-by-default/-/ignore-by-default-1.0.1.tgz#48ca6d72f6c6a3af00a9ad4ae6876be3889e2b09" - -ignore@^3.3.3: - version "3.3.3" - resolved "https://registry.yarnpkg.com/ignore/-/ignore-3.3.3.tgz#432352e57accd87ab3110e82d3fea0e47812156d" - -import-lazy@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/import-lazy/-/import-lazy-2.1.0.tgz#05698e3d45c88e8d7e9d92cb0584e77f096f3e43" - -import-local@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/import-local/-/import-local-0.1.1.tgz#b1179572aacdc11c6a91009fb430dbcab5f668a8" - dependencies: - pkg-dir "^2.0.0" - resolve-cwd "^2.0.0" - -imurmurhash@^0.1.4: - version "0.1.4" - resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" - -indent-string@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-2.1.0.tgz#8e2d48348742121b4a8218b7a137e9a52049dc80" - dependencies: - repeating "^2.0.0" - -indent-string@^3.0.0, indent-string@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-3.1.0.tgz#08ff4334603388399b329e6b9538dc7a3cf5de7d" - -inflight@^1.0.4: - version "1.0.6" - resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" - dependencies: - once "^1.3.0" - wrappy "1" - -inherits@2, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.0, inherits@~2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" - -ini@~1.3.0: - version "1.3.4" - resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.4.tgz#0537cb79daf59b59a1a517dff706c86ec039162e" - -inquirer@^3.0.6: - version "3.2.0" - resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-3.2.0.tgz#45b44c2160c729d7578c54060b3eed94487bb42b" - dependencies: - ansi-escapes "^2.0.0" - chalk "^2.0.0" - cli-cursor "^2.1.0" - cli-width "^2.0.0" - external-editor "^2.0.4" - figures "^2.0.0" - lodash "^4.3.0" - mute-stream "0.0.7" - run-async "^2.2.0" - rx-lite "^4.0.8" - rx-lite-aggregates "^4.0.8" - string-width "^2.1.0" - strip-ansi "^4.0.0" - through "^2.3.6" - -invariant@^2.2.0, invariant@^2.2.2: - version "2.2.2" - resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.2.tgz#9e1f56ac0acdb6bf303306f338be3b204ae60360" - dependencies: - loose-envify "^1.0.0" - -invert-kv@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-1.0.0.tgz#104a8e4aaca6d3d8cd157a8ef8bfab2d7a3ffdb6" - -irregular-plurals@^1.0.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/irregular-plurals/-/irregular-plurals-1.2.0.tgz#38f299834ba8c00c30be9c554e137269752ff3ac" - -is-arrayish@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" - -is-binary-path@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-1.0.1.tgz#75f16642b480f187a711c814161fd3a4a7655898" - dependencies: - binary-extensions "^1.0.0" - -is-buffer@^1.1.5: - version "1.1.5" - resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.5.tgz#1f3b26ef613b214b88cbca23cc6c01d87961eecc" - -is-builtin-module@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-builtin-module/-/is-builtin-module-1.0.0.tgz#540572d34f7ac3119f8f76c30cbc1b1e037affbe" - dependencies: - builtin-modules "^1.0.0" - -is-ci@^1.0.7: - version "1.0.10" - resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-1.0.10.tgz#f739336b2632365061a9d48270cd56ae3369318e" - dependencies: - ci-info "^1.0.0" - -is-dotfile@^1.0.0: - version "1.0.3" - resolved "https://registry.yarnpkg.com/is-dotfile/-/is-dotfile-1.0.3.tgz#a6a2f32ffd2dfb04f5ca25ecd0f6b83cf798a1e1" - -is-equal-shallow@^0.1.3: - version "0.1.3" - resolved "https://registry.yarnpkg.com/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz#2238098fc221de0bcfa5d9eac4c45d638aa1c534" - dependencies: - is-primitive "^2.0.0" - -is-error@^2.2.0: - version "2.2.1" - resolved "https://registry.yarnpkg.com/is-error/-/is-error-2.2.1.tgz#684a96d84076577c98f4cdb40c6d26a5123bf19c" - -is-extendable@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89" - -is-extglob@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-1.0.0.tgz#ac468177c4943405a092fc8f29760c6ffc6206c0" - -is-finite@^1.0.0, is-finite@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/is-finite/-/is-finite-1.0.2.tgz#cc6677695602be550ef11e8b4aa6305342b6d0aa" - dependencies: - number-is-nan "^1.0.0" - -is-fullwidth-code-point@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb" - dependencies: - number-is-nan "^1.0.0" - -is-fullwidth-code-point@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" - -is-generator-fn@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-generator-fn/-/is-generator-fn-1.0.0.tgz#969d49e1bb3329f6bb7f09089be26578b2ddd46a" - -is-glob@^2.0.0, is-glob@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-2.0.1.tgz#d096f926a3ded5600f3fdfd91198cb0888c2d863" - dependencies: - is-extglob "^1.0.0" - -is-module@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-module/-/is-module-1.0.0.tgz#3258fb69f78c14d5b815d664336b4cffb6441591" - -is-npm@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-npm/-/is-npm-1.0.0.tgz#f2fb63a65e4905b406c86072765a1a4dc793b9f4" - -is-number@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/is-number/-/is-number-2.1.0.tgz#01fcbbb393463a548f2f466cce16dece49db908f" - dependencies: - kind-of "^3.0.2" - -is-number@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/is-number/-/is-number-3.0.0.tgz#24fd6201a4782cf50561c810276afc7d12d71195" - dependencies: - kind-of "^3.0.2" - -is-obj@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-1.0.1.tgz#3e4729ac1f5fde025cd7d83a896dab9f4f67db0f" - -is-observable@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/is-observable/-/is-observable-0.2.0.tgz#b361311d83c6e5d726cabf5e250b0237106f5ae2" - dependencies: - symbol-observable "^0.2.2" - -is-path-cwd@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-path-cwd/-/is-path-cwd-1.0.0.tgz#d225ec23132e89edd38fda767472e62e65f1106d" - -is-path-in-cwd@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-path-in-cwd/-/is-path-in-cwd-1.0.0.tgz#6477582b8214d602346094567003be8a9eac04dc" - dependencies: - is-path-inside "^1.0.0" - -is-path-inside@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-1.0.0.tgz#fc06e5a1683fbda13de667aff717bbc10a48f37f" - dependencies: - path-is-inside "^1.0.1" - -is-plain-obj@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-1.1.0.tgz#71a50c8429dfca773c92a390a4a03b39fcd51d3e" - -is-posix-bracket@^0.1.0: - version "0.1.1" - resolved "https://registry.yarnpkg.com/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz#3334dc79774368e92f016e6fbc0a88f5cd6e6bc4" - -is-primitive@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/is-primitive/-/is-primitive-2.0.0.tgz#207bab91638499c07b2adf240a41a87210034575" - -is-promise@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/is-promise/-/is-promise-2.1.0.tgz#79a2a9ece7f096e80f36d2b2f3bc16c1ff4bf3fa" - -is-redirect@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-redirect/-/is-redirect-1.0.0.tgz#1d03dded53bd8db0f30c26e4f95d36fc7c87dc24" - -is-resolvable@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-resolvable/-/is-resolvable-1.0.0.tgz#8df57c61ea2e3c501408d100fb013cf8d6e0cc62" - dependencies: - tryit "^1.0.1" - -is-retry-allowed@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/is-retry-allowed/-/is-retry-allowed-1.1.0.tgz#11a060568b67339444033d0125a61a20d564fb34" - -is-stream@^1.0.0, is-stream@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" - -is-typedarray@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" - -is-url@^1.2.1: - version "1.2.2" - resolved "https://registry.yarnpkg.com/is-url/-/is-url-1.2.2.tgz#498905a593bf47cc2d9e7f738372bbf7696c7f26" - -is-utf8@^0.2.0, is-utf8@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/is-utf8/-/is-utf8-0.2.1.tgz#4b0da1442104d1b336340e80797e865cf39f7d72" - -isarray@1.0.0, isarray@^1.0.0, isarray@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" - -isexe@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" - -isobject@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/isobject/-/isobject-2.1.0.tgz#f065561096a3f1da2ef46272f815c840d87e0c89" - dependencies: - isarray "1.0.0" - -isstream@~0.1.2: - version "0.1.2" - resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" - -istanbul-lib-coverage@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-1.1.1.tgz#73bfb998885299415c93d38a3e9adf784a77a9da" - -istanbul-lib-hook@^1.0.7: - version "1.0.7" - resolved "https://registry.yarnpkg.com/istanbul-lib-hook/-/istanbul-lib-hook-1.0.7.tgz#dd6607f03076578fe7d6f2a630cf143b49bacddc" - dependencies: - append-transform "^0.4.0" - -istanbul-lib-instrument@^1.8.0: - version "1.8.0" - resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-1.8.0.tgz#66f6c9421cc9ec4704f76f2db084ba9078a2b532" - dependencies: - babel-generator "^6.18.0" - babel-template "^6.16.0" - babel-traverse "^6.18.0" - babel-types "^6.18.0" - babylon "^6.18.0" - istanbul-lib-coverage "^1.1.1" - semver "^5.3.0" - -istanbul-lib-report@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/istanbul-lib-report/-/istanbul-lib-report-1.1.1.tgz#f0e55f56655ffa34222080b7a0cd4760e1405fc9" - dependencies: - istanbul-lib-coverage "^1.1.1" - mkdirp "^0.5.1" - path-parse "^1.0.5" - supports-color "^3.1.2" - -istanbul-lib-source-maps@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/istanbul-lib-source-maps/-/istanbul-lib-source-maps-1.2.1.tgz#a6fe1acba8ce08eebc638e572e294d267008aa0c" - dependencies: - debug "^2.6.3" - istanbul-lib-coverage "^1.1.1" - mkdirp "^0.5.1" - rimraf "^2.6.1" - source-map "^0.5.3" - -istanbul-reports@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-1.1.1.tgz#042be5c89e175bc3f86523caab29c014e77fee4e" - dependencies: - handlebars "^4.0.3" - -js-string-escape@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/js-string-escape/-/js-string-escape-1.0.1.tgz#e2625badbc0d67c7533e9edc1068c587ae4137ef" - -js-tokens@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.1.tgz#08e9f132484a2c45a30907e9dc4d5567b7f114d7" - -js-tokens@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b" - -js-yaml@^3.8.2, js-yaml@^3.9.1: - version "3.9.1" - resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.9.1.tgz#08775cebdfdd359209f0d2acd383c8f86a6904a0" - dependencies: - argparse "^1.0.7" - esprima "^4.0.0" - -jsbn@~0.1.0: - version "0.1.1" - resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" - -jschardet@^1.4.2: - version "1.5.0" - resolved "https://registry.yarnpkg.com/jschardet/-/jschardet-1.5.0.tgz#a61f310306a5a71188e1b1acd08add3cfbb08b1e" - -jsesc@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-1.3.0.tgz#46c3fec8c1892b12b0833db9bc7622176dbab34b" - -jsesc@~0.5.0: - version "0.5.0" - resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-0.5.0.tgz#e7dee66e35d6fc16f710fe91d5cf69f70f08911d" - -json-schema-traverse@^0.3.0: - version "0.3.1" - resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz#349a6d44c53a51de89b40805c5d5e59b417d3340" - -json-schema@0.2.3: - version "0.2.3" - resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13" - -json-stable-stringify-without-jsonify@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" - -json-stable-stringify@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz#9a759d39c5f2ff503fd5300646ed445f88c4f9af" - dependencies: - jsonify "~0.0.0" - -json-stringify-safe@~5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" - -json5@^0.5.0, json5@^0.5.1: - version "0.5.1" - resolved "https://registry.yarnpkg.com/json5/-/json5-0.5.1.tgz#1eade7acc012034ad84e2396767ead9fa5495821" - -jsonify@~0.0.0: - version "0.0.0" - resolved "https://registry.yarnpkg.com/jsonify/-/jsonify-0.0.0.tgz#2c74b6ee41d93ca51b7b5aaee8f503631d252a73" - -jsprim@^1.2.2: - version "1.4.0" - resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.0.tgz#a3b87e40298d8c380552d8cc7628a0bb95a22918" - dependencies: - assert-plus "1.0.0" - extsprintf "1.0.2" - json-schema "0.2.3" - verror "1.3.6" - -kind-of@^3.0.2: - version "3.2.2" - resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64" - dependencies: - is-buffer "^1.1.5" - -kind-of@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-4.0.0.tgz#20813df3d712928b207378691a45066fae72dd57" - dependencies: - is-buffer "^1.1.5" - -last-line-stream@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/last-line-stream/-/last-line-stream-1.0.0.tgz#d1b64d69f86ff24af2d04883a2ceee14520a5600" - dependencies: - through2 "^2.0.0" - -latest-version@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/latest-version/-/latest-version-3.1.0.tgz#a205383fea322b33b5ae3b18abee0dc2f356ee15" - dependencies: - package-json "^4.0.0" - -lazy-cache@^1.0.3: - version "1.0.4" - resolved "https://registry.yarnpkg.com/lazy-cache/-/lazy-cache-1.0.4.tgz#a1d78fc3a50474cb80845d3b3b6e1da49a446e8e" - -lcid@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/lcid/-/lcid-1.0.0.tgz#308accafa0bc483a3867b4b6f2b9506251d1b835" - dependencies: - invert-kv "^1.0.0" - -levn@^0.3.0, levn@~0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee" - dependencies: - prelude-ls "~1.1.2" - type-check "~0.3.2" - -load-json-file@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-1.1.0.tgz#956905708d58b4bab4c2261b04f59f31c99374c0" - dependencies: - graceful-fs "^4.1.2" - parse-json "^2.2.0" - pify "^2.0.0" - pinkie-promise "^2.0.0" - strip-bom "^2.0.0" - -load-json-file@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-2.0.0.tgz#7947e42149af80d696cbf797bcaabcfe1fe29ca8" - dependencies: - graceful-fs "^4.1.2" - parse-json "^2.2.0" - pify "^2.0.0" - strip-bom "^3.0.0" - -locate-path@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-2.0.0.tgz#2b568b265eec944c6d9c0de9c3dbbbca0354cd8e" - dependencies: - p-locate "^2.0.0" - path-exists "^3.0.0" - -lodash.clonedeep@^4.5.0: - version "4.5.0" - resolved "https://registry.yarnpkg.com/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz#e23f3f9c4f8fbdde872529c1071857a086e5ccef" - -lodash.clonedeepwith@^4.5.0: - version "4.5.0" - resolved "https://registry.yarnpkg.com/lodash.clonedeepwith/-/lodash.clonedeepwith-4.5.0.tgz#6ee30573a03a1a60d670a62ef33c10cf1afdbdd4" - -lodash.cond@^4.3.0: - version "4.5.2" - resolved "https://registry.yarnpkg.com/lodash.cond/-/lodash.cond-4.5.2.tgz#f471a1da486be60f6ab955d17115523dd1d255d5" - -lodash.debounce@^4.0.3: - version "4.0.8" - resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af" - -lodash.difference@^4.3.0: - version "4.5.0" - resolved "https://registry.yarnpkg.com/lodash.difference/-/lodash.difference-4.5.0.tgz#9ccb4e505d486b91651345772885a2df27fd017c" - -lodash.flatten@^4.2.0: - version "4.4.0" - resolved "https://registry.yarnpkg.com/lodash.flatten/-/lodash.flatten-4.4.0.tgz#f31c22225a9632d2bbf8e4addbef240aa765a61f" - -lodash.flattendeep@^4.4.0: - version "4.4.0" - resolved "https://registry.yarnpkg.com/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz#fb030917f86a3134e5bc9bec0d69e0013ddfedb2" - -lodash.isequal@^4.5.0: - version "4.5.0" - resolved "https://registry.yarnpkg.com/lodash.isequal/-/lodash.isequal-4.5.0.tgz#415c4478f2bcc30120c22ce10ed3226f7d3e18e0" - -lodash.isplainobject@^4.0.6: - version "4.0.6" - resolved "https://registry.yarnpkg.com/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz#7c526a52d89b45c45cc690b88163be0497f550cb" - -lodash.merge@^4.6.0: - version "4.6.0" - resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.0.tgz#69884ba144ac33fe699737a6086deffadd0f89c5" - -lodash.some@^4.6.0: - version "4.6.0" - resolved "https://registry.yarnpkg.com/lodash.some/-/lodash.some-4.6.0.tgz#1bb9f314ef6b8baded13b549169b2a945eb68e4d" - -lodash@^4.17.4, lodash@^4.2.0, lodash@^4.3.0: - version "4.17.4" - resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.4.tgz#78203a4d1c328ae1d86dca6460e369b57f4055ae" - -longest@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/longest/-/longest-1.0.1.tgz#30a0b2da38f73770e8294a0d22e6625ed77d0097" - -loose-envify@^1.0.0: - version "1.3.1" - resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.3.1.tgz#d1a8ad33fa9ce0e713d65fdd0ac8b748d478c848" - dependencies: - js-tokens "^3.0.0" - -loud-rejection@^1.0.0, loud-rejection@^1.2.0: - version "1.6.0" - resolved "https://registry.yarnpkg.com/loud-rejection/-/loud-rejection-1.6.0.tgz#5b46f80147edee578870f086d04821cf998e551f" - dependencies: - currently-unhandled "^0.4.1" - signal-exit "^3.0.0" - -lowercase-keys@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-1.0.0.tgz#4e3366b39e7f5457e35f1324bdf6f88d0bfc7306" - -lru-cache@^4.0.0, lru-cache@^4.0.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.1.1.tgz#622e32e82488b49279114a4f9ecf45e7cd6bba55" - dependencies: - pseudomap "^1.0.2" - yallist "^2.1.2" - -magic-string@^0.22.4: - version "0.22.4" - resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.22.4.tgz#31039b4e40366395618c1d6cf8193c53917475ff" - dependencies: - vlq "^0.2.1" - -make-dir@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-1.0.0.tgz#97a011751e91dd87cfadef58832ebb04936de978" - dependencies: - pify "^2.3.0" - -map-obj@^1.0.0, map-obj@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/map-obj/-/map-obj-1.0.1.tgz#d933ceb9205d82bdcf4886f6742bdc2b4dea146d" - -matcher@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/matcher/-/matcher-1.0.0.tgz#aaf0c4816eb69b92094674175625f3466b0e3e19" - dependencies: - escape-string-regexp "^1.0.4" - -md5-hex@^1.2.0, md5-hex@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/md5-hex/-/md5-hex-1.3.0.tgz#d2c4afe983c4370662179b8cad145219135046c4" - dependencies: - md5-o-matic "^0.1.1" - -md5-hex@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/md5-hex/-/md5-hex-2.0.0.tgz#d0588e9f1c74954492ecd24ac0ac6ce997d92e33" - dependencies: - md5-o-matic "^0.1.1" - -md5-o-matic@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/md5-o-matic/-/md5-o-matic-0.1.1.tgz#822bccd65e117c514fab176b25945d54100a03c3" - -mem@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/mem/-/mem-1.1.0.tgz#5edd52b485ca1d900fe64895505399a0dfa45f76" - dependencies: - mimic-fn "^1.0.0" - -meow@^3.7.0: - version "3.7.0" - resolved "https://registry.yarnpkg.com/meow/-/meow-3.7.0.tgz#72cb668b425228290abbfa856892587308a801fb" - dependencies: - camelcase-keys "^2.0.0" - decamelize "^1.1.2" - loud-rejection "^1.0.0" - map-obj "^1.0.1" - minimist "^1.1.3" - normalize-package-data "^2.3.4" - object-assign "^4.0.1" - read-pkg-up "^1.0.1" - redent "^1.0.0" - trim-newlines "^1.0.0" - -merge-source-map@^1.0.2: - version "1.0.4" - resolved "https://registry.yarnpkg.com/merge-source-map/-/merge-source-map-1.0.4.tgz#a5de46538dae84d4114cc5ea02b4772a6346701f" - dependencies: - source-map "^0.5.6" - -micromatch@^2.1.5, micromatch@^2.3.11: - version "2.3.11" - resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-2.3.11.tgz#86677c97d1720b363431d04d0d15293bd38c1565" - dependencies: - arr-diff "^2.0.0" - array-unique "^0.2.1" - braces "^1.8.2" - expand-brackets "^0.1.4" - extglob "^0.3.1" - filename-regex "^2.0.0" - is-extglob "^1.0.0" - is-glob "^2.0.1" - kind-of "^3.0.2" - normalize-path "^2.0.1" - object.omit "^2.0.0" - parse-glob "^3.0.4" - regex-cache "^0.4.2" - -mime-db@~1.27.0: - version "1.27.0" - resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.27.0.tgz#820f572296bbd20ec25ed55e5b5de869e5436eb1" - -mime-types@^2.1.12, mime-types@~2.1.7: - version "2.1.15" - resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.15.tgz#a4ebf5064094569237b8cf70046776d09fc92aed" - dependencies: - mime-db "~1.27.0" - -mimic-fn@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-1.1.0.tgz#e667783d92e89dbd342818b5230b9d62a672ad18" - -minimatch@^3.0.0, minimatch@^3.0.2, minimatch@^3.0.3, minimatch@^3.0.4: - version "3.0.4" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" - dependencies: - brace-expansion "^1.1.7" - -minimist@0.0.8, minimist@~0.0.1: - version "0.0.8" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" - -minimist@^1.1.3, minimist@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284" - -"mkdirp@>=0.5 0", mkdirp@^0.5.0, mkdirp@^0.5.1: - version "0.5.1" - resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" - dependencies: - minimist "0.0.8" - -ms@2.0.0, ms@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" - -ms@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.1.tgz#30a5864eb3ebb0a66f2ebe6d727af06a09d86e0a" - -multimatch@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/multimatch/-/multimatch-2.1.0.tgz#9c7906a22fb4c02919e2f5f75161b4cdbd4b2a2b" - dependencies: - array-differ "^1.0.0" - array-union "^1.0.1" - arrify "^1.0.0" - minimatch "^3.0.0" - -mute-stream@0.0.7: - version "0.0.7" - resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.7.tgz#3075ce93bc21b8fab43e1bc4da7e8115ed1e7bab" - -nan@^2.3.0: - version "2.6.2" - resolved "https://registry.yarnpkg.com/nan/-/nan-2.6.2.tgz#e4ff34e6c95fdfb5aecc08de6596f43605a7db45" - -natural-compare@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" - -node-pre-gyp@^0.6.36: - version "0.6.36" - resolved "https://registry.yarnpkg.com/node-pre-gyp/-/node-pre-gyp-0.6.36.tgz#db604112cb74e0d477554e9b505b17abddfab786" - dependencies: - mkdirp "^0.5.1" - nopt "^4.0.1" - npmlog "^4.0.2" - rc "^1.1.7" - request "^2.81.0" - rimraf "^2.6.1" - semver "^5.3.0" - tar "^2.2.1" - tar-pack "^3.4.0" - -nopt@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/nopt/-/nopt-4.0.1.tgz#d0d4685afd5415193c8c7505602d0d17cd64474d" - dependencies: - abbrev "1" - osenv "^0.1.4" - -normalize-package-data@^2.3.2, normalize-package-data@^2.3.4: - version "2.3.8" - resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.3.8.tgz#d819eda2a9dedbd1ffa563ea4071d936782295bb" - dependencies: - hosted-git-info "^2.1.4" - is-builtin-module "^1.0.0" - semver "2 || 3 || 4 || 5" - validate-npm-package-license "^3.0.1" - -normalize-path@^2.0.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-2.1.1.tgz#1ab28b556e198363a8c1a6f7e6fa20137fe6aed9" - dependencies: - remove-trailing-separator "^1.0.1" - -npm-run-path@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-1.0.0.tgz#f5c32bf595fe81ae927daec52e82f8b000ac3c8f" - dependencies: - path-key "^1.0.0" - -npm-run-path@^2.0.0: - version "2.0.2" - resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-2.0.2.tgz#35a9232dfa35d7067b4cb2ddf2357b1871536c5f" - dependencies: - path-key "^2.0.0" - -npmlog@^4.0.2: - version "4.1.0" - resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.1.0.tgz#dc59bee85f64f00ed424efb2af0783df25d1c0b5" - dependencies: - are-we-there-yet "~1.1.2" - console-control-strings "~1.1.0" - gauge "~2.7.3" - set-blocking "~2.0.0" - -number-is-nan@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" - -nyc@^11.2.1: - version "11.2.1" - resolved "https://registry.yarnpkg.com/nyc/-/nyc-11.2.1.tgz#ad850afe9dbad7f4970728b4b2e47fed1c38721c" - dependencies: - archy "^1.0.0" - arrify "^1.0.1" - caching-transform "^1.0.0" - convert-source-map "^1.3.0" - debug-log "^1.0.1" - default-require-extensions "^1.0.0" - find-cache-dir "^0.1.1" - find-up "^2.1.0" - foreground-child "^1.5.3" - glob "^7.0.6" - istanbul-lib-coverage "^1.1.1" - istanbul-lib-hook "^1.0.7" - istanbul-lib-instrument "^1.8.0" - istanbul-lib-report "^1.1.1" - istanbul-lib-source-maps "^1.2.1" - istanbul-reports "^1.1.1" - md5-hex "^1.2.0" - merge-source-map "^1.0.2" - micromatch "^2.3.11" - mkdirp "^0.5.0" - resolve-from "^2.0.0" - rimraf "^2.5.4" - signal-exit "^3.0.1" - spawn-wrap "^1.3.8" - test-exclude "^4.1.1" - yargs "^8.0.1" - yargs-parser "^5.0.0" - -oauth-sign@~0.8.1: - version "0.8.2" - resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.8.2.tgz#46a6ab7f0aead8deae9ec0565780b7d4efeb9d43" - -object-assign@^4.0.1, object-assign@^4.1.0: - version "4.1.1" - resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" - -object.omit@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/object.omit/-/object.omit-2.0.1.tgz#1a9c744829f39dbb858c76ca3579ae2a54ebd1fa" - dependencies: - for-own "^0.1.4" - is-extendable "^0.1.1" - -observable-to-promise@^0.5.0: - version "0.5.0" - resolved "https://registry.yarnpkg.com/observable-to-promise/-/observable-to-promise-0.5.0.tgz#c828f0f0dc47e9f86af8a4977c5d55076ce7a91f" - dependencies: - is-observable "^0.2.0" - symbol-observable "^1.0.4" - -once@^1.3.0, once@^1.3.3: - version "1.4.0" - resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" - dependencies: - wrappy "1" - -onetime@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/onetime/-/onetime-2.0.1.tgz#067428230fd67443b2794b22bba528b6867962d4" - dependencies: - mimic-fn "^1.0.0" - -optimist@^0.6.1: - version "0.6.1" - resolved "https://registry.yarnpkg.com/optimist/-/optimist-0.6.1.tgz#da3ea74686fa21a19a111c326e90eb15a0196686" - dependencies: - minimist "~0.0.1" - wordwrap "~0.0.2" - -option-chain@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/option-chain/-/option-chain-1.0.0.tgz#938d73bd4e1783f948d34023644ada23669e30f2" - -optionator@^0.8.2: - version "0.8.2" - resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.2.tgz#364c5e409d3f4d6301d6c0b4c05bba50180aeb64" - dependencies: - deep-is "~0.1.3" - fast-levenshtein "~2.0.4" - levn "~0.3.0" - prelude-ls "~1.1.2" - type-check "~0.3.2" - wordwrap "~1.0.0" - -os-homedir@^1.0.0, os-homedir@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3" - -os-locale@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-2.0.0.tgz#15918ded510522b81ee7ae5a309d54f639fc39a4" - dependencies: - execa "^0.5.0" - lcid "^1.0.0" - mem "^1.1.0" - -os-tmpdir@^1.0.0, os-tmpdir@^1.0.1, os-tmpdir@~1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" - -osenv@^0.1.4: - version "0.1.4" - resolved "https://registry.yarnpkg.com/osenv/-/osenv-0.1.4.tgz#42fe6d5953df06c8064be6f176c3d05aaaa34644" - dependencies: - os-homedir "^1.0.0" - os-tmpdir "^1.0.0" - -p-finally@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae" - -p-limit@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-1.1.0.tgz#b07ff2d9a5d88bec806035895a2bab66a27988bc" - -p-locate@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-2.0.0.tgz#20a0103b222a70c8fd39cc2e580680f3dde5ec43" - dependencies: - p-limit "^1.1.0" - -package-hash@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/package-hash/-/package-hash-1.2.0.tgz#003e56cd57b736a6ed6114cc2b81542672770e44" - dependencies: - md5-hex "^1.3.0" - -package-hash@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/package-hash/-/package-hash-2.0.0.tgz#78ae326c89e05a4d813b68601977af05c00d2a0d" - dependencies: - graceful-fs "^4.1.11" - lodash.flattendeep "^4.4.0" - md5-hex "^2.0.0" - release-zalgo "^1.0.0" - -package-json@^4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/package-json/-/package-json-4.0.1.tgz#8869a0401253661c4c4ca3da6c2121ed555f5eed" - dependencies: - got "^6.7.1" - registry-auth-token "^3.0.1" - registry-url "^3.0.3" - semver "^5.1.0" - -parse-glob@^3.0.4: - version "3.0.4" - resolved "https://registry.yarnpkg.com/parse-glob/-/parse-glob-3.0.4.tgz#b2c376cfb11f35513badd173ef0bb6e3a388391c" - dependencies: - glob-base "^0.3.0" - is-dotfile "^1.0.0" - is-extglob "^1.0.0" - is-glob "^2.0.0" - -parse-json@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-2.2.0.tgz#f480f40434ef80741f8469099f8dea18f55a4dc9" - dependencies: - error-ex "^1.2.0" - -parse-ms@^0.1.0: - version "0.1.2" - resolved "https://registry.yarnpkg.com/parse-ms/-/parse-ms-0.1.2.tgz#dd3fa25ed6c2efc7bdde12ad9b46c163aa29224e" - -parse-ms@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/parse-ms/-/parse-ms-1.0.1.tgz#56346d4749d78f23430ca0c713850aef91aa361d" - -path-exists@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-2.1.0.tgz#0feb6c64f0fc518d9a754dd5efb62c7022761f4b" - dependencies: - pinkie-promise "^2.0.0" - -path-exists@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515" - -path-is-absolute@^1.0.0, path-is-absolute@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" - -path-is-inside@^1.0.1, path-is-inside@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/path-is-inside/-/path-is-inside-1.0.2.tgz#365417dede44430d1c11af61027facf074bdfc53" - -path-key@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/path-key/-/path-key-1.0.0.tgz#5d53d578019646c0d68800db4e146e6bdc2ac7af" - -path-key@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40" - -path-parse@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.5.tgz#3c1adf871ea9cd6c9431b6ea2bd74a0ff055c4c1" - -path-type@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/path-type/-/path-type-1.1.0.tgz#59c44f7ee491da704da415da5a4070ba4f8fe441" - dependencies: - graceful-fs "^4.1.2" - pify "^2.0.0" - pinkie-promise "^2.0.0" - -path-type@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/path-type/-/path-type-2.0.0.tgz#f012ccb8415b7096fc2daa1054c3d72389594c73" - dependencies: - pify "^2.0.0" - -performance-now@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-0.2.0.tgz#33ef30c5c77d4ea21c5a53869d91b56d8f2555e5" - -pify@^2.0.0, pify@^2.3.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" - -pinkie-promise@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/pinkie-promise/-/pinkie-promise-1.0.0.tgz#d1da67f5482563bb7cf57f286ae2822ecfbf3670" - dependencies: - pinkie "^1.0.0" - -pinkie-promise@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/pinkie-promise/-/pinkie-promise-2.0.1.tgz#2135d6dfa7a358c069ac9b178776288228450ffa" - dependencies: - pinkie "^2.0.0" - -pinkie@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-1.0.0.tgz#5a47f28ba1015d0201bda7bf0f358e47bec8c7e4" - -pinkie@^2.0.0: - version "2.0.4" - resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870" - -pkg-conf@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/pkg-conf/-/pkg-conf-2.0.0.tgz#071c87650403bccfb9c627f58751bfe47c067279" - dependencies: - find-up "^2.0.0" - load-json-file "^2.0.0" - -pkg-dir@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-1.0.0.tgz#7a4b508a8d5bb2d629d447056ff4e9c9314cf3d4" - dependencies: - find-up "^1.0.0" - -pkg-dir@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-2.0.0.tgz#f6d5d1109e19d63edf428e0bd57e12777615334b" - dependencies: - find-up "^2.1.0" - -plur@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/plur/-/plur-1.0.0.tgz#db85c6814f5e5e5a3b49efc28d604fec62975156" - -plur@^2.0.0: - version "2.1.2" - resolved "https://registry.yarnpkg.com/plur/-/plur-2.1.2.tgz#7482452c1a0f508e3e344eaec312c91c29dc655a" - dependencies: - irregular-plurals "^1.0.0" - -pluralize@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/pluralize/-/pluralize-7.0.0.tgz#298b89df8b93b0221dbf421ad2b1b1ea23fc6777" - -prelude-ls@~1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" - -prepend-http@^1.0.1: - version "1.0.4" - resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-1.0.4.tgz#d4f4562b0ce3696e41ac52d0e002e57a635dc6dc" - -preserve@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/preserve/-/preserve-0.2.0.tgz#815ed1f6ebc65926f865b310c0713bcb3315ce4b" - -pretty-ms@^0.2.1: - version "0.2.2" - resolved "https://registry.yarnpkg.com/pretty-ms/-/pretty-ms-0.2.2.tgz#da879a682ff33a37011046f13d627f67c73b84f6" - dependencies: - parse-ms "^0.1.0" - -pretty-ms@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/pretty-ms/-/pretty-ms-2.1.0.tgz#4257c256df3fb0b451d6affaab021884126981dc" - dependencies: - is-finite "^1.0.1" - parse-ms "^1.0.0" - plur "^1.0.0" - -private@^0.1.6, private@^0.1.7: - version "0.1.7" - resolved "https://registry.yarnpkg.com/private/-/private-0.1.7.tgz#68ce5e8a1ef0a23bb570cc28537b5332aba63ef1" - -process-nextick-args@~1.0.6: - version "1.0.7" - resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-1.0.7.tgz#150e20b756590ad3f91093f25a4f2ad8bff30ba3" - -progress@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.0.tgz#8a1be366bf8fc23db2bd23f10c6fe920b4389d1f" - -pseudomap@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3" - -punycode@^1.4.1: - version "1.4.1" - resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e" - -qs@~6.4.0: - version "6.4.0" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.4.0.tgz#13e26d28ad6b0ffaa91312cd3bf708ed351e7233" - -randomatic@^1.1.3: - version "1.1.7" - resolved "https://registry.yarnpkg.com/randomatic/-/randomatic-1.1.7.tgz#c7abe9cc8b87c0baa876b19fde83fd464797e38c" - dependencies: - is-number "^3.0.0" - kind-of "^4.0.0" - -rc@^1.0.1, rc@^1.1.6, rc@^1.1.7: - version "1.2.1" - resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.1.tgz#2e03e8e42ee450b8cb3dce65be1bf8974e1dfd95" - dependencies: - deep-extend "~0.4.0" - ini "~1.3.0" - minimist "^1.2.0" - strip-json-comments "~2.0.1" - -read-pkg-up@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-1.0.1.tgz#9d63c13276c065918d57f002a57f40a1b643fb02" - dependencies: - find-up "^1.0.0" - read-pkg "^1.0.0" - -read-pkg-up@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-2.0.0.tgz#6b72a8048984e0c41e79510fd5e9fa99b3b549be" - dependencies: - find-up "^2.0.0" - read-pkg "^2.0.0" - -read-pkg@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-1.1.0.tgz#f5ffaa5ecd29cb31c0474bca7d756b6bb29e3f28" - dependencies: - load-json-file "^1.0.0" - normalize-package-data "^2.3.2" - path-type "^1.0.0" - -read-pkg@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-2.0.0.tgz#8ef1c0623c6a6db0dc6713c4bfac46332b2368f8" - dependencies: - load-json-file "^2.0.0" - normalize-package-data "^2.3.2" - path-type "^2.0.0" - -readable-stream@^2.0.2, readable-stream@^2.0.6, readable-stream@^2.1.4, readable-stream@^2.1.5, readable-stream@^2.2.2: - version "2.3.2" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.2.tgz#5a04df05e4f57fe3f0dc68fdd11dc5c97c7e6f4d" - dependencies: - core-util-is "~1.0.0" - inherits "~2.0.3" - isarray "~1.0.0" - process-nextick-args "~1.0.6" - safe-buffer "~5.1.0" - string_decoder "~1.0.0" - util-deprecate "~1.0.1" - -readdirp@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-2.1.0.tgz#4ed0ad060df3073300c48440373f72d1cc642d78" - dependencies: - graceful-fs "^4.1.2" - minimatch "^3.0.2" - readable-stream "^2.0.2" - set-immediate-shim "^1.0.1" - -redent@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/redent/-/redent-1.0.0.tgz#cf916ab1fd5f1f16dfb20822dd6ec7f730c2afde" - dependencies: - indent-string "^2.1.0" - strip-indent "^1.0.1" - -regenerate@^1.2.1: - version "1.3.2" - resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.3.2.tgz#d1941c67bad437e1be76433add5b385f95b19260" - -regenerator-runtime@^0.10.0: - version "0.10.5" - resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.10.5.tgz#336c3efc1220adcedda2c9fab67b5a7955a33658" - -regenerator-runtime@^0.11.0: - version "0.11.0" - resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.11.0.tgz#7e54fe5b5ccd5d6624ea6255c3473be090b802e1" - -regenerator-transform@0.9.11: - version "0.9.11" - resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.9.11.tgz#3a7d067520cb7b7176769eb5ff868691befe1283" - dependencies: - babel-runtime "^6.18.0" - babel-types "^6.19.0" - private "^0.1.6" - -regex-cache@^0.4.2: - version "0.4.3" - resolved "https://registry.yarnpkg.com/regex-cache/-/regex-cache-0.4.3.tgz#9b1a6c35d4d0dfcef5711ae651e8e9d3d7114145" - dependencies: - is-equal-shallow "^0.1.3" - is-primitive "^2.0.0" - -regexpp@^1.0.1: - version "1.1.0" - resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-1.1.0.tgz#0e3516dd0b7904f413d2d4193dce4618c3a689ab" - -regexpu-core@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-2.0.0.tgz#49d038837b8dcf8bfa5b9a42139938e6ea2ae240" - dependencies: - regenerate "^1.2.1" - regjsgen "^0.2.0" - regjsparser "^0.1.4" - -registry-auth-token@^3.0.1: - version "3.3.1" - resolved "https://registry.yarnpkg.com/registry-auth-token/-/registry-auth-token-3.3.1.tgz#fb0d3289ee0d9ada2cbb52af5dfe66cb070d3006" - dependencies: - rc "^1.1.6" - safe-buffer "^5.0.1" - -registry-url@^3.0.3: - version "3.1.0" - resolved "https://registry.yarnpkg.com/registry-url/-/registry-url-3.1.0.tgz#3d4ef870f73dde1d77f0cf9a381432444e174942" - dependencies: - rc "^1.0.1" - -regjsgen@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/regjsgen/-/regjsgen-0.2.0.tgz#6c016adeac554f75823fe37ac05b92d5a4edb1f7" - -regjsparser@^0.1.4: - version "0.1.5" - resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.1.5.tgz#7ee8f84dc6fa792d3fd0ae228d24bd949ead205c" - dependencies: - jsesc "~0.5.0" - -release-zalgo@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/release-zalgo/-/release-zalgo-1.0.0.tgz#09700b7e5074329739330e535c5a90fb67851730" - dependencies: - es6-error "^4.0.1" - -remove-trailing-separator@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/remove-trailing-separator/-/remove-trailing-separator-1.0.2.tgz#69b062d978727ad14dc6b56ba4ab772fd8d70511" - -repeat-element@^1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.2.tgz#ef089a178d1483baae4d93eb98b4f9e4e11d990a" - -repeat-string@^1.5.2: - version "1.6.1" - resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" - -repeating@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/repeating/-/repeating-2.0.1.tgz#5214c53a926d3552707527fbab415dbc08d06dda" - dependencies: - is-finite "^1.0.0" - -request@^2.81.0: - version "2.81.0" - resolved "https://registry.yarnpkg.com/request/-/request-2.81.0.tgz#c6928946a0e06c5f8d6f8a9333469ffda46298a0" - dependencies: - aws-sign2 "~0.6.0" - aws4 "^1.2.1" - caseless "~0.12.0" - combined-stream "~1.0.5" - extend "~3.0.0" - forever-agent "~0.6.1" - form-data "~2.1.1" - har-validator "~4.2.1" - hawk "~3.1.3" - http-signature "~1.1.0" - is-typedarray "~1.0.0" - isstream "~0.1.2" - json-stringify-safe "~5.0.1" - mime-types "~2.1.7" - oauth-sign "~0.8.1" - performance-now "^0.2.0" - qs "~6.4.0" - safe-buffer "^5.0.1" - stringstream "~0.0.4" - tough-cookie "~2.3.0" - tunnel-agent "^0.6.0" - uuid "^3.0.0" - -require-directory@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" - -require-main-filename@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-1.0.1.tgz#97f717b69d48784f5f526a6c5aa8ffdda055a4d1" - -require-precompiled@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/require-precompiled/-/require-precompiled-0.1.0.tgz#5a1b52eb70ebed43eb982e974c85ab59571e56fa" - -require-uncached@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/require-uncached/-/require-uncached-1.0.3.tgz#4e0d56d6c9662fd31e43011c4b95aa49955421d3" - dependencies: - caller-path "^0.1.0" - resolve-from "^1.0.0" - -resolve-cwd@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-2.0.0.tgz#00a9f7387556e27038eae232caa372a6a59b665a" - dependencies: - resolve-from "^3.0.0" - -resolve-from@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-1.0.1.tgz#26cbfe935d1aeeeabb29bc3fe5aeb01e93d44226" - -resolve-from@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-2.0.0.tgz#9480ab20e94ffa1d9e80a804c7ea147611966b57" - -resolve-from@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-3.0.0.tgz#b22c7af7d9d6881bc8b6e653335eebcb0a188748" - -resolve@1.1.7: - version "1.1.7" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.1.7.tgz#203114d82ad2c5ed9e8e0411b3932875e889e97b" - -resolve@^1.1.6, resolve@^1.2.0: - version "1.3.3" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.3.3.tgz#655907c3469a8680dc2de3a275a8fdd69691f0e5" - dependencies: - path-parse "^1.0.5" - -resolve@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.4.0.tgz#a75be01c53da25d934a98ebd0e4c4a7312f92a86" - dependencies: - path-parse "^1.0.5" - -restore-cursor@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-2.0.0.tgz#9f7ee287f82fd326d4fd162923d62129eee0dfaf" - dependencies: - onetime "^2.0.0" - signal-exit "^3.0.2" - -right-align@^0.1.1: - version "0.1.3" - resolved "https://registry.yarnpkg.com/right-align/-/right-align-0.1.3.tgz#61339b722fe6a3515689210d24e14c96148613ef" - dependencies: - align-text "^0.1.1" - -rimraf@2: - version "2.6.3" - resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.3.tgz#b2d104fe0d8fb27cf9e0a1cda8262dd3833c6cab" - dependencies: - glob "^7.1.3" - -rimraf@^2.2.8, rimraf@^2.3.3, rimraf@^2.5.1, rimraf@^2.5.4, rimraf@^2.6.1: - version "2.6.1" - resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.1.tgz#c2338ec643df7a1b7fe5c54fa86f57428a55f33d" - dependencies: - glob "^7.0.5" - -rollup-plugin-babel-minify@^3.1.2: - version "3.1.2" - resolved "https://registry.yarnpkg.com/rollup-plugin-babel-minify/-/rollup-plugin-babel-minify-3.1.2.tgz#86a99d00b3d60984281baaeff4eb1f0eb509b053" - dependencies: - "@comandeer/babel-plugin-banner" "^1.0.0" - babel-core "^6.21.0" - babel-preset-minify "^0.2.0" - -rollup-plugin-babel@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/rollup-plugin-babel/-/rollup-plugin-babel-3.0.2.tgz#a2765dea0eaa8aece351c983573300d17497495b" - dependencies: - rollup-pluginutils "^1.5.0" - -rollup-plugin-commonjs@^8.2.1: - version "8.2.1" - resolved "https://registry.yarnpkg.com/rollup-plugin-commonjs/-/rollup-plugin-commonjs-8.2.1.tgz#5e40c78375eb163c14c76bce69da1750e5905a2e" - dependencies: - acorn "^5.1.1" - estree-walker "^0.5.0" - magic-string "^0.22.4" - resolve "^1.4.0" - rollup-pluginutils "^2.0.1" - -rollup-plugin-node-resolve@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/rollup-plugin-node-resolve/-/rollup-plugin-node-resolve-3.0.0.tgz#8b897c4c3030d5001277b0514b25d2ca09683ee0" - dependencies: - browser-resolve "^1.11.0" - builtin-modules "^1.1.0" - is-module "^1.0.0" - resolve "^1.1.6" - -rollup-pluginutils@^1.5.0: - version "1.5.2" - resolved "https://registry.yarnpkg.com/rollup-pluginutils/-/rollup-pluginutils-1.5.2.tgz#1e156e778f94b7255bfa1b3d0178be8f5c552408" - dependencies: - estree-walker "^0.2.1" - minimatch "^3.0.2" - -rollup-pluginutils@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/rollup-pluginutils/-/rollup-pluginutils-2.0.1.tgz#7ec95b3573f6543a46a6461bd9a7c544525d0fc0" - dependencies: - estree-walker "^0.3.0" - micromatch "^2.3.11" - -rollup@^0.49.3: - version "0.49.3" - resolved "https://registry.yarnpkg.com/rollup/-/rollup-0.49.3.tgz#4cce32643dd8cf2154c69ff0e43470067db0adbf" - -run-async@^2.2.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/run-async/-/run-async-2.3.0.tgz#0371ab4ae0bdd720d4166d7dfda64ff7a445a6c0" - dependencies: - is-promise "^2.1.0" - -rx-lite-aggregates@^4.0.8: - version "4.0.8" - resolved "https://registry.yarnpkg.com/rx-lite-aggregates/-/rx-lite-aggregates-4.0.8.tgz#753b87a89a11c95467c4ac1626c4efc4e05c67be" - dependencies: - rx-lite "*" - -rx-lite@*, rx-lite@^4.0.8: - version "4.0.8" - resolved "https://registry.yarnpkg.com/rx-lite/-/rx-lite-4.0.8.tgz#0b1e11af8bc44836f04a6407e92da42467b79444" - -safe-buffer@^5.0.1, safe-buffer@^5.1.1, safe-buffer@~5.1.0: - version "5.1.1" - resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.1.tgz#893312af69b2123def71f57889001671eeb2c853" - -safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0: - version "2.1.2" - resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" - -semver-diff@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/semver-diff/-/semver-diff-2.1.0.tgz#4bbb8437c8d37e4b0cf1a68fd726ec6d645d6d36" - dependencies: - semver "^5.0.3" - -"semver@2 || 3 || 4 || 5", semver@^5.0.3, semver@^5.1.0, semver@^5.3.0: - version "5.3.0" - resolved "https://registry.yarnpkg.com/semver/-/semver-5.3.0.tgz#9b2ce5d3de02d17c6012ad326aa6b4d0cf54f94f" - -set-blocking@^2.0.0, set-blocking@~2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" - -set-immediate-shim@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz#4b2b1b27eb808a9f8dcc481a58e5e56f599f3f61" - -shebang-command@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea" - dependencies: - shebang-regex "^1.0.0" - -shebang-regex@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3" - -signal-exit@^3.0.0, signal-exit@^3.0.1, signal-exit@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d" - -slash@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/slash/-/slash-1.0.0.tgz#c41f2f6c39fc16d1cd17ad4b5d896114ae470d55" - -slice-ansi@0.0.4: - version "0.0.4" - resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-0.0.4.tgz#edbf8903f66f7ce2f8eafd6ceed65e264c831b35" - -slice-ansi@1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-1.0.0.tgz#044f1a49d8842ff307aad6b505ed178bd950134d" - dependencies: - is-fullwidth-code-point "^2.0.0" - -slide@^1.1.5: - version "1.1.6" - resolved "https://registry.yarnpkg.com/slide/-/slide-1.1.6.tgz#56eb027d65b4d2dce6cb2e2d32c4d4afc9e1d707" - -sntp@1.x.x: - version "1.0.9" - resolved "https://registry.yarnpkg.com/sntp/-/sntp-1.0.9.tgz#6541184cc90aeea6c6e7b35e2659082443c66198" - dependencies: - hoek "2.x.x" - -sort-keys@^1.1.1, sort-keys@^1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/sort-keys/-/sort-keys-1.1.2.tgz#441b6d4d346798f1b4e49e8920adfba0e543f9ad" - dependencies: - is-plain-obj "^1.0.0" - -source-map-support@^0.4.0, source-map-support@^0.4.2: - version "0.4.15" - resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.4.15.tgz#03202df65c06d2bd8c7ec2362a193056fef8d3b1" - dependencies: - source-map "^0.5.6" - -source-map-support@^0.4.15: - version "0.4.17" - resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.4.17.tgz#6f2150553e6375375d0ccb3180502b78c18ba430" - dependencies: - source-map "^0.5.6" - -source-map@^0.4.4: - version "0.4.4" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.4.4.tgz#eba4f5da9c0dc999de68032d8b4f76173652036b" - dependencies: - amdefine ">=0.0.4" - -source-map@^0.5.0, source-map@^0.5.3, source-map@^0.5.6, source-map@~0.5.1: - version "0.5.6" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.6.tgz#75ce38f52bf0733c5a7f0c118d81334a2bb5f412" - -spawn-wrap@^1.3.8: - version "1.3.8" - resolved "https://registry.yarnpkg.com/spawn-wrap/-/spawn-wrap-1.3.8.tgz#fa2a79b990cbb0bb0018dca6748d88367b19ec31" - dependencies: - foreground-child "^1.5.6" - mkdirp "^0.5.0" - os-homedir "^1.0.1" - rimraf "^2.3.3" - signal-exit "^3.0.2" - which "^1.2.4" - -spdx-correct@~1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-1.0.2.tgz#4b3073d933ff51f3912f03ac5519498a4150db40" - dependencies: - spdx-license-ids "^1.0.2" - -spdx-expression-parse@~1.0.0: - version "1.0.4" - resolved "https://registry.yarnpkg.com/spdx-expression-parse/-/spdx-expression-parse-1.0.4.tgz#9bdf2f20e1f40ed447fbe273266191fced51626c" - -spdx-license-ids@^1.0.2: - version "1.2.2" - resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-1.2.2.tgz#c9df7a3424594ade6bd11900d596696dc06bac57" - -sprintf-js@~1.0.2: - version "1.0.3" - resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" - -sshpk@^1.7.0: - version "1.16.1" - resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.16.1.tgz#fb661c0bef29b39db40769ee39fa70093d6f6877" - dependencies: - asn1 "~0.2.3" - assert-plus "^1.0.0" - bcrypt-pbkdf "^1.0.0" - dashdash "^1.12.0" - ecc-jsbn "~0.1.1" - getpass "^0.1.1" - jsbn "~0.1.0" - safer-buffer "^2.0.2" - tweetnacl "~0.14.0" - -stack-utils@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/stack-utils/-/stack-utils-1.0.1.tgz#d4f33ab54e8e38778b0ca5cfd3b3afb12db68620" - -string-width@^1.0.1, string-width@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3" - dependencies: - code-point-at "^1.0.0" - is-fullwidth-code-point "^1.0.0" - strip-ansi "^3.0.0" - -string-width@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.0.0.tgz#635c5436cc72a6e0c387ceca278d4e2eec52687e" - dependencies: - is-fullwidth-code-point "^2.0.0" - strip-ansi "^3.0.0" - -string-width@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.0.tgz#030664561fc146c9423ec7d978fe2457437fe6d0" - dependencies: - is-fullwidth-code-point "^2.0.0" - strip-ansi "^4.0.0" - -string-width@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" - dependencies: - is-fullwidth-code-point "^2.0.0" - strip-ansi "^4.0.0" - -string_decoder@~1.0.0: - version "1.0.3" - resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.0.3.tgz#0fc67d7c141825de94282dd536bec6b9bce860ab" - dependencies: - safe-buffer "~5.1.0" - -stringstream@~0.0.4: - version "0.0.6" - resolved "https://registry.yarnpkg.com/stringstream/-/stringstream-0.0.6.tgz#7880225b0d4ad10e30927d167a1d6f2fd3b33a72" - -strip-ansi@^3.0.0, strip-ansi@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" - dependencies: - ansi-regex "^2.0.0" - -strip-ansi@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f" - dependencies: - ansi-regex "^3.0.0" - -strip-ansi@~0.1.0: - version "0.1.1" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-0.1.1.tgz#39e8a98d044d150660abe4a6808acf70bb7bc991" - -strip-bom-buf@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/strip-bom-buf/-/strip-bom-buf-1.0.0.tgz#1cb45aaf57530f4caf86c7f75179d2c9a51dd572" - dependencies: - is-utf8 "^0.2.1" - -strip-bom@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-2.0.0.tgz#6219a85616520491f35788bdbf1447a99c7e6b0e" - dependencies: - is-utf8 "^0.2.0" - -strip-bom@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3" - -strip-eof@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf" - -strip-indent@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/strip-indent/-/strip-indent-1.0.1.tgz#0c7962a6adefa7bbd4ac366460a638552ae1a0a2" - dependencies: - get-stdin "^4.0.1" - -strip-json-comments@~2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" - -supports-color@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" - -supports-color@^3.1.2: - version "3.2.3" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-3.2.3.tgz#65ac0504b3954171d8a64946b2ae3cbb8a5f54f6" - dependencies: - has-flag "^1.0.0" - -supports-color@^4.0.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-4.2.0.tgz#ad986dc7eb2315d009b4d77c8169c2231a684037" - dependencies: - has-flag "^2.0.0" - -symbol-observable@^0.2.2: - version "0.2.4" - resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-0.2.4.tgz#95a83db26186d6af7e7a18dbd9760a2f86d08f40" - -symbol-observable@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.0.4.tgz#29bf615d4aa7121bdd898b22d4b3f9bc4e2aa03d" - -table@4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/table/-/table-4.0.2.tgz#a33447375391e766ad34d3486e6e2aedc84d2e36" - dependencies: - ajv "^5.2.3" - ajv-keywords "^2.1.0" - chalk "^2.1.0" - lodash "^4.17.4" - slice-ansi "1.0.0" - string-width "^2.1.1" - -tailored@^2.7.4: - version "2.7.4" - resolved "https://registry.yarnpkg.com/tailored/-/tailored-2.7.4.tgz#473c6c91fcaeb2c8e4ddd5c2bddb33190ac21780" - dependencies: - erlang-types "^1.0.1" - -tar-pack@^3.4.0: - version "3.4.0" - resolved "https://registry.yarnpkg.com/tar-pack/-/tar-pack-3.4.0.tgz#23be2d7f671a8339376cbdb0b8fe3fdebf317984" - dependencies: - debug "^2.2.0" - fstream "^1.0.10" - fstream-ignore "^1.0.5" - once "^1.3.3" - readable-stream "^2.1.4" - rimraf "^2.5.1" - tar "^2.2.1" - uid-number "^0.0.6" - -tar@^2.2.1: - version "2.2.2" - resolved "https://registry.yarnpkg.com/tar/-/tar-2.2.2.tgz#0ca8848562c7299b8b446ff6a4d60cdbb23edc40" - dependencies: - block-stream "*" - fstream "^1.0.12" - inherits "2" - -term-size@^0.1.0: - version "0.1.1" - resolved "https://registry.yarnpkg.com/term-size/-/term-size-0.1.1.tgz#87360b96396cab5760963714cda0d0cbeecad9ca" - dependencies: - execa "^0.4.0" - -test-exclude@^4.1.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/test-exclude/-/test-exclude-4.1.1.tgz#4d84964b0966b0087ecc334a2ce002d3d9341e26" - dependencies: - arrify "^1.0.1" - micromatch "^2.3.11" - object-assign "^4.1.0" - read-pkg-up "^1.0.1" - require-main-filename "^1.0.1" - -text-table@^0.2.0, text-table@~0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" - -through2@^2.0.0: - version "2.0.3" - resolved "https://registry.yarnpkg.com/through2/-/through2-2.0.3.tgz#0004569b37c7c74ba39c43f3ced78d1ad94140be" - dependencies: - readable-stream "^2.1.5" - xtend "~4.0.1" - -through@^2.3.6: - version "2.3.8" - resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" - -time-require@^0.1.2: - version "0.1.2" - resolved "https://registry.yarnpkg.com/time-require/-/time-require-0.1.2.tgz#f9e12cb370fc2605e11404582ba54ef5ca2b2d98" - dependencies: - chalk "^0.4.0" - date-time "^0.1.1" - pretty-ms "^0.2.1" - text-table "^0.2.0" - -time-zone@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/time-zone/-/time-zone-1.0.0.tgz#99c5bf55958966af6d06d83bdf3800dc82faec5d" - -timed-out@^4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/timed-out/-/timed-out-4.0.1.tgz#f32eacac5a175bea25d7fab565ab3ed8741ef56f" - -tmp@^0.0.31: - version "0.0.31" - resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.31.tgz#8f38ab9438e17315e5dbd8b3657e8bfb277ae4a7" - dependencies: - os-tmpdir "~1.0.1" - -to-fast-properties@^1.0.1, to-fast-properties@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-1.0.3.tgz#b83571fa4d8c25b82e231b06e3a3055de4ca1a47" - -tough-cookie@~2.3.0: - version "2.3.4" - resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.3.4.tgz#ec60cee38ac675063ffc97a5c18970578ee83655" - dependencies: - punycode "^1.4.1" - -trim-newlines@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/trim-newlines/-/trim-newlines-1.0.0.tgz#5887966bb582a4503a41eb524f7d35011815a613" - -trim-off-newlines@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/trim-off-newlines/-/trim-off-newlines-1.0.1.tgz#9f9ba9d9efa8764c387698bcbfeb2c848f11adb3" - -trim-right@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/trim-right/-/trim-right-1.0.1.tgz#cb2e1203067e0c8de1f614094b9fe45704ea6003" - -tryit@^1.0.1: - version "1.0.3" - resolved "https://registry.yarnpkg.com/tryit/-/tryit-1.0.3.tgz#393be730a9446fd1ead6da59a014308f36c289cb" - -tunnel-agent@^0.6.0: - version "0.6.0" - resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd" - dependencies: - safe-buffer "^5.0.1" - -tweetnacl@^0.14.3, tweetnacl@~0.14.0: - version "0.14.5" - resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" - -type-check@~0.3.2: - version "0.3.2" - resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.3.2.tgz#5884cab512cf1d355e3fb784f30804b2b520db72" - dependencies: - prelude-ls "~1.1.2" - -typedarray@^0.0.6: - version "0.0.6" - resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" - -uglify-js@^2.6: - version "2.8.29" - resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-2.8.29.tgz#29c5733148057bb4e1f75df35b7a9cb72e6a59dd" - dependencies: - source-map "~0.5.1" - yargs "~3.10.0" - optionalDependencies: - uglify-to-browserify "~1.0.0" - -uglify-to-browserify@~1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz#6e0924d6bda6b5afe349e39a6d632850a0f882b7" - -uid-number@^0.0.6: - version "0.0.6" - resolved "https://registry.yarnpkg.com/uid-number/-/uid-number-0.0.6.tgz#0ea10e8035e8eb5b8e4449f06da1c730663baa81" - -uid2@0.0.3: - version "0.0.3" - resolved "https://registry.yarnpkg.com/uid2/-/uid2-0.0.3.tgz#483126e11774df2f71b8b639dcd799c376162b82" - -unique-string@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/unique-string/-/unique-string-1.0.0.tgz#9e1057cca851abb93398f8b33ae187b99caec11a" - dependencies: - crypto-random-string "^1.0.0" - -unique-temp-dir@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/unique-temp-dir/-/unique-temp-dir-1.0.0.tgz#6dce95b2681ca003eebfb304a415f9cbabcc5385" - dependencies: - mkdirp "^0.5.1" - os-tmpdir "^1.0.1" - uid2 "0.0.3" - -unzip-response@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/unzip-response/-/unzip-response-2.0.1.tgz#d2f0f737d16b0615e72a6935ed04214572d56f97" - -update-notifier@^2.1.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/update-notifier/-/update-notifier-2.2.0.tgz#1b5837cf90c0736d88627732b661c138f86de72f" - dependencies: - boxen "^1.0.0" - chalk "^1.0.0" - configstore "^3.0.0" - import-lazy "^2.1.0" - is-npm "^1.0.0" - latest-version "^3.0.0" - semver-diff "^2.0.0" - xdg-basedir "^3.0.0" - -url-parse-lax@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/url-parse-lax/-/url-parse-lax-1.0.0.tgz#7af8f303645e9bd79a272e7a14ac68bc0609da73" - dependencies: - prepend-http "^1.0.1" - -util-deprecate@~1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" - -uuid@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.1.0.tgz#3dd3d3e790abc24d7b0d3a034ffababe28ebbc04" - -validate-npm-package-license@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.1.tgz#2804babe712ad3379459acfbe24746ab2c303fbc" - dependencies: - spdx-correct "~1.0.0" - spdx-expression-parse "~1.0.0" - -verror@1.3.6: - version "1.3.6" - resolved "https://registry.yarnpkg.com/verror/-/verror-1.3.6.tgz#cff5df12946d297d2baaefaa2689e25be01c005c" - dependencies: - extsprintf "1.0.2" - -vlq@^0.2.1: - version "0.2.2" - resolved "https://registry.yarnpkg.com/vlq/-/vlq-0.2.2.tgz#e316d5257b40b86bb43cb8d5fea5d7f54d6b0ca1" - -well-known-symbols@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/well-known-symbols/-/well-known-symbols-1.0.0.tgz#73c78ae81a7726a8fa598e2880801c8b16225518" - -which-module@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a" - -which@^1.2.4, which@^1.2.8, which@^1.2.9: - version "1.2.14" - resolved "https://registry.yarnpkg.com/which/-/which-1.2.14.tgz#9a87c4378f03e827cecaf1acdf56c736c01c14e5" - dependencies: - isexe "^2.0.0" - -wide-align@^1.1.0: - version "1.1.2" - resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.2.tgz#571e0f1b0604636ebc0dfc21b0339bbe31341710" - dependencies: - string-width "^1.0.2" - -widest-line@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/widest-line/-/widest-line-1.0.0.tgz#0c09c85c2a94683d0d7eaf8ee097d564bf0e105c" - dependencies: - string-width "^1.0.1" - -window-size@0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/window-size/-/window-size-0.1.0.tgz#5438cd2ea93b202efa3a19fe8887aee7c94f9c9d" - -wordwrap@0.0.2: - version "0.0.2" - resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-0.0.2.tgz#b79669bb42ecb409f83d583cad52ca17eaa1643f" - -wordwrap@~0.0.2: - version "0.0.3" - resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-0.0.3.tgz#a3d5da6cd5c0bc0008d37234bbaf1bed63059107" - -wordwrap@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb" - -wrap-ansi@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-2.1.0.tgz#d8fc3d284dd05794fe84973caecdd1cf824fdd85" - dependencies: - string-width "^1.0.1" - strip-ansi "^3.0.1" - -wrappy@1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" - -write-file-atomic@^1.1.4: - version "1.3.4" - resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-1.3.4.tgz#f807a4f0b1d9e913ae7a48112e6cc3af1991b45f" - dependencies: - graceful-fs "^4.1.11" - imurmurhash "^0.1.4" - slide "^1.1.5" - -write-file-atomic@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-2.1.0.tgz#1769f4b551eedce419f0505deae2e26763542d37" - dependencies: - graceful-fs "^4.1.11" - imurmurhash "^0.1.4" - slide "^1.1.5" - -write-json-file@^2.0.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/write-json-file/-/write-json-file-2.2.0.tgz#51862506bbb3b619eefab7859f1fd6c6d0530876" - dependencies: - detect-indent "^5.0.0" - graceful-fs "^4.1.2" - make-dir "^1.0.0" - pify "^2.0.0" - sort-keys "^1.1.1" - write-file-atomic "^2.0.0" - -write-pkg@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/write-pkg/-/write-pkg-2.1.0.tgz#353aa44c39c48c21440f5c08ce6abd46141c9c08" - dependencies: - sort-keys "^1.1.2" - write-json-file "^2.0.0" - -write@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/write/-/write-0.2.1.tgz#5fc03828e264cea3fe91455476f7a3c566cb0757" - dependencies: - mkdirp "^0.5.1" - -xdg-basedir@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/xdg-basedir/-/xdg-basedir-3.0.0.tgz#496b2cc109eca8dbacfe2dc72b603c17c5870ad4" - -xtend@^4.0.0, xtend@~4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.1.tgz#a5c6d532be656e23db820efb943a1f04998d63af" - -y18n@^3.2.1: - version "3.2.1" - resolved "https://registry.yarnpkg.com/y18n/-/y18n-3.2.1.tgz#6d15fba884c08679c0d77e88e7759e811e07fa41" - -yallist@^2.1.2: - version "2.1.2" - resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52" - -yargs-parser@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-5.0.0.tgz#275ecf0d7ffe05c77e64e7c86e4cd94bf0e1228a" - dependencies: - camelcase "^3.0.0" - -yargs-parser@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-7.0.0.tgz#8d0ac42f16ea55debd332caf4c4038b3e3f5dfd9" - dependencies: - camelcase "^4.1.0" - -yargs@^8.0.1: - version "8.0.2" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-8.0.2.tgz#6299a9055b1cefc969ff7e79c1d918dceb22c360" - dependencies: - camelcase "^4.1.0" - cliui "^3.2.0" - decamelize "^1.1.1" - get-caller-file "^1.0.1" - os-locale "^2.0.0" - read-pkg-up "^2.0.0" - require-directory "^2.1.1" - require-main-filename "^1.0.1" - set-blocking "^2.0.0" - string-width "^2.0.0" - which-module "^2.0.0" - y18n "^3.2.1" - yargs-parser "^7.0.0" - -yargs@~3.10.0: - version "3.10.0" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-3.10.0.tgz#f7ee7bd857dd7c1d2d38c0e74efbd681d1431fd1" - dependencies: - camelcase "^1.0.2" - cliui "^2.1.0" - decamelize "^1.0.0" - window-size "0.1.0" From a9a6939a03b06ba20fbc7576e2d061dc6e653948 Mon Sep 17 00:00:00 2001 From: Bryan Joseph Date: Tue, 20 Aug 2019 09:13:27 -0500 Subject: [PATCH 418/418] Update elixir deps --- lib/elixir_script/compiler.ex | 2 +- .../passes/translate/forms/pattern.ex | 8 +++---- mix.lock | 22 ++++++++++--------- test/passes/translate/form_test.exs | 8 +++---- test/passes/translate/forms/map_test.exs | 2 +- 5 files changed, 22 insertions(+), 20 deletions(-) diff --git a/lib/elixir_script/compiler.ex b/lib/elixir_script/compiler.ex index 35f7b8ec..9e36d5a8 100644 --- a/lib/elixir_script/compiler.ex +++ b/lib/elixir_script/compiler.ex @@ -56,7 +56,7 @@ defmodule ElixirScript.Compiler do files = Path.wildcard(path) - ParallelCompiler.files(files, each_module: &on_module_compile(pid, &1, &2, &3)) + ParallelCompiler.compile(files, each_module: &on_module_compile(pid, &1, &2, &3)) entry_modules = pid diff --git a/lib/elixir_script/passes/translate/forms/pattern.ex b/lib/elixir_script/passes/translate/forms/pattern.ex index 9536e7db..a671178a 100644 --- a/lib/elixir_script/passes/translate/forms/pattern.ex +++ b/lib/elixir_script/passes/translate/forms/pattern.ex @@ -207,11 +207,11 @@ defmodule ElixirScript.Translate.Forms.Pattern do { [PM.starts_with(prefix)], [Form.compile!(value, state)] } end - defp process_pattern({:=, _, [{name, _, _} = target, right]}, state) when not name in [:%, :{}, :^, :%{}, :<<>>] do + defp process_pattern({:=, _, [{name, _, _} = target, right]}, state) when name not in [:%, :{}, :^, :%{}, :<<>>] do unify(target, right, state) end - defp process_pattern({:=, _, [left, {name, _, _} = target]}, state) when not name in [:%, :{}, :^, :%{}, :<<>>] do + defp process_pattern({:=, _, [left, {name, _, _} = target]}, state) when name not in [:%, :{}, :^, :%{}, :<<>>] do unify(target, left, state) end @@ -241,8 +241,8 @@ defmodule ElixirScript.Translate.Forms.Pattern do def get_counter(meta) do case Keyword.get(meta, :counter, nil) do nil -> "" - counter -> - counter + {module, value} -> + value |> Kernel.abs() |> to_string() end diff --git a/mix.lock b/mix.lock index 9881ee42..3e10cac4 100644 --- a/mix.lock +++ b/mix.lock @@ -1,22 +1,24 @@ -%{"bunt": {:hex, :bunt, "0.2.0", "951c6e801e8b1d2cbe58ebbd3e616a869061ddadcc4863d0a2182541acae9a38", [:mix], [], "hexpm"}, +%{ + "bunt": {:hex, :bunt, "0.2.0", "951c6e801e8b1d2cbe58ebbd3e616a869061ddadcc4863d0a2182541acae9a38", [:mix], [], "hexpm"}, "certifi": {:hex, :certifi, "2.5.1", "867ce347f7c7d78563450a18a6a28a8090331e77fa02380b4a21962a65d36ee5", [:rebar3], [{:parse_trans, "~>3.3", [hex: :parse_trans, repo: "hexpm", optional: false]}], "hexpm"}, - "credo": {:hex, :credo, "1.0.5", "fdea745579f8845315fe6a3b43e2f9f8866839cfbc8562bb72778e9fdaa94214", [:mix], [{:bunt, "~> 0.2.0", [hex: :bunt, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm"}, - "earmark": {:hex, :earmark, "1.3.2", "b840562ea3d67795ffbb5bd88940b1bed0ed9fa32834915125ea7d02e35888a5", [:mix], [], "hexpm"}, + "credo": {:hex, :credo, "1.1.3", "bf31887b8914a4b7e1810ae2b5aab7c657698abbf4cca6a2335a094d57995168", [:mix], [{:bunt, "~> 0.2.0", [hex: :bunt, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm"}, + "earmark": {:hex, :earmark, "1.3.5", "0db71c8290b5bc81cb0101a2a507a76dca659513984d683119ee722828b424f6", [:mix], [], "hexpm"}, "estree": {:hex, :estree, "2.7.0", "32cb6ff05c85a93bf6c646b3b184e131f699fc1e7157d2b5be148c17f43ae566", [:mix], [], "hexpm"}, - "ex_doc": {:hex, :ex_doc, "0.20.2", "1bd0dfb0304bade58beb77f20f21ee3558cc3c753743ae0ddbb0fd7ba2912331", [:mix], [{:earmark, "~> 1.3", [hex: :earmark, repo: "hexpm", optional: false]}, {:makeup_elixir, "~> 0.10", [hex: :makeup_elixir, repo: "hexpm", optional: false]}], "hexpm"}, - "excoveralls": {:hex, :excoveralls, "0.11.1", "dd677fbdd49114fdbdbf445540ec735808250d56b011077798316505064edb2c", [:mix], [{:hackney, "~> 1.0", [hex: :hackney, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm"}, + "ex_doc": {:hex, :ex_doc, "0.21.1", "5ac36660846967cd869255f4426467a11672fec3d8db602c429425ce5b613b90", [:mix], [{:earmark, "~> 1.3", [hex: :earmark, repo: "hexpm", optional: false]}, {:makeup_elixir, "~> 0.14", [hex: :makeup_elixir, repo: "hexpm", optional: false]}], "hexpm"}, + "excoveralls": {:hex, :excoveralls, "0.11.2", "0c6f2c8db7683b0caa9d490fb8125709c54580b4255ffa7ad35f3264b075a643", [:mix], [{:hackney, "~> 1.0", [hex: :hackney, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm"}, "exjsx": {:hex, :exjsx, "4.0.0", "60548841e0212df401e38e63c0078ec57b33e7ea49b032c796ccad8cde794b5c", [:mix], [{:jsx, "~> 2.8.0", [hex: :jsx, repo: "hexpm", optional: false]}], "hexpm"}, "hackney": {:hex, :hackney, "1.15.1", "9f8f471c844b8ce395f7b6d8398139e26ddca9ebc171a8b91342ee15a19963f4", [:rebar3], [{:certifi, "2.5.1", [hex: :certifi, repo: "hexpm", optional: false]}, {:idna, "6.0.0", [hex: :idna, repo: "hexpm", optional: false]}, {:metrics, "1.0.1", [hex: :metrics, repo: "hexpm", optional: false]}, {:mimerl, "~>1.1", [hex: :mimerl, repo: "hexpm", optional: false]}, {:ssl_verify_fun, "1.1.4", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}], "hexpm"}, "idna": {:hex, :idna, "6.0.0", "689c46cbcdf3524c44d5f3dde8001f364cd7608a99556d8fbd8239a5798d4c10", [:rebar3], [{:unicode_util_compat, "0.4.1", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm"}, "jason": {:hex, :jason, "1.1.2", "b03dedea67a99223a2eaf9f1264ce37154564de899fd3d8b9a21b1a6fd64afe7", [:mix], [{:decimal, "~> 1.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm"}, "jsx": {:hex, :jsx, "2.8.3", "a05252d381885240744d955fbe3cf810504eb2567164824e19303ea59eef62cf", [:mix, :rebar3], [], "hexpm"}, - "makeup": {:hex, :makeup, "0.8.0", "9cf32aea71c7fe0a4b2e9246c2c4978f9070257e5c9ce6d4a28ec450a839b55f", [:mix], [{:nimble_parsec, "~> 0.5.0", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm"}, - "makeup_elixir": {:hex, :makeup_elixir, "0.13.0", "be7a477997dcac2e48a9d695ec730b2d22418292675c75aa2d34ba0909dcdeda", [:mix], [{:makeup, "~> 0.8", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm"}, + "makeup": {:hex, :makeup, "1.0.0", "671df94cf5a594b739ce03b0d0316aa64312cee2574b6a44becb83cd90fb05dc", [:mix], [{:nimble_parsec, "~> 0.5.0", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm"}, + "makeup_elixir": {:hex, :makeup_elixir, "0.14.0", "cf8b7c66ad1cff4c14679698d532f0b5d45a3968ffbcbfd590339cb57742f1ae", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm"}, "metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [:rebar3], [], "hexpm"}, "mimerl": {:hex, :mimerl, "1.2.0", "67e2d3f571088d5cfd3e550c383094b47159f3eee8ffa08e64106cdf5e981be3", [:rebar3], [], "hexpm"}, - "nimble_parsec": {:hex, :nimble_parsec, "0.5.0", "90e2eca3d0266e5c53f8fbe0079694740b9c91b6747f2b7e3c5d21966bba8300", [:mix], [], "hexpm"}, + "nimble_parsec": {:hex, :nimble_parsec, "0.5.1", "c90796ecee0289dbb5ad16d3ad06f957b0cd1199769641c961cfe0b97db190e0", [:mix], [], "hexpm"}, "parse_trans": {:hex, :parse_trans, "3.3.0", "09765507a3c7590a784615cfd421d101aec25098d50b89d7aa1d66646bc571c1", [:rebar3], [], "hexpm"}, "poison": {:hex, :poison, "4.0.1", "bcb755a16fac91cad79bfe9fc3585bb07b9331e50cfe3420a24bcc2d735709ae", [:mix], [], "hexpm"}, "ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.4", "f0eafff810d2041e93f915ef59899c923f4568f4585904d010387ed74988e77b", [:make, :mix, :rebar3], [], "hexpm"}, - "stream_data": {:hex, :stream_data, "0.3.0", "cbfc8e3212f64683615657ea27804126a42ded634adfdfee258bf087ee605d46", [:mix], [], "hexpm"}, - "unicode_util_compat": {:hex, :unicode_util_compat, "0.4.1", "d869e4c68901dd9531385bb0c8c40444ebf624e60b6962d95952775cac5e90cd", [:rebar3], [], "hexpm"}} + "stream_data": {:hex, :stream_data, "0.4.3", "62aafd870caff0849a5057a7ec270fad0eb86889f4d433b937d996de99e3db25", [:mix], [], "hexpm"}, + "unicode_util_compat": {:hex, :unicode_util_compat, "0.4.1", "d869e4c68901dd9531385bb0c8c40444ebf624e60b6962d95952775cac5e90cd", [:rebar3], [], "hexpm"}, +} diff --git a/test/passes/translate/form_test.exs b/test/passes/translate/form_test.exs index 7626edee..07d1b902 100644 --- a/test/passes/translate/form_test.exs +++ b/test/passes/translate/form_test.exs @@ -23,7 +23,7 @@ defmodule ElixirScript.Translate.Forms.Test do StreamData.integer(), StreamData.boolean(), StreamData.binary(), - StreamData.uniform_float() + StreamData.float() ]) do {js_ast, _} = Form.compile(value, state) assert js_ast == J.literal(value) @@ -31,7 +31,7 @@ defmodule ElixirScript.Translate.Forms.Test do end property "atom translates to Symbol.for call", %{state: state} do - check all atom <- StreamData.unquoted_atom() do + check all atom <- StreamData.atom(:alphanumeric) do {js_ast, _} = Form.compile(atom, state) assert js_ast == @@ -77,7 +77,7 @@ defmodule ElixirScript.Translate.Forms.Test do end property "local function call translates to local JavaScript function call", %{state: state} do - check all func <- StreamData.filter(StreamData.unquoted_atom(), fn x -> x not in [:fn] end), + check all func <- StreamData.filter(StreamData.atom(:alphanumeric), fn x -> x not in [:fn] end), params <- StreamData.list_of(StreamData.binary()) do ast = {func, [], params} @@ -102,7 +102,7 @@ defmodule ElixirScript.Translate.Forms.Test do end property "super function call translates to local JavaScript function call" do - check all func <- StreamData.unquoted_atom(), + check all func <- StreamData.atom(:alphanumeric), params <- StreamData.list_of(StreamData.binary()) do ast = {:super, [], [{:def, func}] ++ params} state = %{function: {func, nil}, vars: %{}} diff --git a/test/passes/translate/forms/map_test.exs b/test/passes/translate/forms/map_test.exs index 79454147..22eaa6b1 100644 --- a/test/passes/translate/forms/map_test.exs +++ b/test/passes/translate/forms/map_test.exs @@ -20,7 +20,7 @@ defmodule ElixirScript.Translate.Forms.Map.Test do StreamData.integer(), StreamData.boolean(), StreamData.binary(), - StreamData.uniform_float() + StreamData.float() ]), StreamData.binary() }) do