void ClassGraph::getRelatedNodesRecurse(const ModelData &model, const ModelType *type, eAddNodeTypes addType, int maxDepth, std::vector<ClassNode> &nodes) { mBackgroundTaskLevel++; -- maxDepth; if(maxDepth >= 0 && type /* && type->getObjectType() == otClass*/) { const ModelClassifier *classifier = type->getClass(); if(classifier) { addNodeToVector(ClassNode(classifier, getComponentOptions(*type, mGraphOptions)), nodes); if((addType & AN_MemberChildren) > 0) { for(const auto &attr : classifier->getAttributes()) { #if(DEBUG_ADD) DebugAdd("Member", attr->getDeclType()); #endif getRelatedNodesRecurse(model, attr->getDeclType(), addType, maxDepth, nodes); } } if((addType & AN_Superclass) > 0) { for(const auto &assoc : model.mAssociations) { if(assoc->getChild() != nullptr && assoc->getParent() != nullptr) { if(assoc->getChild() == classifier) { #if(DEBUG_ADD) DebugAdd("Super", assoc->getParent()); #endif getRelatedNodesRecurse(model, assoc->getParent(), addType, maxDepth, nodes); } } } } if((addType & AN_Subclass) > 0) { for(const auto &assoc : model.mAssociations) { // Normally the child and parent should not be nullptr. if(assoc->getChild() != nullptr && assoc->getParent() != nullptr) { if(assoc->getParent() == classifier) { #if(DEBUG_ADD) DebugAdd("Subclass", assoc->getChild()); #endif getRelatedNodesRecurse(model, assoc->getChild(), addType, maxDepth, nodes); } } } } if((addType & AN_FuncParamsUsing) > 0) { ConstModelClassifierVector relatedClasses; model.getRelatedFuncInterfaceClasses(*classifier, relatedClasses); for(const auto &cls : relatedClasses) { #if(DEBUG_ADD) DebugAdd("Param Using", cls); #endif getRelatedNodesRecurse(model, cls, addType, maxDepth, nodes); } } if((addType & AN_FuncBodyUsing) > 0) { ConstModelDeclClasses relatedDeclClasses; model.getRelatedBodyVarClasses(*classifier, relatedDeclClasses); for(const auto &rdc : relatedDeclClasses) { #if(DEBUG_ADD) DebugAdd("Body Using", rdc.cl); #endif getRelatedNodesRecurse(model, rdc.getClass(), addType, maxDepth, nodes); } } } if((addType & AN_Templates) > 0) { if(type->isTemplateUseType()) { // Add types pointed to by templates. ConstModelClassifierVector relatedClassifiers; model.getRelatedTypeArgClasses(*type, relatedClassifiers); for(const auto &rc : relatedClassifiers) { #if(DEBUG_ADD) DebugAdd("Templ User", rc); #endif getRelatedNodesRecurse(model, rc, addType, maxDepth, nodes); } addNodeToVector(ClassNode(type, getComponentOptions(*type, mGraphOptions)), nodes); } } int taskId = 0; if(mBackgroundTaskLevel == 1) { taskId = mForegroundTaskStatusListener->startTask("Adding relations.", model.mTypes.size()); } for(size_t i=0; i<model.mTypes.size(); i++) { addRelatedNodesRecurseUserToVector(model, type, model.mTypes[i].get(), addType, maxDepth, nodes); if(mBackgroundTaskLevel == 1) { if(!mForegroundTaskStatusListener->updateProgressIteration( taskId, i, nullptr)) { break; } } } if(mBackgroundTaskLevel == 1) { mForegroundTaskStatusListener->endTask(taskId); } } mBackgroundTaskLevel--; }
void ClassGraph::addRelatedNodesRecurseUserToVector(const ModelData &model, const ModelType *type, const ModelType *modelType, eAddNodeTypes addType, int maxDepth, std::vector<ClassNode> &nodes) { // Add nodes for template types if they refer to the passed in type. if((addType & AN_Templates) > 0) { if(modelType->isTemplateUseType()) { ConstModelClassifierVector relatedClassifiers; model.getRelatedTypeArgClasses(*modelType, relatedClassifiers); for(const auto &rc : relatedClassifiers) { if(rc == type) { #if(DEBUG_ADD) DebugAdd("Typedef Rel", modelType); #endif getRelatedNodesRecurse(model, modelType, addType, maxDepth, nodes); } } } } // Add nodes if members refer to the passed in type. if((addType & AN_MemberUsers) > 0) { const ModelClassifier*cl = modelType->getClass(); if(cl) { for(const auto &attr : cl->getAttributes()) { const ModelType *attrType = attr->getDeclType(); if(attrType == type) { #if(DEBUG_ADD) DebugAdd("Memb User", cl); #endif getRelatedNodesRecurse(model, cl, addType, maxDepth, nodes); } } } } // Add nodes if func params refer to the passed in type. if((addType & AN_FuncParamsUsers) > 0) { const ModelClassifier*cl = modelType->getClass(); if(cl) { ConstModelClassifierVector relatedClasses; model.getRelatedFuncInterfaceClasses(*cl, relatedClasses); for(auto &cls : relatedClasses) { if(cls == type) { #if(DEBUG_ADD) DebugAdd("Param User", cl); #endif getRelatedNodesRecurse(model, cl, addType, maxDepth, nodes); } } } } // Add nodes if func body variables refer to the passed in type. if((addType & AN_FuncBodyUsers) > 0) { const ModelClassifier*cl = modelType->getClass(); if(cl) { ConstModelDeclClasses relatedDeclClasses; model.getRelatedBodyVarClasses(*cl, relatedDeclClasses); for(auto &rdc : relatedDeclClasses) { if(rdc.getClass() == type) { #if(DEBUG_ADD) DebugAdd("Var User", cl); #endif getRelatedNodesRecurse(model, cl, addType, maxDepth, nodes); } } } } }