diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 41ffbd4df5c..19d74390d57 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -1,6 +1,6 @@ name: Lint -on: [push] +on: [push, pull_request] jobs: lint: diff --git a/ecmascript/codegen/tests/references/15a12468ff312d51.js b/ecmascript/codegen/tests/references/15a12468ff312d51.js index af1aad6c18e..4c94075c1e1 100644 --- a/ecmascript/codegen/tests/references/15a12468ff312d51.js +++ b/ecmascript/codegen/tests/references/15a12468ff312d51.js @@ -1 +1 @@ -622141790000000000000000; +602214179000000000000000; diff --git a/ecmascript/parser/src/lexer/number.rs b/ecmascript/parser/src/lexer/number.rs index 6641e0713d5..3f510ef843e 100644 --- a/ecmascript/parser/src/lexer/number.rs +++ b/ecmascript/parser/src/lexer/number.rs @@ -87,13 +87,14 @@ impl<'a, I: Input> Lexer<'a, I> { debug_assert!(self.cur().unwrap().is_digit(10)); } + let mut raw = Raw(Some(String::new())); // Read numbers after dot - let dec_val = self.read_int(10, 0, &mut Raw(None))?; + let dec_val = self.read_int(10, 0, &mut raw)?; let mut s = String::new(); write!(s, "{}.", val).unwrap(); - if let Some(ref n) = dec_val { - write!(s, "{}", n).unwrap(); + if let Some(..) = dec_val { + s.push_str(&raw.0.as_ref().unwrap()); } val = s.parse().expect("failed to parse float using rust's impl"); @@ -402,6 +403,11 @@ mod tests { debug_assert_eq!(77777777777777777.1f64, num("77777777777777777.1")) } + #[test] + fn issue_480() { + debug_assert_eq!(9.09, num("9.09")) + } + #[test] fn num_legacy_octal() { debug_assert_eq!(0o12 as f64, num("0012")); diff --git a/ecmascript/parser/src/lexer/tests.rs b/ecmascript/parser/src/lexer/tests.rs index 7a3dcdf9aa7..b490d5c7a04 100644 --- a/ecmascript/parser/src/lexer/tests.rs +++ b/ecmascript/parser/src/lexer/tests.rs @@ -1088,6 +1088,36 @@ fn issue_401() { ); } +#[test] +fn issue_481() { + assert_eq!( + lex_tokens( + crate::Syntax::Es(crate::EsConfig { + jsx: true, + ..Default::default() + }), + " {foo}" + ), + vec![ + Token::JSXTagStart, + Token::JSXName { + name: "span".into() + }, + Token::JSXTagEnd, + JSXText { raw: " ".into() }, + LBrace, + Word(Word::Ident("foo".into())), + RBrace, + JSXTagStart, + BinOp(Div), + JSXName { + name: "span".into() + }, + JSXTagEnd, + ] + ); +} + #[bench] fn lex_colors_js(b: &mut Bencher) { b.bytes = include_str!("../../colors.js").len() as _; diff --git a/ecmascript/transforms/src/modules/amd.rs b/ecmascript/transforms/src/modules/amd.rs index fcb251aa037..b3157490006 100644 --- a/ecmascript/transforms/src/modules/amd.rs +++ b/ecmascript/transforms/src/modules/amd.rs @@ -7,7 +7,7 @@ use crate::{ util::{prepend_stmts, var::VarCollector, DestructuringFinder, ExprFactory}, }; use ast::*; -use hashbrown::HashSet; +use fxhash::FxHashSet; use serde::{Deserialize, Serialize}; use std::iter; use swc_atoms::js_word; @@ -55,7 +55,7 @@ impl Fold for Amd { } let mut exports = vec![]; - let mut initialized = HashSet::default(); + let mut initialized = FxHashSet::default(); let mut export_alls = vec![]; let mut emitted_esmodule = false; let mut has_export = false; diff --git a/ecmascript/transforms/src/modules/common_js.rs b/ecmascript/transforms/src/modules/common_js.rs index e712c689816..e487dd53c22 100644 --- a/ecmascript/transforms/src/modules/common_js.rs +++ b/ecmascript/transforms/src/modules/common_js.rs @@ -8,7 +8,7 @@ use crate::{ util::{var::VarCollector, DestructuringFinder, ExprFactory}, }; use ast::*; -use hashbrown::HashSet; +use fxhash::FxHashSet; use swc_atoms::js_word; use swc_common::{Fold, FoldWith, VisitWith, DUMMY_SP}; @@ -40,7 +40,7 @@ impl Fold> for CommonJs { } let mut exports = vec![]; - let mut initialized = HashSet::default(); + let mut initialized = FxHashSet::default(); let mut export_alls = vec![]; for item in items { diff --git a/ecmascript/transforms/src/modules/umd.rs b/ecmascript/transforms/src/modules/umd.rs index 7878d9d986d..6aef2bcf2d6 100644 --- a/ecmascript/transforms/src/modules/umd.rs +++ b/ecmascript/transforms/src/modules/umd.rs @@ -9,7 +9,7 @@ use crate::{ util::{prepend_stmts, var::VarCollector, DestructuringFinder, ExprFactory}, }; use ast::*; -use hashbrown::HashSet; +use fxhash::FxHashSet; use std::sync::Arc; use swc_atoms::js_word; use swc_common::{Fold, FoldWith, Mark, SourceMap, VisitWith, DUMMY_SP}; @@ -53,7 +53,7 @@ impl Fold for Umd { } let mut exports = vec![]; - let mut initialized = HashSet::default(); + let mut initialized = FxHashSet::default(); let mut export_alls = vec![]; let mut emitted_esmodule = false; let mut has_export = false; diff --git a/ecmascript/transforms/src/modules/util.rs b/ecmascript/transforms/src/modules/util.rs index 6888de94200..6b25ec8aaf4 100644 --- a/ecmascript/transforms/src/modules/util.rs +++ b/ecmascript/transforms/src/modules/util.rs @@ -1,5 +1,6 @@ use crate::util::{undefined, DestructuringFinder, ExprFactory}; use ast::*; +use fxhash::FxHashSet; use hashbrown::{hash_map::Entry, HashMap, HashSet}; use indexmap::IndexMap; use inflector::Inflector; @@ -718,7 +719,7 @@ pub(super) fn use_strict() -> Stmt { /// ```js /// exports.default = exports.foo = void 0; /// ``` -pub(super) fn initialize_to_undefined(exports: Ident, initialized: HashSet) -> Box { +pub(super) fn initialize_to_undefined(exports: Ident, initialized: FxHashSet) -> Box { let mut rhs = undefined(DUMMY_SP); for name in initialized.into_iter() { diff --git a/ecmascript/transforms/src/react/jsx.rs b/ecmascript/transforms/src/react/jsx.rs index a20b95d2d21..b90805c946c 100644 --- a/ecmascript/transforms/src/react/jsx.rs +++ b/ecmascript/transforms/src/react/jsx.rs @@ -172,6 +172,7 @@ impl Jsx { if s.value.is_empty() { return None; } + Lit::Str(s).as_arg() } JSXElementChild::JSXExprContainer(JSXExprContainer { @@ -392,11 +393,14 @@ fn to_prop_name(n: JSXAttrName) -> PropName { } fn jsx_text_to_str(t: JsWord) -> JsWord { + if t == *" " { + return t; + } if !t.contains(' ') && !t.contains('\n') { return t; } - let mut buf = String::new(); + let mut buf = String::from(""); for s in t.replace("\n", " ").split_ascii_whitespace() { buf.push_str(s); buf.push(' '); diff --git a/ecmascript/transforms/src/react/jsx/tests.rs b/ecmascript/transforms/src/react/jsx/tests.rs index 8a27ee1d6a3..a5878639e58 100644 --- a/ecmascript/transforms/src/react/jsx/tests.rs +++ b/ecmascript/transforms/src/react/jsx/tests.rs @@ -1066,3 +1066,17 @@ test!( var _react = _interopRequireDefault(require('react')); _react.default.createElement('div', null);" ); + +test!( + ::swc_ecma_parser::Syntax::Es(::swc_ecma_parser::EsConfig { + jsx: true, + ..Default::default() + }), + |_| tr(Options { + use_builtins: true, + ..Default::default() + }), + issue_481, + " {foo};", + "React.createElement('span', null, ' ', foo);" +);