derive Copy for Identifier

This commit is contained in:
Connor Skees 2020-07-08 22:38:56 -04:00
parent 65b281d1f7
commit f9455caeea
11 changed files with 51 additions and 63 deletions

View File

@ -96,7 +96,7 @@ fn variable_exists(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Va
args.max_args(1)?;
match parser.arg(&mut args, 0, "name")? {
Value::String(s, _) => Ok(Value::bool(
parser.scopes.var_exists(&s.into(), parser.global_scope),
parser.scopes.var_exists(s.into(), parser.global_scope),
)),
v => Err((
format!("$name: {} is not a string.", v.inspect(args.span())?),
@ -109,7 +109,7 @@ fn variable_exists(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Va
fn global_variable_exists(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> {
args.max_args(1)?;
match parser.arg(&mut args, 0, "name")? {
Value::String(s, _) => Ok(Value::bool(parser.global_scope.var_exists(&s.into()))),
Value::String(s, _) => Ok(Value::bool(parser.global_scope.var_exists(s.into()))),
v => Err((
format!("$name: {} is not a string.", v.inspect(args.span())?),
args.span(),
@ -122,7 +122,7 @@ fn mixin_exists(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value
args.max_args(2)?;
match parser.arg(&mut args, 0, "name")? {
Value::String(s, _) => Ok(Value::bool(
parser.scopes.mixin_exists(&s.into(), parser.global_scope),
parser.scopes.mixin_exists(s.into(), parser.global_scope),
)),
v => Err((
format!("$name: {} is not a string.", v.inspect(args.span())?),
@ -136,7 +136,7 @@ fn function_exists(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Va
args.max_args(2)?;
match parser.arg(&mut args, 0, "name")? {
Value::String(s, _) => Ok(Value::bool(
parser.scopes.fn_exists(&s.into(), parser.global_scope),
parser.scopes.fn_exists(s.into(), parser.global_scope),
)),
v => Err((
format!("$name: {} is not a string.", v.inspect(args.span())?),
@ -183,7 +183,7 @@ fn get_function(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value
let func = match parser.scopes.get_fn(
Spanned {
node: &name,
node: name,
span: args.span(),
},
parser.global_scope,

View File

@ -112,7 +112,7 @@ impl ListSeparator {
///
/// This struct protects that invariant by normalizing all
/// underscores into hypens.
#[derive(Debug, Clone, Eq, PartialEq, Hash, PartialOrd, Ord)]
#[derive(Debug, Clone, Eq, PartialEq, Hash, PartialOrd, Ord, Copy)]
pub(crate) struct Identifier(InternedString);
impl From<String> for Identifier {

View File

@ -75,6 +75,8 @@ grass input.scss
clippy::items_after_statements,
clippy::shadow_reuse,
clippy::shadow_unrelated,
// this is only available on nightly
clippy::unnested_or_patterns,
)]
#![cfg_attr(feature = "nightly", feature(track_caller))]
#![cfg_attr(feature = "profiling", inline(never))]
@ -108,6 +110,7 @@ mod builtin;
mod color;
mod common;
mod error;
mod interner;
mod lexer;
mod output;
mod parse;
@ -116,7 +119,6 @@ mod selector;
mod style;
mod token;
mod unit;
mod interner;
mod utils;
mod value;

View File

@ -363,7 +363,7 @@ impl<'a> Parser<'a> {
let span = args.span();
let arg_list = Value::ArgList(self.variadic_args(args)?);
scope.insert_var(
arg.name.clone(),
arg.name,
Spanned {
node: arg_list,
span,
@ -371,7 +371,7 @@ impl<'a> Parser<'a> {
);
break;
}
let val = match args.get(idx, arg.name.clone()) {
let val = match args.get(idx, arg.name) {
Some(v) => v,
None => match arg.default.as_mut() {
Some(v) => self.parse_value_from_vec(mem::take(v)),
@ -382,7 +382,7 @@ impl<'a> Parser<'a> {
}
},
}?;
self.scopes.insert_var(arg.name.clone(), val.clone());
self.scopes.insert_var(arg.name, val.clone());
scope.insert_var(arg.name, val);
}
self.scopes.exit_scope();

View File

@ -295,7 +295,7 @@ impl<'a> Parser<'a> {
for i in iter {
self.scopes.insert_var(
var.node.clone(),
var.node,
Spanned {
node: Value::Dimension(Number::from(i), Unit::None),
span: var.span,
@ -467,7 +467,7 @@ impl<'a> Parser<'a> {
for row in iter {
if vars.len() == 1 {
self.scopes.insert_var(
vars[0].node.clone(),
vars[0].node,
Spanned {
node: row,
span: vars[0].span,
@ -480,7 +480,7 @@ impl<'a> Parser<'a> {
.chain(std::iter::once(Value::Null).cycle()),
) {
self.scopes.insert_var(
var.node.clone(),
var.node,
Spanned {
node: val,
span: var.span,

View File

@ -112,13 +112,7 @@ impl<'a> Parser<'a> {
args: fn_args,
declared_at_root,
..
} = self.scopes.get_mixin(
{
let Spanned { ref node, span } = name;
Spanned { node, span }
},
self.global_scope,
)?;
} = self.scopes.get_mixin(name, self.global_scope)?;
let scope = self.eval_args(fn_args, args)?;

View File

@ -218,10 +218,7 @@ impl<'a> Parser<'a> {
styles.push(Style { property, value });
}
Some(Token { kind: '{', .. }) => {
styles.push(Style {
property: property.clone(),
value,
});
styles.push(Style { property, value });
styles.append(&mut self.parse_style_group(property)?);
}
Some(..) | None => {
@ -254,7 +251,7 @@ impl<'a> Parser<'a> {
}
'{' => {
let mut v = vec![Style {
property: super_property.clone(),
property: super_property,
value: Box::new(value),
}];
v.append(&mut self.parse_style_group(super_property)?);

View File

@ -258,7 +258,7 @@ impl<'a> Parser<'a> {
let as_ident = Identifier::from(&s);
let func = match self.scopes.get_fn(
Spanned {
node: &as_ident,
node: as_ident,
span,
},
self.global_scope,
@ -528,13 +528,7 @@ impl<'a> Parser<'a> {
Err(e) => return Some(Err(e)),
};
IntermediateValue::Value(HigherIntermediateValue::Literal(
match self.scopes.get_var(
{
let Spanned { ref node, span } = val;
Spanned { node, span }
},
self.global_scope,
) {
match self.scopes.get_var(val, self.global_scope) {
Ok(v) => v.clone(),
Err(e) => return Some(Err(e)),
},

View File

@ -41,25 +41,23 @@ impl<'a> Parser<'a> {
let value = self.parse_variable_value()?;
if value.global && !value.default {
self.global_scope
.insert_var(ident.clone(), value.value.clone());
self.global_scope.insert_var(ident, value.value.clone());
}
if value.default {
if self.at_root && !self.flags.in_control_flow() {
if !self.global_scope.var_exists(&ident) {
if !self.global_scope.var_exists(ident) {
self.global_scope.insert_var(ident, value.value);
}
} else {
if value.global && !self.global_scope.var_exists(&ident) {
self.global_scope
.insert_var(ident.clone(), value.value.clone());
if value.global && !self.global_scope.var_exists(ident) {
self.global_scope.insert_var(ident, value.value.clone());
}
self.scopes.insert_default_var(ident, value.value);
}
} else if self.at_root {
if self.flags.in_control_flow() {
if self.global_scope.var_exists(&ident) {
if self.global_scope.var_exists(ident) {
self.global_scope.insert_var(ident, value.value);
} else {
self.scopes.insert_var(ident, value.value);

View File

@ -18,6 +18,8 @@ pub(crate) struct Scope {
}
impl Scope {
// `BTreeMap::new` is not yet const
#[allow(clippy::missing_const_for_fn)]
#[must_use]
pub fn new() -> Self {
Self {
@ -27,8 +29,8 @@ impl Scope {
}
}
fn get_var(&self, name: Spanned<&Identifier>) -> SassResult<&Value> {
match self.vars.get(name.node) {
fn get_var(&self, name: Spanned<Identifier>) -> SassResult<&Value> {
match self.vars.get(&name.node) {
Some(v) => Ok(&v.node),
None => Err(("Undefined variable.", name.span).into()),
}
@ -38,12 +40,12 @@ impl Scope {
self.vars.insert(s, v)
}
pub fn var_exists(&self, name: &Identifier) -> bool {
self.vars.contains_key(name)
pub fn var_exists(&self, name: Identifier) -> bool {
self.vars.contains_key(&name)
}
fn get_mixin(&self, name: Spanned<&Identifier>) -> SassResult<Mixin> {
match self.mixins.get(name.node) {
fn get_mixin(&self, name: Spanned<Identifier>) -> SassResult<Mixin> {
match self.mixins.get(&name.node) {
Some(v) => Ok(v.clone()),
None => Err(("Undefined mixin.", name.span).into()),
}
@ -53,23 +55,23 @@ impl Scope {
self.mixins.insert(s.into(), v)
}
fn mixin_exists(&self, name: &Identifier) -> bool {
self.mixins.contains_key(name)
fn mixin_exists(&self, name: Identifier) -> bool {
self.mixins.contains_key(&name)
}
fn get_fn(&self, name: &Identifier) -> Option<Function> {
self.functions.get(name).cloned()
fn get_fn(&self, name: Identifier) -> Option<Function> {
self.functions.get(&name).cloned()
}
pub fn insert_fn<T: Into<Identifier>>(&mut self, s: T, v: Function) -> Option<Function> {
self.functions.insert(s.into(), v)
}
fn fn_exists(&self, name: &Identifier) -> bool {
fn fn_exists(&self, name: Identifier) -> bool {
if self.functions.is_empty() {
return false;
}
self.functions.contains_key(name)
self.functions.contains_key(&name)
}
fn merge(&mut self, other: Scope) {
@ -112,7 +114,7 @@ impl Scopes {
impl Scopes {
pub fn insert_var(&mut self, s: Identifier, v: Spanned<Value>) -> Option<Spanned<Value>> {
for scope in self.0.iter_mut().rev() {
if scope.var_exists(&s) {
if scope.var_exists(s) {
return scope.insert_var(s, v);
}
}
@ -132,7 +134,7 @@ impl Scopes {
v: Spanned<Value>,
) -> Option<Spanned<Value>> {
if let Some(scope) = self.0.last_mut() {
if scope.var_exists(&s) {
if scope.var_exists(s) {
None
} else {
scope.insert_var(s, v)
@ -144,18 +146,18 @@ impl Scopes {
pub fn get_var<'a>(
&'a self,
name: Spanned<&Identifier>,
name: Spanned<Identifier>,
global_scope: &'a Scope,
) -> SassResult<&Value> {
for scope in self.0.iter().rev() {
if scope.var_exists(&name.node) {
if scope.var_exists(name.node) {
return scope.get_var(name);
}
}
global_scope.get_var(name)
}
pub fn var_exists(&self, name: &Identifier, global_scope: &Scope) -> bool {
pub fn var_exists(&self, name: Identifier, global_scope: &Scope) -> bool {
for scope in &self.0 {
if scope.var_exists(name) {
return true;
@ -180,18 +182,18 @@ impl Scopes {
pub fn get_mixin<'a>(
&'a self,
name: Spanned<&Identifier>,
name: Spanned<Identifier>,
global_scope: &'a Scope,
) -> SassResult<Mixin> {
for scope in self.0.iter().rev() {
if scope.mixin_exists(&name.node) {
if scope.mixin_exists(name.node) {
return scope.get_mixin(name);
}
}
global_scope.get_mixin(name)
}
pub fn mixin_exists(&self, name: &Identifier, global_scope: &Scope) -> bool {
pub fn mixin_exists(&self, name: Identifier, global_scope: &Scope) -> bool {
for scope in &self.0 {
if scope.mixin_exists(name) {
return true;
@ -216,18 +218,18 @@ impl Scopes {
pub fn get_fn<'a>(
&'a self,
name: Spanned<&Identifier>,
name: Spanned<Identifier>,
global_scope: &'a Scope,
) -> Option<Function> {
for scope in self.0.iter().rev() {
if scope.fn_exists(&name.node) {
if scope.fn_exists(name.node) {
return scope.get_fn(name.node);
}
}
global_scope.get_fn(name.node)
}
pub fn fn_exists(&self, name: &Identifier, global_scope: &Scope) -> bool {
pub fn fn_exists(&self, name: Identifier, global_scope: &Scope) -> bool {
for scope in &self.0 {
if scope.fn_exists(name) {
return true;

View File

@ -107,6 +107,7 @@ pub(crate) enum Unit {
/// Units multiplied together
/// Boxed under the assumption that mul units are exceedingly rare
#[allow(clippy::box_vec)]
Mul(Box<Vec<Unit>>),
/// Units divided by each other