Skip to content

Commit

Permalink
refactor: Let pretty printing output attributes
Browse files Browse the repository at this point in the history
  • Loading branch information
Marwes committed Jul 6, 2018
1 parent db66561 commit d227c26
Show file tree
Hide file tree
Showing 10 changed files with 186 additions and 110 deletions.
4 changes: 4 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 3 additions & 3 deletions base/src/kind.rs
Original file line number Diff line number Diff line change
Expand Up @@ -95,10 +95,10 @@ impl fmt::Display for Kind {
}
}

impl<'a, A, E> ToDoc<'a, A, E> for ArcKind {
fn to_doc(&'a self, allocator: &'a A, _: E) -> DocBuilder<'a, A>
impl<'a, A, B, E> ToDoc<'a, A, B, E> for ArcKind {
fn to_doc(&'a self, allocator: &'a A, _: E) -> DocBuilder<'a, A, B>
where
A: DocAllocator<'a>,
A: DocAllocator<'a, B>,
{
DocBuilder(allocator, Doc::text(self.to_string()))
}
Expand Down
62 changes: 40 additions & 22 deletions base/src/types/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use std::marker::PhantomData;
use std::ops::{Deref, DerefMut};
use std::sync::Arc;

use pretty::{Arena, DocAllocator, DocBuilder};
use pretty::{Arena, Doc, DocAllocator, DocBuilder};

use smallvec::SmallVec;

Expand Down Expand Up @@ -1267,9 +1267,10 @@ impl<Id> ArcType<Id> {
}
}

pub fn pretty<'a>(&'a self, arena: &'a Arena<'a>) -> DocBuilder<'a, Arena<'a>>
pub fn pretty<'a, A>(&'a self, arena: &'a Arena<'a, A>) -> DocBuilder<'a, Arena<'a, A>, A>
where
Id: AsRef<str>,
A: Clone,
{
top(self).pretty(&Printer::new(arena, &()))
}
Expand Down Expand Up @@ -1666,12 +1667,12 @@ pub enum Prec {
}

impl Prec {
pub fn enclose<'a>(
pub fn enclose<'a, A>(
&self,
limit: Prec,
arena: &'a Arena<'a>,
doc: DocBuilder<'a, Arena<'a>>,
) -> DocBuilder<'a, Arena<'a>> {
arena: &'a Arena<'a, A>,
doc: DocBuilder<'a, Arena<'a, A>, A>,
) -> DocBuilder<'a, Arena<'a, A>, A> {
if *self >= limit {
chain![arena; "(", doc, ")"]
} else {
Expand All @@ -1696,26 +1697,32 @@ pub struct DisplayType<'a, T: 'a> {
typ: &'a T,
}

pub trait ToDoc<'a, A, E> {
fn to_doc(&'a self, allocator: &'a A, env: E) -> DocBuilder<'a, A>
pub trait ToDoc<'a, A, B, E> {
fn to_doc(&'a self, allocator: &'a A, env: E) -> DocBuilder<'a, A, B>
where
A: DocAllocator<'a>;
A: DocAllocator<'a, B>;
}

impl<'a, I> ToDoc<'a, Arena<'a>, ()> for ArcType<I>
impl<'a, I, A> ToDoc<'a, Arena<'a, A>, A, ()> for ArcType<I>
where
I: AsRef<str>,
A: Clone,
{
fn to_doc(&'a self, arena: &'a Arena<'a>, _: ()) -> DocBuilder<'a, Arena<'a>> {
fn to_doc(&'a self, arena: &'a Arena<'a, A>, _: ()) -> DocBuilder<'a, Arena<'a, A>, A> {
self.to_doc(arena, &() as &Source)
}
}

impl<'a, I> ToDoc<'a, Arena<'a>, &'a Source> for ArcType<I>
impl<'a, I, A> ToDoc<'a, Arena<'a, A>, A, &'a Source> for ArcType<I>
where
I: AsRef<str>,
A: Clone,
{
fn to_doc(&'a self, arena: &'a Arena<'a>, source: &'a Source) -> DocBuilder<'a, Arena<'a>> {
fn to_doc(
&'a self,
arena: &'a Arena<'a, A>,
source: &'a Source,
) -> DocBuilder<'a, Arena<'a, A>, A> {
let printer = Printer::new(arena, source);
dt(Prec::Top, self).pretty(&printer)
}
Expand Down Expand Up @@ -1755,7 +1762,10 @@ where
T: Deref<Target = Type<I, T>> + HasSpan + Commented + 'a,
I: AsRef<str> + 'a,
{
pub fn pretty(&self, printer: &Printer<'a, I>) -> DocBuilder<'a, Arena<'a>> {
pub fn pretty<A>(&self, printer: &Printer<'a, I, A>) -> DocBuilder<'a, Arena<'a, A>, A>
where
A: Clone,
{
let arena = printer.arena;

let p = self.prec;
Expand Down Expand Up @@ -1909,12 +1919,15 @@ where
}
}

fn pretty_row(
fn pretty_row<A>(
&self,
open: &str,
printer: &Printer<'a, I>,
pretty_field: &mut FnMut(&'a Field<I, T>) -> DocBuilder<'a, Arena<'a>>,
) -> DocBuilder<'a, Arena<'a>> {
printer: &Printer<'a, I, A>,
pretty_field: &mut FnMut(&'a Field<I, T>) -> DocBuilder<'a, Arena<'a, A>, A>,
) -> DocBuilder<'a, Arena<'a, A>, A>
where
A: Clone,
{
let arena = printer.arena;

let mut doc = arena.nil();
Expand Down Expand Up @@ -2021,7 +2034,7 @@ where
}

let doc = if filtered {
if doc.1 == arena.nil().1 {
if let Doc::Nil = doc.1 {
chain![arena;
newline.clone(),
"..."
Expand All @@ -2031,7 +2044,7 @@ where
newline.clone(),
"...,",
doc,
if newline.1 == arena.space().1 {
if let Doc::Space = newline.1 {
arena.text(",")
} else {
arena.nil()
Expand All @@ -2052,9 +2065,10 @@ where
}
}

fn pretty_function(&self, printer: &Printer<'a, I>) -> DocBuilder<'a, Arena<'a>>
fn pretty_function<A>(&self, printer: &Printer<'a, I, A>) -> DocBuilder<'a, Arena<'a, A>, A>
where
I: AsRef<str>,
A: Clone,
{
let arena = printer.arena;
let p = self.prec;
Expand All @@ -2076,10 +2090,14 @@ where
}
}

pub fn pretty_print<'a, I, T>(printer: &Printer<'a, I>, typ: &'a T) -> DocBuilder<'a, Arena<'a>>
pub fn pretty_print<'a, I, T, A>(
printer: &Printer<'a, I, A>,
typ: &'a T,
) -> DocBuilder<'a, Arena<'a, A>, A>
where
I: AsRef<str> + 'a,
T: Deref<Target = Type<I, T>> + HasSpan + Commented,
A: Clone,
{
dt(Prec::Top, typ).pretty(printer)
}
Expand Down
46 changes: 25 additions & 21 deletions base/src/types/pretty_print.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use std::fmt;
use std::marker::PhantomData;
use std::ops::Deref;

use pretty::{Arena, DocAllocator, DocBuilder};
use pretty::{Arena, Doc, DocAllocator, DocBuilder};

use ast::{is_operator_char, Commented};
use metadata::{Comment, CommentType};
Expand All @@ -12,9 +12,9 @@ use source::Source;

use types::{pretty_print, Type};

pub fn ident<'b, S>(arena: &'b Arena<'b>, name: S) -> DocBuilder<'b, Arena<'b>>
pub fn ident<'a, S, A>(arena: &'a Arena<'a, A>, name: S) -> DocBuilder<'a, Arena<'a, A>, A>
where
S: Into<Cow<'b, str>>,
S: Into<Cow<'a, str>>,
{
let name = name.into();
if name.starts_with(is_operator_char) {
Expand All @@ -24,10 +24,10 @@ where
}
}

pub fn doc_comment<'a>(
arena: &'a Arena<'a>,
pub fn doc_comment<'a, A>(
arena: &'a Arena<'a, A>,
text: Option<&'a Comment>,
) -> DocBuilder<'a, Arena<'a>> {
) -> DocBuilder<'a, Arena<'a, A>, A> {
match text {
Some(comment) => match comment.typ {
CommentType::Line => arena.concat(
Expand Down Expand Up @@ -109,10 +109,11 @@ impl<'a, I, T> TypeFormatter<'a, I, T> {
self
}

pub fn pretty(&self, arena: &'a Arena<'a>) -> DocBuilder<'a, Arena<'a>>
pub fn pretty<A>(&self, arena: &'a Arena<'a, A>) -> DocBuilder<'a, Arena<'a, A>, A>
where
T: Deref<Target = Type<I, T>> + HasSpan + Commented + 'a,
I: AsRef<str>,
A: Clone,
{
use super::top;
top(self.typ).pretty(&Printer {
Expand All @@ -122,7 +123,7 @@ impl<'a, I, T> TypeFormatter<'a, I, T> {
})
}

pub fn build(&self, arena: &'a Arena<'a>, source: &'a Source) -> Printer<'a, I> {
pub fn build<A>(&self, arena: &'a Arena<'a, A>, source: &'a Source) -> Printer<'a, I, A> {
Printer {
arena,
source,
Expand All @@ -137,7 +138,7 @@ where
I: AsRef<str>,
{
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let arena = Arena::new();
let arena = Arena::<()>::new();
let source = &();
let printer = self.build(&arena, source);
let mut s = Vec::new();
Expand All @@ -151,14 +152,14 @@ where
}
}

pub struct Printer<'a, I: 'a> {
pub arena: &'a Arena<'a>,
pub struct Printer<'a, I: 'a, A: 'a> {
pub arena: &'a Arena<'a, A>,
pub source: &'a Source,
filter: &'a Fn(&I) -> Filter,
}

impl<'a, I> Printer<'a, I> {
pub fn new(arena: &'a Arena<'a>, source: &'a Source) -> Printer<'a, I> {
impl<'a, I, A> Printer<'a, I, A> {
pub fn new(arena: &'a Arena<'a, A>, source: &'a Source) -> Printer<'a, I, A> {
Printer {
arena,
source,
Expand All @@ -170,9 +171,9 @@ impl<'a, I> Printer<'a, I> {
(self.filter)(field)
}

pub fn space_before(&self, pos: BytePos) -> DocBuilder<'a, Arena<'a>> {
pub fn space_before(&self, pos: BytePos) -> DocBuilder<'a, Arena<'a, A>, A> {
let (doc, comments) = self.comments_before_(pos);
if doc.1 == self.arena.nil().1 {
if let Doc::Nil = doc.1 {
self.arena.space()
} else if comments {
self.arena.space().append(doc).append(self.arena.space())
Expand All @@ -181,17 +182,17 @@ impl<'a, I> Printer<'a, I> {
}
}

pub fn space_after(&self, end: BytePos) -> DocBuilder<'a, Arena<'a>> {
pub fn space_after(&self, end: BytePos) -> DocBuilder<'a, Arena<'a, A>, A> {
let arena = self.arena;
let doc = self.comments_after(end);
if doc.1 == arena.nil().1 {
if let Doc::Nil = doc.1 {
arena.space()
} else {
arena.space().append(doc)
}
}

pub fn comments_before(&self, pos: BytePos) -> DocBuilder<'a, Arena<'a>> {
pub fn comments_before(&self, pos: BytePos) -> DocBuilder<'a, Arena<'a, A>, A> {
let (doc, comments) = self.comments_before_(pos);
if comments {
doc.append(self.arena.space())
Expand All @@ -200,7 +201,7 @@ impl<'a, I> Printer<'a, I> {
}
}

fn comments_before_(&self, pos: BytePos) -> (DocBuilder<'a, Arena<'a>>, bool) {
fn comments_before_(&self, pos: BytePos) -> (DocBuilder<'a, Arena<'a, A>, A>, bool) {
let arena = self.arena;
let mut doc = arena.nil();
let mut comments = 0;
Expand All @@ -222,7 +223,7 @@ impl<'a, I> Printer<'a, I> {
(doc, comments != 0)
}

pub fn comments_after(&self, end: BytePos) -> DocBuilder<'a, Arena<'a>> {
pub fn comments_after(&self, end: BytePos) -> DocBuilder<'a, Arena<'a, A>, A> {
let (doc, block_comments, _) =
self.comments_count(Span::new(end, self.source.span().end()));
if block_comments == 0 {
Expand All @@ -236,7 +237,10 @@ impl<'a, I> Printer<'a, I> {
}
}

pub fn comments_count(&self, span: Span<BytePos>) -> (DocBuilder<'a, Arena<'a>>, usize, bool) {
pub fn comments_count(
&self,
span: Span<BytePos>,
) -> (DocBuilder<'a, Arena<'a, A>, A>, usize, bool) {
let arena = self.arena;
let mut comments = 0;
let mut ends_with_newline = false;
Expand Down
2 changes: 1 addition & 1 deletion check/src/substitution.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ pub enum Error<T> {
impl<T> fmt::Display for Error<T>
where
T: fmt::Display,
T: for<'a> types::ToDoc<'a, ::pretty::Arena<'a>, ()>,
T: for<'a> types::ToDoc<'a, ::pretty::Arena<'a, ()>, (), ()>,
{
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
use self::Error::*;
Expand Down
4 changes: 2 additions & 2 deletions check/src/typecheck.rs
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ impl<I: fmt::Display + AsRef<str> + Clone> fmt::Display for TypeError<I> {
UndefinedField(ref typ, ref field) => {
let fields = [field.clone()];
let filter = unify_type::similarity_filter(typ, &fields);
let arena = Arena::new();
let arena = Arena::<()>::new();
write!(
f,
"Type `{}` does not have the field `{}`",
Expand Down Expand Up @@ -131,7 +131,7 @@ impl<I: fmt::Display + AsRef<str> + Clone> fmt::Display for TypeError<I> {
}
};

let arena = Arena::new();
let arena = Arena::<()>::new();
let types = chain![&arena;
"Expected:",
chain![&arena;
Expand Down
2 changes: 1 addition & 1 deletion check/src/unify.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ pub enum Error<T, E> {

impl<T, E> fmt::Display for Error<T, E>
where
T: fmt::Display + for<'a> ToDoc<'a, Arena<'a>, ()>,
T: fmt::Display + for<'a> ToDoc<'a, Arena<'a, ()>, (), ()>,
E: fmt::Display,
{
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
Expand Down
2 changes: 1 addition & 1 deletion format/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ pub fn pretty_expr(input: &str, expr: &SpannedExpr<Symbol>) -> String {
};

let source = codespan::FileMap::new("test".into(), input.into());
let arena = pretty::Arena::new();
let arena = pretty::Arena::<()>::new();
let printer = pretty_print::Printer::new(&arena, &source);
printer.format(100, newline, &expr)
}
Expand Down
Loading

0 comments on commit d227c26

Please sign in to comment.