diff --git a/.gitignore b/.gitignore index ebf5f8c73d7d..72adc0d1eb85 100644 --- a/.gitignore +++ b/.gitignore @@ -2,4 +2,5 @@ /target/ **/*.bk core -*.log \ No newline at end of file +*.log +Cargo.lock \ No newline at end of file diff --git a/Cargo.lock b/Cargo.lock deleted file mode 100644 index 9dfc17aa762b..000000000000 --- a/Cargo.lock +++ /dev/null @@ -1,756 +0,0 @@ -[[package]] -name = "aho-corasick" -version = "0.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "memchr 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "ast_node" -version = "0.1.0" -dependencies = [ - "pmutil 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "proc-macro2 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "swc_common 0.1.0", - "swc_macros 0.1.0", - "swc_macros_common 0.1.0", - "syn 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "backtrace" -version = "0.3.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "backtrace-sys 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", - "cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-demangle 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "backtrace-sys" -version = "0.1.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "cc 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "bitflags" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "cc" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "cfg-if" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "chrono" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "num 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)", - "time 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "crossbeam" -version = "0.2.12" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "debug_unreachable" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "unreachable 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "either" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "enum_kind" -version = "0.1.0" -dependencies = [ - "pmutil 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "proc-macro2 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "swc_macros_common 0.1.0", - "syn 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "failure" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "backtrace 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", - "failure_derive 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "failure_derive" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)", - "synstructure 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "fnv" -version = "1.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "fuchsia-zircon" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", - "fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "fuchsia-zircon-sys" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "isatty" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)", - "termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "kernel32-sys" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "lazy_static" -version = "0.2.11" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "lazy_static" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "libc" -version = "0.2.35" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "log" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "log" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "memchr" -version = "0.1.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "libc 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "num" -version = "0.1.41" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "num-integer 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)", - "num-iter 0.1.34 (registry+https://github.com/rust-lang/crates.io-index)", - "num-traits 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "num-integer" -version = "0.1.35" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "num-traits 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "num-iter" -version = "0.1.34" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "num-integer 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)", - "num-traits 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "num-traits" -version = "0.1.41" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "parser_macros" -version = "0.1.0" -dependencies = [ - "proc-macro2 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "swc_macros_common 0.1.0", - "syn 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "phf_generator" -version = "0.7.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "phf_shared 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.3.20 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "phf_shared" -version = "0.7.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "siphasher 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "pmutil" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "proc-macro2 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "precomputed-hash" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "proc-macro2" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "quote" -version = "0.3.15" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "quote" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "proc-macro2 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "rand" -version = "0.3.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "redox_syscall" -version = "0.1.37" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "redox_termios" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "redox_syscall 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "regex" -version = "0.1.80" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "aho-corasick 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", - "memchr 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", - "regex-syntax 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", - "thread_local 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)", - "utf8-ranges 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "regex-syntax" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "rustc-demangle" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "serde" -version = "1.0.27" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "siphasher" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "slog" -version = "2.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "slog-async" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "slog 2.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "take_mut 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "thread_local 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "slog-envlogger" -version = "2.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 0.1.80 (registry+https://github.com/rust-lang/crates.io-index)", - "slog 2.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "slog-async 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "slog-scope 4.0.1 (registry+https://github.com/rust-lang/crates.io-index)", - "slog-stdlog 3.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "slog-term 2.3.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "slog-scope" -version = "4.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "crossbeam 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", - "slog 2.1.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "slog-stdlog" -version = "3.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "crossbeam 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", - "slog 2.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "slog-scope 4.0.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "slog-term" -version = "2.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "chrono 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "isatty 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "slog 2.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "term 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "thread_local 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "string_cache" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "debug_unreachable 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", - "phf_shared 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)", - "precomputed-hash 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)", - "string_cache_codegen 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "string_cache_shared 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "string_cache_codegen" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "phf_generator 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)", - "phf_shared 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", - "string_cache_shared 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "string_cache_shared" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "swc" -version = "0.1.0" -dependencies = [ - "swc_atoms 0.1.0", - "swc_common 0.1.0", - "swc_ecmascript 0.1.0", - "swc_macros 0.1.0", -] - -[[package]] -name = "swc_atoms" -version = "0.1.0" -dependencies = [ - "string_cache 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", - "string_cache_codegen 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "swc_common" -version = "0.1.0" -dependencies = [ - "either 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", - "string_cache 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "swc_ecma_ast" -version = "0.1.0" -dependencies = [ - "swc_atoms 0.1.0", - "swc_common 0.1.0", - "swc_macros 0.1.0", -] - -[[package]] -name = "swc_ecma_parser" -version = "0.1.0" -dependencies = [ - "either 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "failure 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "parser_macros 0.1.0", - "slog 2.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "swc_atoms 0.1.0", - "swc_common 0.1.0", - "swc_ecma_ast 0.1.0", - "swc_macros 0.1.0", - "testing 0.1.0", - "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "swc_ecmascript" -version = "0.1.0" -dependencies = [ - "swc_ecma_ast 0.1.0", - "swc_ecma_parser 0.1.0", -] - -[[package]] -name = "swc_macros" -version = "0.1.0" -dependencies = [ - "ast_node 0.1.0", - "enum_kind 0.1.0", -] - -[[package]] -name = "swc_macros_common" -version = "0.1.0" -dependencies = [ - "pmutil 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "proc-macro2 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "syn" -version = "0.11.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", - "synom 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)", - "unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "syn" -version = "0.12.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "proc-macro2 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "synom" -version = "0.11.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "synstructure" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "take_mut" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "term" -version = "0.4.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "termion" -version = "1.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "libc 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)", - "redox_syscall 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)", - "redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "testing" -version = "0.1.0" -dependencies = [ - "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "slog 2.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "slog-envlogger 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "slog-term 2.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "swc_common 0.1.0", -] - -[[package]] -name = "thread-id" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "thread_local" -version = "0.2.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "thread-id 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "thread_local" -version = "0.3.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "time" -version = "0.1.39" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "libc 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)", - "redox_syscall 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "unicode-xid" -version = "0.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "unicode-xid" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "unreachable" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "unreachable" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "utf8-ranges" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "void" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "winapi" -version = "0.2.8" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "winapi" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "winapi-i686-pc-windows-gnu 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi-x86_64-pc-windows-gnu 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "winapi-build" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "winapi-i686-pc-windows-gnu" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "winapi-x86_64-pc-windows-gnu" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[metadata] -"checksum aho-corasick 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ca972c2ea5f742bfce5687b9aef75506a764f61d37f8f649047846a9686ddb66" -"checksum backtrace 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "ebbbf59b1c43eefa8c3ede390fcc36820b4999f7914104015be25025e0d62af2" -"checksum backtrace-sys 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "44585761d6161b0f57afc49482ab6bd067e4edef48c12a152c237eb0203f7661" -"checksum bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b3c30d3802dfb7281680d6285f2ccdaa8c2d8fee41f93805dba5c4cf50dc23cf" -"checksum cc 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "deaf9ec656256bb25b404c51ef50097207b9cbb29c933d31f92cae5a8a0ffee0" -"checksum cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d4c819a1287eb618df47cc647173c5c4c66ba19d888a6e50d605672aed3140de" -"checksum chrono 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7c20ebe0b2b08b0aeddba49c609fe7957ba2e33449882cb186a180bc60682fa9" -"checksum crossbeam 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)" = "bd66663db5a988098a89599d4857919b3acf7f61402e61365acfd3919857b9be" -"checksum debug_unreachable 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9a032eac705ca39214d169f83e3d3da290af06d8d1d344d1baad2fd002dca4b3" -"checksum either 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "740178ddf48b1a9e878e6d6509a1442a2d42fd2928aae8e7a6f8a36fb01981b3" -"checksum failure 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "934799b6c1de475a012a02dab0ace1ace43789ee4b99bcfbf1a2e3e8ced5de82" -"checksum failure_derive 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c7cdda555bb90c9bb67a3b670a0f42de8e73f5981524123ad8578aafec8ddb8b" -"checksum fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "2fad85553e09a6f881f739c29f0b00b0f01357c743266d478b68951ce23285f3" -"checksum fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82" -"checksum fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7" -"checksum isatty 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "8f2a233726c7bb76995cec749d59582e5664823b7245d4970354408f1d79a7a2" -"checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" -"checksum lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "76f033c7ad61445c5b347c7382dd1237847eb1bce590fe50365dcb33d546be73" -"checksum lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c8f31047daa365f19be14b47c29df4f7c3b581832407daabe6ae77397619237d" -"checksum libc 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)" = "96264e9b293e95d25bfcbbf8a88ffd1aedc85b754eba8b7d78012f638ba220eb" -"checksum log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "e19e8d5c34a3e0e2223db8e060f9e8264aeeb5c5fc64a4ee9965c062211c024b" -"checksum log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "89f010e843f2b1a31dbd316b3b8d443758bc634bed37aabade59c686d644e0a2" -"checksum memchr 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "d8b629fb514376c675b98c1421e80b151d3817ac42d7c667717d282761418d20" -"checksum num 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)" = "cc4083e14b542ea3eb9b5f33ff48bd373a92d78687e74f4cc0a30caeb754f0ca" -"checksum num-integer 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)" = "d1452e8b06e448a07f0e6ebb0bb1d92b8890eea63288c0b627331d53514d0fba" -"checksum num-iter 0.1.34 (registry+https://github.com/rust-lang/crates.io-index)" = "7485fcc84f85b4ecd0ea527b14189281cf27d60e583ae65ebc9c088b13dffe01" -"checksum num-traits 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)" = "cacfcab5eb48250ee7d0c7896b51a2c5eec99c1feea5f32025635f5ae4b00070" -"checksum phf_generator 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)" = "6b07ffcc532ccc85e3afc45865469bf5d9e4ef5bfcf9622e3cfe80c2d275ec03" -"checksum phf_shared 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)" = "07e24b0ca9643bdecd0632f2b3da6b1b89bbb0030e0b992afc1113b23a7bc2f2" -"checksum pmutil 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5483812bd1a336ae14013e7e7afc700a29a11695f8a4768431bab3ed7f9d54d6" -"checksum precomputed-hash 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c" -"checksum proc-macro2 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5f9786e83afb5654ab1b336584548011f252db3c320c0ddba5dc21a1a76f83ca" -"checksum quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e920b65c65f10b2ae65c831a81a073a89edd28c7cce89475bff467ab4167a" -"checksum quote 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1eca14c727ad12702eb4b6bfb5a232287dcf8385cb8ca83a3eeaf6519c44c408" -"checksum rand 0.3.20 (registry+https://github.com/rust-lang/crates.io-index)" = "512870020642bb8c221bf68baa1b2573da814f6ccfe5c9699b1c303047abe9b1" -"checksum redox_syscall 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)" = "0d92eecebad22b767915e4d529f89f28ee96dbbf5a4810d2b844373f136417fd" -"checksum redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7e891cfe48e9100a70a3b6eb652fef28920c117d366339687bd5576160db0f76" -"checksum regex 0.1.80 (registry+https://github.com/rust-lang/crates.io-index)" = "4fd4ace6a8cf7860714a2c2280d6c1f7e6a413486c13298bbc86fd3da019402f" -"checksum regex-syntax 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "f9ec002c35e86791825ed294b50008eea9ddfc8def4420124fbc6b08db834957" -"checksum rustc-demangle 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "aee45432acc62f7b9a108cc054142dac51f979e69e71ddce7d6fc7adf29e817e" -"checksum serde 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)" = "db99f3919e20faa51bb2996057f5031d8685019b5a06139b1ce761da671b8526" -"checksum siphasher 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "0df90a788073e8d0235a67e50441d47db7c8ad9debd91cbf43736a2a92d36537" -"checksum slog 2.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0a6b13b17f4225771f7f15cece704a4e68d3a5f31278ed26367f497133398a18" -"checksum slog-async 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5e319a30c08b004618d5f7ca2f2b1dad7b4623ba7fcb1a12846fc3b01e9eaa10" -"checksum slog-envlogger 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f7c6685180086bf58624e92cb3da5d5f013bebd609454926fc8e2ac6345d384b" -"checksum slog-scope 4.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "053344c94c0e2b22da6305efddb698d7c485809427cf40555dc936085f67a9df" -"checksum slog-stdlog 3.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "ac42f8254ae996cc7d640f9410d3b048dcdf8887a10df4d5d4c44966de24c4a8" -"checksum slog-term 2.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5bb5d9360b2b279b326824b3b4ca2402ead8a8138f0e5ec1900605c861bb6671" -"checksum string_cache 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "413fc7852aeeb5472f1986ef755f561ddf0c789d3d796e65f0b6fe293ecd4ef8" -"checksum string_cache_codegen 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "479cde50c3539481f33906a387f2bd17c8e87cb848c35b6021d41fb81ff9b4d7" -"checksum string_cache_shared 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b1884d1bc09741d466d9b14e6d37ac89d6909cbcac41dd9ae982d4d063bbedfc" -"checksum syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)" = "d3b891b9015c88c576343b9b3e41c2c11a51c219ef067b264bd9c8aa9b441dad" -"checksum syn 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a0dceeafa95292b8a313f611317ae2fcba87dcd9a83e17c0adb4497efe81e7c3" -"checksum synom 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a393066ed9010ebaed60b9eafa373d4b1baac186dd7e008555b0f702b51945b6" -"checksum synstructure 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3a761d12e6d8dcb4dcf952a7a89b475e3a9d69e4a69307e01a470977642914bd" -"checksum take_mut 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "50b910a1174df4aeb5738e8a0e7253883cf7801de40d094175a5a557e487f4c5" -"checksum term 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "fa63644f74ce96fbeb9b794f66aff2a52d601cbd5e80f4b97123e3899f4570f1" -"checksum termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "689a3bdfaab439fd92bc87df5c4c78417d3cbe537487274e9b0b2dce76e92096" -"checksum thread-id 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a9539db560102d1cef46b8b78ce737ff0bb64e7e18d35b2a5688f7d097d0ff03" -"checksum thread_local 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "8576dbbfcaef9641452d5cf0df9b0e7eeab7694956dd33bb61515fb8f18cfdd5" -"checksum thread_local 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "279ef31c19ededf577bfd12dfae728040a21f635b06a24cd670ff510edd38963" -"checksum time 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)" = "a15375f1df02096fb3317256ce2cee6a1f42fc84ea5ad5fc8c421cfe40c73098" -"checksum unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f860d7d29cf02cb2f3f359fd35991af3d30bac52c57d265a3c461074cb4dc" -"checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc" -"checksum unreachable 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1f2ae5ddb18e1c92664717616dd9549dde73f539f01bd7b77c2edb2446bdff91" -"checksum unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "382810877fe448991dfc7f0dd6e3ae5d58088fd0ea5e35189655f84e6814fa56" -"checksum utf8-ranges 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a1ca13c08c41c9c3e04224ed9ff80461d97e121589ff27c753a16cb10830ae0f" -"checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" -"checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" -"checksum winapi 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "b09fb3b6f248ea4cd42c9a65113a847d612e17505d6ebd1f7357ad68a8bf8693" -"checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc" -"checksum winapi-i686-pc-windows-gnu 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "ec6667f60c23eca65c561e63a13d81b44234c2e38a6b6c959025ee907ec614cc" -"checksum winapi-x86_64-pc-windows-gnu 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "98f12c52b2630cd05d2c3ffd8e008f7f48252c042b4871c72aed9dc733b96668" diff --git a/atoms/build.rs b/atoms/build.rs index 787df518c309..5b43c1a820c2 100644 --- a/atoms/build.rs +++ b/atoms/build.rs @@ -66,6 +66,18 @@ fn main() { "private", "protected", "public", + // Used by transforms. + "Array", + "Object", + "Infinity", + "NaN", + "function", + "string", + "number", + "boolean", + "object", + "undefined", + "length", ], ); } diff --git a/common/src/fold.rs b/common/src/fold.rs index 56121849afec..2cbe55873bb3 100644 --- a/common/src/fold.rs +++ b/common/src/fold.rs @@ -28,7 +28,7 @@ impl FoldWith for ! { impl FoldWith for Box where - T: FoldWith, + F: Folder, { fn fold_children(self, f: &mut F) -> Self { box f.fold(*self) @@ -37,7 +37,7 @@ where impl FoldWith for Vec where - T: FoldWith, + F: Folder, { fn fold_children(self, f: &mut F) -> Self { self.into_iter().map(|it| f.fold(it)).collect() @@ -46,10 +46,10 @@ where impl FoldWith for Option where - T: FoldWith, + F: Folder, { fn fold_children(self, f: &mut F) -> Self { - self.map(|t| t.fold_children(f)) + self.map(|t| f.fold(t)) } } diff --git a/common/src/lib.rs b/common/src/lib.rs index 67c6658c9097..632ca1f94eba 100644 --- a/common/src/lib.rs +++ b/common/src/lib.rs @@ -16,7 +16,6 @@ pub use self::span::{BytePos, Span, Spanned}; pub mod compat; pub mod fold; -pub mod parser; mod ast_node; mod gen_iter; mod span; diff --git a/common/src/parser/mod.rs b/common/src/parser/mod.rs deleted file mode 100644 index e256f94e3c8f..000000000000 --- a/common/src/parser/mod.rs +++ /dev/null @@ -1,8 +0,0 @@ -use BytePos; - -pub trait SpannedToken { - type Token; - - fn into_triple(self) -> (BytePos, Self::Token, BytePos); - fn from_triple(start: BytePos, t: Self::Token, end: BytePos) -> Self; -} diff --git a/ecmascript/Cargo.toml b/ecmascript/Cargo.toml index a3022e29d417..125a9792a802 100644 --- a/ecmascript/Cargo.toml +++ b/ecmascript/Cargo.toml @@ -6,6 +6,7 @@ authors = ["강동윤 "] [dependencies] swc_ecma_ast = { path = "./ast" } swc_ecma_parser = { path = "./parser" } +swc_ecma_transforms = { path = "./transforms" } [dev-dependencies] diff --git a/ecmascript/parser/tests/test262.rs b/ecmascript/parser/tests/test262.rs index d2afe1c4f7be..086a5a9466b0 100644 --- a/ecmascript/parser/tests/test262.rs +++ b/ecmascript/parser/tests/test262.rs @@ -6,7 +6,7 @@ #[macro_use] extern crate slog; extern crate swc_common; -extern crate swc_ecmascript; +extern crate swc_ecma_parser; extern crate test; extern crate testing; use slog::Logger; @@ -18,9 +18,9 @@ use std::panic::{catch_unwind, resume_unwind}; use std::path::Path; use swc_common::Span; use swc_common::fold::{FoldWith, Folder}; -use swc_ecmascript::ast::*; -use swc_ecmascript::lexer::Lexer; -use swc_ecmascript::parser::{PResult, Parser}; +use swc_ecma_parser::ast::*; +use swc_ecma_parser::lexer::Lexer; +use swc_ecma_parser::parser::{PResult, Parser}; use test::{test_main, Options, TestDesc, TestDescAndFn, TestFn, TestName}; use test::ShouldPanic::No; diff --git a/ecmascript/src/lib.rs b/ecmascript/src/lib.rs index b66f90d6c1e9..0c8ba9d58cbe 100644 --- a/ecmascript/src/lib.rs +++ b/ecmascript/src/lib.rs @@ -1,2 +1,3 @@ pub extern crate swc_ecma_ast as ast; pub extern crate swc_ecma_parser as parser; +pub extern crate swc_ecma_transforms as transforms; diff --git a/ecmascript/transforms/Cargo.toml b/ecmascript/transforms/Cargo.toml new file mode 100644 index 000000000000..8574932f30f2 --- /dev/null +++ b/ecmascript/transforms/Cargo.toml @@ -0,0 +1,13 @@ +[package] +name = "swc_ecma_transforms" +version = "0.1.0" +authors = ["강동윤 "] + +[dependencies] +swc_atoms = { path = "../../atoms" } +swc_common = { path = "../../common" } +swc_ecma_ast = { path = "../ast" } + +[dev-dependencies] +swc_ecma_parser = { path = "../parser" } +testing = { path = "../../testing" } \ No newline at end of file diff --git a/ecmascript/transforms/src/lib.rs b/ecmascript/transforms/src/lib.rs new file mode 100644 index 000000000000..52cc8ce3700c --- /dev/null +++ b/ecmascript/transforms/src/lib.rs @@ -0,0 +1,11 @@ +#![feature(box_patterns)] +#![feature(box_syntax)] +#![feature(specialization)] + +#[macro_use] +pub extern crate swc_atoms; +pub extern crate swc_common; +pub extern crate swc_ecma_ast as ast; + +pub mod simplify; +pub mod util; diff --git a/ecmascript/transforms/src/simplify/expr.rs b/ecmascript/transforms/src/simplify/expr.rs new file mode 100644 index 000000000000..a5beac6b93ce --- /dev/null +++ b/ecmascript/transforms/src/simplify/expr.rs @@ -0,0 +1,176 @@ +use super::Simplify; +use ast::*; +use ast::{Ident, Lit}; +use ast::ExprKind::*; +use swc_common::fold::{FoldWith, Folder}; +use util::*; + +impl Folder for Simplify { + fn fold(&mut self, expr: ExprKind) -> ExprKind { + let expr = expr.fold_children(self); + + match expr { + // Do nothing for literals. + Lit(_) => expr, + + Unary { prefix, op, arg } => fold_unary(prefix, op, arg), + Binary { left, op, right } => fold_bin(left, op, right), + + Cond { test, cons, alt } => match test.as_bool() { + (p, Known(val)) => { + let expr_value = if val { cons } else { alt }; + if p.is_pure() { + expr_value.node + } else { + Seq { + exprs: vec![test, expr_value], + } + } + } + _ => Cond { test, cons, alt }, + }, + + // Simplify sequence expression. + Seq { exprs } => if exprs.len() == 1 { + exprs.into_iter().next().unwrap().node + } else { + assert!(!exprs.is_empty(), "sequence expression should not be empty"); + //TODO: remove unused + return Seq { exprs }; + }, + + // be conservative. + _ => expr, + } + } +} + +fn fold_bin(left: Box, op: BinaryOp, right: Box) -> ExprKind { + let (left, right) = match op { + BinaryOp::Add => return fold_add(left, right), + BinaryOp::LogicalAnd | BinaryOp::LogicalOr => match left.as_bool() { + (Pure, Known(val)) => { + if op == BinaryOp::LogicalAnd { + if val { + // 1 && $right + return right.node; + } else { + // 0 && $right + return Lit(Lit::Bool(false)); + } + } else { + if val { + // 1 || $right + return left.node; + } else { + // 0 || $right + return right.node; + } + } + } + _ => (left, right), + }, + BinaryOp::InstanceOf => (left, right), + + BinaryOp::Sub | BinaryOp::Div | BinaryOp::Mod => { + // Arithmetic operations + + (left, right) + } + _ => (left, right), + }; + + Binary { left, op, right } +} + +///See https://tc39.github.io/ecma262/#sec-addition-operator-plus +fn fold_add(left: Box, right: Box) -> ExprKind { + // It's string concatenation if either left or right is string. + + Binary { + left, + op: BinaryOp::Add, + right, + } +} + +fn fold_unary(prefix: bool, op: UnaryOp, arg: Box) -> ExprKind { + let span = arg.span; + + match op { + UnaryOp::TypeOf => { + let val = match arg.node { + Function(..) => "function", + Lit(Lit::Str(..)) => "string", + Lit(Lit::Num(..)) => "number", + Lit(Lit::Bool(..)) => "boolean", + Lit(Lit::Null) | Object { .. } | Array { .. } => "object", + Unary { + prefix: true, + op: UnaryOp::Void, + .. + } + | Ident(Ident { + sym: js_word!("undefined"), + .. + }) => { + // We can assume `undefined` is `undefined`, + // because overriding `undefined` is always hard error in swc. + "undefined" + } + + _ => { + return Unary { + prefix: true, + op: UnaryOp::TypeOf, + arg, + } + } + }; + + return Lit(Lit::Str(val.into())); + } + UnaryOp::Bang => match arg.as_bool() { + (p, Known(val)) => { + let new = Lit(Lit::Bool(!val)); + return if p.is_pure() { + new + } else { + Seq { + exprs: vec![arg, box Expr { span, node: new }], + } + }; + } + _ => { + return Unary { + op, + arg, + prefix: true, + } + } + }, + UnaryOp::Plus => {} + UnaryOp::Minus => match arg.node { + Ident(Ident { + sym: js_word!("Infinity"), + .. + }) => return Unary { prefix, op, arg }, + // "-NaN" is "NaN" + Ident(Ident { + sym: js_word!("NaN"), + .. + }) => return arg.node, + Lit(Lit::Num(Number(f))) => return Lit(Lit::Num(Number(-f))), + _ => { + + // TODO: Report that user is something bad (negating non-number value) + } + }, + _ => {} + } + + Unary { prefix, op, arg } +} + +/// Try to fold arithmetic binary operators +fn perform_arithmetic_op(op: BinaryOp, left: Box, right: Box) -> ExprKind {} diff --git a/ecmascript/transforms/src/simplify/mod.rs b/ecmascript/transforms/src/simplify/mod.rs new file mode 100644 index 000000000000..574eeddc3396 --- /dev/null +++ b/ecmascript/transforms/src/simplify/mod.rs @@ -0,0 +1,133 @@ +//! Ported from closure compiler. +use ast::*; +use swc_common::fold::{FoldWith, Folder}; +use util::*; + +mod expr; + +#[derive(Debug, Clone, Copy)] +pub struct Simplify; + +impl Folder> for Simplify +where + Self: Folder, +{ + fn fold(&mut self, stmts: Vec) -> Vec { + let mut buf = Vec::with_capacity(stmts.len()); + + for stmt_like in stmts { + let stmt_like = self.fold(stmt_like); + let stmt_like = match stmt_like.try_into_stmt() { + Ok(stmt) => { + let span = stmt.span; + let stmt = match stmt.node { + // Remove empty statements. + StmtKind::Empty => continue, + + StmtKind::Throw { .. } + | StmtKind::Return { .. } + | StmtKind::Continue { .. } + | StmtKind::Break { .. } => { + let stmt_like = T::from_stmt(stmt); + buf.push(stmt_like); + return buf; + } + // Optimize if statement. + StmtKind::If { + test, + consequent, + alt, + } => { + // check if + let node = match test.as_bool() { + (Pure, Known(val)) => { + if val { + consequent.node + } else { + alt.map(|alt| alt.node).unwrap_or_else(|| StmtKind::Empty) + } + } + // TODO: Impure + _ => StmtKind::If { + test, + consequent, + alt, + }, + }; + Stmt { span, node } + } + _ => stmt, + }; + + T::from_stmt(stmt) + } + Err(stmt_like) => stmt_like, + }; + + buf.push(stmt_like); + } + + buf + } +} + +impl Folder for Simplify { + fn fold(&mut self, stmt: StmtKind) -> StmtKind { + let stmt = stmt.fold_children(self); + + match stmt { + // `1;` -> `;` + StmtKind::Expr(box Expr { span, node }) => match node { + ExprKind::Lit(Lit::Num(..)) + | ExprKind::Lit(Lit::Bool(..)) + | ExprKind::Lit(Lit::Regex(..)) => StmtKind::Empty, + _ => StmtKind::Expr(box Expr { node, span }), + }, + + StmtKind::Block(BlockStmt { span, stmts }) => { + if stmts.len() == 0 { + return StmtKind::Empty; + } else if stmts.len() == 1 { + // TODO: Check lexical variable + return stmts.into_iter().next().unwrap().node; + } else { + StmtKind::Block(BlockStmt { span, stmts }) + } + } + + _ => stmt, + } + } +} + +pub trait StmtLike: Sized { + fn try_into_stmt(self) -> Result; + fn from_stmt(stmt: Stmt) -> Self; +} + +impl StmtLike for Stmt { + fn try_into_stmt(self) -> Result { + Ok(self) + } + fn from_stmt(stmt: Stmt) -> Self { + stmt + } +} + +impl StmtLike for ModuleItem { + fn try_into_stmt(self) -> Result { + match self { + ModuleItem::Stmt(stmt) => Ok(stmt), + _ => Err(self), + } + } + fn from_stmt(stmt: Stmt) -> Self { + ModuleItem::Stmt(stmt) + } +} + +// impl Folder for Simplify { +// fn fold(&mut self, stmt: Stmt) -> Stmt { +// stmt.fold_children(&mut FoldConst) +// } +// } diff --git a/ecmascript/transforms/src/util/mod.rs b/ecmascript/transforms/src/util/mod.rs new file mode 100644 index 000000000000..5aa653308314 --- /dev/null +++ b/ecmascript/transforms/src/util/mod.rs @@ -0,0 +1,336 @@ +pub use self::Purity::{MayBeImpure, Pure}; +pub use self::Value::{Known, Unknown}; +use ast::*; +use std::borrow::Cow; +use std::f64::{INFINITY, NAN}; +use std::num::FpCategory; +use std::ops::{Add, Not}; + +pub trait ExprExt: Sized + AsRef { + /// + /// This method emulates the `Boolean()` JavaScript cast function. + ///Note: unlike getPureBooleanValue this function does not return `None` + ///for expressions with side-effects. + fn as_bool(&self) -> (Purity, Bool) { + let expr = self.as_ref(); + let val = match expr.node { + ExprKind::Paren(ref e) => return e.as_bool(), + ExprKind::Seq { ref exprs } => return exprs.last().unwrap().as_bool(), + ExprKind::Assign { ref right, .. } => return right.as_bool(), + + ExprKind::Unary { + prefix: true, + op: UnaryOp::Bang, + ref arg, + } => { + let (p, v) = arg.as_bool(); + return (p, !v); + } + + ExprKind::Binary { + ref left, + op: op @ BinaryOp::LogicalAnd, + ref right, + } + | ExprKind::Binary { + ref left, + op: op @ BinaryOp::LogicalOr, + ref right, + } => { + // TODO: Ignore purity if value cannot be reached. + + let (lp, lv) = left.as_bool(); + let (rp, rv) = right.as_bool(); + + if lp + rp == Pure { + return (Pure, lv.and(rv)); + } + if op == BinaryOp::LogicalAnd { + lv.and(rv) + } else { + lv.or(rv) + } + } + + ExprKind::Function(..) + | ExprKind::Class(..) + | ExprKind::New { .. } + | ExprKind::Array { .. } + | ExprKind::Object { .. } => Known(true), + + ExprKind::Unary { + prefix: true, + op: UnaryOp::Void, + arg: _, + } => Known(false), + + ExprKind::Lit(ref lit) => { + return ( + Pure, + Known(match *lit { + Lit::Num(Number(n)) => match n.classify() { + FpCategory::Nan | FpCategory::Zero => false, + _ => true, + }, + Lit::Bool(b) => b, + Lit::Str(ref s) => !s.is_empty(), + Lit::Null => false, + Lit::Regex(..) => true, + }), + ) + } + + //TODO? + _ => Unknown, + }; + + (MayBeImpure, val) + } + + /// Emulates javascript Number() cast function. + fn as_number(&self) -> Value { + let expr = self.as_ref(); + let v = match expr.node { + ExprKind::Lit(ref l) => match *l { + Lit::Bool(true) => 1.0, + Lit::Bool(false) | Lit::Null => 0.0, + Lit::Num(Number(n)) => n, + Lit::Str(ref s) => return num_from_str(s), + _ => return Unknown, + }, + ExprKind::Ident(Ident { ref sym, .. }) => match &**sym { + "undefined" | "NaN" => NAN, + "Infinity" => INFINITY, + _ => return Unknown, + }, + ExprKind::Unary { + prefix: true, + op: UnaryOp::Minus, + arg: + box Expr { + span: _, + node: + ExprKind::Ident(Ident { + sym: js_word!("Infinity"), + .. + }), + }, + } => -INFINITY, + ExprKind::Unary { + prefix: true, + op: UnaryOp::Bang, + ref arg, + } => match arg.as_bool() { + (Pure, Known(v)) => { + if v { + 0.0 + } else { + 1.0 + } + } + _ => return Unknown, + }, + ExprKind::Unary { + prefix: true, + op: UnaryOp::Void, + ref arg, + } => { + if arg.may_have_side_effects() { + return Unknown; + } else { + NAN + } + } + + ExprKind::Tpl(..) | ExprKind::Object { .. } | ExprKind::Array { .. } => { + match self.as_string() { + Some(ref s) => return num_from_str(s), + None => return Unknown, + } + } + + _ => return Unknown, + }; + + Known(v) + } + + fn as_string(&self) -> Option> { + let expr = self.as_ref(); + match expr.node { + ExprKind::Lit(ref l) => match *l { + Lit::Str(ref s) => Some(Cow::Borrowed(s)), + Lit::Num(n) => Some(format!("{}", n).into()), + Lit::Bool(true) => Some(Cow::Borrowed("true")), + Lit::Bool(false) => Some(Cow::Borrowed("false")), + Lit::Null => Some(Cow::Borrowed("null")), + _ => None, + }, + ExprKind::Tpl(_) => { + // TODO: + // Only convert a template literal if all its expressions can be converted. + unimplemented!("TplLit.as_string()") + } + ExprKind::Ident(Ident { ref sym, .. }) => match &**sym { + "undefined" | "Infinity" | "NaN" => Some(Cow::Borrowed(&**sym)), + _ => None, + }, + ExprKind::Unary { + prefix: true, + op: UnaryOp::Void, + .. + } => Some(Cow::Borrowed("undefined")), + ExprKind::Unary { + prefix: true, + op: UnaryOp::Bang, + ref arg, + } => match arg.as_bool() { + (Pure, Known(v)) => Some(Cow::Borrowed(if v { "false" } else { "true" })), + _ => None, + }, + ExprKind::Array { ref elems } => { + let mut first = true; + let mut buf = String::new(); + // null, undefined is "" in array literl. + for elem in elems { + let e = match *elem { + Some(ref elem) => match *elem { + ExprOrSpread::Expr(ref e) | ExprOrSpread::Spread(ref e) => match e.node + { + ExprKind::Lit(Lit::Null) + | ExprKind::Ident(Ident { + sym: js_word!("undefined"), + .. + }) => Cow::Borrowed(""), + _ => match e.as_string() { + Some(s) => s, + None => return None, + }, + }, + }, + None => Cow::Borrowed(""), + }; + buf.push_str(&e); + + if first { + first = false; + } else { + buf.push(','); + } + } + Some(buf.into()) + } + ExprKind::Object { .. } => Some(Cow::Borrowed("[object Object]")), + _ => None, + } + } +} + +fn num_from_str(s: &str) -> Value { + if s.contains('\u{000b}') { + return Unknown; + } + + // TODO: Check if this is correct + let s = s.trim(); + + if s.is_empty() { + return Known(0.0); + } + + if s.starts_with("0x") || s.starts_with("0X") { + return match s[2..4].parse() { + Ok(n) => Known(n), + Err(_) => Known(NAN), + }; + } + + if (s.starts_with('-') || s.starts_with('+')) + && (s[1..].starts_with("0x") || s[1..].starts_with("0X")) + { + // hex numbers with explicit signs vary between browsers. + return Unknown; + } + + // Firefox and IE treat the "Infinity" differently. Firefox is case + // insensitive, but IE treats "infinity" as NaN. So leave it alone. + match s { + "infinity" | "+infinity" | "-infinity" => return Unknown, + _ => {} + } + + Known(s.parse().ok().unwrap_or(NAN)) +} + +impl> ExprExt for T {} + +#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] +pub enum Purity { + MayBeImpure, + Pure, +} +impl Purity { + pub fn is_pure(self) -> bool { + self == Pure + } +} + +impl Add for Purity { + type Output = Self; + fn add(self, rhs: Self) -> Self { + match (self, rhs) { + (Pure, Pure) => Pure, + _ => MayBeImpure, + } + } +} + +/// Value. +#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] +pub enum Value { + Known(T), + Unknown, +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] +pub enum Type { + Str, + Obj, + Undetermined, +} + +pub type Bool = Value; + +impl Value { + pub fn and(self, other: Self) -> Self { + match self { + Known(true) => other, + Known(false) => Known(false), + Unknown => match other { + Known(false) => Known(false), + _ => Unknown, + }, + } + } + + pub fn or(self, other: Self) -> Self { + match self { + Known(true) => Known(true), + Known(false) => other, + Unknown => match other { + Known(true) => Known(true), + _ => Unknown, + }, + } + } +} + +impl Not for Value { + type Output = Self; + fn not(self) -> Self { + match self { + Value::Known(b) => Value::Known(!b), + Value::Unknown => Value::Unknown, + } + } +} diff --git a/ecmascript/transforms/tests/transforms.rs b/ecmascript/transforms/tests/transforms.rs new file mode 100644 index 000000000000..cc77966b8903 --- /dev/null +++ b/ecmascript/transforms/tests/transforms.rs @@ -0,0 +1,62 @@ +extern crate swc_common; +extern crate swc_ecma_ast as ast; +extern crate swc_ecma_parser; +extern crate swc_ecma_transforms as transforms; +#[macro_use] +extern crate testing; + +use swc_common::fold::Folder; +use swc_ecma_parser::lexer::Lexer; +use swc_ecma_parser::parser::Parser; +use testing::logger; +use transforms::simplify::Simplify; + +macro_rules! parse { + ($s:expr) => {{ + let l = logger(); + Parser::new_for_module(l.clone(), Lexer::new_from_str(l, $s)) + .parse_module() + .unwrap_or_else(|err| panic!("failed to parse module: {:?}", err)) + }}; +} + +fn fold(t: T, mut f: F) -> T +where + F: Folder, +{ + f.fold(t) +} + +#[test] +fn add_simple() { + assert_eq_ignore_span!(fold(parse!("use(3 + 6)"), Simplify), parse!("use(9)")) +} + +#[test] +fn cond_simple() { + assert_eq_ignore_span!( + fold(parse!("use(true ? 3 : 6)"), Simplify), + parse!("use(3)") + ); + assert_eq_ignore_span!( + fold(parse!("use(false ? 3 : 6)"), Simplify), + parse!("use(6)") + ); +} + +#[test] +fn cond_side_effect() { + assert_eq_ignore_span!( + fold(parse!("new UnknownClass() ? 3 : 6"), Simplify), + parse!("new UnknownClass(), 3") + ); + assert_eq_ignore_span!( + fold(parse!("(void fn()) ? 3 : 6"), Simplify), + parse!("(void fn()), 6") + ); +} + +#[test] +fn oror_non_bool() { + assert_eq_ignore_span!(fold(parse!("use(5 || 50)"), Simplify), parse!("use(5)")) +}