Include doc comments

This commit is contained in:
Louis Pilfold 2021-11-13 11:35:44 +00:00
parent cd31a73da3
commit a3fbc4d2e6
3 changed files with 89 additions and 21 deletions

View file

@ -1,10 +1,5 @@
use crate::{cli, http::HttpClient};
use gleam_core::{
config::DocsPage,
error::{wrap, Error},
io::HttpClient as _,
paths, Result,
};
use gleam_core::{config::DocsPage, error::Error, io::HttpClient as _, paths, Result};
static TOKEN_NAME: &str = concat!(env!("CARGO_PKG_NAME"), " (", env!("CARGO_PKG_VERSION"), ")");
@ -40,22 +35,14 @@ pub fn remove(package: String, version: String) -> Result<(), Error> {
pub fn build() -> Result<()> {
let config = crate::config::root_config()?;
let compiled = crate::build::main()?;
let mut compiled = crate::build::main()?;
// Attach documentation comments to modules
compiled.attach_doc_and_module_comments();
cli::print_generating_documentation();
let out = paths::build_docs(&config.name);
// Attach documentation to Src modules
// let analysed: Vec<_> = compiled
// .modules
// .into_iter()
// .filter(|a| a.origin == Origin::Src)
// .map(|mut a| {
// a.attach_doc_and_module_comments();
// a
// })
// .collect();
// Initialize pages with the README
let mut pages = vec![DocsPage {
title: "README".to_string(),

View file

@ -26,16 +26,19 @@ pub use self::project_compiler::ProjectCompiler;
pub use self::telemetry::Telemetry;
use crate::{
ast::TypedModule,
ast::{SrcSpan, Statement, TypedModule},
config::{self, PackageConfig},
erlang,
error::{Error, FileIoAction, FileKind},
io::OutputFile,
parse::extra::{Comment, ModuleExtra},
type_,
};
use itertools::Itertools;
use serde::{Deserialize, Serialize};
use std::{collections::HashMap, ffi::OsString, fs::DirEntry, path::PathBuf, process};
use std::{
collections::HashMap, ffi::OsString, fs::DirEntry, iter::Peekable, path::PathBuf, process,
};
use strum::{Display, EnumString, EnumVariantNames, VariantNames};
#[derive(
@ -68,6 +71,14 @@ pub struct Package {
pub modules: Vec<Module>,
}
impl Package {
pub fn attach_doc_and_module_comments(&mut self) {
for mut module in &mut self.modules {
module.attach_doc_and_module_comments();
}
}
}
#[derive(Debug)]
pub struct Module {
pub name: String,
@ -75,6 +86,7 @@ pub struct Module {
pub input_path: PathBuf,
pub origin: Origin,
pub ast: TypedModule,
pub extra: ModuleExtra,
}
impl Module {
@ -83,6 +95,51 @@ impl Module {
path.push_str(".erl");
PathBuf::from(path)
}
pub fn attach_doc_and_module_comments(&mut self) {
// Module Comments
self.ast.documentation = self
.extra
.module_comments
.iter()
.map(|span| {
Comment::from((span, self.code.as_str()))
.content
.to_string()
})
.collect();
// Doc Comments
let mut doc_comments = self.extra.doc_comments.iter().peekable();
for statement in &mut self.ast.statements {
let docs: Vec<&str> =
comments_before(&mut doc_comments, statement.location().start, &self.code);
if !docs.is_empty() {
let doc = docs.join("\n");
statement.put_doc(doc);
}
if let Statement::CustomType { constructors, .. } = statement {
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);
}
}
}
}
}
}
}
#[derive(Debug, Clone, Copy, PartialEq)]
@ -90,3 +147,22 @@ pub enum Origin {
Src,
Test,
}
fn comments_before<'a>(
comment_spans: &mut Peekable<impl Iterator<Item = &'a SrcSpan>>,
byte: usize,
src: &'a str,
) -> Vec<&'a str> {
let mut comments = vec![];
while let Some(SrcSpan { 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

@ -6,6 +6,7 @@ use crate::{
error,
io::{FileSystemIO, FileSystemReader, FileSystemWriter},
metadata::ModuleEncoder,
parse::extra::ModuleExtra,
type_, Error, Result, Warning,
};
use std::path::{Path, PathBuf};
@ -192,6 +193,7 @@ fn type_check(
path,
origin,
package,
extra,
} = parsed_modules
.remove(&name)
.expect("Getting parsed module for name");
@ -227,6 +229,7 @@ fn type_check(
// used for code generation
modules.push(Module {
origin,
extra,
name,
code,
ast,
@ -267,7 +270,7 @@ fn parse_sources(
origin,
} in sources
{
let (mut ast, _) = crate::parse::parse_module(&code).map_err(|error| Error::Parse {
let (mut ast, extra) = crate::parse::parse_module(&code).map_err(|error| Error::Parse {
path: path.clone(),
src: code.clone(),
error,
@ -279,6 +282,7 @@ fn parse_sources(
let module = Parsed {
package: package_name.to_string(),
origin,
extra,
path,
name,
code,
@ -340,4 +344,5 @@ struct Parsed {
origin: Origin,
package: String,
ast: UntypedModule,
extra: ModuleExtra,
}