int _tmain(int argc, _TCHAR* argv[]) { if (argc >= 2) { const _TCHAR* outputDir = argc > 2 ? argv[2] : argv[1]; FileSystem::CreateRecursiveDirectory(string(outputDir) + _T("\\")); ClassManager classManager(outputDir); std::wcout << _T("Fetching classes...") << std::endl; for (const auto& file : FileSystem::GetFiles(string(argv[1]), _T("xml"))) { auto fileContent = readXMLFromFile(file.c_str()); using namespace rapidxml; xml_document<_TCHAR> doc; doc.parse<0>(fileContent.data()); Element doxygenNode = Element(doc.first_node(_T("doxygen"))); for (const auto& def : doxygenNode.Elements(_T("compounddef"))) { if (def.GetAttribute(_T("language")) == _T("C++")) { classManager.ProcessDef(def); } } } std::wcout << _T("Running classes analysis...") << std::endl; classManager.Initialize(); std::wcout << _T("Running source files analysis...") << std::endl; const auto files = FileSystem::GetFiles(string(argv[1]), _T("xml")); #pragma omp parallel for for (int i = 0; i < files.size(); i++) { const auto& file = files[i]; auto fileContent = readXMLFromFile(file.c_str()); using namespace rapidxml; xml_document<_TCHAR> doc; doc.parse<0>(fileContent.data()); Element doxygenNode = Element(doc.first_node(_T("doxygen"))); for (const auto& def : doxygenNode.Elements(_T("compounddef"))) { if (def.GetAttribute(_T("language")) == _T("C++") && def.GetAttribute(_T("kind")) == _T("file")) { classManager.ProcessFileDef(def); } } } std::wcout << _T("Writing json output...") << std::endl; classManager.WriteClassesJson(); classManager.WriteNamespaceJsons(); classManager.WriteSingleClassJsons(); std::wcout << _T("Done.") << std::endl; } return 0; }
void printElement(const Element& element, const int indent = 0) { const string indentation(indent*2, _T(' ')); std::wcout << indentation << _T("node: ") << element.Name().str() << std::endl; if (element.Text()) { std::wcout << indentation << _T("text: ") << element.Text().str() << std::endl; } auto& attributes = element.Attributes(); if (!attributes.empty()) { std::wcout << indentation << _T("attributes: ") << std::endl; for (const auto& attribute: attributes) { std::wcout << indentation << _T(" ") << attribute.first.str() << _T(": ") << attribute.second.str() << std::endl; } } auto subitems = element.Elements(); if (!subitems.empty()) { std::wcout << indentation << _T("subitems: ") << std::endl; for (const auto& e: subitems) { printElement(e, indent + 1); } } }
void ClassManager::ProcessDef(const Element& classDef) { const stringRef kind = classDef.GetAttribute(_T("kind")); if (kind == _T("namespace")) { initNamespaces.push_back(string(classDef.GetElement(_T("compoundname")).Text().str())); } else if (kind == _T("class") || kind == _T("struct")) { Class newClass; newClass.doxygenId = classDef.GetAttribute(_T("id")).str(); newClass.type = kind == _T("class") ? Class::CLASS : Class::STRUCT; newClass.name = classDef.GetElement(_T("compoundname")).Text().str(); std::wcout << _T("New class: ") << newClass.name << std::endl; newClass.filename = classDef.GetElement(_T("location")).GetAttribute(_T("file")).str(); newClass.templated = classDef.GetElement(_T("templateparamlist")); newClass.description = trim(classDef.GetElement(_T("briefdescription")).Text().str()); for (const auto& parent : classDef.Elements(_T("basecompoundref"))) { Inheritance inheritance; inheritance.classId = parent.Text().str(); inheritance.protLevel = PACKAGE; stringRef prot = parent.GetAttribute(_T("prot")); if (prot == _T("public")) { inheritance.protLevel = PUBLIC; } else if (prot == _T("protected")) { inheritance.protLevel = PROTECTED; } else if (prot == _T("private")) { inheritance.protLevel = PRIVATE; } inheritance.Virtual = (parent.GetAttribute(_T("virt")) == _T("virtual")); newClass.inheritance.push_back(std::move(inheritance)); } for (const auto& section : classDef.Elements(_T("sectiondef"))) { for (const auto& member : section.Elements(_T("memberdef"))) { EProtectionLevel protectionLevel = PACKAGE; const stringRef prot = member.GetAttribute(_T("prot")); if (prot == _T("public")) { protectionLevel = PUBLIC; } else if (prot == _T("protected")) { protectionLevel = PROTECTED; } else if (prot == _T("private")) { protectionLevel = PRIVATE; } const stringRef kind = member.GetAttribute(_T("kind")); if (kind == _T("function")) { Method method; method.name = member.GetElement(_T("name")).Text().str(); method.doxygenId = member.GetAttribute(_T("id")).str(); method.description = trim(member.GetElement(_T("briefdescription")).Text().str()); method.protectionLevel = protectionLevel; method.returnType = member.GetElement(_T("type")).Text().str(); method.Const = member.GetAttribute(_T("const")) == _T("yes"); method.Virtual = member.GetAttribute(_T("virt")) != _T("non-virtual"); method.Override = (string(member.GetAttribute(_T("argsstring")).str()).find(_T("override")) != string::npos); for (const auto& param : member.Elements(_T("param"))) { Method::Param p; p.name = param.GetElement(_T("declname")).Text().str(); p.type = param.GetElement(_T("type")).Text().str(); method.params.push_back(std::move(p)); } const Element location = member.GetElement(_T("location")); method.locationFile = location.GetAttribute(_T("bodyfile")).str(); method.bodyBeginLine = location.GetAttribute(_T("bodystart")).str(); method.bodyEndLine = location.GetAttribute(_T("bodyend")).str(); if (!newClass.interface && method.Virtual && method.protectionLevel == PUBLIC && classDef.GetAttribute(_T("abstract")) == _T("yes")) { newClass.interface = true; } newClass.methods.push_back(std::move(method)); } else if (kind == _T("variable")) { Member m; m.protectionLevel = protectionLevel; m.name = member.GetElement(_T("name")).Text().str(); m.type = member.GetElement(_T("type")).Text().str(); m.description = trim(member.GetElement(_T("briefdescription")).Text().str()); newClass.members.push_back(std::move(m));} } } initClasses.push_back(std::move(newClass)); } }