Skip to content

Clean up a bit now that lifetimes are non-lexical. #269

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Nov 25, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions src/color.rs
Original file line number Diff line number Diff line change
Expand Up @@ -280,22 +280,22 @@ impl Color {
where
ComponentParser: ColorComponentParser<'i>,
{
// FIXME: remove clone() when lifetimes are non-lexical
let location = input.current_source_location();
let token = input.next()?.clone();
match token {
let token = input.next()?;
match *token {
Token::Hash(ref value) | Token::IDHash(ref value) => {
Color::parse_hash(value.as_bytes())
}
Token::Ident(ref value) => parse_color_keyword(&*value),
Token::Function(ref name) => {
let name = name.clone();
return input.parse_nested_block(|arguments| {
parse_color_function(component_parser, &*name, arguments)
})
}
_ => Err(()),
}
.map_err(|()| location.new_unexpected_token_error(token))
.map_err(|()| location.new_unexpected_token_error(token.clone()))
}

/// Parse a <color> value, per CSS Color Module Level 3.
Expand Down
47 changes: 30 additions & 17 deletions src/nth.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,28 +10,30 @@ use matches::matches;
/// in which case the caller needs to check if the arguments’ parser is exhausted.
/// Return `Ok((A, B))`, or `Err(())` for a syntax error.
pub fn parse_nth<'i, 't>(input: &mut Parser<'i, 't>) -> Result<(i32, i32), BasicParseError<'i>> {
// FIXME: remove .clone() when lifetimes are non-lexical.
match input.next()?.clone() {
match *input.next()? {
Token::Number {
int_value: Some(b), ..
} => Ok((0, b)),
Token::Dimension {
int_value: Some(a),
unit,
ref unit,
..
} => {
match_ignore_ascii_case! {
&unit,
unit,
"n" => Ok(parse_b(input, a)?),
"n-" => Ok(parse_signless_b(input, a, -1)?),
_ => match parse_n_dash_digits(&*unit) {
Ok(b) => Ok((a, b)),
Err(()) => Err(input.new_basic_unexpected_token_error(Token::Ident(unit.clone())))
Err(()) => {
let unit = unit.clone();
Err(input.new_basic_unexpected_token_error(Token::Ident(unit)))
}
}
}
}
Token::Ident(value) => {
match_ignore_ascii_case! { &value,
Token::Ident(ref value) => {
match_ignore_ascii_case! { value,
"even" => Ok((2, 0)),
"odd" => Ok((2, 1)),
"n" => Ok(parse_b(input, 1)?),
Expand All @@ -42,30 +44,41 @@ pub fn parse_nth<'i, 't>(input: &mut Parser<'i, 't>) -> Result<(i32, i32), Basic
let (slice, a) = if value.starts_with("-") {
(&value[1..], -1)
} else {
(&*value, 1)
(&**value, 1)
};
match parse_n_dash_digits(slice) {
Ok(b) => Ok((a, b)),
Err(()) => Err(input.new_basic_unexpected_token_error(Token::Ident(value.clone())))
Err(()) => {
let value = value.clone();
Err(input.new_basic_unexpected_token_error(Token::Ident(value)))
}
}
}
}
}
// FIXME: remove .clone() when lifetimes are non-lexical.
Token::Delim('+') => match input.next_including_whitespace()?.clone() {
Token::Ident(value) => {
match_ignore_ascii_case! { &value,
Token::Delim('+') => match *input.next_including_whitespace()? {
Token::Ident(ref value) => {
match_ignore_ascii_case! { value,
"n" => parse_b(input, 1),
"n-" => parse_signless_b(input, 1, -1),
_ => match parse_n_dash_digits(&*value) {
_ => match parse_n_dash_digits(value) {
Ok(b) => Ok((1, b)),
Err(()) => Err(input.new_basic_unexpected_token_error(Token::Ident(value.clone())))
Err(()) => {
let value = value.clone();
Err(input.new_basic_unexpected_token_error(Token::Ident(value)))
}
}
}
}
token => Err(input.new_basic_unexpected_token_error(token)),
ref token => {
let token = token.clone();
Err(input.new_basic_unexpected_token_error(token))
},
},
ref token => {
let token = token.clone();
Err(input.new_basic_unexpected_token_error(token))
},
token => Err(input.new_basic_unexpected_token_error(token)),
}
}

Expand Down
51 changes: 24 additions & 27 deletions src/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -787,30 +787,30 @@ impl<'i: 't, 't> Parser<'i, 't> {
/// Parse a <url-token> and return the unescaped value.
#[inline]
pub fn expect_url(&mut self) -> Result<CowRcStr<'i>, BasicParseError<'i>> {
// FIXME: revert early returns when lifetimes are non-lexical
expect! {self,
Token::UnquotedUrl(ref value) => return Ok(value.clone()),
Token::Function(ref name) if name.eq_ignore_ascii_case("url") => {}
Token::UnquotedUrl(ref value) => Ok(value.clone()),
Token::Function(ref name) if name.eq_ignore_ascii_case("url") => {
self.parse_nested_block(|input| {
input.expect_string().map_err(Into::into).map(|s| s.clone())
})
.map_err(ParseError::<()>::basic)
}
}
self.parse_nested_block(|input| {
input.expect_string().map_err(Into::into).map(|s| s.clone())
})
.map_err(ParseError::<()>::basic)
}

/// Parse either a <url-token> or a <string-token>, and return the unescaped value.
#[inline]
pub fn expect_url_or_string(&mut self) -> Result<CowRcStr<'i>, BasicParseError<'i>> {
// FIXME: revert early returns when lifetimes are non-lexical
expect! {self,
Token::UnquotedUrl(ref value) => return Ok(value.clone()),
Token::QuotedString(ref value) => return Ok(value.clone()),
Token::Function(ref name) if name.eq_ignore_ascii_case("url") => {}
Token::UnquotedUrl(ref value) => Ok(value.clone()),
Token::QuotedString(ref value) => Ok(value.clone()),
Token::Function(ref name) if name.eq_ignore_ascii_case("url") => {
self.parse_nested_block(|input| {
input.expect_string().map_err(Into::into).map(|s| s.clone())
})
.map_err(ParseError::<()>::basic)
}
}
self.parse_nested_block(|input| {
input.expect_string().map_err(Into::into).map(|s| s.clone())
})
.map_err(ParseError::<()>::basic)
}

/// Parse a <number-token> and return the integer value.
Expand Down Expand Up @@ -928,30 +928,27 @@ impl<'i: 't, 't> Parser<'i, 't> {
/// See `Token::is_parse_error`. This also checks nested blocks and functions recursively.
#[inline]
pub fn expect_no_error_token(&mut self) -> Result<(), BasicParseError<'i>> {
// FIXME: remove break and intermediate variable when lifetimes are non-lexical
let token;
loop {
match self.next_including_whitespace_and_comments() {
Ok(&Token::Function(_))
| Ok(&Token::ParenthesisBlock)
| Ok(&Token::SquareBracketBlock)
| Ok(&Token::CurlyBracketBlock) => {}
| Ok(&Token::CurlyBracketBlock) => {
self.parse_nested_block(|input| {
input.expect_no_error_token().map_err(Into::into)
}).map_err(ParseError::<()>::basic)?
}
Ok(t) => {
// FIXME: maybe these should be separate variants of
// BasicParseError instead?
if t.is_parse_error() {
token = t.clone();
break;
let token = t.clone();
return Err(self.new_basic_unexpected_token_error(token))
}
continue;
}
Err(_) => return Ok(()),
}
let result = self.parse_nested_block(|input| {
input.expect_no_error_token().map_err(|e| Into::into(e))
});
result.map_err(ParseError::<()>::basic)?
}
// FIXME: maybe these should be separate variants of BasicParseError instead?
Err(self.new_basic_unexpected_token_error(token))
}
}

Expand Down
63 changes: 26 additions & 37 deletions src/rules_and_declarations.rs
Original file line number Diff line number Diff line change
Expand Up @@ -266,17 +266,10 @@ where
fn next(&mut self) -> Option<Self::Item> {
loop {
let start = self.input.state();
// FIXME: remove intermediate variable when lifetimes are non-lexical
let ident = match self.input.next_including_whitespace_and_comments() {
match self.input.next_including_whitespace_and_comments() {
Ok(&Token::WhiteSpace(_)) | Ok(&Token::Comment(_)) | Ok(&Token::Semicolon) => continue,
Ok(&Token::Ident(ref name)) => Ok(Ok(name.clone())),
Ok(&Token::AtKeyword(ref name)) => Ok(Err(name.clone())),
Ok(token) => Err(token.clone()),
Err(_) => return None,
};
match ident {
Ok(Ok(name)) => {
// Ident
Ok(&Token::Ident(ref name)) => {
let name = name.clone();
let result = {
let parser = &mut self.parser;
// FIXME: https://github.com/servo/rust-cssparser/issues/254
Expand All @@ -288,18 +281,20 @@ where
};
return Some(result.map_err(|e| (e, self.input.slice_from(start.position()))));
}
Ok(Err(name)) => {
// At-keyword
Ok(&Token::AtKeyword(ref name)) => {
let name = name.clone();
return Some(parse_at_rule(&start, name, self.input, &mut self.parser));
}
Err(token) => {
Ok(token) => {
let token = token.clone();
let result = self.input.parse_until_after(Delimiter::Semicolon, |_| {
Err(start
.source_location()
.new_unexpected_token_error(token.clone()))
.new_unexpected_token_error(token))
});
return Some(result.map_err(|e| (e, self.input.slice_from(start.position()))));
}
Err(..) => return None,
}
}
}
Expand Down Expand Up @@ -374,21 +369,18 @@ where
}
let start = self.input.state();

let at_keyword;
match self.input.next_byte() {
Some(b'@') => {
let at_keyword = match self.input.next_byte()? {
b'@' => {
match self.input.next_including_whitespace_and_comments() {
Ok(&Token::AtKeyword(ref name)) => at_keyword = Some(name.clone()),
_ => at_keyword = None,
}
// FIXME: move this back inside `match` when lifetimes are non-lexical
if at_keyword.is_none() {
self.input.reset(&start)
Ok(&Token::AtKeyword(ref name)) => Some(name.clone()),
_ => {
self.input.reset(&start);
None
},
}
}
Some(_) => at_keyword = None,
None => return None,
}
_ => None,
};

if let Some(name) = at_keyword {
let first_stylesheet_rule = self.is_stylesheet && !self.any_rule_so_far;
Expand Down Expand Up @@ -444,20 +436,17 @@ where
input.parse_entirely(|input| {
input.skip_whitespace();
let start = input.state();

let at_keyword;
if input.next_byte() == Some(b'@') {
let at_keyword = if input.next_byte() == Some(b'@') {
match *input.next_including_whitespace_and_comments()? {
Token::AtKeyword(ref name) => at_keyword = Some(name.clone()),
_ => at_keyword = None,
}
// FIXME: move this back inside `match` when lifetimes are non-lexical
if at_keyword.is_none() {
input.reset(&start)
Token::AtKeyword(ref name) => Some(name.clone()),
_ => {
input.reset(&start);
None
}
}
} else {
at_keyword = None
}
None
};

if let Some(name) = at_keyword {
parse_at_rule(&start, name, input, parser).map_err(|e| e.0)
Expand Down
8 changes: 5 additions & 3 deletions src/unicode_range.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,11 +60,13 @@ impl UnicodeRange {
fn parse_tokens<'i, 't>(input: &mut Parser<'i, 't>) -> Result<(), BasicParseError<'i>> {
match input.next_including_whitespace()?.clone() {
Token::Delim('+') => {
// FIXME: remove .clone() when lifetimes are non-lexical.
match input.next_including_whitespace()?.clone() {
match *input.next_including_whitespace()? {
Token::Ident(_) => {}
Token::Delim('?') => {}
t => return Err(input.new_basic_unexpected_token_error(t)),
ref t => {
let t = t.clone();
return Err(input.new_basic_unexpected_token_error(t));
}
}
parse_question_marks(input)
}
Expand Down