This commit is contained in:
ConnorSkees 2020-04-21 18:22:26 -04:00
parent 6a01eeb1d8
commit 3805eaab2b
15 changed files with 54 additions and 60 deletions

View File

@ -159,7 +159,7 @@ impl CallArgs {
) )
} }
pub fn span(&self) -> Span { pub const fn span(&self) -> Span {
self.1 self.1
} }

View File

@ -229,7 +229,7 @@ pub(crate) fn eat_include<I: Iterator<Item = Token>>(
Vec::new() Vec::new()
}; };
let mixin = scope.get_mixin(name)?.clone(); let mixin = scope.get_mixin(name)?;
let rules = mixin let rules = mixin
.args(args, scope, super_selector)? .args(args, scope, super_selector)?

View File

@ -308,7 +308,7 @@ pub(crate) fn register(f: &mut HashMap<String, Builtin>) {
}) })
.collect::<SassResult<Vec<Vec<Value>>>>()?; .collect::<SassResult<Vec<Vec<Value>>>>()?;
let len = lists.iter().map(|l| l.len()).min().unwrap_or(0); let len = lists.iter().map(Vec::len).min().unwrap_or(0);
if len == 0 { if len == 0 {
return Ok(Value::List( return Ok(Value::List(

View File

@ -186,7 +186,7 @@ pub(crate) fn register(f: &mut HashMap<String, Builtin>) {
Some(n) => n, Some(n) => n,
None => { None => {
return Err(( return Err((
format!("max must be in range 0 < max 2^32, was {}", limit), format!("max must be in range 0 < max \u{2264} 2^32, was {}", limit),
args.span(), args.span(),
) )
.into()) .into())

View File

@ -46,6 +46,7 @@ impl Display for SassError {
// TODO: trim whitespace from start of line shown in error // TODO: trim whitespace from start of line shown in error
// TODO: color errors // TODO: color errors
// TODO: integrate with codemap-diagnostics // TODO: integrate with codemap-diagnostics
#[inline]
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let (message, loc) = match &self.kind { let (message, loc) = match &self.kind {
SassErrorKind::ParseError { message, loc } => (message, loc), SassErrorKind::ParseError { message, loc } => (message, loc),
@ -75,6 +76,7 @@ impl Display for SassError {
} }
impl From<io::Error> for SassError { impl From<io::Error> for SassError {
#[inline]
fn from(error: io::Error) -> Self { fn from(error: io::Error) -> Self {
SassError { SassError {
kind: SassErrorKind::IoError(error), kind: SassErrorKind::IoError(error),
@ -91,6 +93,7 @@ impl From<std::fmt::Error> for SassError {
} }
impl From<FromUtf8Error> for SassError { impl From<FromUtf8Error> for SassError {
#[inline]
fn from(error: FromUtf8Error) -> Self { fn from(error: FromUtf8Error) -> Self {
SassError { SassError {
kind: SassErrorKind::FromUtf8Error(format!( kind: SassErrorKind::FromUtf8Error(format!(
@ -120,6 +123,7 @@ impl From<(String, Span)> for SassError {
} }
impl Error for SassError { impl Error for SassError {
#[inline]
fn description(&self) -> &'static str { fn description(&self) -> &'static str {
"SASS parsing error" "SASS parsing error"
} }

View File

@ -44,7 +44,7 @@ impl<'a> Iterator for Lexer<'a> {
impl<'a> Lexer<'a> { impl<'a> Lexer<'a> {
pub fn new(file: &'a Arc<File>) -> Lexer<'a> { pub fn new(file: &'a Arc<File>) -> Lexer<'a> {
Lexer { Lexer {
buf: file.source().clone().chars().peekable(), buf: file.source().chars().peekable(),
pos: 0, pos: 0,
file, file,
} }

View File

@ -77,6 +77,7 @@ grass input.scss
clippy::indexing_slicing, clippy::indexing_slicing,
clippy::match_same_arms, clippy::match_same_arms,
clippy::or_fun_call, clippy::or_fun_call,
clippy::redundant_pub_crate,
)] )]
#![cfg_attr(feature = "nightly", feature(track_caller))] #![cfg_attr(feature = "nightly", feature(track_caller))]
use std::fs; use std::fs;
@ -136,7 +137,7 @@ pub(crate) enum Stmt {
} }
impl Stmt { impl Stmt {
fn span(self, span: Span) -> Spanned<Self> { const fn span(self, span: Span) -> Spanned<Self> {
Spanned { node: self, span } Spanned { node: self, span }
} }
} }

View File

@ -14,7 +14,7 @@ pub(crate) fn read_until_char<I: Iterator<Item = Token>>(
while let Some(tok) = toks.next() { while let Some(tok) = toks.next() {
match tok.kind { match tok.kind {
'"' | '\'' => { '"' | '\'' => {
v.push(tok.clone()); v.push(tok);
v.extend(read_until_closing_quote(toks, tok.kind)); v.extend(read_until_closing_quote(toks, tok.kind));
continue; continue;
} }

View File

@ -31,7 +31,7 @@ pub(crate) fn eat_number<I: Iterator<Item = Token>>(
let mut dec = String::new(); let mut dec = String::new();
let next_tok = toks.peek().unwrap().clone(); let next_tok = *toks.peek().unwrap();
if next_tok.kind == '.' { if next_tok.kind == '.' {
toks.next(); toks.next();

View File

@ -128,7 +128,7 @@ pub(crate) fn read_until_semicolon_or_closing_curly_brace<I: Iterator<Item = Tok
} }
'"' | '\'' => { '"' | '\'' => {
let quote = toks.next().unwrap(); let quote = toks.next().unwrap();
t.push(quote.clone()); t.push(quote);
t.extend(read_until_closing_quote(toks, quote.kind)); t.extend(read_until_closing_quote(toks, quote.kind));
} }
'{' => { '{' => {
@ -174,7 +174,7 @@ pub(crate) fn read_until_semicolon_or_open_or_closing_curly_brace<I: Iterator<It
} }
'"' | '\'' => { '"' | '\'' => {
let quote = toks.next().unwrap(); let quote = toks.next().unwrap();
t.push(quote.clone()); t.push(quote);
t.extend(read_until_closing_quote(toks, quote.kind)); t.extend(read_until_closing_quote(toks, quote.kind));
} }
'#' => { '#' => {
@ -238,7 +238,7 @@ pub(crate) fn read_until_closing_paren<I: Iterator<Item = Token>>(
} }
'(' => scope += 1, '(' => scope += 1,
'"' | '\'' => { '"' | '\'' => {
v.push(tok.clone()); v.push(tok);
v.extend(read_until_closing_quote(toks, tok.kind)); v.extend(read_until_closing_quote(toks, tok.kind));
continue; continue;
} }
@ -266,7 +266,7 @@ pub(crate) fn read_until_closing_square_brace<I: Iterator<Item = Token>>(
} }
'[' => scope += 1, '[' => scope += 1,
'"' | '\'' => { '"' | '\'' => {
v.push(tok.clone()); v.push(tok);
v.extend(read_until_closing_quote(toks, tok.kind)); v.extend(read_until_closing_quote(toks, tok.kind));
continue; continue;
} }

View File

@ -23,7 +23,7 @@ fn ident_body_no_interpolation<I: Iterator<Item = Token>>(
if unit && tok.kind == '-' { if unit && tok.kind == '-' {
// Disallow `-` followed by a dot or a digit digit in units. // Disallow `-` followed by a dot or a digit digit in units.
let second = match toks.peek_forward(1) { let second = match toks.peek_forward(1) {
Some(v) => v.clone(), Some(v) => *v,
None => break, None => break,
}; };
@ -294,7 +294,7 @@ pub(crate) fn parse_quoted_string<I: Iterator<Item = Token>>(
toks.next(); toks.next();
} }
if value == 0 || (value >= 0xD800 && value <= 0xDFFF) || value >= 0x10FFFF { if value == 0 || (value >= 0xD800 && value <= 0xDFFF) || value >= 0x0010_FFFF {
s.push('\u{FFFD}'); s.push('\u{FFFD}');
} else { } else {
s.push(std::char::from_u32(value).unwrap()); s.push(std::char::from_u32(value).unwrap());

View File

@ -115,14 +115,14 @@ impl Value {
Self::BinaryOp(..) | Self::Paren(..) | Self::UnaryOp(..) => { Self::BinaryOp(..) | Self::Paren(..) | Self::UnaryOp(..) => {
self.clone().eval(span)?.is_null(span) self.clone().eval(span)?.is_null(span)
} }
Self::List(v, ..) => Ok(v.into_iter().all(|f| f.is_null(span).unwrap())), Self::List(v, ..) => Ok(v.iter().all(|f| f.is_null(span).unwrap())),
_ => Ok(false), _ => Ok(false),
} }
} }
pub fn to_css_string(&self, span: Span) -> SassResult<String> { pub fn to_css_string(&self, span: Span) -> SassResult<String> {
Ok(match self { Ok(match self {
Self::Important => format!("!important"), Self::Important => "!important".to_string(),
Self::Dimension(num, unit) => match unit { Self::Dimension(num, unit) => match unit {
Unit::Mul(..) => { Unit::Mul(..) => {
return Err((format!("{}{} isn't a valid CSS value.", num, unit), span).into()); return Err((format!("{}{} isn't a valid CSS value.", num, unit), span).into());
@ -138,14 +138,12 @@ impl Value {
} }
Self::Function(func) => format!("get-function(\"{}\")", func.name()), Self::Function(func) => format!("get-function(\"{}\")", func.name()),
Self::List(vals, sep, brackets) => match brackets { Self::List(vals, sep, brackets) => match brackets {
Brackets::None => format!( Brackets::None => vals
"{}", .iter()
vals.iter()
.filter(|x| !x.is_null(span).unwrap()) .filter(|x| !x.is_null(span).unwrap())
.map(|x| x.to_css_string(span)) .map(|x| x.to_css_string(span))
.collect::<SassResult<Vec<String>>>()? .collect::<SassResult<Vec<String>>>()?
.join(sep.as_str()), .join(sep.as_str()),
),
Brackets::Bracketed => format!( Brackets::Bracketed => format!(
"[{}]", "[{}]",
vals.iter() vals.iter()
@ -157,9 +155,9 @@ impl Value {
}, },
Self::Color(c) => format!("{}", c), Self::Color(c) => format!("{}", c),
Self::UnaryOp(..) | Self::BinaryOp(..) => { Self::UnaryOp(..) | Self::BinaryOp(..) => {
format!("{}", self.clone().eval(span)?.to_css_string(span)?) self.clone().eval(span)?.to_css_string(span)?
} }
Self::Paren(val) => format!("{}", val.to_css_string(span)?), Self::Paren(val) => val.to_css_string(span)?,
Self::Ident(string, QuoteKind::None) => { Self::Ident(string, QuoteKind::None) => {
let mut after_newline = false; let mut after_newline = false;
let mut buf = String::with_capacity(string.len()); let mut buf = String::with_capacity(string.len());
@ -190,14 +188,12 @@ impl Value {
Self::True => "true".to_string(), Self::True => "true".to_string(),
Self::False => "false".to_string(), Self::False => "false".to_string(),
Self::Null => String::new(), Self::Null => String::new(),
Self::ArgList(args) => format!( Self::ArgList(args) => args
"{}", .iter()
args.iter()
.filter(|x| !x.is_null(span).unwrap()) .filter(|x| !x.is_null(span).unwrap())
.map(|a| Ok(a.node.to_css_string(span)?)) .map(|a| Ok(a.node.to_css_string(span)?))
.collect::<SassResult<Vec<String>>>()? .collect::<SassResult<Vec<String>>>()?
.join(", "), .join(", "),
),
}) })
} }
@ -215,13 +211,13 @@ impl Value {
match self { match self {
Self::Ident(s1, _) => Self::Ident(s1, QuoteKind::None), Self::Ident(s1, _) => Self::Ident(s1, QuoteKind::None),
Self::List(v, sep, bracket) => { Self::List(v, sep, bracket) => {
Self::List(v.into_iter().map(|x| x.unquote()).collect(), sep, bracket) Self::List(v.into_iter().map(Value::unquote).collect(), sep, bracket)
} }
v => v, v => v,
} }
} }
pub fn span(self, span: Span) -> Spanned<Self> { pub const fn span(self, span: Span) -> Spanned<Self> {
Spanned { node: self, span } Spanned { node: self, span }
} }
@ -265,7 +261,7 @@ impl Value {
}, },
Value::List(v, sep, brackets) if v.len() == 1 => match brackets { Value::List(v, sep, brackets) if v.len() == 1 => match brackets {
Brackets::None => match sep { Brackets::None => match sep {
ListSeparator::Space => format!("{}", v[0].inspect(span)?), ListSeparator::Space => v[0].inspect(span)?,
ListSeparator::Comma => format!("({},)", v[0].inspect(span)?), ListSeparator::Comma => format!("({},)", v[0].inspect(span)?),
}, },
Brackets::Bracketed => match sep { Brackets::Bracketed => match sep {
@ -274,13 +270,11 @@ impl Value {
}, },
}, },
Self::List(vals, sep, brackets) => match brackets { Self::List(vals, sep, brackets) => match brackets {
Brackets::None => format!( Brackets::None => vals
"{}", .iter()
vals.iter()
.map(|x| x.inspect(span)) .map(|x| x.inspect(span))
.collect::<SassResult<Vec<String>>>()? .collect::<SassResult<Vec<String>>>()?
.join(sep.as_str()), .join(sep.as_str()),
),
Brackets::Bracketed => format!( Brackets::Bracketed => format!(
"[{}]", "[{}]",
vals.iter() vals.iter()
@ -355,7 +349,7 @@ impl Value {
Op::LessThanEqual => return lhs.cmp(*rhs, op, span), Op::LessThanEqual => return lhs.cmp(*rhs, op, span),
Op::Not => unreachable!(), Op::Not => unreachable!(),
Op::And => { Op::And => {
if lhs.clone().is_true(span)? { if lhs.is_true(span)? {
rhs.eval(span)?.node rhs.eval(span)?.node
} else { } else {
lhs.eval(span)?.node lhs.eval(span)?.node
@ -389,16 +383,12 @@ impl Value {
let ordering = match self { let ordering = match self {
Self::Dimension(num, unit) => match &other { Self::Dimension(num, unit) => match &other {
Self::Dimension(num2, unit2) => { Self::Dimension(num2, unit2) => {
if !unit.comparable(&unit2) { if !unit.comparable(unit2) {
return Err( return Err(
(format!("Incompatible units {} and {}.", unit2, unit), span).into(), (format!("Incompatible units {} and {}.", unit2, unit), span).into(),
); );
} }
if &unit == unit2 { if &unit == unit2 || unit == Unit::None || unit2 == &Unit::None {
num.cmp(num2)
} else if unit == Unit::None {
num.cmp(num2)
} else if unit2 == &Unit::None {
num.cmp(num2) num.cmp(num2)
} else { } else {
num.cmp( num.cmp(

View File

@ -32,7 +32,7 @@ impl Value {
}, },
Self::Null => match other { Self::Null => match other {
Self::Null => Self::Null, Self::Null => Self::Null,
_ => Value::Ident(format!("{}", other.to_css_string(span)?), QuoteKind::None), _ => Value::Ident(other.to_css_string(span)?, QuoteKind::None),
}, },
Self::Dimension(num, unit) => match other { Self::Dimension(num, unit) => match other {
Self::Dimension(num2, unit2) => { Self::Dimension(num2, unit2) => {

View File

@ -538,8 +538,7 @@ impl Value {
}, },
}; };
Ok(IntermediateValue::Value( Ok(IntermediateValue::Value(
func.clone() func.eval(
.eval(
eat_call_args(toks, scope, super_selector)?, eat_call_args(toks, scope, super_selector)?,
scope, scope,
super_selector, super_selector,

View File

@ -60,7 +60,7 @@ impl SassFunction {
match self { match self {
Self::Builtin(f, ..) => f.0(args, scope, super_selector), Self::Builtin(f, ..) => f.0(args, scope, super_selector),
// todo: superselector // todo: superselector
Self::UserDefined(f, ..) => f.clone().eval(args, scope, super_selector), Self::UserDefined(f, ..) => f.eval(args, scope, super_selector),
} }
} }
} }