mirror of
https://github.com/swc-project/swc.git
synced 2024-11-09 12:57:40 +03:00
More works (#66)
ecma_transforms: - implement es2015::instanceof - implement es2015::typeof_symbol - implement inline_globals pass ecma_parser: - `PResult<T>` is now `Result<T, ()>` and `Err(())` means that an error is emitted. - add docs
This commit is contained in:
parent
6f8ded406b
commit
1d0c78de6c
@ -4,12 +4,16 @@
|
||||
name = "swc"
|
||||
version = "0.1.0"
|
||||
authors = ["강동윤 <kdy1@outlook.kr>"]
|
||||
license = "Apache-2.0/MIT"
|
||||
repository = "https://github.com/swc-project/swc.git"
|
||||
documentation = "https://swc-project.github.io/rustdoc/swc/"
|
||||
description = "Speedy web compiler"
|
||||
|
||||
[[bin]]
|
||||
name = "swc"
|
||||
|
||||
[dependencies]
|
||||
libswc = { path = "./libswc" }
|
||||
libswc = { version = "0.1", path = "./libswc" }
|
||||
rayon = "1.0.3"
|
||||
slog = "2"
|
||||
slog-envlogger = "2.1"
|
||||
|
16
README.md
16
README.md
@ -24,9 +24,12 @@ RUSTFLAGS='--cfg procmacro2_semver_exempt --cfg parallel_queries' cargo install
|
||||
New generation javascript to old-days javascript.
|
||||
|
||||
- es3
|
||||
- [x] member expression literals
|
||||
- [x] peroperty literals
|
||||
- [ ] reserved words
|
||||
- [x] member-expression-literals
|
||||
- [x] property-literals
|
||||
- [ ] reserved-words
|
||||
|
||||
- es5
|
||||
- [ ] property-mutators
|
||||
|
||||
- es2015
|
||||
- [ ] arrow-functions
|
||||
@ -38,7 +41,7 @@ New generation javascript to old-days javascript.
|
||||
- [ ] duplicate-keys
|
||||
- [ ] for-of
|
||||
- [ ] function-name
|
||||
- [ ] instanceof
|
||||
- [x] instanceof
|
||||
- [ ] literals
|
||||
- [ ] new-target
|
||||
- [ ] object-super
|
||||
@ -47,17 +50,16 @@ New generation javascript to old-days javascript.
|
||||
- [x] spread
|
||||
- [x] sticky regex (`y` flag)
|
||||
- [ ] template-literals
|
||||
- [ ] typeof-symbol
|
||||
- [x] typeof-symbol
|
||||
- [ ] unicode-regex
|
||||
|
||||
- es2016
|
||||
- [x] operator `**`
|
||||
- [x] exponentiation-operator
|
||||
|
||||
- es2017
|
||||
- [ ] async-to-generator
|
||||
|
||||
- es2018
|
||||
- [ ] parser
|
||||
- [ ] async-generator-functions
|
||||
- [ ] dotall-regex
|
||||
- [ ] object-rest-spread
|
||||
|
@ -3,6 +3,10 @@ name = "swc_atoms"
|
||||
build = "build.rs"
|
||||
version = "0.1.0"
|
||||
authors = ["강동윤 <kdy1@outlook.kr>"]
|
||||
license = "Apache-2.0/MIT"
|
||||
repository = "https://github.com/swc-project/swc.git"
|
||||
documentation = "https://swc-project.github.io/rustdoc/swc_atoms/"
|
||||
description = "Atoms for the swc project."
|
||||
|
||||
[dependencies]
|
||||
string_cache = "0.7"
|
||||
|
@ -1,4 +1,5 @@
|
||||
Infinity
|
||||
NODE_ENV
|
||||
NaN
|
||||
Object
|
||||
RegExp
|
||||
@ -24,6 +25,7 @@ delete
|
||||
do
|
||||
else
|
||||
enum
|
||||
env
|
||||
export
|
||||
extends
|
||||
false
|
||||
@ -46,6 +48,7 @@ null
|
||||
of
|
||||
package
|
||||
private
|
||||
process
|
||||
protected
|
||||
public
|
||||
return
|
||||
|
@ -1,10 +1,14 @@
|
||||
[package]
|
||||
name = "swc_common"
|
||||
version = "0.1.0"
|
||||
version = "0.1.1"
|
||||
authors = ["강동윤 <kdy1@outlook.kr>"]
|
||||
license = "Apache-2.0/MIT"
|
||||
repository = "https://github.com/swc-project/swc.git"
|
||||
documentation = "https://swc-project.github.io/rustdoc/swc_common/"
|
||||
description = "Common utilities for the swc project."
|
||||
|
||||
[dependencies]
|
||||
ast_node = { path = "../macros/ast_node" }
|
||||
ast_node = { version = "0.1", path = "../macros/ast_node" }
|
||||
string_cache = "0.7"
|
||||
either = "1.5"
|
||||
rustc-ap-rustc_errors = "297"
|
||||
|
@ -2,11 +2,15 @@
|
||||
name = "swc_ecmascript"
|
||||
version = "0.1.0"
|
||||
authors = ["강동윤 <kdy1@outlook.kr>"]
|
||||
license = "Apache-2.0/MIT"
|
||||
repository = "https://github.com/swc-project/swc.git"
|
||||
documentation = "https://swc-project.github.io/rustdoc/swc_ecmascript/"
|
||||
description = "Ecmascript"
|
||||
|
||||
[dependencies]
|
||||
swc_ecma_ast = { path = "./ast" }
|
||||
swc_ecma_codegen = { path = "./codegen" }
|
||||
swc_ecma_parser = { path = "./parser" }
|
||||
swc_ecma_transforms = { path = "./transforms" }
|
||||
swc_ecma_ast = { version = "0.1", path ="./ast" }
|
||||
swc_ecma_codegen = { version = "0.1", path ="./codegen" }
|
||||
swc_ecma_parser = { version = "0.2", path ="./parser" }
|
||||
swc_ecma_transforms = { version = "0.1", path ="./transforms" }
|
||||
|
||||
[dev-dependencies]
|
||||
|
@ -2,9 +2,13 @@
|
||||
name = "swc_ecma_ast"
|
||||
version = "0.1.0"
|
||||
authors = ["강동윤 <kdy1@outlook.kr>"]
|
||||
license = "Apache-2.0/MIT"
|
||||
repository = "https://github.com/swc-project/swc.git"
|
||||
documentation = "https://swc-project.github.io/rustdoc/swc_ecma_ast/"
|
||||
description = "Ecmascript ast."
|
||||
|
||||
[dependencies]
|
||||
swc_atoms = { path = "../../atoms" }
|
||||
swc_common = { path = "../../common" }
|
||||
enum_kind = { path = "../../macros/enum_kind" }
|
||||
string_enum = { path = "../../macros/string_enum" }
|
||||
swc_atoms = { version = "0.1", path ="../../atoms" }
|
||||
swc_common = { version = "0.1", path ="../../common" }
|
||||
enum_kind = { version = "0.1", path ="../../macros/enum_kind" }
|
||||
string_enum = { version = "0.1", path ="../../macros/string_enum" }
|
||||
|
@ -1,17 +1,21 @@
|
||||
[package]
|
||||
name = "swc_ecma_codegen"
|
||||
version = "0.1.0"
|
||||
version = "0.1.1"
|
||||
authors = ["강동윤 <kdy1@outlook.kr>"]
|
||||
license = "Apache-2.0/MIT"
|
||||
repository = "https://github.com/swc-project/swc.git"
|
||||
documentation = "https://swc-project.github.io/rustdoc/swc_ecma_codegen/"
|
||||
description = "Ecmascript code generator for the swc project."
|
||||
|
||||
[dependencies]
|
||||
bitflags = "1"
|
||||
swc_atoms = { path = "../../atoms" }
|
||||
swc_common = { path = "../../common" }
|
||||
swc_ecma_ast = { path = "../ast" }
|
||||
swc_ecma_codegen_macros = { path = "./macros" }
|
||||
swc_atoms = { version = "0.1", path ="../../atoms" }
|
||||
swc_common = { version = "0.1", path ="../../common" }
|
||||
swc_ecma_ast = { version = "0.1", path ="../ast" }
|
||||
swc_ecma_codegen_macros = { version = "0.1", path ="./macros" }
|
||||
sourcemap = "2.2"
|
||||
|
||||
[dev-dependencies]
|
||||
testing = { path = "../../testing" }
|
||||
testing = { version = "0.1", path ="../../testing" }
|
||||
slog = "2"
|
||||
swc_ecma_parser = { path = "../parser" }
|
||||
swc_ecma_parser = { version = "0.2", path ="../parser" }
|
@ -2,13 +2,17 @@
|
||||
name = "swc_ecma_codegen_macros"
|
||||
version = "0.1.0"
|
||||
authors = ["강동윤 <kdy1@outlook.kr>"]
|
||||
license = "Apache-2.0/MIT"
|
||||
repository = "https://github.com/swc-project/swc.git"
|
||||
documentation = "https://swc-project.github.io/rustdoc/swc_ecma_codegen_macros/"
|
||||
description = "Macros for swc_ecma_codegen."
|
||||
|
||||
|
||||
[lib]
|
||||
proc-macro = true
|
||||
|
||||
[dependencies]
|
||||
swc_macros_common = { path = "../../../macros/common" }
|
||||
swc_macros_common = { version = "0.1", path ="../../../macros/common" }
|
||||
pmutil = "0.2"
|
||||
proc-macro2 = "0.4"
|
||||
|
||||
|
@ -87,13 +87,7 @@ fn test_from_to(from: &str, to: &str) {
|
||||
(&*src).into(),
|
||||
));
|
||||
|
||||
match res {
|
||||
Ok(res) => Ok(res),
|
||||
Err(err) => {
|
||||
err.emit();
|
||||
Err(())
|
||||
}
|
||||
}
|
||||
res
|
||||
})
|
||||
}
|
||||
let res = with_parser(Path::new("test.js"), from, |p| p.parse_module()).unwrap();
|
||||
|
@ -175,19 +175,9 @@ fn error_tests(tests: &mut Vec<TestDescAndFn>) -> Result<(), io::Error> {
|
||||
|
||||
// Parse source
|
||||
if module {
|
||||
emitter
|
||||
.emit_module(&parser.parse_module().map_err(|e| {
|
||||
e.emit();
|
||||
()
|
||||
})?)
|
||||
.unwrap();
|
||||
emitter.emit_module(&parser.parse_module()?).unwrap();
|
||||
} else {
|
||||
emitter
|
||||
.emit_script(&parser.parse_script().map_err(|e| {
|
||||
e.emit();
|
||||
()
|
||||
})?)
|
||||
.unwrap();
|
||||
emitter.emit_script(&parser.parse_script()?).unwrap();
|
||||
}
|
||||
}
|
||||
let ref_file = format!("{}", ref_dir.join(&file_name).display());
|
||||
|
@ -1,18 +1,22 @@
|
||||
[package]
|
||||
name = "swc_ecma_parser"
|
||||
version = "0.1.0"
|
||||
version = "0.2.2"
|
||||
authors = ["강동윤 <kdy1@outlook.kr>"]
|
||||
license = "Apache-2.0/MIT"
|
||||
repository = "https://github.com/swc-project/swc.git"
|
||||
documentation = "https://swc-project.github.io/rustdoc/swc_ecma_parser/"
|
||||
description = "Feature-complete es2019 parser."
|
||||
|
||||
[dependencies]
|
||||
swc_atoms = { path = "../../atoms" }
|
||||
swc_common = { path = "../../common" }
|
||||
swc_ecma_ast = { path = "../ast" }
|
||||
swc_ecma_parser_macros = { path = "./macros" }
|
||||
enum_kind = { path = "../../macros/enum_kind" }
|
||||
swc_atoms = { version = "0.1", path ="../../atoms" }
|
||||
swc_common = { version = "0.1", path ="../../common" }
|
||||
swc_ecma_ast = { version = "0.1", path ="../ast" }
|
||||
swc_ecma_parser_macros = { version = "0.1", path ="./macros" }
|
||||
enum_kind = { version = "0.1", path ="../../macros/enum_kind" }
|
||||
unicode-xid = "0.1"
|
||||
slog = "2.1"
|
||||
either = { version = "1.4" }
|
||||
|
||||
|
||||
[dev-dependencies]
|
||||
testing = { path = "../../testing" }
|
||||
testing = { version = "0.1", path ="../../testing" }
|
@ -2,12 +2,16 @@
|
||||
name = "swc_ecma_parser_macros"
|
||||
version = "0.1.0"
|
||||
authors = ["강동윤 <kdy1@outlook.kr>"]
|
||||
license = "Apache-2.0/MIT"
|
||||
repository = "https://github.com/swc-project/swc.git"
|
||||
documentation = "https://swc-project.github.io/rustdoc/swc_ecma_parser_macros/"
|
||||
description = "Macros for swc_ecma_parser."
|
||||
|
||||
[lib]
|
||||
proc-macro = true
|
||||
|
||||
[dependencies]
|
||||
swc_macros_common = { path = "../../../macros/common" }
|
||||
swc_macros_common = { version = "0.1", path ="../../../macros/common" }
|
||||
proc-macro2 = "0.4.4"
|
||||
|
||||
[dependencies.syn]
|
||||
|
@ -1,12 +1,10 @@
|
||||
//! Ported from [babylon/util/identifier.js][]
|
||||
//!
|
||||
//!
|
||||
//! [babylon/util/identifier.js]:\
|
||||
//! https://github.com/babel/babel/blob/master/packages/babylon/src/util/identifier.js
|
||||
//!
|
||||
//!
|
||||
//! Note: Currently this use xid instead of id because unicode_xid crate
|
||||
//! exists.
|
||||
//!
|
||||
//!
|
||||
//! [babylon/util/identifier.js]:https://github.com/babel/babel/blob/master/packages/babylon/src/util/identifier.js
|
||||
use super::{input::Input, LexResult, Lexer};
|
||||
use error::{ErrorToDiag, SyntaxError};
|
||||
use swc_common::{BytePos, Span};
|
||||
|
@ -1,3 +1,68 @@
|
||||
//! es2019 parser
|
||||
//!
|
||||
//! # Features
|
||||
//!
|
||||
//! ## Heavily tested
|
||||
//!
|
||||
//! Passes almost all tests from [tc39/test262][].
|
||||
//!
|
||||
//! ## Error reporting
|
||||
//!
|
||||
//! ```sh
|
||||
//! error: 'implements', 'interface', 'let', 'package', 'private', 'protected', 'public', 'static', or 'yield' cannot be used as an identifier in strict mode
|
||||
//! --> invalid.js:3:10
|
||||
//! |
|
||||
//! 3 | function yield() {
|
||||
//! | ^^^^^
|
||||
//! ```
|
||||
//!
|
||||
//! # Example
|
||||
//!
|
||||
//! ```
|
||||
//! #[macro_use]
|
||||
//! extern crate slog;
|
||||
//! extern crate swc_common;
|
||||
//! extern crate swc_ecma_parser;
|
||||
//! use swc_common::{
|
||||
//! errors::{ColorConfig, Handler},
|
||||
//! sync::Lrc,
|
||||
//! FileName, FilePathMapping, SourceMap,
|
||||
//! };
|
||||
//! use swc_ecma_parser::{Parser, Session, SourceFileInput};
|
||||
//!
|
||||
//! fn main() {
|
||||
//! swc_common::GLOBALS.set(&swc_common::Globals::new(), || {
|
||||
//! let cm = Lrc::new(SourceMap::new(FilePathMapping::empty()));
|
||||
//! let handler =
|
||||
//! Handler::with_tty_emitter(ColorConfig::Auto, true, false, Some(cm.clone()));
|
||||
//! let logger = slog::Logger::root(slog::Discard, o!());
|
||||
//!
|
||||
//! let session = Session {
|
||||
//! handler: &handler,
|
||||
//! logger: &logger,
|
||||
//! cfg: Default::default(),
|
||||
//! };
|
||||
//!
|
||||
//! // Real usage
|
||||
//! // let fm = cm
|
||||
//! // .load_file(Path::new("test.js"))
|
||||
//! // .expect("failed to load test.js");
|
||||
//!
|
||||
//! let fm = cm.new_source_file(
|
||||
//! FileName::Custom("test.js".into()),
|
||||
//! "function foo() {}".into(),
|
||||
//! );
|
||||
//!
|
||||
//! let mut parser = Parser::new(session, SourceFileInput::from(&*fm));
|
||||
//!
|
||||
//! let _module = parser.parse_module().expect("failed to parser module");
|
||||
//! });
|
||||
//! }
|
||||
//! ```
|
||||
//!
|
||||
//!
|
||||
//! [tc39/test262]:https://github.com/tc39/test262
|
||||
|
||||
#![feature(box_syntax)]
|
||||
#![feature(box_patterns)]
|
||||
#![feature(const_fn)]
|
||||
|
@ -434,19 +434,15 @@ mod tests {
|
||||
|
||||
fn lhs(s: &'static str) -> Box<Expr> {
|
||||
test_parser(s, |p| {
|
||||
p.parse_lhs_expr().unwrap_or_else(|err| {
|
||||
err.emit();
|
||||
unreachable!("failed to parse a left-hand-side expression")
|
||||
})
|
||||
p.parse_lhs_expr()
|
||||
.unwrap_or_else(|()| unreachable!("failed to parse a left-hand-side expression"))
|
||||
})
|
||||
}
|
||||
|
||||
fn expr(s: &'static str) -> Box<Expr> {
|
||||
test_parser(s, |p| {
|
||||
p.parse_expr().unwrap_or_else(|err| {
|
||||
err.emit();
|
||||
unreachable!("failed to parse an expression")
|
||||
})
|
||||
p.parse_expr()
|
||||
.unwrap_or_else(|()| unreachable!("failed to parse an expression"))
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -206,11 +206,8 @@ mod tests {
|
||||
|
||||
fn bin(s: &'static str) -> Box<Expr> {
|
||||
test_parser(s, |p| {
|
||||
p.parse_bin_expr().unwrap_or_else(|err| {
|
||||
err.emit();
|
||||
|
||||
panic!("failed to parse '{}' as a binary expression", s)
|
||||
})
|
||||
p.parse_bin_expr()
|
||||
.unwrap_or_else(|()| panic!("failed to parse '{}' as a binary expression", s))
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -3,37 +3,29 @@ use swc_common::DUMMY_SP as span;
|
||||
|
||||
fn lhs(s: &'static str) -> Box<Expr> {
|
||||
test_parser(s, |p| {
|
||||
p.parse_lhs_expr().unwrap_or_else(|err| {
|
||||
err.emit();
|
||||
unreachable!("failed to parse lhs expression")
|
||||
})
|
||||
p.parse_lhs_expr()
|
||||
.unwrap_or_else(|()| unreachable!("failed to parse lhs expression"))
|
||||
})
|
||||
}
|
||||
|
||||
fn new_expr(s: &'static str) -> Box<Expr> {
|
||||
test_parser(s, |p| {
|
||||
p.parse_new_expr().unwrap_or_else(|err| {
|
||||
err.emit();
|
||||
unreachable!("failed to parse an expression")
|
||||
})
|
||||
p.parse_new_expr()
|
||||
.unwrap_or_else(|()| unreachable!("failed to parse an expression"))
|
||||
})
|
||||
}
|
||||
|
||||
fn member_expr(s: &'static str) -> Box<Expr> {
|
||||
test_parser(s, |p| {
|
||||
p.parse_member_expr().unwrap_or_else(|err| {
|
||||
err.emit();
|
||||
unreachable!("failed to parse an expression")
|
||||
})
|
||||
p.parse_member_expr()
|
||||
.unwrap_or_else(|()| unreachable!("failed to parse an expression"))
|
||||
})
|
||||
}
|
||||
|
||||
fn expr(s: &'static str) -> Box<Expr> {
|
||||
test_parser(s, |p| {
|
||||
p.parse_expr().unwrap_or_else(|err| {
|
||||
err.emit();
|
||||
unreachable!("failed to parse an expression")
|
||||
})
|
||||
p.parse_expr()
|
||||
.unwrap_or_else(|()| unreachable!("failed to parse an expression"))
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -147,11 +147,13 @@ macro_rules! cur {
|
||||
if is_err_token {
|
||||
match $p.input.bump() {
|
||||
$crate::token::Token::Error(e) => {
|
||||
let err: Result<!, _> = Err($crate::error::ErrorToDiag {
|
||||
::swc_common::errors::DiagnosticBuilder::from($crate::error::ErrorToDiag {
|
||||
handler: &$p.session.handler,
|
||||
span: e.span,
|
||||
error: e.error,
|
||||
});
|
||||
})
|
||||
.emit();
|
||||
let err: Result<!, _> = Err(());
|
||||
err?
|
||||
}
|
||||
_ => unreachable!(),
|
||||
@ -160,10 +162,14 @@ macro_rules! cur {
|
||||
|
||||
match $p.input.cur() {
|
||||
Some(c) => Ok(c),
|
||||
None => Err($crate::error::Eof {
|
||||
last,
|
||||
handler: &$p.session.handler,
|
||||
}),
|
||||
None => {
|
||||
::swc_common::errors::DiagnosticBuilder::from($crate::error::Eof {
|
||||
last,
|
||||
handler: &$p.session.handler,
|
||||
})
|
||||
.emit();
|
||||
Err(())
|
||||
}
|
||||
}
|
||||
}};
|
||||
}
|
||||
@ -181,11 +187,15 @@ Current token is {:?}",
|
||||
let last = Span::new(pos, pos, Default::default());
|
||||
match $p.input.peek() {
|
||||
Some(c) => Ok(c),
|
||||
None => Err($crate::error::Eof {
|
||||
//TODO: Use whole span
|
||||
last,
|
||||
handler: &$p.session.handler,
|
||||
}),
|
||||
None => {
|
||||
::swc_common::errors::DiagnosticBuilder::from($crate::error::Eof {
|
||||
//TODO: Use whole span
|
||||
last,
|
||||
handler: &$p.session.handler,
|
||||
})
|
||||
.emit();
|
||||
Err(())
|
||||
}
|
||||
}
|
||||
}};
|
||||
}
|
||||
@ -254,12 +264,13 @@ macro_rules! syntax_error {
|
||||
};
|
||||
|
||||
($p:expr, $span:expr, $err:expr) => {{
|
||||
let err = $crate::error::ErrorToDiag {
|
||||
::swc_common::errors::DiagnosticBuilder::from($crate::error::ErrorToDiag {
|
||||
handler: $p.session.handler,
|
||||
span: $span,
|
||||
error: $err,
|
||||
};
|
||||
let res: Result<!, _> = Err(err);
|
||||
})
|
||||
.emit();
|
||||
let res: Result<!, _> = Err(());
|
||||
res?
|
||||
}};
|
||||
}
|
||||
|
@ -7,7 +7,7 @@ use lexer::{Input, Lexer};
|
||||
use parser_macros::parser;
|
||||
use std::ops::{Deref, DerefMut};
|
||||
use swc_atoms::JsWord;
|
||||
use swc_common::{errors::DiagnosticBuilder, BytePos, Span};
|
||||
use swc_common::{BytePos, Span};
|
||||
use token::*;
|
||||
use Context;
|
||||
use Session;
|
||||
@ -23,7 +23,8 @@ mod pat;
|
||||
mod stmt;
|
||||
mod util;
|
||||
|
||||
pub type PResult<'a, T> = Result<T, DiagnosticBuilder<'a>>;
|
||||
/// When error ocurred, error is emiited and parser returnes Err(()).
|
||||
pub type PResult<'a, T> = Result<T, ()>;
|
||||
|
||||
/// EcmaScript parser.
|
||||
pub struct Parser<'a, I: Input> {
|
||||
@ -95,6 +96,6 @@ fn module_legacy() {
|
||||
let res = f.parse_module();
|
||||
assert!(f.ctx().module);
|
||||
assert!(f.ctx().strict);
|
||||
let _ = res.expect_err("!").cancel();
|
||||
let _ = res.expect_err("!");
|
||||
});
|
||||
}
|
||||
|
@ -268,10 +268,6 @@ impl<'a, I: Input> Parser<'a, I> {
|
||||
});
|
||||
|
||||
if !self.ctx().in_function {
|
||||
match stmt {
|
||||
Ok(_) => {}
|
||||
Err(e) => e.emit(),
|
||||
}
|
||||
syntax_error!(span!(start), SyntaxError::ReturnNotAllowed)
|
||||
} else {
|
||||
stmt
|
||||
@ -731,18 +727,14 @@ mod tests {
|
||||
|
||||
fn stmt(s: &'static str) -> Stmt {
|
||||
test_parser(s, |p| {
|
||||
p.parse_stmt(true).unwrap_or_else(|err| {
|
||||
err.emit();
|
||||
unreachable!("failed to parse a statement")
|
||||
})
|
||||
p.parse_stmt(true)
|
||||
.unwrap_or_else(|()| unreachable!("failed to parse a statement"))
|
||||
})
|
||||
}
|
||||
fn expr(s: &'static str) -> Box<Expr> {
|
||||
test_parser(s, |p| {
|
||||
p.parse_expr().unwrap_or_else(|err| {
|
||||
err.emit();
|
||||
unreachable!("failed to parse an expression")
|
||||
})
|
||||
p.parse_expr()
|
||||
.unwrap_or_else(|()| unreachable!("failed to parse an expression"))
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -1,3 +1,9 @@
|
||||
error: Unexpected eof
|
||||
--> $DIR/tests/test262-parser/fail/03d13b6c40f6aaea.js:1:13
|
||||
|
|
||||
1 | [{a=0},...0]
|
||||
| ^
|
||||
|
||||
error: Unexpected token
|
||||
--> $DIR/tests/test262-parser/fail/03d13b6c40f6aaea.js:1:3
|
||||
|
|
||||
|
@ -1,3 +1,9 @@
|
||||
error: Unexpected eof
|
||||
--> $DIR/tests/test262-parser/fail/0889113e04d3203f.js:1:6
|
||||
|
|
||||
1 | class
|
||||
| ^
|
||||
|
||||
error: Expected ident
|
||||
--> $DIR/tests/test262-parser/fail/0889113e04d3203f.js:1:1
|
||||
|
|
||||
|
@ -1,3 +1,9 @@
|
||||
error: Unexpected eof
|
||||
--> $DIR/tests/test262-parser/fail/0f175471e2f0c3d5.js:1:6
|
||||
|
|
||||
1 | class
|
||||
| ^
|
||||
|
||||
error: Expected ident
|
||||
--> $DIR/tests/test262-parser/fail/0f175471e2f0c3d5.js:1:1
|
||||
|
|
||||
|
@ -1,3 +1,9 @@
|
||||
error: Unexpected eof
|
||||
--> $DIR/tests/test262-parser/fail/245843abef9e72e7.js:1:2
|
||||
|
|
||||
1 | [
|
||||
| ^
|
||||
|
||||
error: Expected RBracket
|
||||
--> $DIR/tests/test262-parser/fail/245843abef9e72e7.js:1:1
|
||||
|
|
||||
|
@ -1,3 +1,9 @@
|
||||
error: Unexpected eof
|
||||
--> $DIR/tests/test262-parser/fail/3d3e6ce2b81a224d.js:1:46
|
||||
|
|
||||
1 | [[[[[[[[[[[[[[[[[[[[{a=b}]]]]]]]]]]]]]]]]]]]]
|
||||
| ^
|
||||
|
||||
error: Unexpected token
|
||||
--> $DIR/tests/test262-parser/fail/3d3e6ce2b81a224d.js:1:22
|
||||
|
|
||||
|
@ -1,3 +1,9 @@
|
||||
error: Unexpected eof
|
||||
--> $DIR/tests/test262-parser/fail/41895c8145489971.js:1:19
|
||||
|
|
||||
1 | `hello ${10 `test`
|
||||
| ^
|
||||
|
||||
error: Expected RBrace
|
||||
--> $DIR/tests/test262-parser/fail/41895c8145489971.js:1:18
|
||||
|
|
||||
|
@ -1,3 +1,9 @@
|
||||
error: Unexpected eof
|
||||
--> $DIR/tests/test262-parser/fail/4e885526e8dfaa12.js:1:11
|
||||
|
|
||||
1 | f({x = 0})
|
||||
| ^
|
||||
|
||||
error: Unexpected token
|
||||
--> $DIR/tests/test262-parser/fail/4e885526e8dfaa12.js:1:4
|
||||
|
|
||||
|
@ -1,3 +1,9 @@
|
||||
error: Unexpected eof
|
||||
--> $DIR/tests/test262-parser/fail/4ee7b10cd97f554c.js:1:3
|
||||
|
|
||||
1 | [,
|
||||
| ^
|
||||
|
||||
error: Expected RBracket
|
||||
--> $DIR/tests/test262-parser/fail/4ee7b10cd97f554c.js:1:2
|
||||
|
|
||||
|
@ -1,3 +1,9 @@
|
||||
error: Unexpected eof
|
||||
--> $DIR/tests/test262-parser/fail/7187f0675eb38279.js:1:7
|
||||
|
|
||||
1 | return
|
||||
| ^
|
||||
|
||||
error: Return statement is not allowed here
|
||||
--> $DIR/tests/test262-parser/fail/7187f0675eb38279.js:1:1
|
||||
|
|
||||
|
@ -1,3 +1,9 @@
|
||||
error: Unexpected eof
|
||||
--> $DIR/tests/test262-parser/fail/73d1b1b1bc1dabfb.js:1:6
|
||||
|
|
||||
1 | super
|
||||
| ^
|
||||
|
||||
error: Unexpected token
|
||||
--> $DIR/tests/test262-parser/fail/73d1b1b1bc1dabfb.js:1:1
|
||||
|
|
||||
|
@ -1,3 +1,9 @@
|
||||
error: Unexpected eof
|
||||
--> $DIR/tests/test262-parser/fail/888d17b2ef3b2afc.js:1:10
|
||||
|
|
||||
1 | 1 + { t:t
|
||||
| ^
|
||||
|
||||
error: Expected Comma
|
||||
--> $DIR/tests/test262-parser/fail/888d17b2ef3b2afc.js:1:9
|
||||
|
|
||||
|
@ -1,3 +1,9 @@
|
||||
error: Unexpected eof
|
||||
--> $DIR/tests/test262-parser/fail/8ba15f5246ca756c.js:1:10
|
||||
|
|
||||
1 | class A {
|
||||
| ^
|
||||
|
||||
error: Expected RBrace
|
||||
--> $DIR/tests/test262-parser/fail/8ba15f5246ca756c.js:1:9
|
||||
|
|
||||
|
@ -1,3 +1,9 @@
|
||||
error: Unexpected eof
|
||||
--> $DIR/tests/test262-parser/fail/8c353ce78b905b58.js:1:5
|
||||
|
|
||||
1 | `${a
|
||||
| ^
|
||||
|
||||
error: Expected RBrace
|
||||
--> $DIR/tests/test262-parser/fail/8c353ce78b905b58.js:1:4
|
||||
|
|
||||
|
@ -1,3 +1,9 @@
|
||||
error: Unexpected eof
|
||||
--> $DIR/tests/test262-parser/fail/a069c2ecbeb0f43a.js:1:37
|
||||
|
|
||||
1 | switch (cond) { case 10: let a = 20;
|
||||
| ^
|
||||
|
||||
error: Expected RBrace
|
||||
--> $DIR/tests/test262-parser/fail/a069c2ecbeb0f43a.js:1:36
|
||||
|
|
||||
|
@ -1,3 +1,9 @@
|
||||
error: Unexpected eof
|
||||
--> $DIR/tests/test262-parser/fail/a9431906f263368d.js:1:10
|
||||
|
|
||||
1 | ({a = 0})
|
||||
| ^
|
||||
|
||||
error: Unexpected token
|
||||
--> $DIR/tests/test262-parser/fail/a9431906f263368d.js:1:3
|
||||
|
|
||||
|
@ -1,3 +1,9 @@
|
||||
error: Unexpected eof
|
||||
--> $DIR/tests/test262-parser/fail/bcde05eea9466dfd.js:1:12
|
||||
|
|
||||
1 | [...{a=0},]
|
||||
| ^
|
||||
|
||||
error: Unexpected token
|
||||
--> $DIR/tests/test262-parser/fail/bcde05eea9466dfd.js:1:6
|
||||
|
|
||||
|
@ -1,3 +1,9 @@
|
||||
error: Unexpected eof
|
||||
--> $DIR/tests/test262-parser/fail/c0ad1c20e662c8ed.js:1:14
|
||||
|
|
||||
1 | obj = {x = 0}
|
||||
| ^
|
||||
|
||||
error: Unexpected token
|
||||
--> $DIR/tests/test262-parser/fail/c0ad1c20e662c8ed.js:1:8
|
||||
|
|
||||
|
@ -1,3 +1,9 @@
|
||||
error: Unexpected eof
|
||||
--> $DIR/tests/test262-parser/fail/d4e259842c4520e1.js:1:6
|
||||
|
|
||||
1 | 1 + (
|
||||
| ^
|
||||
|
||||
error: Expected RParen
|
||||
--> $DIR/tests/test262-parser/fail/d4e259842c4520e1.js:1:5
|
||||
|
|
||||
|
@ -1,3 +1,9 @@
|
||||
error: Unexpected eof
|
||||
--> $DIR/tests/test262-parser/fail/dc5864c9096ad0a8.js:1:17
|
||||
|
|
||||
1 | [a, ...b, {c=0}]
|
||||
| ^
|
||||
|
||||
error: Unexpected token
|
||||
--> $DIR/tests/test262-parser/fail/dc5864c9096ad0a8.js:1:12
|
||||
|
|
||||
|
@ -1,3 +1,9 @@
|
||||
error: Unexpected eof
|
||||
--> $DIR/tests/test262-parser/fail/e922f1c6f6e5fdef.module.js:1:24
|
||||
|
|
||||
1 | export default function
|
||||
| ^
|
||||
|
||||
error: Expected LParen
|
||||
--> $DIR/tests/test262-parser/fail/e922f1c6f6e5fdef.module.js:1:16
|
||||
|
|
||||
|
@ -1,3 +1,9 @@
|
||||
error: Unexpected eof
|
||||
--> $DIR/tests/test262-parser/fail/f51aea0352bb03f3.js:1:4
|
||||
|
|
||||
1 | --1
|
||||
| ^
|
||||
|
||||
error: Cannot assign to this
|
||||
--> $DIR/tests/test262-parser/fail/f51aea0352bb03f3.js:1:3
|
||||
|
|
||||
|
@ -1,3 +1,9 @@
|
||||
error: Unexpected eof
|
||||
--> $DIR/tests/test262-parser/fail/f6cc48c72caf2e32.js:1:4
|
||||
|
|
||||
1 | ++1
|
||||
| ^
|
||||
|
||||
error: Cannot assign to this
|
||||
--> $DIR/tests/test262-parser/fail/f6cc48c72caf2e32.js:1:3
|
||||
|
|
||||
|
@ -283,13 +283,7 @@ where
|
||||
(&*fm).into(),
|
||||
));
|
||||
|
||||
match res {
|
||||
Ok(res) => Ok(res),
|
||||
Err(err) => {
|
||||
err.emit();
|
||||
Err(())
|
||||
}
|
||||
}
|
||||
res
|
||||
});
|
||||
|
||||
output
|
||||
|
@ -2,16 +2,20 @@
|
||||
name = "swc_ecma_transforms"
|
||||
version = "0.1.0"
|
||||
authors = ["강동윤 <kdy1@outlook.kr>"]
|
||||
license = "Apache-2.0/MIT"
|
||||
repository = "https://github.com/swc-project/swc.git"
|
||||
documentation = "https://swc-project.github.io/rustdoc/swc_ecma_transforms/"
|
||||
description = "rust port of babel and closure compiler."
|
||||
|
||||
[dependencies]
|
||||
swc_atoms = { path = "../../atoms" }
|
||||
swc_common = { path = "../../common" }
|
||||
swc_ecma_ast = { path = "../ast" }
|
||||
swc_ecma_parser = { path = "../parser" }
|
||||
swc_atoms = { version = "0.1", path ="../../atoms" }
|
||||
swc_common = { version = "0.1", path ="../../common" }
|
||||
swc_ecma_ast = { version = "0.1", path ="../ast" }
|
||||
swc_ecma_parser = { version = "0.2", path ="../parser" }
|
||||
slog = "2"
|
||||
|
||||
[dev-dependencies]
|
||||
testing = { path = "../../testing" }
|
||||
swc_ecma_codegen = { path = "../codegen" }
|
||||
testing = { version = "0.1", path ="../../testing" }
|
||||
swc_ecma_codegen = { version = "0.1", path ="../codegen" }
|
||||
pretty_assertions = "0.5"
|
||||
sourcemap = "2.2"
|
59
ecmascript/transforms/src/compat/es2015/instanceof.rs
Normal file
59
ecmascript/transforms/src/compat/es2015/instanceof.rs
Normal file
@ -0,0 +1,59 @@
|
||||
use ast::*;
|
||||
use crate::{compat::helpers::Helpers, util::ExprFactory};
|
||||
use std::sync::{atomic::Ordering, Arc};
|
||||
use swc_common::{Fold, FoldWith};
|
||||
|
||||
/// `@babel/plugin-transform-instanceof`
|
||||
///
|
||||
///
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ## In
|
||||
///
|
||||
/// ```js
|
||||
/// foo instanceof Bar;
|
||||
/// ```
|
||||
///
|
||||
/// ## Out
|
||||
///
|
||||
/// ```js
|
||||
/// function _instanceof(left, right) {
|
||||
/// if (right != null && typeof Symbol !== "undefined" && right[Symbol.hasInstance]) {
|
||||
/// return right[Symbol.hasInstance](left);
|
||||
/// } else {
|
||||
/// return left instanceof right;
|
||||
/// }
|
||||
/// }
|
||||
///
|
||||
/// _instanceof(foo, Bar);
|
||||
/// ```
|
||||
pub struct InstanceOf {
|
||||
pub helpers: Arc<Helpers>,
|
||||
}
|
||||
|
||||
impl Fold<Expr> for InstanceOf {
|
||||
fn fold(&mut self, expr: Expr) -> Expr {
|
||||
let expr = expr.fold_children(self);
|
||||
|
||||
match expr {
|
||||
Expr::Bin(BinExpr {
|
||||
span,
|
||||
left,
|
||||
op: op!("instanceof"),
|
||||
right,
|
||||
}) => {
|
||||
self.helpers.instance_of.store(true, Ordering::SeqCst);
|
||||
|
||||
let span = mark!(span);
|
||||
|
||||
Expr::Call(CallExpr {
|
||||
span,
|
||||
callee: quote_ident!(span, "_instanceof").as_callee(),
|
||||
args: vec![left.as_arg(), right.as_arg()],
|
||||
})
|
||||
}
|
||||
_ => expr,
|
||||
}
|
||||
}
|
||||
}
|
@ -1,6 +1,7 @@
|
||||
pub use self::{
|
||||
arrow::Arrow, classes::Classes, shorthand_property::Shorthand, spread::Spread,
|
||||
sticky_regex::StickyRegex, template_literal::TemplateLiteral,
|
||||
arrow::Arrow, classes::Classes, instanceof::InstanceOf, shorthand_property::Shorthand,
|
||||
spread::Spread, sticky_regex::StickyRegex, template_literal::TemplateLiteral,
|
||||
typeof_symbol::TypeOfSymbol,
|
||||
};
|
||||
|
||||
use super::helpers::Helpers;
|
||||
@ -10,13 +11,15 @@ use swc_common::Fold;
|
||||
|
||||
mod arrow;
|
||||
mod classes;
|
||||
mod instanceof;
|
||||
mod shorthand_property;
|
||||
mod spread;
|
||||
mod sticky_regex;
|
||||
mod template_literal;
|
||||
mod typeof_symbol;
|
||||
|
||||
/// Compiles es2015 to es5.
|
||||
pub fn es2015(helpers: Arc<Helpers>) -> impl Fold<Module> {
|
||||
pub fn es2015(helpers: &Arc<Helpers>) -> impl Fold<Module> {
|
||||
Classes {
|
||||
helpers: helpers.clone(),
|
||||
}
|
||||
@ -25,4 +28,10 @@ pub fn es2015(helpers: Arc<Helpers>) -> impl Fold<Module> {
|
||||
})
|
||||
.then(StickyRegex)
|
||||
.then(Shorthand)
|
||||
.then(InstanceOf {
|
||||
helpers: helpers.clone(),
|
||||
})
|
||||
.then(TypeOfSymbol {
|
||||
helpers: helpers.clone(),
|
||||
})
|
||||
}
|
||||
|
@ -11,7 +11,7 @@ impl Fold<Expr> for TemplateLiteral {
|
||||
match e {
|
||||
Expr::Tpl(TplLit { .. }) => {
|
||||
// TODO
|
||||
unimplemented!()
|
||||
unimplemented!("template literal")
|
||||
}
|
||||
_ => e,
|
||||
}
|
||||
|
49
ecmascript/transforms/src/compat/es2015/typeof_symbol.rs
Normal file
49
ecmascript/transforms/src/compat/es2015/typeof_symbol.rs
Normal file
@ -0,0 +1,49 @@
|
||||
use ast::*;
|
||||
use crate::{compat::helpers::Helpers, util::ExprFactory};
|
||||
use std::sync::{atomic::Ordering, Arc};
|
||||
use swc_common::{Fold, FoldWith};
|
||||
|
||||
/// `@babel/plugin-transform-typeof-symbol`
|
||||
///
|
||||
/// # Example
|
||||
/// ## In
|
||||
///
|
||||
/// ```js
|
||||
/// typeof Symbol() === "symbol";
|
||||
/// ```
|
||||
///
|
||||
/// ## Out
|
||||
/// ```js
|
||||
/// var _typeof = function (obj) {
|
||||
/// return obj && obj.constructor === Symbol ? "symbol" : typeof obj;
|
||||
/// };
|
||||
///
|
||||
/// _typeof(Symbol()) === "symbol";
|
||||
/// ```
|
||||
pub struct TypeOfSymbol {
|
||||
pub helpers: Arc<Helpers>,
|
||||
}
|
||||
|
||||
impl Fold<Expr> for TypeOfSymbol {
|
||||
fn fold(&mut self, expr: Expr) -> Expr {
|
||||
let expr = expr.fold_children(self);
|
||||
|
||||
match expr {
|
||||
Expr::Unary(UnaryExpr {
|
||||
span,
|
||||
op: op!("typeof"),
|
||||
arg,
|
||||
}) => {
|
||||
let span = mark!(span);
|
||||
|
||||
self.helpers.type_of.store(true, Ordering::SeqCst);
|
||||
return Expr::Call(CallExpr {
|
||||
span,
|
||||
callee: quote_ident!(span, "_typeof").as_callee(),
|
||||
args: vec![arg.as_arg()],
|
||||
});
|
||||
}
|
||||
_ => expr,
|
||||
}
|
||||
}
|
||||
}
|
7
ecmascript/transforms/src/compat/helpers/_instanceof.js
Normal file
7
ecmascript/transforms/src/compat/helpers/_instanceof.js
Normal file
@ -0,0 +1,7 @@
|
||||
function _instanceof(left, right) {
|
||||
if (right != null && typeof Symbol !== "undefined" && right[Symbol.hasInstance]) {
|
||||
return right[Symbol.hasInstance](left);
|
||||
} else {
|
||||
return left instanceof right;
|
||||
}
|
||||
}
|
3
ecmascript/transforms/src/compat/helpers/_typeof.js
Normal file
3
ecmascript/transforms/src/compat/helpers/_typeof.js
Normal file
@ -0,0 +1,3 @@
|
||||
var _typeof = function (obj) {
|
||||
return obj && obj.constructor === Symbol ? "symbol" : typeof obj;
|
||||
};
|
@ -1,10 +1,7 @@
|
||||
use ast::*;
|
||||
use std::{
|
||||
ops::BitOr,
|
||||
sync::{
|
||||
atomic::{AtomicBool, Ordering},
|
||||
Arc,
|
||||
},
|
||||
use std::sync::{
|
||||
atomic::{AtomicBool, Ordering},
|
||||
Arc,
|
||||
};
|
||||
use swc_common::{
|
||||
errors::{ColorConfig, Handler},
|
||||
@ -29,23 +26,10 @@ pub struct Helpers {
|
||||
pub create_class: AtomicBool,
|
||||
/// `_get`
|
||||
pub get: AtomicBool,
|
||||
}
|
||||
|
||||
impl<'a> BitOr<&'a Helpers> for Helpers {
|
||||
type Output = Self;
|
||||
|
||||
fn bitor(mut self, other: &Helpers) -> Self {
|
||||
*self.extends.get_mut() |= other.extends.load(Ordering::SeqCst);
|
||||
*self.to_consumable_array.get_mut() |= other.to_consumable_array.load(Ordering::SeqCst);
|
||||
*self.class_call_check.get_mut() |= other.class_call_check.load(Ordering::SeqCst);
|
||||
*self.inherits.get_mut() |= other.inherits.load(Ordering::SeqCst);
|
||||
*self.possible_constructor_return.get_mut() |=
|
||||
other.possible_constructor_return.load(Ordering::SeqCst);
|
||||
*self.create_class.get_mut() |= other.create_class.load(Ordering::SeqCst);
|
||||
*self.get.get_mut() |= other.get.load(Ordering::SeqCst);
|
||||
|
||||
self
|
||||
}
|
||||
/// _instanceof
|
||||
pub instance_of: AtomicBool,
|
||||
/// _typeof
|
||||
pub type_of: AtomicBool,
|
||||
}
|
||||
|
||||
pub struct InjectHelpers {
|
||||
@ -76,46 +60,28 @@ impl InjectHelpers {
|
||||
|
||||
let mut stmts = Parser::new(session, SourceFileInput::from(&*fm))
|
||||
.parse_script()
|
||||
.map_err(|e| {
|
||||
e.emit();
|
||||
()
|
||||
})
|
||||
.unwrap();
|
||||
|
||||
buf.append(&mut stmts);
|
||||
};
|
||||
macro_rules! add {
|
||||
($name:tt,$b:expr) => {
|
||||
add($name, &self.helpers.extends, include_str!($name));
|
||||
};
|
||||
}
|
||||
|
||||
add(
|
||||
"_extends.js",
|
||||
&self.helpers.extends,
|
||||
include_str!("_extends.js"),
|
||||
);
|
||||
add(
|
||||
"_toConsumableArray.js",
|
||||
&self.helpers.to_consumable_array,
|
||||
include_str!("_toConsumableArray.js"),
|
||||
);
|
||||
add(
|
||||
"_classCallCheck.js",
|
||||
&self.helpers.class_call_check,
|
||||
include_str!("_classCallCheck.js"),
|
||||
);
|
||||
add(
|
||||
"_inherits.js",
|
||||
&self.helpers.inherits,
|
||||
include_str!("_inherits.js"),
|
||||
);
|
||||
add(
|
||||
add!("_extends.js", &self.helpers.extends);
|
||||
add!("_toConsumableArray.js", &self.helpers.to_consumable_array);
|
||||
add!("_classCallCheck.js", &self.helpers.class_call_check);
|
||||
add!("_inherits.js", &self.helpers.inherits);
|
||||
add!(
|
||||
"_possibleConstructorReturn.js",
|
||||
&self.helpers.possible_constructor_return,
|
||||
include_str!("_possibleConstructorReturn.js"),
|
||||
&self.helpers.possible_constructor_return
|
||||
);
|
||||
add(
|
||||
"_createClass.js",
|
||||
&self.helpers.create_class,
|
||||
include_str!("_createClass.js"),
|
||||
);
|
||||
add("_get.js", &self.helpers.get, include_str!("_get.js"));
|
||||
add!("_createClass.js", &self.helpers.create_class);
|
||||
add!("_get.js", &self.helpers.get);
|
||||
add!("_instanceof.js", &self.helpers.instance_of);
|
||||
add!("_typeof.js", &self.helpers.type_of);
|
||||
|
||||
buf
|
||||
}
|
||||
|
135
ecmascript/transforms/src/inline_globals.rs
Normal file
135
ecmascript/transforms/src/inline_globals.rs
Normal file
@ -0,0 +1,135 @@
|
||||
use ast::*;
|
||||
use std::collections::HashMap;
|
||||
use swc_atoms::JsWord;
|
||||
use swc_common::{Fold, FoldWith};
|
||||
|
||||
pub struct InlineGlobals {
|
||||
pub envs: HashMap<JsWord, Expr>,
|
||||
pub globals: HashMap<JsWord, Expr>,
|
||||
}
|
||||
|
||||
impl Fold<Expr> for InlineGlobals {
|
||||
fn fold(&mut self, expr: Expr) -> Expr {
|
||||
let expr = match expr {
|
||||
// Don't recurese into member expression.
|
||||
Expr::Member(..) => expr,
|
||||
_ => expr.fold_children(self),
|
||||
};
|
||||
|
||||
match expr {
|
||||
Expr::Ident(Ident { ref sym, span }) => {
|
||||
// It's ok because we don't recurse into member expressions.
|
||||
if let Some(value) = self.globals.get(sym) {
|
||||
return value.clone();
|
||||
} else {
|
||||
expr
|
||||
}
|
||||
}
|
||||
Expr::Member(MemberExpr {
|
||||
span,
|
||||
obj:
|
||||
ExprOrSuper::Expr(box Expr::Member(MemberExpr {
|
||||
obj:
|
||||
ExprOrSuper::Expr(box Expr::Ident(Ident {
|
||||
sym: js_word!("process"),
|
||||
..
|
||||
})),
|
||||
prop:
|
||||
box Expr::Ident(Ident {
|
||||
sym: js_word!("env"),
|
||||
..
|
||||
}),
|
||||
span: _,
|
||||
computed: _,
|
||||
})),
|
||||
prop,
|
||||
computed: _,
|
||||
}) => {
|
||||
let prop = match *prop {
|
||||
Expr::Ident(Ident { ref sym, .. }) => {
|
||||
if let Some(env) = self.envs.get(sym) {
|
||||
return env.clone();
|
||||
}
|
||||
return Expr::Lit(Lit::Str(Str {
|
||||
value: js_word!(""),
|
||||
span: mark!(span),
|
||||
has_escape: false,
|
||||
}));
|
||||
}
|
||||
_ => unimplemented!("node.env.NONE-IDENT"),
|
||||
};
|
||||
}
|
||||
_ => expr,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
fn mk_map(values: &[(&str, &str)], is_env: bool) -> HashMap<JsWord, Expr> {
|
||||
let mut m = HashMap::new();
|
||||
|
||||
crate::tests::Tester::run(|tester| {
|
||||
for (k, v) in values {
|
||||
let v = if is_env {
|
||||
format!("'{}'", v)
|
||||
} else {
|
||||
(*v).into()
|
||||
};
|
||||
|
||||
let mut v = tester.apply_transform(::testing::DropSpan, "global.js", &v)?;
|
||||
assert_eq!(v.body.len(), 1);
|
||||
let v = match v.body.pop().unwrap() {
|
||||
ModuleItem::Stmt(Stmt::Expr(box expr)) => expr,
|
||||
_ => unreachable!(),
|
||||
};
|
||||
|
||||
m.insert((*k).into(), v);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
});
|
||||
|
||||
m
|
||||
}
|
||||
|
||||
fn envs(values: &[(&str, &str)]) -> HashMap<JsWord, Expr> {
|
||||
mk_map(values, true)
|
||||
}
|
||||
|
||||
fn globals(values: &[(&str, &str)]) -> HashMap<JsWord, Expr> {
|
||||
mk_map(values, false)
|
||||
}
|
||||
|
||||
test!(
|
||||
InlineGlobals {
|
||||
envs: envs(&[("NODE_ENV", "development")]),
|
||||
globals: globals(&[]),
|
||||
},
|
||||
node_env,
|
||||
r#"if (process.env.NODE_ENV === 'development') {}"#,
|
||||
r#"if ('development' === 'development') {}"#
|
||||
);
|
||||
|
||||
test!(
|
||||
InlineGlobals {
|
||||
envs: envs(&[]),
|
||||
globals: globals(&[("__DEBUG__", "true")]),
|
||||
},
|
||||
inline_globals,
|
||||
r#"if (__DEBUG__) {}"#,
|
||||
r#"if (true) {}"#
|
||||
);
|
||||
|
||||
test!(
|
||||
InlineGlobals {
|
||||
envs: envs(&[]),
|
||||
globals: globals(&[("debug", "true")]),
|
||||
},
|
||||
non_global,
|
||||
r#"if (foo.debug) {}"#,
|
||||
r#"if (foo.debug) {}"#
|
||||
);
|
||||
}
|
@ -23,7 +23,7 @@ extern crate sourcemap;
|
||||
#[macro_use]
|
||||
extern crate testing;
|
||||
|
||||
pub use self::simplify::simplifier;
|
||||
pub use self::{inline_globals::InlineGlobals, simplify::simplifier};
|
||||
|
||||
#[cfg(test)]
|
||||
#[macro_use]
|
||||
@ -32,6 +32,7 @@ mod tests;
|
||||
mod quote;
|
||||
pub mod compat;
|
||||
mod fixer;
|
||||
mod inline_globals;
|
||||
pub mod scope;
|
||||
mod simplify;
|
||||
pub mod util;
|
||||
|
@ -1,5 +1,5 @@
|
||||
use swc_common::{Fold, FoldWith};
|
||||
use ast::*;
|
||||
use swc_common::{Fold, FoldWith};
|
||||
|
||||
pub trait FoldScope<T> {
|
||||
/// `scope`: Scope which contains `node`.
|
||||
|
@ -41,8 +41,8 @@ impl<'a> Tester<'a> {
|
||||
pub fn apply_transform<T: Fold<Module>>(
|
||||
&mut self,
|
||||
mut tr: T,
|
||||
name: &'static str,
|
||||
src: &'static str,
|
||||
name: &str,
|
||||
src: &str,
|
||||
) -> Result<Module, ()> {
|
||||
let fm = self
|
||||
.cm
|
||||
@ -57,10 +57,7 @@ impl<'a> Tester<'a> {
|
||||
|
||||
let module = {
|
||||
let mut p = Parser::new(sess, SourceFileInput::from(&*fm));
|
||||
p.parse_module().map_err(|err| {
|
||||
err.emit();
|
||||
()
|
||||
})?
|
||||
p.parse_module()?
|
||||
};
|
||||
// println!("parsed {} as a module\n{:?}", src, module);
|
||||
|
||||
|
@ -3,11 +3,15 @@ name = "libswc"
|
||||
version = "0.1.0"
|
||||
authors = ["강동윤 <kdy1@outlook.kr>"]
|
||||
edition = "2018"
|
||||
license = "Apache-2.0/MIT"
|
||||
repository = "https://github.com/swc-project/swc.git"
|
||||
documentation = "https://swc-project.github.io/rustdoc/libswc/"
|
||||
description = "Speedy web compiler: Make the web (development) faster"
|
||||
|
||||
[dependencies]
|
||||
swc_atoms = { path = "../atoms" }
|
||||
swc_common = { path = "../common" }
|
||||
swc_ecmascript = { path = "../ecmascript" }
|
||||
swc_atoms = { version = "0.1", path ="../atoms" }
|
||||
swc_common = { version = "0.1", path ="../common" }
|
||||
swc_ecmascript = { version = "0.1", path ="../ecmascript" }
|
||||
rayon = "1.0.3"
|
||||
slog = "2"
|
||||
sourcemap = "2.2"
|
@ -51,13 +51,7 @@ impl Compiler {
|
||||
logger: &logger,
|
||||
cfg: Default::default(),
|
||||
};
|
||||
let module = Parser::new(session, SourceFileInput::from(&*fm))
|
||||
.parse_module()
|
||||
.map_err(|e| {
|
||||
e.emit();
|
||||
()
|
||||
});
|
||||
module
|
||||
Parser::new(session, SourceFileInput::from(&*fm)).parse_module()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2,12 +2,16 @@
|
||||
name = "ast_node"
|
||||
version = "0.1.0"
|
||||
authors = ["강동윤 <kdy1@outlook.kr>"]
|
||||
license = "Apache-2.0/MIT"
|
||||
repository = "https://github.com/swc-project/swc.git"
|
||||
documentation = "https://swc-project.github.io/rustdoc/ast_node/"
|
||||
description = "Macros for ast nodes."
|
||||
|
||||
[lib]
|
||||
proc-macro = true
|
||||
|
||||
[dependencies]
|
||||
swc_macros_common = { path = "../common" }
|
||||
swc_macros_common = { version = "0.1", path = "../common" }
|
||||
pmutil = "0.2"
|
||||
proc-macro2 = { version = "0.4.4", features = ["nightly"] }
|
||||
quote = "0.6"
|
||||
@ -19,4 +23,4 @@ features = ["derive", "fold", "parsing", "printing"]
|
||||
|
||||
|
||||
[dev-dependencies]
|
||||
swc_common = { path = "../../common" }
|
||||
swc_common = { version = "0.1", path = "../../common" }
|
@ -2,6 +2,10 @@
|
||||
name = "swc_macros_common"
|
||||
version = "0.1.0"
|
||||
authors = ["강동윤 <kdy1@outlook.kr>"]
|
||||
license = "Apache-2.0/MIT"
|
||||
repository = "https://github.com/swc-project/swc.git"
|
||||
documentation = "https://swc-project.github.io/rustdoc/swc_macros_common/"
|
||||
description = "Common utilities for swc macros."
|
||||
|
||||
[dependencies]
|
||||
pmutil = "0.2"
|
||||
|
@ -2,12 +2,16 @@
|
||||
name = "enum_kind"
|
||||
version = "0.1.0"
|
||||
authors = ["강동윤 <kdy1@outlook.kr>"]
|
||||
license = "Apache-2.0/MIT"
|
||||
repository = "https://github.com/swc-project/swc.git"
|
||||
documentation = "https://swc-project.github.io/rustdoc/enum_kind/"
|
||||
description = "Easily manage values related to enum."
|
||||
|
||||
[lib]
|
||||
proc-macro = true
|
||||
|
||||
[dependencies]
|
||||
swc_macros_common = { path = "../common" }
|
||||
swc_macros_common = { version = "0.1", path ="../common" }
|
||||
pmutil = "0.2"
|
||||
proc-macro2 = "0.4.4"
|
||||
|
||||
|
@ -2,12 +2,16 @@
|
||||
name = "string_enum"
|
||||
version = "0.1.0"
|
||||
authors = ["강동윤 <kdy1@outlook.kr>"]
|
||||
license = "Apache-2.0/MIT"
|
||||
repository = "https://github.com/swc-project/swc.git"
|
||||
documentation = "https://swc-project.github.io/rustdoc/string_enum/"
|
||||
description = "String based enum."
|
||||
|
||||
[lib]
|
||||
proc-macro = true
|
||||
|
||||
[dependencies]
|
||||
swc_macros_common = { path = "../common" }
|
||||
swc_macros_common = { version = "0.1", path ="../common" }
|
||||
pmutil = "0.2"
|
||||
proc-macro2 = "0.4.4"
|
||||
quote = "0.6.3"
|
||||
|
@ -114,7 +114,7 @@ fn js_pass(cm: Lrc<SourceMap>, matches: &ArgMatches) -> Box<Fold<Module>> {
|
||||
let helpers = Arc::new(compat::helpers::Helpers::default());
|
||||
|
||||
let pass: Box<Fold<Module>> = box compat::es2016()
|
||||
.then(compat::es2015(helpers.clone()))
|
||||
.then(compat::es2015(&helpers))
|
||||
.then(compat::es3())
|
||||
.then(compat::helpers::InjectHelpers {
|
||||
cm,
|
||||
|
@ -2,9 +2,13 @@
|
||||
name = "testing"
|
||||
version = "0.1.0"
|
||||
authors = ["강동윤 <kdy1@outlook.kr>"]
|
||||
license = "Apache-2.0/MIT"
|
||||
repository = "https://github.com/swc-project/swc.git"
|
||||
documentation = "https://swc-project.github.io/rustdoc/testing/"
|
||||
description = "Testing utilities for the swc project."
|
||||
|
||||
[dependencies]
|
||||
swc_common = { path = "../common" }
|
||||
swc_common = { version = "0.1", path ="../common" }
|
||||
slog = "2"
|
||||
slog-envlogger = "2.1"
|
||||
slog-term = "2.3"
|
||||
|
Loading…
Reference in New Issue
Block a user