Mike Gerwitz

Activist for User Freedom

aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJoseph Frazer <joseph.frazer@ryansg.com>2020-03-11 10:23:34 -0400
committerMike Gerwitz <mike.gerwitz@ryansg.com>2020-03-13 11:51:59 -0400
commit59a0c382af82e3529cf2ba4c399024fb00387c79 (patch)
treeb0eb2e201bec6975663f88010f07f96d90d2325d
parent5f3ccc6894f0a0769d0ed96ff928480a7ff896d5 (diff)
downloadtame-59a0c382af82e3529cf2ba4c399024fb00387c79.tar.gz
tame-59a0c382af82e3529cf2ba4c399024fb00387c79.tar.bz2
tame-59a0c382af82e3529cf2ba4c399024fb00387c79.zip
[DEV-7085] Move sections to IR module
We need to use `Sections` in both the writer and the ASG so it needs to be in a place that makes sense.
-rw-r--r--tamer/src/ir/asg/mod.rs2
-rw-r--r--tamer/src/ir/asg/section.rs274
-rw-r--r--tamer/src/ld/poc.rs4
-rw-r--r--tamer/src/obj/xmle/writer/mod.rs5
-rw-r--r--tamer/src/obj/xmle/writer/writer.rs256
-rw-r--r--tamer/src/obj/xmle/writer/xmle.rs11
6 files changed, 287 insertions, 265 deletions
diff --git a/tamer/src/ir/asg/mod.rs b/tamer/src/ir/asg/mod.rs
index 8905768..13315d6 100644
--- a/tamer/src/ir/asg/mod.rs
+++ b/tamer/src/ir/asg/mod.rs
@@ -185,10 +185,12 @@ mod base;
mod graph;
mod ident;
mod object;
+mod section;
pub use graph::{Asg, AsgError, AsgResult, ObjectRef};
pub use ident::{Dim, IdentKind};
pub use object::{FragmentText, Object, Source};
+pub use section::{Section, SectionIterator, Sections};
/// Default concrete ASG implementation.
pub type DefaultAsg<'i, Ix> = base::BaseAsg<'i, Ix>;
diff --git a/tamer/src/ir/asg/section.rs b/tamer/src/ir/asg/section.rs
new file mode 100644
index 0000000..062a3f2
--- /dev/null
+++ b/tamer/src/ir/asg/section.rs
@@ -0,0 +1,274 @@
+// Section/Sections IR representation
+//
+// Copyright (C) 2014-2020 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/>.
+
+use crate::ir::asg::Object;
+
+type ObjectRef<'a, 'i> = &'a Object<'i>;
+pub type ObjectVec<'a, 'i> = Vec<ObjectRef<'a, 'i>>;
+
+/// A Section that needs to be written to the buffer
+///
+/// Most sections will only need a `body`, but some innlude `head` and `tail`
+/// information. Rather than dealing with those differently, each `Section`
+/// will have a `head` and `tail` that are empty by default.
+#[derive(Clone, Default)]
+pub struct Section<'a, 'i> {
+ head: ObjectVec<'a, 'i>,
+ body: ObjectVec<'a, 'i>,
+ tail: ObjectVec<'a, 'i>,
+}
+
+impl<'a, 'i> Section<'a, 'i> {
+ /// Constructor for Sections
+ ///
+ /// ```
+ /// use tamer::ir::asg::Section;
+ ///
+ /// let section = Section::new();
+ /// ```
+ pub fn new() -> Self {
+ Self {
+ head: Vec::new(),
+ body: Vec::new(),
+ tail: Vec::new(),
+ }
+ }
+
+ /// The length of the `Section`
+ pub fn len(&self) -> usize {
+ self.head.len() + self.body.len() + self.tail.len()
+ }
+
+ /// Check if the `Section` is empty
+ pub fn is_empty(&self) -> bool {
+ self.len() == 0
+ }
+
+ /// Push an `Object` into a `Section`'s head
+ pub fn push_head(&mut self, obj: ObjectRef<'a, 'i>) {
+ self.head.push(&obj)
+ }
+
+ /// Push an `Object` into a `Section`'s body
+ pub fn push_body(&mut self, obj: ObjectRef<'a, 'i>) {
+ self.body.push(&obj)
+ }
+
+ /// Push an `Object` into a `Section`'s tail
+ pub fn push_tail(&mut self, obj: ObjectRef<'a, 'i>) {
+ self.tail.push(&obj)
+ }
+
+ /// Merge the parts of a `Section` into one [`SectionIterator`]
+ ///
+ /// The `Section` internals need to be iterated as a group so we needed to
+ /// create a custom iterator, [`SectionIterator`] to do this for us. This
+ /// method allows us to access the iterator.
+ ///
+ /// ```
+ /// use tamer::ir::asg::{Object, Section};
+ ///
+ /// let mut section = Section::new();
+ /// let obj = Object::Empty;
+ /// let expect = vec![&obj, &obj, &obj];
+ ///
+ /// section.push_head(&obj);
+ /// section.push_body(&obj);
+ /// section.push_tail(&obj);
+ /// let section_iter = section.iter();
+ ///
+ /// for object in section_iter {
+ /// assert_eq!(&obj, object);
+ /// }
+ /// ```
+ pub fn iter(&self) -> SectionIterator {
+ SectionIterator {
+ inner: Box::new(
+ self.head
+ .iter()
+ .chain(self.body.iter())
+ .chain(self.tail.iter())
+ .copied(),
+ ),
+ }
+ }
+}
+
+/// Wrapper for an Iterator
+///
+/// This allows us to iterate over all parts of a [`Section`].
+pub struct SectionIterator<'a, 'i> {
+ inner: Box<dyn Iterator<Item = &'a Object<'i>> + 'a>,
+}
+
+impl<'a, 'i> Iterator for SectionIterator<'a, 'i> {
+ type Item = &'a Object<'i>;
+
+ fn next(&mut self) -> Option<Self::Item> {
+ self.inner.next()
+ }
+}
+
+/// Sections that need to be written to a buffer
+///
+/// All the properties are public [`Section`] objects and will be accessed
+/// directly by the the objects interacting with them.
+#[derive(Default)]
+pub struct Sections<'a, 'i> {
+ pub map: Section<'a, 'i>,
+ pub retmap: Section<'a, 'i>,
+ pub meta: Section<'a, 'i>,
+ pub worksheet: Section<'a, 'i>,
+ pub params: Section<'a, 'i>,
+ pub types: Section<'a, 'i>,
+ pub funcs: Section<'a, 'i>,
+ pub rater: Section<'a, 'i>,
+}
+
+impl<'a, 'i> Sections<'a, 'i> {
+ /// Constructor for Sections
+ ///
+ /// ```
+ /// use tamer::ir::asg::Sections;
+ ///
+ /// let sections = Sections::new();
+ /// ```
+ pub fn new() -> Self {
+ Self {
+ map: Section::new(),
+ retmap: Section::new(),
+ meta: Section::new(),
+ worksheet: Section::new(),
+ params: Section::new(),
+ types: Section::new(),
+ funcs: Section::new(),
+ rater: Section::new(),
+ }
+ }
+}
+
+#[cfg(test)]
+mod test {
+ use super::*;
+
+ #[test]
+ fn section_empty() {
+ let section = Section::new();
+
+ assert!(section.head.is_empty());
+ assert!(section.body.is_empty());
+ assert!(section.tail.is_empty());
+ }
+
+ #[test]
+ fn section_head() {
+ let mut section = Section::new();
+ let obj = Object::Empty;
+
+ assert!(section.head.is_empty());
+
+ section.push_head(&obj);
+
+ assert_eq!(Some(&&obj), section.head.get(0));
+ }
+
+ #[test]
+ fn section_body() {
+ let mut section = Section::new();
+ let obj = Object::Empty;
+
+ assert!(section.body.is_empty());
+
+ section.push_body(&obj);
+
+ let body = section.body;
+ assert_eq!(Some(&&obj), body.get(0));
+ }
+
+ #[test]
+ fn section_tail() {
+ let mut section = Section::new();
+ let obj = Object::Empty;
+
+ assert!(section.tail.is_empty());
+
+ section.push_tail(&obj);
+
+ assert_eq!(Some(&&obj), section.tail.get(0));
+ }
+
+ #[test]
+ fn section_len() {
+ let mut section = Section::new();
+ let obj = Object::Empty;
+
+ assert_eq!(0, section.len());
+ section.push_head(&obj);
+ assert_eq!(1, section.len());
+ section.push_body(&obj);
+ assert_eq!(2, section.len());
+ section.push_tail(&obj);
+ assert_eq!(3, section.len());
+ }
+
+ #[test]
+ fn section_is_empty_head() {
+ let mut section = Section::new();
+ let obj = Object::Empty;
+
+ assert!(section.is_empty());
+ section.push_head(&obj);
+ assert!(!section.is_empty());
+ }
+
+ #[test]
+ fn section_is_empty_body() {
+ let mut section = Section::new();
+ let obj = Object::Empty;
+
+ assert!(section.is_empty());
+ section.push_body(&obj);
+ assert!(!section.is_empty());
+ }
+
+ #[test]
+ fn section_is_empty_tail() {
+ let mut section = Section::new();
+ let obj = Object::Empty;
+
+ assert!(section.is_empty());
+ section.push_tail(&obj);
+ assert!(!section.is_empty());
+ }
+
+ #[test]
+ fn section_iterator() {
+ let mut section = Section::new();
+ let obj = Object::Empty;
+ let expect = vec![&obj, &obj, &obj];
+
+ section.push_head(&obj);
+ section.push_body(&obj);
+ section.push_tail(&obj);
+
+ let collection: Vec<_> = section.iter().collect();
+
+ assert_eq!(expect, collection);
+ }
+}
diff --git a/tamer/src/ld/poc.rs b/tamer/src/ld/poc.rs
index 52f4366..3e6fb0a 100644
--- a/tamer/src/ld/poc.rs
+++ b/tamer/src/ld/poc.rs
@@ -22,9 +22,9 @@
use crate::global;
use crate::ir::asg::{
- Asg, AsgError, DefaultAsg, IdentKind, Object, ObjectRef, Source,
+ Asg, AsgError, DefaultAsg, IdentKind, Object, ObjectRef, Sections, Source,
};
-use crate::obj::xmle::writer::{Sections, XmleWriter};
+use crate::obj::xmle::writer::XmleWriter;
use crate::obj::xmlo::reader::{XmloError, XmloEvent, XmloReader};
use crate::sym::{DefaultInterner, Interner, Symbol};
use fxhash::{FxHashMap, FxHashSet};
diff --git a/tamer/src/obj/xmle/writer/mod.rs b/tamer/src/obj/xmle/writer/mod.rs
index 973a040..43cc939 100644
--- a/tamer/src/obj/xmle/writer/mod.rs
+++ b/tamer/src/obj/xmle/writer/mod.rs
@@ -28,7 +28,8 @@
//! The example below is incomplete, but shows the general usage.
//!
//! ```
-//! use tamer::obj::xmle::writer::{Sections, XmleWriter};
+//! use tamer::obj::xmle::writer::XmleWriter;
+//! use tamer::ir::asg::Sections;
//! use tamer::sym::{DefaultInterner, Interner, Symbol};
//! use std::io::Cursor;
//!
@@ -44,6 +45,6 @@
mod writer;
mod xmle;
-pub use writer::{Result, Section, Sections, Writer, WriterError};
+pub use writer::{Result, Writer, WriterError};
pub use xmle::XmleWriter;
diff --git a/tamer/src/obj/xmle/writer/writer.rs b/tamer/src/obj/xmle/writer/writer.rs
index 7c592cf..2e4c167 100644
--- a/tamer/src/obj/xmle/writer/writer.rs
+++ b/tamer/src/obj/xmle/writer/writer.rs
@@ -17,16 +17,14 @@
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
-use crate::ir::asg::Object;
+use crate::ir::asg::Sections;
use crate::sym::Symbol;
use quick_xml::Error as XmlError;
use std::io::{Error as IoError, Write};
use std::result;
use std::str::Utf8Error;
-type ObjectRef<'a, 'i> = &'a Object<'i>;
pub type Result<T = ()> = result::Result<T, WriterError>;
-pub type ObjectVec<'a, 'i> = Vec<ObjectRef<'a, 'i>>;
/// A wrapper around a `Write` object
///
@@ -42,148 +40,6 @@ pub trait Writer<W: Write> {
Self: Sized;
}
-/// A Section that needs to be written to the buffer
-///
-/// Most sections will only need a `body`, but some innlude `head` and `tail`
-/// information. Rather than dealing with those differently, each `Section`
-/// will have a `head` and `tail` that are empty by default.
-#[derive(Clone, Default)]
-pub struct Section<'a, 'i> {
- head: ObjectVec<'a, 'i>,
- body: ObjectVec<'a, 'i>,
- tail: ObjectVec<'a, 'i>,
-}
-
-impl<'a, 'i> Section<'a, 'i> {
- /// Constructor for Sections
- ///
- /// ```
- /// use tamer::obj::xmle::writer::Section;
- ///
- /// let section = Section::new();
- /// ```
- pub fn new() -> Self {
- Self {
- head: Vec::new(),
- body: Vec::new(),
- tail: Vec::new(),
- }
- }
-
- /// The length of the `Section`
- pub fn len(&self) -> usize {
- self.head.len() + self.body.len() + self.tail.len()
- }
-
- /// Check if the `Section` is empty
- pub fn is_empty(&self) -> bool {
- self.len() == 0
- }
-
- /// Push an `Object` into a `Section`'s head
- pub fn push_head(&mut self, obj: ObjectRef<'a, 'i>) {
- self.head.push(&obj)
- }
-
- /// Push an `Object` into a `Section`'s body
- pub fn push_body(&mut self, obj: ObjectRef<'a, 'i>) {
- self.body.push(&obj)
- }
-
- /// Push an `Object` into a `Section`'s tail
- pub fn push_tail(&mut self, obj: ObjectRef<'a, 'i>) {
- self.tail.push(&obj)
- }
-
- /// Merge the parts of a `Section` into one [`SectionIterator`]
- ///
- /// The `Section` internals need to be iterated as a group so we needed to
- /// create a custom iterator, [`SectionIterator`] to do this for us. This
- /// method allows us to access the iterator.
- ///
- /// ```
- /// use tamer::obj::xmle::writer::Section;
- /// use tamer::ir::asg::Object;
- ///
- /// let mut section = Section::new();
- /// let obj = Object::Empty;
- /// let expect = vec![&obj, &obj, &obj];
- ///
- /// section.push_head(&obj);
- /// section.push_body(&obj);
- /// section.push_tail(&obj);
- /// let section_iter = section.iter();
- ///
- /// for object in section_iter {
- /// assert_eq!(&obj, object);
- /// }
- /// ```
- pub fn iter(&self) -> SectionIterator {
- SectionIterator {
- inner: Box::new(
- self.head
- .iter()
- .chain(self.body.iter())
- .chain(self.tail.iter())
- .copied(),
- ),
- }
- }
-}
-
-/// Wrapper for an Iterator
-///
-/// This allows us to iterate over all parts of a [`Section`].
-pub struct SectionIterator<'a, 'i> {
- inner: Box<dyn Iterator<Item = &'a Object<'i>> + 'a>,
-}
-
-impl<'a, 'i> Iterator for SectionIterator<'a, 'i> {
- type Item = &'a Object<'i>;
-
- fn next(&mut self) -> Option<Self::Item> {
- self.inner.next()
- }
-}
-
-/// Sections that need to be written to a buffer
-///
-/// All the properties are public [`Section`] objects and will be accessed
-/// directly by the [`Writer`].
-#[derive(Default)]
-pub struct Sections<'a, 'i> {
- pub map: Section<'a, 'i>,
- pub retmap: Section<'a, 'i>,
- pub meta: Section<'a, 'i>,
- pub worksheet: Section<'a, 'i>,
- pub params: Section<'a, 'i>,
- pub types: Section<'a, 'i>,
- pub funcs: Section<'a, 'i>,
- pub rater: Section<'a, 'i>,
-}
-
-impl<'a, 'i> Sections<'a, 'i> {
- /// Constructor for Sections
- ///
- /// ```
- /// use tamer::obj::xmle::writer::Sections;
- ///
- /// let sections = Sections::new();
- /// ```
- pub fn new() -> Self {
- Self {
- map: Section::new(),
- retmap: Section::new(),
- meta: Section::new(),
- worksheet: Section::new(),
- params: Section::new(),
- types: Section::new(),
- funcs: Section::new(),
- rater: Section::new(),
- }
- }
-}
-
/// Error implementations for the writer
#[derive(Debug)]
pub enum WriterError {
@@ -233,113 +89,3 @@ impl From<XmlError> for WriterError {
WriterError::XmlError(err)
}
}
-
-#[cfg(test)]
-mod test {
- use super::*;
-
- #[test]
- fn section_empty() {
- let section = Section::new();
-
- assert!(section.head.is_empty());
- assert!(section.body.is_empty());
- assert!(section.tail.is_empty());
- }
-
- #[test]
- fn section_head() {
- let mut section = Section::new();
- let obj = Object::Empty;
-
- assert!(section.head.is_empty());
-
- section.push_head(&obj);
-
- assert_eq!(Some(&&obj), section.head.get(0));
- }
-
- #[test]
- fn section_body() {
- let mut section = Section::new();
- let obj = Object::Empty;
-
- assert!(section.body.is_empty());
-
- section.push_body(&obj);
-
- let body = section.body;
- assert_eq!(Some(&&obj), body.get(0));
- }
-
- #[test]
- fn section_tail() {
- let mut section = Section::new();
- let obj = Object::Empty;
-
- assert!(section.tail.is_empty());
-
- section.push_tail(&obj);
-
- assert_eq!(Some(&&obj), section.tail.get(0));
- }
-
- #[test]
- fn section_len() {
- let mut section = Section::new();
- let obj = Object::Empty;
-
- assert_eq!(0, section.len());
- section.push_head(&obj);
- assert_eq!(1, section.len());
- section.push_body(&obj);
- assert_eq!(2, section.len());
- section.push_tail(&obj);
- assert_eq!(3, section.len());
- }
-
- #[test]
- fn section_is_empty_head() {
- let mut section = Section::new();
- let obj = Object::Empty;
-
- assert!(section.is_empty());
- section.push_head(&obj);
- assert!(!section.is_empty());
- }
-
- #[test]
- fn section_is_empty_body() {
- let mut section = Section::new();
- let obj = Object::Empty;
-
- assert!(section.is_empty());
- section.push_body(&obj);
- assert!(!section.is_empty());
- }
-
- #[test]
- fn section_is_empty_tail() {
- let mut section = Section::new();
- let obj = Object::Empty;
-
- assert!(section.is_empty());
- section.push_tail(&obj);
- assert!(!section.is_empty());
- }
-
- #[test]
- fn section_iterator() {
- let mut section = Section::new();
- let obj = Object::Empty;
- let expect = vec![&obj, &obj, &obj];
-
- section.push_head(&obj);
- section.push_body(&obj);
- section.push_tail(&obj);
-
- let collection: Vec<_> = section.iter().collect();
-
- assert_eq!(expect, collection);
- }
-}
diff --git a/tamer/src/obj/xmle/writer/xmle.rs b/tamer/src/obj/xmle/writer/xmle.rs
index d6baadf..0a81214 100644
--- a/tamer/src/obj/xmle/writer/xmle.rs
+++ b/tamer/src/obj/xmle/writer/xmle.rs
@@ -17,8 +17,8 @@
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
-use super::writer::{Result, SectionIterator, Sections, WriterError};
-use crate::ir::asg::{IdentKind, Object};
+use super::writer::{Result, WriterError};
+use crate::ir::asg::{IdentKind, Object, SectionIterator, Sections};
use crate::sym::Symbol;
use fxhash::FxHashSet;
#[cfg(test)]
@@ -69,7 +69,8 @@ impl<W: Write> XmleWriter<W> {
///
/// ```
/// use std::io::Cursor;
- /// use tamer::obj::xmle::writer::{Sections, XmleWriter};
+ /// use tamer::obj::xmle::writer::XmleWriter;
+ /// use tamer::ir::asg::Sections;
/// use tamer::sym::{Symbol, SymbolIndex};
/// use tamer::sym::{DefaultInterner, Interner};
///
@@ -410,10 +411,8 @@ mod mock {
#[cfg(test)]
mod test {
use super::*;
- use crate::ir::asg::Dim;
- use crate::ir::asg::Source;
+ use crate::ir::asg::{Dim, Section, Source};
use crate::ir::legacyir::SymAttrs;
- use crate::obj::xmle::writer::Section;
use crate::sym::{Symbol, SymbolIndex};
use std::str;