Include hidden classes in documentation to avoid confusion.

This commit is contained in:
Matthias Koefferlein 2026-01-11 01:30:25 +01:00
parent c3b6476176
commit b409ed8b44
2 changed files with 105 additions and 16 deletions

View File

@ -203,13 +203,29 @@ public:
} }
/** /**
* @brief Iterates all subclasses (end) * @brief Iterates all child classes (end)
*/ */
tl::weak_collection<ClassBase>::const_iterator end_child_classes () const tl::weak_collection<ClassBase>::const_iterator end_child_classes () const
{ {
return m_child_classes.end (); return m_child_classes.end ();
} }
/**
* @brief Iterates all subclasses (begin)
*/
tl::weak_collection<ClassBase>::const_iterator begin_subclasses () const
{
return m_subclasses.begin ();
}
/**
* @brief Iterates all subclasses (end)
*/
tl::weak_collection<ClassBase>::const_iterator end_subclasses () const
{
return m_subclasses.end ();
}
/** /**
* @brief Iterates all classes present (begin) * @brief Iterates all classes present (begin)
*/ */

View File

@ -993,7 +993,11 @@ GSIHelpProvider::produce_class_doc (const std::string &cls) const
<< "<!DOCTYPE language SYSTEM \"klayout_doc.dtd\">" << std::endl << "<!DOCTYPE language SYSTEM \"klayout_doc.dtd\">" << std::endl
<< std::endl; << std::endl;
os << "<doc><title>" << tl::to_string (QObject::tr ("API reference - Class")) << " " << escape_xml (cls) << "</title>" << std::endl; os << "<doc><title>" << tl::to_string (QObject::tr ("API reference - Class")) << " " << escape_xml (cls);
if (class_doc.hidden) {
os << " " << tl::to_string (QObject::tr ("[internal]"));
}
os << "</title>" << std::endl;
os << "<property name=\"module\" value=\"" << escape_xml (cls_obj->module ()) << "\"/>" << std::endl; os << "<property name=\"module\" value=\"" << escape_xml (cls_obj->module ()) << "\"/>" << std::endl;
os << "<keyword name=\"" << escape_xml (cls) << "\"/>" << std::endl; os << "<keyword name=\"" << escape_xml (cls) << "\"/>" << std::endl;
@ -1006,13 +1010,15 @@ GSIHelpProvider::produce_class_doc (const std::string &cls) const
os << "<p><b>" << tl::to_string (QObject::tr ("Description")) << "</b>: " << escape_xml (class_doc.brief_doc) << "</p>" << std::endl; os << "<p><b>" << tl::to_string (QObject::tr ("Description")) << "</b>: " << escape_xml (class_doc.brief_doc) << "</p>" << std::endl;
std::vector<const gsi::ClassBase *> classes; const gsi::ClassBase *act_cls_obj = real_class (cls_obj);
classes.push_back (real_class (cls_obj));
const gsi::ClassBase *base = real_class (cls_obj)->base (); std::vector<const gsi::ClassBase *> classes;
classes.push_back (act_cls_obj);
const gsi::ClassBase *base = act_cls_obj->base ();
if (base) { if (base) {
const gsi::ClassBase *last_cls = real_class (cls_obj); const gsi::ClassBase *last_cls = act_cls_obj;
bool all_collected = false; bool all_collected = false;
os << "<p><b>" << tl::to_string (QObject::tr ("Class hierarchy")) << "</b>: " << make_qualified_name (cls_obj); os << "<p><b>" << tl::to_string (QObject::tr ("Class hierarchy")) << "</b>: " << make_qualified_name (cls_obj);
@ -1032,6 +1038,7 @@ GSIHelpProvider::produce_class_doc (const std::string &cls) const
all_collected = true; all_collected = true;
} else if (! all_collected) { } else if (! all_collected) {
// class needs to be mixed into the parent // class needs to be mixed into the parent
os << " &#187; <a href=\"" << escape_xml (class_doc_url (base->name ())) << "\">" << escape_xml (base->name ()) << " " << tl::to_string (QObject::tr ("[internal]")) << "</a>";
classes.push_back (base); classes.push_back (base);
} }
@ -1051,34 +1058,90 @@ GSIHelpProvider::produce_class_doc (const std::string &cls) const
os << "</p>" << std::endl; os << "</p>" << std::endl;
} }
// Produce child classes
bool any = false; bool any = false;
for (std::vector<const gsi::ClassBase *>::const_iterator c = classes.begin (); c != classes.end (); ++c) { for (std::vector<const gsi::ClassBase *>::const_iterator c = classes.begin (); c != classes.end (); ++c) {
for (tl::weak_collection<gsi::ClassBase>::const_iterator cc = (*c)->begin_child_classes (); cc != (*c)->end_child_classes (); ++cc) { for (tl::weak_collection<gsi::ClassBase>::const_iterator cc = (*c)->begin_child_classes (); cc != (*c)->end_child_classes (); ++cc) {
DocumentationParser &cdoc = cls_documentation (cc.operator-> ()); DocumentationParser &cdoc = cls_documentation (cc.operator-> ());
if (! cdoc.hidden || ! cdoc.alias.empty ()) {
if (any) { if (any) {
os << ", "; os << ", ";
} else { } else {
os << "<p><b>" << tl::to_string (QObject::tr ("Sub-classes")) << "</b>: "; os << "<p><b>" << tl::to_string (QObject::tr ("Child classes")) << "</b>: ";
any = true; any = true;
} }
os << "<a href=\"" << escape_xml (class_doc_url (make_qualified_name (cc.operator-> ()))) << "\">" << escape_xml (cc->name ()) << "</a>"; os << "<a href=\""
<< escape_xml (class_doc_url (make_qualified_name (cc.operator-> ())))
<< "\">"
<< escape_xml (cc->name ());
if (cdoc.hidden && cdoc.alias.empty ()) {
os << " " << tl::to_string (QObject::tr ("[internal]"));
}
os << "</a>";
} }
} }
}
if (any) { if (any) {
os << "</p>" << std::endl; os << "</p>" << std::endl;
} }
// Produce subclasses (parent classes)
any = false;
for (tl::weak_collection<gsi::ClassBase>::const_iterator cc = act_cls_obj->begin_subclasses (); cc != act_cls_obj->end_subclasses (); ++cc) {
DocumentationParser &cdoc = cls_documentation (cc.operator-> ());
if (any) {
os << ", ";
} else {
os << "<p><b>" << tl::to_string (QObject::tr ("Subclasses")) << "</b>: ";
any = true;
}
os << "<a href=\""
<< escape_xml (class_doc_url (make_qualified_name (cc.operator-> ())))
<< "\">"
<< escape_xml (cc->name ());
if (cdoc.hidden && cdoc.alias.empty ()) {
os << " " << tl::to_string (QObject::tr ("[internal]"));
}
os << "</a>";
}
if (any) {
os << "</p>" << std::endl;
}
// Inserts an index
os << "<h2-index/>" << std::endl; os << "<h2-index/>" << std::endl;
// Produce class doc body
if (class_doc.hidden && class_doc.alias.empty ()) {
os << "<p><b>"
<< tl::to_string (QObject::tr ("Note"))
<< "</b>: "
<< tl::to_string (QObject::tr (
"This class is an internal class provided for technical reasons - i.e. "
"as a placeholder class for argument binding or as an abstract interface. "
"You should not instantiate objects of this class directly. "
"Instead, use the subclasses listed above. "
"Also see there for more documentation and actual incarnations of this class."
))
<< "</p>" << std::endl;
}
os << replace_references (class_doc.doc_html (), cls_obj) << std::endl; os << replace_references (class_doc.doc_html (), cls_obj) << std::endl;
// collect the methods of the class and their hidden base classes // collect the methods of the class and their hidden base classes
@ -1117,6 +1180,8 @@ GSIHelpProvider::produce_class_doc (const std::string &cls) const
return os.str (); return os.str ();
} }
// Produce methods brief descriptions
int n = 0; int n = 0;
int row = 0; int row = 0;
@ -1190,6 +1255,8 @@ GSIHelpProvider::produce_class_doc (const std::string &cls) const
os << "</table>" << std::endl; os << "</table>" << std::endl;
} }
// Produce static methods brief descriptions
any = false; any = false;
n = 0; n = 0;
@ -1230,6 +1297,8 @@ GSIHelpProvider::produce_class_doc (const std::string &cls) const
os << "</table>" << std::endl; os << "</table>" << std::endl;
} }
// Produce protected methods brief descriptions
any = false; any = false;
n = 0; n = 0;
@ -1272,6 +1341,8 @@ GSIHelpProvider::produce_class_doc (const std::string &cls) const
os << "</table>" << std::endl; os << "</table>" << std::endl;
} }
// Produce deprecated methods brief descriptions
any = false; any = false;
n = 0; n = 0;
@ -1323,6 +1394,8 @@ GSIHelpProvider::produce_class_doc (const std::string &cls) const
os << "</table>" << std::endl; os << "</table>" << std::endl;
} }
// Produce method details
n = 0; n = 0;
os << "<a name=\"detailed\"/><h2>" << tl::to_string (QObject::tr ("Detailed description")) << "</h2>" << std::endl; os << "<a name=\"detailed\"/><h2>" << tl::to_string (QObject::tr ("Detailed description")) << "</h2>" << std::endl;