diff --git a/src/parse/args.rs b/src/parse/args.rs index da5b0c7..0e7dbc8 100644 --- a/src/parse/args.rs +++ b/src/parse/args.rs @@ -270,7 +270,7 @@ impl<'a> Parser<'a> { self.whitespace(); if self.toks.peek().is_none() { - return Ok(CallArgs(args, span)); + return Err(("expected \")\".", span).into()); } } } diff --git a/src/parse/ident.rs b/src/parse/ident.rs index 9be64c4..eab65c0 100644 --- a/src/parse/ident.rs +++ b/src/parse/ident.rs @@ -80,7 +80,7 @@ impl<'a> Parser<'a> { let mut value = 0; let first = match self.toks.peek() { Some(t) => t, - None => return Ok(String::new()), + None => return Err(("Expected expression.", self.span_before).into()), }; let mut span = first.pos(); if first.kind == '\n' { @@ -252,8 +252,18 @@ impl<'a> Parser<'a> { while let Some(tok) = self.toks.next() { span = span.merge(tok.pos()); match tok.kind { - '"' if q == '"' => break, - '\'' if q == '\'' => break, + '"' if q == '"' => { + return Ok(Spanned { + node: Value::String(s, QuoteKind::Quoted), + span, + }) + } + '\'' if q == '\'' => { + return Ok(Spanned { + node: Value::String(s, QuoteKind::Quoted), + span, + }) + } '#' => { if let Some(Token { kind: '{', pos }) = self.toks.peek() { self.span_before = self.span_before.merge(*pos); @@ -318,9 +328,6 @@ impl<'a> Parser<'a> { _ => s.push(tok.kind), } } - Ok(Spanned { - node: Value::String(s, QuoteKind::Quoted), - span, - }) + Err((format!("Expected {}.", q), span).into()) } } diff --git a/src/parse/mod.rs b/src/parse/mod.rs index b0d3578..33f6907 100644 --- a/src/parse/mod.rs +++ b/src/parse/mod.rs @@ -144,11 +144,10 @@ impl<'a> Parser<'a> { } } AtRuleKind::Error => { - let toks = read_until_semicolon_or_closing_curly_brace(self.toks)?; let Spanned { node: message, span, - } = self.parse_value_from_vec(toks)?; + } = self.parse_value()?; return Err(( message.inspect(span)?.to_string(), @@ -157,11 +156,10 @@ impl<'a> Parser<'a> { .into()); } AtRuleKind::Warn => { - let toks = read_until_semicolon_or_closing_curly_brace(self.toks)?; let Spanned { node: message, span, - } = self.parse_value_from_vec(toks)?; + } = self.parse_value()?; span.merge(kind_string.span); if let Some(Token { kind: ';', pos }) = self.toks.peek() { kind_string.span.merge(*pos); @@ -173,11 +171,10 @@ impl<'a> Parser<'a> { }) } AtRuleKind::Debug => { - let toks = read_until_semicolon_or_closing_curly_brace(self.toks)?; let Spanned { node: message, span, - } = self.parse_value_from_vec(toks)?; + } = self.parse_value()?; span.merge(kind_string.span); if let Some(Token { kind: ';', pos }) = self.toks.peek() { kind_string.span.merge(*pos); @@ -534,14 +531,12 @@ impl<'a> Parser<'a> { let mut found_true = false; let mut body = Vec::new(); - let init_cond_toks = read_until_open_curly_brace(self.toks)?; - if init_cond_toks.is_empty() { - return Err(("Expected expression.", self.span_before).into()); - } + let init_cond = self.parse_value()?.node; + // consume the open curly brace let span_before = match self.toks.next() { - Some(t) => t.pos, - None => return Err(("Expected expression.", self.span_before).into()), + Some(Token { kind: '{', pos }) => pos, + Some(..) | None => return Err(("expected \"}\".", self.span_before).into()), }; if self.toks.peek().is_none() { @@ -550,7 +545,7 @@ impl<'a> Parser<'a> { self.whitespace_or_comment(); - if self.parse_value_from_vec(init_cond_toks)?.is_true() { + if init_cond.is_true() { found_true = true; body = Parser { toks: self.toks, diff --git a/src/parse/value/parse.rs b/src/parse/value/parse.rs index d27f697..dd40e9b 100644 --- a/src/parse/value/parse.rs +++ b/src/parse/value/parse.rs @@ -55,8 +55,11 @@ impl<'a> Parser<'a> { pub(crate) fn parse_value(&mut self) -> SassResult> { self.whitespace(); let span = match self.toks.peek() { + Some(Token { kind: '}', .. }) + | Some(Token { kind: ';', .. }) + | Some(Token { kind: '{', .. }) + | None => return Err(("Expected expression.", self.span_before).into()), Some(Token { pos, .. }) => *pos, - None => return Err(("Expected expression.", self.span_before).into()), }; let mut last_was_whitespace = false; let mut space_separated = Vec::new(); diff --git a/tests/error.rs b/tests/error.rs index d8571c5..7b9a359 100644 --- a/tests/error.rs +++ b/tests/error.rs @@ -219,17 +219,14 @@ error!( "a {$color: {ed;}", "Error: Expected expression." ); error!( - #[ignore = "this test does not fail because the closing brace is included in the value"] empty_style_value_no_semicolon, "a {color:}", "Error: Expected expression." ); error!( - #[ignore = "this test does not fail because the semicolon is included in the value"] empty_style_value_semicolon, "a {color:;}", "Error: Expected expression." ); error!( - #[ignore = "this does not fail"] ident_colon_closing_brace, "r:}", "Error: Expected expression." );