Skip to content

Commit 2fbce1a

Browse files
Add inheriting classes to DocTools
1 parent 7c9d931 commit 2fbce1a

5 files changed

Lines changed: 93 additions & 62 deletions

File tree

editor/doc_tools.cpp

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -307,21 +307,21 @@ void DocTools::merge_from(const DocTools &p_data) {
307307
}
308308
}
309309

310-
void DocTools::remove_from(const DocTools &p_data) {
311-
for (const KeyValue<String, DocData::ClassDoc> &E : p_data.class_list) {
312-
if (class_list.has(E.key)) {
313-
class_list.erase(E.key);
314-
}
315-
}
316-
}
317-
318310
void DocTools::add_doc(const DocData::ClassDoc &p_class_doc) {
319311
ERR_FAIL_COND(p_class_doc.name.is_empty());
320312
class_list[p_class_doc.name] = p_class_doc;
313+
inheriting[p_class_doc.inherits].insert(p_class_doc.name);
321314
}
322315

323316
void DocTools::remove_doc(const String &p_class_name) {
324317
ERR_FAIL_COND(p_class_name.is_empty() || !class_list.has(p_class_name));
318+
const String &inherits = class_list[p_class_name].inherits;
319+
if (inheriting.has(inherits)) {
320+
inheriting[inherits].erase(p_class_name);
321+
if (inheriting[inherits].is_empty()) {
322+
inheriting.erase(inherits);
323+
}
324+
}
325325
class_list.erase(p_class_name);
326326
}
327327

@@ -391,6 +391,8 @@ void DocTools::generate(BitField<GenerateFlags> p_flags) {
391391
c.name = cname;
392392
c.inherits = ClassDB::get_parent_class(name);
393393

394+
inheriting[c.inherits].insert(cname);
395+
394396
List<PropertyInfo> properties;
395397
List<PropertyInfo> own_properties;
396398

@@ -692,6 +694,7 @@ void DocTools::generate(BitField<GenerateFlags> p_flags) {
692694
// it's not a ClassDB-exposed class.
693695
class_list["Variant"] = DocData::ClassDoc();
694696
class_list["Variant"].name = "Variant";
697+
inheriting[""].insert("Variant");
695698
}
696699

697700
// Add Variant data types.
@@ -709,6 +712,8 @@ void DocTools::generate(BitField<GenerateFlags> p_flags) {
709712
DocData::ClassDoc &c = class_list[cname];
710713
c.name = cname;
711714

715+
inheriting[""].insert(cname);
716+
712717
Callable::CallError cerror;
713718
Variant v;
714719
Variant::construct(Variant::Type(i), v, nullptr, 0, cerror);
@@ -870,6 +875,8 @@ void DocTools::generate(BitField<GenerateFlags> p_flags) {
870875
DocData::ClassDoc &c = class_list[cname];
871876
c.name = cname;
872877

878+
inheriting[""].insert(cname);
879+
873880
// Global constants.
874881
for (int i = 0; i < CoreConstants::get_global_constant_count(); i++) {
875882
DocData::ConstantDoc cd;
@@ -953,6 +960,8 @@ void DocTools::generate(BitField<GenerateFlags> p_flags) {
953960
DocData::ClassDoc c;
954961
c.name = cname;
955962

963+
inheriting[""].insert(cname);
964+
956965
// Get functions.
957966
List<MethodInfo> minfo;
958967
lang->get_public_functions(&minfo);
@@ -1195,6 +1204,8 @@ Error DocTools::_load(Ref<XMLParser> parser) {
11951204
c.inherits = parser->get_named_attribute_value("inherits");
11961205
}
11971206

1207+
inheriting[c.inherits].insert(name);
1208+
11981209
if (parser->has_attribute("is_deprecated")) {
11991210
c.is_deprecated = parser->get_named_attribute_value("is_deprecated").to_lower() == "true";
12001211
}

editor/doc_tools.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,16 +32,17 @@
3232
#define DOC_TOOLS_H
3333

3434
#include "core/doc_data.h"
35+
#include "core/templates/rb_set.h"
3536

3637
class DocTools {
3738
public:
3839
String version;
3940
HashMap<String, DocData::ClassDoc> class_list;
41+
HashMap<String, RBSet<String, NaturalNoCaseComparator>> inheriting;
4042

4143
static Error erase_classes(const String &p_dir);
4244

4345
void merge_from(const DocTools &p_data);
44-
void remove_from(const DocTools &p_data);
4546
void add_doc(const DocData::ClassDoc &p_class_doc);
4647
void remove_doc(const String &p_class_name);
4748
bool has_doc(const String &p_class_name);

editor/editor_help.cpp

Lines changed: 13 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -812,35 +812,25 @@ void EditorHelp::_update_doc() {
812812
class_desc->add_newline();
813813
}
814814

815-
// Descendents
816-
if (cd.is_script_doc || ClassDB::class_exists(cd.name)) {
817-
bool found = false;
818-
bool prev = false;
819-
815+
// Descendants
816+
if ((cd.is_script_doc || ClassDB::class_exists(cd.name)) && doc->inheriting.has(cd.name)) {
820817
_push_normal_font();
821-
for (const KeyValue<String, DocData::ClassDoc> &E : doc->class_list) {
822-
if (E.value.inherits == cd.name) {
823-
if (!found) {
824-
class_desc->push_color(theme_cache.title_color);
825-
class_desc->add_text(TTR("Inherited by:") + " ");
826-
found = true;
827-
}
818+
class_desc->push_color(theme_cache.title_color);
819+
class_desc->add_text(TTR("Inherited by:") + " ");
828820

829-
if (prev) {
830-
class_desc->add_text(" , ");
831-
}
832-
_add_type_icon(E.value.name, theme_cache.doc_font_size, "ArrowRight");
833-
class_desc->add_text(non_breaking_space); // Otherwise icon borrows hyperlink from _add_type().
834-
_add_type(E.value.name);
835-
prev = true;
821+
for (RBSet<String, NaturalNoCaseComparator>::Element *itr = doc->inheriting[cd.name].front(); itr; itr = itr->next()) {
822+
if (itr->prev()) {
823+
class_desc->add_text(" , ");
836824
}
825+
826+
_add_type_icon(itr->get(), theme_cache.doc_font_size, "ArrowRight");
827+
class_desc->add_text(non_breaking_space); // Otherwise icon borrows hyperlink from _add_type().
828+
_add_type(itr->get());
837829
}
838830
_pop_normal_font();
839831

840-
if (found) {
841-
class_desc->pop();
842-
class_desc->add_newline();
843-
}
832+
class_desc->pop();
833+
class_desc->add_newline();
844834
}
845835

846836
// Note if deprecated.

editor/editor_help_search.cpp

Lines changed: 58 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -317,7 +317,13 @@ bool EditorHelpSearch::Runner::_slice() {
317317
}
318318

319319
bool EditorHelpSearch::Runner::_phase_match_classes_init() {
320-
iterator_doc = EditorHelp::get_doc_data()->class_list.begin();
320+
iterator_doc = nullptr;
321+
iterator_stack.clear();
322+
if (search_flags & SEARCH_SHOW_HIERARCHY) {
323+
iterator_stack.push_back(EditorHelp::get_doc_data()->inheriting[""].front());
324+
} else {
325+
iterator_doc = EditorHelp::get_doc_data()->class_list.begin();
326+
}
321327
matches.clear();
322328
matched_item = nullptr;
323329
match_highest_score = 0;
@@ -331,81 +337,103 @@ bool EditorHelpSearch::Runner::_phase_match_classes_init() {
331337
}
332338

333339
bool EditorHelpSearch::Runner::_phase_match_classes() {
334-
if (!iterator_doc) {
340+
if (!iterator_doc && iterator_stack.is_empty()) {
335341
return true;
336342
}
337343

338-
DocData::ClassDoc &class_doc = iterator_doc->value;
339-
if (class_doc.name.is_empty()) {
340-
++iterator_doc;
341-
return false;
344+
DocData::ClassDoc *class_doc = nullptr;
345+
if (iterator_doc) {
346+
class_doc = &iterator_doc->value;
347+
} else if (!iterator_stack.is_empty() && iterator_stack[iterator_stack.size() - 1]) {
348+
class_doc = EditorHelp::get_doc_data()->class_list.getptr(iterator_stack[iterator_stack.size() - 1]->get());
349+
}
350+
351+
if (class_doc && class_doc->name.is_empty()) {
352+
class_doc = nullptr;
342353
}
343354

344-
if (!_is_class_disabled_by_feature_profile(class_doc.name)) {
355+
if (class_doc && !_is_class_disabled_by_feature_profile(class_doc->name)) {
345356
ClassMatch match;
346-
match.doc = &class_doc;
357+
match.doc = class_doc;
347358

348359
// Match class name.
349360
if (search_flags & SEARCH_CLASSES) {
350361
// If the search term is empty, add any classes which are not script docs or which don't start with
351362
// a double-quotation. This will ensure that only C++ classes and explicitly named classes will
352363
// be added.
353-
match.name = (term.is_empty() && (!class_doc.is_script_doc || class_doc.name[0] != '\"')) || _match_string(term, class_doc.name);
364+
match.name = (term.is_empty() && (!class_doc->is_script_doc || class_doc->name[0] != '\"')) || _match_string(term, class_doc->name);
354365
}
355366

356367
// Match members only if the term is long enough, to avoid slow performance from building a large tree.
357368
// Make an exception for annotations, since there are not that many of them.
358369
if (term.length() > 1 || term == "@") {
359370
if (search_flags & SEARCH_CONSTRUCTORS) {
360-
_match_method_name_and_push_back(class_doc.constructors, &match.constructors);
371+
_match_method_name_and_push_back(class_doc->constructors, &match.constructors);
361372
}
362373
if (search_flags & SEARCH_METHODS) {
363-
_match_method_name_and_push_back(class_doc.methods, &match.methods);
374+
_match_method_name_and_push_back(class_doc->methods, &match.methods);
364375
}
365376
if (search_flags & SEARCH_OPERATORS) {
366-
_match_method_name_and_push_back(class_doc.operators, &match.operators);
377+
_match_method_name_and_push_back(class_doc->operators, &match.operators);
367378
}
368379
if (search_flags & SEARCH_SIGNALS) {
369-
for (int i = 0; i < class_doc.signals.size(); i++) {
370-
if (_all_terms_in_name(class_doc.signals[i].name)) {
371-
match.signals.push_back(const_cast<DocData::MethodDoc *>(&class_doc.signals[i]));
380+
for (int i = 0; i < class_doc->signals.size(); i++) {
381+
if (_all_terms_in_name(class_doc->signals[i].name)) {
382+
match.signals.push_back(const_cast<DocData::MethodDoc *>(&class_doc->signals[i]));
372383
}
373384
}
374385
}
375386
if (search_flags & SEARCH_CONSTANTS) {
376-
for (int i = 0; i < class_doc.constants.size(); i++) {
377-
if (_all_terms_in_name(class_doc.constants[i].name)) {
378-
match.constants.push_back(const_cast<DocData::ConstantDoc *>(&class_doc.constants[i]));
387+
for (int i = 0; i < class_doc->constants.size(); i++) {
388+
if (_all_terms_in_name(class_doc->constants[i].name)) {
389+
match.constants.push_back(const_cast<DocData::ConstantDoc *>(&class_doc->constants[i]));
379390
}
380391
}
381392
}
382393
if (search_flags & SEARCH_PROPERTIES) {
383-
for (int i = 0; i < class_doc.properties.size(); i++) {
384-
if (_all_terms_in_name(class_doc.properties[i].name)) {
385-
match.properties.push_back(const_cast<DocData::PropertyDoc *>(&class_doc.properties[i]));
394+
for (int i = 0; i < class_doc->properties.size(); i++) {
395+
if (_all_terms_in_name(class_doc->properties[i].name)) {
396+
match.properties.push_back(const_cast<DocData::PropertyDoc *>(&class_doc->properties[i]));
386397
}
387398
}
388399
}
389400
if (search_flags & SEARCH_THEME_ITEMS) {
390-
for (int i = 0; i < class_doc.theme_properties.size(); i++) {
391-
if (_all_terms_in_name(class_doc.theme_properties[i].name)) {
392-
match.theme_properties.push_back(const_cast<DocData::ThemeItemDoc *>(&class_doc.theme_properties[i]));
401+
for (int i = 0; i < class_doc->theme_properties.size(); i++) {
402+
if (_all_terms_in_name(class_doc->theme_properties[i].name)) {
403+
match.theme_properties.push_back(const_cast<DocData::ThemeItemDoc *>(&class_doc->theme_properties[i]));
393404
}
394405
}
395406
}
396407
if (search_flags & SEARCH_ANNOTATIONS) {
397-
for (int i = 0; i < class_doc.annotations.size(); i++) {
398-
if (_match_string(term, class_doc.annotations[i].name)) {
399-
match.annotations.push_back(const_cast<DocData::MethodDoc *>(&class_doc.annotations[i]));
408+
for (int i = 0; i < class_doc->annotations.size(); i++) {
409+
if (_match_string(term, class_doc->annotations[i].name)) {
410+
match.annotations.push_back(const_cast<DocData::MethodDoc *>(&class_doc->annotations[i]));
400411
}
401412
}
402413
}
403414
}
404-
matches[class_doc.name] = match;
415+
matches[class_doc->name] = match;
416+
}
417+
418+
if (iterator_doc) {
419+
++iterator_doc;
420+
return !iterator_doc;
421+
}
422+
423+
if (!iterator_stack.is_empty()) {
424+
if (iterator_stack[iterator_stack.size() - 1]) {
425+
iterator_stack[iterator_stack.size() - 1] = iterator_stack[iterator_stack.size() - 1]->next();
426+
}
427+
if (!iterator_stack[iterator_stack.size() - 1]) {
428+
iterator_stack.resize(iterator_stack.size() - 1);
429+
}
430+
}
431+
432+
if (class_doc && EditorHelp::get_doc_data()->inheriting.has(class_doc->name)) {
433+
iterator_stack.push_back(EditorHelp::get_doc_data()->inheriting[class_doc->name].front());
405434
}
406435

407-
++iterator_doc;
408-
return !iterator_doc;
436+
return iterator_stack.is_empty();
409437
}
410438

411439
bool EditorHelpSearch::Runner::_phase_class_items_init() {

editor/editor_help_search.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,7 @@ class EditorHelpSearch::Runner : public RefCounted {
124124
Color disabled_color;
125125

126126
HashMap<String, DocData::ClassDoc>::Iterator iterator_doc;
127+
LocalVector<RBSet<String, NaturalNoCaseComparator>::Element *> iterator_stack;
127128
HashMap<String, ClassMatch> matches;
128129
HashMap<String, ClassMatch>::Iterator iterator_match;
129130
TreeItem *root_item = nullptr;

0 commit comments

Comments
 (0)