Propagate errors properly (reduce unwrap() calls)

This commit is contained in:
ConnorSkees 2020-01-17 21:42:51 -05:00
parent 02d6a511a5
commit 8076125576
2 changed files with 26 additions and 22 deletions

View File

@ -229,7 +229,7 @@ struct StyleSheetParser<'a> {
impl<'a> StyleSheetParser<'a> { impl<'a> StyleSheetParser<'a> {
fn parse_toplevel(mut self) -> SassResult<StyleSheet> { fn parse_toplevel(mut self) -> SassResult<StyleSheet> {
let mut rules = Vec::new(); let mut rules: Vec<Stmt> = Vec::new();
while let Some(Token { kind, .. }) = self.lexer.peek() { while let Some(Token { kind, .. }) = self.lexer.peek() {
match kind.clone() { match kind.clone() {
TokenKind::Ident(_) TokenKind::Ident(_)
@ -300,7 +300,9 @@ impl<'a> StyleSheetParser<'a> {
fn eat_rules(&mut self, super_selector: &Selector, scope: &mut Scope) -> Vec<Stmt> { fn eat_rules(&mut self, super_selector: &Selector, scope: &mut Scope) -> Vec<Stmt> {
let mut stmts = Vec::new(); let mut stmts = Vec::new();
while let Ok(tok) = eat_expr(&mut self.lexer, scope, super_selector) { while let Some(tok) = eat_expr(&mut self.lexer, scope, super_selector)
.unwrap_or_else(|error| self.error(error.0, error.1))
{
match tok { match tok {
Expr::Style(s) => stmts.push(Stmt::Style(s)), Expr::Style(s) => stmts.push(Stmt::Style(s)),
Expr::MixinDecl(name, mixin) => { Expr::MixinDecl(name, mixin) => {
@ -383,7 +385,7 @@ fn eat_include<I: Iterator<Item = Token>>(
}; };
let rules = mixin let rules = mixin
.call_with_args(&args) .call_with_args(&args)
.eval(super_selector, &mut scope.clone()); .eval(super_selector, &mut scope.clone())?;
Ok(rules) Ok(rules)
} }
@ -482,23 +484,25 @@ pub(crate) fn eat_expr<I: Iterator<Item = Token>>(
toks: &mut Peekable<I>, toks: &mut Peekable<I>,
scope: &Scope, scope: &Scope,
super_selector: &Selector, super_selector: &Selector,
) -> Result<Expr, ()> { ) -> Result<Option<Expr>, (Pos, &'static str)> {
let mut values = Vec::with_capacity(5); let mut values = Vec::with_capacity(5);
while let Some(tok) = toks.peek() { while let Some(tok) = toks.peek() {
match &tok.kind { match &tok.kind {
TokenKind::Symbol(Symbol::SemiColon) | TokenKind::Symbol(Symbol::CloseCurlyBrace) => { TokenKind::Symbol(Symbol::SemiColon) | TokenKind::Symbol(Symbol::CloseCurlyBrace) => {
toks.next(); toks.next();
devour_whitespace(toks); devour_whitespace(toks);
return Ok(Expr::Style(Style::from_tokens(&values, scope)?)); return Ok(Some(Expr::Style(
Style::from_tokens(&values, scope).unwrap(),
)));
} }
TokenKind::Symbol(Symbol::OpenCurlyBrace) => { TokenKind::Symbol(Symbol::OpenCurlyBrace) => {
toks.next(); toks.next();
devour_whitespace(toks); devour_whitespace(toks);
return Ok(Expr::Selector(Selector::from_tokens( return Ok(Some(Expr::Selector(Selector::from_tokens(
&mut values.iter().peekable(), &mut values.iter().peekable(),
super_selector, super_selector,
scope, scope,
))); ))));
} }
TokenKind::Variable(_) => { TokenKind::Variable(_) => {
let tok = toks.next().unwrap(); let tok = toks.next().unwrap();
@ -512,10 +516,10 @@ pub(crate) fn eat_expr<I: Iterator<Item = Token>>(
{ {
toks.next(); toks.next();
devour_whitespace(toks); devour_whitespace(toks);
return Ok(Expr::VariableDecl( return Ok(Some(Expr::VariableDecl(
name, name,
eat_variable_value(toks, scope).unwrap(), // .unwrap_or_else(|err| self.error(err.0, err.1)), eat_variable_value(toks, scope)?
)); )));
} else { } else {
values.push(Token { values.push(Token {
kind: TokenKind::Variable(name), kind: TokenKind::Variable(name),
@ -532,20 +536,20 @@ pub(crate) fn eat_expr<I: Iterator<Item = Token>>(
}; };
devour_whitespace(toks); devour_whitespace(toks);
if values.is_empty() { if values.is_empty() {
return Ok(Expr::MultilineComment(s.clone())); return Ok(Some(Expr::MultilineComment(s.clone())));
} else { } else {
values.push(tok.clone()) values.push(tok.clone())
} }
} }
TokenKind::AtRule(AtRule::Include) => { TokenKind::AtRule(AtRule::Include) => {
return Ok(Expr::Include( return Ok(Some(Expr::Include(
eat_include(toks, scope, super_selector).unwrap(), eat_include(toks, scope, super_selector)?,
)); )));
} }
TokenKind::AtRule(AtRule::Mixin) => { TokenKind::AtRule(AtRule::Mixin) => {
toks.next(); toks.next();
let (name, mixin) = parse_mixin(toks, scope.clone()).unwrap(); let (name, mixin) = parse_mixin(toks, scope.clone()).unwrap();
return Ok(Expr::MixinDecl(name, mixin)); return Ok(Some(Expr::MixinDecl(name, mixin)));
} }
TokenKind::AtRule(_) => { TokenKind::AtRule(_) => {
if let Some(Token { if let Some(Token {
@ -554,7 +558,7 @@ pub(crate) fn eat_expr<I: Iterator<Item = Token>>(
}) = toks.next() }) = toks.next()
{ {
if let Ok(a) = eat_at_rule(rule, pos, toks, scope) { if let Ok(a) = eat_at_rule(rule, pos, toks, scope) {
return Ok(a); return Ok(Some(a));
} }
} }
} }
@ -576,7 +580,7 @@ pub(crate) fn eat_expr<I: Iterator<Item = Token>>(
} }
}; };
} }
Err(()) Ok(None)
} }
/// Functions that print to stdout or stderr /// Functions that print to stdout or stderr

View File

@ -1,7 +1,7 @@
use std::iter::Peekable; use std::iter::Peekable;
use std::vec::IntoIter; use std::vec::IntoIter;
use crate::common::Scope; use crate::common::{Pos, Scope};
use crate::function::{CallArgs, FuncArgs}; use crate::function::{CallArgs, FuncArgs};
use crate::selector::Selector; use crate::selector::Selector;
use crate::{eat_expr, Expr, RuleSet, Stmt, Token}; use crate::{eat_expr, Expr, RuleSet, Stmt, Token};
@ -39,16 +39,16 @@ impl Mixin {
self self
} }
pub fn eval(&mut self, super_selector: &Selector, scope: &mut Scope) -> Vec<Stmt> { pub fn eval(&mut self, super_selector: &Selector, scope: &mut Scope) -> Result<Vec<Stmt>, (Pos, &'static str)> {
let mut stmts = Vec::new(); let mut stmts = Vec::new();
while let Ok(expr) = eat_expr(&mut self.body, scope, super_selector) { while let Some(expr) = eat_expr(&mut self.body, scope, super_selector)? {
match expr { match expr {
Expr::Style(s) => stmts.push(Stmt::Style(s)), Expr::Style(s) => stmts.push(Stmt::Style(s)),
Expr::Include(_) => todo!(), Expr::Include(_) => todo!(),
Expr::MixinDecl(_, _) => todo!(), Expr::MixinDecl(_, _) => todo!(),
Expr::Selector(s) => { Expr::Selector(s) => {
self.nesting += 1; self.nesting += 1;
let rules = self.eval(&super_selector.clone().zip(s.clone()), scope); let rules = self.eval(&super_selector.clone().zip(s.clone()), scope)?;
stmts.push(Stmt::RuleSet(RuleSet { stmts.push(Stmt::RuleSet(RuleSet {
super_selector: super_selector.clone(), super_selector: super_selector.clone(),
selector: s, selector: s,
@ -67,6 +67,6 @@ impl Mixin {
Expr::MultilineComment(s) => stmts.push(Stmt::MultilineComment(s)), Expr::MultilineComment(s) => stmts.push(Stmt::MultilineComment(s)),
} }
} }
stmts Ok(stmts)
} }
} }