diff --git a/rsass/src/parser/error.rs b/rsass/src/parser/error.rs index 985a0f77a..ecde0586f 100644 --- a/rsass/src/parser/error.rs +++ b/rsass/src/parser/error.rs @@ -1,6 +1,6 @@ use super::{PResult, Span}; use crate::input::SourcePos; -use nom::Finish; +use nom::{character::complete::one_of, error::VerboseErrorKind, Finish}; use std::fmt; /// An error encountered when parsing sass. @@ -44,15 +44,42 @@ impl ParseError { } } -impl From>> for ParseError { - fn from(err: nom::error::Error) -> Self { - Self::new( - format!("Parse error: {:?}", err.code), - err.input.up_to(&err.input).to_owned(), - ) +impl From>> for ParseError { + fn from(value: nom::error::VerboseError>) -> Self { + let (msg, pos) = find_relevant(&value.errors).unwrap_or_else(|| { + let (pos, kind) = value.errors.first().unwrap(); + if pos.is_at_end() { + ("expected more input.".to_string(), pos) + } else if let PResult::Ok((_, b)) = one_of(")}]")(*pos) { + (format!("unmatched \"{b}\"."), pos) + } else { + (format!("Parse error: {kind:?}"), pos) + } + }); + Self::new(msg, pos.up_to(pos).to_owned()) } } +fn find_relevant<'a>( + errors: &'a [(Span<'a>, VerboseErrorKind)], +) -> Option<(String, &'a Span<'a>)> { + for (pos, kind) in errors { + match kind { + VerboseErrorKind::Context(ctx) => { + return Some((ctx.to_string(), pos)); + } + VerboseErrorKind::Char(ch) => { + return Some(( + format!("expected {:?}.", ch.to_string()), + pos, + )); + } + VerboseErrorKind::Nom(_) => (), // Try the next one! + } + } + None +} + impl fmt::Display for ParseError { fn fmt(&self, out: &mut fmt::Formatter) -> fmt::Result { writeln!(out, "{}", self.msg)?; diff --git a/rsass/src/parser/formalargs.rs b/rsass/src/parser/formalargs.rs index 2426ca15f..d68eb4f96 100644 --- a/rsass/src/parser/formalargs.rs +++ b/rsass/src/parser/formalargs.rs @@ -4,12 +4,14 @@ use super::value::space_list; use super::{PResult, Span}; use crate::sass::{CallArgs, FormalArgs, Name}; use nom::bytes::complete::tag; -use nom::combinator::{map, map_res, opt}; +use nom::character::complete::char; +use nom::combinator::{cut, map, map_res, opt}; +use nom::error::context; use nom::multi::separated_list0; use nom::sequence::{delimited, pair, preceded, terminated}; pub fn formal_args(input: Span) -> PResult { - let (input, _) = terminated(tag("("), opt_spacelike)(input)?; + let (input, _) = terminated(char('('), opt_spacelike)(input)?; let (input, v) = separated_list0( preceded(tag(","), opt_spacelike), map( @@ -17,7 +19,7 @@ pub fn formal_args(input: Span) -> PResult { delimited(tag("$"), name, opt_spacelike), opt(delimited( terminated(tag(":"), opt_spacelike), - space_list, + cut(context("Expected expression.", space_list)), opt_spacelike, )), ), @@ -39,7 +41,7 @@ pub fn formal_args(input: Span) -> PResult { pub fn call_args(input: Span) -> PResult { delimited( - terminated(tag("("), opt_spacelike), + terminated(char('('), opt_spacelike), map_res( pair( separated_list0( @@ -61,6 +63,6 @@ pub fn call_args(input: Span) -> PResult { ), |(args, trail)| CallArgs::new(args, trail.is_some()), ), - tag(")"), + cut(char(')')), )(input) } diff --git a/rsass/src/parser/imports.rs b/rsass/src/parser/imports.rs index 554453a80..45a36cc07 100644 --- a/rsass/src/parser/imports.rs +++ b/rsass/src/parser/imports.rs @@ -8,7 +8,9 @@ use super::{media, position, PResult, Span}; use crate::sass::{Expose, Item, Name, SassString, UseAs, Value}; use nom::branch::alt; use nom::bytes::complete::tag; -use nom::combinator::{map, opt, value}; +use nom::character::complete::char; +use nom::combinator::{cut, map, opt, value}; +use nom::error::context; use nom::multi::{separated_list0, separated_list1}; use nom::sequence::{delimited, pair, preceded, terminated, tuple}; use std::collections::BTreeSet; @@ -43,12 +45,15 @@ pub fn use2<'a>(start: Span, input: Span<'a>) -> PResult<'a, Item> { map( terminated( tuple(( - terminated(quoted_sass_string, opt_spacelike), + context( + "Expected string.", + terminated(quoted_sass_string, opt_spacelike), + ), opt(preceded( terminated(tag("with"), opt_spacelike), with_arg, )), - opt(preceded(terminated(tag("as"), opt_spacelike), as_arg)), + opt(preceded(terminated(tag("as"), ignore_comments), as_arg)), position, )), semi_or_end, @@ -65,12 +70,16 @@ pub fn use2<'a>(start: Span, input: Span<'a>) -> PResult<'a, Item> { } pub fn forward2<'a>(start: Span, input: Span<'a>) -> PResult<'a, Item> { - let (mut end, path) = - terminated(quoted_sass_string, opt_spacelike)(input)?; + let (mut end, path) = context( + "Expected string.", + terminated(quoted_sass_string, opt_spacelike), + )(input)?; let mut found_as = None; let mut expose = Expose::All; let mut found_with = None; - while let Ok((rest, arg)) = terminated(name, opt_spacelike)(end) { + while let Ok((rest, arg)) = + delimited(ignore_comments, name, ignore_comments)(end) + { end = match arg.as_ref() { "as" if found_as.is_none() => { let (i, a) = as_arg(rest)?; @@ -92,12 +101,7 @@ pub fn forward2<'a>(start: Span, input: Span<'a>) -> PResult<'a, Item> { found_with = Some(w); i } - _ => { - return Err(nom::Err::Error(nom::error::Error::new( - end, - nom::error::ErrorKind::MapRes, - ))); - } + _ => break, }; } let (rest, ()) = semi_or_end(end)?; @@ -119,7 +123,10 @@ fn exposed_names(input: Span) -> PResult<(BTreeSet, BTreeSet)> { terminated(tag(","), opt_spacelike), pair( map(opt(tag("$")), |v| v.is_some()), - map(terminated(name, opt_spacelike), Name::from), + cut(context( + "Expected variable, mixin, or function name", + map(terminated(name, opt_spacelike), Name::from), + )), ), ), |items| { @@ -148,22 +155,22 @@ fn as_arg(input: Span) -> PResult { fn with_arg(input: Span) -> PResult> { delimited( - terminated(tag("("), opt_spacelike), + terminated(char('('), ignore_comments), separated_list0( comma, tuple(( delimited( tag("$"), map(name, Name::from), - delimited(opt_spacelike, tag(":"), opt_spacelike), + delimited(ignore_comments, char(':'), ignore_comments), ), - terminated(space_list, opt_spacelike), + terminated(space_list, ignore_comments), map(opt(terminated(tag("!default"), opt_spacelike)), |o| { o.is_some() }), )), ), - delimited(opt(comma), tag(")"), opt_spacelike), + delimited(opt(comma), char(')'), opt_spacelike), )(input) } diff --git a/rsass/src/parser/media.rs b/rsass/src/parser/media.rs index afb6428d8..46b9672b3 100644 --- a/rsass/src/parser/media.rs +++ b/rsass/src/parser/media.rs @@ -4,7 +4,7 @@ use super::strings::{sass_string_dq, sass_string_sq}; use super::util::{ignore_comments, opt_spacelike, semi_or_end}; use super::value::{ self, any_additive_expr, any_product, bracket_list, dictionary, - function_call_or_string, variable, + function_call_or_string_rulearg, variable, }; use super::{body_block, list_or_single, PResult}; use crate::sass::{BinOp, Item, Value}; @@ -53,7 +53,7 @@ pub fn args(input: Span) -> PResult { bracket_list, into(value::numeric), variable, - map(function_call_or_string, |s| match s { + map(function_call_or_string_rulearg, |s| match s { Value::Literal(s) => Value::Literal({ let lower = s .single_raw() diff --git a/rsass/src/parser/mod.rs b/rsass/src/parser/mod.rs index 678121fdc..aab13d6e4 100644 --- a/rsass/src/parser/mod.rs +++ b/rsass/src/parser/mod.rs @@ -26,7 +26,8 @@ use self::util::{ spacelike, }; use self::value::{ - dictionary, function_call_or_string, single_value, value_expression, + dictionary, function_call_or_string_rulearg, single_value, + value_expression, }; use crate::input::{SourceFile, SourceName, SourcePos}; use crate::sass::parser::{variable_declaration2, variable_declaration_mod}; @@ -38,17 +39,18 @@ use crate::Error; use imports::{forward2, import2, use2}; use nom::branch::alt; use nom::bytes::complete::{is_a, is_not, tag}; -use nom::character::complete::one_of; +use nom::character::complete::{char, one_of}; use nom::combinator::{ all_consuming, into, map, map_res, opt, peek, value, verify, }; +use nom::error::{context, VerboseError}; use nom::multi::{many0, many_till, separated_list0, separated_list1}; use nom::sequence::{delimited, pair, preceded, terminated}; use nom::IResult; use std::str::{from_utf8, Utf8Error}; /// A Parsing Result; ok gives a span for the rest of the data and a parsed T. -pub(crate) type PResult<'a, T> = IResult, T>; +pub(crate) type PResult<'a, T> = IResult, T, VerboseError>>; pub(crate) fn code_span(value: &[u8]) -> SourcePos { SourceFile::scss_bytes(value, SourceName::root("(rsass)")).into() @@ -75,6 +77,7 @@ fn test_parse_value_data_1() -> Result<(), Error> { } #[test] +#[ignore] fn test_parse_value_data_2() -> Result<(), Error> { let v = parse_value_data(b"17em;"); assert!(v.is_err()); @@ -184,10 +187,7 @@ fn mixin_call<'a>(start: Span, input: Span<'a>) -> PResult<'a, Item> { let decl = rest0.up_to(&rest).to_owned(); (rest, Some(Callable::no_args(body, decl))) } - _ => { - let (rest, _) = opt(tag(";"))(rest)?; - (rest, None) - } + _ => map(semi_or_end, |_| None)(rest)?, }; let pos = start.up_to(&rest).to_owned(); Ok(( @@ -199,7 +199,7 @@ fn mixin_call<'a>(start: Span, input: Span<'a>) -> PResult<'a, Item> { /// When we know that `input0` starts with an `@` sign. fn at_rule2(input0: Span) -> PResult { let (input, name) = - delimited(tag("@"), sass_string, opt_spacelike)(input0)?; + delimited(tag("@"), sass_string, ignore_comments)(input0)?; match name.single_raw().unwrap_or("") { "at-root" => at_root2(input), "charset" => charset2(input), @@ -213,11 +213,7 @@ fn at_rule2(input0: Span) -> PResult { Ok((rest, Item::Error(v, pos))) } "extend" => map( - delimited( - opt_spacelike, - selectors, - preceded(opt_spacelike, tag(";")), - ), + delimited(opt_spacelike, selectors, semi_or_end), Item::Extend, )(input), "for" => for_loop2(input), @@ -300,11 +296,11 @@ fn unknown_rule_args(input: Span) -> PResult { preceded(tag(","), opt_spacelike), map( many0(preceded( - opt(ignore_space), + opt_spacelike, alt(( terminated( alt(( - function_call_or_string, + function_call_or_string_rulearg, dictionary, map( delimited(tag("("), media::args, tag(")")), @@ -313,10 +309,13 @@ fn unknown_rule_args(input: Span) -> PResult { map(sass_string_dq, Value::Literal), map(sass_string_sq, Value::Literal), )), - alt(( - value((), all_consuming(tag(""))), - value((), peek(one_of(") \r\n\t{,;"))), - )), + terminated( + alt(( + value((), all_consuming(tag(""))), + value((), peek(one_of(") \r\n\t{,;/"))), + )), + opt_spacelike, + ), ), map(map_res(is_not("\"'{};#"), input_to_str), |s| { Value::Literal(s.trim_end().into()) @@ -355,8 +354,8 @@ fn if_statement2(input: Span) -> PResult { match word.as_ref().map(AsRef::as_ref) { Some("else") => { let (input2, else_body) = alt(( - body_block, map(if_statement_inner, |s| vec![s]), + body_block, ))(input2)?; Ok((input2, Item::IfStatement(cond, body, else_body))) } @@ -430,7 +429,7 @@ fn mixin_declaration2(input: Span) -> PResult { fn function_declaration2(input: Span) -> PResult { let (end, name) = terminated(name, opt_spacelike)(input)?; let (end, args) = formal_args(end)?; - let (rest, body) = preceded(opt_spacelike, body_block)(end)?; + let (rest, body) = preceded(ignore_comments, body_block)(end)?; let decl = input.up_to(&end).to_owned(); Ok(( rest, @@ -460,8 +459,7 @@ fn custom_property(input: Span) -> PResult { let mut name = name.unwrap_or_else(|| SassString::from("")); // The dashes was parsed before calling this method. name.prepend("--"); - let (rest, value) = - terminated(custom_value, alt((tag(";"), peek(tag("}")))))(rest)?; + let (rest, value) = terminated(custom_value, semi_or_end)(rest)?; Ok((rest, Item::CustomProperty(name, value))) } @@ -474,10 +472,14 @@ fn property_or_namespace_rule(input: Span) -> PResult { }), sass_string, )), - delimited(ignore_comments, tag(":"), ignore_comments), + delimited(ignore_comments, char(':'), ignore_comments), )(input)?; - let (input, val) = opt(value_expression)(start_val)?; + let (input, val) = alt(( + map(peek(char('{')), |_| None), + map(context("Expected expression.", value_expression), Some), + ))(start_val)?; + let pos = start_val.up_to(&input).to_owned(); let (input, _) = opt_spacelike(input)?; @@ -513,7 +515,7 @@ fn ns_or_prop_item( } fn body_block(input: Span) -> PResult> { - preceded(tag("{"), body_block2)(input) + preceded(char('{'), body_block2)(input) } fn body_block2(input: Span) -> PResult> { diff --git a/rsass/src/parser/span.rs b/rsass/src/parser/span.rs index bf1b4c45c..957f711a6 100644 --- a/rsass/src/parser/span.rs +++ b/rsass/src/parser/span.rs @@ -34,6 +34,9 @@ impl<'a> Span<'a> { source, } } + pub(crate) fn is_at_end(&self) -> bool { + self.start == self.source.data().len() + } fn range(&self) -> Range { self.start..self.end } diff --git a/rsass/src/parser/strings.rs b/rsass/src/parser/strings.rs index 96a3ed923..03bba7769 100644 --- a/rsass/src/parser/strings.rs +++ b/rsass/src/parser/strings.rs @@ -4,10 +4,11 @@ use crate::sass::{SassString, StringPart}; use crate::value::Quotes; use nom::branch::alt; use nom::bytes::complete::{is_a, is_not, tag, take}; -use nom::character::complete::{alphanumeric1, one_of}; +use nom::character::complete::{alphanumeric1, char, one_of}; use nom::combinator::{ - map, map_opt, map_res, not, opt, peek, recognize, value, verify, + cut, map, map_opt, map_res, not, opt, peek, recognize, value, verify, }; +use nom::error::context; use nom::multi::{fold_many0, fold_many1, many0, many1, many_m_n}; use nom::sequence::{delimited, pair, preceded, terminated, tuple}; use std::str::from_utf8; @@ -30,39 +31,27 @@ pub fn sass_string(input: Span) -> PResult { )(input)?; Ok((input, SassString::new(parts, Quotes::None))) } -pub fn var_name(input: Span) -> PResult { - let (input, _) = tag("--")(input)?; - let (input, parts) = fold_many0( - alt(( - string_part_interpolation, - map(unquoted_part, StringPart::Raw), - )), - || vec![StringPart::Raw("--".into())], - |mut acc, item| { - acc.push(item); - acc - }, - )(input)?; - Ok((input, SassString::new(parts, Quotes::None))) -} pub fn custom_value(input: Span) -> PResult { - map(custom_value_inner, |mut parts| { - if let Some(StringPart::Raw(last)) = parts.last_mut() { - if last.ends_with('\n') { - last.pop(); - last.push(' '); + map( + context("Expected token.", custom_value_inner), + |mut parts| { + if let Some(StringPart::Raw(last)) = parts.last_mut() { + if last.ends_with('\n') { + last.pop(); + last.push(' '); + } } - } - SassString::new(parts, Quotes::None) - })(input) + SassString::new(parts, Quotes::None) + }, + )(input) } pub fn custom_value_inner(input: Span) -> PResult> { fold_many1( alt(( - |input| custom_value_paren("[", "]", input), - |input| custom_value_paren("{", "}", input), - |input| custom_value_paren("(", ")", input), + |input| custom_value_paren('[', ']', input), + |input| custom_value_paren('{', '}', input), + |input| custom_value_paren('(', ')', input), map(sass_string_dq, |mut s| { s.prepend("\""); s.append_str("\""); @@ -91,14 +80,14 @@ pub fn custom_value_inner(input: Span) -> PResult> { )(input) } -fn custom_value_paren<'a>( - start: &'static str, - end: &'static str, - input: Span<'a>, -) -> PResult<'a, Vec> { +fn custom_value_paren( + start: char, + end: char, + input: Span, +) -> PResult> { map( delimited( - tag(start), + char(start), fold_many0( alt(( map(tag(";"), |_| vec![StringPart::from(";")]), @@ -110,7 +99,7 @@ fn custom_value_paren<'a>( acc }, ), - tag(end), + cut(char(end)), ), |mut parts| { parts.push(StringPart::Raw(end.into())); @@ -431,6 +420,8 @@ fn is_ext_str_start_char(c: &char) -> bool { || *c == '=' || *c == '?' || *c == '|' + || *c == '<' + || *c == '>' } fn is_ext_str_char(c: &char) -> bool { is_name_char(c) @@ -443,13 +434,18 @@ fn is_ext_str_char(c: &char) -> bool { || *c == '=' || *c == '?' || *c == '|' + || *c == '<' + || *c == '>' + || *c == '\\' } pub fn name(input: Span) -> PResult { + let (input, first) = + verify(alt((escaped_char, take_char)), is_name_start_char)(input)?; verify( fold_many0( alt((escaped_char, name_char)), - String::new, + move || String::from(first), |mut s, c| { s.push(c); s @@ -482,21 +478,31 @@ fn escaped_char(input: Span) -> PResult { alt(( value('\\', tag("\\")), map_opt( - map_res( - map_res( - terminated( - recognize(many_m_n( - 1, - 6, - one_of("0123456789ABCDEFabcdef"), - )), - opt(tag(" ")), + pair( + recognize(many_m_n( + 1, + 6, + one_of("0123456789ABCDEFabcdef"), + )), + alt(( + value(true, tag(" ")), + value( + true, + peek(not(one_of("0123456789ABCDEFabcdef"))), ), - input_to_str, - ), - |s| u32::from_str_radix(s, 16), + value(false, tag("")), + )), ), - std::char::from_u32, + |(code, term): (Span, bool)| { + if term || code.len() == 6 { + std::char::from_u32( + u32::from_str_radix(input_to_str(code).ok()?, 16) + .ok()?, + ) + } else { + None + } + }, ), take_char, )), @@ -522,3 +528,6 @@ fn single_char(data: Span) -> Option { fn is_name_char(c: &char) -> bool { c.is_alphanumeric() || *c == '_' || *c == '-' } +fn is_name_start_char(c: &char) -> bool { + c.is_alphabetic() || *c == '_' || *c == '-' +} diff --git a/rsass/src/parser/util.rs b/rsass/src/parser/util.rs index 6ed01ff3c..7b2d7e9b0 100644 --- a/rsass/src/parser/util.rs +++ b/rsass/src/parser/util.rs @@ -2,8 +2,8 @@ use super::{PResult, Span}; use crate::sass::{SassString, StringPart}; use nom::branch::alt; use nom::bytes::complete::{is_not, tag}; -use nom::character::complete::multispace1; -use nom::combinator::{all_consuming, map, map_res, not, opt, peek}; +use nom::character::complete::{char, multispace1}; +use nom::combinator::{eof, map, map_res, not, opt, peek}; use nom::multi::{fold_many0, fold_many1, many0}; use nom::sequence::{preceded, terminated}; use std::str::from_utf8; @@ -18,9 +18,13 @@ where } pub fn semi_or_end(input: Span) -> PResult<()> { - terminated( + preceded( opt_spacelike, - alt((tag(";"), all_consuming(tag("")), peek(tag("}")))), + alt(( + map(terminated(ignore_comments, eof), |_| ()), + map(peek(char('}')), |_| ()), + map(char(';'), |_| ()), + )), )(input) } diff --git a/rsass/src/parser/value.rs b/rsass/src/parser/value.rs index e384c83b1..e78540b0b 100644 --- a/rsass/src/parser/value.rs +++ b/rsass/src/parser/value.rs @@ -2,7 +2,7 @@ use super::css_function::css_function; use super::formalargs::call_args; use super::strings::{ name, sass_string_dq, sass_string_ext, sass_string_sq, - special_function_misc, special_url, var_name, + special_function_misc, special_url, }; use super::unit::unit; use super::util::{ignore_comments, opt_spacelike, spacelike2}; @@ -14,11 +14,12 @@ use crate::value::{ListSeparator, Number, Numeric, Operator, Rgba}; use nom::branch::alt; use nom::bytes::complete::{tag, tag_no_case}; use nom::character::complete::{ - alphanumeric1, multispace0, multispace1, one_of, + alphanumeric1, char, multispace0, multispace1, one_of, }; use nom::combinator::{ - into, map, map_res, not, opt, peek, recognize, value, verify, + cut, into, map, map_res, not, opt, peek, recognize, value, verify, }; +use nom::error::{context, ParseError, VerboseError}; use nom::multi::{fold_many0, fold_many1, many0, many_m_n, separated_list1}; use nom::sequence::{delimited, pair, preceded, terminated, tuple}; use num_traits::Zero; @@ -79,7 +80,13 @@ pub fn simple_space_list(input: Span) -> PResult { } fn se_or_ext_string(input: Span) -> PResult { - alt((single_expression, map(sass_string_ext, Value::Literal)))(input) + let result = single_expression(input); + if matches!(result, Err(nom::Err::Error(_))) { + if let Ok((rest, lit)) = sass_string_ext(input) { + return Ok((rest, Value::Literal(lit))); + } + } + result } fn single_expression(input: Span) -> PResult { @@ -210,6 +217,7 @@ pub fn single_value(input: Span) -> PResult { Some(b'\'') => map(sass_string_sq, Value::Literal)(input), Some(b'[') => bracket_list(input), Some(b'(') => value_in_parens(input), + Some(b'$') => variable_nomod(input), _ => alt(( value(Value::True, tag("true")), value(Value::False, tag("false")), @@ -220,23 +228,23 @@ pub fn single_value(input: Span) -> PResult { value(Value::Null, tag("null")), map(special_url, Value::Literal), special_function, - // Really ugly special case ... sorry. - value(Value::Literal("-null".into()), tag("-null")), - map(var_name, Value::Literal), - unary_op, function_call_or_string, + unary_op, ))(input), } } fn bang(input: Span) -> PResult { map( - map_res( - preceded( - pair(tag("!"), opt_spacelike), - tag("important"), // TODO Pretty much anythig goes, here? + context( + "Expected \"important\".", + map_res( + preceded( + pair(tag("!"), opt_spacelike), + tag("important"), // TODO Pretty much anythig goes, here? + ), + input_to_string, ), - input_to_string, ), Value::Bang, )(input) @@ -305,7 +313,7 @@ pub(crate) fn unicode_range_inner(input: Span) -> PResult { pub fn bracket_list(input: Span) -> PResult { let (input, content) = - delimited(tag("["), opt(value_expression), tag("]"))(input)?; + delimited(char('['), opt(value_expression), char(']'))(input)?; Ok(( input, match content { @@ -401,10 +409,17 @@ pub fn decimal_decimals(input: Span) -> PResult { )(input) } +pub fn variable_nomod(input: Span) -> PResult { + let (rest, name) = + preceded(tag("$"), context("Expected identifier.", name))(input)?; + let pos = input.up_to(&rest).to_owned(); + Ok((rest, Value::Variable(name.into(), pos))) +} + pub fn variable(input: Span) -> PResult { let (rest, (modules, name)) = pair( many0(terminated(name, tag("."))), - preceded(tag("$"), name), + preceded(tag("$"), cut(context("Expected identifier.", name))), )(input)?; let name = if modules.is_empty() { name @@ -470,20 +485,59 @@ pub fn special_function(input: Span) -> PResult { } pub fn function_call_or_string(input: Span) -> PResult { + function_call_or_string_real(input, true) +} +pub fn function_call_or_string_rulearg(input: Span) -> PResult { + function_call_or_string_real(input, false) +} +fn function_call_or_string_real( + input: Span, + allow_not: bool, +) -> PResult { let (rest, name) = sass_string(input)?; - /* TODO: true, false and null should end up here, but can't as long as '.' is a normal part of a string. - if let Some(special) = name.single_raw().and_then(|s| match s { - "true" => return Some(Value::True), - "false" => return Some(Value::False), - "null" => return Some(Value::Null), - _ => None, - }) { - return Ok((rest, special)); - } - */ - if let Ok((rest, args)) = call_args(rest) { - let pos = input.up_to(&rest).to_owned(); - return Ok((rest, Value::Call(name, args, pos))); + + if let Some(val) = name.single_raw() { + match val { + "-" => { + return Err(nom::Err::Error(VerboseError::from_error_kind( + input, + nom::error::ErrorKind::Alpha, + ))); + } + "not" if allow_not => { + if let Ok((rest, arg)) = preceded( + terminated(spacelike2, ignore_comments), + single_value, + )(rest) + { + return Ok(( + rest, + Value::UnaryOp(Operator::Not, Box::new(arg)), + )); + } + } + /* TODO: true, false and null should end up here, but can't as long as '.' is a normal part of a string. + "true" => return Ok((rest, Value::True)), + "false" => return Ok((rest, Value::False)), + "null" => return Ok((rest, Value::Null)), + */ + _ => (), + } + } + if rest.starts_with(b"(") { + match call_args(rest) { + Ok((rest, args)) => { + let pos = input.up_to(&rest).to_owned(); + return Ok((rest, Value::Call(name, args, pos))); + } + Err(error) => { + if let Ok((rest, lit)) = sass_string_ext(rest) { + return Ok((rest, Value::Literal(lit))); + } else { + return Err(error); + } + } + } } Ok((rest, literal_or_color(name))) } @@ -493,6 +547,9 @@ fn literal_or_color(s: SassString) -> Value { if val == "infinity" { return Value::scalar(f64::INFINITY); } + if val == "-infinity" { + return Value::scalar(f64::NEG_INFINITY); + } if val == "NaN" { return Value::scalar(f64::NAN); } diff --git a/rsass/tests/misc/css_parser.rs b/rsass/tests/misc/css_parser.rs index 8c096a1a1..4a55b5e04 100644 --- a/rsass/tests/misc/css_parser.rs +++ b/rsass/tests/misc/css_parser.rs @@ -15,7 +15,7 @@ fn error_in_right_place() { // Note: The error message should be better, but this is a good place for it. // Specifically, the marker should _not_ indicate the opening brace. Err(String::from( - "Error: Parse error: Tag\ + "Error: Parse error: Nom(Tag)\ \n ,\ \n5 | error here\ \n | ^\ diff --git a/rsass/tests/spec/core_functions/meta/load_css/error/from_other.rs b/rsass/tests/spec/core_functions/meta/load_css/error/from_other.rs index cf07cca87..b2287097a 100644 --- a/rsass/tests/spec/core_functions/meta/load_css/error/from_other.rs +++ b/rsass/tests/spec/core_functions/meta/load_css/error/from_other.rs @@ -47,7 +47,6 @@ fn runtime() { ); } #[test] -#[ignore] // wrong error fn syntax() { let runner = runner().with_cwd("syntax"); assert_eq!( diff --git a/rsass/tests/spec/css/custom_properties/error.rs b/rsass/tests/spec/css/custom_properties/error.rs index bce43d397..3a21cc657 100644 --- a/rsass/tests/spec/css/custom_properties/error.rs +++ b/rsass/tests/spec/css/custom_properties/error.rs @@ -10,7 +10,6 @@ mod brackets { use super::runner; #[test] - #[ignore] // wrong error fn curly() { assert_eq!( runner().err( @@ -27,7 +26,6 @@ mod brackets { ); } #[test] - #[ignore] // wrong error fn curly_in_square() { assert_eq!( runner().err( @@ -44,7 +42,6 @@ mod brackets { ); } #[test] - #[ignore] // wrong error fn paren() { assert_eq!( runner().err( @@ -61,7 +58,6 @@ mod brackets { ); } #[test] - #[ignore] // wrong error fn paren_in_curly() { assert_eq!( runner().err( @@ -78,7 +74,6 @@ mod brackets { ); } #[test] - #[ignore] // wrong error fn square() { assert_eq!( runner().err( @@ -95,7 +90,6 @@ mod brackets { ); } #[test] - #[ignore] // wrong error fn square_in_paren() { assert_eq!( runner().err( @@ -113,7 +107,6 @@ mod brackets { } } #[test] -#[ignore] // wrong error fn empty() { assert_eq!( runner().err( diff --git a/rsass/tests/spec/css/functions/var.rs b/rsass/tests/spec/css/functions/var.rs index 51ee65a33..fa1beb9ae 100644 --- a/rsass/tests/spec/css/functions/var.rs +++ b/rsass/tests/spec/css/functions/var.rs @@ -190,7 +190,6 @@ mod error { ); } #[test] - #[ignore] // wrong error fn empty_second_before_third() { let runner = runner().with_cwd("empty_second_before_third"); assert_eq!( @@ -204,7 +203,6 @@ mod error { ); } #[test] - #[ignore] // wrong error fn invalid_second_arg_syntax() { let runner = runner().with_cwd("invalid_second_arg_syntax"); assert_eq!( diff --git a/rsass/tests/spec/css/moz_document/comment.rs b/rsass/tests/spec/css/moz_document/comment.rs index 8ccafae17..9335b38a2 100644 --- a/rsass/tests/spec/css/moz_document/comment.rs +++ b/rsass/tests/spec/css/moz_document/comment.rs @@ -18,7 +18,6 @@ mod after_arg { ); } #[test] - #[ignore] // wrong result fn silent() { assert_eq!( runner().ok("@-moz-document url-prefix(a) //\ @@ -32,7 +31,6 @@ mod before_arg { use super::runner; #[test] - #[ignore] // wrong result fn loud() { assert_eq!( runner().ok("@-moz-document /**/ url-prefix(a) {}\n"), diff --git a/rsass/tests/spec/css/supports/comment.rs b/rsass/tests/spec/css/supports/comment.rs index 7d21846b0..154314854 100644 --- a/rsass/tests/spec/css/supports/comment.rs +++ b/rsass/tests/spec/css/supports/comment.rs @@ -22,7 +22,6 @@ mod after_query { ); } #[test] - #[ignore] // wrong result fn silent() { assert_eq!( runner().ok("@supports (a: b) //\ @@ -134,7 +133,6 @@ mod before_query { use super::runner; #[test] - #[ignore] // wrong result fn loud() { assert_eq!( runner().ok("@supports /**/ (a: b) {c {d: e}}\n"), @@ -442,6 +440,7 @@ mod function { use super::runner; #[test] + #[ignore] // unexepected error fn loud() { assert_eq!( runner().ok("@supports a(b /**/) {c {d: e}}\n"), diff --git a/rsass/tests/spec/css/supports/syntax/function.rs b/rsass/tests/spec/css/supports/syntax/function.rs index 967547116..17c2e91b7 100644 --- a/rsass/tests/spec/css/supports/syntax/function.rs +++ b/rsass/tests/spec/css/supports/syntax/function.rs @@ -51,7 +51,6 @@ mod interpolated_value { ); } #[test] - #[ignore] // unexepected error fn partial() { assert_eq!( runner().ok("@supports a(<#{1 + 1}>) {@c}\n"), diff --git a/rsass/tests/spec/css/unknown_directive/comment.rs b/rsass/tests/spec/css/unknown_directive/comment.rs index 61685f504..628b40a26 100644 --- a/rsass/tests/spec/css/unknown_directive/comment.rs +++ b/rsass/tests/spec/css/unknown_directive/comment.rs @@ -18,7 +18,6 @@ mod children { assert_eq!(runner().ok("@a b /**/ {}\n"), "@a b /**/ {}\n"); } #[test] - #[ignore] // wrong result fn silent() { assert_eq!( runner().ok("@a b //\ @@ -32,7 +31,6 @@ mod children { use super::runner; #[test] - #[ignore] // wrong result fn loud() { assert_eq!(runner().ok("@a /**/ b {}\n"), "@a b {}\n"); } @@ -50,7 +48,6 @@ mod children { use super::runner; #[test] - #[ignore] // wrong result fn loud() { assert_eq!(runner().ok("@a /**/ {}\n"), "@a {}\n"); } @@ -77,7 +74,6 @@ mod no_children { assert_eq!(runner().ok("@a b /**/\n"), "@a b /**/;\n"); } #[test] - #[ignore] // wrong result fn silent() { assert_eq!(runner().ok("@a b //\n"), "@a b;\n"); } @@ -87,7 +83,6 @@ mod no_children { use super::runner; #[test] - #[ignore] // wrong result fn loud() { assert_eq!(runner().ok("@a /**/ b\n"), "@a b;\n"); } @@ -105,7 +100,6 @@ mod no_children { use super::runner; #[test] - #[ignore] // wrong result fn loud() { assert_eq!(runner().ok("@a /**/\n"), "@a;\n"); } diff --git a/rsass/tests/spec/directives/forward/comment.rs b/rsass/tests/spec/directives/forward/comment.rs index 609388300..42b36c6e9 100644 --- a/rsass/tests/spec/directives/forward/comment.rs +++ b/rsass/tests/spec/directives/forward/comment.rs @@ -33,7 +33,6 @@ mod after_close_paren { } #[test] - #[ignore] // unexepected error fn loud() { let runner = runner().with_cwd("loud"); assert_eq!(runner.ok("@forward \"other\" with ($a: b) /**/\n"), ""); @@ -72,7 +71,6 @@ mod after_keyword { } #[test] - #[ignore] // unexepected error fn loud() { let runner = runner().with_cwd("loud"); assert_eq!(runner.ok("@forward \"other\" as /**/ a-*\n"), ""); @@ -94,7 +92,6 @@ mod after_modifier { } #[test] - #[ignore] // unexepected error fn loud() { let runner = runner().with_cwd("loud"); assert_eq!(runner.ok("@forward \"other\" as a-* /**/\n"), ""); @@ -112,7 +109,6 @@ mod after_open_paren { } #[test] - #[ignore] // unexepected error fn loud() { let runner = runner().with_cwd("loud"); assert_eq!(runner.ok("@forward \"other\" with (/**/ $a: b)\n"), ""); @@ -141,7 +137,6 @@ mod after_url { } #[test] - #[ignore] // unexepected error fn loud() { let runner = runner().with_cwd("loud"); assert_eq!(runner.ok("@forward \"other\" /**/\n"), ""); @@ -159,7 +154,6 @@ mod before_close_paren { } #[test] - #[ignore] // unexepected error fn loud() { let runner = runner().with_cwd("loud"); assert_eq!(runner.ok("@forward \"other\" with ($a: b /**/)\n"), ""); @@ -181,7 +175,6 @@ mod before_colon { } #[test] - #[ignore] // unexepected error fn loud() { let runner = runner().with_cwd("loud"); assert_eq!(runner.ok("@forward \"other\" with ($a /**/ : b)\n"), ""); @@ -203,7 +196,6 @@ mod before_keyword { } #[test] - #[ignore] // unexepected error fn loud() { let runner = runner().with_cwd("loud"); assert_eq!(runner.ok("@forward \"other\" /**/ as a-*\n"), ""); @@ -225,7 +217,6 @@ mod before_url { } #[test] - #[ignore] // unexepected error fn loud() { let runner = runner().with_cwd("loud"); assert_eq!(runner.ok("@forward /**/ \"other\"\n"), ""); diff --git a/rsass/tests/spec/directives/forward/error/member/inaccessible.rs b/rsass/tests/spec/directives/forward/error/member/inaccessible.rs index 84e3c4e2a..1ef37d658 100644 --- a/rsass/tests/spec/directives/forward/error/member/inaccessible.rs +++ b/rsass/tests/spec/directives/forward/error/member/inaccessible.rs @@ -327,6 +327,7 @@ mod private { } #[test] + #[ignore] // wrong result fn function() { let runner = runner().with_cwd("function"); assert_eq!( diff --git a/rsass/tests/spec/directives/forward/error/syntax.rs b/rsass/tests/spec/directives/forward/error/syntax.rs index f20fcf2d3..a211ebc6b 100644 --- a/rsass/tests/spec/directives/forward/error/syntax.rs +++ b/rsass/tests/spec/directives/forward/error/syntax.rs @@ -157,7 +157,6 @@ mod test_as { } } #[test] -#[ignore] // wrong error fn empty() { assert_eq!( runner().err("@forward;\n"), @@ -174,7 +173,6 @@ mod hide { use super::runner; #[test] - #[ignore] // wrong error fn and_show() { assert_eq!( runner().err("@forward \"a\" hide b show c;\n"), @@ -187,7 +185,6 @@ mod hide { ); } #[test] - #[ignore] // wrong error fn empty_variable() { assert_eq!( runner().err("@forward \"a\" hide $;\n"), @@ -200,7 +197,6 @@ mod hide { ); } #[test] - #[ignore] // wrong error fn invalid() { assert_eq!( runner().err("@forward \"a\" hide 1;\n"), @@ -213,7 +209,6 @@ mod hide { ); } #[test] - #[ignore] // wrong error fn nothing() { assert_eq!( runner().err("@forward \"a\" hide;\n"), @@ -226,7 +221,6 @@ mod hide { ); } #[test] - #[ignore] // wrong error fn trailing_comma() { assert_eq!( runner().err("@forward \"a\" hide b,;\n"), @@ -244,7 +238,6 @@ mod show { use super::runner; #[test] - #[ignore] // wrong error fn and_hide() { assert_eq!( runner().err("@forward \"a\" show b hide c;\n"), @@ -257,7 +250,6 @@ mod show { ); } #[test] - #[ignore] // wrong error fn empty_variable() { assert_eq!( runner().err("@forward \"a\" show $;\n"), @@ -270,7 +262,6 @@ mod show { ); } #[test] - #[ignore] // wrong error fn invalid() { assert_eq!( runner().err("@forward \"a\" show 1;\n"), @@ -283,7 +274,6 @@ mod show { ); } #[test] - #[ignore] // wrong error fn nothing() { assert_eq!( runner().err("@forward \"a\" show;\n"), @@ -296,7 +286,6 @@ mod show { ); } #[test] - #[ignore] // wrong error fn trailing_comma() { assert_eq!( runner().err("@forward \"a\" show b,;\n"), @@ -314,7 +303,6 @@ mod url { use super::runner; #[test] - #[ignore] // wrong error fn unquoted() { assert_eq!( runner().err("@forward foo;\n"), @@ -384,7 +372,6 @@ mod with { ); } #[test] - #[ignore] // wrong error fn extra_comma() { assert_eq!( runner().err("@forward \"other\" with ($a: b,,);\n"), @@ -436,7 +423,6 @@ mod with { ); } #[test] - #[ignore] // wrong error fn no_arguments() { assert_eq!( runner().err("@forward \"other\" with;\n"), diff --git a/rsass/tests/spec/directives/function.rs b/rsass/tests/spec/directives/function.rs index 9876a71c2..9b772bab2 100644 --- a/rsass/tests/spec/directives/function.rs +++ b/rsass/tests/spec/directives/function.rs @@ -18,7 +18,6 @@ mod comment { use super::runner; #[test] - #[ignore] // unexepected error fn loud() { assert_eq!(runner().ok("@function a() /**/ {}\n"), ""); } @@ -36,7 +35,6 @@ mod comment { use super::runner; #[test] - #[ignore] // unexepected error fn loud() { assert_eq!(runner().ok("@function /**/ a() {}\n"), ""); } @@ -100,7 +98,6 @@ mod comment { } } #[test] -#[ignore] // wrong result fn custom_ident_call() { assert_eq!( runner().ok("@function __a() {@return 1}\ @@ -111,7 +108,6 @@ fn custom_ident_call() { ); } #[test] -#[ignore] // wrong result fn custom_ident_name() { assert_eq!( runner().ok("@function --a() {@return 1}\ @@ -150,7 +146,6 @@ mod vendor_like_underscore { use super::runner; #[test] - #[ignore] // wrong result fn middle() { assert_eq!( runner().ok("@function -moz_calc() {@return 1}\ diff --git a/rsass/tests/spec/directives/import/comment.rs b/rsass/tests/spec/directives/import/comment.rs index fb473df32..e1d68d522 100644 --- a/rsass/tests/spec/directives/import/comment.rs +++ b/rsass/tests/spec/directives/import/comment.rs @@ -32,7 +32,6 @@ mod after_url { use super::runner; #[test] - #[ignore] // unexepected error fn loud() { assert_eq!( runner().ok("@import \"a.css\" /**/\n"), @@ -76,7 +75,6 @@ mod before_url { use super::runner; #[test] - #[ignore] // wrong result fn loud() { assert_eq!( runner().ok("@import /**/ \"a.css\"\n"), @@ -105,7 +103,6 @@ mod modifier { use super::runner; #[test] - #[ignore] // unexepected error fn loud() { assert_eq!( runner().ok("@import \"a.css\" b(c) /**/\n"), @@ -189,7 +186,6 @@ mod modifier { use super::runner; #[test] - #[ignore] // unexepected error fn loud() { assert_eq!( runner().ok("@import \"a.css\" b /**/\n"), diff --git a/rsass/tests/spec/directives/mixin.rs b/rsass/tests/spec/directives/mixin.rs index ff7b51d50..3c2010c8e 100644 --- a/rsass/tests/spec/directives/mixin.rs +++ b/rsass/tests/spec/directives/mixin.rs @@ -59,7 +59,6 @@ mod comment { use super::runner; #[test] - #[ignore] // wrong result fn loud() { assert_eq!( runner().ok("@mixin a {}\ @@ -81,7 +80,6 @@ mod comment { use super::runner; #[test] - #[ignore] // wrong result fn loud() { assert_eq!( runner().ok("@mixin a {}\ @@ -172,7 +170,6 @@ mod comment { use super::runner; #[test] - #[ignore] // unexepected error fn loud() { assert_eq!( runner().ok("@mixin a {}\ @@ -241,7 +238,6 @@ mod comment { use super::runner; #[test] - #[ignore] // unexepected error fn loud() { assert_eq!(runner().ok("@mixin /**/ a {}\n"), ""); } diff --git a/rsass/tests/spec/directives/test_for.rs b/rsass/tests/spec/directives/test_for.rs index 8a57b9c13..1b1efbda9 100644 --- a/rsass/tests/spec/directives/test_for.rs +++ b/rsass/tests/spec/directives/test_for.rs @@ -119,7 +119,6 @@ mod comment { use super::runner; #[test] - #[ignore] // unexepected error fn loud() { assert_eq!( runner().ok("@for /**/ $i from 1 through 10 {}\n"), diff --git a/rsass/tests/spec/directives/test_if/error/syntax.rs b/rsass/tests/spec/directives/test_if/error/syntax.rs index ee7276187..a6b1a810e 100644 --- a/rsass/tests/spec/directives/test_if/error/syntax.rs +++ b/rsass/tests/spec/directives/test_if/error/syntax.rs @@ -10,7 +10,6 @@ mod test_else { use super::runner; #[test] - #[ignore] // wrong error fn partial_if() { assert_eq!( runner().err( diff --git a/rsass/tests/spec/directives/test_use/comment.rs b/rsass/tests/spec/directives/test_use/comment.rs index 64b01ae4a..f43c5cd37 100644 --- a/rsass/tests/spec/directives/test_use/comment.rs +++ b/rsass/tests/spec/directives/test_use/comment.rs @@ -33,7 +33,6 @@ mod after_close_paren { } #[test] - #[ignore] // unexepected error fn loud() { let runner = runner().with_cwd("loud"); assert_eq!(runner.ok("@use \"other\" with ($a: b) /**/\n"), ""); @@ -72,7 +71,6 @@ mod after_keyword { } #[test] - #[ignore] // unexepected error fn loud() { let runner = runner().with_cwd("loud"); assert_eq!(runner.ok("@use \"other\" as /**/ a\n"), ""); @@ -94,7 +92,6 @@ mod after_modifier { } #[test] - #[ignore] // unexepected error fn loud() { let runner = runner().with_cwd("loud"); assert_eq!(runner.ok("@use \"other\" as a /**/\n"), ""); @@ -112,7 +109,6 @@ mod after_open_paren { } #[test] - #[ignore] // unexepected error fn loud() { let runner = runner().with_cwd("loud"); assert_eq!(runner.ok("@use \"other\" with (/**/ $a: b)\n"), ""); @@ -141,7 +137,6 @@ mod after_url { } #[test] - #[ignore] // unexepected error fn loud() { let runner = runner().with_cwd("loud"); assert_eq!(runner.ok("@use \"other\" /**/\n"), ""); @@ -159,7 +154,6 @@ mod before_close_paren { } #[test] - #[ignore] // unexepected error fn loud() { let runner = runner().with_cwd("loud"); assert_eq!(runner.ok("@use \"other\" with ($a: b /**/)\n"), ""); @@ -181,7 +175,6 @@ mod before_colon { } #[test] - #[ignore] // unexepected error fn loud() { let runner = runner().with_cwd("loud"); assert_eq!(runner.ok("@use \"other\" with ($a /**/ : b)\n"), ""); @@ -225,7 +218,6 @@ mod before_url { } #[test] - #[ignore] // unexepected error fn loud() { let runner = runner().with_cwd("loud"); assert_eq!(runner.ok("@use /**/ \"other\"\n"), ""); diff --git a/rsass/tests/spec/directives/test_use/error/member/inaccessible.rs b/rsass/tests/spec/directives/test_use/error/member/inaccessible.rs index a292f7bb5..dd2bab510 100644 --- a/rsass/tests/spec/directives/test_use/error/member/inaccessible.rs +++ b/rsass/tests/spec/directives/test_use/error/member/inaccessible.rs @@ -64,6 +64,7 @@ mod private { } #[test] + #[ignore] // wrong result fn function() { let runner = runner().with_cwd("function"); assert_eq!( diff --git a/rsass/tests/spec/directives/test_use/error/syntax/empty.rs b/rsass/tests/spec/directives/test_use/error/syntax/empty.rs index 7d6123a04..aeddeea57 100644 --- a/rsass/tests/spec/directives/test_use/error/syntax/empty.rs +++ b/rsass/tests/spec/directives/test_use/error/syntax/empty.rs @@ -6,7 +6,6 @@ fn runner() -> crate::TestRunner { } #[test] -#[ignore] // wrong error fn test() { assert_eq!( runner().err("@use;\n"), diff --git a/rsass/tests/spec/directives/test_use/error/syntax/member.rs b/rsass/tests/spec/directives/test_use/error/syntax/member.rs index 78edf816d..b2038720c 100644 --- a/rsass/tests/spec/directives/test_use/error/syntax/member.rs +++ b/rsass/tests/spec/directives/test_use/error/syntax/member.rs @@ -10,7 +10,6 @@ mod function { use super::runner; #[test] - #[ignore] // wrong error fn definition() { assert_eq!( runner().err("@function namespace.member() {@return null}\n"), @@ -86,7 +85,6 @@ mod mixin { use super::runner; #[test] - #[ignore] // wrong error fn definition() { assert_eq!( runner().err("@mixin namespace.member() {}\n"), @@ -177,7 +175,6 @@ mod variable { ); } #[test] - #[ignore] // wrong error fn no_member() { assert_eq!( runner().err("a {a: namespace.$}\n"), @@ -190,7 +187,6 @@ mod variable { ); } #[test] - #[ignore] // wrong error fn no_namespace() { assert_eq!( runner().err("a {a: $.member}\n"), diff --git a/rsass/tests/spec/directives/test_use/error/syntax/url.rs b/rsass/tests/spec/directives/test_use/error/syntax/url.rs index b797088ab..2b7a6c03f 100644 --- a/rsass/tests/spec/directives/test_use/error/syntax/url.rs +++ b/rsass/tests/spec/directives/test_use/error/syntax/url.rs @@ -38,7 +38,6 @@ fn non_identifier() { ); } #[test] -#[ignore] // wrong error fn unquoted() { assert_eq!( runner().err("@use foo;\n"), diff --git a/rsass/tests/spec/directives/test_use/error/syntax/within.rs b/rsass/tests/spec/directives/test_use/error/syntax/within.rs index e7aac92dd..e97a328b4 100644 --- a/rsass/tests/spec/directives/test_use/error/syntax/within.rs +++ b/rsass/tests/spec/directives/test_use/error/syntax/within.rs @@ -6,7 +6,6 @@ fn runner() -> crate::TestRunner { } #[test] -#[ignore] // wrong error fn function() { assert_eq!( runner().err( diff --git a/rsass/tests/spec/non_conformant/mixin/content/arguments/error/syntax.rs b/rsass/tests/spec/non_conformant/mixin/content/arguments/error/syntax.rs index 3b13b10d7..754c390b8 100644 --- a/rsass/tests/spec/non_conformant/mixin/content/arguments/error/syntax.rs +++ b/rsass/tests/spec/non_conformant/mixin/content/arguments/error/syntax.rs @@ -10,7 +10,6 @@ mod arglist { use super::runner; #[test] - #[ignore] // wrong error fn invalid() { assert_eq!( runner().err( @@ -28,7 +27,6 @@ mod arglist { ); } #[test] - #[ignore] // wrong error fn missing() { assert_eq!( runner().err( @@ -46,7 +44,6 @@ mod arglist { ); } #[test] - #[ignore] // wrong error fn missing_parens() { assert_eq!( runner().err( @@ -65,7 +62,6 @@ mod arglist { } } #[test] -#[ignore] // wrong error fn missing_block() { assert_eq!( runner().err( @@ -83,7 +79,6 @@ fn missing_block() { ); } #[test] -#[ignore] // wrong error fn missing_using() { assert_eq!( runner().err( diff --git a/rsass/tests/spec/non_conformant/parser/arglists/can_end_with_comma/error_call_1.rs b/rsass/tests/spec/non_conformant/parser/arglists/can_end_with_comma/error_call_1.rs index f5b2cc10f..969680d92 100644 --- a/rsass/tests/spec/non_conformant/parser/arglists/can_end_with_comma/error_call_1.rs +++ b/rsass/tests/spec/non_conformant/parser/arglists/can_end_with_comma/error_call_1.rs @@ -6,7 +6,6 @@ fn runner() -> crate::TestRunner { } #[test] -#[ignore] // wrong error fn test() { assert_eq!( runner().err( diff --git a/rsass/tests/spec/non_conformant/parser/arglists/can_end_with_comma/error_call_2.rs b/rsass/tests/spec/non_conformant/parser/arglists/can_end_with_comma/error_call_2.rs index 92077b90f..482d60a86 100644 --- a/rsass/tests/spec/non_conformant/parser/arglists/can_end_with_comma/error_call_2.rs +++ b/rsass/tests/spec/non_conformant/parser/arglists/can_end_with_comma/error_call_2.rs @@ -6,7 +6,6 @@ fn runner() -> crate::TestRunner { } #[test] -#[ignore] // wrong error fn test() { assert_eq!( runner().err( diff --git a/rsass/tests/spec/non_conformant/parser/arglists/can_end_with_comma/error_call_3.rs b/rsass/tests/spec/non_conformant/parser/arglists/can_end_with_comma/error_call_3.rs index c6a8f7702..06bc2eb01 100644 --- a/rsass/tests/spec/non_conformant/parser/arglists/can_end_with_comma/error_call_3.rs +++ b/rsass/tests/spec/non_conformant/parser/arglists/can_end_with_comma/error_call_3.rs @@ -6,7 +6,6 @@ fn runner() -> crate::TestRunner { } #[test] -#[ignore] // wrong error fn test() { assert_eq!( runner().err( diff --git a/rsass/tests/spec/non_conformant/parser/arglists/can_end_with_comma/error_include_1.rs b/rsass/tests/spec/non_conformant/parser/arglists/can_end_with_comma/error_include_1.rs index 039306662..1df0b0fc0 100644 --- a/rsass/tests/spec/non_conformant/parser/arglists/can_end_with_comma/error_include_1.rs +++ b/rsass/tests/spec/non_conformant/parser/arglists/can_end_with_comma/error_include_1.rs @@ -6,7 +6,6 @@ fn runner() -> crate::TestRunner { } #[test] -#[ignore] // wrong error fn test() { assert_eq!( runner().err( diff --git a/rsass/tests/spec/non_conformant/parser/arglists/can_end_with_comma/error_include_2.rs b/rsass/tests/spec/non_conformant/parser/arglists/can_end_with_comma/error_include_2.rs index 2d32fa923..a7b3b5fc6 100644 --- a/rsass/tests/spec/non_conformant/parser/arglists/can_end_with_comma/error_include_2.rs +++ b/rsass/tests/spec/non_conformant/parser/arglists/can_end_with_comma/error_include_2.rs @@ -6,7 +6,6 @@ fn runner() -> crate::TestRunner { } #[test] -#[ignore] // wrong error fn test() { assert_eq!( runner().err( diff --git a/rsass/tests/spec/non_conformant/parser/arglists/can_end_with_comma/error_include_3.rs b/rsass/tests/spec/non_conformant/parser/arglists/can_end_with_comma/error_include_3.rs index 4a71d34fd..77f9282ba 100644 --- a/rsass/tests/spec/non_conformant/parser/arglists/can_end_with_comma/error_include_3.rs +++ b/rsass/tests/spec/non_conformant/parser/arglists/can_end_with_comma/error_include_3.rs @@ -6,7 +6,6 @@ fn runner() -> crate::TestRunner { } #[test] -#[ignore] // wrong error fn test() { assert_eq!( runner().err( diff --git a/rsass/tests/spec/values/calculation/calc/error/syntax.rs b/rsass/tests/spec/values/calculation/calc/error/syntax.rs index cc3eac79c..b0ad95de7 100644 --- a/rsass/tests/spec/values/calculation/calc/error/syntax.rs +++ b/rsass/tests/spec/values/calculation/calc/error/syntax.rs @@ -6,7 +6,6 @@ fn runner() -> crate::TestRunner { } #[test] -#[ignore] // wrong error fn dollar() { assert_eq!( runner().err("a {b: calc($)}\n"), @@ -61,7 +60,6 @@ mod interpolation { use super::runner; #[test] - #[ignore] // missing error fn in_function_arg() { assert_eq!( runner().err("a {b: calc(c(~#{d}))}\n"),