From adcd0de7e422f65d30180f069404932c5aa269ce Mon Sep 17 00:00:00 2001 From: Tom Alexander Date: Fri, 29 Dec 2023 15:38:18 -0500 Subject: [PATCH] Compare standard properties. --- src/compare/mod.rs | 1 + src/compare/util.rs | 2 +- src/wasm_test/compare.rs | 101 ++++++++++++++++++++++++++++++++++++++- 3 files changed, 102 insertions(+), 2 deletions(-) diff --git a/src/compare/mod.rs b/src/compare/mod.rs index 5b1ab67..76ee7a0 100644 --- a/src/compare/mod.rs +++ b/src/compare/mod.rs @@ -20,4 +20,5 @@ pub use sexp::Token; pub(crate) use util::get_emacs_standard_properties; pub(crate) use util::get_property; pub(crate) use util::get_property_quoted_string; +pub(crate) use util::maybe_token_to_usize; pub(crate) use util::EmacsStandardProperties; diff --git a/src/compare/util.rs b/src/compare/util.rs index b22fe84..f0a0b03 100644 --- a/src/compare/util.rs +++ b/src/compare/util.rs @@ -203,7 +203,7 @@ pub(crate) fn get_emacs_standard_properties( }) } -fn maybe_token_to_usize( +pub(crate) fn maybe_token_to_usize( token: Option<&Token<'_>>, ) -> Result, Box> { Ok(token diff --git a/src/wasm_test/compare.rs b/src/wasm_test/compare.rs index cfa65e7..59bd911 100644 --- a/src/wasm_test/compare.rs +++ b/src/wasm_test/compare.rs @@ -1,9 +1,13 @@ use std::borrow::Cow; +use std::collections::HashMap; use super::diff::WasmDiffResult; use super::diff::WasmDiffStatus; +use crate::compare::get_emacs_standard_properties; +use crate::compare::maybe_token_to_usize; use crate::compare::ElispFact; use crate::compare::EmacsField; +use crate::compare::EmacsStandardProperties; use crate::compare::Token; use crate::wasm::WasmAngleLink; use crate::wasm::WasmAstNode; @@ -231,7 +235,60 @@ fn compare_ast_node<'b, 's, 'p>( } } - // TODO: compare standard-properties. + { + // Compare standard-properties. + let mut layer = WasmDiffResult::default(); + layer.name = "standard-properties".into(); + let emacs_standard_properties = wasm_get_emacs_standard_properties(&emacs_attributes_map)?; + let wasm_standard_properties = wasm + .get("standard-properties") + .ok_or(r#"Wasm AST nodes should have a "standard-properties" attribute."#)? + .as_object() + .ok_or(r#"Wasm ast node "standard-properties" attribute should be an object."#)?; + for (emacs_value, wasm_name) in [ + (emacs_standard_properties.begin, "begin"), + (emacs_standard_properties.end, "end"), + (emacs_standard_properties.contents_begin, "contents_begin"), + (emacs_standard_properties.contents_end, "contents_end"), + (emacs_standard_properties.post_blank, "post_blank"), + ] { + match (emacs_value, wasm_standard_properties.get(wasm_name)) { + (None, None) => {} + (None, Some(_)) => { + layer.status.push(WasmDiffStatus::Bad( + format!( + "Elisp node lacked field present in wasm node. Name=({name}).", + name = wasm_name, + ) + .into(), + )); + } + (Some(_), None) => { + layer.status.push(WasmDiffStatus::Bad( + format!( + "Wasm node lacked field present in elisp node. Name=({name}).", + name = wasm_name, + ) + .into(), + )); + } + (Some(e), Some(serde_json::Value::Number(w))) + if w.as_u64().map(|w| w as usize) == Some(e) => {} + (Some(e), Some(w)) => { + layer.status.push(WasmDiffStatus::Bad( + format!( + "Property value mismatch. Emacs=({emacs:?}) Wasm=({wasm:?}).", + emacs = e, + wasm = w, + ) + .into(), + )); + } + } + } + result.children.push(layer); + } + // TODO: compare children Ok(result) @@ -251,6 +308,48 @@ fn compare_quoted_string<'e, 's, 'w>( Ok(result) } +pub(crate) fn wasm_get_emacs_standard_properties( + attributes_map: &HashMap<&str, &Token<'_>>, +) -> Result> { + let standard_properties = attributes_map.get(":standard-properties"); + Ok(if standard_properties.is_some() { + let mut std_props = standard_properties + .expect("if statement proves its Some") + .as_vector()? + .iter(); + let begin = maybe_token_to_usize(std_props.next())?; + let post_affiliated = maybe_token_to_usize(std_props.next())?; + let contents_begin = maybe_token_to_usize(std_props.next())?; + let contents_end = maybe_token_to_usize(std_props.next())?; + let end = maybe_token_to_usize(std_props.next())?; + let post_blank = maybe_token_to_usize(std_props.next())?; + EmacsStandardProperties { + begin, + post_affiliated, + contents_begin, + contents_end, + end, + post_blank, + } + } else { + let begin = maybe_token_to_usize(attributes_map.get(":begin").copied())?; + let end = maybe_token_to_usize(attributes_map.get(":end").copied())?; + let contents_begin = maybe_token_to_usize(attributes_map.get(":contents-begin").copied())?; + let contents_end = maybe_token_to_usize(attributes_map.get(":contents-end").copied())?; + let post_blank = maybe_token_to_usize(attributes_map.get(":post-blank").copied())?; + let post_affiliated = + maybe_token_to_usize(attributes_map.get(":post-affiliated").copied())?; + EmacsStandardProperties { + begin, + post_affiliated, + contents_begin, + contents_end, + end, + post_blank, + } + }) +} + // pub fn old_wasm_compare_document<'b, 's, 'p>( // source: &'s str, // emacs: &'b Token<'s>,