perf(css/parser): Reduce number of function calls (#6587)

This commit is contained in:
Alexander Akait 2022-12-07 04:45:03 +03:00 committed by GitHub
parent 259eb87bd6
commit 252edb550b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 2078 additions and 166 deletions

View File

@ -21,7 +21,7 @@ where
cur_pos: BytePos,
start_pos: BytePos,
/// Used to override last_pos
last_pos: Option<BytePos>,
override_pos: Option<BytePos>,
config: ParserConfig,
buf: Rc<RefCell<String>>,
raw_buf: Rc<RefCell<String>>,
@ -41,7 +41,7 @@ where
cur: None,
cur_pos: start_pos,
start_pos,
last_pos: None,
override_pos: None,
config,
buf: Rc::new(RefCell::new(String::with_capacity(256))),
raw_buf: Rc::new(RefCell::new(String::with_capacity(256))),
@ -98,7 +98,10 @@ impl<I: Input> Iterator for Lexer<I> {
match token {
Ok(token) => {
let end = self.last_pos.take().unwrap_or_else(|| self.input.cur_pos());
let end = self
.override_pos
.take()
.unwrap_or_else(|| self.input.last_pos());
let span = Span::new(self.start_pos, end, Default::default());
let token_and_span = TokenAndSpan { span, token };
@ -124,12 +127,12 @@ where
type State = LexerState;
fn start_pos(&mut self) -> BytePos {
self.input.cur_pos()
self.input.last_pos()
}
fn state(&mut self) -> Self::State {
LexerState {
pos: self.input.cur_pos(),
pos: self.input.last_pos(),
}
}
@ -187,13 +190,17 @@ where
}
#[inline(always)]
fn consume(&mut self) {
self.cur = self.input.cur();
self.cur_pos = self.input.cur_pos();
fn consume(&mut self) -> Option<char> {
let cur = self.input.cur();
if self.cur.is_some() {
self.cur = cur;
self.cur_pos = self.input.last_pos();
if cur.is_some() {
self.input.bump();
}
cur
}
#[inline(always)]
@ -204,18 +211,17 @@ where
#[cold]
fn emit_error(&mut self, kind: ErrorKind) {
self.errors.borrow_mut().push(Error::new(
Span::new(self.cur_pos, self.input.cur_pos(), Default::default()),
Span::new(self.cur_pos, self.input.last_pos(), Default::default()),
kind,
));
}
fn consume_token(&mut self) -> LexResult<Token> {
self.read_comments();
self.start_pos = self.input.cur_pos();
self.consume();
self.start_pos = self.input.last_pos();
// Consume the next input code point.
match self.cur() {
match self.consume() {
// whitespace
// Consume as much whitespace as possible. Return a <whitespace-token>.
Some(c) if is_whitespace(c) => self.with_buf(|l, buf| {
@ -251,48 +257,25 @@ where
// If the next input code point is a name code point or the next two input code
// points are a valid escape, then:
if (first.is_some() && is_name(first.unwrap()))
|| self.is_valid_escape(first, second)?
|| self.is_valid_escape(first, second)
{
// Create a <hash-token>.
let mut hash_token = Token::Hash {
is_id: Default::default(),
value: Default::default(),
raw: Default::default(),
};
// If the next 3 input code points would start an identifier, set the
// <hash-token>s type flag to "id".
let third = self.next_next_next();
let is_would_start_ident = self.would_start_ident(first, second, third)?;
let is_would_start_ident = self.would_start_ident(first, second, third);
match hash_token {
Token::Hash { ref mut is_id, .. } => {
*is_id = is_would_start_ident;
}
_ => {
unreachable!();
}
}
// Consume a name, and set the <hash-token>s value to the returned string.
// Consume an ident sequence, and set the <hash-token>s value to the returned
// string.
let ident_sequence = self.read_ident_sequence()?;
match hash_token {
Token::Hash {
ref mut value,
ref mut raw,
..
} => {
*value = ident_sequence.0;
*raw = ident_sequence.1;
}
_ => {
unreachable!();
}
}
// Return the <hash-token>.
return Ok(hash_token);
return Ok(Token::Hash {
is_id: is_would_start_ident,
value: ident_sequence.0,
raw: ident_sequence.1,
});
}
Ok(Token::Delim { value: '#' })
@ -310,7 +293,7 @@ where
Some('+') => {
// If the input stream starts with a number, reconsume the current input code
// point, consume a numeric token and return it.
if self.would_start_number(None, None, None)? {
if self.would_start_number(None, None, None) {
self.reconsume();
return self.read_numeric();
@ -318,7 +301,7 @@ where
// Otherwise, return a <delim-token> with its value set to the current input
// code point.
Ok(Token::Delim { value: '+' })
Ok(tok!("+"))
}
// U+002C COMMA (,)
// Return a <comma-token>.
@ -327,7 +310,7 @@ where
Some('-') => {
// If the input stream starts with a number, reconsume the current input code
// point, consume a numeric token, and return it.
if self.would_start_number(None, None, None)? {
if self.would_start_number(None, None, None) {
self.reconsume();
return self.read_numeric();
@ -342,7 +325,7 @@ where
}
// Otherwise, if the input stream starts with an identifier, reconsume the current
// input code point, consume an ident-like token, and return it.
else if self.would_start_ident(None, None, None)? {
else if self.would_start_ident(None, None, None) {
self.reconsume();
return self.read_ident_like();
@ -350,13 +333,13 @@ where
// Otherwise, return a <delim-token> with its value set to the current input
// code point.
Ok(Token::Delim { value: '-' })
Ok(tok!("-"))
}
// U+002E FULL STOP (.)
Some('.') => {
// If the input stream starts with a number, reconsume the current input code
// point, consume a numeric token, and return it.
if self.would_start_number(None, None, None)? {
if self.would_start_number(None, None, None) {
self.reconsume();
return self.read_numeric();
@ -364,7 +347,7 @@ where
// Otherwise, return a <delim-token> with its value set to the current input
// code point.
Ok(Token::Delim { value: '.' })
Ok(tok!("."))
}
// U+003A COLON (:)
// Return a <colon-token>.
@ -390,7 +373,7 @@ where
// Otherwise, return a <delim-token> with its value set to the current input
// code point.
Ok(Token::Delim { value: '<' })
Ok(tok!("<"))
}
// U+0040 COMMERCIAL AT (@)
Some('@') => {
@ -401,7 +384,7 @@ where
// If the next 3 input code points would start an identifier, consume a name,
// create an <at-keyword-token> with its value set to the returned value, and
// return it.
if self.would_start_ident(first, second, third)? {
if self.would_start_ident(first, second, third) {
let ident_sequence = self.read_ident_sequence()?;
return Ok(Token::AtKeyword {
@ -421,7 +404,7 @@ where
Some('\\') => {
// If the input stream starts with a valid escape, reconsume the current input
// code point, consume an ident-like token, and return it.
if self.is_valid_escape(None, None)? {
if self.is_valid_escape(None, None) {
self.reconsume();
return self.read_ident_like();
@ -480,17 +463,18 @@ where
self.consume(); // '/'
loop {
self.consume();
match self.cur() {
match self.consume() {
Some('*') if self.next() == Some('/') => {
self.consume(); // '/'
break;
}
None => {
let end = self.last_pos.take().unwrap_or_else(|| self.input.cur_pos());
let span = Span::new(self.start_pos, end, Default::default());
let span = Span::new(
self.start_pos,
self.input.last_pos(),
Default::default(),
);
self.errors
.borrow_mut()
@ -511,9 +495,7 @@ where
self.consume(); // '/'
loop {
self.consume();
match self.cur() {
match self.consume() {
Some(c) if is_newline(c) => {
break;
}
@ -537,7 +519,7 @@ where
let next_third = self.next_next_next();
// If the next 3 input code points would start an identifier, then:
if self.would_start_ident(next_first, next_second, next_third)? {
if self.would_start_ident(next_first, next_second, next_third) {
// Swap logic to avoid create empty strings, because it doesn't make sense
//
// Consume a name. Set the <dimension-token>s unit to the returned value.
@ -587,7 +569,7 @@ where
if ident_sequence.0.to_ascii_lowercase() == js_word!("url") && self.next() == Some('(') {
self.consume();
let start_whitespace = self.input.cur_pos();
let start_whitespace = self.input.last_pos();
// While the next two input code points are whitespace, consume the next input
// code point.
@ -616,7 +598,7 @@ where
{
// Override last position because we consumed whitespaces, but they
// should not be part of token
self.last_pos = Some(start_whitespace);
self.override_pos = Some(start_whitespace);
return Ok(Token::Function {
value: ident_sequence.0,
@ -670,9 +652,7 @@ where
// Repeatedly consume the next input code point from the stream:
loop {
l.consume();
match l.cur() {
match l.consume() {
// ending code point
// Return the <string-token>.
Some(c) if c == ending_code_point.unwrap() => {
@ -722,7 +702,7 @@ where
// Otherwise, (the stream starts with a valid escape) consume an escaped
// code point and append the returned code point to
// the <string-token>s value.
else if l.is_valid_escape(None, None)? {
else if l.is_valid_escape(None, None) {
let escape = l.read_escape()?;
buf.push(escape.0);
@ -767,9 +747,7 @@ where
// Repeatedly consume the next input code point from the stream:
loop {
l.consume();
match l.cur() {
match l.consume() {
// U+0029 RIGHT PARENTHESIS ())
// Return the <url-token>.
Some(')') => {
@ -873,7 +851,7 @@ where
// If the stream starts with a valid escape, consume an escaped code point
// and append the returned code point to the
// <url-token>s value.
if l.is_valid_escape(None, None)? {
if l.is_valid_escape(None, None) {
let escaped = l.read_escape()?;
out.push(escaped.0);
@ -915,9 +893,7 @@ where
fn read_escape(&mut self) -> LexResult<(char, String)> {
self.with_sub_buf(|l, buf| {
// Consume the next input code point.
l.consume();
match l.cur() {
match l.consume() {
// hex digit
Some(c) if is_hex_digit(c) => {
let mut hex = c.to_digit(16).unwrap();
@ -994,21 +970,17 @@ where
// or can be called with the input stream itself. In the latter case, the two
// code points in question are the current input code point and the next input
// code point, in that order.
fn is_valid_escape(
&mut self,
maybe_first: Option<char>,
maybe_second: Option<char>,
) -> LexResult<bool> {
fn is_valid_escape(&mut self, maybe_first: Option<char>, maybe_second: Option<char>) -> bool {
// If the first code point is not U+005C REVERSE SOLIDUS (\), return false.
if maybe_first.or_else(|| self.cur()) != Some('\\') {
return Ok(false);
return false;
}
match maybe_second.or_else(|| self.next()) {
// Otherwise, if the second code point is a newline, return false.
Some(second) => Ok(!is_newline(second)),
Some(second) => !is_newline(second),
// Otherwise, return true.
None => Ok(false),
None => false,
}
}
@ -1023,7 +995,7 @@ where
maybe_first: Option<char>,
maybe_second: Option<char>,
maybe_third: Option<char>,
) -> LexResult<bool> {
) -> bool {
// Look at the first code point:
let first = maybe_first.or_else(|| self.cur());
@ -1035,10 +1007,10 @@ where
match second {
// If the second code point is a name-start code point
// return true.
Some(c) if is_name_start(c) => Ok(true),
Some(c) if is_name_start(c) => true,
// or a U+002D HYPHEN-MINUS,
// return true.
Some('-') => Ok(true),
Some('-') => true,
// or the second and third code points are a valid escape
// return true.
Some(_) => {
@ -1047,21 +1019,21 @@ where
self.is_valid_escape(second, third)
}
// Otherwise, return false.
_ => Ok(false),
_ => false,
}
}
// name-start code point
// Return true.
Some(c) if is_name_start(c) => Ok(true),
Some(c) if is_name_start(c) => true,
// U+005C REVERSE SOLIDUS (\)
// If the first and second code points are a valid escape, return true. Otherwise,
// return false.
Some('\\') => {
let second = maybe_second.or_else(|| self.next());
Ok(self.is_valid_escape(first, second)?)
self.is_valid_escape(first, second)
}
_ => Ok(false),
_ => false,
}
}
@ -1077,7 +1049,7 @@ where
maybe_first: Option<char>,
maybe_second: Option<char>,
maybe_third: Option<char>,
) -> LexResult<bool> {
) -> bool {
// Look at the first code point:
let first = maybe_first.or_else(|| self.cur());
@ -1087,20 +1059,20 @@ where
Some('+') | Some('-') => {
match maybe_second.or_else(|| self.next()) {
// If the second code point is a digit, return true.
Some(second) if second.is_ascii_digit() => return Ok(true),
Some(second) if second.is_ascii_digit() => return true,
// Otherwise, if the second code point is a U+002E FULL STOP (.) and the
// third code point is a digit, return true.
Some('.') => {
if let Some(third) = maybe_third.or_else(|| self.next_next()) {
if third.is_ascii_digit() {
return Ok(true);
return true;
}
}
return Ok(false);
return false;
}
// Otherwise, return false.
_ => return Ok(false),
_ => return false,
};
}
// U+002E FULL STOP (.)
@ -1108,19 +1080,19 @@ where
// If the second code point is a digit, return true.
if let Some(second) = self.next() {
if second.is_ascii_digit() {
return Ok(true);
return true;
}
}
// Otherwise, return false.
Ok(false)
false
}
// digit
// Return true.
Some(first) if first.is_ascii_digit() => Ok(true),
Some(first) if first.is_ascii_digit() => true,
// anything else
// Return false.
_ => Ok(false),
_ => false,
}
}
@ -1135,9 +1107,7 @@ where
// Repeatedly consume the next input code point from the stream:
loop {
l.consume();
match l.cur() {
match l.consume() {
// name code point
// Append the code point to result.
Some(c) if is_name(c) => {
@ -1146,7 +1116,7 @@ where
}
// the stream starts with a valid escape
// Consume an escaped code point. Append the returned code point to result.
Some(c) if l.is_valid_escape(None, None)? => {
Some(c) if l.is_valid_escape(None, None) => {
let escaped = l.read_escape()?;
buf.push(escaped.0);
@ -1291,9 +1261,7 @@ where
self.with_sub_buf(|l, raw| {
// Repeatedly consume the next input code point from the stream:
loop {
l.consume();
match l.cur() {
match l.consume() {
// U+0029 RIGHT PARENTHESIS ())
// EOF
// Return.
@ -1306,7 +1274,7 @@ where
break;
}
// the input stream starts with a valid escape
Some(c) if l.is_valid_escape(None, None) == Ok(true) => {
Some(c) if l.is_valid_escape(None, None) => {
// Consume an escaped code point. This allows an escaped right parenthesis
// ("\)") to be encountered without ending the <bad-url-token>.
let escaped = l.read_escape()?;

View File

@ -35,12 +35,12 @@ macro_rules! tok {
swc_css_ast::Token::BadUrl { .. }
};
("[") => {
swc_css_ast::Token::LBracket
("{") => {
swc_css_ast::Token::LBrace
};
("]") => {
swc_css_ast::Token::RBracket
("}") => {
swc_css_ast::Token::RBrace
};
("(") => {
@ -51,8 +51,12 @@ macro_rules! tok {
swc_css_ast::Token::RParen
};
("%") => {
swc_css_ast::Token::Delim { value: '%', .. }
("[") => {
swc_css_ast::Token::LBracket
};
("]") => {
swc_css_ast::Token::RBracket
};
(",") => {
@ -63,28 +67,8 @@ macro_rules! tok {
swc_css_ast::Token::Semi
};
("!") => {
swc_css_ast::Token::Delim { value: '!', .. }
};
("?") => {
swc_css_ast::Token::Delim { value: '?', .. }
};
("{") => {
swc_css_ast::Token::LBrace
};
("}") => {
swc_css_ast::Token::RBrace
};
("[") => {
swc_css_ast::Token::LBracket
};
("]") => {
swc_css_ast::Token::RBracket
swc_css_ast::Token::Delim { value: '?' }
};
(":") => {
@ -92,7 +76,7 @@ macro_rules! tok {
};
("*") => {
swc_css_ast::Token::Delim { value: '*', .. }
swc_css_ast::Token::Delim { value: '*' }
};
("@") => {
@ -104,27 +88,27 @@ macro_rules! tok {
};
("&") => {
swc_css_ast::Token::Delim { value: '&', .. }
swc_css_ast::Token::Delim { value: '&' }
};
("|") => {
swc_css_ast::Token::Delim { value: '|', .. }
swc_css_ast::Token::Delim { value: '|' }
};
("$") => {
swc_css_ast::Token::Delim { value: '$', .. }
swc_css_ast::Token::Delim { value: '$' }
};
("^") => {
swc_css_ast::Token::Delim { value: '^', .. }
swc_css_ast::Token::Delim { value: '^' }
};
("~") => {
swc_css_ast::Token::Delim { value: '~', .. }
swc_css_ast::Token::Delim { value: '~' }
};
("=") => {
swc_css_ast::Token::Delim { value: '=', .. }
swc_css_ast::Token::Delim { value: '=' }
};
(" ") => {
@ -140,26 +124,26 @@ macro_rules! tok {
};
("+") => {
swc_css_ast::Token::Delim { value: '+', .. }
swc_css_ast::Token::Delim { value: '+' }
};
("-") => {
swc_css_ast::Token::Delim { value: '-', .. }
swc_css_ast::Token::Delim { value: '-' }
};
(".") => {
swc_css_ast::Token::Delim { value: '.', .. }
swc_css_ast::Token::Delim { value: '.' }
};
("/") => {
swc_css_ast::Token::Delim { value: '/', .. }
swc_css_ast::Token::Delim { value: '/' }
};
("<") => {
swc_css_ast::Token::Delim { value: '<', .. }
swc_css_ast::Token::Delim { value: '<' }
};
(">") => {
swc_css_ast::Token::Delim { value: '>', .. }
swc_css_ast::Token::Delim { value: '>' }
};
}

View File

@ -0,0 +1,6 @@
a { animation: test; }
a { animation: тест; }
a { animation: т\ест; }
a { animation: 😋; }
a { animation: \\😋; }
a { animation: \😋; }

View File

@ -0,0 +1,700 @@
{
"type": "Stylesheet",
"span": {
"start": 1,
"end": 151,
"ctxt": 0
},
"rules": [
{
"type": "QualifiedRule",
"span": {
"start": 1,
"end": 23,
"ctxt": 0
},
"prelude": {
"type": "SelectorList",
"span": {
"start": 1,
"end": 2,
"ctxt": 0
},
"children": [
{
"type": "ComplexSelector",
"span": {
"start": 1,
"end": 2,
"ctxt": 0
},
"children": [
{
"type": "CompoundSelector",
"span": {
"start": 1,
"end": 2,
"ctxt": 0
},
"nestingSelector": null,
"typeSelector": {
"type": "TagNameSelector",
"span": {
"start": 1,
"end": 2,
"ctxt": 0
},
"name": {
"type": "WqName",
"span": {
"start": 1,
"end": 2,
"ctxt": 0
},
"prefix": null,
"value": {
"type": "Ident",
"span": {
"start": 1,
"end": 2,
"ctxt": 0
},
"value": "a",
"raw": "a"
}
}
},
"subclassSelectors": []
}
]
}
]
},
"block": {
"type": "SimpleBlock",
"span": {
"start": 3,
"end": 23,
"ctxt": 0
},
"name": {
"type": "PreservedToken",
"span": {
"start": 3,
"end": 4,
"ctxt": 0
},
"token": "LBrace"
},
"value": [
{
"type": "Declaration",
"span": {
"start": 5,
"end": 20,
"ctxt": 0
},
"name": {
"type": "Ident",
"span": {
"start": 5,
"end": 14,
"ctxt": 0
},
"value": "animation",
"raw": "animation"
},
"value": [
{
"type": "Ident",
"span": {
"start": 16,
"end": 20,
"ctxt": 0
},
"value": "test",
"raw": "test"
}
],
"important": null
}
]
}
},
{
"type": "QualifiedRule",
"span": {
"start": 24,
"end": 50,
"ctxt": 0
},
"prelude": {
"type": "SelectorList",
"span": {
"start": 24,
"end": 25,
"ctxt": 0
},
"children": [
{
"type": "ComplexSelector",
"span": {
"start": 24,
"end": 25,
"ctxt": 0
},
"children": [
{
"type": "CompoundSelector",
"span": {
"start": 24,
"end": 25,
"ctxt": 0
},
"nestingSelector": null,
"typeSelector": {
"type": "TagNameSelector",
"span": {
"start": 24,
"end": 25,
"ctxt": 0
},
"name": {
"type": "WqName",
"span": {
"start": 24,
"end": 25,
"ctxt": 0
},
"prefix": null,
"value": {
"type": "Ident",
"span": {
"start": 24,
"end": 25,
"ctxt": 0
},
"value": "a",
"raw": "a"
}
}
},
"subclassSelectors": []
}
]
}
]
},
"block": {
"type": "SimpleBlock",
"span": {
"start": 26,
"end": 50,
"ctxt": 0
},
"name": {
"type": "PreservedToken",
"span": {
"start": 26,
"end": 27,
"ctxt": 0
},
"token": "LBrace"
},
"value": [
{
"type": "Declaration",
"span": {
"start": 28,
"end": 47,
"ctxt": 0
},
"name": {
"type": "Ident",
"span": {
"start": 28,
"end": 37,
"ctxt": 0
},
"value": "animation",
"raw": "animation"
},
"value": [
{
"type": "Ident",
"span": {
"start": 39,
"end": 47,
"ctxt": 0
},
"value": "тест",
"raw": "тест"
}
],
"important": null
}
]
}
},
{
"type": "QualifiedRule",
"span": {
"start": 51,
"end": 78,
"ctxt": 0
},
"prelude": {
"type": "SelectorList",
"span": {
"start": 51,
"end": 52,
"ctxt": 0
},
"children": [
{
"type": "ComplexSelector",
"span": {
"start": 51,
"end": 52,
"ctxt": 0
},
"children": [
{
"type": "CompoundSelector",
"span": {
"start": 51,
"end": 52,
"ctxt": 0
},
"nestingSelector": null,
"typeSelector": {
"type": "TagNameSelector",
"span": {
"start": 51,
"end": 52,
"ctxt": 0
},
"name": {
"type": "WqName",
"span": {
"start": 51,
"end": 52,
"ctxt": 0
},
"prefix": null,
"value": {
"type": "Ident",
"span": {
"start": 51,
"end": 52,
"ctxt": 0
},
"value": "a",
"raw": "a"
}
}
},
"subclassSelectors": []
}
]
}
]
},
"block": {
"type": "SimpleBlock",
"span": {
"start": 53,
"end": 78,
"ctxt": 0
},
"name": {
"type": "PreservedToken",
"span": {
"start": 53,
"end": 54,
"ctxt": 0
},
"token": "LBrace"
},
"value": [
{
"type": "Declaration",
"span": {
"start": 55,
"end": 75,
"ctxt": 0
},
"name": {
"type": "Ident",
"span": {
"start": 55,
"end": 64,
"ctxt": 0
},
"value": "animation",
"raw": "animation"
},
"value": [
{
"type": "Ident",
"span": {
"start": 66,
"end": 75,
"ctxt": 0
},
"value": "тест",
"raw": "т\\ест"
}
],
"important": null
}
]
}
},
{
"type": "QualifiedRule",
"span": {
"start": 79,
"end": 101,
"ctxt": 0
},
"prelude": {
"type": "SelectorList",
"span": {
"start": 79,
"end": 80,
"ctxt": 0
},
"children": [
{
"type": "ComplexSelector",
"span": {
"start": 79,
"end": 80,
"ctxt": 0
},
"children": [
{
"type": "CompoundSelector",
"span": {
"start": 79,
"end": 80,
"ctxt": 0
},
"nestingSelector": null,
"typeSelector": {
"type": "TagNameSelector",
"span": {
"start": 79,
"end": 80,
"ctxt": 0
},
"name": {
"type": "WqName",
"span": {
"start": 79,
"end": 80,
"ctxt": 0
},
"prefix": null,
"value": {
"type": "Ident",
"span": {
"start": 79,
"end": 80,
"ctxt": 0
},
"value": "a",
"raw": "a"
}
}
},
"subclassSelectors": []
}
]
}
]
},
"block": {
"type": "SimpleBlock",
"span": {
"start": 81,
"end": 101,
"ctxt": 0
},
"name": {
"type": "PreservedToken",
"span": {
"start": 81,
"end": 82,
"ctxt": 0
},
"token": "LBrace"
},
"value": [
{
"type": "Declaration",
"span": {
"start": 83,
"end": 98,
"ctxt": 0
},
"name": {
"type": "Ident",
"span": {
"start": 83,
"end": 92,
"ctxt": 0
},
"value": "animation",
"raw": "animation"
},
"value": [
{
"type": "Ident",
"span": {
"start": 94,
"end": 98,
"ctxt": 0
},
"value": "😋",
"raw": "😋"
}
],
"important": null
}
]
}
},
{
"type": "QualifiedRule",
"span": {
"start": 102,
"end": 126,
"ctxt": 0
},
"prelude": {
"type": "SelectorList",
"span": {
"start": 102,
"end": 103,
"ctxt": 0
},
"children": [
{
"type": "ComplexSelector",
"span": {
"start": 102,
"end": 103,
"ctxt": 0
},
"children": [
{
"type": "CompoundSelector",
"span": {
"start": 102,
"end": 103,
"ctxt": 0
},
"nestingSelector": null,
"typeSelector": {
"type": "TagNameSelector",
"span": {
"start": 102,
"end": 103,
"ctxt": 0
},
"name": {
"type": "WqName",
"span": {
"start": 102,
"end": 103,
"ctxt": 0
},
"prefix": null,
"value": {
"type": "Ident",
"span": {
"start": 102,
"end": 103,
"ctxt": 0
},
"value": "a",
"raw": "a"
}
}
},
"subclassSelectors": []
}
]
}
]
},
"block": {
"type": "SimpleBlock",
"span": {
"start": 104,
"end": 126,
"ctxt": 0
},
"name": {
"type": "PreservedToken",
"span": {
"start": 104,
"end": 105,
"ctxt": 0
},
"token": "LBrace"
},
"value": [
{
"type": "Declaration",
"span": {
"start": 106,
"end": 123,
"ctxt": 0
},
"name": {
"type": "Ident",
"span": {
"start": 106,
"end": 115,
"ctxt": 0
},
"value": "animation",
"raw": "animation"
},
"value": [
{
"type": "Ident",
"span": {
"start": 117,
"end": 123,
"ctxt": 0
},
"value": "\\😋",
"raw": "\\\\😋"
}
],
"important": null
}
]
}
},
{
"type": "QualifiedRule",
"span": {
"start": 127,
"end": 150,
"ctxt": 0
},
"prelude": {
"type": "SelectorList",
"span": {
"start": 127,
"end": 128,
"ctxt": 0
},
"children": [
{
"type": "ComplexSelector",
"span": {
"start": 127,
"end": 128,
"ctxt": 0
},
"children": [
{
"type": "CompoundSelector",
"span": {
"start": 127,
"end": 128,
"ctxt": 0
},
"nestingSelector": null,
"typeSelector": {
"type": "TagNameSelector",
"span": {
"start": 127,
"end": 128,
"ctxt": 0
},
"name": {
"type": "WqName",
"span": {
"start": 127,
"end": 128,
"ctxt": 0
},
"prefix": null,
"value": {
"type": "Ident",
"span": {
"start": 127,
"end": 128,
"ctxt": 0
},
"value": "a",
"raw": "a"
}
}
},
"subclassSelectors": []
}
]
}
]
},
"block": {
"type": "SimpleBlock",
"span": {
"start": 129,
"end": 150,
"ctxt": 0
},
"name": {
"type": "PreservedToken",
"span": {
"start": 129,
"end": 130,
"ctxt": 0
},
"token": "LBrace"
},
"value": [
{
"type": "Declaration",
"span": {
"start": 131,
"end": 147,
"ctxt": 0
},
"name": {
"type": "Ident",
"span": {
"start": 131,
"end": 140,
"ctxt": 0
},
"value": "animation",
"raw": "animation"
},
"value": [
{
"type": "Ident",
"span": {
"start": 142,
"end": 147,
"ctxt": 0
},
"value": "😋",
"raw": "\\😋"
}
],
"important": null
}
]
}
}
]
}

View File

@ -0,0 +1,838 @@
x Stylesheet
,-[$DIR/tests/fixture/value/ident/input.css:1:1]
1 | ,-> a { animation: test; }
2 | | a { animation: тест; }
3 | | a { animation: т\ест; }
4 | | a { animation: 😋; }
5 | | a { animation: \\😋; }
6 | `-> a { animation: \😋; }
`----
x Rule
,-[$DIR/tests/fixture/value/ident/input.css:1:1]
1 | a { animation: test; }
: ^^^^^^^^^^^^^^^^^^^^^^
2 | a { animation: тест; }
`----
x QualifiedRule
,-[$DIR/tests/fixture/value/ident/input.css:1:1]
1 | a { animation: test; }
: ^^^^^^^^^^^^^^^^^^^^^^
2 | a { animation: тест; }
`----
x SelectorList
,-[$DIR/tests/fixture/value/ident/input.css:1:1]
1 | a { animation: test; }
: ^
2 | a { animation: тест; }
`----
x ComplexSelector
,-[$DIR/tests/fixture/value/ident/input.css:1:1]
1 | a { animation: test; }
: ^
2 | a { animation: тест; }
`----
x CompoundSelector
,-[$DIR/tests/fixture/value/ident/input.css:1:1]
1 | a { animation: test; }
: ^
2 | a { animation: тест; }
`----
x TypeSelector
,-[$DIR/tests/fixture/value/ident/input.css:1:1]
1 | a { animation: test; }
: ^
2 | a { animation: тест; }
`----
x TagNameSelector
,-[$DIR/tests/fixture/value/ident/input.css:1:1]
1 | a { animation: test; }
: ^
2 | a { animation: тест; }
`----
x WqName
,-[$DIR/tests/fixture/value/ident/input.css:1:1]
1 | a { animation: test; }
: ^
2 | a { animation: тест; }
`----
x Ident
,-[$DIR/tests/fixture/value/ident/input.css:1:1]
1 | a { animation: test; }
: ^
2 | a { animation: тест; }
`----
x SimpleBlock
,-[$DIR/tests/fixture/value/ident/input.css:1:1]
1 | a { animation: test; }
: ^^^^^^^^^^^^^^^^^^^^
2 | a { animation: тест; }
`----
x LBrace
,-[$DIR/tests/fixture/value/ident/input.css:1:1]
1 | a { animation: test; }
: ^
2 | a { animation: тест; }
`----
x ComponentValue
,-[$DIR/tests/fixture/value/ident/input.css:1:1]
1 | a { animation: test; }
: ^^^^^^^^^^^^^^^
2 | a { animation: тест; }
`----
x StyleBlock
,-[$DIR/tests/fixture/value/ident/input.css:1:1]
1 | a { animation: test; }
: ^^^^^^^^^^^^^^^
2 | a { animation: тест; }
`----
x Declaration
,-[$DIR/tests/fixture/value/ident/input.css:1:1]
1 | a { animation: test; }
: ^^^^^^^^^^^^^^^
2 | a { animation: тест; }
`----
x DeclarationName
,-[$DIR/tests/fixture/value/ident/input.css:1:1]
1 | a { animation: test; }
: ^^^^^^^^^
2 | a { animation: тест; }
`----
x Ident
,-[$DIR/tests/fixture/value/ident/input.css:1:1]
1 | a { animation: test; }
: ^^^^^^^^^
2 | a { animation: тест; }
`----
x ComponentValue
,-[$DIR/tests/fixture/value/ident/input.css:1:1]
1 | a { animation: test; }
: ^^^^
2 | a { animation: тест; }
`----
x Ident
,-[$DIR/tests/fixture/value/ident/input.css:1:1]
1 | a { animation: test; }
: ^^^^
2 | a { animation: тест; }
`----
x Rule
,-[$DIR/tests/fixture/value/ident/input.css:1:1]
1 | a { animation: test; }
2 | a { animation: тест; }
: ^^^^^^^^^^^^^^^^^^^^^^^^^^
3 | a { animation: т\ест; }
`----
x QualifiedRule
,-[$DIR/tests/fixture/value/ident/input.css:1:1]
1 | a { animation: test; }
2 | a { animation: тест; }
: ^^^^^^^^^^^^^^^^^^^^^^^^^^
3 | a { animation: т\ест; }
`----
x SelectorList
,-[$DIR/tests/fixture/value/ident/input.css:1:1]
1 | a { animation: test; }
2 | a { animation: тест; }
: ^
3 | a { animation: т\ест; }
`----
x ComplexSelector
,-[$DIR/tests/fixture/value/ident/input.css:1:1]
1 | a { animation: test; }
2 | a { animation: тест; }
: ^
3 | a { animation: т\ест; }
`----
x CompoundSelector
,-[$DIR/tests/fixture/value/ident/input.css:1:1]
1 | a { animation: test; }
2 | a { animation: тест; }
: ^
3 | a { animation: т\ест; }
`----
x TypeSelector
,-[$DIR/tests/fixture/value/ident/input.css:1:1]
1 | a { animation: test; }
2 | a { animation: тест; }
: ^
3 | a { animation: т\ест; }
`----
x TagNameSelector
,-[$DIR/tests/fixture/value/ident/input.css:1:1]
1 | a { animation: test; }
2 | a { animation: тест; }
: ^
3 | a { animation: т\ест; }
`----
x WqName
,-[$DIR/tests/fixture/value/ident/input.css:1:1]
1 | a { animation: test; }
2 | a { animation: тест; }
: ^
3 | a { animation: т\ест; }
`----
x Ident
,-[$DIR/tests/fixture/value/ident/input.css:1:1]
1 | a { animation: test; }
2 | a { animation: тест; }
: ^
3 | a { animation: т\ест; }
`----
x SimpleBlock
,-[$DIR/tests/fixture/value/ident/input.css:1:1]
1 | a { animation: test; }
2 | a { animation: тест; }
: ^^^^^^^^^^^^^^^^^^^^^^^^
3 | a { animation: т\ест; }
`----
x LBrace
,-[$DIR/tests/fixture/value/ident/input.css:1:1]
1 | a { animation: test; }
2 | a { animation: тест; }
: ^
3 | a { animation: т\ест; }
`----
x ComponentValue
,-[$DIR/tests/fixture/value/ident/input.css:1:1]
1 | a { animation: test; }
2 | a { animation: тест; }
: ^^^^^^^^^^^^^^^^^^^
3 | a { animation: т\ест; }
`----
x StyleBlock
,-[$DIR/tests/fixture/value/ident/input.css:1:1]
1 | a { animation: test; }
2 | a { animation: тест; }
: ^^^^^^^^^^^^^^^^^^^
3 | a { animation: т\ест; }
`----
x Declaration
,-[$DIR/tests/fixture/value/ident/input.css:1:1]
1 | a { animation: test; }
2 | a { animation: тест; }
: ^^^^^^^^^^^^^^^^^^^
3 | a { animation: т\ест; }
`----
x DeclarationName
,-[$DIR/tests/fixture/value/ident/input.css:1:1]
1 | a { animation: test; }
2 | a { animation: тест; }
: ^^^^^^^^^
3 | a { animation: т\ест; }
`----
x Ident
,-[$DIR/tests/fixture/value/ident/input.css:1:1]
1 | a { animation: test; }
2 | a { animation: тест; }
: ^^^^^^^^^
3 | a { animation: т\ест; }
`----
x ComponentValue
,-[$DIR/tests/fixture/value/ident/input.css:1:1]
1 | a { animation: test; }
2 | a { animation: тест; }
: ^^^^^^^^
3 | a { animation: т\ест; }
`----
x Ident
,-[$DIR/tests/fixture/value/ident/input.css:1:1]
1 | a { animation: test; }
2 | a { animation: тест; }
: ^^^^^^^^
3 | a { animation: т\ест; }
`----
x Rule
,-[$DIR/tests/fixture/value/ident/input.css:2:1]
2 | a { animation: тест; }
3 | a { animation: т\ест; }
: ^^^^^^^^^^^^^^^^^^^^^^^^^^^
4 | a { animation: 😋; }
`----
x QualifiedRule
,-[$DIR/tests/fixture/value/ident/input.css:2:1]
2 | a { animation: тест; }
3 | a { animation: т\ест; }
: ^^^^^^^^^^^^^^^^^^^^^^^^^^^
4 | a { animation: 😋; }
`----
x SelectorList
,-[$DIR/tests/fixture/value/ident/input.css:2:1]
2 | a { animation: тест; }
3 | a { animation: т\ест; }
: ^
4 | a { animation: 😋; }
`----
x ComplexSelector
,-[$DIR/tests/fixture/value/ident/input.css:2:1]
2 | a { animation: тест; }
3 | a { animation: т\ест; }
: ^
4 | a { animation: 😋; }
`----
x CompoundSelector
,-[$DIR/tests/fixture/value/ident/input.css:2:1]
2 | a { animation: тест; }
3 | a { animation: т\ест; }
: ^
4 | a { animation: 😋; }
`----
x TypeSelector
,-[$DIR/tests/fixture/value/ident/input.css:2:1]
2 | a { animation: тест; }
3 | a { animation: т\ест; }
: ^
4 | a { animation: 😋; }
`----
x TagNameSelector
,-[$DIR/tests/fixture/value/ident/input.css:2:1]
2 | a { animation: тест; }
3 | a { animation: т\ест; }
: ^
4 | a { animation: 😋; }
`----
x WqName
,-[$DIR/tests/fixture/value/ident/input.css:2:1]
2 | a { animation: тест; }
3 | a { animation: т\ест; }
: ^
4 | a { animation: 😋; }
`----
x Ident
,-[$DIR/tests/fixture/value/ident/input.css:2:1]
2 | a { animation: тест; }
3 | a { animation: т\ест; }
: ^
4 | a { animation: 😋; }
`----
x SimpleBlock
,-[$DIR/tests/fixture/value/ident/input.css:2:1]
2 | a { animation: тест; }
3 | a { animation: т\ест; }
: ^^^^^^^^^^^^^^^^^^^^^^^^^
4 | a { animation: 😋; }
`----
x LBrace
,-[$DIR/tests/fixture/value/ident/input.css:2:1]
2 | a { animation: тест; }
3 | a { animation: т\ест; }
: ^
4 | a { animation: 😋; }
`----
x ComponentValue
,-[$DIR/tests/fixture/value/ident/input.css:2:1]
2 | a { animation: тест; }
3 | a { animation: т\ест; }
: ^^^^^^^^^^^^^^^^^^^^
4 | a { animation: 😋; }
`----
x StyleBlock
,-[$DIR/tests/fixture/value/ident/input.css:2:1]
2 | a { animation: тест; }
3 | a { animation: т\ест; }
: ^^^^^^^^^^^^^^^^^^^^
4 | a { animation: 😋; }
`----
x Declaration
,-[$DIR/tests/fixture/value/ident/input.css:2:1]
2 | a { animation: тест; }
3 | a { animation: т\ест; }
: ^^^^^^^^^^^^^^^^^^^^
4 | a { animation: 😋; }
`----
x DeclarationName
,-[$DIR/tests/fixture/value/ident/input.css:2:1]
2 | a { animation: тест; }
3 | a { animation: т\ест; }
: ^^^^^^^^^
4 | a { animation: 😋; }
`----
x Ident
,-[$DIR/tests/fixture/value/ident/input.css:2:1]
2 | a { animation: тест; }
3 | a { animation: т\ест; }
: ^^^^^^^^^
4 | a { animation: 😋; }
`----
x ComponentValue
,-[$DIR/tests/fixture/value/ident/input.css:2:1]
2 | a { animation: тест; }
3 | a { animation: т\ест; }
: ^^^^^^^^^
4 | a { animation: 😋; }
`----
x Ident
,-[$DIR/tests/fixture/value/ident/input.css:2:1]
2 | a { animation: тест; }
3 | a { animation: т\ест; }
: ^^^^^^^^^
4 | a { animation: 😋; }
`----
x Rule
,-[$DIR/tests/fixture/value/ident/input.css:3:1]
3 | a { animation: т\ест; }
4 | a { animation: 😋; }
: ^^^^^^^^^^^^^^^^^^^^^^
5 | a { animation: \\😋; }
`----
x QualifiedRule
,-[$DIR/tests/fixture/value/ident/input.css:3:1]
3 | a { animation: т\ест; }
4 | a { animation: 😋; }
: ^^^^^^^^^^^^^^^^^^^^^^
5 | a { animation: \\😋; }
`----
x SelectorList
,-[$DIR/tests/fixture/value/ident/input.css:3:1]
3 | a { animation: т\ест; }
4 | a { animation: 😋; }
: ^
5 | a { animation: \\😋; }
`----
x ComplexSelector
,-[$DIR/tests/fixture/value/ident/input.css:3:1]
3 | a { animation: т\ест; }
4 | a { animation: 😋; }
: ^
5 | a { animation: \\😋; }
`----
x CompoundSelector
,-[$DIR/tests/fixture/value/ident/input.css:3:1]
3 | a { animation: т\ест; }
4 | a { animation: 😋; }
: ^
5 | a { animation: \\😋; }
`----
x TypeSelector
,-[$DIR/tests/fixture/value/ident/input.css:3:1]
3 | a { animation: т\ест; }
4 | a { animation: 😋; }
: ^
5 | a { animation: \\😋; }
`----
x TagNameSelector
,-[$DIR/tests/fixture/value/ident/input.css:3:1]
3 | a { animation: т\ест; }
4 | a { animation: 😋; }
: ^
5 | a { animation: \\😋; }
`----
x WqName
,-[$DIR/tests/fixture/value/ident/input.css:3:1]
3 | a { animation: т\ест; }
4 | a { animation: 😋; }
: ^
5 | a { animation: \\😋; }
`----
x Ident
,-[$DIR/tests/fixture/value/ident/input.css:3:1]
3 | a { animation: т\ест; }
4 | a { animation: 😋; }
: ^
5 | a { animation: \\😋; }
`----
x SimpleBlock
,-[$DIR/tests/fixture/value/ident/input.css:3:1]
3 | a { animation: т\ест; }
4 | a { animation: 😋; }
: ^^^^^^^^^^^^^^^^^^^^
5 | a { animation: \\😋; }
`----
x LBrace
,-[$DIR/tests/fixture/value/ident/input.css:3:1]
3 | a { animation: т\ест; }
4 | a { animation: 😋; }
: ^
5 | a { animation: \\😋; }
`----
x ComponentValue
,-[$DIR/tests/fixture/value/ident/input.css:3:1]
3 | a { animation: т\ест; }
4 | a { animation: 😋; }
: ^^^^^^^^^^^^^^^
5 | a { animation: \\😋; }
`----
x StyleBlock
,-[$DIR/tests/fixture/value/ident/input.css:3:1]
3 | a { animation: т\ест; }
4 | a { animation: 😋; }
: ^^^^^^^^^^^^^^^
5 | a { animation: \\😋; }
`----
x Declaration
,-[$DIR/tests/fixture/value/ident/input.css:3:1]
3 | a { animation: т\ест; }
4 | a { animation: 😋; }
: ^^^^^^^^^^^^^^^
5 | a { animation: \\😋; }
`----
x DeclarationName
,-[$DIR/tests/fixture/value/ident/input.css:3:1]
3 | a { animation: т\ест; }
4 | a { animation: 😋; }
: ^^^^^^^^^
5 | a { animation: \\😋; }
`----
x Ident
,-[$DIR/tests/fixture/value/ident/input.css:3:1]
3 | a { animation: т\ест; }
4 | a { animation: 😋; }
: ^^^^^^^^^
5 | a { animation: \\😋; }
`----
x ComponentValue
,-[$DIR/tests/fixture/value/ident/input.css:3:1]
3 | a { animation: т\ест; }
4 | a { animation: 😋; }
: ^^^^
5 | a { animation: \\😋; }
`----
x Ident
,-[$DIR/tests/fixture/value/ident/input.css:3:1]
3 | a { animation: т\ест; }
4 | a { animation: 😋; }
: ^^^^
5 | a { animation: \\😋; }
`----
x Rule
,-[$DIR/tests/fixture/value/ident/input.css:4:1]
4 | a { animation: 😋; }
5 | a { animation: \\😋; }
: ^^^^^^^^^^^^^^^^^^^^^^^^
6 | a { animation: \😋; }
`----
x QualifiedRule
,-[$DIR/tests/fixture/value/ident/input.css:4:1]
4 | a { animation: 😋; }
5 | a { animation: \\😋; }
: ^^^^^^^^^^^^^^^^^^^^^^^^
6 | a { animation: \😋; }
`----
x SelectorList
,-[$DIR/tests/fixture/value/ident/input.css:4:1]
4 | a { animation: 😋; }
5 | a { animation: \\😋; }
: ^
6 | a { animation: \😋; }
`----
x ComplexSelector
,-[$DIR/tests/fixture/value/ident/input.css:4:1]
4 | a { animation: 😋; }
5 | a { animation: \\😋; }
: ^
6 | a { animation: \😋; }
`----
x CompoundSelector
,-[$DIR/tests/fixture/value/ident/input.css:4:1]
4 | a { animation: 😋; }
5 | a { animation: \\😋; }
: ^
6 | a { animation: \😋; }
`----
x TypeSelector
,-[$DIR/tests/fixture/value/ident/input.css:4:1]
4 | a { animation: 😋; }
5 | a { animation: \\😋; }
: ^
6 | a { animation: \😋; }
`----
x TagNameSelector
,-[$DIR/tests/fixture/value/ident/input.css:4:1]
4 | a { animation: 😋; }
5 | a { animation: \\😋; }
: ^
6 | a { animation: \😋; }
`----
x WqName
,-[$DIR/tests/fixture/value/ident/input.css:4:1]
4 | a { animation: 😋; }
5 | a { animation: \\😋; }
: ^
6 | a { animation: \😋; }
`----
x Ident
,-[$DIR/tests/fixture/value/ident/input.css:4:1]
4 | a { animation: 😋; }
5 | a { animation: \\😋; }
: ^
6 | a { animation: \😋; }
`----
x SimpleBlock
,-[$DIR/tests/fixture/value/ident/input.css:4:1]
4 | a { animation: 😋; }
5 | a { animation: \\😋; }
: ^^^^^^^^^^^^^^^^^^^^^^
6 | a { animation: \😋; }
`----
x LBrace
,-[$DIR/tests/fixture/value/ident/input.css:4:1]
4 | a { animation: 😋; }
5 | a { animation: \\😋; }
: ^
6 | a { animation: \😋; }
`----
x ComponentValue
,-[$DIR/tests/fixture/value/ident/input.css:4:1]
4 | a { animation: 😋; }
5 | a { animation: \\😋; }
: ^^^^^^^^^^^^^^^^^
6 | a { animation: \😋; }
`----
x StyleBlock
,-[$DIR/tests/fixture/value/ident/input.css:4:1]
4 | a { animation: 😋; }
5 | a { animation: \\😋; }
: ^^^^^^^^^^^^^^^^^
6 | a { animation: \😋; }
`----
x Declaration
,-[$DIR/tests/fixture/value/ident/input.css:4:1]
4 | a { animation: 😋; }
5 | a { animation: \\😋; }
: ^^^^^^^^^^^^^^^^^
6 | a { animation: \😋; }
`----
x DeclarationName
,-[$DIR/tests/fixture/value/ident/input.css:4:1]
4 | a { animation: 😋; }
5 | a { animation: \\😋; }
: ^^^^^^^^^
6 | a { animation: \😋; }
`----
x Ident
,-[$DIR/tests/fixture/value/ident/input.css:4:1]
4 | a { animation: 😋; }
5 | a { animation: \\😋; }
: ^^^^^^^^^
6 | a { animation: \😋; }
`----
x ComponentValue
,-[$DIR/tests/fixture/value/ident/input.css:4:1]
4 | a { animation: 😋; }
5 | a { animation: \\😋; }
: ^^^^^^
6 | a { animation: \😋; }
`----
x Ident
,-[$DIR/tests/fixture/value/ident/input.css:4:1]
4 | a { animation: 😋; }
5 | a { animation: \\😋; }
: ^^^^^^
6 | a { animation: \😋; }
`----
x Rule
,-[$DIR/tests/fixture/value/ident/input.css:5:1]
5 | a { animation: \\😋; }
6 | a { animation: \😋; }
: ^^^^^^^^^^^^^^^^^^^^^^^
`----
x QualifiedRule
,-[$DIR/tests/fixture/value/ident/input.css:5:1]
5 | a { animation: \\😋; }
6 | a { animation: \😋; }
: ^^^^^^^^^^^^^^^^^^^^^^^
`----
x SelectorList
,-[$DIR/tests/fixture/value/ident/input.css:5:1]
5 | a { animation: \\😋; }
6 | a { animation: \😋; }
: ^
`----
x ComplexSelector
,-[$DIR/tests/fixture/value/ident/input.css:5:1]
5 | a { animation: \\😋; }
6 | a { animation: \😋; }
: ^
`----
x CompoundSelector
,-[$DIR/tests/fixture/value/ident/input.css:5:1]
5 | a { animation: \\😋; }
6 | a { animation: \😋; }
: ^
`----
x TypeSelector
,-[$DIR/tests/fixture/value/ident/input.css:5:1]
5 | a { animation: \\😋; }
6 | a { animation: \😋; }
: ^
`----
x TagNameSelector
,-[$DIR/tests/fixture/value/ident/input.css:5:1]
5 | a { animation: \\😋; }
6 | a { animation: \😋; }
: ^
`----
x WqName
,-[$DIR/tests/fixture/value/ident/input.css:5:1]
5 | a { animation: \\😋; }
6 | a { animation: \😋; }
: ^
`----
x Ident
,-[$DIR/tests/fixture/value/ident/input.css:5:1]
5 | a { animation: \\😋; }
6 | a { animation: \😋; }
: ^
`----
x SimpleBlock
,-[$DIR/tests/fixture/value/ident/input.css:5:1]
5 | a { animation: \\😋; }
6 | a { animation: \😋; }
: ^^^^^^^^^^^^^^^^^^^^^
`----
x LBrace
,-[$DIR/tests/fixture/value/ident/input.css:5:1]
5 | a { animation: \\😋; }
6 | a { animation: \😋; }
: ^
`----
x ComponentValue
,-[$DIR/tests/fixture/value/ident/input.css:5:1]
5 | a { animation: \\😋; }
6 | a { animation: \😋; }
: ^^^^^^^^^^^^^^^^
`----
x StyleBlock
,-[$DIR/tests/fixture/value/ident/input.css:5:1]
5 | a { animation: \\😋; }
6 | a { animation: \😋; }
: ^^^^^^^^^^^^^^^^
`----
x Declaration
,-[$DIR/tests/fixture/value/ident/input.css:5:1]
5 | a { animation: \\😋; }
6 | a { animation: \😋; }
: ^^^^^^^^^^^^^^^^
`----
x DeclarationName
,-[$DIR/tests/fixture/value/ident/input.css:5:1]
5 | a { animation: \\😋; }
6 | a { animation: \😋; }
: ^^^^^^^^^
`----
x Ident
,-[$DIR/tests/fixture/value/ident/input.css:5:1]
5 | a { animation: \\😋; }
6 | a { animation: \😋; }
: ^^^^^^^^^
`----
x ComponentValue
,-[$DIR/tests/fixture/value/ident/input.css:5:1]
5 | a { animation: \\😋; }
6 | a { animation: \😋; }
: ^^^^^
`----
x Ident
,-[$DIR/tests/fixture/value/ident/input.css:5:1]
5 | a { animation: \\😋; }
6 | a { animation: \😋; }
: ^^^^^
`----

View File

@ -36,4 +36,5 @@ https://example.com/image.png
);
background: URL(https://example.com/ima\)ge.png);
background: url( "https://example.com/image.png" );
}

View File

@ -2,7 +2,7 @@
"type": "Stylesheet",
"span": {
"start": 1,
"end": 1336,
"end": 1396,
"ctxt": 0
},
"rules": [
@ -10,7 +10,7 @@
"type": "QualifiedRule",
"span": {
"start": 1,
"end": 1335,
"end": 1395,
"ctxt": 0
},
"prelude": {
@ -74,7 +74,7 @@
"type": "SimpleBlock",
"span": {
"start": 5,
"end": 1335,
"end": 1395,
"ctxt": 0
},
"name": {
@ -1426,6 +1426,56 @@
}
],
"important": null
},
{
"type": "Declaration",
"span": {
"start": 1338,
"end": 1392,
"ctxt": 0
},
"name": {
"type": "Ident",
"span": {
"start": 1338,
"end": 1348,
"ctxt": 0
},
"value": "background",
"raw": "background"
},
"value": [
{
"type": "Url",
"span": {
"start": 1350,
"end": 1392,
"ctxt": 0
},
"name": {
"type": "Ident",
"span": {
"start": 1350,
"end": 1353,
"ctxt": 0
},
"value": "url",
"raw": "url"
},
"value": {
"type": "String",
"span": {
"start": 1357,
"end": 1388,
"ctxt": 0
},
"value": "https://example.com/image.png",
"raw": "\"https://example.com/image.png\""
},
"modifiers": []
}
],
"important": null
}
]
}

View File

@ -39,7 +39,8 @@
36 | |
37 | | );
38 | | background: URL(https://example.com/ima\)ge.png);
39 | `-> }
39 | | background: url( "https://example.com/image.png" );
40 | `-> }
`----
x Rule
@ -82,7 +83,8 @@
36 | |
37 | | );
38 | | background: URL(https://example.com/ima\)ge.png);
39 | `-> }
39 | | background: url( "https://example.com/image.png" );
40 | `-> }
`----
x QualifiedRule
@ -125,7 +127,8 @@
36 | |
37 | | );
38 | | background: URL(https://example.com/ima\)ge.png);
39 | `-> }
39 | | background: url( "https://example.com/image.png" );
40 | `-> }
`----
x SelectorList
@ -217,7 +220,8 @@
36 | |
37 | | );
38 | | background: URL(https://example.com/ima\)ge.png);
39 | `-> }
39 | | background: url( "https://example.com/image.png" );
40 | `-> }
`----
x LBrace
@ -2248,7 +2252,7 @@
37 | );
38 | background: URL(https://example.com/ima\)ge.png);
: ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
39 | }
39 | background: url( "https://example.com/image.png" );
`----
x StyleBlock
@ -2256,7 +2260,7 @@
37 | );
38 | background: URL(https://example.com/ima\)ge.png);
: ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
39 | }
39 | background: url( "https://example.com/image.png" );
`----
x Declaration
@ -2264,7 +2268,7 @@
37 | );
38 | background: URL(https://example.com/ima\)ge.png);
: ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
39 | }
39 | background: url( "https://example.com/image.png" );
`----
x DeclarationName
@ -2272,7 +2276,7 @@
37 | );
38 | background: URL(https://example.com/ima\)ge.png);
: ^^^^^^^^^^
39 | }
39 | background: url( "https://example.com/image.png" );
`----
x Ident
@ -2280,7 +2284,7 @@
37 | );
38 | background: URL(https://example.com/ima\)ge.png);
: ^^^^^^^^^^
39 | }
39 | background: url( "https://example.com/image.png" );
`----
x ComponentValue
@ -2288,7 +2292,7 @@
37 | );
38 | background: URL(https://example.com/ima\)ge.png);
: ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
39 | }
39 | background: url( "https://example.com/image.png" );
`----
x Url
@ -2296,7 +2300,7 @@
37 | );
38 | background: URL(https://example.com/ima\)ge.png);
: ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
39 | }
39 | background: url( "https://example.com/image.png" );
`----
x Ident
@ -2304,7 +2308,7 @@
37 | );
38 | background: URL(https://example.com/ima\)ge.png);
: ^^^
39 | }
39 | background: url( "https://example.com/image.png" );
`----
x UrlValue
@ -2312,7 +2316,7 @@
37 | );
38 | background: URL(https://example.com/ima\)ge.png);
: ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
39 | }
39 | background: url( "https://example.com/image.png" );
`----
x UrlValueRaw
@ -2320,5 +2324,85 @@
37 | );
38 | background: URL(https://example.com/ima\)ge.png);
: ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
39 | }
39 | background: url( "https://example.com/image.png" );
`----
x ComponentValue
,-[$DIR/tests/fixture/value/url/input.css:38:1]
38 | background: URL(https://example.com/ima\)ge.png);
39 | background: url( "https://example.com/image.png" );
: ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
40 | }
`----
x StyleBlock
,-[$DIR/tests/fixture/value/url/input.css:38:1]
38 | background: URL(https://example.com/ima\)ge.png);
39 | background: url( "https://example.com/image.png" );
: ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
40 | }
`----
x Declaration
,-[$DIR/tests/fixture/value/url/input.css:38:1]
38 | background: URL(https://example.com/ima\)ge.png);
39 | background: url( "https://example.com/image.png" );
: ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
40 | }
`----
x DeclarationName
,-[$DIR/tests/fixture/value/url/input.css:38:1]
38 | background: URL(https://example.com/ima\)ge.png);
39 | background: url( "https://example.com/image.png" );
: ^^^^^^^^^^
40 | }
`----
x Ident
,-[$DIR/tests/fixture/value/url/input.css:38:1]
38 | background: URL(https://example.com/ima\)ge.png);
39 | background: url( "https://example.com/image.png" );
: ^^^^^^^^^^
40 | }
`----
x ComponentValue
,-[$DIR/tests/fixture/value/url/input.css:38:1]
38 | background: URL(https://example.com/ima\)ge.png);
39 | background: url( "https://example.com/image.png" );
: ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
40 | }
`----
x Url
,-[$DIR/tests/fixture/value/url/input.css:38:1]
38 | background: URL(https://example.com/ima\)ge.png);
39 | background: url( "https://example.com/image.png" );
: ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
40 | }
`----
x Ident
,-[$DIR/tests/fixture/value/url/input.css:38:1]
38 | background: URL(https://example.com/ima\)ge.png);
39 | background: url( "https://example.com/image.png" );
: ^^^
40 | }
`----
x UrlValue
,-[$DIR/tests/fixture/value/url/input.css:38:1]
38 | background: URL(https://example.com/ima\)ge.png);
39 | background: url( "https://example.com/image.png" );
: ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
40 | }
`----
x Str
,-[$DIR/tests/fixture/value/url/input.css:38:1]
38 | background: URL(https://example.com/ima\)ge.png);
39 | background: url( "https://example.com/image.png" );
: ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
40 | }
`----

View File

@ -0,0 +1,4 @@
// test
a {
color: red;
}

View File

@ -0,0 +1,125 @@
{
"type": "Stylesheet",
"span": {
"start": 9,
"end": 31,
"ctxt": 0
},
"rules": [
{
"type": "QualifiedRule",
"span": {
"start": 9,
"end": 30,
"ctxt": 0
},
"prelude": {
"type": "SelectorList",
"span": {
"start": 9,
"end": 10,
"ctxt": 0
},
"children": [
{
"type": "ComplexSelector",
"span": {
"start": 9,
"end": 10,
"ctxt": 0
},
"children": [
{
"type": "CompoundSelector",
"span": {
"start": 9,
"end": 10,
"ctxt": 0
},
"nestingSelector": null,
"typeSelector": {
"type": "TagNameSelector",
"span": {
"start": 9,
"end": 10,
"ctxt": 0
},
"name": {
"type": "WqName",
"span": {
"start": 9,
"end": 10,
"ctxt": 0
},
"prefix": null,
"value": {
"type": "Ident",
"span": {
"start": 9,
"end": 10,
"ctxt": 0
},
"value": "a",
"raw": "a"
}
}
},
"subclassSelectors": []
}
]
}
]
},
"block": {
"type": "SimpleBlock",
"span": {
"start": 11,
"end": 30,
"ctxt": 0
},
"name": {
"type": "PreservedToken",
"span": {
"start": 11,
"end": 12,
"ctxt": 0
},
"token": "LBrace"
},
"value": [
{
"type": "Declaration",
"span": {
"start": 17,
"end": 27,
"ctxt": 0
},
"name": {
"type": "Ident",
"span": {
"start": 17,
"end": 22,
"ctxt": 0
},
"value": "color",
"raw": "color"
},
"value": [
{
"type": "Ident",
"span": {
"start": 24,
"end": 27,
"ctxt": 0
},
"value": "red",
"raw": "red"
}
],
"important": null
}
]
}
}
]
}

View File

@ -0,0 +1,152 @@
x Stylesheet
,-[$DIR/tests/line-comment/css-in-js/11/input.css:1:1]
1 | // test
2 | ,-> a {
3 | | color: red;
4 | `-> }
`----
x Rule
,-[$DIR/tests/line-comment/css-in-js/11/input.css:1:1]
1 | // test
2 | ,-> a {
3 | | color: red;
4 | `-> }
`----
x QualifiedRule
,-[$DIR/tests/line-comment/css-in-js/11/input.css:1:1]
1 | // test
2 | ,-> a {
3 | | color: red;
4 | `-> }
`----
x SelectorList
,-[$DIR/tests/line-comment/css-in-js/11/input.css:1:1]
1 | // test
2 | a {
: ^
3 | color: red;
`----
x ComplexSelector
,-[$DIR/tests/line-comment/css-in-js/11/input.css:1:1]
1 | // test
2 | a {
: ^
3 | color: red;
`----
x CompoundSelector
,-[$DIR/tests/line-comment/css-in-js/11/input.css:1:1]
1 | // test
2 | a {
: ^
3 | color: red;
`----
x TypeSelector
,-[$DIR/tests/line-comment/css-in-js/11/input.css:1:1]
1 | // test
2 | a {
: ^
3 | color: red;
`----
x TagNameSelector
,-[$DIR/tests/line-comment/css-in-js/11/input.css:1:1]
1 | // test
2 | a {
: ^
3 | color: red;
`----
x WqName
,-[$DIR/tests/line-comment/css-in-js/11/input.css:1:1]
1 | // test
2 | a {
: ^
3 | color: red;
`----
x Ident
,-[$DIR/tests/line-comment/css-in-js/11/input.css:1:1]
1 | // test
2 | a {
: ^
3 | color: red;
`----
x SimpleBlock
,-[$DIR/tests/line-comment/css-in-js/11/input.css:1:1]
1 | // test
2 | ,-> a {
3 | | color: red;
4 | `-> }
`----
x LBrace
,-[$DIR/tests/line-comment/css-in-js/11/input.css:1:1]
1 | // test
2 | a {
: ^
3 | color: red;
`----
x ComponentValue
,-[$DIR/tests/line-comment/css-in-js/11/input.css:2:1]
2 | a {
3 | color: red;
: ^^^^^^^^^^
4 | }
`----
x StyleBlock
,-[$DIR/tests/line-comment/css-in-js/11/input.css:2:1]
2 | a {
3 | color: red;
: ^^^^^^^^^^
4 | }
`----
x Declaration
,-[$DIR/tests/line-comment/css-in-js/11/input.css:2:1]
2 | a {
3 | color: red;
: ^^^^^^^^^^
4 | }
`----
x DeclarationName
,-[$DIR/tests/line-comment/css-in-js/11/input.css:2:1]
2 | a {
3 | color: red;
: ^^^^^
4 | }
`----
x Ident
,-[$DIR/tests/line-comment/css-in-js/11/input.css:2:1]
2 | a {
3 | color: red;
: ^^^^^
4 | }
`----
x ComponentValue
,-[$DIR/tests/line-comment/css-in-js/11/input.css:2:1]
2 | a {
3 | color: red;
: ^^^
4 | }
`----
x Ident
,-[$DIR/tests/line-comment/css-in-js/11/input.css:2:1]
2 | a {
3 | color: red;
: ^^^
4 | }
`----