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