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-10934
main
Mike Gerwitz 2022-04-08 16:16:23 -04:00
parent 68223cb7d3
commit a1a4ad3e8e
5 changed files with 183 additions and 155 deletions

View File

@ -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),
)??;
}

View File

@ -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 {

View File

@ -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,
)
})
})
},
)
})????
},
)????
}
};

View File

@ -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

View File

@ -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)),