use Arc instead of Box inside AstExpr
speeds up bootstrap by ~15-20%
This commit is contained in:
parent
f20c000b54
commit
190201bcce
@ -1,4 +1,4 @@
|
|||||||
use std::iter::Iterator;
|
use std::{iter::Iterator, sync::Arc};
|
||||||
|
|
||||||
use codemap::{Span, Spanned};
|
use codemap::{Span, Spanned};
|
||||||
|
|
||||||
@ -43,9 +43,9 @@ pub(crate) struct AstSassMap(pub Vec<(Spanned<AstExpr>, AstExpr)>);
|
|||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub(crate) enum AstExpr {
|
pub(crate) enum AstExpr {
|
||||||
BinaryOp {
|
BinaryOp {
|
||||||
lhs: Box<Self>,
|
lhs: Arc<Self>,
|
||||||
op: BinaryOp,
|
op: BinaryOp,
|
||||||
rhs: Box<Self>,
|
rhs: Arc<Self>,
|
||||||
allows_slash: bool,
|
allows_slash: bool,
|
||||||
span: Span,
|
span: Span,
|
||||||
},
|
},
|
||||||
@ -55,9 +55,9 @@ pub(crate) enum AstExpr {
|
|||||||
name: CalculationName,
|
name: CalculationName,
|
||||||
args: Vec<Self>,
|
args: Vec<Self>,
|
||||||
},
|
},
|
||||||
Color(Box<Color>),
|
Color(Arc<Color>),
|
||||||
FunctionCall(FunctionCallExpr),
|
FunctionCall(FunctionCallExpr),
|
||||||
If(Box<Ternary>),
|
If(Arc<Ternary>),
|
||||||
InterpolatedFunction(InterpolatedFunction),
|
InterpolatedFunction(InterpolatedFunction),
|
||||||
List(ListExpr),
|
List(ListExpr),
|
||||||
Map(AstSassMap),
|
Map(AstSassMap),
|
||||||
@ -66,11 +66,11 @@ pub(crate) enum AstExpr {
|
|||||||
n: Number,
|
n: Number,
|
||||||
unit: Unit,
|
unit: Unit,
|
||||||
},
|
},
|
||||||
Paren(Box<Self>),
|
Paren(Arc<Self>),
|
||||||
ParentSelector,
|
ParentSelector,
|
||||||
String(StringExpr, Span),
|
String(StringExpr, Span),
|
||||||
Supports(Box<AstSupportsCondition>),
|
Supports(Arc<AstSupportsCondition>),
|
||||||
UnaryOp(UnaryOp, Box<Self>, Span),
|
UnaryOp(UnaryOp, Arc<Self>, Span),
|
||||||
Variable {
|
Variable {
|
||||||
name: Spanned<Identifier>,
|
name: Spanned<Identifier>,
|
||||||
namespace: Option<Spanned<Identifier>>,
|
namespace: Option<Spanned<Identifier>>,
|
||||||
@ -174,9 +174,9 @@ impl AstExpr {
|
|||||||
|
|
||||||
pub fn slash(left: Self, right: Self, span: Span) -> Self {
|
pub fn slash(left: Self, right: Self, span: Span) -> Self {
|
||||||
Self::BinaryOp {
|
Self::BinaryOp {
|
||||||
lhs: Box::new(left),
|
lhs: Arc::new(left),
|
||||||
op: BinaryOp::Div,
|
op: BinaryOp::Div,
|
||||||
rhs: Box::new(right),
|
rhs: Arc::new(right),
|
||||||
allows_slash: true,
|
allows_slash: true,
|
||||||
span,
|
span,
|
||||||
}
|
}
|
||||||
|
@ -59,7 +59,7 @@ fn hsl_3_args(
|
|||||||
visitor,
|
visitor,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
Ok(Value::Color(Box::new(Color::from_hsla_fn(
|
Ok(Value::Color(Arc::new(Color::from_hsla_fn(
|
||||||
Number(hue.num.rem_euclid(360.0)),
|
Number(hue.num.rem_euclid(360.0)),
|
||||||
saturation.num / Number(100.0),
|
saturation.num / Number(100.0),
|
||||||
lightness.num / Number(100.0),
|
lightness.num / Number(100.0),
|
||||||
@ -172,7 +172,7 @@ pub(crate) fn adjust_hue(mut args: ArgumentResult, visitor: &mut Visitor) -> Sas
|
|||||||
.assert_number_with_name("degrees", args.span())?
|
.assert_number_with_name("degrees", args.span())?
|
||||||
.num;
|
.num;
|
||||||
|
|
||||||
Ok(Value::Color(Box::new(color.adjust_hue(degrees))))
|
Ok(Value::Color(Arc::new(color.adjust_hue(degrees))))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn lighten(mut args: ArgumentResult, visitor: &mut Visitor) -> SassResult<Value> {
|
fn lighten(mut args: ArgumentResult, visitor: &mut Visitor) -> SassResult<Value> {
|
||||||
@ -186,7 +186,7 @@ fn lighten(mut args: ArgumentResult, visitor: &mut Visitor) -> SassResult<Value>
|
|||||||
.assert_number_with_name("amount", args.span())?;
|
.assert_number_with_name("amount", args.span())?;
|
||||||
let amount = bound!(args, "amount", amount.num, amount.unit, 0, 100) / Number(100.0);
|
let amount = bound!(args, "amount", amount.num, amount.unit, 0, 100) / Number(100.0);
|
||||||
|
|
||||||
Ok(Value::Color(Box::new(color.lighten(amount))))
|
Ok(Value::Color(Arc::new(color.lighten(amount))))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn darken(mut args: ArgumentResult, visitor: &mut Visitor) -> SassResult<Value> {
|
fn darken(mut args: ArgumentResult, visitor: &mut Visitor) -> SassResult<Value> {
|
||||||
@ -213,7 +213,7 @@ fn darken(mut args: ArgumentResult, visitor: &mut Visitor) -> SassResult<Value>
|
|||||||
.into())
|
.into())
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
Ok(Value::Color(Box::new(color.darken(amount))))
|
Ok(Value::Color(Arc::new(color.darken(amount))))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn saturate(mut args: ArgumentResult, visitor: &mut Visitor) -> SassResult<Value> {
|
fn saturate(mut args: ArgumentResult, visitor: &mut Visitor) -> SassResult<Value> {
|
||||||
@ -271,7 +271,7 @@ fn saturate(mut args: ArgumentResult, visitor: &mut Visitor) -> SassResult<Value
|
|||||||
.into())
|
.into())
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
Ok(Value::Color(Box::new(color.saturate(amount))))
|
Ok(Value::Color(Arc::new(color.saturate(amount))))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn desaturate(mut args: ArgumentResult, visitor: &mut Visitor) -> SassResult<Value> {
|
fn desaturate(mut args: ArgumentResult, visitor: &mut Visitor) -> SassResult<Value> {
|
||||||
@ -297,7 +297,7 @@ fn desaturate(mut args: ArgumentResult, visitor: &mut Visitor) -> SassResult<Val
|
|||||||
.into())
|
.into())
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
Ok(Value::Color(Box::new(color.desaturate(amount))))
|
Ok(Value::Color(Arc::new(color.desaturate(amount))))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn grayscale(mut args: ArgumentResult, visitor: &mut Visitor) -> SassResult<Value> {
|
pub(crate) fn grayscale(mut args: ArgumentResult, visitor: &mut Visitor) -> SassResult<Value> {
|
||||||
@ -322,7 +322,7 @@ pub(crate) fn grayscale(mut args: ArgumentResult, visitor: &mut Visitor) -> Sass
|
|||||||
.into())
|
.into())
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
Ok(Value::Color(Box::new(color.desaturate(Number::one()))))
|
Ok(Value::Color(Arc::new(color.desaturate(Number::one()))))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn complement(mut args: ArgumentResult, visitor: &mut Visitor) -> SassResult<Value> {
|
pub(crate) fn complement(mut args: ArgumentResult, visitor: &mut Visitor) -> SassResult<Value> {
|
||||||
@ -330,7 +330,7 @@ pub(crate) fn complement(mut args: ArgumentResult, visitor: &mut Visitor) -> Sas
|
|||||||
let color = args
|
let color = args
|
||||||
.get_err(0, "color")?
|
.get_err(0, "color")?
|
||||||
.assert_color_with_name("color", args.span())?;
|
.assert_color_with_name("color", args.span())?;
|
||||||
Ok(Value::Color(Box::new(color.complement())))
|
Ok(Value::Color(Arc::new(color.complement())))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn invert(mut args: ArgumentResult, visitor: &mut Visitor) -> SassResult<Value> {
|
pub(crate) fn invert(mut args: ArgumentResult, visitor: &mut Visitor) -> SassResult<Value> {
|
||||||
@ -362,7 +362,7 @@ pub(crate) fn invert(mut args: ArgumentResult, visitor: &mut Visitor) -> SassRes
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
match args.get_err(0, "color")? {
|
match args.get_err(0, "color")? {
|
||||||
Value::Color(c) => Ok(Value::Color(Box::new(
|
Value::Color(c) => Ok(Value::Color(Arc::new(
|
||||||
c.invert(weight.unwrap_or_else(Number::one)),
|
c.invert(weight.unwrap_or_else(Number::one)),
|
||||||
))),
|
))),
|
||||||
Value::Dimension(SassNumber {
|
Value::Dimension(SassNumber {
|
||||||
|
@ -78,7 +78,7 @@ fn hwb_inner(mut args: ArgumentResult, visitor: &mut Visitor) -> SassResult<Valu
|
|||||||
None => Number::one(),
|
None => Number::one(),
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(Value::Color(Box::new(Color::from_hwb(
|
Ok(Value::Color(Arc::new(Color::from_hwb(
|
||||||
hue,
|
hue,
|
||||||
whiteness.num,
|
whiteness.num,
|
||||||
blackness.num,
|
blackness.num,
|
||||||
|
@ -104,7 +104,7 @@ fn opacify(mut args: ArgumentResult, visitor: &mut Visitor) -> SassResult<Value>
|
|||||||
|
|
||||||
let amount = bound!(args, "amount", amount.num, amount.unit(), 0, 1);
|
let amount = bound!(args, "amount", amount.num, amount.unit(), 0, 1);
|
||||||
|
|
||||||
Ok(Value::Color(Box::new(color.fade_in(amount))))
|
Ok(Value::Color(Arc::new(color.fade_in(amount))))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn transparentize(mut args: ArgumentResult, visitor: &mut Visitor) -> SassResult<Value> {
|
fn transparentize(mut args: ArgumentResult, visitor: &mut Visitor) -> SassResult<Value> {
|
||||||
@ -127,7 +127,7 @@ fn transparentize(mut args: ArgumentResult, visitor: &mut Visitor) -> SassResult
|
|||||||
.into())
|
.into())
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
Ok(Value::Color(Box::new(color.fade_out(amount))))
|
Ok(Value::Color(Arc::new(color.fade_out(amount))))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn declare(f: &mut GlobalFunctionMap) {
|
pub(crate) fn declare(f: &mut GlobalFunctionMap) {
|
||||||
|
@ -57,7 +57,7 @@ pub(crate) fn change_color(mut args: ArgumentResult, visitor: &mut Visitor) -> S
|
|||||||
opt_rgba!(args, blue, "blue", 0, 255);
|
opt_rgba!(args, blue, "blue", 0, 255);
|
||||||
|
|
||||||
if red.is_some() || green.is_some() || blue.is_some() {
|
if red.is_some() || green.is_some() || blue.is_some() {
|
||||||
return Ok(Value::Color(Box::new(Color::from_rgba(
|
return Ok(Value::Color(Arc::new(Color::from_rgba(
|
||||||
red.unwrap_or_else(|| color.red()),
|
red.unwrap_or_else(|| color.red()),
|
||||||
green.unwrap_or_else(|| color.green()),
|
green.unwrap_or_else(|| color.green()),
|
||||||
blue.unwrap_or_else(|| color.blue()),
|
blue.unwrap_or_else(|| color.blue()),
|
||||||
@ -84,7 +84,7 @@ pub(crate) fn change_color(mut args: ArgumentResult, visitor: &mut Visitor) -> S
|
|||||||
if hue.is_some() || saturation.is_some() || lightness.is_some() {
|
if hue.is_some() || saturation.is_some() || lightness.is_some() {
|
||||||
// Color::as_hsla() returns more exact values than Color::hue(), etc.
|
// Color::as_hsla() returns more exact values than Color::hue(), etc.
|
||||||
let (this_hue, this_saturation, this_lightness, this_alpha) = color.as_hsla();
|
let (this_hue, this_saturation, this_lightness, this_alpha) = color.as_hsla();
|
||||||
return Ok(Value::Color(Box::new(Color::from_hsla(
|
return Ok(Value::Color(Arc::new(Color::from_hsla(
|
||||||
hue.unwrap_or(this_hue),
|
hue.unwrap_or(this_hue),
|
||||||
saturation.unwrap_or(this_saturation),
|
saturation.unwrap_or(this_saturation),
|
||||||
lightness.unwrap_or(this_lightness),
|
lightness.unwrap_or(this_lightness),
|
||||||
@ -93,9 +93,9 @@ pub(crate) fn change_color(mut args: ArgumentResult, visitor: &mut Visitor) -> S
|
|||||||
}
|
}
|
||||||
|
|
||||||
Ok(Value::Color(if let Some(a) = alpha {
|
Ok(Value::Color(if let Some(a) = alpha {
|
||||||
Box::new(color.with_alpha(a))
|
Arc::new(color.with_alpha(a))
|
||||||
} else {
|
} else {
|
||||||
Box::new(color)
|
color
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -110,7 +110,7 @@ pub(crate) fn adjust_color(mut args: ArgumentResult, visitor: &mut Visitor) -> S
|
|||||||
opt_rgba!(args, blue, "blue", -255, 255);
|
opt_rgba!(args, blue, "blue", -255, 255);
|
||||||
|
|
||||||
if red.is_some() || green.is_some() || blue.is_some() {
|
if red.is_some() || green.is_some() || blue.is_some() {
|
||||||
return Ok(Value::Color(Box::new(Color::from_rgba(
|
return Ok(Value::Color(Arc::new(Color::from_rgba(
|
||||||
color.red() + red.unwrap_or_else(Number::zero),
|
color.red() + red.unwrap_or_else(Number::zero),
|
||||||
color.green() + green.unwrap_or_else(Number::zero),
|
color.green() + green.unwrap_or_else(Number::zero),
|
||||||
color.blue() + blue.unwrap_or_else(Number::zero),
|
color.blue() + blue.unwrap_or_else(Number::zero),
|
||||||
@ -137,7 +137,7 @@ pub(crate) fn adjust_color(mut args: ArgumentResult, visitor: &mut Visitor) -> S
|
|||||||
if hue.is_some() || saturation.is_some() || lightness.is_some() {
|
if hue.is_some() || saturation.is_some() || lightness.is_some() {
|
||||||
// Color::as_hsla() returns more exact values than Color::hue(), etc.
|
// Color::as_hsla() returns more exact values than Color::hue(), etc.
|
||||||
let (this_hue, this_saturation, this_lightness, this_alpha) = color.as_hsla();
|
let (this_hue, this_saturation, this_lightness, this_alpha) = color.as_hsla();
|
||||||
return Ok(Value::Color(Box::new(Color::from_hsla(
|
return Ok(Value::Color(Arc::new(Color::from_hsla(
|
||||||
this_hue + hue.unwrap_or_else(Number::zero),
|
this_hue + hue.unwrap_or_else(Number::zero),
|
||||||
this_saturation + saturation.unwrap_or_else(Number::zero),
|
this_saturation + saturation.unwrap_or_else(Number::zero),
|
||||||
this_lightness + lightness.unwrap_or_else(Number::zero),
|
this_lightness + lightness.unwrap_or_else(Number::zero),
|
||||||
@ -147,9 +147,9 @@ pub(crate) fn adjust_color(mut args: ArgumentResult, visitor: &mut Visitor) -> S
|
|||||||
|
|
||||||
Ok(Value::Color(if let Some(a) = alpha {
|
Ok(Value::Color(if let Some(a) = alpha {
|
||||||
let temp_alpha = color.alpha();
|
let temp_alpha = color.alpha();
|
||||||
Box::new(color.with_alpha(temp_alpha + a))
|
Arc::new(color.with_alpha(temp_alpha + a))
|
||||||
} else {
|
} else {
|
||||||
Box::new(color)
|
color
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -198,7 +198,7 @@ pub(crate) fn scale_color(mut args: ArgumentResult, visitor: &mut Visitor) -> Sa
|
|||||||
let alpha = get_arg(&mut args, "alpha", -100.0, 100.0)?;
|
let alpha = get_arg(&mut args, "alpha", -100.0, 100.0)?;
|
||||||
|
|
||||||
if red.is_some() || green.is_some() || blue.is_some() {
|
if red.is_some() || green.is_some() || blue.is_some() {
|
||||||
return Ok(Value::Color(Box::new(Color::from_rgba(
|
return Ok(Value::Color(Arc::new(Color::from_rgba(
|
||||||
scale(color.red(), red.unwrap_or_else(Number::zero), Number(255.0)),
|
scale(color.red(), red.unwrap_or_else(Number::zero), Number(255.0)),
|
||||||
scale(
|
scale(
|
||||||
color.green(),
|
color.green(),
|
||||||
@ -224,7 +224,7 @@ pub(crate) fn scale_color(mut args: ArgumentResult, visitor: &mut Visitor) -> Sa
|
|||||||
if saturation.is_some() || lightness.is_some() {
|
if saturation.is_some() || lightness.is_some() {
|
||||||
// Color::as_hsla() returns more exact values than Color::hue(), etc.
|
// Color::as_hsla() returns more exact values than Color::hue(), etc.
|
||||||
let (this_hue, this_saturation, this_lightness, this_alpha) = color.as_hsla();
|
let (this_hue, this_saturation, this_lightness, this_alpha) = color.as_hsla();
|
||||||
return Ok(Value::Color(Box::new(Color::from_hsla(
|
return Ok(Value::Color(Arc::new(Color::from_hsla(
|
||||||
scale(this_hue, Number::zero(), Number(360.0)),
|
scale(this_hue, Number::zero(), Number(360.0)),
|
||||||
scale(
|
scale(
|
||||||
this_saturation,
|
this_saturation,
|
||||||
@ -252,7 +252,7 @@ pub(crate) fn scale_color(mut args: ArgumentResult, visitor: &mut Visitor) -> Sa
|
|||||||
let this_whiteness = color.whiteness() * Number(100.0);
|
let this_whiteness = color.whiteness() * Number(100.0);
|
||||||
let this_blackness = color.blackness() * Number(100.0);
|
let this_blackness = color.blackness() * Number(100.0);
|
||||||
|
|
||||||
return Ok(Value::Color(Box::new(Color::from_hwb(
|
return Ok(Value::Color(Arc::new(Color::from_hwb(
|
||||||
scale(this_hue, Number::zero(), Number(360.0)),
|
scale(this_hue, Number::zero(), Number(360.0)),
|
||||||
scale(
|
scale(
|
||||||
this_whiteness,
|
this_whiteness,
|
||||||
@ -274,9 +274,9 @@ pub(crate) fn scale_color(mut args: ArgumentResult, visitor: &mut Visitor) -> Sa
|
|||||||
|
|
||||||
Ok(Value::Color(if let Some(a) = alpha {
|
Ok(Value::Color(if let Some(a) = alpha {
|
||||||
let temp_alpha = color.alpha();
|
let temp_alpha = color.alpha();
|
||||||
Box::new(color.with_alpha(scale(temp_alpha, a, Number::one())))
|
Arc::new(color.with_alpha(scale(temp_alpha, a, Number::one())))
|
||||||
} else {
|
} else {
|
||||||
Box::new(color)
|
color
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -72,7 +72,7 @@ fn inner_rgb_2_arg(
|
|||||||
|
|
||||||
let color = color.assert_color_with_name("color", args.span())?;
|
let color = color.assert_color_with_name("color", args.span())?;
|
||||||
let alpha = alpha.assert_number_with_name("alpha", args.span())?;
|
let alpha = alpha.assert_number_with_name("alpha", args.span())?;
|
||||||
Ok(Value::Color(Box::new(color.with_alpha(Number(
|
Ok(Value::Color(Arc::new(color.with_alpha(Number(
|
||||||
percentage_or_unitless(&alpha, 1.0, "alpha", args.span(), visitor)?,
|
percentage_or_unitless(&alpha, 1.0, "alpha", args.span(), visitor)?,
|
||||||
)))))
|
)))))
|
||||||
}
|
}
|
||||||
@ -120,7 +120,7 @@ fn inner_rgb_3_arg(
|
|||||||
let green = green.assert_number_with_name("green", span)?;
|
let green = green.assert_number_with_name("green", span)?;
|
||||||
let blue = blue.assert_number_with_name("blue", span)?;
|
let blue = blue.assert_number_with_name("blue", span)?;
|
||||||
|
|
||||||
Ok(Value::Color(Box::new(Color::from_rgba_fn(
|
Ok(Value::Color(Arc::new(Color::from_rgba_fn(
|
||||||
Number(fuzzy_round(percentage_or_unitless(
|
Number(fuzzy_round(percentage_or_unitless(
|
||||||
&red, 255.0, "red", span, visitor,
|
&red, 255.0, "red", span, visitor,
|
||||||
)?)),
|
)?)),
|
||||||
@ -432,7 +432,7 @@ pub(crate) fn mix(mut args: ArgumentResult, visitor: &mut Visitor) -> SassResult
|
|||||||
.into())
|
.into())
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
Ok(Value::Color(Box::new(color1.mix(&color2, weight))))
|
Ok(Value::Color(Arc::new(color1.mix(&color2, weight))))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn declare(f: &mut GlobalFunctionMap) {
|
pub(crate) fn declare(f: &mut GlobalFunctionMap) {
|
||||||
|
@ -27,6 +27,7 @@ mod builtin_imports {
|
|||||||
};
|
};
|
||||||
|
|
||||||
pub(crate) use std::{
|
pub(crate) use std::{
|
||||||
|
sync::Arc,
|
||||||
cmp::Ordering,
|
cmp::Ordering,
|
||||||
collections::{BTreeMap, BTreeSet},
|
collections::{BTreeMap, BTreeSet},
|
||||||
};
|
};
|
||||||
|
@ -197,7 +197,7 @@ impl Color {
|
|||||||
/// Mix two colors together with weight
|
/// Mix two colors together with weight
|
||||||
/// Algorithm adapted from
|
/// Algorithm adapted from
|
||||||
/// <https://github.com/sass/dart-sass/blob/0d0270cb12a9ac5cce73a4d0785fecb00735feee/lib/src/functions/color.dart#L718>
|
/// <https://github.com/sass/dart-sass/blob/0d0270cb12a9ac5cce73a4d0785fecb00735feee/lib/src/functions/color.dart#L718>
|
||||||
pub fn mix(self, other: &Color, weight: Number) -> Self {
|
pub fn mix(&self, other: &Color, weight: Number) -> Self {
|
||||||
let weight = weight.clamp(0.0, 100.0);
|
let weight = weight.clamp(0.0, 100.0);
|
||||||
let normalized_weight = weight * Number(2.0) - Number::one();
|
let normalized_weight = weight * Number(2.0) - Number::one();
|
||||||
let alpha_distance = self.alpha() - other.alpha();
|
let alpha_distance = self.alpha() - other.alpha();
|
||||||
@ -445,21 +445,21 @@ impl Color {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Change `alpha` to value given
|
/// Change `alpha` to value given
|
||||||
pub fn with_alpha(self, alpha: Number) -> Self {
|
pub fn with_alpha(&self, alpha: Number) -> Self {
|
||||||
Color::from_rgba(self.red(), self.green(), self.blue(), alpha)
|
Color::from_rgba(self.red(), self.green(), self.blue(), alpha)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Makes a color more opaque.
|
/// Makes a color more opaque.
|
||||||
/// Takes a color and a number between 0 and 1,
|
/// Takes a color and a number between 0 and 1,
|
||||||
/// and returns a color with the opacity increased by that amount.
|
/// and returns a color with the opacity increased by that amount.
|
||||||
pub fn fade_in(self, amount: Number) -> Self {
|
pub fn fade_in(&self, amount: Number) -> Self {
|
||||||
Color::from_rgba(self.red(), self.green(), self.blue(), self.alpha() + amount)
|
Color::from_rgba(self.red(), self.green(), self.blue(), self.alpha() + amount)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Makes a color more transparent.
|
/// Makes a color more transparent.
|
||||||
/// Takes a color and a number between 0 and 1,
|
/// Takes a color and a number between 0 and 1,
|
||||||
/// and returns a color with the opacity decreased by that amount.
|
/// and returns a color with the opacity decreased by that amount.
|
||||||
pub fn fade_out(self, amount: Number) -> Self {
|
pub fn fade_out(&self, amount: Number) -> Self {
|
||||||
Color::from_rgba(self.red(), self.green(), self.blue(), self.alpha() - amount)
|
Color::from_rgba(self.red(), self.green(), self.blue(), self.alpha() - amount)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2427,24 +2427,25 @@ impl<'a> Visitor<'a> {
|
|||||||
rhs,
|
rhs,
|
||||||
allows_slash,
|
allows_slash,
|
||||||
span,
|
span,
|
||||||
} => self.visit_bin_op(*lhs, op, *rhs, allows_slash, span)?,
|
} => self.visit_bin_op((*lhs).clone(), op, (*rhs).clone(), allows_slash, span)?,
|
||||||
AstExpr::True => Value::True,
|
AstExpr::True => Value::True,
|
||||||
AstExpr::False => Value::False,
|
AstExpr::False => Value::False,
|
||||||
AstExpr::Calculation { name, args } => {
|
AstExpr::Calculation { name, args } => {
|
||||||
self.visit_calculation_expr(name, args, self.span_before)?
|
self.visit_calculation_expr(name, args, self.span_before)?
|
||||||
}
|
}
|
||||||
AstExpr::FunctionCall(func_call) => self.visit_function_call_expr(func_call)?,
|
AstExpr::FunctionCall(func_call) => self.visit_function_call_expr(func_call)?,
|
||||||
AstExpr::If(if_expr) => self.visit_ternary(*if_expr)?,
|
AstExpr::If(if_expr) => self.visit_ternary((*if_expr).clone())?,
|
||||||
AstExpr::InterpolatedFunction(func) => self.visit_interpolated_func_expr(func)?,
|
AstExpr::InterpolatedFunction(func) => self.visit_interpolated_func_expr(func)?,
|
||||||
AstExpr::Map(map) => self.visit_map(map)?,
|
AstExpr::Map(map) => self.visit_map(map)?,
|
||||||
AstExpr::Null => Value::Null,
|
AstExpr::Null => Value::Null,
|
||||||
AstExpr::Paren(expr) => self.visit_expr(*expr)?,
|
AstExpr::Paren(expr) => self.visit_expr((*expr).clone())?,
|
||||||
AstExpr::ParentSelector => self.visit_parent_selector(),
|
AstExpr::ParentSelector => self.visit_parent_selector(),
|
||||||
AstExpr::UnaryOp(op, expr, span) => self.visit_unary_op(op, *expr, span)?,
|
AstExpr::UnaryOp(op, expr, span) => self.visit_unary_op(op, (*expr).clone(), span)?,
|
||||||
AstExpr::Variable { name, namespace } => self.env.get_var(name, namespace)?,
|
AstExpr::Variable { name, namespace } => self.env.get_var(name, namespace)?,
|
||||||
AstExpr::Supports(condition) => {
|
AstExpr::Supports(condition) => Value::String(
|
||||||
Value::String(self.visit_supports_condition(*condition)?, QuoteKind::None)
|
self.visit_supports_condition((*condition).clone())?,
|
||||||
}
|
QuoteKind::None,
|
||||||
|
),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2459,7 +2460,8 @@ impl<'a> Visitor<'a> {
|
|||||||
AstExpr::FunctionCall(FunctionCallExpr { ref name, .. })
|
AstExpr::FunctionCall(FunctionCallExpr { ref name, .. })
|
||||||
if name.as_str().to_ascii_lowercase() == "var" =>
|
if name.as_str().to_ascii_lowercase() == "var" =>
|
||||||
{
|
{
|
||||||
let result = self.visit_calculation_value(*inner, in_min_or_max, span)?;
|
let result =
|
||||||
|
self.visit_calculation_value((*inner).clone(), in_min_or_max, span)?;
|
||||||
|
|
||||||
if let CalculationArg::String(text) = result {
|
if let CalculationArg::String(text) = result {
|
||||||
CalculationArg::String(format!("({})", text))
|
CalculationArg::String(format!("({})", text))
|
||||||
@ -2467,7 +2469,7 @@ impl<'a> Visitor<'a> {
|
|||||||
result
|
result
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => self.visit_calculation_value(*inner, in_min_or_max, span)?,
|
_ => self.visit_calculation_value((*inner).clone(), in_min_or_max, span)?,
|
||||||
},
|
},
|
||||||
AstExpr::String(string_expr, _span) => {
|
AstExpr::String(string_expr, _span) => {
|
||||||
debug_assert!(string_expr.1 == QuoteKind::None);
|
debug_assert!(string_expr.1 == QuoteKind::None);
|
||||||
@ -2475,8 +2477,8 @@ impl<'a> Visitor<'a> {
|
|||||||
}
|
}
|
||||||
AstExpr::BinaryOp { lhs, op, rhs, .. } => SassCalculation::operate_internal(
|
AstExpr::BinaryOp { lhs, op, rhs, .. } => SassCalculation::operate_internal(
|
||||||
op,
|
op,
|
||||||
self.visit_calculation_value(*lhs, in_min_or_max, span)?,
|
self.visit_calculation_value((*lhs).clone(), in_min_or_max, span)?,
|
||||||
self.visit_calculation_value(*rhs, in_min_or_max, span)?,
|
self.visit_calculation_value((*rhs).clone(), in_min_or_max, span)?,
|
||||||
in_min_or_max,
|
in_min_or_max,
|
||||||
!self.flags.in_supports_declaration(),
|
!self.flags.in_supports_declaration(),
|
||||||
self.options,
|
self.options,
|
||||||
|
@ -3,7 +3,7 @@ use std::{
|
|||||||
collections::{BTreeMap, HashSet},
|
collections::{BTreeMap, HashSet},
|
||||||
ffi::OsString,
|
ffi::OsString,
|
||||||
mem,
|
mem,
|
||||||
path::{Path, PathBuf},
|
path::{Path, PathBuf}, sync::Arc,
|
||||||
};
|
};
|
||||||
|
|
||||||
use codemap::{CodeMap, Span, Spanned};
|
use codemap::{CodeMap, Span, Spanned};
|
||||||
@ -745,7 +745,7 @@ pub(crate) trait StylesheetParser<'a>: BaseParser<'a> + Sized {
|
|||||||
}
|
}
|
||||||
|
|
||||||
buffer
|
buffer
|
||||||
.add_expr(AstExpr::Supports(Box::new(query)).span(self.span_before()));
|
.add_expr(AstExpr::Supports(Arc::new(query)).span(self.span_before()));
|
||||||
|
|
||||||
if !is_declaration {
|
if !is_declaration {
|
||||||
buffer.add_char(')');
|
buffer.add_char(')');
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
use std::{iter::Iterator, marker::PhantomData};
|
use std::{iter::Iterator, marker::PhantomData, sync::Arc};
|
||||||
|
|
||||||
use codemap::Spanned;
|
use codemap::Spanned;
|
||||||
|
|
||||||
@ -539,9 +539,9 @@ impl<'a, 'c, P: StylesheetParser<'a>> ValueParser<'a, 'c, P> {
|
|||||||
} else {
|
} else {
|
||||||
self.single_expression = Some(
|
self.single_expression = Some(
|
||||||
AstExpr::BinaryOp {
|
AstExpr::BinaryOp {
|
||||||
lhs: Box::new(left.node),
|
lhs: Arc::new(left.node),
|
||||||
op: operator,
|
op: operator,
|
||||||
rhs: Box::new(right.node),
|
rhs: Arc::new(right.node),
|
||||||
allows_slash: false,
|
allows_slash: false,
|
||||||
span,
|
span,
|
||||||
}
|
}
|
||||||
@ -742,7 +742,7 @@ impl<'a, 'c, P: StylesheetParser<'a>> ValueParser<'a, 'c, P> {
|
|||||||
parser
|
parser
|
||||||
.flags_mut()
|
.flags_mut()
|
||||||
.set(ContextFlags::IN_PARENS, was_in_parentheses);
|
.set(ContextFlags::IN_PARENS, was_in_parentheses);
|
||||||
return Ok(AstExpr::Paren(Box::new(first.node)).span(first.span));
|
return Ok(AstExpr::Paren(Arc::new(first.node)).span(first.span));
|
||||||
}
|
}
|
||||||
|
|
||||||
parser.whitespace()?;
|
parser.whitespace()?;
|
||||||
@ -842,7 +842,7 @@ impl<'a, 'c, P: StylesheetParser<'a>> ValueParser<'a, 'c, P> {
|
|||||||
})
|
})
|
||||||
) {
|
) {
|
||||||
let color = self.parse_hex_color_contents(parser)?;
|
let color = self.parse_hex_color_contents(parser)?;
|
||||||
return Ok(AstExpr::Color(Box::new(color)).span(parser.toks_mut().span_from(start)));
|
return Ok(AstExpr::Color(Arc::new(color)).span(parser.toks_mut().span_from(start)));
|
||||||
}
|
}
|
||||||
|
|
||||||
let after_hash = parser.toks().cursor();
|
let after_hash = parser.toks().cursor();
|
||||||
@ -851,7 +851,7 @@ impl<'a, 'c, P: StylesheetParser<'a>> ValueParser<'a, 'c, P> {
|
|||||||
parser.toks_mut().set_cursor(after_hash);
|
parser.toks_mut().set_cursor(after_hash);
|
||||||
let color = self.parse_hex_color_contents(parser)?;
|
let color = self.parse_hex_color_contents(parser)?;
|
||||||
return Ok(
|
return Ok(
|
||||||
AstExpr::Color(Box::new(color)).span(parser.toks_mut().span_from(after_hash))
|
AstExpr::Color(Arc::new(color)).span(parser.toks_mut().span_from(after_hash))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -940,7 +940,7 @@ impl<'a, 'c, P: StylesheetParser<'a>> ValueParser<'a, 'c, P> {
|
|||||||
|
|
||||||
let span = op_span.merge(parser.toks().current_span());
|
let span = op_span.merge(parser.toks().current_span());
|
||||||
|
|
||||||
Ok(AstExpr::UnaryOp(operator, Box::new(operand.node), span).span(span))
|
Ok(AstExpr::UnaryOp(operator, Arc::new(operand.node), span).span(span))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn expect_unary_operator(parser: &mut P) -> SassResult<UnaryOp> {
|
fn expect_unary_operator(parser: &mut P) -> SassResult<UnaryOp> {
|
||||||
@ -1159,7 +1159,7 @@ impl<'a, 'c, P: StylesheetParser<'a>> ValueParser<'a, 'c, P> {
|
|||||||
if plain == "if" && parser.toks().next_char_is('(') {
|
if plain == "if" && parser.toks().next_char_is('(') {
|
||||||
let call_args = parser.parse_argument_invocation(false, false)?;
|
let call_args = parser.parse_argument_invocation(false, false)?;
|
||||||
let span = call_args.span;
|
let span = call_args.span;
|
||||||
return Ok(AstExpr::If(Box::new(Ternary(call_args))).span(span));
|
return Ok(AstExpr::If(Arc::new(Ternary(call_args))).span(span));
|
||||||
} else if plain == "not" {
|
} else if plain == "not" {
|
||||||
parser.whitespace()?;
|
parser.whitespace()?;
|
||||||
|
|
||||||
@ -1167,7 +1167,7 @@ impl<'a, 'c, P: StylesheetParser<'a>> ValueParser<'a, 'c, P> {
|
|||||||
|
|
||||||
let span = parser.toks_mut().span_from(start);
|
let span = parser.toks_mut().span_from(start);
|
||||||
|
|
||||||
return Ok(AstExpr::UnaryOp(UnaryOp::Not, Box::new(value.node), span).span(span));
|
return Ok(AstExpr::UnaryOp(UnaryOp::Not, Arc::new(value.node), span).span(span));
|
||||||
}
|
}
|
||||||
|
|
||||||
let lower_ref = lower.as_ref().unwrap();
|
let lower_ref = lower.as_ref().unwrap();
|
||||||
@ -1181,7 +1181,7 @@ impl<'a, 'c, P: StylesheetParser<'a>> ValueParser<'a, 'c, P> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if let Some(color) = NAMED_COLORS.get_by_name(lower_ref.as_str()) {
|
if let Some(color) = NAMED_COLORS.get_by_name(lower_ref.as_str()) {
|
||||||
return Ok(AstExpr::Color(Box::new(Color::new(
|
return Ok(AstExpr::Color(Arc::new(Color::new(
|
||||||
color[0],
|
color[0],
|
||||||
color[1],
|
color[1],
|
||||||
color[2],
|
color[2],
|
||||||
@ -1535,7 +1535,7 @@ impl<'a, 'c, P: StylesheetParser<'a>> ValueParser<'a, 'c, P> {
|
|||||||
parser.whitespace()?;
|
parser.whitespace()?;
|
||||||
parser.expect_char(')')?;
|
parser.expect_char(')')?;
|
||||||
|
|
||||||
Ok(AstExpr::Paren(Box::new(value)).span(parser.toks_mut().span_from(start)))
|
Ok(AstExpr::Paren(Arc::new(value)).span(parser.toks_mut().span_from(start)))
|
||||||
}
|
}
|
||||||
_ if !parser.looking_at_identifier() => Err((
|
_ if !parser.looking_at_identifier() => Err((
|
||||||
"Expected number, variable, function, or calculation.",
|
"Expected number, variable, function, or calculation.",
|
||||||
@ -1567,7 +1567,7 @@ impl<'a, 'c, P: StylesheetParser<'a>> ValueParser<'a, 'c, P> {
|
|||||||
if let Some(calc) = calculation {
|
if let Some(calc) = calculation {
|
||||||
Ok(calc)
|
Ok(calc)
|
||||||
} else if lowercase == "if" {
|
} else if lowercase == "if" {
|
||||||
Ok(AstExpr::If(Box::new(Ternary(
|
Ok(AstExpr::If(Arc::new(Ternary(
|
||||||
parser.parse_argument_invocation(false, false)?,
|
parser.parse_argument_invocation(false, false)?,
|
||||||
)))
|
)))
|
||||||
.span(parser.toks_mut().span_from(start)))
|
.span(parser.toks_mut().span_from(start)))
|
||||||
@ -1601,13 +1601,13 @@ impl<'a, 'c, P: StylesheetParser<'a>> ValueParser<'a, 'c, P> {
|
|||||||
let span = product.span.merge(rhs.span);
|
let span = product.span.merge(rhs.span);
|
||||||
|
|
||||||
product.node = AstExpr::BinaryOp {
|
product.node = AstExpr::BinaryOp {
|
||||||
lhs: Box::new(product.node),
|
lhs: Arc::new(product.node),
|
||||||
op: if op == '*' {
|
op: if op == '*' {
|
||||||
BinaryOp::Mul
|
BinaryOp::Mul
|
||||||
} else {
|
} else {
|
||||||
BinaryOp::Div
|
BinaryOp::Div
|
||||||
},
|
},
|
||||||
rhs: Box::new(rhs.node),
|
rhs: Arc::new(rhs.node),
|
||||||
allows_slash: false,
|
allows_slash: false,
|
||||||
span,
|
span,
|
||||||
};
|
};
|
||||||
@ -1655,13 +1655,13 @@ impl<'a, 'c, P: StylesheetParser<'a>> ValueParser<'a, 'c, P> {
|
|||||||
let span = sum.span.merge(rhs.span);
|
let span = sum.span.merge(rhs.span);
|
||||||
|
|
||||||
sum = AstExpr::BinaryOp {
|
sum = AstExpr::BinaryOp {
|
||||||
lhs: Box::new(sum.node),
|
lhs: Arc::new(sum.node),
|
||||||
op: if next == '+' {
|
op: if next == '+' {
|
||||||
BinaryOp::Plus
|
BinaryOp::Plus
|
||||||
} else {
|
} else {
|
||||||
BinaryOp::Minus
|
BinaryOp::Minus
|
||||||
},
|
},
|
||||||
rhs: Box::new(rhs.node),
|
rhs: Arc::new(rhs.node),
|
||||||
allows_slash: false,
|
allows_slash: false,
|
||||||
span,
|
span,
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
use std::cmp::Ordering;
|
use std::{cmp::Ordering, sync::Arc};
|
||||||
|
|
||||||
use codemap::{Span, Spanned};
|
use codemap::{Span, Spanned};
|
||||||
|
|
||||||
@ -35,7 +35,7 @@ pub(crate) enum Value {
|
|||||||
Null,
|
Null,
|
||||||
Dimension(SassNumber),
|
Dimension(SassNumber),
|
||||||
List(Vec<Value>, ListSeparator, Brackets),
|
List(Vec<Value>, ListSeparator, Brackets),
|
||||||
Color(Box<Color>),
|
Color(Arc<Color>),
|
||||||
String(String, QuoteKind),
|
String(String, QuoteKind),
|
||||||
Map(SassMap),
|
Map(SassMap),
|
||||||
ArgList(ArgList),
|
ArgList(ArgList),
|
||||||
@ -155,9 +155,9 @@ impl Value {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn assert_color_with_name(self, name: &str, span: Span) -> SassResult<Color> {
|
pub fn assert_color_with_name(self, name: &str, span: Span) -> SassResult<Arc<Color>> {
|
||||||
match self {
|
match self {
|
||||||
Value::Color(c) => Ok(*c),
|
Value::Color(c) => Ok(c),
|
||||||
_ => Err((
|
_ => Err((
|
||||||
format!(
|
format!(
|
||||||
"${name}: {} is not a color.",
|
"${name}: {} is not a color.",
|
||||||
|
Loading…
x
Reference in New Issue
Block a user