tamer: Introduce context into XirReader
tamec and tameld will now both introduce a `Context` to XIR, which will use it to create spans. Here's an example of an error, now that it's all working well together: $ target/release/tameld --emit xmle -o /dev/null path/to/package.xmlo error: invalid preproc:sym/@dim `9` at [/../path/to/package.xmlo offset 1175451-1175452] A future task will make this human-readable by producing line and column numbers, and perhaps even a snippet (if not now, then eventually). It's exciting to see this coming together finally. DEV-10934main
parent
68223cb7d3
commit
a1a4ad3e8e
|
@ -23,15 +23,11 @@
|
|||
extern crate tamer;
|
||||
|
||||
use getopts::{Fail, Options};
|
||||
use std::env;
|
||||
use std::error::Error;
|
||||
use std::ffi::OsStr;
|
||||
use std::fs;
|
||||
use std::path::Path;
|
||||
use std::{env, io::BufWriter};
|
||||
use tamer::{
|
||||
iter::into_iter_while_ok,
|
||||
xir::{reader::XmlXirReader, DefaultEscaper},
|
||||
};
|
||||
|
||||
#[cfg(feature = "wip-frontends")]
|
||||
use {std::io::BufReader, tamer::fs::File};
|
||||
|
@ -63,17 +59,26 @@ pub fn main() -> Result<(), Box<dyn Error>> {
|
|||
|
||||
#[cfg(feature = "wip-frontends")]
|
||||
{
|
||||
use tamer::xir::writer::XmlWriter;
|
||||
use std::io::BufWriter;
|
||||
use tamer::{
|
||||
fs::PathFile,
|
||||
iter::into_iter_while_ok,
|
||||
xir::{
|
||||
reader::XmlXirReader, writer::XmlWriter, DefaultEscaper,
|
||||
},
|
||||
};
|
||||
|
||||
let escaper = DefaultEscaper::default();
|
||||
let file: BufReader<fs::File> = File::open(source)?;
|
||||
let mut fout = BufWriter::new(fs::File::create(dest)?);
|
||||
|
||||
let PathFile(_, file, ctx): PathFile<BufReader<fs::File>> =
|
||||
PathFile::open(source)?;
|
||||
|
||||
// Parse into XIR and re-lower into XML,
|
||||
// which is similar to a copy but proves that we're able
|
||||
// to parse source files.
|
||||
into_iter_while_ok(
|
||||
XmlXirReader::new(file, &escaper),
|
||||
XmlXirReader::new(file, &escaper, ctx),
|
||||
|toks| toks.write(&mut fout, Default::default(), &escaper),
|
||||
)??;
|
||||
}
|
||||
|
|
|
@ -45,6 +45,9 @@ use std::io::{BufReader, Read, Result};
|
|||
use std::marker::PhantomData;
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
use crate::span::{Context, UNKNOWN_CONTEXT};
|
||||
use crate::sym::GlobalSymbolIntern;
|
||||
|
||||
/// A file.
|
||||
pub trait File
|
||||
where
|
||||
|
@ -67,20 +70,19 @@ impl<F: File + Read> File for BufReader<F> {
|
|||
}
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
pub struct PathFile<F: File>(PathBuf, F);
|
||||
|
||||
impl<F: File> Into<(PathBuf, F)> for PathFile<F> {
|
||||
fn into(self) -> (PathBuf, F) {
|
||||
(self.0, self.1)
|
||||
}
|
||||
}
|
||||
pub struct PathFile<F: File>(pub PathBuf, pub F, pub Context);
|
||||
|
||||
impl<F: File> File for PathFile<F> {
|
||||
fn open<P: AsRef<Path>>(path: P) -> Result<Self> {
|
||||
let buf = path.as_ref().to_path_buf();
|
||||
let file = F::open(&buf)?;
|
||||
|
||||
Ok(Self(buf, file))
|
||||
let ctx = buf
|
||||
.to_str()
|
||||
.map(|s| s.intern().into())
|
||||
.unwrap_or(UNKNOWN_CONTEXT);
|
||||
|
||||
Ok(Self(buf, file, ctx))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -224,10 +226,14 @@ mod test {
|
|||
let path: PathBuf = "buf/path".into();
|
||||
let result: PathFile<DummyFile> = File::open(path.clone()).unwrap();
|
||||
|
||||
assert_eq!(PathFile(path.clone(), DummyFile(path.clone())), result);
|
||||
|
||||
// Tuple conversion.
|
||||
assert_eq!((path.clone(), DummyFile(path.clone())), result.into());
|
||||
assert_eq!(
|
||||
PathFile(
|
||||
path.clone(),
|
||||
DummyFile(path.clone()),
|
||||
"buf/path".intern().into()
|
||||
),
|
||||
result
|
||||
);
|
||||
}
|
||||
|
||||
mod canonicalizer {
|
||||
|
|
|
@ -176,17 +176,18 @@ fn load_xmlo<'a, P: AsRef<Path>, S: Escaper>(
|
|||
escaper: &S,
|
||||
state: LinkerAsgBuilderState,
|
||||
) -> Result<LinkerAsgBuilderState, Box<dyn Error>> {
|
||||
let cfile: PathFile<BufReader<fs::File>> = match fs.open(path_str)? {
|
||||
VisitOnceFile::FirstVisit(file) => file,
|
||||
VisitOnceFile::Visited => return Ok(state),
|
||||
};
|
||||
|
||||
let (path, file) = cfile.into();
|
||||
let PathFile(path, file, ctx): PathFile<BufReader<fs::File>> =
|
||||
match fs.open(path_str)? {
|
||||
VisitOnceFile::FirstVisit(file) => file,
|
||||
VisitOnceFile::Visited => return Ok(state),
|
||||
};
|
||||
|
||||
let mut state = {
|
||||
#[cfg(not(feature = "wip-xmlo-xir-reader"))]
|
||||
{
|
||||
let xmlo: XmloReader<_> = file.into();
|
||||
let _ctx = ctx; // suppress warning
|
||||
|
||||
depgraph.import_xmlo(xmlo, state)?
|
||||
}
|
||||
|
||||
|
@ -198,22 +199,28 @@ fn load_xmlo<'a, P: AsRef<Path>, S: Escaper>(
|
|||
|
||||
// TODO: This entire block is a WIP and will be incrementally
|
||||
// abstracted away.
|
||||
into_iter_while_ok(XmlXirReader::new(file, escaper), |toks| {
|
||||
flat::State::<64>::parse(toks).lower_while_ok::<XmloReader, _>(
|
||||
|xirf| {
|
||||
into_iter_while_ok(xirf, |xmlo_out| {
|
||||
// TODO: Transitionary---we do not want to filter.
|
||||
depgraph.import_xmlo(
|
||||
xmlo_out.filter_map(|parsed| match parsed {
|
||||
Parsed::Incomplete => None,
|
||||
Parsed::Object(obj) => Some(Ok(obj)),
|
||||
}),
|
||||
state,
|
||||
)
|
||||
into_iter_while_ok(
|
||||
XmlXirReader::new(file, escaper, ctx),
|
||||
|toks| {
|
||||
flat::State::<64>::parse(toks)
|
||||
.lower_while_ok::<XmloReader, _>(|xirf| {
|
||||
into_iter_while_ok(xirf, |xmlo_out| {
|
||||
// TODO: Transitionary---we do not want to filter.
|
||||
depgraph.import_xmlo(
|
||||
xmlo_out.filter_map(
|
||||
|parsed| match parsed {
|
||||
Parsed::Incomplete => None,
|
||||
Parsed::Object(obj) => {
|
||||
Some(Ok(obj))
|
||||
}
|
||||
},
|
||||
),
|
||||
state,
|
||||
)
|
||||
})
|
||||
})
|
||||
},
|
||||
)
|
||||
})????
|
||||
},
|
||||
)????
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
|
||||
use super::{error::SpanlessError, DefaultEscaper, Error, Escaper, Token};
|
||||
use crate::{
|
||||
span::UNKNOWN_CONTEXT as UC,
|
||||
span::Context,
|
||||
sym::{st::raw::WS_EMPTY, GlobalSymbolInternBytes},
|
||||
};
|
||||
use quick_xml::{
|
||||
|
@ -60,6 +60,9 @@ where
|
|||
/// Inner parser.
|
||||
reader: quick_xml::Reader<B>,
|
||||
|
||||
/// Parsing context for reader.
|
||||
ctx: Context,
|
||||
|
||||
/// Buffer for [`quick_xml::Reader`].
|
||||
readbuf: Vec<u8>,
|
||||
|
||||
|
@ -77,7 +80,7 @@ where
|
|||
}
|
||||
|
||||
impl<'s, B: BufRead, S: Escaper> XmlXirReader<'s, B, S> {
|
||||
pub fn new(reader: B, escaper: &'s S) -> Self {
|
||||
pub fn new(reader: B, escaper: &'s S, ctx: Context) -> Self {
|
||||
let mut reader = quick_xml::Reader::from_reader(reader);
|
||||
|
||||
// XIR must support mismatched tags so that we are able to represent
|
||||
|
@ -87,6 +90,7 @@ impl<'s, B: BufRead, S: Escaper> XmlXirReader<'s, B, S> {
|
|||
|
||||
Self {
|
||||
reader,
|
||||
ctx,
|
||||
readbuf: Vec::new(),
|
||||
// This capacity is largely arbitrary,
|
||||
// but [`Token`]s are small enough that it likely does not
|
||||
|
@ -107,6 +111,7 @@ impl<'s, B: BufRead, S: Escaper> XmlXirReader<'s, B, S> {
|
|||
self.tokbuf.clear();
|
||||
self.readbuf.clear();
|
||||
|
||||
let ctx = self.ctx;
|
||||
let prev_pos = self.reader.buffer_position();
|
||||
|
||||
match self.reader.read_event(&mut self.readbuf) {
|
||||
|
@ -115,7 +120,7 @@ impl<'s, B: BufRead, S: Escaper> XmlXirReader<'s, B, S> {
|
|||
// But we don't encounter much of anything here with how we make
|
||||
// use of quick-xml.
|
||||
Err(inner) => Some(Err({
|
||||
let span = UC.span_or_zz(prev_pos, 0);
|
||||
let span = ctx.span_or_zz(prev_pos, 0);
|
||||
SpanlessError::from(inner).with_span(span)
|
||||
})),
|
||||
|
||||
|
@ -130,13 +135,14 @@ impl<'s, B: BufRead, S: Escaper> XmlXirReader<'s, B, S> {
|
|||
&mut self.tokbuf,
|
||||
ele,
|
||||
prev_pos,
|
||||
ctx,
|
||||
)
|
||||
.and_then(|open| {
|
||||
let new_pos = self.reader.buffer_position();
|
||||
|
||||
// `<tag ... />`
|
||||
// ||
|
||||
let span = UC.span_or_zz(new_pos - 2, 2);
|
||||
let span = ctx.span_or_zz(new_pos - 2, 2);
|
||||
|
||||
// Tag is self-closing, but this does not yet
|
||||
// handle whitespace before the `/`
|
||||
|
@ -152,12 +158,13 @@ impl<'s, B: BufRead, S: Escaper> XmlXirReader<'s, B, S> {
|
|||
&mut self.tokbuf,
|
||||
ele,
|
||||
prev_pos,
|
||||
ctx,
|
||||
)),
|
||||
|
||||
QuickXmlEvent::End(ele) => Some({
|
||||
// </foo>
|
||||
// |----| name + '<' + '/' + '>'
|
||||
let span = UC.span_or_zz(prev_pos, ele.name().len() + 3);
|
||||
let span = ctx.span_or_zz(prev_pos, ele.name().len() + 3);
|
||||
|
||||
ele.name()
|
||||
.try_into()
|
||||
|
@ -180,7 +187,7 @@ impl<'s, B: BufRead, S: Escaper> XmlXirReader<'s, B, S> {
|
|||
QuickXmlEvent::Text(bytes) => Some({
|
||||
// <text>foo bar</text>
|
||||
// |-----|
|
||||
let span = UC.span_or_zz(prev_pos, bytes.len());
|
||||
let span = ctx.span_or_zz(prev_pos, bytes.len());
|
||||
|
||||
bytes
|
||||
.intern_utf8()
|
||||
|
@ -194,7 +201,7 @@ impl<'s, B: BufRead, S: Escaper> XmlXirReader<'s, B, S> {
|
|||
QuickXmlEvent::Comment(bytes) => Some({
|
||||
// <!-- foo -->
|
||||
// |----------| " foo " + "<!--" + "-->"
|
||||
let span = UC.span_or_zz(prev_pos, bytes.len() + 7);
|
||||
let span = ctx.span_or_zz(prev_pos, bytes.len() + 7);
|
||||
|
||||
bytes
|
||||
.intern_utf8()
|
||||
|
@ -204,7 +211,7 @@ impl<'s, B: BufRead, S: Escaper> XmlXirReader<'s, B, S> {
|
|||
|
||||
// TODO: This must appear in the Prolog.
|
||||
QuickXmlEvent::Decl(decl) => {
|
||||
match Self::validate_decl(&decl, prev_pos) {
|
||||
match Self::validate_decl(&decl, prev_pos, ctx) {
|
||||
Err(x) => Some(Err(x)),
|
||||
Ok(()) => self.refill_buf(),
|
||||
}
|
||||
|
@ -233,12 +240,12 @@ impl<'s, B: BufRead, S: Escaper> XmlXirReader<'s, B, S> {
|
|||
/// people unfamiliar with the system do not have expectations that
|
||||
/// are going to be unmet,
|
||||
/// which may result in subtle (or even serious) problems.
|
||||
fn validate_decl(decl: &BytesDecl, pos: usize) -> Result<()> {
|
||||
fn validate_decl(decl: &BytesDecl, pos: usize, ctx: Context) -> Result<()> {
|
||||
// Starts after `<?`, which we want to include.
|
||||
let decl_ptr = decl.as_ptr() as usize - 2 + pos;
|
||||
|
||||
// Fallback span that covers the entire declaration.
|
||||
let decl_span = UC.span_or_zz(pos, decl.len() + 4);
|
||||
let decl_span = ctx.span_or_zz(pos, decl.len() + 4);
|
||||
|
||||
let ver =
|
||||
&decl.version().map_err(Error::from_with_span(decl_span))?[..];
|
||||
|
@ -249,7 +256,7 @@ impl<'s, B: BufRead, S: Escaper> XmlXirReader<'s, B, S> {
|
|||
// <?xml version="X.Y"?>
|
||||
// |-|
|
||||
let ver_pos = (ver.as_ptr() as usize) - decl_ptr;
|
||||
let span = UC.span_or_zz(ver_pos, ver.len());
|
||||
let span = ctx.span_or_zz(ver_pos, ver.len());
|
||||
|
||||
Err(Error::UnsupportedXmlVersion(
|
||||
ver.intern_utf8().map_err(Error::from_with_span(span))?,
|
||||
|
@ -262,7 +269,7 @@ impl<'s, B: BufRead, S: Escaper> XmlXirReader<'s, B, S> {
|
|||
b"utf-8" | b"UTF-8" => (),
|
||||
invalid => {
|
||||
let enc_pos = (invalid.as_ptr() as usize) - decl_ptr;
|
||||
let span = UC.span_or_zz(enc_pos, invalid.len());
|
||||
let span = ctx.span_or_zz(enc_pos, invalid.len());
|
||||
|
||||
Err(Error::UnsupportedEncoding(
|
||||
invalid
|
||||
|
@ -288,6 +295,7 @@ impl<'s, B: BufRead, S: Escaper> XmlXirReader<'s, B, S> {
|
|||
tokbuf: &mut VecDeque<Token>,
|
||||
ele: BytesStart,
|
||||
pos: usize,
|
||||
ctx: Context,
|
||||
) -> Result<Token> {
|
||||
// Starts after the opening tag `<`, so adjust.
|
||||
let addr = ele.as_ptr() as usize - 1;
|
||||
|
@ -300,7 +308,7 @@ impl<'s, B: BufRead, S: Escaper> XmlXirReader<'s, B, S> {
|
|||
WS_EMPTY,
|
||||
// <>
|
||||
// | where QName should be
|
||||
UC.span_or_zz(pos + 1, 0),
|
||||
ctx.span_or_zz(pos + 1, 0),
|
||||
));
|
||||
}
|
||||
|
||||
|
@ -311,7 +319,7 @@ impl<'s, B: BufRead, S: Escaper> XmlXirReader<'s, B, S> {
|
|||
return Err({
|
||||
// <foo="bar" ...>
|
||||
// |-------|
|
||||
let span = UC.span_or_zz(pos + 1, len);
|
||||
let span = ctx.span_or_zz(pos + 1, len);
|
||||
|
||||
Error::InvalidQName(
|
||||
ele.name()
|
||||
|
@ -328,7 +336,7 @@ impl<'s, B: BufRead, S: Escaper> XmlXirReader<'s, B, S> {
|
|||
// `ele` contains every byte up to the [self-]closing tag.
|
||||
ele.name()
|
||||
.try_into()
|
||||
.map_err(Error::from_with_span(UC.span_or_zz(pos + 1, len)))
|
||||
.map_err(Error::from_with_span(ctx.span_or_zz(pos + 1, len)))
|
||||
.and_then(|qname| {
|
||||
let has_attrs = ele.attributes_raw().len() > 0;
|
||||
let noattr_add: usize = (!has_attrs).into();
|
||||
|
@ -338,7 +346,7 @@ impl<'s, B: BufRead, S: Escaper> XmlXirReader<'s, B, S> {
|
|||
//
|
||||
// <tag>..</tag>
|
||||
// |---| name + '<' + '>'
|
||||
let span = UC.span_or_zz(pos, len + 1 + noattr_add);
|
||||
let span = ctx.span_or_zz(pos, len + 1 + noattr_add);
|
||||
|
||||
if has_attrs {
|
||||
let found = Self::parse_attrs(
|
||||
|
@ -347,6 +355,7 @@ impl<'s, B: BufRead, S: Escaper> XmlXirReader<'s, B, S> {
|
|||
ele.attributes(),
|
||||
addr - pos, // offset relative to _beginning_ of buf
|
||||
pos,
|
||||
ctx,
|
||||
)?;
|
||||
|
||||
// Given this input, quick-xml ignores the bytes entirely:
|
||||
|
@ -365,7 +374,7 @@ impl<'s, B: BufRead, S: Escaper> XmlXirReader<'s, B, S> {
|
|||
{
|
||||
return Err(Error::AttrValueExpected(
|
||||
None,
|
||||
UC.span_or_zz(pos + ele.len() + 1, 0),
|
||||
ctx.span_or_zz(pos + ele.len() + 1, 0),
|
||||
));
|
||||
}
|
||||
}
|
||||
|
@ -411,6 +420,7 @@ impl<'s, B: BufRead, S: Escaper> XmlXirReader<'s, B, S> {
|
|||
mut attrs: Attributes<'a>,
|
||||
ele_ptr: usize,
|
||||
ele_pos: usize,
|
||||
ctx: Context,
|
||||
) -> Result<bool> {
|
||||
let mut found = false;
|
||||
|
||||
|
@ -427,7 +437,7 @@ impl<'s, B: BufRead, S: Escaper> XmlXirReader<'s, B, S> {
|
|||
// but we should discover it.
|
||||
Error::AttrValueExpected(
|
||||
None,
|
||||
UC.span_or_zz(ele_pos + pos, 0),
|
||||
ctx.span_or_zz(ele_pos + pos, 0),
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -435,12 +445,12 @@ impl<'s, B: BufRead, S: Escaper> XmlXirReader<'s, B, S> {
|
|||
// TODO: name and span length
|
||||
Error::AttrValueUnquoted(
|
||||
None,
|
||||
UC.span_or_zz(ele_pos + pos, 0),
|
||||
ctx.span_or_zz(ele_pos + pos, 0),
|
||||
)
|
||||
}
|
||||
|
||||
// fallback
|
||||
e => Error::from_with_span(UC.span_or_zz(ele_pos, 0))(e),
|
||||
e => Error::from_with_span(ctx.span_or_zz(ele_pos, 0))(e),
|
||||
})?;
|
||||
|
||||
let keyoffset = attr.key.as_ptr() as usize;
|
||||
|
@ -460,8 +470,8 @@ impl<'s, B: BufRead, S: Escaper> XmlXirReader<'s, B, S> {
|
|||
|
||||
let value_offset = valoffset - ele_ptr;
|
||||
|
||||
let span_name = UC.span_or_zz(name_offset, attr.key.len());
|
||||
let span_value = UC.span_or_zz(value_offset, attr.value.len());
|
||||
let span_name = ctx.span_or_zz(name_offset, attr.key.len());
|
||||
let span_value = ctx.span_or_zz(value_offset, attr.value.len());
|
||||
|
||||
// The name must be parsed as a QName.
|
||||
let name = attr
|
||||
|
|
|
@ -23,7 +23,7 @@ use super::*;
|
|||
use crate::sym::GlobalSymbolIntern;
|
||||
use crate::{
|
||||
convert::ExpectInto,
|
||||
span::UNKNOWN_CONTEXT as UC,
|
||||
span::DUMMY_CONTEXT as DC,
|
||||
xir::{Error, Token},
|
||||
};
|
||||
|
||||
|
@ -83,7 +83,7 @@ macro_rules! new_sut {
|
|||
|
||||
(b $sut:ident = $data:expr) => {
|
||||
let escaper = MockEscaper::default();
|
||||
let $sut = Sut::new($data, &escaper);
|
||||
let $sut = Sut::new($data, &escaper, DC);
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -94,8 +94,8 @@ fn empty_node_without_prefix_or_attributes() {
|
|||
// 0 10
|
||||
// A B
|
||||
|
||||
let a = UC.span(0, 11);
|
||||
let b = UC.span(12, 2);
|
||||
let a = DC.span(0, 11);
|
||||
let b = DC.span(12, 2);
|
||||
|
||||
assert_eq!(
|
||||
Ok(vec![
|
||||
|
@ -114,10 +114,10 @@ fn does_not_resolve_xmlns() {
|
|||
// 0 5 7 11 14 22 25
|
||||
// A B C D
|
||||
|
||||
let a = UC.span(0, 6);
|
||||
let b = UC.span(7, 5);
|
||||
let c = UC.span(14, 9);
|
||||
let d = UC.span(25, 2);
|
||||
let a = DC.span(0, 6);
|
||||
let b = DC.span(7, 5);
|
||||
let c = DC.span(14, 9);
|
||||
let d = DC.span(25, 2);
|
||||
|
||||
assert_eq!(
|
||||
Ok(vec![
|
||||
|
@ -139,10 +139,10 @@ fn empty_node_with_prefix_without_attributes_unresolved() {
|
|||
// 0 12 14 20 23 31 34
|
||||
// A B C D
|
||||
|
||||
let a = UC.span(0, 13);
|
||||
let b = UC.span(14, 7);
|
||||
let c = UC.span(23, 9);
|
||||
let d = UC.span(34, 2);
|
||||
let a = DC.span(0, 13);
|
||||
let b = DC.span(14, 7);
|
||||
let c = DC.span(23, 9);
|
||||
let d = DC.span(34, 2);
|
||||
|
||||
// Should be the QName, _unresolved_.
|
||||
assert_eq!(
|
||||
|
@ -165,7 +165,7 @@ fn prefix_with_empty_local_name_invalid_qname() {
|
|||
// 1
|
||||
// A
|
||||
|
||||
let a = UC.span(1, 2);
|
||||
let a = DC.span(1, 2);
|
||||
|
||||
let result = sut.collect::<Result<Vec<_>>>();
|
||||
|
||||
|
@ -185,14 +185,14 @@ fn multiple_attrs_ordered() {
|
|||
// 0 3 5 7 10 13 18 21 25 28 31
|
||||
// A B C D E F G H
|
||||
|
||||
let a = UC.span(0, 4);
|
||||
let b = UC.span(5, 3);
|
||||
let c = UC.span(10, 1);
|
||||
let d = UC.span(13, 3);
|
||||
let e = UC.span(18, 1);
|
||||
let f = UC.span(21, 5);
|
||||
let g = UC.span(28, 1);
|
||||
let h = UC.span(31, 2);
|
||||
let a = DC.span(0, 4);
|
||||
let b = DC.span(5, 3);
|
||||
let c = DC.span(10, 1);
|
||||
let d = DC.span(13, 3);
|
||||
let e = DC.span(18, 1);
|
||||
let f = DC.span(21, 5);
|
||||
let g = DC.span(28, 1);
|
||||
let h = DC.span(31, 2);
|
||||
|
||||
assert_eq!(
|
||||
Ok(vec![
|
||||
|
@ -219,10 +219,10 @@ fn empty_attr_value() {
|
|||
// zero-length span, where
|
||||
// the value _would_ be
|
||||
|
||||
let a = UC.span(0, 4);
|
||||
let b = UC.span(5, 5);
|
||||
let c = UC.span(12, 0);
|
||||
let d = UC.span(14, 2);
|
||||
let a = DC.span(0, 4);
|
||||
let b = DC.span(5, 5);
|
||||
let c = DC.span(12, 0);
|
||||
let d = DC.span(14, 2);
|
||||
|
||||
assert_eq!(
|
||||
Ok(vec![
|
||||
|
@ -245,12 +245,12 @@ fn permits_duplicate_attrs() {
|
|||
// 0 3 5 8 11 14 17 20 23
|
||||
// A B C D E F
|
||||
|
||||
let a = UC.span(0, 4);
|
||||
let b = UC.span(5, 4);
|
||||
let c = UC.span(11, 1);
|
||||
let d = UC.span(14, 4);
|
||||
let e = UC.span(20, 1);
|
||||
let f = UC.span(23, 2);
|
||||
let a = DC.span(0, 4);
|
||||
let b = DC.span(5, 4);
|
||||
let c = DC.span(11, 1);
|
||||
let d = DC.span(14, 4);
|
||||
let e = DC.span(20, 1);
|
||||
let f = DC.span(23, 2);
|
||||
|
||||
assert_eq!(
|
||||
Ok(vec![
|
||||
|
@ -275,10 +275,10 @@ fn child_node_self_closing() {
|
|||
// note that this includes '>' when there are no attrs,
|
||||
// since that results in a more intuitive span (subject to change)
|
||||
|
||||
let a = UC.span(0, 6);
|
||||
let b = UC.span(6, 6);
|
||||
let c = UC.span(13, 2);
|
||||
let d = UC.span(15, 7);
|
||||
let a = DC.span(0, 6);
|
||||
let b = DC.span(6, 6);
|
||||
let c = DC.span(13, 2);
|
||||
let d = DC.span(15, 7);
|
||||
|
||||
assert_eq!(
|
||||
Ok(vec![
|
||||
|
@ -298,12 +298,12 @@ fn sibling_nodes() {
|
|||
// 0 5`6 11 13`15 20 22`24 30
|
||||
// A B C D E F
|
||||
|
||||
let a = UC.span(0, 6);
|
||||
let b = UC.span(6, 6);
|
||||
let c = UC.span(13, 2);
|
||||
let d = UC.span(15, 6);
|
||||
let e = UC.span(22, 2);
|
||||
let f = UC.span(24, 7);
|
||||
let a = DC.span(0, 6);
|
||||
let b = DC.span(6, 6);
|
||||
let c = DC.span(13, 2);
|
||||
let d = DC.span(15, 6);
|
||||
let e = DC.span(22, 2);
|
||||
let f = DC.span(24, 7);
|
||||
|
||||
assert_eq!(
|
||||
Ok(vec![
|
||||
|
@ -325,12 +325,12 @@ fn child_node_with_attrs() {
|
|||
// 0 5`6 11 13 18 20 23`25 31
|
||||
// A B C D E F
|
||||
|
||||
let a = UC.span(0, 6);
|
||||
let b = UC.span(6, 6);
|
||||
let c = UC.span(13, 3);
|
||||
let d = UC.span(18, 3);
|
||||
let e = UC.span(23, 2);
|
||||
let f = UC.span(25, 7);
|
||||
let a = DC.span(0, 6);
|
||||
let b = DC.span(6, 6);
|
||||
let c = DC.span(13, 3);
|
||||
let d = DC.span(18, 3);
|
||||
let e = DC.span(23, 2);
|
||||
let f = DC.span(25, 7);
|
||||
|
||||
assert_eq!(
|
||||
Ok(vec![
|
||||
|
@ -352,9 +352,9 @@ fn child_text() {
|
|||
// 0 5`6 12`13 19
|
||||
// A B C
|
||||
|
||||
let a = UC.span(0, 6);
|
||||
let b = UC.span(6, 7);
|
||||
let c = UC.span(13, 7);
|
||||
let a = DC.span(0, 6);
|
||||
let b = DC.span(6, 7);
|
||||
let c = DC.span(13, 7);
|
||||
|
||||
assert_eq!(
|
||||
Ok(vec![
|
||||
|
@ -373,12 +373,12 @@ fn mixed_child_content() {
|
|||
// 0 5`6 9 12`13`16 21 27
|
||||
// A B C D E F
|
||||
|
||||
let a = UC.span(0, 6);
|
||||
let b = UC.span(6, 3);
|
||||
let c = UC.span(9, 4);
|
||||
let d = UC.span(13, 3);
|
||||
let e = UC.span(16, 5);
|
||||
let f = UC.span(21, 7);
|
||||
let a = DC.span(0, 6);
|
||||
let b = DC.span(6, 3);
|
||||
let c = DC.span(9, 4);
|
||||
let d = DC.span(13, 3);
|
||||
let e = DC.span(16, 5);
|
||||
let f = DC.span(21, 7);
|
||||
|
||||
assert_eq!(
|
||||
Ok(vec![
|
||||
|
@ -411,14 +411,14 @@ fn mixed_child_content_with_newlines() {
|
|||
// 19
|
||||
// A B C D E F G H
|
||||
|
||||
let a = UC.span(0, 1);
|
||||
let b = UC.span(1, 6);
|
||||
let c = UC.span(7, 3);
|
||||
let d = UC.span(10, 6);
|
||||
let e = UC.span(17, 2);
|
||||
let f = UC.span(19, 1);
|
||||
let g = UC.span(20, 7);
|
||||
let h = UC.span(27, 1);
|
||||
let a = DC.span(0, 1);
|
||||
let b = DC.span(1, 6);
|
||||
let c = DC.span(7, 3);
|
||||
let d = DC.span(10, 6);
|
||||
let e = DC.span(17, 2);
|
||||
let f = DC.span(19, 1);
|
||||
let g = DC.span(20, 7);
|
||||
let h = DC.span(27, 1);
|
||||
|
||||
assert_eq!(
|
||||
Ok(vec![
|
||||
|
@ -442,10 +442,10 @@ fn comment() {
|
|||
// 0 10`11 16`17 30`31 37
|
||||
// A B C D
|
||||
|
||||
let a = UC.span(0, 11);
|
||||
let b = UC.span(11, 6);
|
||||
let c = UC.span(17, 14);
|
||||
let d = UC.span(31, 7);
|
||||
let a = DC.span(0, 11);
|
||||
let b = DC.span(11, 6);
|
||||
let c = DC.span(17, 14);
|
||||
let d = DC.span(31, 7);
|
||||
|
||||
assert_eq!(
|
||||
Ok(vec![
|
||||
|
@ -471,10 +471,10 @@ lines-->
|
|||
// 0 5`6 37'38`39 45
|
||||
// A B C D
|
||||
|
||||
let a = UC.span(0, 6);
|
||||
let b = UC.span(6, 32);
|
||||
let c = UC.span(38, 1);
|
||||
let d = UC.span(39, 7);
|
||||
let a = DC.span(0, 6);
|
||||
let b = DC.span(6, 32);
|
||||
let c = DC.span(38, 1);
|
||||
let d = DC.span(39, 7);
|
||||
|
||||
assert_eq!(
|
||||
Ok(vec![
|
||||
|
@ -495,10 +495,10 @@ fn permits_mismatched_tags() {
|
|||
// 0 5`6 11 13`15 25
|
||||
// A B C D
|
||||
|
||||
let a = UC.span(0, 6);
|
||||
let b = UC.span(6, 6);
|
||||
let c = UC.span(13, 2);
|
||||
let d = UC.span(15, 11);
|
||||
let a = DC.span(0, 6);
|
||||
let b = DC.span(6, 6);
|
||||
let c = DC.span(13, 2);
|
||||
let d = DC.span(15, 11);
|
||||
|
||||
assert_eq!(
|
||||
Ok(vec![
|
||||
|
@ -517,7 +517,7 @@ fn node_name_invalid_utf8() {
|
|||
new_sut!(b sut = bytes);
|
||||
|
||||
// We report at the QName, not the start tag.
|
||||
let span = UC.span(1, 1);
|
||||
let span = DC.span(1, 1);
|
||||
|
||||
let result = sut.collect::<Result<Vec<_>>>();
|
||||
|
||||
|
@ -539,7 +539,7 @@ fn attr_name_invalid_utf8() {
|
|||
|
||||
new_sut!(sut = s);
|
||||
|
||||
let span = UC.span(3, 1);
|
||||
let span = DC.span(3, 1);
|
||||
|
||||
let result = sut.collect::<Result<Vec<_>>>();
|
||||
|
||||
|
@ -561,7 +561,7 @@ fn attr_value_invalid_utf8() {
|
|||
|
||||
new_sut!(sut = s);
|
||||
|
||||
let span = UC.span(9, 4);
|
||||
let span = DC.span(9, 4);
|
||||
|
||||
let result = sut.collect::<Result<Vec<_>>>();
|
||||
|
||||
|
@ -585,8 +585,8 @@ fn valid_xml_decl_no_encoding() {
|
|||
// We do not yet emit a token for
|
||||
// XML declarations
|
||||
|
||||
let a = UC.span(21, 5);
|
||||
let b = UC.span(27, 2);
|
||||
let a = DC.span(21, 5);
|
||||
let b = DC.span(27, 2);
|
||||
|
||||
assert_eq!(
|
||||
Ok(vec![
|
||||
|
@ -619,7 +619,7 @@ fn invalid_xml_decl_version() {
|
|||
// 15 17
|
||||
|
||||
// Unlike above, we do actually calculate a span here.
|
||||
let span = UC.span(15, 3);
|
||||
let span = DC.span(15, 3);
|
||||
|
||||
assert_eq!(
|
||||
Err(Error::UnsupportedXmlVersion("1.1".intern(), span)),
|
||||
|
@ -634,7 +634,7 @@ fn invalid_xml_encoding() {
|
|||
// |-----|
|
||||
// 30 37
|
||||
|
||||
let span = UC.span(30, 7);
|
||||
let span = DC.span(30, 7);
|
||||
|
||||
assert_eq!(
|
||||
Err(Error::UnsupportedEncoding("latin-1".intern(), span)),
|
||||
|
@ -672,7 +672,7 @@ fn attr_single_no_value_no_eq() {
|
|||
// WS to make sure we add the file-relative pos
|
||||
// and not just have the span relative to the element
|
||||
|
||||
let span = UC.span(10, 0);
|
||||
let span = DC.span(10, 0);
|
||||
|
||||
assert_eq!(
|
||||
Err(Error::AttrValueExpected(None, span)),
|
||||
|
@ -687,7 +687,7 @@ fn attr_single_no_value_with_eq() {
|
|||
// 11
|
||||
// where the `"value"` should be
|
||||
|
||||
let span = UC.span(11, 0);
|
||||
let span = DC.span(11, 0);
|
||||
|
||||
assert_eq!(
|
||||
Err(Error::AttrValueExpected(None, span)),
|
||||
|
@ -702,7 +702,7 @@ fn attr_multi_no_value_no_eq() {
|
|||
// 10
|
||||
// where the `="value"` should be
|
||||
|
||||
let span = UC.span(10, 0);
|
||||
let span = DC.span(10, 0);
|
||||
|
||||
assert_eq!(
|
||||
// quick-xml doesn't provide the name
|
||||
|
@ -720,7 +720,7 @@ fn attr_multi_no_value_with_eq() {
|
|||
|
||||
// TODO: quick-xml does not give us the length so we'll have to figure
|
||||
// it out ourselves.
|
||||
let span = UC.span(11, 0);
|
||||
let span = DC.span(11, 0);
|
||||
|
||||
assert_eq!(
|
||||
Err(Error::AttrValueUnquoted(None, span)),
|
||||
|
@ -735,7 +735,7 @@ fn attr_multiple_no_value_no_eq_then_good() {
|
|||
// 10
|
||||
// where the `="value"` should be
|
||||
|
||||
let span = UC.span(10, 0);
|
||||
let span = DC.span(10, 0);
|
||||
|
||||
assert_eq!(
|
||||
// quick-xml doesn't provide the name
|
||||
|
@ -751,7 +751,7 @@ fn empty_element_qname_no_attrs() {
|
|||
// 1
|
||||
// where the QName should be
|
||||
|
||||
let span = UC.span(1, 0);
|
||||
let span = DC.span(1, 0);
|
||||
|
||||
assert_eq!(
|
||||
Err(Error::InvalidQName("".intern(), span)),
|
||||
|
@ -766,7 +766,7 @@ fn empty_element_qname_with_space_no_attrs() {
|
|||
// 1
|
||||
// where the QName should be
|
||||
|
||||
let span = UC.span(1, 0);
|
||||
let span = DC.span(1, 0);
|
||||
|
||||
assert_eq!(
|
||||
Err(Error::InvalidQName("".intern(), span)),
|
||||
|
@ -780,7 +780,7 @@ fn empty_element_qname_with_attr() {
|
|||
// |-------|
|
||||
// 1 10
|
||||
|
||||
let span = UC.span(1, 9);
|
||||
let span = DC.span(1, 9);
|
||||
|
||||
assert_eq!(
|
||||
Err(Error::InvalidQName("foo=\"bar\"".intern(), span)),
|
||||
|
@ -795,7 +795,7 @@ fn empty_element_qname_with_space_with_attr() {
|
|||
// 1
|
||||
// quick-xml interprets the space as a "" QName
|
||||
|
||||
let span = UC.span(1, 0);
|
||||
let span = DC.span(1, 0);
|
||||
|
||||
assert_eq!(
|
||||
Err(Error::InvalidQName("".intern(), span)),
|
||||
|
|
Loading…
Reference in New Issue