derive Copy for Identifier
This commit is contained in:
parent
65b281d1f7
commit
f9455caeea
@ -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,
|
||||
|
@ -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 {
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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();
|
||||
|
@ -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,
|
||||
|
@ -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)?;
|
||||
|
||||
|
@ -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)?);
|
||||
|
@ -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)),
|
||||
},
|
||||
|
@ -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);
|
||||
|
48
src/scope.rs
48
src/scope.rs
@ -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;
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user