mirror of
https://github.com/swc-project/swc.git
synced 2024-12-03 00:54:25 +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]]
|
||||
name = "swc_css"
|
||||
version = "0.17.0"
|
||||
version = "0.18.0"
|
||||
dependencies = [
|
||||
"swc_css_ast",
|
||||
"swc_css_codegen",
|
||||
@ -2522,7 +2522,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "swc_css_codegen"
|
||||
version = "0.15.0"
|
||||
version = "0.16.0"
|
||||
dependencies = [
|
||||
"auto_impl",
|
||||
"bitflags",
|
||||
@ -2548,7 +2548,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "swc_css_parser"
|
||||
version = "0.17.0"
|
||||
version = "0.18.0"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"lexical",
|
||||
@ -3142,7 +3142,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "swc_stylis"
|
||||
version = "0.14.0"
|
||||
version = "0.15.0"
|
||||
dependencies = [
|
||||
"swc_atoms 0.2.8",
|
||||
"swc_common",
|
||||
|
@ -6,11 +6,11 @@ edition = "2018"
|
||||
license = "Apache-2.0/MIT"
|
||||
name = "swc_css"
|
||||
repository = "https://github.com/swc-project/swc.git"
|
||||
version = "0.17.0"
|
||||
version = "0.18.0"
|
||||
|
||||
[dependencies]
|
||||
swc_css_ast = {version = "0.16.0", path = "./ast"}
|
||||
swc_css_codegen = {version = "0.15.0", path = "./codegen"}
|
||||
swc_css_parser = {version = "0.17.0", path = "./parser"}
|
||||
swc_css_codegen = {version = "0.16.0", path = "./codegen"}
|
||||
swc_css_parser = {version = "0.18.0", path = "./parser"}
|
||||
swc_css_utils = {version = "0.13.0", path = "./utils/"}
|
||||
swc_css_visit = {version = "0.15.0", path = "./visit"}
|
||||
|
@ -6,7 +6,7 @@ edition = "2018"
|
||||
license = "Apache-2.0/MIT"
|
||||
name = "swc_css_codegen"
|
||||
repository = "https://github.com/swc-project/swc.git"
|
||||
version = "0.15.0"
|
||||
version = "0.16.0"
|
||||
|
||||
[dependencies]
|
||||
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/"}
|
||||
|
||||
[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"}
|
||||
testing = {version = "0.14.0", path = "../../testing"}
|
||||
|
@ -19,8 +19,15 @@ fn parse_again(input: PathBuf) {
|
||||
eprintln!("==== ==== Input ==== ====\n{}\n", fm.src);
|
||||
|
||||
let mut errors = vec![];
|
||||
let mut stylesheet: Stylesheet =
|
||||
parse_file(&fm, ParserConfig { parse_values: true }, &mut errors).unwrap();
|
||||
let mut stylesheet: Stylesheet = parse_file(
|
||||
&fm,
|
||||
ParserConfig {
|
||||
parse_values: true,
|
||||
..Default::default()
|
||||
},
|
||||
&mut errors,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
for err in take(&mut errors) {
|
||||
err.to_diagnostics(&handler).emit();
|
||||
@ -37,12 +44,17 @@ fn parse_again(input: PathBuf) {
|
||||
eprintln!("==== ==== Codegen ==== ====\n{}\n", css_str);
|
||||
|
||||
let new_fm = cm.new_source_file(FileName::Anon, css_str);
|
||||
let mut parsed: Stylesheet =
|
||||
parse_file(&new_fm, ParserConfig { parse_values: true }, &mut errors).map_err(
|
||||
|err| {
|
||||
err.to_diagnostics(&handler).emit();
|
||||
},
|
||||
)?;
|
||||
let mut parsed: Stylesheet = parse_file(
|
||||
&new_fm,
|
||||
ParserConfig {
|
||||
parse_values: true,
|
||||
..Default::default()
|
||||
},
|
||||
&mut errors,
|
||||
)
|
||||
.map_err(|err| {
|
||||
err.to_diagnostics(&handler).emit();
|
||||
})?;
|
||||
|
||||
for err in errors {
|
||||
err.to_diagnostics(&handler).emit();
|
||||
|
@ -6,7 +6,7 @@ edition = "2018"
|
||||
license = "Apache-2.0/MIT"
|
||||
name = "swc_css_parser"
|
||||
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
|
||||
|
||||
[features]
|
||||
|
@ -1,6 +1,6 @@
|
||||
use crate::{
|
||||
error::{Error, ErrorKind},
|
||||
parser::{input::ParserInput, PResult},
|
||||
parser::{input::ParserInput, PResult, ParserConfig},
|
||||
};
|
||||
use swc_atoms::{js_word, JsWord};
|
||||
use swc_common::{input::Input, BytePos, Span};
|
||||
@ -19,18 +19,20 @@ where
|
||||
start_pos: BytePos,
|
||||
/// Used to override last_pos
|
||||
last_pos: Option<BytePos>,
|
||||
config: ParserConfig,
|
||||
}
|
||||
|
||||
impl<I> Lexer<I>
|
||||
where
|
||||
I: Input,
|
||||
{
|
||||
pub fn new(input: I) -> Self {
|
||||
pub fn new(input: I, config: ParserConfig) -> Self {
|
||||
let start_pos = input.last_pos();
|
||||
Lexer {
|
||||
input,
|
||||
start_pos,
|
||||
last_pos: None,
|
||||
config,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -100,6 +102,15 @@ where
|
||||
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 {
|
||||
($b:tt,$tok:tt) => {{
|
||||
if self.input.eat_byte($b) {
|
||||
@ -755,6 +766,15 @@ where
|
||||
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(())
|
||||
}
|
||||
|
||||
@ -788,6 +808,29 @@ where
|
||||
|
||||
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)]
|
||||
|
@ -43,7 +43,7 @@ pub fn parse_str<'a, T>(
|
||||
where
|
||||
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 res = parser.parse();
|
||||
@ -63,7 +63,7 @@ pub fn parse_file<'a, T>(
|
||||
where
|
||||
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 res = parser.parse();
|
||||
|
@ -24,6 +24,13 @@ pub type PResult<T> = Result<T, Error>;
|
||||
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||
pub struct ParserConfig {
|
||||
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)]
|
||||
|
@ -27,9 +27,16 @@ impl Visit for AssertValid {
|
||||
|
||||
let mut errors = vec![];
|
||||
|
||||
let _selectors: Vec<ComplexSelector> =
|
||||
parse_tokens(&s.args, ParserConfig { parse_values: true }, &mut errors)
|
||||
.unwrap_or_else(|err| panic!("failed to parse tokens: {:?}\n{:?}", err, s.args));
|
||||
let _selectors: Vec<ComplexSelector> = parse_tokens(
|
||||
&s.args,
|
||||
ParserConfig {
|
||||
parse_values: true,
|
||||
|
||||
..Default::default()
|
||||
},
|
||||
&mut errors,
|
||||
)
|
||||
.unwrap_or_else(|err| panic!("failed to parse tokens: {:?}\n{:?}", err, s.args));
|
||||
|
||||
for err in errors {
|
||||
panic!("{:?}", err);
|
||||
@ -45,7 +52,7 @@ fn tokens_input(input: PathBuf) {
|
||||
let fm = cm.load_file(&input).unwrap();
|
||||
|
||||
let tokens = {
|
||||
let mut lexer = Lexer::new(SourceFileInput::from(&*fm));
|
||||
let mut lexer = Lexer::new(SourceFileInput::from(&*fm), Default::default());
|
||||
|
||||
let mut tokens = vec![];
|
||||
|
||||
@ -59,9 +66,16 @@ fn tokens_input(input: PathBuf) {
|
||||
};
|
||||
|
||||
let mut errors = vec![];
|
||||
let ss: Stylesheet =
|
||||
parse_tokens(&tokens, ParserConfig { parse_values: true }, &mut errors)
|
||||
.expect("failed to parse tokens");
|
||||
let ss: Stylesheet = parse_tokens(
|
||||
&tokens,
|
||||
ParserConfig {
|
||||
parse_values: true,
|
||||
|
||||
..Default::default()
|
||||
},
|
||||
&mut errors,
|
||||
)
|
||||
.expect("failed to parse tokens");
|
||||
|
||||
for err in errors {
|
||||
err.to_diagnostics(&handler).emit();
|
||||
@ -78,16 +92,15 @@ fn tokens_input(input: PathBuf) {
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
#[testing::fixture("tests/fixture/**/input.css")]
|
||||
fn pass(input: PathBuf) {
|
||||
fn test_pass(input: PathBuf, config: ParserConfig) {
|
||||
eprintln!("Input: {}", input.display());
|
||||
|
||||
testing::run_test2(false, |cm, handler| {
|
||||
let ref_json_path = input.parent().unwrap().join("output.json");
|
||||
|
||||
let fm = cm.load_file(&input).unwrap();
|
||||
let lexer = Lexer::new(SourceFileInput::from(&*fm));
|
||||
let mut parser = Parser::new(lexer, ParserConfig { parse_values: true });
|
||||
let lexer = Lexer::new(SourceFileInput::from(&*fm), config);
|
||||
let mut parser = Parser::new(lexer, config);
|
||||
|
||||
let stylesheet = parser.parse_all();
|
||||
|
||||
@ -99,8 +112,8 @@ fn pass(input: PathBuf) {
|
||||
|
||||
actual_json.clone().compare_to_file(&ref_json_path).unwrap();
|
||||
|
||||
{
|
||||
let mut lexer = Lexer::new(SourceFileInput::from(&*fm));
|
||||
if !config.allow_wrong_line_comments {
|
||||
let mut lexer = Lexer::new(SourceFileInput::from(&*fm), Default::default());
|
||||
let mut tokens = Tokens {
|
||||
span: Span::new(fm.start_pos, fm.end_pos, Default::default()),
|
||||
tokens: vec![],
|
||||
@ -123,9 +136,16 @@ fn pass(input: PathBuf) {
|
||||
}
|
||||
|
||||
let mut errors = vec![];
|
||||
let ss_tok: Stylesheet =
|
||||
parse_tokens(&tokens, ParserConfig { parse_values: true }, &mut errors)
|
||||
.expect("failed to parse token");
|
||||
let ss_tok: Stylesheet = parse_tokens(
|
||||
&tokens,
|
||||
ParserConfig {
|
||||
parse_values: true,
|
||||
|
||||
..Default::default()
|
||||
},
|
||||
&mut errors,
|
||||
)
|
||||
.expect("failed to parse token");
|
||||
|
||||
for err in errors {
|
||||
err.to_diagnostics(&handler).emit();
|
||||
@ -153,6 +173,29 @@ fn pass(input: PathBuf) {
|
||||
.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")]
|
||||
fn recovery(input: PathBuf) {
|
||||
eprintln!("Input: {}", input.display());
|
||||
@ -168,9 +211,13 @@ fn recovery(input: PathBuf) {
|
||||
|
||||
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 lexer = Lexer::new(SourceFileInput::from(&*fm));
|
||||
let mut parser = Parser::new(lexer, ParserConfig { parse_values: true });
|
||||
let lexer = Lexer::new(SourceFileInput::from(&*fm), config);
|
||||
let mut parser = Parser::new(lexer, config);
|
||||
|
||||
let stylesheet = parser.parse_all();
|
||||
|
||||
@ -183,7 +230,7 @@ fn recovery(input: PathBuf) {
|
||||
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 {
|
||||
span: Span::new(fm.start_pos, fm.end_pos, Default::default()),
|
||||
tokens: vec![],
|
||||
@ -206,9 +253,15 @@ fn recovery(input: PathBuf) {
|
||||
}
|
||||
|
||||
let mut errors = vec![];
|
||||
let ss_tok: Stylesheet =
|
||||
parse_tokens(&tokens, ParserConfig { parse_values: true }, &mut errors)
|
||||
.expect("failed to parse token");
|
||||
let ss_tok: Stylesheet = parse_tokens(
|
||||
&tokens,
|
||||
ParserConfig {
|
||||
parse_values: true,
|
||||
..Default::default()
|
||||
},
|
||||
&mut errors,
|
||||
)
|
||||
.expect("failed to parse token");
|
||||
|
||||
for err in errors {
|
||||
err.to_diagnostics(&handler).emit();
|
||||
@ -340,13 +393,19 @@ fn span(input: PathBuf) {
|
||||
let dir = input.parent().unwrap().to_path_buf();
|
||||
|
||||
let output = testing::run_test2(false, |cm, handler| {
|
||||
// Type annotation
|
||||
if false {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
let config = ParserConfig {
|
||||
parse_values: true,
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
let fm = cm.load_file(&input).unwrap();
|
||||
let lexer = Lexer::new(SourceFileInput::from(&*fm));
|
||||
let mut parser = Parser::new(lexer, ParserConfig { parse_values: true });
|
||||
let lexer = Lexer::new(SourceFileInput::from(&*fm), config);
|
||||
let mut parser = Parser::new(lexer, config);
|
||||
|
||||
let stylesheet = parser.parse_all();
|
||||
|
||||
@ -382,9 +441,15 @@ fn fail(input: PathBuf) {
|
||||
let stderr_path = input.parent().unwrap().join("output.stderr");
|
||||
|
||||
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 lexer = Lexer::new(SourceFileInput::from(&*fm));
|
||||
let mut parser = Parser::new(lexer, ParserConfig { parse_values: true });
|
||||
let lexer = Lexer::new(SourceFileInput::from(&*fm), config);
|
||||
let mut parser = Parser::new(lexer, config);
|
||||
|
||||
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"
|
||||
name = "swc_stylis"
|
||||
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
|
||||
|
||||
@ -18,6 +18,6 @@ swc_css_utils = {version = "0.13.0", path = "../utils/"}
|
||||
swc_css_visit = {version = "0.15.0", path = "../visit"}
|
||||
|
||||
[dev-dependencies]
|
||||
swc_css_codegen = {version = "0.15.0", path = "../codegen"}
|
||||
swc_css_parser = {version = "0.17.0", path = "../parser"}
|
||||
swc_css_codegen = {version = "0.16.0", path = "../codegen"}
|
||||
swc_css_parser = {version = "0.18.0", path = "../parser"}
|
||||
testing = {version = "0.14.0", path = "../../testing"}
|
||||
|
Loading…
Reference in New Issue
Block a user