mirror of
https://github.com/swc-project/swc.git
synced 2024-12-11 07:35:15 +03:00
feat(css/parser): Allow invalid line comments (#2443)
swc_css_parser: - Accept line comments with an option.
This commit is contained in:
parent
c2ce89c0fb
commit
7f04ef4715
8
Cargo.lock
generated
8
Cargo.lock
generated
@ -2500,7 +2500,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "swc_css"
|
name = "swc_css"
|
||||||
version = "0.17.0"
|
version = "0.18.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"swc_css_ast",
|
"swc_css_ast",
|
||||||
"swc_css_codegen",
|
"swc_css_codegen",
|
||||||
@ -2522,7 +2522,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "swc_css_codegen"
|
name = "swc_css_codegen"
|
||||||
version = "0.15.0"
|
version = "0.16.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"auto_impl",
|
"auto_impl",
|
||||||
"bitflags",
|
"bitflags",
|
||||||
@ -2548,7 +2548,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "swc_css_parser"
|
name = "swc_css_parser"
|
||||||
version = "0.17.0"
|
version = "0.18.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags",
|
"bitflags",
|
||||||
"lexical",
|
"lexical",
|
||||||
@ -3142,7 +3142,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "swc_stylis"
|
name = "swc_stylis"
|
||||||
version = "0.14.0"
|
version = "0.15.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"swc_atoms 0.2.8",
|
"swc_atoms 0.2.8",
|
||||||
"swc_common",
|
"swc_common",
|
||||||
|
@ -6,11 +6,11 @@ edition = "2018"
|
|||||||
license = "Apache-2.0/MIT"
|
license = "Apache-2.0/MIT"
|
||||||
name = "swc_css"
|
name = "swc_css"
|
||||||
repository = "https://github.com/swc-project/swc.git"
|
repository = "https://github.com/swc-project/swc.git"
|
||||||
version = "0.17.0"
|
version = "0.18.0"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
swc_css_ast = {version = "0.16.0", path = "./ast"}
|
swc_css_ast = {version = "0.16.0", path = "./ast"}
|
||||||
swc_css_codegen = {version = "0.15.0", path = "./codegen"}
|
swc_css_codegen = {version = "0.16.0", path = "./codegen"}
|
||||||
swc_css_parser = {version = "0.17.0", path = "./parser"}
|
swc_css_parser = {version = "0.18.0", path = "./parser"}
|
||||||
swc_css_utils = {version = "0.13.0", path = "./utils/"}
|
swc_css_utils = {version = "0.13.0", path = "./utils/"}
|
||||||
swc_css_visit = {version = "0.15.0", path = "./visit"}
|
swc_css_visit = {version = "0.15.0", path = "./visit"}
|
||||||
|
@ -6,7 +6,7 @@ edition = "2018"
|
|||||||
license = "Apache-2.0/MIT"
|
license = "Apache-2.0/MIT"
|
||||||
name = "swc_css_codegen"
|
name = "swc_css_codegen"
|
||||||
repository = "https://github.com/swc-project/swc.git"
|
repository = "https://github.com/swc-project/swc.git"
|
||||||
version = "0.15.0"
|
version = "0.16.0"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
auto_impl = "0.4.1"
|
auto_impl = "0.4.1"
|
||||||
@ -17,6 +17,6 @@ swc_css_ast = {version = "0.16.0", path = "../ast/"}
|
|||||||
swc_css_codegen_macros = {version = "0.2.0", path = "macros/"}
|
swc_css_codegen_macros = {version = "0.2.0", path = "macros/"}
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
swc_css_parser = {version = "0.17.0", path = "../parser"}
|
swc_css_parser = {version = "0.18.0", path = "../parser"}
|
||||||
swc_css_visit = {version = "0.15.0", path = "../visit"}
|
swc_css_visit = {version = "0.15.0", path = "../visit"}
|
||||||
testing = {version = "0.14.0", path = "../../testing"}
|
testing = {version = "0.14.0", path = "../../testing"}
|
||||||
|
@ -19,8 +19,15 @@ fn parse_again(input: PathBuf) {
|
|||||||
eprintln!("==== ==== Input ==== ====\n{}\n", fm.src);
|
eprintln!("==== ==== Input ==== ====\n{}\n", fm.src);
|
||||||
|
|
||||||
let mut errors = vec![];
|
let mut errors = vec![];
|
||||||
let mut stylesheet: Stylesheet =
|
let mut stylesheet: Stylesheet = parse_file(
|
||||||
parse_file(&fm, ParserConfig { parse_values: true }, &mut errors).unwrap();
|
&fm,
|
||||||
|
ParserConfig {
|
||||||
|
parse_values: true,
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
&mut errors,
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
for err in take(&mut errors) {
|
for err in take(&mut errors) {
|
||||||
err.to_diagnostics(&handler).emit();
|
err.to_diagnostics(&handler).emit();
|
||||||
@ -37,12 +44,17 @@ fn parse_again(input: PathBuf) {
|
|||||||
eprintln!("==== ==== Codegen ==== ====\n{}\n", css_str);
|
eprintln!("==== ==== Codegen ==== ====\n{}\n", css_str);
|
||||||
|
|
||||||
let new_fm = cm.new_source_file(FileName::Anon, css_str);
|
let new_fm = cm.new_source_file(FileName::Anon, css_str);
|
||||||
let mut parsed: Stylesheet =
|
let mut parsed: Stylesheet = parse_file(
|
||||||
parse_file(&new_fm, ParserConfig { parse_values: true }, &mut errors).map_err(
|
&new_fm,
|
||||||
|err| {
|
ParserConfig {
|
||||||
err.to_diagnostics(&handler).emit();
|
parse_values: true,
|
||||||
|
..Default::default()
|
||||||
},
|
},
|
||||||
)?;
|
&mut errors,
|
||||||
|
)
|
||||||
|
.map_err(|err| {
|
||||||
|
err.to_diagnostics(&handler).emit();
|
||||||
|
})?;
|
||||||
|
|
||||||
for err in errors {
|
for err in errors {
|
||||||
err.to_diagnostics(&handler).emit();
|
err.to_diagnostics(&handler).emit();
|
||||||
|
@ -6,7 +6,7 @@ edition = "2018"
|
|||||||
license = "Apache-2.0/MIT"
|
license = "Apache-2.0/MIT"
|
||||||
name = "swc_css_parser"
|
name = "swc_css_parser"
|
||||||
repository = "https://github.com/swc-project/swc.git"
|
repository = "https://github.com/swc-project/swc.git"
|
||||||
version = "0.17.0"
|
version = "0.18.0"
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
error::{Error, ErrorKind},
|
error::{Error, ErrorKind},
|
||||||
parser::{input::ParserInput, PResult},
|
parser::{input::ParserInput, PResult, ParserConfig},
|
||||||
};
|
};
|
||||||
use swc_atoms::{js_word, JsWord};
|
use swc_atoms::{js_word, JsWord};
|
||||||
use swc_common::{input::Input, BytePos, Span};
|
use swc_common::{input::Input, BytePos, Span};
|
||||||
@ -19,18 +19,20 @@ where
|
|||||||
start_pos: BytePos,
|
start_pos: BytePos,
|
||||||
/// Used to override last_pos
|
/// Used to override last_pos
|
||||||
last_pos: Option<BytePos>,
|
last_pos: Option<BytePos>,
|
||||||
|
config: ParserConfig,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<I> Lexer<I>
|
impl<I> Lexer<I>
|
||||||
where
|
where
|
||||||
I: Input,
|
I: Input,
|
||||||
{
|
{
|
||||||
pub fn new(input: I) -> Self {
|
pub fn new(input: I, config: ParserConfig) -> Self {
|
||||||
let start_pos = input.last_pos();
|
let start_pos = input.last_pos();
|
||||||
Lexer {
|
Lexer {
|
||||||
input,
|
input,
|
||||||
start_pos,
|
start_pos,
|
||||||
last_pos: None,
|
last_pos: None,
|
||||||
|
config,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -100,6 +102,15 @@ where
|
|||||||
return self.read_token();
|
return self.read_token();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if self.config.allow_wrong_line_comments {
|
||||||
|
if self.input.is_byte(b'/') && self.input.peek() == Some('/') {
|
||||||
|
self.skip_line_comment()?;
|
||||||
|
self.start_pos = self.input.cur_pos();
|
||||||
|
|
||||||
|
return self.read_token();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
macro_rules! try_delim {
|
macro_rules! try_delim {
|
||||||
($b:tt,$tok:tt) => {{
|
($b:tt,$tok:tt) => {{
|
||||||
if self.input.eat_byte($b) {
|
if self.input.eat_byte($b) {
|
||||||
@ -755,6 +766,15 @@ where
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if self.config.allow_wrong_line_comments {
|
||||||
|
if self.input.is_byte(b'/') && self.input.peek() == Some('/') {
|
||||||
|
self.skip_line_comment()?;
|
||||||
|
self.start_pos = self.input.cur_pos();
|
||||||
|
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -788,6 +808,29 @@ where
|
|||||||
|
|
||||||
Err(ErrorKind::UnterminatedBlockComment)
|
Err(ErrorKind::UnterminatedBlockComment)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn skip_line_comment(&mut self) -> LexResult<()> {
|
||||||
|
debug_assert_eq!(self.input.cur(), Some('/'));
|
||||||
|
debug_assert_eq!(self.input.peek(), Some('/'));
|
||||||
|
|
||||||
|
self.input.bump();
|
||||||
|
self.input.bump();
|
||||||
|
|
||||||
|
debug_assert!(
|
||||||
|
self.config.allow_wrong_line_comments,
|
||||||
|
"Line comments are wrong and should be lexed only if it's explicitly requested"
|
||||||
|
);
|
||||||
|
|
||||||
|
while let Some(c) = self.input.cur() {
|
||||||
|
if is_newline(c) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
self.input.bump();
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
|
@ -43,7 +43,7 @@ pub fn parse_str<'a, T>(
|
|||||||
where
|
where
|
||||||
Parser<Lexer<StringInput<'a>>>: Parse<T>,
|
Parser<Lexer<StringInput<'a>>>: Parse<T>,
|
||||||
{
|
{
|
||||||
let lexer = Lexer::new(StringInput::new(src, start_pos, end_pos));
|
let lexer = Lexer::new(StringInput::new(src, start_pos, end_pos), config);
|
||||||
let mut parser = Parser::new(lexer, config);
|
let mut parser = Parser::new(lexer, config);
|
||||||
|
|
||||||
let res = parser.parse();
|
let res = parser.parse();
|
||||||
@ -63,7 +63,7 @@ pub fn parse_file<'a, T>(
|
|||||||
where
|
where
|
||||||
Parser<Lexer<StringInput<'a>>>: Parse<T>,
|
Parser<Lexer<StringInput<'a>>>: Parse<T>,
|
||||||
{
|
{
|
||||||
let lexer = Lexer::new(StringInput::from(fm));
|
let lexer = Lexer::new(StringInput::from(fm), config);
|
||||||
let mut parser = Parser::new(lexer, config);
|
let mut parser = Parser::new(lexer, config);
|
||||||
|
|
||||||
let res = parser.parse();
|
let res = parser.parse();
|
||||||
|
@ -24,6 +24,13 @@ pub type PResult<T> = Result<T, Error>;
|
|||||||
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||||
pub struct ParserConfig {
|
pub struct ParserConfig {
|
||||||
pub parse_values: bool,
|
pub parse_values: bool,
|
||||||
|
|
||||||
|
/// If this is `true`, **wrong** comments starting with `//` will be treated
|
||||||
|
/// as a comment.
|
||||||
|
///
|
||||||
|
/// This option exists because there are so many css-in-js tools and people
|
||||||
|
/// use `//` as a comment because it's javascript file.
|
||||||
|
pub allow_wrong_line_comments: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Default, Clone, Copy)]
|
#[derive(Debug, Default, Clone, Copy)]
|
||||||
|
@ -27,8 +27,15 @@ impl Visit for AssertValid {
|
|||||||
|
|
||||||
let mut errors = vec![];
|
let mut errors = vec![];
|
||||||
|
|
||||||
let _selectors: Vec<ComplexSelector> =
|
let _selectors: Vec<ComplexSelector> = parse_tokens(
|
||||||
parse_tokens(&s.args, ParserConfig { parse_values: true }, &mut errors)
|
&s.args,
|
||||||
|
ParserConfig {
|
||||||
|
parse_values: true,
|
||||||
|
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
&mut errors,
|
||||||
|
)
|
||||||
.unwrap_or_else(|err| panic!("failed to parse tokens: {:?}\n{:?}", err, s.args));
|
.unwrap_or_else(|err| panic!("failed to parse tokens: {:?}\n{:?}", err, s.args));
|
||||||
|
|
||||||
for err in errors {
|
for err in errors {
|
||||||
@ -45,7 +52,7 @@ fn tokens_input(input: PathBuf) {
|
|||||||
let fm = cm.load_file(&input).unwrap();
|
let fm = cm.load_file(&input).unwrap();
|
||||||
|
|
||||||
let tokens = {
|
let tokens = {
|
||||||
let mut lexer = Lexer::new(SourceFileInput::from(&*fm));
|
let mut lexer = Lexer::new(SourceFileInput::from(&*fm), Default::default());
|
||||||
|
|
||||||
let mut tokens = vec![];
|
let mut tokens = vec![];
|
||||||
|
|
||||||
@ -59,8 +66,15 @@ fn tokens_input(input: PathBuf) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let mut errors = vec![];
|
let mut errors = vec![];
|
||||||
let ss: Stylesheet =
|
let ss: Stylesheet = parse_tokens(
|
||||||
parse_tokens(&tokens, ParserConfig { parse_values: true }, &mut errors)
|
&tokens,
|
||||||
|
ParserConfig {
|
||||||
|
parse_values: true,
|
||||||
|
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
&mut errors,
|
||||||
|
)
|
||||||
.expect("failed to parse tokens");
|
.expect("failed to parse tokens");
|
||||||
|
|
||||||
for err in errors {
|
for err in errors {
|
||||||
@ -78,16 +92,15 @@ fn tokens_input(input: PathBuf) {
|
|||||||
.unwrap();
|
.unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
#[testing::fixture("tests/fixture/**/input.css")]
|
fn test_pass(input: PathBuf, config: ParserConfig) {
|
||||||
fn pass(input: PathBuf) {
|
|
||||||
eprintln!("Input: {}", input.display());
|
eprintln!("Input: {}", input.display());
|
||||||
|
|
||||||
testing::run_test2(false, |cm, handler| {
|
testing::run_test2(false, |cm, handler| {
|
||||||
let ref_json_path = input.parent().unwrap().join("output.json");
|
let ref_json_path = input.parent().unwrap().join("output.json");
|
||||||
|
|
||||||
let fm = cm.load_file(&input).unwrap();
|
let fm = cm.load_file(&input).unwrap();
|
||||||
let lexer = Lexer::new(SourceFileInput::from(&*fm));
|
let lexer = Lexer::new(SourceFileInput::from(&*fm), config);
|
||||||
let mut parser = Parser::new(lexer, ParserConfig { parse_values: true });
|
let mut parser = Parser::new(lexer, config);
|
||||||
|
|
||||||
let stylesheet = parser.parse_all();
|
let stylesheet = parser.parse_all();
|
||||||
|
|
||||||
@ -99,8 +112,8 @@ fn pass(input: PathBuf) {
|
|||||||
|
|
||||||
actual_json.clone().compare_to_file(&ref_json_path).unwrap();
|
actual_json.clone().compare_to_file(&ref_json_path).unwrap();
|
||||||
|
|
||||||
{
|
if !config.allow_wrong_line_comments {
|
||||||
let mut lexer = Lexer::new(SourceFileInput::from(&*fm));
|
let mut lexer = Lexer::new(SourceFileInput::from(&*fm), Default::default());
|
||||||
let mut tokens = Tokens {
|
let mut tokens = Tokens {
|
||||||
span: Span::new(fm.start_pos, fm.end_pos, Default::default()),
|
span: Span::new(fm.start_pos, fm.end_pos, Default::default()),
|
||||||
tokens: vec![],
|
tokens: vec![],
|
||||||
@ -123,8 +136,15 @@ fn pass(input: PathBuf) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let mut errors = vec![];
|
let mut errors = vec![];
|
||||||
let ss_tok: Stylesheet =
|
let ss_tok: Stylesheet = parse_tokens(
|
||||||
parse_tokens(&tokens, ParserConfig { parse_values: true }, &mut errors)
|
&tokens,
|
||||||
|
ParserConfig {
|
||||||
|
parse_values: true,
|
||||||
|
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
&mut errors,
|
||||||
|
)
|
||||||
.expect("failed to parse token");
|
.expect("failed to parse token");
|
||||||
|
|
||||||
for err in errors {
|
for err in errors {
|
||||||
@ -153,6 +173,29 @@ fn pass(input: PathBuf) {
|
|||||||
.unwrap();
|
.unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[testing::fixture("tests/fixture/**/input.css")]
|
||||||
|
fn pass(input: PathBuf) {
|
||||||
|
test_pass(
|
||||||
|
input,
|
||||||
|
ParserConfig {
|
||||||
|
parse_values: true,
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[testing::fixture("tests/line-comment/**/input.css")]
|
||||||
|
fn line_commetns(input: PathBuf) {
|
||||||
|
test_pass(
|
||||||
|
input,
|
||||||
|
ParserConfig {
|
||||||
|
parse_values: true,
|
||||||
|
allow_wrong_line_comments: true,
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
#[testing::fixture("tests/recovery/**/input.css")]
|
#[testing::fixture("tests/recovery/**/input.css")]
|
||||||
fn recovery(input: PathBuf) {
|
fn recovery(input: PathBuf) {
|
||||||
eprintln!("Input: {}", input.display());
|
eprintln!("Input: {}", input.display());
|
||||||
@ -168,9 +211,13 @@ fn recovery(input: PathBuf) {
|
|||||||
|
|
||||||
let ref_json_path = input.parent().unwrap().join("output.json");
|
let ref_json_path = input.parent().unwrap().join("output.json");
|
||||||
|
|
||||||
|
let config = ParserConfig {
|
||||||
|
parse_values: true,
|
||||||
|
allow_wrong_line_comments: false,
|
||||||
|
};
|
||||||
let fm = cm.load_file(&input).unwrap();
|
let fm = cm.load_file(&input).unwrap();
|
||||||
let lexer = Lexer::new(SourceFileInput::from(&*fm));
|
let lexer = Lexer::new(SourceFileInput::from(&*fm), config);
|
||||||
let mut parser = Parser::new(lexer, ParserConfig { parse_values: true });
|
let mut parser = Parser::new(lexer, config);
|
||||||
|
|
||||||
let stylesheet = parser.parse_all();
|
let stylesheet = parser.parse_all();
|
||||||
|
|
||||||
@ -183,7 +230,7 @@ fn recovery(input: PathBuf) {
|
|||||||
actual_json.clone().compare_to_file(&ref_json_path).unwrap();
|
actual_json.clone().compare_to_file(&ref_json_path).unwrap();
|
||||||
|
|
||||||
{
|
{
|
||||||
let mut lexer = Lexer::new(SourceFileInput::from(&*fm));
|
let mut lexer = Lexer::new(SourceFileInput::from(&*fm), Default::default());
|
||||||
let mut tokens = Tokens {
|
let mut tokens = Tokens {
|
||||||
span: Span::new(fm.start_pos, fm.end_pos, Default::default()),
|
span: Span::new(fm.start_pos, fm.end_pos, Default::default()),
|
||||||
tokens: vec![],
|
tokens: vec![],
|
||||||
@ -206,8 +253,14 @@ fn recovery(input: PathBuf) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let mut errors = vec![];
|
let mut errors = vec![];
|
||||||
let ss_tok: Stylesheet =
|
let ss_tok: Stylesheet = parse_tokens(
|
||||||
parse_tokens(&tokens, ParserConfig { parse_values: true }, &mut errors)
|
&tokens,
|
||||||
|
ParserConfig {
|
||||||
|
parse_values: true,
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
&mut errors,
|
||||||
|
)
|
||||||
.expect("failed to parse token");
|
.expect("failed to parse token");
|
||||||
|
|
||||||
for err in errors {
|
for err in errors {
|
||||||
@ -340,13 +393,19 @@ fn span(input: PathBuf) {
|
|||||||
let dir = input.parent().unwrap().to_path_buf();
|
let dir = input.parent().unwrap().to_path_buf();
|
||||||
|
|
||||||
let output = testing::run_test2(false, |cm, handler| {
|
let output = testing::run_test2(false, |cm, handler| {
|
||||||
|
// Type annotation
|
||||||
if false {
|
if false {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let config = ParserConfig {
|
||||||
|
parse_values: true,
|
||||||
|
..Default::default()
|
||||||
|
};
|
||||||
|
|
||||||
let fm = cm.load_file(&input).unwrap();
|
let fm = cm.load_file(&input).unwrap();
|
||||||
let lexer = Lexer::new(SourceFileInput::from(&*fm));
|
let lexer = Lexer::new(SourceFileInput::from(&*fm), config);
|
||||||
let mut parser = Parser::new(lexer, ParserConfig { parse_values: true });
|
let mut parser = Parser::new(lexer, config);
|
||||||
|
|
||||||
let stylesheet = parser.parse_all();
|
let stylesheet = parser.parse_all();
|
||||||
|
|
||||||
@ -382,9 +441,15 @@ fn fail(input: PathBuf) {
|
|||||||
let stderr_path = input.parent().unwrap().join("output.stderr");
|
let stderr_path = input.parent().unwrap().join("output.stderr");
|
||||||
|
|
||||||
let stderr = testing::run_test2(false, |cm, handler| -> Result<(), _> {
|
let stderr = testing::run_test2(false, |cm, handler| -> Result<(), _> {
|
||||||
|
let config = ParserConfig {
|
||||||
|
parse_values: true,
|
||||||
|
|
||||||
|
..Default::default()
|
||||||
|
};
|
||||||
|
|
||||||
let fm = cm.load_file(&input).unwrap();
|
let fm = cm.load_file(&input).unwrap();
|
||||||
let lexer = Lexer::new(SourceFileInput::from(&*fm));
|
let lexer = Lexer::new(SourceFileInput::from(&*fm), config);
|
||||||
let mut parser = Parser::new(lexer, ParserConfig { parse_values: true });
|
let mut parser = Parser::new(lexer, config);
|
||||||
|
|
||||||
let stylesheet = parser.parse_all();
|
let stylesheet = parser.parse_all();
|
||||||
|
|
||||||
|
4
css/parser/tests/line-comment/css-in-js/1/input.css
Normal file
4
css/parser/tests/line-comment/css-in-js/1/input.css
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
// Line comment
|
||||||
|
foo {
|
||||||
|
color: red;
|
||||||
|
}
|
101
css/parser/tests/line-comment/css-in-js/1/output.json
Normal file
101
css/parser/tests/line-comment/css-in-js/1/output.json
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
{
|
||||||
|
"type": "Stylesheet",
|
||||||
|
"span": {
|
||||||
|
"start": 15,
|
||||||
|
"end": 40,
|
||||||
|
"ctxt": 0
|
||||||
|
},
|
||||||
|
"rules": [
|
||||||
|
{
|
||||||
|
"type": "StyleRule",
|
||||||
|
"span": {
|
||||||
|
"start": 16,
|
||||||
|
"end": 39,
|
||||||
|
"ctxt": 0
|
||||||
|
},
|
||||||
|
"selectors": [
|
||||||
|
{
|
||||||
|
"type": "ComplexSelector",
|
||||||
|
"span": {
|
||||||
|
"start": 16,
|
||||||
|
"end": 19,
|
||||||
|
"ctxt": 0
|
||||||
|
},
|
||||||
|
"selectors": [
|
||||||
|
{
|
||||||
|
"type": "CompoundSelector",
|
||||||
|
"span": {
|
||||||
|
"start": 16,
|
||||||
|
"end": 19,
|
||||||
|
"ctxt": 0
|
||||||
|
},
|
||||||
|
"hasNestPrefix": false,
|
||||||
|
"combinator": null,
|
||||||
|
"typeSelector": {
|
||||||
|
"type": "NamespacedName",
|
||||||
|
"span": {
|
||||||
|
"start": 16,
|
||||||
|
"end": 19,
|
||||||
|
"ctxt": 0
|
||||||
|
},
|
||||||
|
"prefix": null,
|
||||||
|
"name": {
|
||||||
|
"type": "Text",
|
||||||
|
"span": {
|
||||||
|
"start": 16,
|
||||||
|
"end": 19,
|
||||||
|
"ctxt": 0
|
||||||
|
},
|
||||||
|
"value": "foo",
|
||||||
|
"raw": "foo"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"subclassSelectors": []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"block": {
|
||||||
|
"type": "DeclBlock",
|
||||||
|
"span": {
|
||||||
|
"start": 20,
|
||||||
|
"end": 39,
|
||||||
|
"ctxt": 0
|
||||||
|
},
|
||||||
|
"items": [
|
||||||
|
{
|
||||||
|
"type": "Property",
|
||||||
|
"span": {
|
||||||
|
"start": 26,
|
||||||
|
"end": 36,
|
||||||
|
"ctxt": 0
|
||||||
|
},
|
||||||
|
"name": {
|
||||||
|
"type": "Text",
|
||||||
|
"span": {
|
||||||
|
"start": 26,
|
||||||
|
"end": 31,
|
||||||
|
"ctxt": 0
|
||||||
|
},
|
||||||
|
"value": "color",
|
||||||
|
"raw": "color"
|
||||||
|
},
|
||||||
|
"values": [
|
||||||
|
{
|
||||||
|
"type": "Text",
|
||||||
|
"span": {
|
||||||
|
"start": 33,
|
||||||
|
"end": 36,
|
||||||
|
"ctxt": 0
|
||||||
|
},
|
||||||
|
"value": "red",
|
||||||
|
"raw": "red"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"important": null
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
4
css/parser/tests/line-comment/css-in-js/2/input.css
Normal file
4
css/parser/tests/line-comment/css-in-js/2/input.css
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
foo {
|
||||||
|
// Line comment
|
||||||
|
color: red;
|
||||||
|
}
|
101
css/parser/tests/line-comment/css-in-js/2/output.json
Normal file
101
css/parser/tests/line-comment/css-in-js/2/output.json
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
{
|
||||||
|
"type": "Stylesheet",
|
||||||
|
"span": {
|
||||||
|
"start": 0,
|
||||||
|
"end": 44,
|
||||||
|
"ctxt": 0
|
||||||
|
},
|
||||||
|
"rules": [
|
||||||
|
{
|
||||||
|
"type": "StyleRule",
|
||||||
|
"span": {
|
||||||
|
"start": 0,
|
||||||
|
"end": 43,
|
||||||
|
"ctxt": 0
|
||||||
|
},
|
||||||
|
"selectors": [
|
||||||
|
{
|
||||||
|
"type": "ComplexSelector",
|
||||||
|
"span": {
|
||||||
|
"start": 0,
|
||||||
|
"end": 3,
|
||||||
|
"ctxt": 0
|
||||||
|
},
|
||||||
|
"selectors": [
|
||||||
|
{
|
||||||
|
"type": "CompoundSelector",
|
||||||
|
"span": {
|
||||||
|
"start": 0,
|
||||||
|
"end": 3,
|
||||||
|
"ctxt": 0
|
||||||
|
},
|
||||||
|
"hasNestPrefix": false,
|
||||||
|
"combinator": null,
|
||||||
|
"typeSelector": {
|
||||||
|
"type": "NamespacedName",
|
||||||
|
"span": {
|
||||||
|
"start": 0,
|
||||||
|
"end": 3,
|
||||||
|
"ctxt": 0
|
||||||
|
},
|
||||||
|
"prefix": null,
|
||||||
|
"name": {
|
||||||
|
"type": "Text",
|
||||||
|
"span": {
|
||||||
|
"start": 0,
|
||||||
|
"end": 3,
|
||||||
|
"ctxt": 0
|
||||||
|
},
|
||||||
|
"value": "foo",
|
||||||
|
"raw": "foo"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"subclassSelectors": []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"block": {
|
||||||
|
"type": "DeclBlock",
|
||||||
|
"span": {
|
||||||
|
"start": 4,
|
||||||
|
"end": 43,
|
||||||
|
"ctxt": 0
|
||||||
|
},
|
||||||
|
"items": [
|
||||||
|
{
|
||||||
|
"type": "Property",
|
||||||
|
"span": {
|
||||||
|
"start": 30,
|
||||||
|
"end": 40,
|
||||||
|
"ctxt": 0
|
||||||
|
},
|
||||||
|
"name": {
|
||||||
|
"type": "Text",
|
||||||
|
"span": {
|
||||||
|
"start": 30,
|
||||||
|
"end": 35,
|
||||||
|
"ctxt": 0
|
||||||
|
},
|
||||||
|
"value": "color",
|
||||||
|
"raw": "color"
|
||||||
|
},
|
||||||
|
"values": [
|
||||||
|
{
|
||||||
|
"type": "Text",
|
||||||
|
"span": {
|
||||||
|
"start": 37,
|
||||||
|
"end": 40,
|
||||||
|
"ctxt": 0
|
||||||
|
},
|
||||||
|
"value": "red",
|
||||||
|
"raw": "red"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"important": null
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
4
css/parser/tests/line-comment/css-in-js/3/input.css
Normal file
4
css/parser/tests/line-comment/css-in-js/3/input.css
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
foo {
|
||||||
|
color: red;
|
||||||
|
// Line comment
|
||||||
|
}
|
101
css/parser/tests/line-comment/css-in-js/3/output.json
Normal file
101
css/parser/tests/line-comment/css-in-js/3/output.json
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
{
|
||||||
|
"type": "Stylesheet",
|
||||||
|
"span": {
|
||||||
|
"start": 0,
|
||||||
|
"end": 44,
|
||||||
|
"ctxt": 0
|
||||||
|
},
|
||||||
|
"rules": [
|
||||||
|
{
|
||||||
|
"type": "StyleRule",
|
||||||
|
"span": {
|
||||||
|
"start": 0,
|
||||||
|
"end": 43,
|
||||||
|
"ctxt": 0
|
||||||
|
},
|
||||||
|
"selectors": [
|
||||||
|
{
|
||||||
|
"type": "ComplexSelector",
|
||||||
|
"span": {
|
||||||
|
"start": 0,
|
||||||
|
"end": 3,
|
||||||
|
"ctxt": 0
|
||||||
|
},
|
||||||
|
"selectors": [
|
||||||
|
{
|
||||||
|
"type": "CompoundSelector",
|
||||||
|
"span": {
|
||||||
|
"start": 0,
|
||||||
|
"end": 3,
|
||||||
|
"ctxt": 0
|
||||||
|
},
|
||||||
|
"hasNestPrefix": false,
|
||||||
|
"combinator": null,
|
||||||
|
"typeSelector": {
|
||||||
|
"type": "NamespacedName",
|
||||||
|
"span": {
|
||||||
|
"start": 0,
|
||||||
|
"end": 3,
|
||||||
|
"ctxt": 0
|
||||||
|
},
|
||||||
|
"prefix": null,
|
||||||
|
"name": {
|
||||||
|
"type": "Text",
|
||||||
|
"span": {
|
||||||
|
"start": 0,
|
||||||
|
"end": 3,
|
||||||
|
"ctxt": 0
|
||||||
|
},
|
||||||
|
"value": "foo",
|
||||||
|
"raw": "foo"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"subclassSelectors": []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"block": {
|
||||||
|
"type": "DeclBlock",
|
||||||
|
"span": {
|
||||||
|
"start": 4,
|
||||||
|
"end": 43,
|
||||||
|
"ctxt": 0
|
||||||
|
},
|
||||||
|
"items": [
|
||||||
|
{
|
||||||
|
"type": "Property",
|
||||||
|
"span": {
|
||||||
|
"start": 10,
|
||||||
|
"end": 20,
|
||||||
|
"ctxt": 0
|
||||||
|
},
|
||||||
|
"name": {
|
||||||
|
"type": "Text",
|
||||||
|
"span": {
|
||||||
|
"start": 10,
|
||||||
|
"end": 15,
|
||||||
|
"ctxt": 0
|
||||||
|
},
|
||||||
|
"value": "color",
|
||||||
|
"raw": "color"
|
||||||
|
},
|
||||||
|
"values": [
|
||||||
|
{
|
||||||
|
"type": "Text",
|
||||||
|
"span": {
|
||||||
|
"start": 17,
|
||||||
|
"end": 20,
|
||||||
|
"ctxt": 0
|
||||||
|
},
|
||||||
|
"value": "red",
|
||||||
|
"raw": "red"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"important": null
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
5
css/parser/tests/line-comment/css-in-js/4/input.css
Normal file
5
css/parser/tests/line-comment/css-in-js/4/input.css
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
foo {
|
||||||
|
color: red;
|
||||||
|
// Line comment
|
||||||
|
top: 0;
|
||||||
|
}
|
131
css/parser/tests/line-comment/css-in-js/4/output.json
Normal file
131
css/parser/tests/line-comment/css-in-js/4/output.json
Normal file
@ -0,0 +1,131 @@
|
|||||||
|
{
|
||||||
|
"type": "Stylesheet",
|
||||||
|
"span": {
|
||||||
|
"start": 0,
|
||||||
|
"end": 56,
|
||||||
|
"ctxt": 0
|
||||||
|
},
|
||||||
|
"rules": [
|
||||||
|
{
|
||||||
|
"type": "StyleRule",
|
||||||
|
"span": {
|
||||||
|
"start": 0,
|
||||||
|
"end": 55,
|
||||||
|
"ctxt": 0
|
||||||
|
},
|
||||||
|
"selectors": [
|
||||||
|
{
|
||||||
|
"type": "ComplexSelector",
|
||||||
|
"span": {
|
||||||
|
"start": 0,
|
||||||
|
"end": 3,
|
||||||
|
"ctxt": 0
|
||||||
|
},
|
||||||
|
"selectors": [
|
||||||
|
{
|
||||||
|
"type": "CompoundSelector",
|
||||||
|
"span": {
|
||||||
|
"start": 0,
|
||||||
|
"end": 3,
|
||||||
|
"ctxt": 0
|
||||||
|
},
|
||||||
|
"hasNestPrefix": false,
|
||||||
|
"combinator": null,
|
||||||
|
"typeSelector": {
|
||||||
|
"type": "NamespacedName",
|
||||||
|
"span": {
|
||||||
|
"start": 0,
|
||||||
|
"end": 3,
|
||||||
|
"ctxt": 0
|
||||||
|
},
|
||||||
|
"prefix": null,
|
||||||
|
"name": {
|
||||||
|
"type": "Text",
|
||||||
|
"span": {
|
||||||
|
"start": 0,
|
||||||
|
"end": 3,
|
||||||
|
"ctxt": 0
|
||||||
|
},
|
||||||
|
"value": "foo",
|
||||||
|
"raw": "foo"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"subclassSelectors": []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"block": {
|
||||||
|
"type": "DeclBlock",
|
||||||
|
"span": {
|
||||||
|
"start": 4,
|
||||||
|
"end": 55,
|
||||||
|
"ctxt": 0
|
||||||
|
},
|
||||||
|
"items": [
|
||||||
|
{
|
||||||
|
"type": "Property",
|
||||||
|
"span": {
|
||||||
|
"start": 10,
|
||||||
|
"end": 20,
|
||||||
|
"ctxt": 0
|
||||||
|
},
|
||||||
|
"name": {
|
||||||
|
"type": "Text",
|
||||||
|
"span": {
|
||||||
|
"start": 10,
|
||||||
|
"end": 15,
|
||||||
|
"ctxt": 0
|
||||||
|
},
|
||||||
|
"value": "color",
|
||||||
|
"raw": "color"
|
||||||
|
},
|
||||||
|
"values": [
|
||||||
|
{
|
||||||
|
"type": "Text",
|
||||||
|
"span": {
|
||||||
|
"start": 17,
|
||||||
|
"end": 20,
|
||||||
|
"ctxt": 0
|
||||||
|
},
|
||||||
|
"value": "red",
|
||||||
|
"raw": "red"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"important": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "Property",
|
||||||
|
"span": {
|
||||||
|
"start": 46,
|
||||||
|
"end": 52,
|
||||||
|
"ctxt": 0
|
||||||
|
},
|
||||||
|
"name": {
|
||||||
|
"type": "Text",
|
||||||
|
"span": {
|
||||||
|
"start": 46,
|
||||||
|
"end": 49,
|
||||||
|
"ctxt": 0
|
||||||
|
},
|
||||||
|
"value": "top",
|
||||||
|
"raw": "top"
|
||||||
|
},
|
||||||
|
"values": [
|
||||||
|
{
|
||||||
|
"type": "Number",
|
||||||
|
"span": {
|
||||||
|
"start": 51,
|
||||||
|
"end": 52,
|
||||||
|
"ctxt": 0
|
||||||
|
},
|
||||||
|
"value": 0.0
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"important": null
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
@ -6,7 +6,7 @@ edition = "2018"
|
|||||||
license = "Apache-2.0/MIT"
|
license = "Apache-2.0/MIT"
|
||||||
name = "swc_stylis"
|
name = "swc_stylis"
|
||||||
repository = "https://github.com/swc-project/swc.git"
|
repository = "https://github.com/swc-project/swc.git"
|
||||||
version = "0.14.0"
|
version = "0.15.0"
|
||||||
|
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
@ -18,6 +18,6 @@ swc_css_utils = {version = "0.13.0", path = "../utils/"}
|
|||||||
swc_css_visit = {version = "0.15.0", path = "../visit"}
|
swc_css_visit = {version = "0.15.0", path = "../visit"}
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
swc_css_codegen = {version = "0.15.0", path = "../codegen"}
|
swc_css_codegen = {version = "0.16.0", path = "../codegen"}
|
||||||
swc_css_parser = {version = "0.17.0", path = "../parser"}
|
swc_css_parser = {version = "0.18.0", path = "../parser"}
|
||||||
testing = {version = "0.14.0", path = "../../testing"}
|
testing = {version = "0.14.0", path = "../../testing"}
|
||||||
|
Loading…
Reference in New Issue
Block a user