forge_doc/preprocessor/
inheritdoc.rs
1use super::{Preprocessor, PreprocessorId};
2use crate::{
3 document::DocumentContent, Comments, Document, ParseItem, ParseSource, PreprocessorOutput,
4};
5use alloy_primitives::map::HashMap;
6use forge_fmt::solang_ext::SafeUnwrap;
7
8pub const INHERITDOC_ID: PreprocessorId = PreprocessorId("inheritdoc");
10
11#[derive(Debug, Default)]
17#[non_exhaustive]
18pub struct Inheritdoc;
19
20impl Preprocessor for Inheritdoc {
21 fn id(&self) -> PreprocessorId {
22 INHERITDOC_ID
23 }
24
25 fn preprocess(&self, documents: Vec<Document>) -> Result<Vec<Document>, eyre::Error> {
26 for document in &documents {
27 if let DocumentContent::Single(ref item) = document.content {
28 let context = self.visit_item(item, &documents);
29 if !context.is_empty() {
30 document.add_context(self.id(), PreprocessorOutput::Inheritdoc(context));
31 }
32 }
33 }
34
35 Ok(documents)
36 }
37}
38
39impl Inheritdoc {
40 fn visit_item(&self, item: &ParseItem, documents: &Vec<Document>) -> HashMap<String, Comments> {
41 let mut context = HashMap::default();
42
43 let matched = item
45 .comments
46 .find_inheritdoc_base()
47 .and_then(|base| self.try_match_inheritdoc(base, &item.source, documents));
48 if let Some((key, comments)) = matched {
49 context.insert(key, comments);
50 }
51
52 for ch in &item.children {
54 let matched = ch
55 .comments
56 .find_inheritdoc_base()
57 .and_then(|base| self.try_match_inheritdoc(base, &ch.source, documents));
58 if let Some((key, comments)) = matched {
59 context.insert(key, comments);
60 }
61 }
62
63 context
64 }
65
66 fn try_match_inheritdoc(
67 &self,
68 base: &str,
69 source: &ParseSource,
70 documents: &Vec<Document>,
71 ) -> Option<(String, Comments)> {
72 for candidate in documents {
73 if let DocumentContent::Single(ref item) = candidate.content {
74 if let ParseSource::Contract(ref contract) = item.source {
75 if base == contract.name.safe_unwrap().name {
76 for children in &item.children {
80 if source.ident() == children.source.ident() {
82 let key = format!("{}.{}", base, source.ident());
83 return Some((key, children.comments.clone()))
84 }
85 }
86 }
87 }
88 }
89 }
90 None
91 }
92}