avoid cloning identifiers for functions

This commit is contained in:
Connor Skees 2020-07-07 21:11:45 -04:00
parent 5f938315dc
commit 0c0c154b66
4 changed files with 15 additions and 22 deletions

View File

@ -4,7 +4,7 @@ use codemap::Spanned;
use crate::{ use crate::{
args::CallArgs, args::CallArgs,
common::QuoteKind, common::{Identifier, QuoteKind},
error::SassResult, error::SassResult,
parse::Parser, parse::Parser,
unit::Unit, unit::Unit,
@ -153,8 +153,8 @@ fn function_exists(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Va
fn get_function(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> { fn get_function(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> {
args.max_args(3)?; args.max_args(3)?;
let name = match parser.arg(&mut args, 0, "name")? { let name: Identifier = match parser.arg(&mut args, 0, "name")? {
Value::String(s, _) => s, Value::String(s, _) => s.into(),
v => { v => {
return Err(( return Err((
format!("$name: {} is not a string.", v.inspect(args.span())?), format!("$name: {} is not a string.", v.inspect(args.span())?),
@ -193,9 +193,9 @@ fn get_function(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value
}, },
parser.global_scope, parser.global_scope,
) { ) {
Ok(f) => SassFunction::UserDefined(Box::new(f), name.into()), Ok(f) => SassFunction::UserDefined(Box::new(f), name),
Err(..) => match GLOBAL_FUNCTIONS.get(name.as_str()) { Err(..) => match GLOBAL_FUNCTIONS.get(name.as_str()) {
Some(f) => SassFunction::Builtin(f.clone(), name.into()), Some(f) => SassFunction::Builtin(f.clone(), name),
None => return Err((format!("Function not found: {}", name), args.span()).into()), None => return Err((format!("Function not found: {}", name), args.span()).into()),
}, },
}; };

View File

@ -139,9 +139,8 @@ impl Default for Identifier {
} }
impl Identifier { impl Identifier {
#[allow(clippy::missing_const_for_fn)] pub fn as_str(&self) -> &str {
pub fn into_inner(self) -> String { &self.0
self.0
} }
} }

View File

@ -255,17 +255,16 @@ impl<'a> Parser<'a> {
} }
let as_ident = Identifier::from(&s); let as_ident = Identifier::from(&s);
let ident_as_string = as_ident.clone().into_inner();
let func = match self.scopes.last().get_fn( let func = match self.scopes.last().get_fn(
Spanned { Spanned {
node: as_ident.clone(), node: &as_ident,
span, span,
}, },
self.global_scope, self.global_scope,
) { ) {
Ok(f) => f, Ok(f) => f,
Err(_) => { Err(_) => {
if let Some(f) = GLOBAL_FUNCTIONS.get(ident_as_string.as_str()) { if let Some(f) = GLOBAL_FUNCTIONS.get(as_ident.as_str()) {
return Ok(IntermediateValue::Value(HigherIntermediateValue::Function( return Ok(IntermediateValue::Value(HigherIntermediateValue::Function(
SassFunction::Builtin(f.clone(), as_ident), SassFunction::Builtin(f.clone(), as_ident),
self.parse_call_args()?, self.parse_call_args()?,

View File

@ -90,22 +90,17 @@ impl Scope {
self.mixins.contains_key(&name) || global_scope.mixin_exists_no_global(&name) self.mixins.contains_key(&name) || global_scope.mixin_exists_no_global(&name)
} }
fn get_fn_no_global(&self, name: &Spanned<Identifier>) -> SassResult<Function> { fn get_fn_no_global(&self, name: Spanned<&Identifier>) -> SassResult<Function> {
match self.functions.get(&name.node) { match self.functions.get(name.node) {
Some(v) => Ok(v.clone()), Some(v) => Ok(v.clone()),
None => Err(("Undefined function.", name.span).into()), None => Err(("Undefined function.", name.span).into()),
} }
} }
pub fn get_fn<T: Into<Identifier>>( pub fn get_fn(&self, name: Spanned<&Identifier>, global_scope: &Scope) -> SassResult<Function> {
&self, match self.functions.get(name.node) {
name: Spanned<T>,
global_scope: &Scope,
) -> SassResult<Function> {
let name = name.map_node(Into::into);
match self.functions.get(&name.node) {
Some(v) => Ok(v.clone()), Some(v) => Ok(v.clone()),
None => global_scope.get_fn_no_global(&name), None => global_scope.get_fn_no_global(name),
} }
} }
@ -121,6 +116,6 @@ impl Scope {
let name = v.into(); let name = v.into();
self.functions.contains_key(&name) self.functions.contains_key(&name)
|| global_scope.fn_exists_no_global(&name) || global_scope.fn_exists_no_global(&name)
|| GLOBAL_FUNCTIONS.contains_key(name.clone().into_inner().as_str()) || GLOBAL_FUNCTIONS.contains_key(name.as_str())
} }
} }