/tests/auto/icheckbuild/parsemanager.cpp
C++ | 1531 lines | 1162 code | 102 blank | 267 comment | 253 complexity | 98726de61b6fc844b4807c9bc07356af MD5 | raw file
Possible License(s): LGPL-2.1
Large files files are truncated, but you can click here to view the full file
- /**************************************************************************
- **
- ** This file is part of Qt Creator
- **
- ** Copyright (c) 2012 Nokia Corporation and/or its subsidiary(-ies).
- **
- ** Contact: Nokia Corporation (qt-info@nokia.com)
- **
- **
- ** GNU Lesser General Public License Usage
- **
- ** This file may be used under the terms of the GNU Lesser General Public
- ** License version 2.1 as published by the Free Software Foundation and
- ** appearing in the file LICENSE.LGPL included in the packaging of this file.
- ** Please review the following information to ensure the GNU Lesser General
- ** Public License version 2.1 requirements will be met:
- ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
- **
- ** In addition, as a special exception, Nokia gives you certain additional
- ** rights. These rights are described in the Nokia Qt LGPL Exception
- ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
- **
- ** Other Usage
- **
- ** Alternatively, this file may be used in accordance with the terms and
- ** conditions contained in a signed written agreement between you and Nokia.
- **
- ** If you have questions regarding the use of this file, please contact
- ** Nokia at qt-info@nokia.com.
- **
- **************************************************************************/
- #include "parsemanager.h"
- #include "cplusplus/CppDocument.h"
- #include "Control.h"
- #include "Literals.h"
- #include "Overview.h"
- #include "Scope.h"
- #include "TranslationUnit.h"
- #include "AST.h"
- #include "Symbols.h"
- #include "Bind.h"
- #include <QDebug>
- #include "Name.h"
- #include "cpptools/cppmodelmanager.h"
- #include <QTextStream>
- using namespace CppTools;
- using namespace CppTools::Internal;
- using namespace CPlusPlus;
- //<------------------------------------------------------- Compare function for the internal structures
- /**********************************
- Compares function with function
- with return type, function name
- and their arguments and arguments
- types.
- **********************************/
- bool FUNCTIONITEM::isEqualTo(FUNCTIONITEM *cpfct, bool ignoreName/* = true*/)
- {
- if(ignoreName)
- return function->isEqualTo(cpfct->function, true);
- return function->isEqualTo(cpfct->function);
- }
- /*****************************************************************
- Compares two property regarding
- of their function definition,
- type definition, function arguments
- and function types.
- Q_PROPERTY( ConnectionState state READ state NOTIFY stateChanged);
- ******************************************************************/
- bool PROPERTYITEM::isEqualTo(PROPERTYITEM *cpppt)
- {
- if (!ast->type_id || !cpppt->ast->type_id)
- return false;
- if (type != cpppt->type)
- return false;
- if (!ast->property_name || !ast->property_name->name || !ast->property_name->name->identifier())
- return false;
- QString thistypename = ast->property_name->name->identifier()->chars();
- if (!cpppt->ast->property_name || !cpppt->ast->property_name->name || !cpppt->ast->property_name->name->identifier())
- return false;
- QString cppttypename = cpppt->ast->property_name->name->identifier()->chars();
- if(thistypename != cppttypename)
- return false;
- if ((this->readAst == 0) != (cpppt->readAst == 0))
- return false;
- if((this->writeAst == 0) != (cpppt->writeAst == 0))
- return false;
- if((this->resetAst == 0) != (cpppt->resetAst == 0))
- return false;
- if((this->notifyAst == 0) != (cpppt->notifyAst == 0))
- return false;
- //check for read function
- if(this->readAst){
- if(!this->readFct || !cpppt->readFct)
- return false;
- if(!this->readFct->isEqualTo(cpppt->readFct))
- return false;
- }
- //check for write function
- if(this->writeAst){
- if(!this->writeFct || !cpppt->writeFct)
- return false;
- if(!this->writeFct->isEqualTo(cpppt->writeFct))
- return false;
- }
- //check for reset function
- if(this->resetAst){
- if(!this->resetFct || !cpppt->resetFct)
- return false;
- if(!this->resetFct->isEqualTo(cpppt->resetFct))
- return false;
- }
- //check for notify function
- if(this->notifyAst){
- if(!this->notifyFct || !cpppt->notifyFct)
- return false;
- if(!this->notifyFct->isEqualTo(cpppt->notifyFct))
- return false;
- }
- return true;
- }
- /*****************************************************************
- Compares two enums regarding
- of their values created by the getEnumValueStringList function.
- *****************************************************************/
- bool QENUMITEM::isEqualTo(QENUMITEM *cpenum)
- {
- if(this->values.count() != cpenum->values.count())
- return false;
- foreach(QString str, this->values){
- if(!cpenum->values.contains(str))
- return false;
- }
- return true;
- }
- /*****************************************************************
- Compares two flags regarding
- of their enum definitions and their
- values created by the getEnumValueStringList function.
- *****************************************************************/
- bool QFLAGITEM::isEqualTo(QFLAGITEM *cpflag)
- {
- if(this->enumvalues.count() != cpflag->enumvalues.count())
- return false;
- foreach(QString str, this->enumvalues){
- if(!cpflag->enumvalues.contains(str))
- return false;
- }
- return true;
- }
- ParseManager::ParseManager()
- : pCppPreprocessor(0)
- {
- }
- ParseManager::~ParseManager()
- {
- if(pCppPreprocessor)
- delete pCppPreprocessor;
- if(::m_resultFile){
- ::m_resultFile->close();
- delete ::m_resultFile;
- ::m_resultFile = 0;
- }
- }
- /**************************************
- Function for setting the include
- Paths
- **************************************/
- void ParseManager::setIncludePath(const QStringList &includePath)
- {
- m_includePaths = includePath;
- }
- /**************************************
- public Function that starts the parsing
- all of the files in the sourceFiles
- string list.
- **************************************/
- void ParseManager::parse(const QStringList &sourceFiles)
- {
- m_errormsgs.clear();
- if(pCppPreprocessor){
- delete pCppPreprocessor;
- pCppPreprocessor = 0;
- }
- if (! sourceFiles.isEmpty()) {
- m_strHeaderFile = sourceFiles[0];
- pCppPreprocessor = new CppTools::Internal::CppPreprocessor(QPointer<CPlusPlus::ParseManager>(this));
- pCppPreprocessor->setIncludePaths(m_includePaths);
- pCppPreprocessor->setFrameworkPaths(m_frameworkPaths);
- parse(pCppPreprocessor, sourceFiles);
- }
- }
- /*********************************************
- private function that prepare the filelist
- to parse and starts the parser.
- *********************************************/
- void ParseManager::parse(CppTools::Internal::CppPreprocessor *preproc,
- const QStringList &files)
- {
- if (files.isEmpty())
- return;
- //check if file is C++ header file
- QStringList headers;
- foreach (const QString &file, files) {
- const QFileInfo fileInfo(file);
- QString ext = fileInfo.suffix();
- if (ext.toLower() == "h")
- headers.append(file);
- }
- foreach (const QString &file, files) {
- preproc->snapshot.remove(file);
- }
- preproc->setTodo(headers);
- QString conf = QLatin1String("<configuration>");
- preproc->run(conf);
- for (int i = 0; i < headers.size(); ++i) {
- QString fileName = headers.at(i);
- preproc->run(fileName);
- }
- }
- //This function creates a class list for each class and its base classes in
- //the header file that needs to be checked.
- //e.g.
- // Cl1 Cl2
- // __|__ __|__
- // | | | |
- // Cl11 Cl12 Cl21 Cl22
- //
- //==> list[0] = {Cl1, Cl11, Cl12}
- // list[1] = {Cl2, Cl21, Cl22}
- QList<CLASSTREE*> ParseManager::CreateClassLists(bool isInterfaceHeader)
- {
- QList<CLASSTREE*>ret;
- QList<CLASSLISTITEM*> classlist;
- QList<CLASSLISTITEM*> allclasslist;
- Trace("Following classes scaned for header file: " + m_strHeaderFile);
- //Iteration over all parsed documents
- if(getPreProcessor()){
- for (Snapshot::const_iterator it = getPreProcessor()->snapshot.begin()
- ; it != getPreProcessor()->snapshot.end(); ++it)
- {
- Document::Ptr doc = (*it);
- if(doc){
- QFileInfo fileinf(doc->fileName());
- QFileInfo fileinf1(m_strHeaderFile);
- //Get the Translated unit
- Control* ctrl = doc->control();
- TranslationUnit* trlUnit = ctrl->translationUnit();
- AST* pAst = trlUnit->ast();
- TranslationUnitAST *ptrAst = 0;
- if(pAst && (ptrAst = pAst->asTranslationUnit())){
- //iteration over all translated declaration in this document
- for (DeclarationListAST *pDecllist = ptrAst->declaration_list; pDecllist; pDecllist = pDecllist->next) {
- if(pDecllist->value){
- SimpleDeclarationAST *pSimpleDec = pDecllist->value->asSimpleDeclaration();
- if(pSimpleDec){
- //Iteration over class specifier
- for (SpecifierListAST *pSimpleDecDecllist = pSimpleDec->decl_specifier_list; pSimpleDecDecllist; pSimpleDecDecllist = pSimpleDecDecllist->next) {
- ClassSpecifierAST * pclassspec = pSimpleDecDecllist->value->asClassSpecifier();
- if(pclassspec){
- CLASSLISTITEM* item = new CLASSLISTITEM();
- item->classspec = pclassspec;
- item->trlUnit = trlUnit;
- allclasslist.push_back(item);
- QString classname = item->trlUnit->spell(item->classspec->name->firstToken());
- Trace("- " + classname + " class scaned");
- //We found a class that is defined in the header file that needs to be checked
- if(fileinf.fileName().toLower() == fileinf1.fileName().toLower()){
- CLASSTREE* cltree = new CLASSTREE();
- cltree->highestlevelclass = item;
- cltree->classlist.push_back(item);
- ret.push_back(cltree);
- }
- }
- }
- }
- }
- }
- }
- }
- }
- }
- //after we search for the classes we need to search for the baseclasses
- Trace("Following classes found in Header file: " + m_strHeaderFile);
- foreach(CLASSTREE *cltree, ret){
- QString classname = cltree->highestlevelclass->trlUnit->spell(cltree->highestlevelclass->classspec->name->firstToken());
- Trace("- " + classname + " class found");
- QList<CLASSLISTITEM*> baseclasslist;
- getBaseClasses(cltree->highestlevelclass, baseclasslist, allclasslist, 0, isInterfaceHeader);
- cltree->classlist.append(baseclasslist);
- }
- return ret;
- }
- /********************************************
- Gets all the baseclass from a class and
- add those base classes into the baseclasslist
- ********************************************/
- void ParseManager::getBaseClasses(const CLASSLISTITEM* pclass
- , QList<CLASSLISTITEM*> &baseclasslist
- , const QList<CLASSLISTITEM*> &allclasslist
- , int level
- , bool isInterfaceHeader)
- {
- //iteration over the base_clause_list of the current class
- QString levelmarker = " ";
- for(int i = 0; i < level; i++)
- levelmarker += " ";
- levelmarker += "|- ";
- QList<CLASSLISTITEM*>child;
- for(BaseSpecifierListAST *pBaseSpecList = pclass->classspec->base_clause_list; pBaseSpecList; pBaseSpecList = pBaseSpecList->next)
- {
- BaseSpecifierAST *pBaseSpec = pBaseSpecList->value;
- bool found = false;
- foreach(CLASSLISTITEM* pclspec, allclasslist)
- {
- if(pclspec->classspec->symbol->name()
- && pBaseSpec->symbol->name()
- && pclspec->classspec->symbol->name()->isEqualTo(pBaseSpec->symbol->name()))
- {
- child.push_back(pclspec);
- baseclasslist.push_back(pclspec);
- QString classname = pclspec->trlUnit->spell(pclspec->classspec->name->firstToken());
- Trace(levelmarker + classname + " class found");
- found = true;
- break;
- }
- }
- if(!found && pBaseSpec->name){
- QString classname = pclass->trlUnit->spell(pBaseSpec->name->firstToken());
- if(isInterfaceHeader)
- Trace(levelmarker + classname + " class not found! Interface classes should not be inherited from Qt Objects!");
- else
- Trace(levelmarker + classname + " class not found!");
- }
- }
- //call the function recursive because all the basclasses can have other base classes
- foreach(CLASSLISTITEM* pchclass, child){
- getBaseClasses(pchclass, baseclasslist, allclasslist, ++level, isInterfaceHeader);
- }
- }
- /**************************************************
- This function finds and creates all Elements wich
- are significant for MetaDatas.
- Those element will be added in the aparameter
- lists.
- **************************************************/
- void ParseManager::getElements(QList<FUNCTIONITEM*> &functionlist
- , QList<PROPERTYITEM*> &propertylist
- , QList<QENUMITEM*> &qenumlist
- , QList<ENUMITEM*> &enumlist
- , QList<QFLAGITEM*> &qflaglist
- , QList<QDECLAREFLAGSITEM*> &qdeclareflaglist
- , const QList<CLASSLISTITEM*> classitems
- , const CLASSLISTITEM* highestlevelclass)
- {
- foreach(CLASSLISTITEM* classitem, classitems){
- QString classname = "";
- if(classitem->classspec->name)
- classname = classitem->trlUnit->spell(classitem->classspec->name->firstToken());
- for (DeclarationListAST *pmemberlist = classitem->classspec->member_specifier_list; pmemberlist; pmemberlist = pmemberlist->next) {
- /**********
- Functions
- **********/
- if (FunctionDefinitionAST *pfctdef = pmemberlist->value->asFunctionDefinition()){
- FUNCTIONITEM* item = new FUNCTIONITEM;
- item->trlUnit = classitem->trlUnit;
- item->function = pfctdef->symbol;
- item->classAst = classitem->classspec;
- item->highestlevelclass = highestlevelclass;
- functionlist.push_back(item);
- if(isMetaObjFunction(item))
- Trace(" - " + getTraceFuntionString(item, classname) + " found");
- }
- SimpleDeclarationAST *pdecl = pmemberlist->value->asSimpleDeclaration();
- if(pdecl){
- for(List<Symbol*>* decllist = pdecl->symbols; decllist; decllist = decllist->next)
- {
- Function* pfct = decllist->value->type()->asFunctionType();
- if(pfct){
- FUNCTIONITEM* item = new FUNCTIONITEM();
- item->trlUnit = classitem->trlUnit;
- item->function = pfct;
- item->classAst = classitem->classspec;
- item->highestlevelclass = highestlevelclass;
- functionlist.push_back(item);
- if(isMetaObjFunction(item))
- Trace(" - " + getTraceFuntionString(item, classname) + " found");
- }
- }
- /******
- enum
- ******/
- for(List<SpecifierAST*>* decllist = pdecl->decl_specifier_list; decllist; decllist = decllist->next)
- {
- EnumSpecifierAST * penum = decllist->value->asEnumSpecifier();
- if(penum){
- ENUMITEM* item = new ENUMITEM();
- item->ast = penum;
- item->highestlevelclass = highestlevelclass;
- item->trlUnit = classitem->trlUnit;
- enumlist.push_back(item);
- }
- }
- }
- else{
- /**********
- Q_PROPERTY
- **********/
- if(QtPropertyDeclarationAST *ppdecl = pmemberlist->value->asQtPropertyDeclaration()) {
- propertylist.push_back(PROPERTYITEM::create(ppdecl, highestlevelclass));
- if (ppdecl->property_name && ppdecl->property_name->name && ppdecl->property_name->name->identifier()) {
- Trace(" - Q_PROPERTY: " + QLatin1String(ppdecl->property_name->name->identifier()->chars()) + " found");
- }
- } else{
- /**********
- Q_ENUM
- **********/
- if (QtEnumDeclarationAST *pqenum = pmemberlist->value->asQtEnumDeclaration()) {
- for (NameListAST *plist = pqenum->enumerator_list; plist; plist = plist->next) {
- QENUMITEM* item = new QENUMITEM;
- item->name = plist->value->name->identifier()->chars();
- item->highestlevelclass = highestlevelclass;
- qenumlist.push_back(item);
- Trace(" - Q_ENUM: " + classname + "::" + item->name + " found");
- }
- }
- else{
- /**********
- Q_FLAGS
- **********/
- if (QtFlagsDeclarationAST *pqflags = pmemberlist->value->asQtFlagsDeclaration()){
- for (NameListAST *plist = pqflags->flag_enums_list; plist; plist = plist->next) {
- QFLAGITEM* item = new QFLAGITEM;
- item->name = plist->value->name;
- item->highestlevelclass = highestlevelclass;
- qflaglist.push_back(item);
- Trace(" - Q_FLAGS: " + classname + "::" + item->name->identifier()->chars() + " found");
- }
- }
- #if 0
- /*The code for Q_DECLARE_FLAGS was wrong. It's optional, and only does a typedef.
- That means, if you do the typedef yourself and not use Q_DECLARE_FLAGS, that *is* valid.
- Meaning, if one would want to do a check like the ones in this app, one has to check the defined types in the class scope.*/
- else {
- /****************
- Q_DECLARE_FLAGS
- ****************/
- QtDeclareFlagsDeclarationAST *pqdeclflags = pmemberlist->value->asQDeclareFlagsDeclarationAST();
- if(pqdeclflags){
- QDECLAREFLAGSITEM* item = new QDECLAREFLAGSITEM();
- item->ast = pqdeclflags;
- item->highestlevelclass = highestlevelclass;
- item->trlUnit = classitem->trlUnit;
- qdeclareflaglist.push_back(item);
- }
- }
- #endif
- }
- }
- }
- }
- }
- }
- /*********************************************
- Function that starts the comare between the
- parser result and their metadata content.
- *********************************************/
- bool ParseManager::checkAllMetadatas(ParseManager* pInterfaceParserManager, QString resultfile)
- {
- bool ret = true;
- //Create output file
- if(resultfile != "" && ::m_resultFile == 0){
- ::m_resultFile = new QFile(resultfile);
- if (!::m_resultFile->open(QFile::WriteOnly | QFile::Truncate)) {
- delete ::m_resultFile;
- ::m_resultFile = 0;
- }
- }
- /************************************************
- Get all elements from the interface header file
- ************************************************/
- Trace("### Get all elements from the interface header file ###");
- QList<CLASSTREE*> ilookuplist = pInterfaceParserManager->CreateClassLists(true);
- QList<QList<FUNCTIONITEM*> > ifunctionslookuplist;
- QList<QList<PROPERTYITEM*> > ipropertieslookuplist;
- QList<QList<QENUMITEM*> > iqenumlookuplist;
- QList<QList<ENUMITEM*> > ienumlookuplist;
- QList<QList<QFLAGITEM*> > iqflaglookuplist;
- QList<QList<QDECLAREFLAGSITEM*> > iqdeclareflaglookuplist;
- Trace("Following MetaData found:");
- foreach(CLASSTREE* iclasstree, ilookuplist){
- QList<FUNCTIONITEM*>functionlist;
- QList<PROPERTYITEM*>propertylist;
- QList<QENUMITEM*>qenumlist;
- QList<ENUMITEM*>enumlist;
- QList<QFLAGITEM*> qflaglist;
- QList<QDECLAREFLAGSITEM*> qdeclareflag;
- getElements(functionlist
- , propertylist
- , qenumlist
- , enumlist
- , qflaglist
- , qdeclareflag
- , iclasstree->classlist
- , iclasstree->highestlevelclass);
- if(functionlist.size() > 0)
- ifunctionslookuplist.append(functionlist);
- if(propertylist.size() > 0)
- ipropertieslookuplist.append(propertylist);
- if(qenumlist.size() > 0)
- iqenumlookuplist.append(qenumlist);
- if(enumlist.size() > 0)
- ienumlookuplist.append(enumlist);
- if(qflaglist.size() > 0)
- iqflaglookuplist.append(qflaglist);
- if(qdeclareflag.size() > 0)
- iqdeclareflaglookuplist.append(qdeclareflag);
- }
- /************************************************
- Get all elements from the compare header file
- ************************************************/
- Trace("\n");
- Trace("### Get all elements from the compare header file ###");
- QList<CLASSTREE*> lookuplist = CreateClassLists(false);
- QList<QList<FUNCTIONITEM*> > functionslookuplist;
- QList<QList<PROPERTYITEM*> > propertieslookuplist;
- QList<QList<QENUMITEM*> > qenumlookuplist;
- QList<QList<ENUMITEM*> > enumlookuplist;
- QList<QList<QFLAGITEM*> > qflaglookuplist;
- QList<QList<QDECLAREFLAGSITEM*> > qdeclareflaglookuplist;
- Trace("Following MetaData found:");
- foreach(CLASSTREE* classtree, lookuplist){
- QList<FUNCTIONITEM*>functionlist;
- QList<PROPERTYITEM*>propertylist;
- QList<QENUMITEM*>qenumlist;
- QList<ENUMITEM*>enumlist;
- QList<QFLAGITEM*> qflaglist;
- QList<QDECLAREFLAGSITEM*> qdeclareflag;
- getElements(functionlist
- , propertylist
- , qenumlist
- , enumlist
- , qflaglist
- , qdeclareflag
- , classtree->classlist
- , classtree->highestlevelclass);
- if(functionlist.size() > 0)
- functionslookuplist.append(functionlist);
- if(propertylist.size() > 0)
- propertieslookuplist.append(propertylist);
- if(qenumlist.size() > 0)
- qenumlookuplist.append(qenumlist);
- if(enumlist.size() > 0)
- enumlookuplist.append(enumlist);
- if(qflaglist.size() > 0)
- qflaglookuplist.append(qflaglist);
- if(qdeclareflag.size() > 0)
- qdeclareflaglookuplist.append(qdeclareflag);
- }
- Trace("\n");
- Trace("### Result: ###");
- /******************************
- Check for function
- ******************************/
- Trace("Compare all interface MetaData functions:");
- QList<FUNCTIONITEM*> missingifcts = checkMetadataFunctions(functionslookuplist, ifunctionslookuplist);
- if(missingifcts.size() > 0){
- foreach(FUNCTIONITEM* ifct, missingifcts){
- m_errormsgs.append(getErrorMessage(ifct));
- }
- ret = false;
- Trace("- Failed!");
- }
- else{
- Trace("- OK");
- }
- /******************************
- Check for properies
- ******************************/
- Trace("Compare all interface MetaData properties:");
- QList<PROPERTYITEM*> missingippts = checkMetadataProperties(propertieslookuplist, functionslookuplist, ipropertieslookuplist, ifunctionslookuplist);
- if(missingippts.size() > 0){
- foreach(PROPERTYITEM* ippt, missingippts){
- m_errormsgs.append(getErrorMessage(ippt));
- }
- ret = false;
- Trace("- Failed!");
- }
- else{
- Trace("- OK");
- }
- /******************************
- Check for enums
- ******************************/
- Trace("Compare all interface MetaData enums:");
- QList<QENUMITEM*> missingiqenums = checkMetadataEnums(qenumlookuplist, enumlookuplist, iqenumlookuplist, ienumlookuplist);
- if(missingiqenums.size() > 0){
- foreach(QENUMITEM* ienum, missingiqenums){
- m_errormsgs.append(getErrorMessage(ienum));
- }
- ret = false;
- Trace("- Failed!");
- }
- else{
- Trace("- OK");
- }
- /******************************
- Check for flags
- ******************************/
- Trace("Compare all interface MetaData flags:");
- QList<QFLAGITEM*> missingiqflags = checkMetadataFlags(qflaglookuplist, qdeclareflaglookuplist, enumlookuplist
- , iqflaglookuplist, iqdeclareflaglookuplist, ienumlookuplist);
- if(missingiqflags.size() > 0){
- foreach(QFLAGITEM* iflags, missingiqflags){
- m_errormsgs.append(getErrorMessage(iflags));
- }
- ret = false;
- Trace("- Failed!");
- }
- else{
- Trace("- OK");
- }
- /******************************
- Add summary
- ******************************/
- Trace("\n");
- Trace("### summary ###");
- if(m_errormsgs.size() > 0){
- Trace("- Folowing interface items are missing:");
- foreach(QString msg, m_errormsgs)
- Trace(" - " + msg);
- }
- else
- Trace("Interface is full defined.");
- //now delet all Classitems
- foreach(CLASSTREE* l, ilookuplist){
- l->classlist.clear();
- }
- foreach(CLASSTREE* l, lookuplist){
- l->classlist.clear();
- }
- //delete all functionitems
- foreach(QList<FUNCTIONITEM*>l, ifunctionslookuplist){
- l.clear();
- }
- foreach(QList<FUNCTIONITEM*>l, functionslookuplist){
- l.clear();
- }
- //delete all properties
- foreach(QList<PROPERTYITEM*>l, ipropertieslookuplist){
- l.clear();
- }
- foreach(QList<PROPERTYITEM*>l, propertieslookuplist){
- l.clear();
- }
- //delete all qenums
- foreach(QList<QENUMITEM*>l, iqenumlookuplist){
- l.clear();
- }
- foreach(QList<QENUMITEM*>l, iqenumlookuplist){
- l.clear();
- }
- //delete all enums
- foreach(QList<ENUMITEM*>l, ienumlookuplist){
- l.clear();
- }
- foreach(QList<ENUMITEM*>l, enumlookuplist){
- l.clear();
- }
- //delete all qflags
- foreach(QList<QFLAGITEM*>l, iqflaglookuplist){
- l.clear();
- }
- foreach(QList<QFLAGITEM*>l, qflaglookuplist){
- l.clear();
- }
- //delete all qdeclareflags
- foreach(QList<QDECLAREFLAGSITEM*>l, iqdeclareflaglookuplist){
- l.clear();
- }
- foreach(QList<QDECLAREFLAGSITEM*>l, qdeclareflaglookuplist){
- l.clear();
- }
- return ret;
- }
- //<------------------------------------------------------- Start of MetaData functions
- /***********************************
- Function that checks all functions
- which will occur in the MetaData
- ***********************************/
- QList<FUNCTIONITEM*> ParseManager::checkMetadataFunctions(const QList<QList<FUNCTIONITEM*> > &classfctlist, const QList<QList<FUNCTIONITEM*> > &iclassfctlist)
- {
- QList<FUNCTIONITEM*> missingifcts;
- //Compare each function from interface with function from header (incl. baseclass functions)
- QList<FUNCTIONITEM*> ifcts;
- foreach(QList<FUNCTIONITEM*>ifunctionlist, iclassfctlist){
- ifcts.clear();
- //check if one header class contains all function from one interface header class
- if(classfctlist.count() > 0){
- foreach(QList<FUNCTIONITEM*>functionlist, classfctlist){
- QList<FUNCTIONITEM*> tmpl = containsAllMetadataFunction(functionlist, ifunctionlist);
- if(tmpl.size() == 0){
- ifcts.clear();
- break;
- }
- else
- ifcts.append(tmpl);
- }
- }
- else {
- foreach(FUNCTIONITEM *pfct, ifunctionlist)
- pfct->classWichIsNotFound << "<all classes>";
- ifcts.append(ifunctionlist);
- }
- missingifcts.append(ifcts);
- }
- return missingifcts;
- }
- /*********************************************
- Helper function to check if a function will
- occure in the MetaData.
- *********************************************/
- bool ParseManager::isMetaObjFunction(FUNCTIONITEM* fct)
- {
- if(fct->function->isInvokable()
- || fct->function->isSignal()
- || fct->function->isSlot())
- return true;
- return false;
- }
- /****************************************************
- Check if all function from iclassfctlist are defined
- in the classfctlist as well.
- It will return all the function they are missing.
- ****************************************************/
- QList<FUNCTIONITEM*> ParseManager::containsAllMetadataFunction(const QList<FUNCTIONITEM*> &classfctlist, const QList<FUNCTIONITEM*> &iclassfctlist)
- {
- QList<FUNCTIONITEM*> ret;
- foreach(FUNCTIONITEM* ifct, iclassfctlist){
- if(isMetaObjFunction(ifct)){
- bool found = false;
- QStringList missingimplinclasses;
- ClassSpecifierAST* clspec = 0;
- QString classname = "";
- foreach(FUNCTIONITEM* fct, classfctlist){
- if(clspec != fct->highestlevelclass->classspec){
- clspec = fct->highestlevelclass->classspec;
- //get the classname
- unsigned int firsttoken = clspec->name->firstToken();
- classname += fct->trlUnit->spell(firsttoken);
- if(missingimplinclasses.indexOf(classname) < 0)
- missingimplinclasses.push_back(classname);
- }
- if(fct->isEqualTo(ifct, false)){
- found = true;
- missingimplinclasses.clear();
- Trace("- " + getTraceFuntionString(fct, classname) + " implemented");
- break;
- }
- }
- if(!found){
- ifct->classWichIsNotFound.append(missingimplinclasses);
- ret.push_back(ifct);
- QString classname = ifct->trlUnit->spell(ifct->highestlevelclass->classspec->name->firstToken());
- Trace("- " + getTraceFuntionString(ifct, classname) + " not implemented!");
- }
- }
- }
- return ret;
- }
- /************************************
- Function that gives back an error
- string for a MetaData function
- mismatch.
- ************************************/
- QStringList ParseManager::getErrorMessage(FUNCTIONITEM* fct)
- {
- QStringList ret;
- QString fctstring = "";
- QString fcttype = "";
- foreach(QString classname, fct->classWichIsNotFound){
- QString tmp;
- QTextStream out(&tmp);
- fcttype = "";
- fctstring = classname;
- fctstring += "::";
- unsigned int token = fct->function->sourceLocation() - 1;
- while(fct->trlUnit->tokenAt(token).isNot(T_EOF_SYMBOL)){
- fctstring += fct->trlUnit->tokenAt(token).spell();
- if(*fct->trlUnit->tokenAt(token).spell() == ')')
- break;
- fctstring += " ";
- token++;
- }
- Function* pfct = fct->function;
- if(pfct){
- fcttype = "type: ";
- //Check for private, protected and public
- if(pfct->isPublic())
- fcttype = "public ";
- if(pfct->isProtected())
- fcttype = "protected ";
- if(pfct->isPrivate())
- fcttype = "private ";
- if(pfct->isVirtual())
- fcttype += "virtual ";
- if(pfct->isPureVirtual())
- fcttype += "pure virtual ";
- if(pfct->isSignal())
- fcttype += "Signal ";
- if(pfct->isSlot())
- fcttype += "Slot ";
- if(pfct->isNormal())
- fcttype += "Normal ";
- if(pfct->isInvokable())
- fcttype += "Invokable ";
- }
- out << fcttype << fctstring;
- ret << tmp;
- }
- return ret;
- }
- //--->
- //<------------------------------------------------------- Start of Q_PROPERTY checks
- /***********************************
- Function that checks all Property
- which will occur in the MetaData
- ***********************************/
- QList<PROPERTYITEM*> ParseManager::checkMetadataProperties(const QList<QList<PROPERTYITEM*> > &classproplist
- , const QList<QList<FUNCTIONITEM*> > &classfctlist
- , const QList<QList<PROPERTYITEM*> > &iclassproplist
- , const QList<QList<FUNCTIONITEM*> > &iclassfctlist)
- {
- QList<PROPERTYITEM*> missingiprops;
- //assign the property functions
- foreach(QList<PROPERTYITEM*>proplist, classproplist){
- foreach(PROPERTYITEM* prop, proplist){
- assignPropertyFunctions(prop, classfctlist);
- }
- }
- foreach(QList<PROPERTYITEM*>proplist, iclassproplist){
- foreach(PROPERTYITEM* prop, proplist){
- assignPropertyFunctions(prop, iclassfctlist);
- }
- }
- //Compare each qproperty from interface with qproperty from header (incl. baseclass functions)
- QList<PROPERTYITEM*> ippts;
- foreach(QList<PROPERTYITEM*>ipropertylist, iclassproplist){
- ippts.clear();
- //check if one header class contains all function from one interface header class
- if(classproplist.count() > 0){
- foreach(QList<PROPERTYITEM*>propertylist, classproplist){
- QList<PROPERTYITEM*> tmpl = containsAllPropertyFunction(propertylist, ipropertylist);
- if(tmpl.size() == 0)
- ippts.clear();
- else
- ippts.append(tmpl);
- }
- }
- else {
- foreach(PROPERTYITEM *pprop, ipropertylist){
- pprop->classWichIsNotFound << "<all classes>";
- QString name = pprop->ast->property_name->name->identifier()->chars();
- Trace("- Property: <all classes>::" + name + " not found!");
- }
- ippts.append(ipropertylist);
- }
- missingiprops.append(ippts);
- }
- return missingiprops;
- }
- static QString findName(ExpressionAST *ast)
- {
- // The "old" icheck code assumed that functions were only a single identifier, so I'll assume the same:
- if (NameAST *nameAST = ast->asName())
- return nameAST->name->identifier()->chars();
- else
- return QString();
- }
- /**************************************
- Function that resolves the dependensies
- between Q_PROPERTY
- and thier READ, WRITE, NOTIFY and RESET
- functions.
- ***************************************/
- void ParseManager::assignPropertyFunctions(PROPERTYITEM* prop, const QList<QList<FUNCTIONITEM*> > &fctlookuplist)
- {
- //get the name of the needed functions
- QString readfctname;
- QString writefctname;
- QString resetfctname;
- QString notifyfctname;
- int needtofind = 0;
- if(prop->readAst){
- readfctname = findName(prop->readAst);
- needtofind++;
- }
- if(prop->writeAst){
- writefctname = findName(prop->writeAst);
- needtofind++;
- }
- if(prop->resetAst){
- resetfctname = findName(prop->resetAst);
- needtofind++;
- }
- if(prop->notifyAst){
- notifyfctname = findName(prop->notifyAst);
- needtofind++;
- }
- //Now iterate over all function to find all functions wich are defined in the Q_PROPERTY macro
- if(needtofind > 0){
- prop->foundalldefinedfct = false;
- foreach(QList<FUNCTIONITEM*> fctlist, fctlookuplist){
- foreach(FUNCTIONITEM* pfct, fctlist){
- QString fctname = pfct->trlUnit->spell(pfct->function->sourceLocation());
- //check the function type against the property type
- FullySpecifiedType retTy = pfct->function->returnType();
- if (!fctname.isEmpty() && retTy.isValid()) {
- if(prop->readAst && fctname == readfctname){
- if (prop->type != retTy)
- continue;
- prop->readFct = pfct;
- needtofind--;
- }
- if(prop->writeAst && fctname == writefctname){
- prop->writeFct = pfct;
- needtofind--;
- }
- if(prop->resetAst && fctname == resetfctname){
- prop->resetFct = pfct;
- needtofind--;
- }
- if(prop->notifyAst && fctname == notifyfctname){
- prop->notifyFct = pfct;
- needtofind--;
- }
- if(needtofind <= 0){
- //a flag that indicates if a function was missing
- prop->foundalldefinedfct = true;
- return;
- }
- }
- }
- }
- }
- }
- /**************************************
- Function that checks if all functions
- dependencies in Q_PROPERTY have the
- same arguments and retunr value.
- ***************************************/
- QList<PROPERTYITEM*> ParseManager::containsAllPropertyFunction(const QList<PROPERTYITEM*> &classproplist, const QList<PROPERTYITEM*> &iclassproplist)
- {
- QList<PROPERTYITEM*> ret;
- foreach(PROPERTYITEM* ipropt, iclassproplist){
- if(ipropt->foundalldefinedfct){
- bool found = false;
- QStringList missingimplinclasses;
- ClassSpecifierAST* clspec = 0;
- QString classname = "";
- foreach(PROPERTYITEM* propt, classproplist){
- if(clspec != propt->highestlevelclass->classspec){
- clspec = propt->highestlevelclass->classspec;
- //get the classname
- unsigned int firsttoken = clspec->name->firstToken();
- classname += propt->trlUnit->spell(firsttoken);
- if(missingimplinclasses.indexOf(classname) < 0)
- missingimplinclasses.push_back(classname);
- }
- if(propt->isEqualTo(ipropt)){
- found = true;
- missingimplinclasses.clear();
- Trace("- Property: " + classname + "::" + propt->ast->property_name->name->identifier()->chars() + " found");
- break;
- }
- }
- if(!found){
- ipropt->classWichIsNotFound.append(missingimplinclasses);
- ret.push_back(ipropt);
- QString classname = ipropt->trlUnit->spell(ipropt->highestlevelclass->classspec->name->firstToken());
- Trace("- Property: " + classname + "::" + ipropt->ast->property_name->name->identifier()->chars() + " not found!");
- }
- }
- else{
- QString classname = ipropt->trlUnit->spell(ipropt->highestlevelclass->classspec->name->firstToken());
- Overview oo;
- QString proptype = oo(ipropt->type);
- Trace("- Property: " + classname + "::" + proptype + " functions are missing!");
- ret.push_back(ipropt);
- }
- }
- return ret;
- }
- /************************************
- Function that gives back an error
- string for a Q_PROPERTY mismatch.
- ************************************/
- QStringList ParseManager::getErrorMessage(PROPERTYITEM* ppt)
- {
- QStringList ret;
- QString pptstring = "";
- if(!ppt->foundalldefinedfct)
- {
- QString tmp;
- QTextStream out(&tmp);
- unsigned int firsttoken = ppt->highestlevelclass->classspec->name->firstToken();
- unsigned int lasttoken = ppt->highestlevelclass->classspec->name->lastToken();
- for(unsigned int i = firsttoken; i < lasttoken; i++){
- out << ppt->trlUnit->spell(i);
- }
- out << "::";
- firsttoken = ppt->ast->firstToken();
- lasttoken = ppt->ast->lastToken();
- for(unsigned int i = firsttoken; i <= lasttoken; i++){
- out << ppt->trlUnit->spell(i) << " ";
- }
- out << endl << " -";
- if(ppt->readAst && !ppt->readFct)
- out << "READ ";
- if(ppt->writeAst && !ppt->writeFct)
- out << "WRITE ";
- if(ppt->resetAst && !ppt->resetFct)
- out << "RESET.";
- if(ppt->notifyAst && !ppt->notifyFct)
- out << "NOTIFY ";
- out << "functions missing." << endl;
- ret << tmp;
- }
- for(int i = 0; i < ppt->classWichIsNotFound.size(); i++){
- QString tmp;
- QTextStream out(&tmp);
- pptstring = ppt->classWichIsNotFound[i];
- pptstring += "::";
- unsigned int firsttoken = ppt->ast->firstToken();
- unsigned int lasttoken = ppt->ast->lastToken();
- for(unsigned int i = firsttoken; i <= lasttoken; i++){
- pptstring += ppt->trlUnit->spell(i);
- pptstring += " ";
- }
- out << pptstring;
- ret << tmp;
- }
- return ret;
- }
- //--->
- //<------------------------------------------------------- Start of Q_ENUMS checks
- /***********************************
- Function that checks all enums
- which will occur in the MetaData
- ***********************************/
- QList<QENUMITEM*> ParseManager::checkMetadataEnums(const QList<QList<QENUMITEM*> > &classqenumlist
- , const QList<QList<ENUMITEM*> > &classenumlist
- , const QList<QList<QENUMITEM*> > &iclassqenumlist
- , const QList<QList<ENUMITEM*> > &iclassenumlist)
- {
- QList<QENUMITEM*> missingiqenums;
- //assign the property functions
- foreach(QList<QENUMITEM*>qenumlist, classqenumlist){
- foreach(QENUMITEM* qenum, qenumlist){
- assignEnumValues(qenum, classenumlist);
- }
- }
- foreach(QList<QENUMITEM*>qenumlist, iclassqenumlist){
- foreach(QENUMITEM* qenum, qenumlist){
- assignEnumValues(qenum, iclassenumlist);
- }
- }
- //Compare each qenum from interface with qenum from header (incl. baseclass functions)
- QList<QENUMITEM*> iqenums;
- foreach(QList<QENUMITEM*>iqenumlist, iclassqenumlist){
- iqenums.clear();
- //check if one header class contains all function from one interface header class
- if(classqenumlist.count() > 0){
- foreach(QList<QENUMITEM*>qenumlist, classqenumlist){
- QList<QENUMITEM*> tmpl = containsAllEnums(qenumlist, iqenumlist);
- if(tmpl.size() == 0)
- iqenums.clear();
- else
- iqenums.append(tmpl);
- }
- }
- else {
- foreach(QENUMITEM *qenum, iqenumlist){
- qenum->classWichIsNotFound << "<all classes>";
- Trace("- Enum: <all classes>::" + qenum->name + " not found!");
- }
- iqenums.append(iqenumlist);
- }
- missingiqenums.append(iqenums);
- }
- return missingiqenums;
- }
- /*********************************************
- Helper function which creates a string out of
- an enumerator including its values.
- *********************************************/
- QStringList ParseManager::getEnumValueStringList(ENUMITEM *penum, QString mappedenumname/* = ""*/)
- {
- QStringList ret;
- EnumSpecifierAST *penumsec = penum->ast;
- QString enumname = penum->trlUnit->spell(penumsec->name->firstToken());
- int enumvalue = 0;
- //now iterrate over all enumitems and create a string like following:
- //EnumName.EnumItemName.Value
- //ConnectionState.disconnected.0
- for (EnumeratorListAST *plist = penum->ast->enumerator_list; plist; plist = plist->next) {
- QString value = enumname;
- if(mappedenumname.size() > 0)
- value = mappedenumname;
- value += ".";
- value += penum->trlUnit->spell(plist->value->identifier_token);
- value += ".";
- if(plist->value->equal_token > 0 && plist->value->expression){
- QString v = penum->trlUnit->spell(plist->value->expression->firstToken());
- bool ch;
- int newval = enumvalue;
- if(v.indexOf("0x") >= 0)
- newval = v.toInt(&ch, 16);
- else
- newval = v.toInt(&ch, 10);
- if(ch)
- enumvalue = newval;
- }
- value += QString::number(enumvalue);
- enumvalue++;
- // now add this enumitem string in the VALUE list
- ret << value;
- }
- return ret;
- }
- /**************************************
- Function that resolves the dependensies
- between Q_ENUMS and enums.
- ***************************************/
- void ParseManager::assignEnumValues(QENUMITEM* qenum, const QList<QList<ENUMITEM*> > &enumlookuplist)
- {
- //iterate over all enums and find the one with the same name like enumname
- bool found = false;
- foreach (QList<ENUMITEM*> penumlist, enumlookuplist) {
- foreach(ENUMITEM *penum, penumlist){
- EnumSpecifierAST *penumsec = penum->ast;
- QString enumname1 = penum->trlUnit->spell(penumsec->name->firstToken());
- if(qenum->name == enumname1){
- qenum->values << getEnumValueStringList(penum);
- found = true;
- break;
- }
- }
- if(!found)
- qenum->foundallenums = false;
- }
- }
- /***********************************
- Function that checkt if the Q_ENUMS
- are completed defined and if the
- Enum values are the same.
- ***********************************/
- QList<QENUMITEM*> ParseManager::containsAllEnums(const QList<QENUMITEM*> &classqenumlist, const QList<QENUMITEM*> &iclassqenumlist)
- {
- Overview oo;
- QList<QENUMITEM*> ret;
- foreach(QENUMITEM* iqenum, iclassqenumlist){
- bool found = false;
- QStringList missingimplinclasses;
- ClassSpecifierAST* clspec = 0;
- QString classname = "";
- foreach(QENUMITEM* qenum, classqenumlist){
- if(clspec != qenum->highestlevelclass->classspec){
- clspec = qenum->highestlevelclass->classspec;
- //get the classname
- classname += oo(clspec->symbol);
- if(missingimplinclasses.indexOf(classname) < 0)
- missingimplinclasses.push_back(classname);
- }
- if(qenum->isEqualTo(iqenum)){
- found = true;
- missingimplinclasses.clear();
- Trace("- Enum: " + classname + "::" + qenum->name + " found");
- break;
- }
- }
- if(!found){
- iqenum->classWichIsNotFound.append(missingimplinclasses);
- ret.push_back(iqenum);
- QString classname = oo(iqenum->highestlevelclass->classspec->symbol);
- Trace("- Enum: " + classname + "::" + iqenum->name + " not found!");
- }
- }
- return ret;
- }
- /************************************
- Function that gives back an error
- string for a Q_ENUMS mismatch.
- ************************************/
- QStringList ParseManager::getErrorMessage(QENUMITEM* qenum)
- {
- Overview oo;
- QStringList ret;
- if(!qenum->foundallenums)
- {
- QString tmp;
- QTextStream out(&tmp);
- out << oo(qenum->highestlevelclass->classspec->symbol);
- out << "::Q_ENUMS " << qenum->name << " enum missing.";
- ret << tmp;
- }
- for (int i = 0; i < qenum->classWichIsNotFound.size(); i++){
- QString tmp;
- QTextStream out(&tmp);
- out << qenum->classWichIsNotFound[i] << "::Q_ENUMS "
- << qenum->name;
- ret << tmp;
- }
- return ret;
- }
- //--->
- //<------------------------------------------------------- Start of Q_FLAGS checks
- /***********************************
- Function that checks all flags
- which will occur in the MetaData
- ***********************************/
- QList<QFLAGITEM*> ParseManager::checkMetadataFlags(const QList<QList<QFLAGITEM*> > &classqflaglist
- , const QList<QList<QDECLAREFLAGSITEM*> > &classqdeclareflaglist
- , const QList<QList<ENUMITEM*> > &classenumlist
- , const QList<QList<QFLAGITEM*> > &iclassqflaglist
- , const QList<QList<QDECLAREFLAGSITEM*> > &iclassqdeclareflaglist
- , con…
Large files files are truncated, but you can click here to view the full file