Reduce usage of .clone()

This commit is contained in:
ConnorSkees 2020-01-18 20:24:28 -05:00
parent b28295d2b1
commit 720b1e9f22
5 changed files with 51 additions and 46 deletions

View File

@ -51,7 +51,7 @@ use crate::common::{AtRule, Keyword, Op, Pos, Printer, Scope, Symbol, Whitespace
use crate::css::Css;
use crate::error::SassError;
use crate::format::PrettyPrinter;
use crate::function::{eat_call_args, eat_func_args, CallArgs, FuncArgs};
use crate::function::{eat_call_args, CallArgs};
use crate::imports::import;
use crate::lexer::Lexer;
use crate::mixin::Mixin;
@ -268,7 +268,7 @@ impl<'a> StyleSheetParser<'a> {
fn parse_toplevel(mut self) -> SassResult<(Vec<Stmt>, Scope)> {
let mut rules: Vec<Stmt> = Vec::new();
while let Some(Token { kind, .. }) = self.lexer.peek() {
match kind.clone() {
match kind {
TokenKind::Ident(_)
| TokenKind::Attribute(_)
| TokenKind::Interpolation
@ -281,11 +281,15 @@ impl<'a> StyleSheetParser<'a> {
self.lexer.next();
continue;
}
TokenKind::Variable(name) => {
let Token { pos, .. } = self
TokenKind::Variable(_) => {
let Token { pos, kind } = self
.lexer
.next()
.expect("this cannot occur as we have already peeked");
.expect("this must exist because we have already peeked");
let name = match kind {
TokenKind::Variable(n) => n,
_ => unsafe { std::hint::unreachable_unchecked() },
};
devour_whitespace(&mut self.lexer);
if self
.lexer
@ -300,8 +304,16 @@ impl<'a> StyleSheetParser<'a> {
.unwrap_or_else(|err| self.error(err.0, err.1));
self.global_scope.vars.insert(name, val);
}
TokenKind::MultilineComment(comment) => {
self.lexer.next();
TokenKind::MultilineComment(_) => {
let comment = match self
.lexer
.next()
.expect("this must exist because we have already peeked")
.kind
{
TokenKind::MultilineComment(c) => c,
_ => unsafe { std::hint::unreachable_unchecked() },
};
rules.push(Stmt::MultilineComment(comment));
}
TokenKind::AtRule(AtRule::Import) => {
@ -460,7 +472,7 @@ fn eat_include<I: Iterator<Item = Token>>(
devour_whitespace(toks);
let mut mixin = if let Some(m) = scope.mixins.get(&name) {
let mixin = if let Some(m) = scope.mixins.get(&name) {
m.clone()
} else {
return Err((pos, "expected identifier"));
@ -521,18 +533,16 @@ pub(crate) fn eat_expr<I: Iterator<Item = Token>>(
TokenKind::Symbol(Symbol::SemiColon) | TokenKind::Symbol(Symbol::CloseCurlyBrace) => {
toks.next();
devour_whitespace(toks);
return Ok(Some(Expr::Style(
match Style::from_tokens(&values, scope) {
Ok(x) => x,
Err(_) => return Ok(None),
},
)));
return Ok(Some(Expr::Style(match Style::from_tokens(values, scope) {
Ok(x) => x,
Err(_) => return Ok(None),
})));
}
TokenKind::Symbol(Symbol::OpenCurlyBrace) => {
toks.next();
devour_whitespace(toks);
return Ok(Some(Expr::Selector(Selector::from_tokens(
&mut values.iter().peekable(),
&mut values.into_iter().peekable(),
scope,
))));
}

View File

@ -80,7 +80,7 @@ impl Mixin {
Ok((name, Mixin::new(scope.clone(), args, body)))
}
pub fn args(&mut self, args: &CallArgs) -> &mut Mixin {
pub fn args(mut self, args: &CallArgs) -> Mixin {
for (idx, arg) in args.0.iter().enumerate() {
if arg.is_named() {
todo!("keyword args")
@ -99,7 +99,7 @@ impl Mixin {
self
}
pub fn call(&mut self, super_selector: &Selector) -> Result<Vec<Stmt>, (Pos, &'static str)> {
pub fn call(mut self, super_selector: &Selector) -> Result<Vec<Stmt>, (Pos, &'static str)> {
self.eval(super_selector, &mut self.scope.clone())
}

View File

@ -3,8 +3,8 @@ use crate::utils::{devour_whitespace, eat_interpolation, IsWhitespace};
use crate::{Token, TokenKind};
use std::fmt::{self, Display};
use std::iter::Peekable;
use std::slice::Iter;
use std::string::ToString;
use std::vec::IntoIter;
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct Selector(pub Vec<SelectorKind>);
@ -175,7 +175,7 @@ impl<'a> SelectorParser<'a> {
}
}
fn all_selectors(&mut self, tokens: &'a mut Peekable<Iter<'_, Token>>) -> Selector {
fn all_selectors(mut self, tokens: &'a mut Peekable<IntoIter<Token>>) -> Selector {
self.tokens_to_selectors(tokens);
// remove trailing whitespace
while let Some(x) = self.selectors.pop() {
@ -184,10 +184,10 @@ impl<'a> SelectorParser<'a> {
break;
}
}
Selector(self.selectors.clone())
Selector(self.selectors)
}
fn consume_pseudo_selector(&mut self, tokens: &'_ mut Peekable<Iter<'_, Token>>) {
fn consume_pseudo_selector(&mut self, tokens: &'_ mut Peekable<IntoIter<Token>>) {
if let Some(Token {
kind: TokenKind::Ident(s),
..
@ -205,28 +205,27 @@ impl<'a> SelectorParser<'a> {
break;
}
let tok = tokens.next().unwrap();
toks.push(tok.kind.clone());
toks.push(tok.kind);
}
tokens.next();
self.selectors
.push(SelectorKind::PseudoParen(s.clone(), toks))
self.selectors.push(SelectorKind::PseudoParen(s, toks))
} else {
self.selectors.push(SelectorKind::Pseudo(s.clone()))
self.selectors.push(SelectorKind::Pseudo(s))
}
} else {
todo!("expected ident after `:` in selector")
}
}
fn tokens_to_selectors(&mut self, tokens: &'_ mut Peekable<Iter<'_, Token>>) {
fn tokens_to_selectors(&mut self, tokens: &'_ mut Peekable<IntoIter<Token>>) {
while tokens.peek().is_some() {
self.consume_selector(tokens)
}
}
fn consume_selector(&mut self, tokens: &'_ mut Peekable<Iter<'_, Token>>) {
fn consume_selector(&mut self, tokens: &'_ mut Peekable<IntoIter<Token>>) {
if devour_whitespace(tokens) {
if let Some(&&Token {
if let Some(Token {
kind: TokenKind::Symbol(Symbol::Comma),
..
}) = tokens.peek()
@ -239,10 +238,8 @@ impl<'a> SelectorParser<'a> {
return;
}
if let Some(Token { kind, .. }) = tokens.next() {
match &kind {
TokenKind::Ident(ident) => {
self.selectors.push(SelectorKind::Element(ident.clone()))
}
match kind {
TokenKind::Ident(ident) => self.selectors.push(SelectorKind::Element(ident)),
TokenKind::Unit(u) => self.selectors.push(SelectorKind::Element(u.to_string())),
TokenKind::Symbol(Symbol::Period) => self.selectors.push(SelectorKind::Class),
TokenKind::Symbol(Symbol::Hash) => self.selectors.push(SelectorKind::Id),
@ -254,11 +251,9 @@ impl<'a> SelectorParser<'a> {
TokenKind::Symbol(Symbol::Mul) => self.selectors.push(SelectorKind::Universal),
TokenKind::Symbol(Symbol::BitAnd) => self.selectors.push(SelectorKind::Super),
TokenKind::Interpolation => self.tokens_to_selectors(
&mut eat_interpolation(tokens, self.scope).iter().peekable(),
&mut eat_interpolation(tokens, self.scope).into_iter().peekable(),
),
TokenKind::Attribute(attr) => {
self.selectors.push(SelectorKind::Attribute(attr.clone()))
}
TokenKind::Attribute(attr) => self.selectors.push(SelectorKind::Attribute(attr)),
_ => todo!("unimplemented selector"),
};
}
@ -267,7 +262,7 @@ impl<'a> SelectorParser<'a> {
impl Selector {
pub fn from_tokens<'a>(
tokens: &'a mut Peekable<Iter<'a, Token>>,
tokens: &'a mut Peekable<IntoIter<Token>>,
scope: &'a Scope,
) -> Selector {
SelectorParser::new(scope).all_selectors(tokens)

View File

@ -3,7 +3,7 @@ use crate::utils::{deref_variable, eat_interpolation};
use crate::{Token, TokenKind};
use std::fmt::{self, Display};
use std::iter::Peekable;
use std::slice::Iter;
use std::vec::IntoIter;
/// A style: `color: red`
#[derive(Clone, Debug, Eq, PartialEq)]
@ -19,22 +19,22 @@ impl Display for Style {
}
impl Style {
pub fn from_tokens(tokens: &[Token], scope: &Scope) -> Result<Self, ()> {
pub fn from_tokens(tokens: Vec<Token>, scope: &Scope) -> Result<Self, ()> {
Ok(StyleParser::new(tokens, scope)?.parse())
}
}
struct StyleParser<'a> {
tokens: Peekable<Iter<'a, Token>>,
tokens: Peekable<IntoIter<Token>>,
scope: &'a Scope,
}
impl<'a> StyleParser<'a> {
fn new(tokens: &'a [Token], scope: &'a Scope) -> Result<Self, ()> {
fn new(tokens: Vec<Token>, scope: &'a Scope) -> Result<Self, ()> {
if tokens.is_empty() {
return Err(());
}
let tokens = tokens.iter().peekable();
let tokens = tokens.into_iter().peekable();
Ok(StyleParser { tokens, scope })
}

View File

@ -28,7 +28,7 @@ pub fn deref_variable(name: &str, scope: &Scope) -> Vec<Token> {
.peekable();
let mut val = Vec::with_capacity(toks.len());
while let Some(tok) = toks.next() {
match &tok.kind {
match tok.kind {
TokenKind::Variable(ref v) => val.extend(deref_variable(v, scope)),
TokenKind::Whitespace(_) => {
devour_whitespace(&mut toks);
@ -45,19 +45,19 @@ pub fn deref_variable(name: &str, scope: &Scope) -> Vec<Token> {
val
}
pub fn eat_interpolation<'a, I: Iterator<Item = &'a Token>>(
pub fn eat_interpolation<I: Iterator<Item = Token>>(
tokens: &mut Peekable<I>,
scope: &Scope,
) -> Vec<Token> {
let mut val = Vec::new();
for tok in tokens {
match &tok.kind {
match tok.kind {
TokenKind::Symbol(Symbol::CloseCurlyBrace) => break,
TokenKind::Symbol(Symbol::OpenCurlyBrace) => {
todo!("invalid character in interpolation")
}
TokenKind::Variable(ref v) => val.extend(deref_variable(v, scope)),
_ => val.push(tok.clone()),
_ => val.push(tok),
}
}
val