From 250967a14561da5f840ef307fc5ee265f8ef3704 Mon Sep 17 00:00:00 2001 From: Luis Paulo Torres de Oliveira Date: Wed, 11 Dec 2013 18:13:46 -0300 Subject: Create class functions recovery methods for the gcc-xml architecture recovery plugin. Change-Id: Iaccfbf4be28714241dd9feffe72a0fd58b04c28d Reviewed-by: Sandro S. Andrade --- .../gccxmlarchitecturerecoverybackendplugin.cpp | 162 ++++++++++++++++++--- .../gccxmlarchitecturerecoverybackendplugin.h | 19 ++- 2 files changed, 160 insertions(+), 21 deletions(-) (limited to 'examples/uml') diff --git a/examples/uml/duse-mt/src/plugins/gccxmlarchitecturerecoverybackend/gccxmlarchitecturerecoverybackendplugin.cpp b/examples/uml/duse-mt/src/plugins/gccxmlarchitecturerecoverybackend/gccxmlarchitecturerecoverybackendplugin.cpp index 0349b576..e161b412 100644 --- a/examples/uml/duse-mt/src/plugins/gccxmlarchitecturerecoverybackend/gccxmlarchitecturerecoverybackendplugin.cpp +++ b/examples/uml/duse-mt/src/plugins/gccxmlarchitecturerecoverybackend/gccxmlarchitecturerecoverybackendplugin.cpp @@ -61,6 +61,7 @@ bool GccXmlArchitectureRecoveryBackendPlugin::initialize() QAction *newArchitectureRecoveryProcessAction = new QAction(QIcon(), tr("New architecture recovery process"), this); connect(newArchitectureRecoveryProcessAction, SIGNAL(triggered()), this, SLOT(newArchitectureRecoveryProcess())); ICore::self()->uiController()->addAction(newArchitectureRecoveryProcessAction, tr("menu_File")); + qRegisterMetaType("ClassFunctions"); return true; } @@ -71,8 +72,8 @@ void GccXmlArchitectureRecoveryBackendPlugin::setRootProjectDir(const QDir &root void GccXmlArchitectureRecoveryBackendPlugin::newArchitectureRecoveryProcess() { - QString fileName = QFileDialog::getOpenFileName(0, tr("Open xml file"), "/home", tr("Xml files (*.xml)")); - _rootProjectDir = QDir(fileName); + QString directory = QFileDialog::getExistingDirectory(0, tr("Open code tree"), QDir::currentPath()); + _rootProjectDir = QDir(directory); components(); } @@ -84,12 +85,10 @@ QObjectList GccXmlArchitectureRecoveryBackendPlugin::components() QStringList xmlFiles = generateXmlFiles(headers); int xmlFilesSize = xmlFiles.size(); for (int i = 0; i < xmlFilesSize; ++i) { - QString xmlFile = xmlFiles.at(i).toLocal8Bit().constData(); + _xmlFileName = xmlFiles.at(i).toLocal8Bit().constData(); - if (openXmlFile(_rootProjectDir.absolutePath() + "/" + xmlFile)) { - QObject *component = extractComponent(xmlFile); - components.append(component); - } + QObject *component = extractComponent(); + components.append(component); } return components; @@ -129,12 +128,13 @@ bool GccXmlArchitectureRecoveryBackendPlugin::openXmlFile(const QString &filePat return true; } -QStringList GccXmlArchitectureRecoveryBackendPlugin::findConstructorsFromXml(QString xmlFile) +QStringList GccXmlArchitectureRecoveryBackendPlugin::findConstructorsFromXml() { QStringList constructors; - openXmlFile(_rootProjectDir.absolutePath() + "/" + xmlFile); - QString className = xmlFile.replace(".xml", ""); + openXmlFile(_rootProjectDir.absolutePath() + "/" + _xmlFileName); + QString className = _xmlFileName; + className.replace(".xml", ""); while (!_xmlReader->atEnd() && !_xmlReader->hasError()) { QXmlStreamReader::TokenType token = _xmlReader->readNext(); @@ -143,29 +143,155 @@ QStringList GccXmlArchitectureRecoveryBackendPlugin::findConstructorsFromXml(QSt QXmlStreamAttributes attributes = _xmlReader->attributes(); QString attribute = attributes.value("demangled").toString(); - if (attribute.contains(className + "::")) { + if (attribute.contains(className + "::", Qt::CaseInsensitive)) { constructors.append(attribute); } } } } + if (_xmlFile.isOpen()) { + _xmlFile.close(); + } return constructors; } -QObject *GccXmlArchitectureRecoveryBackendPlugin::extractComponent(QString xmlFile) +QObject *GccXmlArchitectureRecoveryBackendPlugin::extractComponent() { - QStringList constructors = findConstructorsFromXml(xmlFile); + QObject *component = new QObject; + QString className; + QStringList constructors = findConstructorsFromXml(); - QString expression = constructors.last(); - QStringList elements = expression.split("::"); - QString className = elements.at(0) + "::" + elements.at(1); + if (!constructors.isEmpty()) { + QString expression = constructors.last(); + QStringList elements = expression.split("::"); + className = elements.at(0) + "::" + elements.at(1); - QObject *component = new QObject; - component->setObjectName(className); + component->setObjectName(className); + } else { + className = _xmlFileName; + className.replace(".xml", ""); + component->setObjectName(className); + } + + findFunctionsFromXml(component); return component; } +void GccXmlArchitectureRecoveryBackendPlugin::findFunctionsFromXml(QObject *component) +{ + QHash > classFunctions; + + openXmlFile(_rootProjectDir.absolutePath() + "/" + _xmlFileName); + + QStringList expression = component->objectName().split("::"); + QString classNamespace = expression.first(); + + while (!_xmlReader->atEnd() && !_xmlReader->hasError()) { + QXmlStreamReader::TokenType token = _xmlReader->readNext(); + + if (token == QXmlStreamReader::StartElement) { + if ((_xmlReader->name() == "Method") || + (_xmlReader->name() == "Constructor") || + (_xmlReader->name() == "Destructor")) { + QString attribute = _xmlReader->attributes().value("demangled").toString(); + + if (attribute.contains(classNamespace + "::", Qt::CaseInsensitive)) { + classFunctions = classFunctionsContainer(attribute, classFunctions); + } + } + } + } + if (_xmlFile.isOpen()) { + _xmlFile.close(); + } + + component->setProperty("Functions", QVariant::fromValue(classFunctions)); +} + +QHash > GccXmlArchitectureRecoveryBackendPlugin::classFunctionsContainer(QString xmlAttribute, QHash > &classFunctions) +{ + QMultiHash function; + + QStringList signature = xmlAttribute.split("::"); + QString className = signature.at(0) + "::" + signature.at(1); + QString functionName = signature.at(2).left(signature.at(2).indexOf("(")); + + findFunctionParameters(functionName, function); + classFunctions.insert(className, function); + + return classFunctions; +} + +void GccXmlArchitectureRecoveryBackendPlugin::findFunctionParameters(const QString &functionName, QMultiHash &function) +{ + while (_xmlReader->readNextStartElement()) { + if (!_xmlReader->attributes().value("name").toString().isEmpty()) { + QString parameterName = _xmlReader->attributes().value("name").toString(); + QString typeID = _xmlReader->attributes().value("type").toString(); + + QString parameterTypeNumber = findTypeNumber(typeID); + QString parameterType = findType(parameterTypeNumber); + if (parameterType == "") { + parameterType = findType(typeID); + } + + function.insert(functionName, parameterName + " " + parameterType); + } + } +} + +QString GccXmlArchitectureRecoveryBackendPlugin::findTypeNumber(const QString &typeID) +{ + QFile file(_rootProjectDir.absolutePath() + "/" + _xmlFileName); + QXmlStreamReader *typeNumberCollector = new QXmlStreamReader(&file); + file.open(QIODevice::ReadOnly | QIODevice::Text); + + while (!typeNumberCollector->atEnd() && !typeNumberCollector->hasError()) { + QXmlStreamReader::TokenType token = typeNumberCollector->readNext(); + + if (token == QXmlStreamReader::StartElement) { + if (typeNumberCollector->name() == "PointerType") { + if (typeNumberCollector->attributes().value("id").toString() == typeID) { + break; + } + } + } + } + + QString typeNumber = typeNumberCollector->attributes().value("type").toString(); + + file.close(); + delete typeNumberCollector; + + return typeNumber; } +QString GccXmlArchitectureRecoveryBackendPlugin::findType(const QString &typeNumber) +{ + QFile file(_rootProjectDir.absolutePath() + "/" + _xmlFileName); + QXmlStreamReader *typeCollector = new QXmlStreamReader(&file); + file.open(QIODevice::ReadOnly | QIODevice::Text); + + while (!typeCollector->atEnd() && !typeCollector->hasError()) { + QXmlStreamReader::TokenType token = typeCollector->readNext(); + + if (token == QXmlStreamReader::StartElement) { + if (typeCollector->name() == "Class") { + if (typeCollector->attributes().value("id").toString() == typeNumber) { + break; + } + } + } + } + + QString type = typeCollector->attributes().value("name").toString(); + + file.close(); + delete typeCollector; + + return type; +} + +} diff --git a/examples/uml/duse-mt/src/plugins/gccxmlarchitecturerecoverybackend/gccxmlarchitecturerecoverybackendplugin.h b/examples/uml/duse-mt/src/plugins/gccxmlarchitecturerecoverybackend/gccxmlarchitecturerecoverybackendplugin.h index 642bb5cb..8c14f3c1 100644 --- a/examples/uml/duse-mt/src/plugins/gccxmlarchitecturerecoverybackend/gccxmlarchitecturerecoverybackendplugin.h +++ b/examples/uml/duse-mt/src/plugins/gccxmlarchitecturerecoverybackend/gccxmlarchitecturerecoverybackendplugin.h @@ -45,8 +45,11 @@ #include #include +#include #include #include +#include +#include QT_BEGIN_NAMESPACE class QXmlStreamReader; @@ -76,14 +79,24 @@ private Q_SLOTS: private: QStringList generateXmlFiles(const QStringList &codeFiles) const; bool openXmlFile(const QString &filePath); - QStringList findConstructorsFromXml(QString xmlFile); - QObject *extractComponent(QString xmlFile); + QStringList findConstructorsFromXml(); + QObject *extractComponent(); + void findFunctionsFromXml(QObject *component); + QHash > classFunctionsContainer(QString xmlAttribute, QHash > &classFunctions); + void findFunctionParameters(const QString &functionName, QMultiHash &function); + QString findTypeNumber(const QString &typeID); + QString findType(const QString &typeNumber); QDir _rootProjectDir; QFile _xmlFile; + QString _xmlFileName; QXmlStreamReader *_xmlReader; }; -} +typedef QHash > ClassFunctions; #endif // GCCXMLARCHITECTURERECOVERYBACKENDPLUGIN + +} + +Q_DECLARE_METATYPE(DuSE::ClassFunctions); -- cgit v1.2.3