Merge pull request #4812 from roc-lang/module-header-docs

Module header docs
This commit is contained in:
Richard Feldman 2022-12-28 21:22:53 -05:00 committed by GitHub
commit 6721e731f4
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 102 additions and 73 deletions

View file

@ -1,63 +1,4 @@
interface Str
exposes [
Utf8Problem,
Utf8ByteProblem,
concat,
isEmpty,
joinWith,
split,
repeat,
countGraphemes,
countUtf8Bytes,
startsWithScalar,
toUtf8,
fromUtf8,
fromUtf8Range,
startsWith,
endsWith,
trim,
trimLeft,
trimRight,
toDec,
toF64,
toF32,
toNat,
toU128,
toI128,
toU64,
toI64,
toU32,
toI32,
toU16,
toI16,
toU8,
toI8,
toScalars,
replaceEach,
replaceFirst,
replaceLast,
splitFirst,
splitLast,
walkUtf8WithIndex,
reserve,
appendScalar,
walkScalars,
walkScalarsUntil,
withCapacity,
withPrefix,
graphemes,
]
imports [
Bool.{ Bool, Eq },
Result.{ Result },
List,
Num.{ Nat, Num, U8, U16, U32, U64, U128, I8, I16, I32, I64, I128, F32, F64, Dec },
]
## # Types
##
## Dealing with text is a deep topic, so by design, Roc's `Str` module sticks
## to the basics.
## Working with Unicode strings in Roc.
##
## ### Unicode
##
@ -128,6 +69,63 @@ interface Str
## and you can use it as many times as you like inside a string. The name
## between the parentheses must refer to a `Str` value that is currently in
## scope, and it must be a name - it can't be an arbitrary expression like a function call.
interface Str
exposes [
Utf8Problem,
Utf8ByteProblem,
concat,
isEmpty,
joinWith,
split,
repeat,
countGraphemes,
countUtf8Bytes,
startsWithScalar,
toUtf8,
fromUtf8,
fromUtf8Range,
startsWith,
endsWith,
trim,
trimLeft,
trimRight,
toDec,
toF64,
toF32,
toNat,
toU128,
toI128,
toU64,
toI64,
toU32,
toI32,
toU16,
toI16,
toU8,
toI8,
toScalars,
replaceEach,
replaceFirst,
replaceLast,
splitFirst,
splitLast,
walkUtf8WithIndex,
reserve,
appendScalar,
walkScalars,
walkScalarsUntil,
withCapacity,
withPrefix,
graphemes,
]
imports [
Bool.{ Bool, Eq },
Result.{ Result },
List,
Num.{ Nat, Num, U8, U16, U32, U64, U128, I8, I16, I32, I64, I128, F32, F64, Dec },
]
## Test
Utf8ByteProblem : [
InvalidStartByte,
UnexpectedEndOfSequence,

View file

@ -90,6 +90,7 @@ pub struct Tag {
pub values: Vec<TypeAnnotation>,
}
#[allow(clippy::too_many_arguments)]
pub fn generate_module_docs(
scope: Scope,
home: ModuleId,
@ -98,6 +99,7 @@ pub fn generate_module_docs(
parsed_defs: &roc_parse::ast::Defs,
exposed_module_ids: &[ModuleId],
exposed_symbols: VecSet<Symbol>,
header_comments: &[CommentOrNewline<'_>],
) -> ModuleDocumentation {
let entries = generate_entry_docs(
home,
@ -105,6 +107,7 @@ pub fn generate_module_docs(
module_ids,
parsed_defs,
exposed_module_ids,
header_comments,
);
ModuleDocumentation {
@ -148,10 +151,16 @@ fn generate_entry_docs(
module_ids: &ModuleIds,
defs: &roc_parse::ast::Defs<'_>,
exposed_module_ids: &[ModuleId],
header_comments: &[CommentOrNewline<'_>],
) -> Vec<DocEntry> {
use roc_parse::ast::Pattern;
let mut acc = Vec::with_capacity(defs.tags.len());
let mut acc = Vec::with_capacity(defs.tags.len() + 1);
if let Some(docs) = comments_or_new_lines_to_docs(header_comments) {
acc.push(DetachedDoc(docs));
}
let mut before_comments_or_new_lines: Option<&[CommentOrNewline]> = None;
let mut scratchpad = Vec::new();
@ -208,10 +217,11 @@ fn generate_entry_docs(
}
}
ValueDef::Body(_, _) => (),
ValueDef::Body(_, _) => {
// TODO generate docs for un-annotated bodies
}
ValueDef::Dbg { .. } => {
// Don't generate docs for `dbg`s
}

View file

@ -41,7 +41,9 @@ use roc_mono::layout::{
use roc_packaging::cache::{self, RocCacheDir};
#[cfg(not(target_family = "wasm"))]
use roc_packaging::https::PackageMetadata;
use roc_parse::ast::{self, Defs, ExtractSpaces, Spaced, StrLiteral, TypeAnnotation};
use roc_parse::ast::{
self, CommentOrNewline, Defs, ExtractSpaces, Spaced, StrLiteral, TypeAnnotation,
};
use roc_parse::header::{
ExposedName, ImportsEntry, PackageEntry, PackageHeader, PlatformHeader, To, TypedIdent,
};
@ -683,6 +685,7 @@ struct ModuleHeader<'a> {
exposed_imports: MutMap<Ident, (Symbol, Region)>,
parse_state: roc_parse::state::State<'a>,
header_type: HeaderType<'a>,
header_comments: &'a [CommentOrNewline<'a>],
symbols_from_requires: Vec<(Loc<Symbol>, Loc<TypeAnnotation<'a>>)>,
module_timing: ModuleTiming,
}
@ -824,6 +827,7 @@ struct ParsedModule<'a> {
parsed_defs: Defs<'a>,
symbols_from_requires: Vec<(Loc<Symbol>, Loc<TypeAnnotation<'a>>)>,
header_type: HeaderType<'a>,
header_comments: &'a [CommentOrNewline<'a>],
}
type LocExpects = VecMap<Region, Vec<ExpectLookup>>;
@ -3503,7 +3507,7 @@ fn load_package_from_disk<'a>(
Ok((
ast::Module {
header: ast::Header::Package(header),
..
comments,
},
parser_state,
)) => {
@ -3516,6 +3520,7 @@ fn load_package_from_disk<'a>(
module_ids,
ident_ids_by_module,
&header,
comments,
pkg_module_timing,
);
@ -3524,7 +3529,7 @@ fn load_package_from_disk<'a>(
Ok((
ast::Module {
header: ast::Header::Platform(header),
..
comments,
},
parser_state,
)) => {
@ -3546,6 +3551,7 @@ fn load_package_from_disk<'a>(
exposes_ids.into_bump_slice(),
ident_ids_by_module,
&header,
comments,
pkg_module_timing,
);
@ -3608,7 +3614,7 @@ fn load_builtin_module_help<'a>(
Ok((
ast::Module {
header: ast::Header::Interface(header),
..
comments,
},
parse_state,
)) => {
@ -3623,6 +3629,7 @@ fn load_builtin_module_help<'a>(
exposes: unspace(arena, header.exposes.item.items),
generates_with: &[],
},
module_comments: comments,
};
(info, parse_state)
@ -3907,14 +3914,13 @@ fn parse_header<'a>(
Ok((
ast::Module {
header: ast::Header::Interface(header),
..
comments,
},
parse_state,
)) => {
verify_interface_matches_file_path(header.name, &filename, &parse_state)?;
let header_name_region = header.name.region;
let info = HeaderInfo {
filename,
is_root_module,
@ -3925,6 +3931,7 @@ fn parse_header<'a>(
name: header.name.value,
exposes: unspace(arena, header.exposes.item.items),
},
module_comments: comments,
};
let (module_id, module_name, header) = build_header(
@ -3962,7 +3969,7 @@ fn parse_header<'a>(
Ok((
ast::Module {
header: ast::Header::Hosted(header),
..
comments,
},
parse_state,
)) => {
@ -3978,6 +3985,7 @@ fn parse_header<'a>(
generates: header.generates.item,
generates_with: unspace(arena, header.generates_with.item.items),
},
module_comments: comments,
};
let (module_id, _, header) = build_header(
@ -3997,7 +4005,7 @@ fn parse_header<'a>(
Ok((
ast::Module {
header: ast::Header::App(header),
..
comments,
},
parse_state,
)) => {
@ -4038,6 +4046,7 @@ fn parse_header<'a>(
output_name: header.name.value,
to_platform: header.provides.to.value,
},
module_comments: comments,
};
let (module_id, _, resolved_header) = build_header(
@ -4090,7 +4099,7 @@ fn parse_header<'a>(
Ok((
ast::Module {
header: ast::Header::Package(header),
..
comments,
},
parse_state,
)) => {
@ -4103,6 +4112,7 @@ fn parse_header<'a>(
module_ids,
ident_ids_by_module,
&header,
comments,
module_timing,
);
@ -4116,7 +4126,7 @@ fn parse_header<'a>(
Ok((
ast::Module {
header: ast::Header::Platform(header),
..
comments,
},
parse_state,
)) => {
@ -4137,6 +4147,7 @@ fn parse_header<'a>(
exposes_ids.into_bump_slice(),
ident_ids_by_module,
&header,
comments,
module_timing,
);
@ -4302,6 +4313,7 @@ struct HeaderInfo<'a> {
packages: &'a [Loc<PackageEntry<'a>>],
imports: &'a [Loc<ImportsEntry<'a>>],
header_type: HeaderType<'a>,
module_comments: &'a [CommentOrNewline<'a>],
}
fn build_header<'a>(
@ -4318,6 +4330,7 @@ fn build_header<'a>(
packages,
imports,
header_type,
module_comments: header_comments,
} = info;
let mut imported_modules: MutMap<ModuleId, Region> = MutMap::default();
@ -4633,6 +4646,7 @@ fn build_header<'a>(
exposed_imports: scope,
symbols_from_requires,
header_type,
header_comments,
module_timing,
},
)
@ -5160,6 +5174,7 @@ fn build_package_header<'a>(
module_ids: Arc<Mutex<PackageModuleIds<'a>>>,
ident_ids_by_module: SharedIdentIdsByModule,
header: &PackageHeader<'a>,
comments: &'a [CommentOrNewline<'a>],
module_timing: ModuleTiming,
) -> (ModuleId, PQModuleName<'a>, ModuleHeader<'a>) {
let exposes = bumpalo::collections::Vec::from_iter_in(
@ -5187,6 +5202,7 @@ fn build_package_header<'a>(
packages,
imports: &[],
header_type,
module_comments: comments,
};
build_header(
@ -5208,6 +5224,7 @@ fn build_platform_header<'a>(
exposes_ids: &'a [ModuleId],
ident_ids_by_module: SharedIdentIdsByModule,
header: &PlatformHeader<'a>,
comments: &'a [CommentOrNewline<'a>],
module_timing: ModuleTiming,
) -> (ModuleId, PQModuleName<'a>, ModuleHeader<'a>) {
// If we have an app module, then it's the root module;
@ -5250,6 +5267,7 @@ fn build_platform_header<'a>(
packages: &[],
imports,
header_type,
module_comments: comments,
};
build_header(
@ -5349,6 +5367,7 @@ fn canonicalize_and_constrain<'a>(
&parsed_defs_for_docs,
exposed_module_ids,
module_output.exposed_symbols.clone(),
parsed.header_comments,
);
Some(docs)
@ -5487,6 +5506,7 @@ fn parse<'a>(arena: &'a Bump, header: ModuleHeader<'a>) -> Result<Msg<'a>, Loadi
module_path,
header_type,
symbols_from_requires,
header_comments: header_docs,
..
} = header;
@ -5502,6 +5522,7 @@ fn parse<'a>(arena: &'a Bump, header: ModuleHeader<'a>) -> Result<Msg<'a>, Loadi
parsed_defs,
symbols_from_requires,
header_type,
header_comments: header_docs,
};
Ok(Msg::Parsed(parsed))