From 71a7ee256addc3bdff3669c8ac84f36c06463070 Mon Sep 17 00:00:00 2001 From: "Arend van Beelen jr." Date: Wed, 27 Mar 2024 16:23:46 +0100 Subject: [PATCH] Refactor truthiness --- crates/core/src/binding.rs | 28 ++++++++++ crates/core/src/pattern/boolean_constant.rs | 61 ++------------------- crates/core/src/pattern/resolved_pattern.rs | 28 ++++++++++ 3 files changed, 61 insertions(+), 56 deletions(-) diff --git a/crates/core/src/binding.rs b/crates/core/src/binding.rs index c1d9d1f26..eed7ad439 100644 --- a/crates/core/src/binding.rs +++ b/crates/core/src/binding.rs @@ -6,6 +6,7 @@ use marzano_language::language::{FieldId, Language}; use marzano_language::target_language::TargetLanguage; use marzano_util::analysis_logs::{AnalysisLogBuilder, AnalysisLogs}; use marzano_util::position::{Position, Range}; +use marzano_util::tree_sitter_util::children_by_field_id_count; use std::ops::Range as StdRange; use std::{borrow::Cow, collections::HashMap, fmt::Display}; use tree_sitter::Node; @@ -22,6 +23,18 @@ pub enum Constant { Undefined, } +impl Constant { + pub(crate) fn is_truthy(&self) -> bool { + match self { + Constant::Integer(i) => *i != 0, + Constant::Float(d) => *d != 0.0, + Constant::Boolean(b) => *b, + Constant::String(s) => !s.is_empty(), + Constant::Undefined => false, + } + } +} + impl Display for Constant { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { @@ -511,6 +524,21 @@ impl<'a> Binding<'a> { Binding::ConstantRef(_) => None, } } + + pub fn is_truthy(&self) -> bool { + match self { + Self::Empty(..) => false, + Self::List(_, node, field_id) => { + let child_count = children_by_field_id_count(node, *field_id); + child_count > 0 + } + Self::Node(..) => true, + // This refers to a slice of the source code, not a Grit string literal, so it is truthy + Self::String(..) => true, + Self::FileName(_) => true, + Self::ConstantRef(c) => c.is_truthy(), + } + } } pub(crate) fn node_text<'a>(source: &'a str, node: &Node) -> &'a str { diff --git a/crates/core/src/pattern/boolean_constant.rs b/crates/core/src/pattern/boolean_constant.rs index fa6a82da2..c79d26352 100644 --- a/crates/core/src/pattern/boolean_constant.rs +++ b/crates/core/src/pattern/boolean_constant.rs @@ -1,12 +1,11 @@ use super::{ patterns::{Matcher, Name}, - resolved_pattern::{ResolvedPattern, ResolvedSnippet}, + resolved_pattern::ResolvedPattern, state::State, }; -use crate::binding::{Binding, Constant}; use crate::context::Context; use anyhow::Result; -use marzano_util::{analysis_logs::AnalysisLogs, tree_sitter_util::children_by_field_id_count}; +use marzano_util::analysis_logs::AnalysisLogs; use tree_sitter::Node; #[derive(Debug, Clone)] @@ -44,58 +43,8 @@ impl Matcher for BooleanConstant { _context: &'a impl Context, _logs: &mut AnalysisLogs, ) -> Result { - let binding_as_bool = match binding { - ResolvedPattern::Binding(bindings) => { - if let Some(b) = bindings.last() { - evaluate_binding_truthiness(b) - } else { - false - } - } - ResolvedPattern::List(elements) => !elements.is_empty(), - ResolvedPattern::Map(map) => !map.is_empty(), - ResolvedPattern::Constant(c) => match c { - Constant::Integer(i) => *i != 0, - Constant::Float(d) => *d != 0.0, - Constant::Boolean(b) => *b, - Constant::String(s) => !s.is_empty(), - Constant::Undefined => false, - }, - ResolvedPattern::Snippets(s) => { - if let Some(s) = s.last() { - match s { - ResolvedSnippet::Binding(b) => evaluate_binding_truthiness(b), - ResolvedSnippet::Text(t) => !t.is_empty(), - ResolvedSnippet::LazyFn(t) => !t.text(&state.files)?.is_empty(), - } - } else { - false - } - } - ResolvedPattern::File(..) => true, - ResolvedPattern::Files(..) => true, - }; - Ok(binding_as_bool == self.value) - } -} - -fn evaluate_binding_truthiness(b: &Binding) -> bool { - match b { - Binding::Empty(..) => false, - Binding::List(_, node, field_id) => { - let child_count = children_by_field_id_count(node, *field_id); - child_count > 0 - } - Binding::Node(..) => true, - // This refers to a slice of the source code, not a Grit string literal, so it is truthy - Binding::String(..) => true, - Binding::FileName(_) => true, - Binding::ConstantRef(c) => match c { - Constant::Integer(i) => *i != 0, - Constant::Float(d) => *d != 0.0, - Constant::Boolean(b) => *b, - Constant::String(s) => !s.is_empty(), - Constant::Undefined => false, - }, + binding + .is_truthy(state) + .map(|truthiness| truthiness == self.value) } } diff --git a/crates/core/src/pattern/resolved_pattern.rs b/crates/core/src/pattern/resolved_pattern.rs index d42c5ad1f..a34e34e04 100644 --- a/crates/core/src/pattern/resolved_pattern.rs +++ b/crates/core/src/pattern/resolved_pattern.rs @@ -358,6 +358,15 @@ impl<'a> ResolvedSnippet<'a> { }; res } + + pub(crate) fn is_truthy(&self, state: &mut State<'a>) -> Result { + let truthiness = match self { + Self::Binding(b) => b.is_truthy(), + Self::Text(t) => !t.is_empty(), + Self::LazyFn(t) => !t.text(&state.files)?.is_empty(), + }; + Ok(truthiness) + } } impl<'a> ResolvedPattern<'a> { @@ -996,6 +1005,25 @@ impl<'a> ResolvedPattern<'a> { } Ok(()) } + + pub(crate) fn is_truthy(&self, state: &mut State<'a>) -> Result { + let truthiness = match self { + Self::Binding(bindings) => bindings.last().map_or(false, Binding::is_truthy), + Self::List(elements) => !elements.is_empty(), + Self::Map(map) => !map.is_empty(), + Self::Constant(c) => c.is_truthy(), + Self::Snippets(s) => { + if let Some(s) = s.last() { + s.is_truthy(state)? + } else { + false + } + } + Self::File(..) => true, + Self::Files(..) => true, + }; + Ok(truthiness) + } } pub(crate) fn pattern_to_binding<'a>(