diff --git a/Cargo.lock b/Cargo.lock index 0b9b0b0c1c..f0b1a3fe97 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3139,6 +3139,7 @@ dependencies = [ "roc_load", "roc_module", "roc_region", + "roc_types", ] [[package]] diff --git a/compiler/can/src/module.rs b/compiler/can/src/module.rs index 2b45a14f32..345bb0853e 100644 --- a/compiler/can/src/module.rs +++ b/compiler/can/src/module.rs @@ -20,7 +20,7 @@ use roc_types::types::Alias; pub struct Module { pub module_id: ModuleId, pub exposed_imports: MutMap, - pub exposed_symbols: Vec, + pub exposed_symbols: MutSet, pub references: MutSet, pub aliases: MutMap, pub rigid_variables: MutMap, @@ -50,7 +50,7 @@ pub fn canonicalize_module_defs<'a, F>( dep_idents: MutMap, aliases: MutMap, exposed_imports: MutMap, - exposed_symbols: &Vec, + exposed_symbols: &MutSet, var_store: &mut VarStore, look_up_builtin: F, ) -> Result @@ -203,11 +203,7 @@ where // we can see if there were any // exposed symbols which did not have // corresponding defs. - if let Some(index) = - exposed_but_not_defined.iter().position(|s| *s == *symbol) - { - exposed_but_not_defined.remove(index); - } + exposed_but_not_defined.remove(symbol); } } } @@ -220,11 +216,7 @@ where // we can see if there were any // exposed symbols which did not have // corresponding defs. - if let Some(index) = - exposed_but_not_defined.iter().position(|s| *s == *symbol) - { - exposed_but_not_defined.remove(index); - } + exposed_but_not_defined.remove(symbol); } } } @@ -252,9 +244,7 @@ where // we can see if there were any // exposed symbols which did not have // corresponding defs. - if let Some(index) = exposed_but_not_defined.iter().position(|s| *s == symbol) { - exposed_but_not_defined.remove(index); - } + exposed_but_not_defined.remove(&symbol); aliases.insert(symbol, alias); } diff --git a/compiler/load/src/docs.rs b/compiler/load/src/docs.rs index f8dae3f72f..1fa5db439d 100644 --- a/compiler/load/src/docs.rs +++ b/compiler/load/src/docs.rs @@ -123,7 +123,10 @@ fn detached_docs_from_comments_and_new_lines<'a>( } CommentOrNewline::LineComment(_) | CommentOrNewline::Newline => { - detached_docs.push(docs.clone()); + if !docs.is_empty() { + detached_docs.push(docs.clone()); + } + docs = String::new(); } } diff --git a/compiler/load/src/effect_module.rs b/compiler/load/src/effect_module.rs index 81be7ecf60..5dab90a4f8 100644 --- a/compiler/load/src/effect_module.rs +++ b/compiler/load/src/effect_module.rs @@ -48,7 +48,7 @@ pub fn build_effect_builtins( scope: &mut Scope, effect_symbol: Symbol, var_store: &mut VarStore, - exposed_symbols: &mut Vec, + exposed_symbols: &mut MutSet, declarations: &mut Vec, ) { for (_, f) in BUILTIN_EFFECT_FUNCTIONS.iter() { @@ -60,7 +60,7 @@ pub fn build_effect_builtins( var_store, ); - exposed_symbols.push(symbol); + exposed_symbols.insert(symbol); declarations.push(Declaration::Declare(def)); } } diff --git a/compiler/load/src/file.rs b/compiler/load/src/file.rs index 8e9533102f..86965ddc2d 100644 --- a/compiler/load/src/file.rs +++ b/compiler/load/src/file.rs @@ -487,9 +487,7 @@ fn start_phase<'a>( let exposed_symbols = state .exposed_symbols_by_module .remove(&module_id) - .expect("Could not find listener ID in exposed_symbols_by_module") - .into_iter() - .collect::>(); + .expect("Could not find listener ID in exposed_symbols_by_module"); let mut aliases = MutMap::default(); @@ -974,7 +972,7 @@ enum BuildTask<'a> { parsed: ParsedModule<'a>, module_ids: ModuleIds, dep_idents: MutMap, - exposed_symbols: Vec, + exposed_symbols: MutSet, aliases: MutMap, }, Solve { @@ -3503,8 +3501,8 @@ fn fabricate_effects_module<'a>( let mut declarations = Vec::new(); - let exposed_symbols: Vec = { - let mut exposed_symbols = Vec::new(); + let exposed_symbols: MutSet = { + let mut exposed_symbols = MutSet::default(); { for (ident, ann) in effect_entries { @@ -3536,8 +3534,7 @@ fn fabricate_effects_module<'a>( &mut var_store, annotation, ); - - exposed_symbols.push(symbol); + exposed_symbols.insert(symbol); declarations.push(Declaration::Declare(def)); } @@ -3651,7 +3648,7 @@ fn canonicalize_and_constrain<'a, F>( arena: &'a Bump, module_ids: &ModuleIds, dep_idents: MutMap, - exposed_symbols: Vec, + exposed_symbols: MutSet, aliases: MutMap, parsed: ParsedModule<'a>, look_up_builtins: F, diff --git a/docs/Cargo.toml b/docs/Cargo.toml index 2b6c47da05..d57e99ece4 100644 --- a/docs/Cargo.toml +++ b/docs/Cargo.toml @@ -14,6 +14,7 @@ roc_builtins = { path = "../compiler/builtins" } roc_can = { path = "../compiler/can" } roc_module = { path = "../compiler/module" } roc_region = { path = "../compiler/region" } +roc_types = { path = "../compiler/types" } roc_collections = { path = "../compiler/collections" } bumpalo = { version = "3.2", features = ["collections"] } diff --git a/docs/src/lib.rs b/docs/src/lib.rs index 7973bd23dd..facb4644f1 100644 --- a/docs/src/lib.rs +++ b/docs/src/lib.rs @@ -163,9 +163,8 @@ fn render_main_content( } } DocEntry::DetachedDoc(docs) => { - buf.push_str( - markdown_to_html(&mut module.scope, interns, docs.to_string()).as_str(), - ); + let markdown = markdown_to_html(&mut module.scope, interns, docs.to_string()); + buf.push_str(markdown.as_str()); } }; } @@ -526,7 +525,7 @@ fn type_annotation_to_html(indent_level: usize, buf: &mut String, type_ann: &Typ } } -fn insert_doc_links(scope: &mut Scope, interns: &Interns, markdown: String) -> String { +pub fn insert_doc_links(scope: &mut Scope, interns: &Interns, markdown: String) -> String { let buf = &markdown; let mut result = String::new(); @@ -572,7 +571,11 @@ fn insert_doc_links(scope: &mut Scope, interns: &Interns, markdown: String) -> S } } - result + if chomping_from == None { + markdown + } else { + result + } } fn make_doc_link(scope: &mut Scope, interns: &Interns, doc_item: &str) -> String { @@ -619,62 +622,65 @@ fn markdown_to_html(scope: &mut Scope, interns: &Interns, markdown: String) -> S let mut docs_parser = vec![]; let (_, _) = pulldown_cmark::Parser::new_ext(&markdown_with_links, markdown_options).fold( (0, 0), - |(start_quote_count, end_quote_count), event| match event { - // Replace this sequence (`>>>` syntax): - // Start(BlockQuote) - // Start(BlockQuote) - // Start(BlockQuote) - // Start(Paragraph) - // For `Start(CodeBlock(Fenced(Borrowed("roc"))))` - Event::Start(BlockQuote) => { - docs_parser.push(event); - (start_quote_count + 1, 0) - } - Event::Start(Paragraph) => { - if start_quote_count == 3 { - docs_parser.pop(); - docs_parser.pop(); - docs_parser.pop(); - docs_parser.push(Event::Start(CodeBlock(CodeBlockKind::Fenced( - CowStr::Borrowed("roc"), - )))); - } else { + |(start_quote_count, end_quote_count), event| { + match event { + // Replace this sequence (`>>>` syntax): + // Start(BlockQuote) + // Start(BlockQuote) + // Start(BlockQuote) + // Start(Paragraph) + // For `Start(CodeBlock(Fenced(Borrowed("roc"))))` + Event::Start(BlockQuote) => { docs_parser.push(event); + (start_quote_count + 1, 0) } - (0, 0) - } - // Replace this sequence (`>>>` syntax): - // End(Paragraph) - // End(BlockQuote) - // End(BlockQuote) - // End(BlockQuote) - // For `End(CodeBlock(Fenced(Borrowed("roc"))))` - Event::End(Paragraph) => { - docs_parser.push(event); - (0, 1) - } - Event::End(BlockQuote) => { - if end_quote_count == 3 { - docs_parser.pop(); - docs_parser.pop(); - docs_parser.pop(); - docs_parser.push(Event::End(CodeBlock(CodeBlockKind::Fenced( - CowStr::Borrowed("roc"), - )))); + Event::Start(Paragraph) => { + if start_quote_count == 3 { + docs_parser.pop(); + docs_parser.pop(); + docs_parser.pop(); + docs_parser.push(Event::Start(CodeBlock(CodeBlockKind::Fenced( + CowStr::Borrowed("roc"), + )))); + } else { + docs_parser.push(event); + } + (0, 0) + } + // Replace this sequence (`>>>` syntax): + // End(Paragraph) + // End(BlockQuote) + // End(BlockQuote) + // End(BlockQuote) + // For `End(CodeBlock(Fenced(Borrowed("roc"))))` + Event::End(Paragraph) => { + docs_parser.push(event); + (0, 1) + } + Event::End(BlockQuote) => { + if end_quote_count == 3 { + docs_parser.pop(); + docs_parser.pop(); + docs_parser.pop(); + docs_parser.push(Event::End(CodeBlock(CodeBlockKind::Fenced( + CowStr::Borrowed("roc"), + )))); + (0, 0) + } else { + docs_parser.push(event); + (0, end_quote_count + 1) + } + } + _ => { + docs_parser.push(event); (0, 0) - } else { - docs_parser.push(event); - (0, end_quote_count + 1) } - } - _ => { - docs_parser.push(event); - (0, 0) } }, ); let mut docs_html = String::new(); + pulldown_cmark::html::push_html(&mut docs_html, docs_parser.into_iter()); docs_html diff --git a/docs/tests/insert_links.rs b/docs/tests/insert_links.rs new file mode 100644 index 0000000000..e01e3eca5b --- /dev/null +++ b/docs/tests/insert_links.rs @@ -0,0 +1,43 @@ +#[macro_use] +extern crate pretty_assertions; + +#[cfg(test)] +mod insert_doc_links { + use roc_can::env::Env; + use roc_can::scope::Scope; + use roc_collections::all::MutMap; + use roc_docs::insert_doc_links; + use roc_module::symbol::{IdentIds, Interns, ModuleIds}; + use roc_types::subs::VarStore; + + #[test] + fn no_doc_links() { + let home = ModuleIds::default().get_or_insert(&"Test".into()); + + let module_ids = ModuleIds::default(); + + let dep_idents = IdentIds::exposed_builtins(0); + + let env = Env::new(home, dep_idents, &module_ids, IdentIds::default()); + + let all_ident_ids = MutMap::default(); + + let interns = Interns { + module_ids: env.module_ids.clone(), + all_ident_ids, + }; + + let var_store = &mut VarStore::default(); + let scope = &mut Scope::new(home, var_store); + + let markdown = r#" + # Hello + Hello thanks for using my package + "#; + + assert_eq!( + markdown, + insert_doc_links(scope, &interns, markdown.to_string()), + ); + } +}