Skip to content

Commit 4f1a0c0

Browse files
committed
StructSignatureBuilder
commit-id:f73980e3
1 parent 2dd0620 commit 4f1a0c0

19 files changed

+486
-141
lines changed

Cargo.lock

Lines changed: 74 additions & 77 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 33 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -183,38 +183,38 @@ strip = "debuginfo"
183183
opt-level = 3
184184

185185
[patch.crates-io]
186-
cairo-lang-casm = { git = "https://github.com/starkware-libs/cairo", rev = "9af4f9f5dfee9e3ceb8e21b375926677dae7df53" }
187-
cairo-lang-compiler = { git = "https://github.com/starkware-libs/cairo", rev = "9af4f9f5dfee9e3ceb8e21b375926677dae7df53" }
188-
cairo-lang-debug = { git = "https://github.com/starkware-libs/cairo", rev = "9af4f9f5dfee9e3ceb8e21b375926677dae7df53" }
189-
cairo-lang-defs = { git = "https://github.com/starkware-libs/cairo", rev = "9af4f9f5dfee9e3ceb8e21b375926677dae7df53" }
190-
cairo-lang-diagnostics = { git = "https://github.com/starkware-libs/cairo", rev = "9af4f9f5dfee9e3ceb8e21b375926677dae7df53" }
191-
cairo-lang-doc = { git = "https://github.com/starkware-libs/cairo", rev = "9af4f9f5dfee9e3ceb8e21b375926677dae7df53" }
192-
cairo-lang-eq-solver = { git = "https://github.com/starkware-libs/cairo", rev = "9af4f9f5dfee9e3ceb8e21b375926677dae7df53" }
193-
cairo-lang-executable = { git = "https://github.com/starkware-libs/cairo", rev = "9af4f9f5dfee9e3ceb8e21b375926677dae7df53" }
194-
cairo-lang-executable-plugin = { git = "https://github.com/starkware-libs/cairo", rev = "9af4f9f5dfee9e3ceb8e21b375926677dae7df53" }
195-
cairo-lang-filesystem = { git = "https://github.com/starkware-libs/cairo", rev = "9af4f9f5dfee9e3ceb8e21b375926677dae7df53" }
196-
cairo-lang-formatter = { git = "https://github.com/starkware-libs/cairo", rev = "9af4f9f5dfee9e3ceb8e21b375926677dae7df53" }
197-
cairo-lang-lowering = { git = "https://github.com/starkware-libs/cairo", rev = "9af4f9f5dfee9e3ceb8e21b375926677dae7df53" }
198-
cairo-lang-parser = { git = "https://github.com/starkware-libs/cairo", rev = "9af4f9f5dfee9e3ceb8e21b375926677dae7df53" }
199-
cairo-lang-plugins = { git = "https://github.com/starkware-libs/cairo", rev = "9af4f9f5dfee9e3ceb8e21b375926677dae7df53" }
200-
cairo-lang-proc-macros = { git = "https://github.com/starkware-libs/cairo", rev = "9af4f9f5dfee9e3ceb8e21b375926677dae7df53" }
201-
cairo-lang-project = { git = "https://github.com/starkware-libs/cairo", rev = "9af4f9f5dfee9e3ceb8e21b375926677dae7df53" }
202-
cairo-lang-runnable-utils = { git = "https://github.com/starkware-libs/cairo", rev = "9af4f9f5dfee9e3ceb8e21b375926677dae7df53" }
203-
cairo-lang-runner = { git = "https://github.com/starkware-libs/cairo", rev = "9af4f9f5dfee9e3ceb8e21b375926677dae7df53" }
204-
cairo-lang-semantic = { git = "https://github.com/starkware-libs/cairo", rev = "9af4f9f5dfee9e3ceb8e21b375926677dae7df53" }
205-
cairo-lang-sierra = { git = "https://github.com/starkware-libs/cairo", rev = "9af4f9f5dfee9e3ceb8e21b375926677dae7df53" }
206-
cairo-lang-sierra-ap-change = { git = "https://github.com/starkware-libs/cairo", rev = "9af4f9f5dfee9e3ceb8e21b375926677dae7df53" }
207-
cairo-lang-sierra-gas = { git = "https://github.com/starkware-libs/cairo", rev = "9af4f9f5dfee9e3ceb8e21b375926677dae7df53" }
208-
cairo-lang-sierra-generator = { git = "https://github.com/starkware-libs/cairo", rev = "9af4f9f5dfee9e3ceb8e21b375926677dae7df53" }
209-
cairo-lang-sierra-to-casm = { git = "https://github.com/starkware-libs/cairo", rev = "9af4f9f5dfee9e3ceb8e21b375926677dae7df53" }
210-
cairo-lang-sierra-type-size = { git = "https://github.com/starkware-libs/cairo", rev = "9af4f9f5dfee9e3ceb8e21b375926677dae7df53" }
211-
cairo-lang-starknet = { git = "https://github.com/starkware-libs/cairo", rev = "9af4f9f5dfee9e3ceb8e21b375926677dae7df53" }
212-
cairo-lang-starknet-classes = { git = "https://github.com/starkware-libs/cairo", rev = "9af4f9f5dfee9e3ceb8e21b375926677dae7df53" }
213-
cairo-lang-syntax = { git = "https://github.com/starkware-libs/cairo", rev = "9af4f9f5dfee9e3ceb8e21b375926677dae7df53" }
214-
cairo-lang-syntax-codegen = { git = "https://github.com/starkware-libs/cairo", rev = "9af4f9f5dfee9e3ceb8e21b375926677dae7df53" }
215-
cairo-lang-test-plugin = { git = "https://github.com/starkware-libs/cairo", rev = "9af4f9f5dfee9e3ceb8e21b375926677dae7df53" }
216-
cairo-lang-test-runner = { git = "https://github.com/starkware-libs/cairo", rev = "9af4f9f5dfee9e3ceb8e21b375926677dae7df53" }
217-
cairo-lang-test-utils = { git = "https://github.com/starkware-libs/cairo", rev = "9af4f9f5dfee9e3ceb8e21b375926677dae7df53" }
218-
cairo-lang-utils = { git = "https://github.com/starkware-libs/cairo", rev = "9af4f9f5dfee9e3ceb8e21b375926677dae7df53" }
186+
cairo-lang-casm = { git = "https://github.com/starkware-libs/cairo", rev = "81eb71aa23ce91d8d2f770a4415b0648346a398e" }
187+
cairo-lang-compiler = { git = "https://github.com/starkware-libs/cairo", rev = "81eb71aa23ce91d8d2f770a4415b0648346a398e" }
188+
cairo-lang-debug = { git = "https://github.com/starkware-libs/cairo", rev = "81eb71aa23ce91d8d2f770a4415b0648346a398e" }
189+
cairo-lang-defs = { git = "https://github.com/starkware-libs/cairo", rev = "81eb71aa23ce91d8d2f770a4415b0648346a398e" }
190+
cairo-lang-diagnostics = { git = "https://github.com/starkware-libs/cairo", rev = "81eb71aa23ce91d8d2f770a4415b0648346a398e" }
191+
cairo-lang-doc = { git = "https://github.com/starkware-libs/cairo", rev = "81eb71aa23ce91d8d2f770a4415b0648346a398e" }
192+
cairo-lang-eq-solver = { git = "https://github.com/starkware-libs/cairo", rev = "81eb71aa23ce91d8d2f770a4415b0648346a398e" }
193+
cairo-lang-executable = { git = "https://github.com/starkware-libs/cairo", rev = "81eb71aa23ce91d8d2f770a4415b0648346a398e" }
194+
cairo-lang-executable-plugin = { git = "https://github.com/starkware-libs/cairo", rev = "81eb71aa23ce91d8d2f770a4415b0648346a398e" }
195+
cairo-lang-filesystem = { git = "https://github.com/starkware-libs/cairo", rev = "81eb71aa23ce91d8d2f770a4415b0648346a398e" }
196+
cairo-lang-formatter = { git = "https://github.com/starkware-libs/cairo", rev = "81eb71aa23ce91d8d2f770a4415b0648346a398e" }
197+
cairo-lang-lowering = { git = "https://github.com/starkware-libs/cairo", rev = "81eb71aa23ce91d8d2f770a4415b0648346a398e" }
198+
cairo-lang-parser = { git = "https://github.com/starkware-libs/cairo", rev = "81eb71aa23ce91d8d2f770a4415b0648346a398e" }
199+
cairo-lang-plugins = { git = "https://github.com/starkware-libs/cairo", rev = "81eb71aa23ce91d8d2f770a4415b0648346a398e" }
200+
cairo-lang-proc-macros = { git = "https://github.com/starkware-libs/cairo", rev = "81eb71aa23ce91d8d2f770a4415b0648346a398e" }
201+
cairo-lang-project = { git = "https://github.com/starkware-libs/cairo", rev = "81eb71aa23ce91d8d2f770a4415b0648346a398e" }
202+
cairo-lang-runnable-utils = { git = "https://github.com/starkware-libs/cairo", rev = "81eb71aa23ce91d8d2f770a4415b0648346a398e" }
203+
cairo-lang-runner = { git = "https://github.com/starkware-libs/cairo", rev = "81eb71aa23ce91d8d2f770a4415b0648346a398e" }
204+
cairo-lang-semantic = { git = "https://github.com/starkware-libs/cairo", rev = "81eb71aa23ce91d8d2f770a4415b0648346a398e" }
205+
cairo-lang-sierra = { git = "https://github.com/starkware-libs/cairo", rev = "81eb71aa23ce91d8d2f770a4415b0648346a398e" }
206+
cairo-lang-sierra-ap-change = { git = "https://github.com/starkware-libs/cairo", rev = "81eb71aa23ce91d8d2f770a4415b0648346a398e" }
207+
cairo-lang-sierra-gas = { git = "https://github.com/starkware-libs/cairo", rev = "81eb71aa23ce91d8d2f770a4415b0648346a398e" }
208+
cairo-lang-sierra-generator = { git = "https://github.com/starkware-libs/cairo", rev = "81eb71aa23ce91d8d2f770a4415b0648346a398e" }
209+
cairo-lang-sierra-to-casm = { git = "https://github.com/starkware-libs/cairo", rev = "81eb71aa23ce91d8d2f770a4415b0648346a398e" }
210+
cairo-lang-sierra-type-size = { git = "https://github.com/starkware-libs/cairo", rev = "81eb71aa23ce91d8d2f770a4415b0648346a398e" }
211+
cairo-lang-starknet = { git = "https://github.com/starkware-libs/cairo", rev = "81eb71aa23ce91d8d2f770a4415b0648346a398e" }
212+
cairo-lang-starknet-classes = { git = "https://github.com/starkware-libs/cairo", rev = "81eb71aa23ce91d8d2f770a4415b0648346a398e" }
213+
cairo-lang-syntax = { git = "https://github.com/starkware-libs/cairo", rev = "81eb71aa23ce91d8d2f770a4415b0648346a398e" }
214+
cairo-lang-syntax-codegen = { git = "https://github.com/starkware-libs/cairo", rev = "81eb71aa23ce91d8d2f770a4415b0648346a398e" }
215+
cairo-lang-test-plugin = { git = "https://github.com/starkware-libs/cairo", rev = "81eb71aa23ce91d8d2f770a4415b0648346a398e" }
216+
cairo-lang-test-runner = { git = "https://github.com/starkware-libs/cairo", rev = "81eb71aa23ce91d8d2f770a4415b0648346a398e" }
217+
cairo-lang-test-utils = { git = "https://github.com/starkware-libs/cairo", rev = "81eb71aa23ce91d8d2f770a4415b0648346a398e" }
218+
cairo-lang-utils = { git = "https://github.com/starkware-libs/cairo", rev = "81eb71aa23ce91d8d2f770a4415b0648346a398e" }
219219
cairo-language-server = { git = "https://github.com/software-mansion/cairols", rev = "c7039c331c74ef9c2f9fd537434157ad2870fd3f" }
220220
cairo-lint = { git = "https://github.com/software-mansion/cairo-lint.git", rev = "73ef36f59dc81848abfffbeb028695d29409023c"}

extensions/scarb-doc/src/types/struct_types.rs

Lines changed: 154 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,19 @@
11
use crate::db::ScarbDocDatabase;
2+
use crate::location_links::DocLocationLink;
23
use crate::types::module_type::is_doc_hidden_attr;
34
use crate::types::other_types::doc_full_path;
45
use crate::types::item_data::ItemData;
56
use cairo_lang_defs::ids::{
6-
LanguageElementId, LookupItemId, MemberId, ModuleItemId, NamedLanguageElementId, StructId,
7+
LanguageElementId, LookupItemId, MemberId, ModuleItemId, NamedLanguageElementId, StructId, TopLevelLanguageElementId,
78
};
89
use cairo_lang_diagnostics::Maybe;
10+
use cairo_lang_doc::db::DocGroup;
911
use cairo_lang_doc::documentable_item::DocumentableItemId;
12+
use cairo_lang_doc::helpers::{
13+
get_generic_params, get_struct_attributes_syntax, get_syntactic_visibility,
14+
};
15+
use cairo_lang_doc::location_links::{LocationLink, format_signature};
16+
use cairo_lang_doc::signature_data::SignatureDataRetriever;
1017
use cairo_lang_semantic::items::structure::StructSemantic;
1118
use cairo_lang_semantic::items::visibility::Visibility;
1219
use cairo_lang_syntax::node::ast;
@@ -30,31 +37,19 @@ impl<'db> Struct<'db> {
3037
id: StructId<'db>,
3138
include_private_items: bool,
3239
) -> Maybe<Self> {
33-
let members = db.struct_members(id)?;
34-
35-
let item_data = ItemData::new(
40+
let mut item_data = ItemData::new_without_signature(
3641
db,
3742
id,
3843
LookupItemId::ModuleItem(ModuleItemId::Struct(id)).into(),
39-
doc_full_path(&id.parent_module(db), db),
4044
);
41-
let members = members
42-
.iter()
43-
.filter_map(|(_, semantic_member)| {
44-
let visible = matches!(semantic_member.visibility, Visibility::Public);
45-
let syntax_node = &semantic_member.id.stable_location(db).syntax_node(db);
46-
if (include_private_items || visible) && !is_doc_hidden_attr(db, syntax_node) {
47-
Some(Ok(Member::new(db, semantic_member.id)))
48-
} else {
49-
None
50-
}
51-
})
52-
.collect::<Maybe<Vec<_>>>()?;
45+
let mut signature_builder = StructSignatureBuilder::new(db, id, include_private_items);
46+
let (signature, location_links, members) = signature_builder.build_signature(db);
47+
item_data.signature = Some(signature);
48+
item_data.doc_location_links = location_links;
5349

54-
let node = id.stable_ptr(db);
5550
Ok(Self {
5651
id,
57-
node,
52+
node: id.stable_ptr(db),
5853
members,
5954
item_data,
6055
})
@@ -68,6 +63,146 @@ impl<'db> Struct<'db> {
6863
}
6964
}
7065

66+
struct MemberDataHelper<'db> {
67+
signature: Option<String>,
68+
member_id: MemberId<'db>,
69+
location_links: Vec<LocationLink<'db>>,
70+
}
71+
72+
impl<'db> MemberDataHelper<'db> {
73+
fn new(member_id: MemberId<'db>, db: &'db ScarbDocDatabase) -> Self {
74+
let (signature, location_links) =
75+
db.get_item_signature_with_links(DocumentableItemId::Member(member_id));
76+
Self {
77+
signature,
78+
member_id,
79+
location_links,
80+
}
81+
}
82+
}
83+
84+
struct StructSignatureBuilder<'a> {
85+
members_data: Vec<MemberDataHelper<'a>>,
86+
has_private_members: bool,
87+
has_public_members: bool,
88+
buff: String,
89+
location_links: Vec<LocationLink<'a>>,
90+
}
91+
92+
impl<'db> StructSignatureBuilder<'db> {
93+
const INDENT: &'static str = " ";
94+
const PRIVATE_MEMBERS: &'static str = "/* private fields */";
95+
96+
fn new(db: &'db ScarbDocDatabase, id: StructId<'db>, include_private_items: bool) -> Self {
97+
let members = db.struct_members(id)
98+
.expect(&format!("Failed to get members of struct: {}", id.full_path(db)));
99+
let signature_data = StructId::retrieve_signature_data(db, id)
100+
.expect(&format!("Failed to get signature data for struct: {}", id.full_path(db)));
101+
102+
let mut buff = String::new();
103+
let mut location_links = Vec::new();
104+
105+
if let Some(attributes) = signature_data.attributes {
106+
let attributes_syntax = get_struct_attributes_syntax(attributes, db)
107+
.expect(&format!("Failed to format attributes syntax for struct: {}", id.full_path(db)));
108+
109+
buff.push_str(&attributes_syntax);
110+
}
111+
buff.push_str(&format!(
112+
"{}struct {}",
113+
get_syntactic_visibility(&signature_data.visibility),
114+
signature_data.name.long(db)
115+
));
116+
117+
if let Some(generic_params) = signature_data.generic_params {
118+
let (stx, _location_links) = get_generic_params(generic_params, db)
119+
.expect(&format!("Failed to get format params for struct: {}", id.full_path(db)));
120+
121+
buff.push_str(&stx);
122+
location_links.extend(_location_links);
123+
}
124+
let mut has_private_members = false;
125+
let mut has_public_members = false;
126+
127+
let members_data: Vec<MemberDataHelper> = members
128+
.iter()
129+
.filter_map(|(_, semantic_member)| {
130+
let visible = matches!(semantic_member.visibility, Visibility::Public);
131+
let syntax_node = &semantic_member.id.stable_location(db).syntax_node(db);
132+
133+
if (include_private_items || visible) && !is_doc_hidden_attr(db, syntax_node) {
134+
let mdh = MemberDataHelper::new(semantic_member.id, db);
135+
has_public_members = true;
136+
Some(Ok(mdh))
137+
} else {
138+
has_private_members = true;
139+
None
140+
}
141+
})
142+
.collect::<Maybe<Vec<_>>>()
143+
.expect(&format!("Failed to collect members data for struct: {}", id.full_path(db)));
144+
145+
StructSignatureBuilder {
146+
members_data,
147+
has_private_members,
148+
has_public_members,
149+
buff,
150+
location_links,
151+
}
152+
}
153+
154+
fn build_signature(
155+
&mut self,
156+
db: &'db ScarbDocDatabase,
157+
) -> (String, Vec<DocLocationLink>, Vec<Member<'db>>) {
158+
let mut members = Vec::new();
159+
self.buff.push_str(" {");
160+
161+
for mdh in &self.members_data {
162+
members.push(Member::new(db, mdh.member_id));
163+
let mut offset = self.buff.len();
164+
offset += "\n".len() + Self::INDENT.len();
165+
166+
let formatted_member_signature = format!(
167+
"\n{}{},",
168+
Self::INDENT,
169+
mdh.signature.clone().unwrap_or_default()
170+
);
171+
self.buff.push_str(&formatted_member_signature);
172+
self.location_links.extend(
173+
mdh.location_links
174+
.iter()
175+
.map(|link| LocationLink::new(link.start, link.end, link.item_id, offset))
176+
.collect::<Vec<_>>(),
177+
);
178+
}
179+
180+
if !&self.members_data.is_empty() {
181+
self.buff.push('\n');
182+
}
183+
184+
if self.has_private_members {
185+
let (prefix, postfix) = if self.has_public_members {
186+
(Self::INDENT, "\n")
187+
} else {
188+
(" ", " ")
189+
};
190+
self.buff.push_str(&format!("{prefix}{}{postfix}", Self::PRIVATE_MEMBERS));
191+
}
192+
self.buff.push('}');
193+
194+
let (new_sig_formatted, formatted_location_links) =
195+
format_signature(db, self.buff.clone(), self.location_links.clone());
196+
197+
let doc_location_links = formatted_location_links
198+
.iter()
199+
.map(|link| DocLocationLink::new(link.start, link.end, link.item_id, db))
200+
.collect::<Vec<_>>();
201+
202+
(new_sig_formatted, doc_location_links, members)
203+
}
204+
}
205+
71206
#[derive(Serialize, Clone)]
72207
pub struct Member<'db> {
73208
#[serde(skip)]

extensions/scarb-doc/tests/code/code_8.cairo

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,22 @@ mod inner_module {
1414
#[doc(group: "invisible group")]
1515
pub fn this_should_not_be_documented() {}
1616

17+
pub struct LinkedStruct {}
18+
19+
pub struct TestMembersVisibility {
20+
invisible_field: felt252,
21+
invisible_field2_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_long_one: felt252,
22+
pub visible_field: LinkedStruct,
23+
pub visible_field2_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_very_long_one: LinkedStruct,
24+
invisible_field3: felt252,
25+
}
26+
27+
#[doc(group: "visible")]
28+
pub struct TestMembersVisibility2 {
29+
no_fields_should_be_documented: LinkedStruct,
30+
}
31+
32+
1733
}
1834

1935
mod macro_module {
@@ -29,3 +45,4 @@ mod macro_module {
2945
pub use inner_module::visible_in_reeksports;
3046
pub use inner_module::inner_function_visible_in_group;
3147
pub use macro_module::macro_definition;
48+
pub use inner_module::{LinkedStruct, TestMembersVisibility, TestMembersVisibility2};

extensions/scarb-doc/tests/data/expose_macros/src/hello_world-OuterStruct.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ Fully qualified path: [hello_world](./hello_world.md)::[OuterStruct](./hello_wor
66

77
<pre><code class="language-cairo">pub struct OuterStruct {
88
pub work: felt252,
9-
properly: felt252,
9+
/* private fields */
1010
}</code></pre>
1111

1212
## Members

extensions/scarb-doc/tests/data/expose_macros/src/hello_world-regina-VisibleStruct.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ Fully qualified path: [hello_world](./hello_world.md)::[regina](./hello_world-re
66

77
<pre><code class="language-cairo">pub struct VisibleStruct {
88
pub works: felt252,
9-
properly: felt252,
9+
/* private fields */
1010
}</code></pre>
1111

1212
## Members

extensions/scarb-doc/tests/data/hello_world_doc_groups_reeksports/src/SUMMARY.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@
33
- [inner_module](./hello_world-inner_module.md)
44
- [Free functions](./hello_world-inner_module-free_functions.md)
55
- [visible_in_reeksports](./hello_world-inner_module-visible_in_reeksports.md)
6+
- [Structs](./hello_world-inner_module-structs.md)
7+
- [LinkedStruct](./hello_world-inner_module-LinkedStruct.md)
8+
- [TestMembersVisibility](./hello_world-inner_module-TestMembersVisibility.md)
69
- [macro_module](./hello_world-macro_module.md)
710
- [Macro declarations](./hello_world-macro_module-macro_declarations.md)
811
- [macro_definition](./hello_world-macro_module-macro_definition.md)
@@ -11,3 +14,5 @@
1114
- [Free functions](./visible-free_functions.md)
1215
- [top_level_fn_visible_in_group](./hello_world-top_level_fn_visible_in_group.md)
1316
- [inner_function_visible_in_group](./hello_world-inner_module-inner_function_visible_in_group.md)
17+
- [Structs](./visible-structs.md)
18+
- [TestMembersVisibility2](./hello_world-inner_module-TestMembersVisibility2.md)
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
# LinkedStruct
2+
3+
Fully qualified path: [hello_world](./hello_world.md)::[inner_module](./hello_world-inner_module.md)::[LinkedStruct](./hello_world-inner_module-LinkedStruct.md)
4+
5+
<pre><code class="language-cairo">pub struct LinkedStruct {}</code></pre>
6+

0 commit comments

Comments
 (0)