From 7dc6501ec0eb67e7b3693add390b1d90ef3a195b Mon Sep 17 00:00:00 2001 From: Piotr Magiera Date: Wed, 26 Jun 2024 18:24:02 +0200 Subject: [PATCH] members of structs --- Cargo.toml | 2 +- extensions/scarb-doc/src/types.rs | 56 +++++++++++++++++++++++++++--- extensions/scarb-doc/tests/test.rs | 7 ++++ 3 files changed, 60 insertions(+), 5 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index b146271ef..16eeb616b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -136,7 +136,7 @@ zip = { version = "0.6", default-features = false, features = ["deflate"] } zstd = "0.13" [profile.release] -lto = true +#lto = true [profile.ci] inherits = "test" diff --git a/extensions/scarb-doc/src/types.rs b/extensions/scarb-doc/src/types.rs index 4fe12899a..c0e214251 100644 --- a/extensions/scarb-doc/src/types.rs +++ b/extensions/scarb-doc/src/types.rs @@ -3,15 +3,18 @@ use cairo_lang_compiler::db::RootDatabase; use cairo_lang_defs::db::DefsGroup; +use cairo_lang_defs::diagnostic_utils::StableLocation; use cairo_lang_defs::ids::{ ConstantId, EnumId, ExternFunctionId, ExternTypeId, FreeFunctionId, ImplAliasId, - ImplConstantDefId, ImplDefId, ImplFunctionId, ImplItemId, ImplTypeDefId, LookupItemId, - MemberId, ModuleId, ModuleItemId, ModuleTypeAliasId, StructId, TopLevelLanguageElementId, - TraitConstantId, TraitFunctionId, TraitId, TraitItemId, TraitTypeId, UseId, VariantId, + ImplConstantDefId, ImplDefId, ImplFunctionId, ImplItemId, ImplTypeDefId, LanguageElementId, + LookupItemId, MemberId, ModuleId, ModuleItemId, ModuleTypeAliasId, StructId, + TopLevelLanguageElementId, TraitConstantId, TraitFunctionId, TraitId, TraitItemId, TraitTypeId, + UseId, VariantId, }; use cairo_lang_filesystem::ids::CrateId; use cairo_lang_semantic::db::SemanticGroup; use cairo_lang_syntax::node::{ast, TypedStablePtr, TypedSyntaxNode}; +use itertools::Itertools; #[derive(Clone, Debug)] pub struct Crate { @@ -264,6 +267,16 @@ pub struct Struct { impl Struct { pub fn new(db: &RootDatabase, id: StructId) -> Self { let members = db.struct_members(id).unwrap(); + let members_stable_locations = members + .iter() + .map(|(_, member)| member.id.stable_location(db)) + .collect_vec(); + + let members_docs = members_stable_locations + .iter() + .map(|x| get_item_documentation(db, x)) + .collect_vec(); + let members = members .iter() .map(|(_name, semantic_member)| Member::new(db, semantic_member.id)) @@ -290,7 +303,7 @@ pub struct Member { pub item_data: ItemData, // TODO: no LookupItemId enum variant for struct / enum items - // pub lookup_item_data: LookupItemData, + pub lookup_item_data: LookupItemData, } impl Member { @@ -300,6 +313,7 @@ impl Member { id, node, item_data: ItemData::new(db, id, node), + lookup_item_data: LookupItemData {}, } } } @@ -692,3 +706,37 @@ impl ExternFunction { } } } + +/// Gets the documentation above an item definition. +fn get_item_documentation(db: &dyn DefsGroup, stable_location: &StableLocation) -> Option { + // Get the text of the item (trivia + definition) + let doc = stable_location.syntax_node(db).get_text(db.upcast()); + // Only get the doc comments (start with `///` or `//!`) above the function. + let doc = doc + .lines() + .take_while_ref(|line| { + !line + .trim_start() + .chars() + .next() + .map_or(false, |c| c.is_alphabetic()) + }) + .filter_map(|line| { + // Remove indentation. + let dedent = line.trim_start(); + // Check if this is a doc comment. + for prefix in ["///", "//!"] { + if let Some(content) = dedent.strip_prefix(prefix) { + // TODO(mkaput): The way how removing this indentation is performed is probably + // wrong. The code should probably learn how many spaces are used at the first + // line of comments block, and then remove the same amount of spaces in the + // block, instead of assuming just one space. + // Remove inner indentation if one exists. + return Some(content.strip_prefix(' ').unwrap_or(content)); + } + } + None + }) + .collect::>(); + (!doc.is_empty()).then(|| doc.join("\n")) +} diff --git a/extensions/scarb-doc/tests/test.rs b/extensions/scarb-doc/tests/test.rs index d1c162df2..88b7c586f 100644 --- a/extensions/scarb-doc/tests/test.rs +++ b/extensions/scarb-doc/tests/test.rs @@ -181,6 +181,12 @@ fn test_workspace() { fn hello_world() -> u32 { 1 } + + /// Nice essa. + struct Essa { + /// Nice field. + field: u8, + } "#}) .build(&hello); @@ -208,6 +214,7 @@ fn test_workspace() { .assert() .success(); let stdout = std::str::from_utf8(&output.get_output().stdout).unwrap(); + assert!(stdout.contains("Module: \"hello_world\"")); assert!(!stdout.contains("Module: \"goodbye_world\"")); }