From 2290bf30072c50ac692798b864f78b20e64c7d69 Mon Sep 17 00:00:00 2001 From: hdwalters Date: Mon, 23 Sep 2024 09:56:18 +0100 Subject: [PATCH] Sort functions by name in documentation (#470) * Minor refactoring. * Use absolute or relative output directory for documentation. * Sort functions by name. * Fix Clippy compiler error. * Rename and refactor docs item name function. --- src/compiler.rs | 39 +++++++++++++++-------------------- src/modules/block.rs | 14 +++++++++++-- src/modules/statement/stmt.rs | 7 +++++++ 3 files changed, 36 insertions(+), 24 deletions(-) diff --git a/src/compiler.rs b/src/compiler.rs index 2e81d40e..9520c10b 100644 --- a/src/compiler.rs +++ b/src/compiler.rs @@ -128,10 +128,7 @@ impl AmberCompiler { meta: &ParserMetadata, ) -> Vec<(String, Block)> { let imports_sorted = meta.import_cache.topological_sort(); - let imports_blocks = meta - .import_cache - .files - .iter() + let imports_blocks = meta.import_cache.files.iter() .map(|file| { file.metadata .as_ref() @@ -186,32 +183,29 @@ impl AmberCompiler { } pub fn document(&self, block: Block, meta: ParserMetadata, output: String) { - let base_path = PathBuf::from( - meta.get_path() - .expect("Input file must exist in docs generation"), - ); + let base_path = meta.get_path() + .map(PathBuf::from) + .expect("Input file must exist in docs generation"); let base_dir = fs::canonicalize(base_path).map(|val| { val.parent() .expect("Parent dir must exist in docs generation") .to_owned() .clone() }); - if let Err(err) = base_dir { + let base_dir = base_dir.unwrap_or_else(|err| { Message::new_err_msg("Couldn't get the absolute path to the provided input file") .comment(err.to_string()) .show(); std::process::exit(1); - } - let base_dir = base_dir.unwrap(); + }); let ast_forest = self.get_sorted_ast_forest(block, &meta); let mut paths = vec![]; for (path, block) in ast_forest { let dep_path = { - let dep_path = fs::canonicalize(PathBuf::from(path.clone())); - if dep_path.is_err() { - continue; - } - let dep_path = dep_path.unwrap(); + let dep_path = match fs::canonicalize(PathBuf::from(path)) { + Ok(path) => path, + Err(_) => continue, + }; if !dep_path.starts_with(&base_dir) { continue; @@ -220,22 +214,23 @@ impl AmberCompiler { dep_path }; let document = block.document(&meta); - // Save to file + // Save to file; replace the base directory if the output + // path is absolute, otherwise append the output path. let dir_path = { - let file_dir = dep_path.strip_prefix(&base_dir).unwrap(); - let parent = file_dir.parent().unwrap().display(); - format!("{}/{output}/{}", base_dir.to_string_lossy(), parent) + let file_path = dep_path.strip_prefix(&base_dir).unwrap(); + let file_dir = file_path.parent().unwrap(); + base_dir.join(&output).join(file_dir) }; if let Err(err) = fs::create_dir_all(dir_path.clone()) { Message::new_err_msg(format!( - "Couldn't create directory `{dir_path}`. Do you have sufficient permissions?" + "Couldn't create directory `{}`. Do you have sufficient permissions?", dir_path.display() )) .comment(err.to_string()) .show(); std::process::exit(1); } let filename = dep_path.file_stem().unwrap().to_string_lossy(); - let path = PathBuf::from(dir_path).join(format!("{filename}.md")); + let path = dir_path.join(format!("{filename}.md")); let mut file = File::create(path.clone()).unwrap(); file.write_all(document.as_bytes()).unwrap(); paths.push(String::from(path.to_string_lossy())); diff --git a/src/modules/block.rs b/src/modules/block.rs index 1dd52a3b..b414ff35 100644 --- a/src/modules/block.rs +++ b/src/modules/block.rs @@ -1,6 +1,8 @@ use std::collections::VecDeque; +use std::ops::Index; use heraclitus_compiler::prelude::*; +use itertools::Itertools; use crate::docs::module::DocumentationModule; use crate::utils::{metadata::ParserMetadata, TranslateMetadata}; use crate::translate::module::TranslateModule; @@ -82,8 +84,16 @@ impl TranslateModule for Block { impl DocumentationModule for Block { fn document(&self, meta: &ParserMetadata) -> String { - self.statements.iter() + let indices = self.statements.iter() + .enumerate() + .map(|(index, statement)| (index, statement.get_docs_item_name())) + .filter_map(|(index, name)| name.map(|n| (n, index))) + .sorted() + .collect::>(); + indices.iter() + .map(|(_, index)| self.statements.index(*index)) .map(|statement| statement.document(meta)) - .collect::>().join("") + .collect::>() + .join("") } } diff --git a/src/modules/statement/stmt.rs b/src/modules/statement/stmt.rs index 3334f71b..fa8a7aa0 100644 --- a/src/modules/statement/stmt.rs +++ b/src/modules/statement/stmt.rs @@ -114,6 +114,13 @@ impl Statement { Err(details) => Err(details) } } + + pub fn get_docs_item_name(&self) -> Option { + match &self.value { + Some(StatementType::FunctionDeclaration(inner)) => Some(inner.name.clone()), + _ => None, + } + } } impl SyntaxModule for Statement {