2021-11-16 15:47:52 -05:00
|
|
|
// XIR-based xmlo object errors
|
|
|
|
//
|
|
|
|
// Copyright (C) 2014-2021 Ryan Specialty Group, LLC.
|
|
|
|
//
|
|
|
|
// This file is part of TAME.
|
|
|
|
//
|
|
|
|
// This program is free software: you can redistribute it and/or modify
|
|
|
|
// it under the terms of the GNU General Public License as published by
|
|
|
|
// the Free Software Foundation, either version 3 of the License, or
|
|
|
|
// (at your option) any later version.
|
|
|
|
//
|
|
|
|
// This program is distributed in the hope that it will be useful,
|
|
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
// GNU General Public License for more details.
|
|
|
|
//
|
|
|
|
// You should have received a copy of the GNU General Public License
|
|
|
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
|
|
|
|
//! Errors while processing `xmlo` object files.
|
|
|
|
|
2022-03-18 16:24:53 -04:00
|
|
|
use crate::parse::ParseError;
|
2022-03-29 11:14:47 -04:00
|
|
|
use crate::span::Span;
|
2021-11-16 15:47:52 -05:00
|
|
|
use crate::sym::SymbolId;
|
|
|
|
use crate::tpwrap::quick_xml::{Error as XmlError, InnerXmlError};
|
2022-03-18 16:24:53 -04:00
|
|
|
use crate::xir::{tree::StackError, Token};
|
2021-11-16 15:47:52 -05:00
|
|
|
use std::fmt::Display;
|
|
|
|
|
|
|
|
/// Error during `xmlo` processing.
|
|
|
|
///
|
|
|
|
/// Errors contain only owned values rather than references to original
|
|
|
|
/// data since they represent conditions requiring termination from
|
|
|
|
/// malformed compiler output,
|
|
|
|
/// and so should rarely occur.
|
|
|
|
/// This drastically simplifies the reader and [`Result`] chaining.
|
|
|
|
///
|
|
|
|
/// TODO: These errors provide no context (byte offset).
|
tamer: obj::xmlo::reader: Begin conversion to ParseState
This begins to transition XmloReader into a ParseState. Unlike previous
changes where ParseStates were composed into a single ParseState, this is
instead a lowering operation that will take the output of one Parser and
provide it to another.
The mess in ld::poc (...which still needs to be refactored and removed)
shows the concept, which will be abstracted away. This won't actually get
to the ASG in order to test that that this works with the
wip-xmlo-xir-reader flag on (development hasn't gotten that far yet), but
since it type-checks, it should conceptually work.
Wiring lowering operations together is something that I've been dreading for
months, but my approach of only abstracting after-the-fact has helped to
guide a sane approach for this. For some definition of "sane".
It's also worth noting that AsgBuilder will too become a ParseState
implemented as another lowering operation, so:
XIR -> XIRF -> XMLO -> ASG
These steps will all be streaming, with iteration happening only at the
topmost level. For this reason, it's important that ASG not be responsible
for doing that pull, and further we should propagate Parsed::Incomplete
rather than filtering it out and looping an indeterminate number of times
outside of the toplevel.
One final note: the choice of 64 for the maximum depth is entirely
arbitrary and should be more than generous; it'll be finalized at some point
in the future once I actually evaluate what maximum depth is reasonable
based on how the system is used, with some added growing room.
DEV-10863
2022-03-22 13:56:43 -04:00
|
|
|
#[derive(Debug, PartialEq, Eq)]
|
2021-11-16 15:47:52 -05:00
|
|
|
pub enum XmloError {
|
|
|
|
/// XML parsing error (legacy, quick-xml).
|
|
|
|
XmlError(XmlError),
|
2021-11-18 00:59:10 -05:00
|
|
|
/// XIR parsing error.
|
2022-03-18 15:26:05 -04:00
|
|
|
XirtError(ParseError<Token, StackError>),
|
2021-11-16 15:47:52 -05:00
|
|
|
/// The root node was not an `lv:package`.
|
|
|
|
UnexpectedRoot,
|
|
|
|
/// A `preproc:sym` node was found, but is missing `@name`.
|
2022-03-29 11:14:47 -04:00
|
|
|
UnassociatedSym(Span),
|
2021-11-16 15:47:52 -05:00
|
|
|
/// The provided `preproc:sym/@type` is unknown or invalid.
|
2022-03-30 09:06:10 -04:00
|
|
|
InvalidType(SymbolId, Span),
|
2021-11-16 15:47:52 -05:00
|
|
|
/// The provided `preproc:sym/@dtype` is unknown or invalid.
|
2022-03-30 09:06:10 -04:00
|
|
|
InvalidDtype(SymbolId, Span),
|
2021-11-16 15:47:52 -05:00
|
|
|
/// The provided `preproc:sym/@dim` is invalid.
|
2022-03-29 11:14:47 -04:00
|
|
|
InvalidDim(SymbolId, Span),
|
2021-11-16 15:47:52 -05:00
|
|
|
/// A `preproc:sym-dep` element was found, but is missing `@name`.
|
|
|
|
UnassociatedSymDep,
|
|
|
|
/// The `preproc:sym[@type="map"]` contains unexpected or invalid data.
|
|
|
|
InvalidMapFrom(String),
|
|
|
|
/// Invalid dependency in adjacency list
|
|
|
|
/// (`preproc:sym-dep/preproc:sym-ref`).
|
|
|
|
MalformedSymRef(String),
|
|
|
|
/// A `preproc:fragment` element was found, but is missing `@id`.
|
|
|
|
UnassociatedFragment,
|
|
|
|
/// A `preproc:fragment` element was found, but is missing `text()`.
|
|
|
|
MissingFragmentText(SymbolId),
|
|
|
|
/// Token stream ended unexpectedly.
|
|
|
|
UnexpectedEof,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl From<InnerXmlError> for XmloError {
|
|
|
|
fn from(e: InnerXmlError) -> Self {
|
|
|
|
XmloError::XmlError(e.into())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-03-18 15:26:05 -04:00
|
|
|
impl From<ParseError<Token, StackError>> for XmloError {
|
|
|
|
fn from(e: ParseError<Token, StackError>) -> Self {
|
2021-11-18 00:59:10 -05:00
|
|
|
Self::XirtError(e)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-11-16 15:47:52 -05:00
|
|
|
impl Display for XmloError {
|
|
|
|
fn fmt(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result {
|
|
|
|
match self {
|
|
|
|
Self::XmlError(e) => e.fmt(fmt),
|
2021-11-18 00:59:10 -05:00
|
|
|
Self::XirtError(e) => e.fmt(fmt),
|
2021-11-16 15:47:52 -05:00
|
|
|
Self::UnexpectedRoot => {
|
|
|
|
write!(fmt, "unexpected package root (is this a package?)")
|
|
|
|
}
|
2022-03-29 11:14:47 -04:00
|
|
|
Self::UnassociatedSym(span) => write!(
|
2021-11-16 15:47:52 -05:00
|
|
|
fmt,
|
2022-03-29 11:14:47 -04:00
|
|
|
"unassociated symbol table entry: \
|
|
|
|
preproc:sym/@name missing at {span}"
|
2021-11-16 15:47:52 -05:00
|
|
|
),
|
2022-03-30 09:06:10 -04:00
|
|
|
Self::InvalidType(ty, span) => {
|
|
|
|
write!(fmt, "invalid preproc:sym/@type `{ty}` at {span}")
|
2021-11-16 15:47:52 -05:00
|
|
|
}
|
2022-03-30 09:06:10 -04:00
|
|
|
Self::InvalidDtype(dtype, span) => {
|
|
|
|
write!(fmt, "invalid preproc:sym/@dtype `{dtype}` at {span}")
|
2021-11-16 15:47:52 -05:00
|
|
|
}
|
2022-03-29 11:14:47 -04:00
|
|
|
Self::InvalidDim(dim, span) => {
|
|
|
|
write!(fmt, "invalid preproc:sym/@dim `{dim}` at {span}")
|
2021-11-16 15:47:52 -05:00
|
|
|
}
|
|
|
|
Self::InvalidMapFrom(msg) => {
|
|
|
|
write!(fmt, "invalid preproc:sym[@type=\"map\"]: {}", msg)
|
|
|
|
}
|
|
|
|
Self::UnassociatedSymDep => write!(
|
|
|
|
fmt,
|
|
|
|
"unassociated dependency list: preproc:sym-dep/@name missing"
|
|
|
|
),
|
|
|
|
Self::MalformedSymRef(msg) => {
|
|
|
|
write!(fmt, "malformed dependency ref: {}", msg)
|
|
|
|
}
|
|
|
|
Self::UnassociatedFragment => write!(
|
|
|
|
fmt,
|
|
|
|
"unassociated fragment: preproc:fragment/@id missing"
|
|
|
|
),
|
|
|
|
Self::MissingFragmentText(symname) => write!(
|
|
|
|
fmt,
|
|
|
|
"fragment found, but missing text for symbol `{}`",
|
|
|
|
symname,
|
|
|
|
),
|
|
|
|
Self::UnexpectedEof => write!(fmt, "unexpected EOF"),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl std::error::Error for XmloError {
|
|
|
|
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
|
|
|
|
match self {
|
|
|
|
Self::XmlError(e) => Some(e),
|
2021-11-18 00:59:10 -05:00
|
|
|
Self::XirtError(e) => Some(e),
|
2021-11-16 15:47:52 -05:00
|
|
|
_ => None,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|