refactor(css/parser): Refactor codes related to simple blocks (#3506)

This commit is contained in:
Alexander Akait 2022-02-10 07:54:46 +03:00 committed by GitHub
parent 5488159ba5
commit 4e124c7bca
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 184 additions and 248 deletions

View File

@ -122,6 +122,109 @@ where
}
}
impl<I> Parse<SimpleBlock> for Parser<I>
where
I: ParserInput,
{
fn parse(&mut self) -> PResult<SimpleBlock> {
let span = self.input.cur_span()?;
let name = match cur!(self) {
tok!("{") => {
bump!(self);
'{'
}
tok!("(") => {
bump!(self);
'('
}
tok!("[") => {
bump!(self);
'['
}
_ => {
unreachable!();
}
};
// Create a simple block with its associated token set to the current input
// token and with its value initially set to an empty list.
let mut simple_block = SimpleBlock {
span: Default::default(),
name,
value: vec![],
};
// TODO refactor me
self.input.skip_ws()?;
// Repeatedly consume the next input token and process it as follows:
loop {
// <EOF-token>
// This is a parse error. Return the block.
if is!(self, EOF) {
let span = self.input.cur_span()?;
self.errors.push(Error::new(span, ErrorKind::Eof));
break;
}
match cur!(self) {
// ending token
// Return the block.
tok!("]") if name == '[' => {
bump!(self);
break;
}
tok!(")") if name == '(' => {
bump!(self);
break;
}
tok!("}") if name == '{' => {
bump!(self);
break;
}
// anything else
// Reconsume the current input token. Consume a component value and append it to the
// value of the block.
_ => {
let state = self.input.state();
let ctx = Ctx {
// TODO refactor me
allow_operation_in_value: name == '(',
..self.ctx
};
let parsed = self.with_ctx(ctx).parse_one_value_inner();
let value = match parsed {
Ok(value) => {
self.input.skip_ws()?;
value
}
Err(err) => {
self.errors.push(err);
self.input.reset(&state);
self.parse_component_value()?
}
};
simple_block.value.push(value);
}
}
}
simple_block.span = span!(self, span.lo);
Ok(simple_block)
}
}
impl<I> Parse<Block> for Parser<I>
where
I: ParserInput,

View File

@ -231,7 +231,7 @@ where
})
}
fn parse_one_value_inner(&mut self) -> PResult<Value> {
pub(super) fn parse_one_value_inner(&mut self) -> PResult<Value> {
// TODO remove me
self.input.skip_ws()?;
@ -270,7 +270,14 @@ where
tok!("percentage") | tok!("dimension") | tok!("num") => {
let span = self.input.cur_span()?;
let base = self.parse_basical_numeric_value()?;
let base = match cur!(self) {
tok!("percentage") => Value::Percentage(self.parse()?),
tok!("dimension") => Value::Dimension(self.parse()?),
tok!("num") => Value::Number(self.parse()?),
_ => {
unreachable!()
}
};
return self.parse_numeric_value_with_base(span.lo, base);
}
@ -287,27 +294,17 @@ where
return Ok(Value::Ident(self.parse()?));
}
tok!("[") => return self.parse_square_brackets_value().map(From::from),
tok!("[") => return Ok(Value::SimpleBlock(self.parse()?)),
tok!("(") => return self.parse_round_brackets_value().map(From::from),
tok!("(") => return Ok(Value::SimpleBlock(self.parse()?)),
tok!("{") => {
return self.parse_brace_value().map(From::from);
}
tok!("{") => return Ok(Value::SimpleBlock(self.parse()?)),
tok!("#") => return Ok(Value::Color(Color::HexColor(self.parse()?))),
_ => {}
}
if is_one_of!(self, "<!--", "-->", "!", ";") {
let token = self.input.bump()?.unwrap();
return Ok(Value::Tokens(Tokens {
span,
tokens: vec![token],
}));
}
Err(Error::new(span, ErrorKind::Expected("Declaration value")))
}
@ -352,105 +349,6 @@ where
Ok(base)
}
fn parse_brace_value(&mut self) -> PResult<SimpleBlock> {
let span = self.input.cur_span()?;
expect!(self, "{");
let brace_start = self.input.cur_span()?.lo;
let mut tokens = vec![];
let mut brace_cnt = 1;
loop {
if is!(self, "}") {
brace_cnt -= 1;
if brace_cnt == 0 {
break;
}
}
if is!(self, "{") {
brace_cnt += 1;
}
let token = self.input.bump()?;
match token {
Some(token) => tokens.push(token),
None => break,
}
}
let brace_span = span!(self, brace_start);
expect!(self, "}");
Ok(SimpleBlock {
span: span!(self, span.lo),
name: '{',
// TODO refactor me
value: vec![Value::Tokens(Tokens {
span: brace_span,
tokens,
})],
})
}
fn parse_basical_numeric_value(&mut self) -> PResult<Value> {
match cur!(self) {
tok!("percentage") => Ok(Value::Percentage(self.parse()?)),
tok!("dimension") => Ok(Value::Dimension(self.parse()?)),
tok!("num") => Ok(Value::Number(self.parse()?)),
_ => {
unreachable!()
}
}
}
fn parse_square_brackets_value(&mut self) -> PResult<SimpleBlock> {
let span = self.input.cur_span()?;
expect!(self, "[");
self.input.skip_ws()?;
let value = self.parse_property_values()?.0;
self.input.skip_ws()?;
expect!(self, "]");
Ok(SimpleBlock {
span: span!(self, span.lo),
name: '[',
value,
})
}
fn parse_round_brackets_value(&mut self) -> PResult<SimpleBlock> {
let span = self.input.cur_span()?;
expect!(self, "(");
self.input.skip_ws()?;
let value = if is!(self, ")") {
vec![]
} else {
let ctx = Ctx {
allow_operation_in_value: true,
..self.ctx
};
self.with_ctx(ctx).parse_property_values()?.0
};
expect!(self, ")");
Ok(SimpleBlock {
span: span!(self, span.lo),
name: '(',
value,
})
}
pub fn parse_simple_block(&mut self, ending: char) -> PResult<SimpleBlock> {
let start_pos = self.input.last_pos()? - BytePos(1);
let mut simple_block = SimpleBlock {

View File

@ -1,5 +1,11 @@
error: Expected "}"
error: Expected Declaration value
--> $DIR/tests/errors/rome/invalid/fit-content/invalid-call/input.css:2:45
|
2 | grid-template-columns: fit-content("broken";
| ^
error: Expected Declaration value
--> $DIR/tests/errors/rome/invalid/fit-content/invalid-call/input.css:3:1
|

View File

@ -1,12 +1,28 @@
error: Expected "]"
error: Expected "}"
error: Expected Declaration value
--> $DIR/tests/errors/rome/invalid/grid/repeat/unclosed-lint-name/input.css:2:45
|
2 | grid-template-columns: repeat(4, [col-start);
| ^
error: Expected Declaration value
--> $DIR/tests/errors/rome/invalid/grid/repeat/unclosed-lint-name/input.css:2:46
|
2 | grid-template-columns: repeat(4, [col-start);
| ^
error: Expected Declaration value
--> $DIR/tests/errors/rome/invalid/grid/repeat/unclosed-lint-name/input.css:3:1
|
3 | }
| ^
error: Unexpected end of file
--> $DIR/tests/errors/rome/invalid/grid/repeat/unclosed-lint-name/input.css:3:3
|
3 | }
| ^
error: Unexpected end of file

View File

@ -1,5 +1,11 @@
error: Expected "}"
error: Expected Declaration value
--> $DIR/tests/errors/rome/invalid/min-or-max/input.css:2:18
|
2 | width: min(500px;
| ^
error: Expected Declaration value
--> $DIR/tests/errors/rome/invalid/min-or-max/input.css:3:1
|

View File

@ -179,27 +179,14 @@
"name": "{",
"value": [
{
"type": "Tokens",
"type": "Ident",
"span": {
"start": 53,
"end": 58,
"ctxt": 0
},
"tokens": [
{
"span": {
"start": 53,
"end": 58,
"ctxt": 0
},
"token": {
"Ident": {
"value": "value",
"raw": "value"
}
}
}
]
"value": "value",
"raw": "value"
}
]
}
@ -893,27 +880,14 @@
"name": "{",
"value": [
{
"type": "Tokens",
"type": "Ident",
"span": {
"start": 364,
"end": 369,
"ctxt": 0
},
"tokens": [
{
"span": {
"start": 364,
"end": 369,
"ctxt": 0
},
"token": {
"Ident": {
"value": "value",
"raw": "value"
}
}
}
]
"value": "value",
"raw": "value"
}
]
},
@ -927,27 +901,14 @@
"name": "{",
"value": [
{
"type": "Tokens",
"type": "Ident",
"span": {
"start": 371,
"end": 376,
"ctxt": 0
},
"tokens": [
{
"span": {
"start": 371,
"end": 376,
"ctxt": 0
},
"token": {
"Ident": {
"value": "value",
"raw": "value"
}
}
}
]
"value": "value",
"raw": "value"
}
]
}

View File

@ -197,13 +197,7 @@ error: Value
4 | prop: {value};
| ^^^^^
error: Tokens
--> $DIR/tests/fixture/declaration/input.css:4:12
|
4 | prop: {value};
| ^^^^^
error: Ident { value: Atom('value' type=inline), raw: Atom('value' type=inline) }
error: Ident
--> $DIR/tests/fixture/declaration/input.css:4:12
|
4 | prop: {value};
@ -911,13 +905,7 @@ error: Value
17 | prop: {value}{value};
| ^^^^^
error: Tokens
--> $DIR/tests/fixture/declaration/input.css:17:12
|
17 | prop: {value}{value};
| ^^^^^
error: Ident { value: Atom('value' type=inline), raw: Atom('value' type=inline) }
error: Ident
--> $DIR/tests/fixture/declaration/input.css:17:12
|
17 | prop: {value}{value};
@ -941,13 +929,7 @@ error: Value
17 | prop: {value}{value};
| ^^^^^
error: Tokens
--> $DIR/tests/fixture/declaration/input.css:17:19
|
17 | prop: {value}{value};
| ^^^^^
error: Ident { value: Atom('value' type=inline), raw: Atom('value' type=inline) }
error: Ident
--> $DIR/tests/fixture/declaration/input.css:17:19
|
17 | prop: {value}{value};

View File

@ -525,39 +525,24 @@
},
"name": "{",
"value": [
{
"type": "Ident",
"span": {
"start": 166,
"end": 169,
"ctxt": 0
},
"value": "foo",
"raw": "foo"
},
{
"type": "Tokens",
"span": {
"start": 165,
"end": 175,
"start": 169,
"end": 170,
"ctxt": 0
},
"tokens": [
{
"span": {
"start": 165,
"end": 166,
"ctxt": 0
},
"token": {
"WhiteSpace": {
"value": " "
}
}
},
{
"span": {
"start": 166,
"end": 169,
"ctxt": 0
},
"token": {
"Ident": {
"value": "foo",
"raw": "foo"
}
}
},
{
"span": {
"start": 169,
@ -565,45 +550,18 @@
"ctxt": 0
},
"token": "Colon"
},
{
"span": {
"start": 170,
"end": 171,
"ctxt": 0
},
"token": {
"WhiteSpace": {
"value": " "
}
}
},
{
"span": {
"start": 171,
"end": 174,
"ctxt": 0
},
"token": {
"Ident": {
"value": "bar",
"raw": "bar"
}
}
},
{
"span": {
"start": 174,
"end": 175,
"ctxt": 0
},
"token": {
"WhiteSpace": {
"value": " "
}
}
}
]
},
{
"type": "Ident",
"span": {
"start": 171,
"end": 174,
"ctxt": 0
},
"value": "bar",
"raw": "bar"
}
]
}

View File

@ -16,3 +16,9 @@ error: Expected Declaration value
4 | prop: func3( ident.ident );
| ^
error: Expected Declaration value
--> $DIR/tests/recovery/function/input.css:7:21
|
7 | prop: func({ foo: bar });
| ^