mirror of
https://github.com/swc-project/swc.git
synced 2024-11-24 02:06:08 +03:00
refactor(css/parser): Refactor codes related to simple blocks (#3506)
This commit is contained in:
parent
5488159ba5
commit
4e124c7bca
@ -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,
|
||||
|
@ -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 {
|
||||
|
@ -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
|
||||
|
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
|
||||
|
@ -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"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
@ -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};
|
||||
|
@ -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"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
@ -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 });
|
||||
| ^
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user