mirror of
https://github.com/roc-lang/roc.git
synced 2025-08-16 18:10:14 +00:00
Merge branch 'main' into inline-imports
This commit is contained in:
commit
d5a38a26db
667 changed files with 22300 additions and 14562 deletions
|
@ -18,10 +18,22 @@ pub struct ModuleDocumentation {
|
|||
pub exposed_symbols: VecSet<Symbol>,
|
||||
}
|
||||
|
||||
impl ModuleDocumentation {
|
||||
pub fn get_doc_for_symbol(&self, symbol_to_match: &Symbol) -> Option<String> {
|
||||
self.entries.iter().find_map(|doc| match doc {
|
||||
DocEntry::DocDef(DocDef { symbol, docs, .. }) if symbol == symbol_to_match => {
|
||||
docs.clone()
|
||||
}
|
||||
_ => None,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum DocEntry {
|
||||
DocDef(DocDef),
|
||||
DetachedDoc(String),
|
||||
ModuleDoc(String),
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
|
@ -174,10 +186,10 @@ fn generate_entry_docs(
|
|||
) -> Vec<DocEntry> {
|
||||
use roc_parse::ast::Pattern;
|
||||
|
||||
let mut acc = Vec::with_capacity(defs.tags.len() + 1);
|
||||
let mut doc_entries = Vec::with_capacity(defs.tags.len() + 1);
|
||||
|
||||
if let Some(docs) = comments_or_new_lines_to_docs(header_comments) {
|
||||
acc.push(DetachedDoc(docs));
|
||||
doc_entries.push(DocEntry::ModuleDoc(docs));
|
||||
}
|
||||
|
||||
let mut before_comments_or_new_lines: Option<&[CommentOrNewline]> = None;
|
||||
|
@ -200,7 +212,11 @@ fn generate_entry_docs(
|
|||
match either_index.split() {
|
||||
Err(value_index) => match &defs.value_defs[value_index.index()] {
|
||||
ValueDef::Annotation(loc_pattern, loc_ann) => {
|
||||
if let Pattern::Identifier(identifier) = loc_pattern.value {
|
||||
if let Pattern::Identifier {
|
||||
ident: identifier,
|
||||
suffixed: _,
|
||||
} = loc_pattern.value
|
||||
{
|
||||
// Check if this module exposes the def
|
||||
if let Some(ident_id) = ident_ids.get_id(identifier) {
|
||||
let name = identifier.to_string();
|
||||
|
@ -211,7 +227,7 @@ fn generate_entry_docs(
|
|||
type_vars: Vec::new(),
|
||||
docs,
|
||||
};
|
||||
acc.push(DocEntry::DocDef(doc_def));
|
||||
doc_entries.push(DocEntry::DocDef(doc_def));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -221,7 +237,11 @@ fn generate_entry_docs(
|
|||
ann_type,
|
||||
..
|
||||
} => {
|
||||
if let Pattern::Identifier(identifier) = ann_pattern.value {
|
||||
if let Pattern::Identifier {
|
||||
ident: identifier,
|
||||
suffixed: _,
|
||||
} = ann_pattern.value
|
||||
{
|
||||
// Check if this module exposes the def
|
||||
if let Some(ident_id) = ident_ids.get_id(identifier) {
|
||||
let doc_def = DocDef {
|
||||
|
@ -231,13 +251,29 @@ fn generate_entry_docs(
|
|||
symbol: Symbol::new(home, ident_id),
|
||||
docs,
|
||||
};
|
||||
acc.push(DocEntry::DocDef(doc_def));
|
||||
doc_entries.push(DocEntry::DocDef(doc_def));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ValueDef::Body(_, _) => {
|
||||
// TODO generate docs for un-annotated bodies
|
||||
ValueDef::Body(pattern, _) => {
|
||||
if let Pattern::Identifier {
|
||||
ident: identifier,
|
||||
suffixed: _,
|
||||
} = pattern.value
|
||||
{
|
||||
// Check if this module exposes the def
|
||||
if let Some(ident_id) = ident_ids.get_id(identifier) {
|
||||
let doc_def = DocDef {
|
||||
name: identifier.to_string(),
|
||||
type_annotation: TypeAnnotation::NoTypeAnn,
|
||||
type_vars: Vec::new(),
|
||||
symbol: Symbol::new(home, ident_id),
|
||||
docs,
|
||||
};
|
||||
doc_entries.push(DocEntry::DocDef(doc_def));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ValueDef::Dbg { .. } => {
|
||||
|
@ -257,7 +293,27 @@ fn generate_entry_docs(
|
|||
ValueDef::IngestedFileImport { .. } => {
|
||||
// Don't generate docs for ingested file imports
|
||||
}
|
||||
|
||||
ValueDef::Stmt(loc_expr) => {
|
||||
if let roc_parse::ast::Expr::Var {
|
||||
ident: identifier, ..
|
||||
} = loc_expr.value
|
||||
{
|
||||
// Check if this module exposes the def
|
||||
if let Some(ident_id) = ident_ids.get_id(identifier) {
|
||||
let doc_def = DocDef {
|
||||
name: identifier.to_string(),
|
||||
type_annotation: TypeAnnotation::NoTypeAnn,
|
||||
type_vars: Vec::new(),
|
||||
symbol: Symbol::new(home, ident_id),
|
||||
docs,
|
||||
};
|
||||
doc_entries.push(DocEntry::DocDef(doc_def));
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
Ok(type_index) => match &defs.type_defs[type_index.index()] {
|
||||
TypeDef::Alias {
|
||||
header: TypeHeader { name, vars },
|
||||
|
@ -266,7 +322,11 @@ fn generate_entry_docs(
|
|||
let mut type_vars = Vec::new();
|
||||
|
||||
for var in vars.iter() {
|
||||
if let Pattern::Identifier(ident_name) = var.value {
|
||||
if let Pattern::Identifier {
|
||||
ident: ident_name,
|
||||
suffixed: _,
|
||||
} = var.value
|
||||
{
|
||||
type_vars.push(ident_name.to_string());
|
||||
}
|
||||
}
|
||||
|
@ -290,7 +350,7 @@ fn generate_entry_docs(
|
|||
docs,
|
||||
symbol: Symbol::new(home, ident_id),
|
||||
};
|
||||
acc.push(DocEntry::DocDef(doc_def));
|
||||
doc_entries.push(DocEntry::DocDef(doc_def));
|
||||
}
|
||||
|
||||
TypeDef::Opaque {
|
||||
|
@ -300,7 +360,11 @@ fn generate_entry_docs(
|
|||
let mut type_vars = Vec::new();
|
||||
|
||||
for var in vars.iter() {
|
||||
if let Pattern::Identifier(ident_name) = var.value {
|
||||
if let Pattern::Identifier {
|
||||
ident: ident_name,
|
||||
suffixed: _,
|
||||
} = var.value
|
||||
{
|
||||
type_vars.push(ident_name.to_string());
|
||||
}
|
||||
}
|
||||
|
@ -313,7 +377,7 @@ fn generate_entry_docs(
|
|||
docs,
|
||||
symbol: Symbol::new(home, ident_id),
|
||||
};
|
||||
acc.push(DocEntry::DocDef(doc_def));
|
||||
doc_entries.push(DocEntry::DocDef(doc_def));
|
||||
}
|
||||
|
||||
TypeDef::Ability {
|
||||
|
@ -324,7 +388,11 @@ fn generate_entry_docs(
|
|||
let mut type_vars = Vec::new();
|
||||
|
||||
for var in vars.iter() {
|
||||
if let Pattern::Identifier(ident_name) = var.value {
|
||||
if let Pattern::Identifier {
|
||||
ident: ident_name,
|
||||
suffixed: _,
|
||||
} = var.value
|
||||
{
|
||||
type_vars.push(ident_name.to_string());
|
||||
}
|
||||
}
|
||||
|
@ -353,7 +421,7 @@ fn generate_entry_docs(
|
|||
type_vars,
|
||||
docs,
|
||||
};
|
||||
acc.push(DocEntry::DocDef(doc_def));
|
||||
doc_entries.push(DocEntry::DocDef(doc_def));
|
||||
}
|
||||
},
|
||||
}
|
||||
|
@ -365,40 +433,49 @@ fn generate_entry_docs(
|
|||
let it = before_comments_or_new_lines.iter().flat_map(|e| e.iter());
|
||||
|
||||
for detached_doc in detached_docs_from_comments_and_new_lines(it) {
|
||||
acc.push(DetachedDoc(detached_doc));
|
||||
doc_entries.push(DetachedDoc(detached_doc));
|
||||
}
|
||||
|
||||
acc
|
||||
doc_entries
|
||||
}
|
||||
|
||||
/// Does this type contain any types which are not exposed outside the package?
|
||||
/// (If so, we shouldn't try to render a type annotation for it.)
|
||||
fn contains_unexposed_type(
|
||||
ann: &ast::TypeAnnotation,
|
||||
type_ann: &ast::TypeAnnotation,
|
||||
exposed_module_ids: &[ModuleId],
|
||||
module_ids: &ModuleIds,
|
||||
) -> bool {
|
||||
use ast::TypeAnnotation::*;
|
||||
|
||||
match ann {
|
||||
match type_ann {
|
||||
// Apply is the one case that can directly return true.
|
||||
Apply(module_name, _ident, loc_args) => {
|
||||
let apply_module_id = module_ids.get_id(&(*module_name).into());
|
||||
let loc_args_contains_unexposed_type = loc_args.iter().any(|loc_arg| {
|
||||
contains_unexposed_type(&loc_arg.value, exposed_module_ids, module_ids)
|
||||
});
|
||||
|
||||
// If the *ident* was unexposed, we would have gotten a naming error
|
||||
// during canonicalization, so all we need to check is the module.
|
||||
let module_id = module_ids.get_id(&(*module_name).into()).unwrap();
|
||||
if let Some(module_id) = apply_module_id {
|
||||
!exposed_module_ids.contains(&module_id) || loc_args_contains_unexposed_type
|
||||
} else {
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
!exposed_module_ids.contains(&module_id)
|
||||
|| loc_args.iter().any(|loc_arg| {
|
||||
contains_unexposed_type(&loc_arg.value, exposed_module_ids, module_ids)
|
||||
})
|
||||
}
|
||||
Malformed(_) | Inferred | Wildcard | BoundVariable(_) => false,
|
||||
|
||||
Function(loc_args, loc_ret) => {
|
||||
let loc_args_contains_unexposed_type = loc_args.iter().any(|loc_arg| {
|
||||
contains_unexposed_type(&loc_arg.value, exposed_module_ids, module_ids)
|
||||
});
|
||||
|
||||
contains_unexposed_type(&loc_ret.value, exposed_module_ids, module_ids)
|
||||
|| loc_args.iter().any(|loc_arg| {
|
||||
contains_unexposed_type(&loc_arg.value, exposed_module_ids, module_ids)
|
||||
})
|
||||
|| loc_args_contains_unexposed_type
|
||||
}
|
||||
|
||||
Record { fields, ext } => {
|
||||
if let Some(loc_ext) = ext {
|
||||
if contains_unexposed_type(&loc_ext.value, exposed_module_ids, module_ids) {
|
||||
|
@ -428,6 +505,7 @@ fn contains_unexposed_type(
|
|||
|
||||
false
|
||||
}
|
||||
|
||||
Tuple { elems: fields, ext } => {
|
||||
if let Some(loc_ext) = ext {
|
||||
if contains_unexposed_type(&loc_ext.value, exposed_module_ids, module_ids) {
|
||||
|
@ -439,6 +517,7 @@ fn contains_unexposed_type(
|
|||
contains_unexposed_type(&loc_field.value, exposed_module_ids, module_ids)
|
||||
})
|
||||
}
|
||||
|
||||
TagUnion { ext, tags } => {
|
||||
use ast::Tag;
|
||||
|
||||
|
@ -474,14 +553,17 @@ fn contains_unexposed_type(
|
|||
|
||||
false
|
||||
}
|
||||
|
||||
Where(loc_ann, _loc_has_clauses) => {
|
||||
// We assume all the abilities in the `implements` clause are from exported modules.
|
||||
// TODO don't assume this! Instead, look them up and verify.
|
||||
contains_unexposed_type(&loc_ann.value, exposed_module_ids, module_ids)
|
||||
}
|
||||
|
||||
As(loc_ann, _spaces, _type_header) => {
|
||||
contains_unexposed_type(&loc_ann.value, exposed_module_ids, module_ids)
|
||||
}
|
||||
|
||||
SpaceBefore(ann, _) | ast::TypeAnnotation::SpaceAfter(ann, _) => {
|
||||
contains_unexposed_type(ann, exposed_module_ids, module_ids)
|
||||
}
|
||||
|
@ -572,7 +654,7 @@ fn type_to_docs(in_func_type_ann: bool, type_annotation: ast::TypeAnnotation) ->
|
|||
.vars
|
||||
.iter()
|
||||
.filter_map(|loc_pattern| match loc_pattern.value {
|
||||
ast::Pattern::Identifier(ident) => Some(ident.to_string()),
|
||||
ast::Pattern::Identifier { ident, suffixed: _ } => Some(ident.to_string()),
|
||||
_ => None,
|
||||
})
|
||||
.collect(),
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue