Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
789: Flesh out the std lib docs more r=Marwes a=Marwes



Co-authored-by: Markus Westerlind <marwes91@gmail.com>
  • Loading branch information
bors[bot] and Marwes authored Oct 7, 2019
2 parents 24ca105 + 3857668 commit 3a5ef58
Show file tree
Hide file tree
Showing 37 changed files with 217 additions and 87 deletions.
34 changes: 21 additions & 13 deletions base/src/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ impl<'a, T: ?Sized + IdentEnv> IdentEnv for &'a mut T {

#[derive(Clone, Eq, PartialEq, Debug)]
struct InnerAstType<Id> {
comment: Option<Comment>,
metadata: Option<Metadata>,
typ: Spanned<Type<Id, AstType<Id>>, BytePos>,
}

Expand Down Expand Up @@ -101,7 +101,10 @@ impl<Id: AsRef<str>> fmt::Display for AstType<Id> {
impl<Id> From<Spanned<Type<Id, AstType<Id>>, BytePos>> for AstType<Id> {
fn from(typ: Spanned<Type<Id, AstType<Id>>, BytePos>) -> Self {
AstType {
_typ: Box::new(InnerAstType { comment: None, typ }),
_typ: Box::new(InnerAstType {
metadata: None,
typ,
}),
}
}
}
Expand Down Expand Up @@ -139,34 +142,39 @@ where
}
}

pub trait Commented {
fn comment(&self) -> Option<&Comment>;
}
pub trait HasMetadata {
fn metadata(&self) -> Option<&Metadata>;

impl<Id> Commented for AstType<Id> {
fn comment(&self) -> Option<&Comment> {
self._typ.comment.as_ref()
self.metadata()
.and_then(|metadata| metadata.comment.as_ref())
}
}

impl<Id> HasMetadata for AstType<Id> {
fn metadata(&self) -> Option<&Metadata> {
self._typ.metadata.as_ref()
}
}

impl<Id> AstType<Id> {
pub fn with_comment<T>(comment: T, typ: Spanned<Type<Id, AstType<Id>>, BytePos>) -> Self
pub fn with_metadata<T>(metadata: T, typ: Spanned<Type<Id, AstType<Id>>, BytePos>) -> Self
where
T: Into<Option<Comment>>,
T: Into<Option<Metadata>>,
{
AstType {
_typ: Box::new(InnerAstType {
comment: comment.into(),
metadata: metadata.into(),
typ,
}),
}
}

pub fn set_comment<T>(&mut self, comment: T)
pub fn set_metadata<T>(&mut self, metadata: T)
where
T: Into<Option<Comment>>,
T: Into<Option<Metadata>>,
{
self._typ.comment = comment.into();
self._typ.metadata = metadata.into();
}

pub fn into_inner(self) -> Type<Id, Self> {
Expand Down
12 changes: 11 additions & 1 deletion base/src/metadata.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use std::{collections::BTreeMap, sync::Arc};
use std::{collections::BTreeMap, fmt, sync::Arc};

use crate::{
ast::Argument,
Expand Down Expand Up @@ -42,6 +42,16 @@ pub struct Attribute {
pub arguments: Option<String>,
}

impl fmt::Display for Attribute {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "#[{}", self.name)?;
if let Some(arguments) = &self.arguments {
write!(f, "({})", arguments)?;
}
write!(f, "]")
}
}

#[derive(Clone, Debug, Default, Eq, PartialEq, Hash)]
#[cfg_attr(feature = "serde_derive", derive(Deserialize, Serialize))]
pub struct Metadata {
Expand Down
14 changes: 7 additions & 7 deletions base/src/types/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,11 @@ use smallvec::SmallVec;
use itertools::Itertools;

use crate::{
ast::{Commented, EmptyEnv, IdentEnv},
ast::{EmptyEnv, HasMetadata, IdentEnv},
fnv::FnvMap,
kind::{ArcKind, Kind, KindCache, KindEnv},
merge::{merge, merge_collect},
metadata::Comment,
metadata::Metadata,
pos::{BytePos, HasSpan, Span},
source::Source,
symbol::{Name, Symbol, SymbolRef},
Expand Down Expand Up @@ -1434,8 +1434,8 @@ impl<Id> HasSpan for ArcType<Id> {
}
}

impl<Id> Commented for ArcType<Id> {
fn comment(&self) -> Option<&Comment> {
impl<Id> HasMetadata for ArcType<Id> {
fn metadata(&self) -> Option<&Metadata> {
None
}
}
Expand Down Expand Up @@ -1598,7 +1598,7 @@ pub trait TypeExt: Deref<Target = Type<<Self as TypeExt>::Id, Self>> + Clone + S
where
Self::Id: AsRef<str> + 'a,
A: Clone,
Self: Commented + HasSpan,
Self: HasMetadata + HasSpan,
{
top(self).pretty(&Printer::new(arena, &()))
}
Expand Down Expand Up @@ -2312,7 +2312,7 @@ const INDENT: usize = 4;

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

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

use crate::ast::{is_operator_char, Commented};
use crate::ast::{is_operator_char, HasMetadata};
use crate::metadata::{Comment, CommentType};
use crate::pos::{BytePos, HasSpan, Span};
use crate::source::Source;
Expand Down Expand Up @@ -129,7 +129,7 @@ impl<'a, I, T, A> TypeFormatter<'a, I, T, A> {

pub fn pretty(&self, arena: &'a Arena<'a, A>) -> DocBuilder<'a, Arena<'a, A>, A>
where
T: Deref<Target = Type<I, T>> + HasSpan + Commented + 'a,
T: Deref<Target = Type<I, T>> + HasSpan + HasMetadata + 'a,
I: AsRef<str>,
A: Clone,
{
Expand All @@ -156,7 +156,7 @@ impl<'a, I, T, A> TypeFormatter<'a, I, T, A> {

impl<'a, I, T> fmt::Display for TypeFormatter<'a, I, T, ()>
where
T: Deref<Target = Type<I, T>> + HasSpan + Commented + 'a,
T: Deref<Target = Type<I, T>> + HasSpan + HasMetadata + 'a,
I: AsRef<str>,
{
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
Expand Down
12 changes: 6 additions & 6 deletions check/src/metadata.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use std::{collections::BTreeMap, sync::Arc};

use crate::base::ast::Visitor;
use crate::base::ast::{
self, Argument, AstType, Commented, Expr, Pattern, SpannedExpr, SpannedPattern, ValueBinding,
self, Argument, AstType, Expr, HasMetadata, Pattern, SpannedExpr, SpannedPattern, ValueBinding,
};
use crate::base::fnv::FnvMap;
use crate::base::metadata::{Metadata, MetadataEnv};
Expand Down Expand Up @@ -199,7 +199,7 @@ pub fn metadata(
}
for field in types {
if let Some(m) = metadata.get_module(field.name.value.as_ref()) {
// FIXME Shouldn't need to insert this metadata twice
// TODO Shouldn't need to insert this metadata twice
if let Some(type_field) = typ
.type_field_iter()
.find(|type_field| type_field.name.name_eq(&field.name.value))
Expand Down Expand Up @@ -356,7 +356,7 @@ pub fn metadata(
);

if metadata.has_data() {
// FIXME Shouldn't need to insert this metadata twice
// TODO Shouldn't need to insert this metadata twice
self.stack_var(bind.alias.value.name.clone(), metadata.clone());
self.stack_var(bind.name.value.clone(), metadata);
}
Expand All @@ -383,10 +383,10 @@ pub fn metadata(
let module: BTreeMap<_, _> = row_iter(typ)
.filter_map(|field| {
let field_metadata = Self::metadata_of_type(&field.typ);
let field_metadata = match field.typ.comment() {
Some(comment) => {
let field_metadata = match field.typ.metadata() {
Some(other_metadata) => {
let mut metadata = field_metadata.unwrap_or_default();
metadata.comment = Some(comment.clone());
metadata.merge_with_ref(other_metadata);
Some(metadata)
}
None => field_metadata,
Expand Down
4 changes: 2 additions & 2 deletions check/src/typecheck/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ where
I: fmt::Display + AsRef<str> + Clone,
T: TypeExt<Id = I>
+ fmt::Display
+ ast::Commented
+ ast::HasMetadata
+ pos::HasSpan
+ for<'a> ToDoc<'a, Arena<'a, ()>, (), ()>,
{
Expand Down Expand Up @@ -217,7 +217,7 @@ where
I: fmt::Display + AsRef<str> + Clone,
T: TypeExt<Id = I>
+ fmt::Display
+ ast::Commented
+ ast::HasMetadata
+ pos::HasSpan
+ for<'a> ToDoc<'a, Arena<'a, ()>, (), ()>,
{
Expand Down
4 changes: 2 additions & 2 deletions check/src/unify_type.rs
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ impl<T> From<ResolveError> for TypeError<Symbol, T> {
impl<I, T> fmt::Display for TypeError<I, T>
where
I: fmt::Display + AsRef<str>,
T: TypeExt<Id = I> + ast::Commented + pos::HasSpan,
T: TypeExt<Id = I> + ast::HasMetadata + pos::HasSpan,
{
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let filter = self.make_filter();
Expand Down Expand Up @@ -176,7 +176,7 @@ where
impl<I, T> TypeError<I, T>
where
I: fmt::Display + AsRef<str>,
T: TypeExt<Id = I> + ast::Commented + pos::HasSpan,
T: TypeExt<Id = I> + ast::HasMetadata + pos::HasSpan,
{
pub fn make_filter<'a>(&'a self) -> Box<dyn Fn(&I) -> Filter + 'a> {
match *self {
Expand Down
36 changes: 35 additions & 1 deletion check/tests/metadata.rs
Original file line number Diff line number Diff line change
Expand Up @@ -337,7 +337,7 @@ let x ?test : [Test a] -> a = test.x
}

#[test]
fn propagate_metadata_through_implicits() {
fn propagate_metadata_through_implicits1() {
let _ = env_logger::try_init();

let text = r#"
Expand Down Expand Up @@ -369,3 +369,37 @@ let x ?test : [Test a] -> Test (Wrap a) = { x = Wrap test.x }
})
);
}

#[test]
fn propagate_metadata_through_implicits2() {
let _ = env_logger::try_init();

let text = r#"
type Test a = {
#[attribute]
x : a,
}
type Wrap a = | Wrap a
let x ?test : [Test a] -> a = test.x
{ x }
"#;
let (mut expr, result) = support::typecheck_expr(text);

assert!(result.is_ok(), "{}", result.unwrap_err());

let metadata = metadata(&MockEnv, &mut expr);
assert_eq!(
metadata.module.get("x").map(|m| &**m),
Some(&Metadata {
definition: metadata.module.get("x").and_then(|m| m.definition.clone()),
attributes: vec![Attribute {
name: "attribute".into(),
arguments: None,
}],
args: vec![Argument::implicit(intern("test@9_8"))],
..Metadata::default()
})
);
}
4 changes: 2 additions & 2 deletions doc/src/doc/module.html
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ <h2 class="pb-3 mb-4 border-bottom"><a class="anchor field" id="Types" href="#Ty
<div class="row">
<div class="col-md-10">
<h4>
<pre>type <a id="type.{{name}}" href="#type.{{name}}">{{name}}</a>{{#each args}} {{name}}{{/each}} = {{{type~}}}
<pre>{{attributes}}type <a id="type.{{name}}" href="#type.{{name}}">{{name}}</a>{{#each args}} {{name}}{{/each}} = {{{type~}}}
</pre>
</h4>
</div>
Expand All @@ -88,7 +88,7 @@ <h2 class="pb-3 mb-4 border-bottom"><a class="anchor field" id="Values" href="#V
<div class="row">
<div class="col-md-10">
<h4>
<pre>let <a class="anchor field" id="value.{{name}}" href="#value.{{name}}">{{name}}</a>
<pre>{{attributes}}let <a class="anchor field" id="value.{{name}}" href="#value.{{name}}">{{name}}</a>
{{~#each args~}}
{{~#if implicit}} ?{{name}}{{else}} {{name}}{{~/if~}}
{{~/each}} : {{{type~}}}
Expand Down
15 changes: 15 additions & 0 deletions doc/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ pub struct Field {
pub args: Vec<Argument>,
#[serde(rename = "type")]
pub typ: String,
pub attributes: String,
pub comment: String,
pub definition_line: Option<u32>,
}
Expand Down Expand Up @@ -168,11 +169,16 @@ pub fn record(
.type_field_iter()
.filter(|field| !hidden(meta, field.name.as_ref()))
.map(|field| {
let attributes;
let comment;
let definition_line;

match meta.module.get(AsRef::<str>::as_ref(&field.name)) {
Some(meta) => {
attributes = meta
.attributes()
.format_with("", |x, f| f(&format_args!("{}\n", x)))
.to_string();
comment = meta
.comment
.as_ref()
Expand All @@ -182,6 +188,7 @@ pub fn record(
definition_line = None; // FIXME line_number(meta);
}
None => {
attributes = "".to_string();
comment = "".to_string();
definition_line = None;
}
Expand All @@ -199,6 +206,7 @@ pub fn record(
})
.collect(),
typ: print_type(current_module, &field.typ.unresolved_type().remove_forall()),
attributes,
comment,
definition_line,
}
Expand All @@ -210,11 +218,16 @@ pub fn record(
.filter(|field| !hidden(meta, field.name.as_ref()))
.map(|field| {
let args;
let attributes;
let comment;
let definition_line;

match meta.module.get(AsRef::<str>::as_ref(&field.name)) {
Some(meta) => {
attributes = meta
.attributes()
.format_with("", |x, f| f(&format_args!("{}\n", x)))
.to_string();
args = meta
.args
.iter()
Expand All @@ -233,6 +246,7 @@ pub fn record(
}
_ => {
args = Vec::new();
attributes = "".to_string();
comment = "".to_string();
definition_line = None;
}
Expand All @@ -242,6 +256,7 @@ pub fn record(
name: field.name.definition_name().to_string(),
args,
typ: print_type(current_module, &field.typ),
attributes,
comment,
definition_line,
}
Expand Down
1 change: 1 addition & 0 deletions doc/tests/doc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ let test x = x
name: "x".to_string(),
}],
typ: handlebars::html_escape("forall a . a -> a"),
attributes: "".to_string(),
comment: "This is the test function".to_string(),
definition_line: None,
}],
Expand Down
Loading

0 comments on commit 3a5ef58

Please sign in to comment.