Compare plain text AST nodes.
This commit is contained in:
parent
037caf369c
commit
777c756a7f
@ -16,6 +16,7 @@ pub(crate) use compare_field::EmacsField;
|
|||||||
pub(crate) use elisp_fact::ElispFact;
|
pub(crate) use elisp_fact::ElispFact;
|
||||||
pub use sexp::sexp;
|
pub use sexp::sexp;
|
||||||
pub(crate) use sexp::unquote;
|
pub(crate) use sexp::unquote;
|
||||||
|
pub(crate) use sexp::TextWithProperties;
|
||||||
pub use sexp::Token;
|
pub use sexp::Token;
|
||||||
pub(crate) use util::get_emacs_standard_properties;
|
pub(crate) use util::get_emacs_standard_properties;
|
||||||
pub(crate) use util::get_property;
|
pub(crate) use util::get_property;
|
||||||
|
@ -21,7 +21,7 @@ to_wasm!(
|
|||||||
original,
|
original,
|
||||||
wasm_context,
|
wasm_context,
|
||||||
{ WasmAstNode::PlainText(original) },
|
{ WasmAstNode::PlainText(original) },
|
||||||
{ "TODO".into() },
|
{ "plain-text".into() },
|
||||||
{
|
{
|
||||||
Ok((
|
Ok((
|
||||||
Vec::new(),
|
Vec::new(),
|
||||||
|
@ -5,9 +5,11 @@ use super::diff::WasmDiffResult;
|
|||||||
use super::diff::WasmDiffStatus;
|
use super::diff::WasmDiffStatus;
|
||||||
use crate::compare::get_emacs_standard_properties;
|
use crate::compare::get_emacs_standard_properties;
|
||||||
use crate::compare::maybe_token_to_usize;
|
use crate::compare::maybe_token_to_usize;
|
||||||
|
use crate::compare::unquote;
|
||||||
use crate::compare::ElispFact;
|
use crate::compare::ElispFact;
|
||||||
use crate::compare::EmacsField;
|
use crate::compare::EmacsField;
|
||||||
use crate::compare::EmacsStandardProperties;
|
use crate::compare::EmacsStandardProperties;
|
||||||
|
use crate::compare::TextWithProperties;
|
||||||
use crate::compare::Token;
|
use crate::compare::Token;
|
||||||
use crate::wasm::WasmAngleLink;
|
use crate::wasm::WasmAngleLink;
|
||||||
use crate::wasm::WasmAstNode;
|
use crate::wasm::WasmAstNode;
|
||||||
@ -109,6 +111,9 @@ fn compare_json_value<'b, 's>(
|
|||||||
{
|
{
|
||||||
compare_optional_pair(source, e, wasm)
|
compare_optional_pair(source, e, wasm)
|
||||||
}
|
}
|
||||||
|
(serde_json::Value::Object(w), Token::TextWithProperties(e)) if is_plain_text(w) => {
|
||||||
|
compare_plain_text(source, e, w)
|
||||||
|
}
|
||||||
(serde_json::Value::Null, Token::Atom(_)) => todo!(),
|
(serde_json::Value::Null, Token::Atom(_)) => todo!(),
|
||||||
(serde_json::Value::Null, Token::List(_)) => todo!(),
|
(serde_json::Value::Null, Token::List(_)) => todo!(),
|
||||||
(serde_json::Value::Null, Token::TextWithProperties(_)) => todo!(),
|
(serde_json::Value::Null, Token::TextWithProperties(_)) => todo!(),
|
||||||
@ -478,6 +483,124 @@ fn compare_optional_pair<'e, 's, 'w>(
|
|||||||
Ok(result)
|
Ok(result)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn is_plain_text<'e, 's, 'w>(wasm: &'w serde_json::Map<String, serde_json::Value>) -> bool {
|
||||||
|
if let Some(serde_json::Value::String(node_type)) = wasm.get("ast-node") {
|
||||||
|
node_type == "plain-text"
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn compare_plain_text<'e, 's, 'w>(
|
||||||
|
source: &'s str,
|
||||||
|
emacs: &'e TextWithProperties<'s>,
|
||||||
|
wasm: &'w serde_json::Map<String, serde_json::Value>,
|
||||||
|
) -> Result<WasmDiffResult<'s>, Box<dyn std::error::Error>> {
|
||||||
|
let mut result = WasmDiffResult::default();
|
||||||
|
if !is_plain_text(wasm) {
|
||||||
|
result.status.push(WasmDiffStatus::Bad(
|
||||||
|
format!(
|
||||||
|
"AST node type mismatch. Emacs=({emacs:?}) Wasm=({wasm:?}).",
|
||||||
|
emacs = emacs,
|
||||||
|
wasm = wasm,
|
||||||
|
)
|
||||||
|
.into(),
|
||||||
|
));
|
||||||
|
return Ok(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
let emacs_text = unquote(emacs.text)?;
|
||||||
|
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."#)?;
|
||||||
|
let wasm_begin = {
|
||||||
|
if let Some(serde_json::Value::Number(begin)) = wasm_standard_properties.get("begin") {
|
||||||
|
begin
|
||||||
|
.as_u64()
|
||||||
|
.map(|w| w as usize)
|
||||||
|
.ok_or("Begin should be a number.")?
|
||||||
|
} else {
|
||||||
|
result.status.push(WasmDiffStatus::Bad(
|
||||||
|
format!(
|
||||||
|
"AST node type mismatch. Emacs=({emacs:?}) Wasm=({wasm:?}).",
|
||||||
|
emacs = emacs,
|
||||||
|
wasm = wasm,
|
||||||
|
)
|
||||||
|
.into(),
|
||||||
|
));
|
||||||
|
return Ok(result);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let wasm_end = {
|
||||||
|
if let Some(serde_json::Value::Number(end)) = wasm_standard_properties.get("end") {
|
||||||
|
end.as_u64()
|
||||||
|
.map(|w| w as usize)
|
||||||
|
.ok_or("End should be a number.")?
|
||||||
|
} else {
|
||||||
|
result.status.push(WasmDiffStatus::Bad(
|
||||||
|
format!(
|
||||||
|
"AST node type mismatch. Emacs=({emacs:?}) Wasm=({wasm:?}).",
|
||||||
|
emacs = emacs,
|
||||||
|
wasm = wasm,
|
||||||
|
)
|
||||||
|
.into(),
|
||||||
|
));
|
||||||
|
return Ok(result);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let wasm_text: String = source
|
||||||
|
.chars()
|
||||||
|
.skip(wasm_begin - 1)
|
||||||
|
.take(wasm_end - wasm_begin)
|
||||||
|
.collect();
|
||||||
|
if wasm_text != emacs_text {
|
||||||
|
result.status.push(WasmDiffStatus::Bad(
|
||||||
|
format!(
|
||||||
|
"Text mismatch. Emacs=({emacs:?}) Wasm=({wasm:?}).",
|
||||||
|
emacs = emacs_text,
|
||||||
|
wasm = wasm_text,
|
||||||
|
)
|
||||||
|
.into(),
|
||||||
|
));
|
||||||
|
return Ok(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
let emacs_start = emacs
|
||||||
|
.properties
|
||||||
|
.first()
|
||||||
|
.map(|t| t.as_atom())
|
||||||
|
.map_or(Ok(None), |r| r.map(Some))?;
|
||||||
|
if emacs_start != Some("0") {
|
||||||
|
result.status.push(WasmDiffStatus::Bad(
|
||||||
|
format!(
|
||||||
|
"Text should start at offset 0. Emacs=({emacs:?}) Wasm=({wasm:?}).",
|
||||||
|
emacs = emacs,
|
||||||
|
wasm = wasm,
|
||||||
|
)
|
||||||
|
.into(),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
let emacs_end = emacs
|
||||||
|
.properties
|
||||||
|
.get(1)
|
||||||
|
.map(|t| t.as_atom())
|
||||||
|
.map_or(Ok(None), |r| r.map(Some))?;
|
||||||
|
if emacs_end != Some((wasm_end - wasm_begin).to_string().as_str()) {
|
||||||
|
result.status.push(WasmDiffStatus::Bad(
|
||||||
|
format!(
|
||||||
|
"Text end mismatch. Emacs=({emacs:?}) Wasm=({wasm:?}).",
|
||||||
|
emacs = emacs_end,
|
||||||
|
wasm = wasm_end - wasm_begin,
|
||||||
|
)
|
||||||
|
.into(),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(result)
|
||||||
|
}
|
||||||
|
|
||||||
// pub fn old_wasm_compare_document<'b, 's, 'p>(
|
// pub fn old_wasm_compare_document<'b, 's, 'p>(
|
||||||
// source: &'s str,
|
// source: &'s str,
|
||||||
// emacs: &'b Token<'s>,
|
// emacs: &'b Token<'s>,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user