From 8d1e8a99c59257e638a49d180c229b5362e4415c Mon Sep 17 00:00:00 2001 From: Connor Skees Date: Mon, 17 Aug 2020 06:16:18 -0400 Subject: [PATCH] refactor how default variables are evaluated --- src/parse/variable.rs | 49 +++++++++++++++++++++++++++---------------- src/scope.rs | 22 +++++++------------ tests/selectors.rs | 2 +- tests/variables.rs | 26 +++++++++++++++++++++++ 4 files changed, 66 insertions(+), 33 deletions(-) diff --git a/src/parse/variable.rs b/src/parse/variable.rs index c1bedf4..1656db5 100644 --- a/src/parse/variable.rs +++ b/src/parse/variable.rs @@ -39,30 +39,43 @@ impl<'a> Parser<'a> { } = self.parse_variable_value()?; if default { - let config_val = self.module_config.get(ident); - if self.at_root && !self.flags.in_control_flow() { - if !self.global_scope.default_var_exists(ident) { - let value = if let Some(config_val) = config_val { - config_val - } else { - self.parse_value_from_vec(val_toks, true)?.node - }; + let config_val = self.module_config.get(ident).filter(|v| !v.is_null()); - self.global_scope.insert_var(ident, value); - } - } else { - let value = if let Some(config_val) = config_val { - config_val + let value = if (self.at_root && !self.flags.in_control_flow()) || global { + if self.global_scope.default_var_exists(ident) { + return Ok(()); + } else if let Some(value) = config_val { + value } else { self.parse_value_from_vec(val_toks, true)?.node - }; - - if global && !self.global_scope.default_var_exists(ident) { - self.global_scope.insert_var(ident, value.clone()); } - self.scopes.insert_default_var(ident, value); + } else if self.at_root && self.flags.in_control_flow() { + if self.global_scope.default_var_exists(ident) { + return Ok(()); + } + + self.parse_value_from_vec(val_toks, true)?.node + } else if !self.at_root { + if self.scopes.default_var_exists(ident) { + return Ok(()); + } + + self.parse_value_from_vec(val_toks, true)?.node + } else { + self.parse_value_from_vec(val_toks, true)?.node + }; + + if self.at_root && !self.flags.in_control_flow() { + self.global_scope.insert_var(ident, value); + return Ok(()); } + if global { + self.global_scope.insert_var(ident, value.clone()); + } + + self.scopes.insert_var(ident, value); + return Ok(()); } diff --git a/src/scope.rs b/src/scope.rs index a70f843..528101b 100644 --- a/src/scope.rs +++ b/src/scope.rs @@ -88,21 +88,13 @@ impl Scope { self.merge(other.scope); } - pub fn default_var_exists(&mut self, s: Identifier) -> bool { + pub fn default_var_exists(&self, s: Identifier) -> bool { if let Some(default_var) = self.get_var_no_err(s) { !default_var.is_null() } else { false } } - - pub fn insert_default_var(&mut self, s: Identifier, v: Value) -> Option { - if self.default_var_exists(s) { - None - } else { - self.insert_var(s, v) - } - } } #[derive(Debug, Default)] @@ -171,12 +163,14 @@ impl Scopes { } } - pub fn insert_default_var(&mut self, s: Identifier, v: Value) -> Option { - if let Some(scope) = self.0.last_mut() { - scope.insert_default_var(s, v) - } else { - panic!() + pub fn default_var_exists(&self, name: Identifier) -> bool { + for scope in self.0.iter().rev() { + if scope.default_var_exists(name) { + return true; + } } + + false } pub fn get_var<'a>( diff --git a/tests/selectors.rs b/tests/selectors.rs index 6c70e00..b28b13b 100644 --- a/tests/selectors.rs +++ b/tests/selectors.rs @@ -682,7 +682,7 @@ test!( "null {\n color: null;\n}\n" ); test!( - #[ignore = "we do not yet have a good way of consuming a string without converting \a to a newline"] + #[ignore = "we do not yet have a good way of consuming a string without converting \\a to a newline"] silent_comment_in_quoted_attribute_value, ".foo bar[val=\"//\"] {\n color: &;\n}\n", ".foo bar[val=\"//\"] {\n color: .foo bar[val=\"//\"];\n}\n" diff --git a/tests/variables.rs b/tests/variables.rs index 71cffa1..f5be38f 100644 --- a/tests/variables.rs +++ b/tests/variables.rs @@ -182,6 +182,32 @@ test!( }", "a {\n color: red;\n}\n" ); +test!( + default_at_root_inside_control_flow, + "$a: initial; + + @if true { + $a: outer !default; + } + + a { + color: $a; + }", + "a {\n color: initial;\n}\n" +); +test!( + default_at_root_inside_control_flow_outer_is_null, + "$a: null; + + @if true { + $a: outer !default; + } + + a { + color: $a; + }", + "a {\n color: outer;\n}\n" +); // https://github.com/Kixiron/lasso/issues/7 test!( regression_test_for_lasso_0_3_0,