Implement modules' extra, to get function & module comments in docs.

This commit is contained in:
KtorZ 2022-12-16 23:07:08 +01:00
parent 536c9457b3
commit 873bd85d8b
No known key found for this signature in database
GPG Key ID: 33173CB6F77F4277
5 changed files with 95 additions and 10 deletions

View File

@ -356,6 +356,12 @@ pub struct RecordConstructor<T> {
pub sugar: bool, pub sugar: bool,
} }
impl<A> RecordConstructor<A> {
pub fn put_doc(&mut self, new_doc: String) {
self.doc = Some(new_doc);
}
}
#[derive(Debug, Clone, PartialEq)] #[derive(Debug, Clone, PartialEq)]
pub struct RecordConstructorArg<T> { pub struct RecordConstructorArg<T> {
pub label: Option<String>, pub label: Option<String>,
@ -366,6 +372,12 @@ pub struct RecordConstructorArg<T> {
pub doc: Option<String>, pub doc: Option<String>,
} }
impl<T: PartialEq> RecordConstructorArg<T> {
pub fn put_doc(&mut self, new_doc: String) {
self.doc = Some(new_doc);
}
}
pub type TypedArg = Arg<Arc<Type>>; pub type TypedArg = Arg<Arc<Type>>;
pub type UntypedArg = Arg<()>; pub type UntypedArg = Arg<()>;

View File

@ -33,22 +33,18 @@ pub fn module(
let tokens = tokens.into_iter().filter(|(token, span)| match token { let tokens = tokens.into_iter().filter(|(token, span)| match token {
Token::ModuleComment => { Token::ModuleComment => {
extra.module_comments.push(*span); extra.module_comments.push(*span);
false false
} }
Token::DocComment => { Token::DocComment => {
extra.doc_comments.push(*span); extra.doc_comments.push(*span);
false false
} }
Token::Comment => { Token::Comment => {
extra.comments.push(*span); extra.comments.push(*span);
false false
} }
Token::EmptyLine => { Token::EmptyLine => {
extra.empty_lines.push(span.start); extra.empty_lines.push(span.start);
false false
} }
Token::NewLine => false, Token::NewLine => false,

View File

@ -1,4 +1,5 @@
use crate::ast::Span; use crate::ast::Span;
use std::iter::Peekable;
#[derive(Debug, PartialEq, Eq, Default, Clone)] #[derive(Debug, PartialEq, Eq, Default, Clone)]
pub struct ModuleExtra { pub struct ModuleExtra {
@ -33,3 +34,22 @@ impl<'a> From<(&Span, &'a str)> for Comment<'a> {
} }
} }
} }
pub fn comments_before<'a>(
comment_spans: &mut Peekable<impl Iterator<Item = &'a Span>>,
byte: usize,
src: &'a str,
) -> Vec<&'a str> {
let mut comments = vec![];
while let Some(Span { start, .. }) = comment_spans.peek() {
if start <= &byte {
let comment = comment_spans
.next()
.expect("Comment before accessing next span");
comments.push(Comment::from((comment, src)).content)
} else {
break;
}
}
comments
}

View File

@ -108,7 +108,10 @@ where
self.read_source_files()?; self.read_source_files()?;
let destination = destination.unwrap_or(self.root.join("doc")); let destination = destination.unwrap_or(self.root.join("doc"));
let parsed_modules = self.parse_sources()?; let mut parsed_modules = self.parse_sources()?;
for (_, module) in parsed_modules.iter_mut() {
module.attach_doc_and_module_comments();
}
let checked_modules = self.type_check(parsed_modules)?; let checked_modules = self.type_check(parsed_modules)?;
self.event_listener.handle_event(Event::GeneratingDocFiles { self.event_listener.handle_event(Event::GeneratingDocFiles {
output_path: destination.clone(), output_path: destination.clone(),
@ -229,7 +232,7 @@ where
} in self.sources.drain(0..) } in self.sources.drain(0..)
{ {
match aiken_lang::parser::module(&code, kind) { match aiken_lang::parser::module(&code, kind) {
Ok((mut ast, _)) => { Ok((mut ast, extra)) => {
// Store the name // Store the name
ast.name = name.clone(); ast.name = name.clone();
@ -239,6 +242,7 @@ where
code, code,
name, name,
path, path,
extra,
package: self.config.name.clone(), package: self.config.name.clone(),
}; };
@ -286,6 +290,7 @@ where
path, path,
code, code,
kind, kind,
extra,
// TODO: come back and figure out where to use this // TODO: come back and figure out where to use this
package: _package, package: _package,
ast, ast,
@ -324,7 +329,7 @@ where
name.clone(), name.clone(),
CheckedModule { CheckedModule {
kind, kind,
// extra, extra,
name, name,
code, code,
ast, ast,

View File

@ -4,7 +4,10 @@ use std::{
path::PathBuf, path::PathBuf,
}; };
use aiken_lang::ast::{Definition, ModuleKind, TypedModule, UntypedModule}; use aiken_lang::{
ast::{DataType, Definition, ModuleKind, TypedModule, UntypedModule},
parser::extra::{comments_before, Comment, ModuleExtra},
};
use petgraph::{algo, graph::NodeIndex, Direction, Graph}; use petgraph::{algo, graph::NodeIndex, Direction, Graph};
use crate::error::Error; use crate::error::Error;
@ -17,7 +20,7 @@ pub struct ParsedModule {
pub kind: ModuleKind, pub kind: ModuleKind,
pub package: String, pub package: String,
pub ast: UntypedModule, pub ast: UntypedModule,
// extra: ModuleExtra, pub extra: ModuleExtra,
} }
impl ParsedModule { impl ParsedModule {
@ -33,6 +36,55 @@ impl ParsedModule {
(name, deps) (name, deps)
} }
pub fn attach_doc_and_module_comments(&mut self) {
// Module Comments
self.ast.docs = self
.extra
.module_comments
.iter()
.map(|span| {
Comment::from((span, self.code.as_str()))
.content
.to_string()
})
.collect();
// Order definitions to avoid dissociating doc comments from them
let mut definitions: Vec<_> = self.ast.definitions.iter_mut().collect();
definitions.sort_by(|a, b| a.location().start.cmp(&b.location().start));
// Doc Comments
let mut doc_comments = self.extra.doc_comments.iter().peekable();
for def in &mut definitions {
let docs: Vec<&str> =
comments_before(&mut doc_comments, def.location().start, &self.code);
if !docs.is_empty() {
let doc = docs.join("\n");
def.put_doc(doc);
}
if let Definition::DataType(DataType { constructors, .. }) = def {
for constructor in constructors {
let docs: Vec<&str> =
comments_before(&mut doc_comments, constructor.location.start, &self.code);
if !docs.is_empty() {
let doc = docs.join("\n");
constructor.put_doc(doc);
}
for argument in constructor.arguments.iter_mut() {
let docs: Vec<&str> =
comments_before(&mut doc_comments, argument.location.start, &self.code);
if !docs.is_empty() {
let doc = docs.join("\n");
argument.put_doc(doc);
}
}
}
}
}
}
} }
pub struct ParsedModules(HashMap<String, ParsedModule>); pub struct ParsedModules(HashMap<String, ParsedModule>);
@ -168,7 +220,7 @@ pub struct CheckedModule {
pub input_path: PathBuf, pub input_path: PathBuf,
pub kind: ModuleKind, pub kind: ModuleKind,
pub ast: TypedModule, pub ast: TypedModule,
// pub extra: ModuleExtra, pub extra: ModuleExtra,
} }
impl CheckedModule { impl CheckedModule {