lazily evaluate default variable values
This commit is contained in:
parent
01a11d7787
commit
5634681fa2
@ -1,10 +1,7 @@
|
|||||||
use codemap::Spanned;
|
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
common::Identifier,
|
common::Identifier,
|
||||||
error::SassResult,
|
error::SassResult,
|
||||||
utils::{peek_ident_no_interpolation, read_until_closing_paren, read_until_closing_quote},
|
utils::{peek_ident_no_interpolation, read_until_closing_paren, read_until_closing_quote},
|
||||||
value::Value,
|
|
||||||
Token,
|
Token,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -12,15 +9,15 @@ use super::Parser;
|
|||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
struct VariableValue {
|
struct VariableValue {
|
||||||
value: Spanned<Value>,
|
val_toks: Vec<Token>,
|
||||||
global: bool,
|
global: bool,
|
||||||
default: bool,
|
default: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl VariableValue {
|
impl VariableValue {
|
||||||
pub const fn new(value: Spanned<Value>, global: bool, default: bool) -> Self {
|
pub const fn new(val_toks: Vec<Token>, global: bool, default: bool) -> Self {
|
||||||
Self {
|
Self {
|
||||||
value,
|
val_toks,
|
||||||
global,
|
global,
|
||||||
default,
|
default,
|
||||||
}
|
}
|
||||||
@ -35,35 +32,47 @@ impl<'a> Parser<'a> {
|
|||||||
if !matches!(self.toks.next(), Some(Token { kind: ':', .. })) {
|
if !matches!(self.toks.next(), Some(Token { kind: ':', .. })) {
|
||||||
return Err(("expected \":\".", self.span_before).into());
|
return Err(("expected \":\".", self.span_before).into());
|
||||||
}
|
}
|
||||||
let value = self.parse_variable_value()?;
|
let VariableValue {
|
||||||
|
val_toks,
|
||||||
|
global,
|
||||||
|
default,
|
||||||
|
} = self.parse_variable_value()?;
|
||||||
|
|
||||||
if value.global && !value.default {
|
if default {
|
||||||
self.global_scope.insert_var(ident, value.value.clone());
|
|
||||||
}
|
|
||||||
|
|
||||||
if value.default {
|
|
||||||
if self.at_root && !self.flags.in_control_flow() {
|
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);
|
let value = self.parse_value_from_vec(val_toks, true)?;
|
||||||
|
self.global_scope.insert_var(ident, value);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if value.global && !self.global_scope.var_exists(ident) {
|
let value = self.parse_value_from_vec(val_toks, true)?;
|
||||||
self.global_scope.insert_var(ident, value.value.clone());
|
if global && !self.global_scope.var_exists(ident) {
|
||||||
|
self.global_scope.insert_var(ident, value.clone());
|
||||||
}
|
}
|
||||||
self.scopes.insert_default_var(ident, value.value);
|
self.scopes.insert_default_var(ident, value);
|
||||||
}
|
}
|
||||||
} else if self.at_root {
|
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
|
||||||
|
let value = self.parse_value_from_vec(val_toks, true)?;
|
||||||
|
|
||||||
|
if global {
|
||||||
|
self.global_scope.insert_var(ident, value.clone());
|
||||||
|
}
|
||||||
|
|
||||||
|
if self.at_root {
|
||||||
if self.flags.in_control_flow() {
|
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);
|
self.global_scope.insert_var(ident, value);
|
||||||
} else {
|
} else {
|
||||||
self.scopes.insert_var(ident, value.value);
|
self.scopes.insert_var(ident, value);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
self.global_scope.insert_var(ident, value.value);
|
self.global_scope.insert_var(ident, value);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
self.scopes.insert_var(ident, value.value);
|
self.scopes.insert_var(ident, value);
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@ -166,7 +175,7 @@ impl<'a> Parser<'a> {
|
|||||||
_ => val_toks.push(self.toks.next().unwrap()),
|
_ => val_toks.push(self.toks.next().unwrap()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let val = self.parse_value_from_vec(val_toks, true)?;
|
|
||||||
Ok(VariableValue::new(val, global, default))
|
Ok(VariableValue::new(val_toks, global, default))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -138,6 +138,17 @@ test!(
|
|||||||
"$a: red != blue;\n\na {\n color: $a;\n}\n",
|
"$a: red != blue;\n\na {\n color: $a;\n}\n",
|
||||||
"a {\n color: true;\n}\n"
|
"a {\n color: true;\n}\n"
|
||||||
);
|
);
|
||||||
|
test!(
|
||||||
|
error_in_default_value_already_set_is_ignored,
|
||||||
|
"$a: red;
|
||||||
|
|
||||||
|
$a: hue(\"not a color, should error\") !default;
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: $a;
|
||||||
|
}",
|
||||||
|
"a {\n color: red;\n}\n"
|
||||||
|
);
|
||||||
// https://github.com/Kixiron/lasso/issues/7
|
// https://github.com/Kixiron/lasso/issues/7
|
||||||
test!(
|
test!(
|
||||||
regression_test_for_lasso_0_3_0,
|
regression_test_for_lasso_0_3_0,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user