PageRenderTime 58ms CodeModel.GetById 14ms RepoModel.GetById 0ms app.codeStats 0ms

/tests/auto/icheckbuild/parsemanager.cpp

https://bitbucket.org/kpozn/qt-creator-py-reborn
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

  1. /**************************************************************************
  2. **
  3. ** This file is part of Qt Creator
  4. **
  5. ** Copyright (c) 2012 Nokia Corporation and/or its subsidiary(-ies).
  6. **
  7. ** Contact: Nokia Corporation (qt-info@nokia.com)
  8. **
  9. **
  10. ** GNU Lesser General Public License Usage
  11. **
  12. ** This file may be used under the terms of the GNU Lesser General Public
  13. ** License version 2.1 as published by the Free Software Foundation and
  14. ** appearing in the file LICENSE.LGPL included in the packaging of this file.
  15. ** Please review the following information to ensure the GNU Lesser General
  16. ** Public License version 2.1 requirements will be met:
  17. ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
  18. **
  19. ** In addition, as a special exception, Nokia gives you certain additional
  20. ** rights. These rights are described in the Nokia Qt LGPL Exception
  21. ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
  22. **
  23. ** Other Usage
  24. **
  25. ** Alternatively, this file may be used in accordance with the terms and
  26. ** conditions contained in a signed written agreement between you and Nokia.
  27. **
  28. ** If you have questions regarding the use of this file, please contact
  29. ** Nokia at qt-info@nokia.com.
  30. **
  31. **************************************************************************/
  32. #include "parsemanager.h"
  33. #include "cplusplus/CppDocument.h"
  34. #include "Control.h"
  35. #include "Literals.h"
  36. #include "Overview.h"
  37. #include "Scope.h"
  38. #include "TranslationUnit.h"
  39. #include "AST.h"
  40. #include "Symbols.h"
  41. #include "Bind.h"
  42. #include <QDebug>
  43. #include "Name.h"
  44. #include "cpptools/cppmodelmanager.h"
  45. #include <QTextStream>
  46. using namespace CppTools;
  47. using namespace CppTools::Internal;
  48. using namespace CPlusPlus;
  49. //<------------------------------------------------------- Compare function for the internal structures
  50. /**********************************
  51. Compares function with function
  52. with return type, function name
  53. and their arguments and arguments
  54. types.
  55. **********************************/
  56. bool FUNCTIONITEM::isEqualTo(FUNCTIONITEM *cpfct, bool ignoreName/* = true*/)
  57. {
  58. if(ignoreName)
  59. return function->isEqualTo(cpfct->function, true);
  60. return function->isEqualTo(cpfct->function);
  61. }
  62. /*****************************************************************
  63. Compares two property regarding
  64. of their function definition,
  65. type definition, function arguments
  66. and function types.
  67. Q_PROPERTY( ConnectionState state READ state NOTIFY stateChanged);
  68. ******************************************************************/
  69. bool PROPERTYITEM::isEqualTo(PROPERTYITEM *cpppt)
  70. {
  71. if (!ast->type_id || !cpppt->ast->type_id)
  72. return false;
  73. if (type != cpppt->type)
  74. return false;
  75. if (!ast->property_name || !ast->property_name->name || !ast->property_name->name->identifier())
  76. return false;
  77. QString thistypename = ast->property_name->name->identifier()->chars();
  78. if (!cpppt->ast->property_name || !cpppt->ast->property_name->name || !cpppt->ast->property_name->name->identifier())
  79. return false;
  80. QString cppttypename = cpppt->ast->property_name->name->identifier()->chars();
  81. if(thistypename != cppttypename)
  82. return false;
  83. if ((this->readAst == 0) != (cpppt->readAst == 0))
  84. return false;
  85. if((this->writeAst == 0) != (cpppt->writeAst == 0))
  86. return false;
  87. if((this->resetAst == 0) != (cpppt->resetAst == 0))
  88. return false;
  89. if((this->notifyAst == 0) != (cpppt->notifyAst == 0))
  90. return false;
  91. //check for read function
  92. if(this->readAst){
  93. if(!this->readFct || !cpppt->readFct)
  94. return false;
  95. if(!this->readFct->isEqualTo(cpppt->readFct))
  96. return false;
  97. }
  98. //check for write function
  99. if(this->writeAst){
  100. if(!this->writeFct || !cpppt->writeFct)
  101. return false;
  102. if(!this->writeFct->isEqualTo(cpppt->writeFct))
  103. return false;
  104. }
  105. //check for reset function
  106. if(this->resetAst){
  107. if(!this->resetFct || !cpppt->resetFct)
  108. return false;
  109. if(!this->resetFct->isEqualTo(cpppt->resetFct))
  110. return false;
  111. }
  112. //check for notify function
  113. if(this->notifyAst){
  114. if(!this->notifyFct || !cpppt->notifyFct)
  115. return false;
  116. if(!this->notifyFct->isEqualTo(cpppt->notifyFct))
  117. return false;
  118. }
  119. return true;
  120. }
  121. /*****************************************************************
  122. Compares two enums regarding
  123. of their values created by the getEnumValueStringList function.
  124. *****************************************************************/
  125. bool QENUMITEM::isEqualTo(QENUMITEM *cpenum)
  126. {
  127. if(this->values.count() != cpenum->values.count())
  128. return false;
  129. foreach(QString str, this->values){
  130. if(!cpenum->values.contains(str))
  131. return false;
  132. }
  133. return true;
  134. }
  135. /*****************************************************************
  136. Compares two flags regarding
  137. of their enum definitions and their
  138. values created by the getEnumValueStringList function.
  139. *****************************************************************/
  140. bool QFLAGITEM::isEqualTo(QFLAGITEM *cpflag)
  141. {
  142. if(this->enumvalues.count() != cpflag->enumvalues.count())
  143. return false;
  144. foreach(QString str, this->enumvalues){
  145. if(!cpflag->enumvalues.contains(str))
  146. return false;
  147. }
  148. return true;
  149. }
  150. ParseManager::ParseManager()
  151. : pCppPreprocessor(0)
  152. {
  153. }
  154. ParseManager::~ParseManager()
  155. {
  156. if(pCppPreprocessor)
  157. delete pCppPreprocessor;
  158. if(::m_resultFile){
  159. ::m_resultFile->close();
  160. delete ::m_resultFile;
  161. ::m_resultFile = 0;
  162. }
  163. }
  164. /**************************************
  165. Function for setting the include
  166. Paths
  167. **************************************/
  168. void ParseManager::setIncludePath(const QStringList &includePath)
  169. {
  170. m_includePaths = includePath;
  171. }
  172. /**************************************
  173. public Function that starts the parsing
  174. all of the files in the sourceFiles
  175. string list.
  176. **************************************/
  177. void ParseManager::parse(const QStringList &sourceFiles)
  178. {
  179. m_errormsgs.clear();
  180. if(pCppPreprocessor){
  181. delete pCppPreprocessor;
  182. pCppPreprocessor = 0;
  183. }
  184. if (! sourceFiles.isEmpty()) {
  185. m_strHeaderFile = sourceFiles[0];
  186. pCppPreprocessor = new CppTools::Internal::CppPreprocessor(QPointer<CPlusPlus::ParseManager>(this));
  187. pCppPreprocessor->setIncludePaths(m_includePaths);
  188. pCppPreprocessor->setFrameworkPaths(m_frameworkPaths);
  189. parse(pCppPreprocessor, sourceFiles);
  190. }
  191. }
  192. /*********************************************
  193. private function that prepare the filelist
  194. to parse and starts the parser.
  195. *********************************************/
  196. void ParseManager::parse(CppTools::Internal::CppPreprocessor *preproc,
  197. const QStringList &files)
  198. {
  199. if (files.isEmpty())
  200. return;
  201. //check if file is C++ header file
  202. QStringList headers;
  203. foreach (const QString &file, files) {
  204. const QFileInfo fileInfo(file);
  205. QString ext = fileInfo.suffix();
  206. if (ext.toLower() == "h")
  207. headers.append(file);
  208. }
  209. foreach (const QString &file, files) {
  210. preproc->snapshot.remove(file);
  211. }
  212. preproc->setTodo(headers);
  213. QString conf = QLatin1String("<configuration>");
  214. preproc->run(conf);
  215. for (int i = 0; i < headers.size(); ++i) {
  216. QString fileName = headers.at(i);
  217. preproc->run(fileName);
  218. }
  219. }
  220. //This function creates a class list for each class and its base classes in
  221. //the header file that needs to be checked.
  222. //e.g.
  223. // Cl1 Cl2
  224. // __|__ __|__
  225. // | | | |
  226. // Cl11 Cl12 Cl21 Cl22
  227. //
  228. //==> list[0] = {Cl1, Cl11, Cl12}
  229. // list[1] = {Cl2, Cl21, Cl22}
  230. QList<CLASSTREE*> ParseManager::CreateClassLists(bool isInterfaceHeader)
  231. {
  232. QList<CLASSTREE*>ret;
  233. QList<CLASSLISTITEM*> classlist;
  234. QList<CLASSLISTITEM*> allclasslist;
  235. Trace("Following classes scaned for header file: " + m_strHeaderFile);
  236. //Iteration over all parsed documents
  237. if(getPreProcessor()){
  238. for (Snapshot::const_iterator it = getPreProcessor()->snapshot.begin()
  239. ; it != getPreProcessor()->snapshot.end(); ++it)
  240. {
  241. Document::Ptr doc = (*it);
  242. if(doc){
  243. QFileInfo fileinf(doc->fileName());
  244. QFileInfo fileinf1(m_strHeaderFile);
  245. //Get the Translated unit
  246. Control* ctrl = doc->control();
  247. TranslationUnit* trlUnit = ctrl->translationUnit();
  248. AST* pAst = trlUnit->ast();
  249. TranslationUnitAST *ptrAst = 0;
  250. if(pAst && (ptrAst = pAst->asTranslationUnit())){
  251. //iteration over all translated declaration in this document
  252. for (DeclarationListAST *pDecllist = ptrAst->declaration_list; pDecllist; pDecllist = pDecllist->next) {
  253. if(pDecllist->value){
  254. SimpleDeclarationAST *pSimpleDec = pDecllist->value->asSimpleDeclaration();
  255. if(pSimpleDec){
  256. //Iteration over class specifier
  257. for (SpecifierListAST *pSimpleDecDecllist = pSimpleDec->decl_specifier_list; pSimpleDecDecllist; pSimpleDecDecllist = pSimpleDecDecllist->next) {
  258. ClassSpecifierAST * pclassspec = pSimpleDecDecllist->value->asClassSpecifier();
  259. if(pclassspec){
  260. CLASSLISTITEM* item = new CLASSLISTITEM();
  261. item->classspec = pclassspec;
  262. item->trlUnit = trlUnit;
  263. allclasslist.push_back(item);
  264. QString classname = item->trlUnit->spell(item->classspec->name->firstToken());
  265. Trace("- " + classname + " class scaned");
  266. //We found a class that is defined in the header file that needs to be checked
  267. if(fileinf.fileName().toLower() == fileinf1.fileName().toLower()){
  268. CLASSTREE* cltree = new CLASSTREE();
  269. cltree->highestlevelclass = item;
  270. cltree->classlist.push_back(item);
  271. ret.push_back(cltree);
  272. }
  273. }
  274. }
  275. }
  276. }
  277. }
  278. }
  279. }
  280. }
  281. }
  282. //after we search for the classes we need to search for the baseclasses
  283. Trace("Following classes found in Header file: " + m_strHeaderFile);
  284. foreach(CLASSTREE *cltree, ret){
  285. QString classname = cltree->highestlevelclass->trlUnit->spell(cltree->highestlevelclass->classspec->name->firstToken());
  286. Trace("- " + classname + " class found");
  287. QList<CLASSLISTITEM*> baseclasslist;
  288. getBaseClasses(cltree->highestlevelclass, baseclasslist, allclasslist, 0, isInterfaceHeader);
  289. cltree->classlist.append(baseclasslist);
  290. }
  291. return ret;
  292. }
  293. /********************************************
  294. Gets all the baseclass from a class and
  295. add those base classes into the baseclasslist
  296. ********************************************/
  297. void ParseManager::getBaseClasses(const CLASSLISTITEM* pclass
  298. , QList<CLASSLISTITEM*> &baseclasslist
  299. , const QList<CLASSLISTITEM*> &allclasslist
  300. , int level
  301. , bool isInterfaceHeader)
  302. {
  303. //iteration over the base_clause_list of the current class
  304. QString levelmarker = " ";
  305. for(int i = 0; i < level; i++)
  306. levelmarker += " ";
  307. levelmarker += "|- ";
  308. QList<CLASSLISTITEM*>child;
  309. for(BaseSpecifierListAST *pBaseSpecList = pclass->classspec->base_clause_list; pBaseSpecList; pBaseSpecList = pBaseSpecList->next)
  310. {
  311. BaseSpecifierAST *pBaseSpec = pBaseSpecList->value;
  312. bool found = false;
  313. foreach(CLASSLISTITEM* pclspec, allclasslist)
  314. {
  315. if(pclspec->classspec->symbol->name()
  316. && pBaseSpec->symbol->name()
  317. && pclspec->classspec->symbol->name()->isEqualTo(pBaseSpec->symbol->name()))
  318. {
  319. child.push_back(pclspec);
  320. baseclasslist.push_back(pclspec);
  321. QString classname = pclspec->trlUnit->spell(pclspec->classspec->name->firstToken());
  322. Trace(levelmarker + classname + " class found");
  323. found = true;
  324. break;
  325. }
  326. }
  327. if(!found && pBaseSpec->name){
  328. QString classname = pclass->trlUnit->spell(pBaseSpec->name->firstToken());
  329. if(isInterfaceHeader)
  330. Trace(levelmarker + classname + " class not found! Interface classes should not be inherited from Qt Objects!");
  331. else
  332. Trace(levelmarker + classname + " class not found!");
  333. }
  334. }
  335. //call the function recursive because all the basclasses can have other base classes
  336. foreach(CLASSLISTITEM* pchclass, child){
  337. getBaseClasses(pchclass, baseclasslist, allclasslist, ++level, isInterfaceHeader);
  338. }
  339. }
  340. /**************************************************
  341. This function finds and creates all Elements wich
  342. are significant for MetaDatas.
  343. Those element will be added in the aparameter
  344. lists.
  345. **************************************************/
  346. void ParseManager::getElements(QList<FUNCTIONITEM*> &functionlist
  347. , QList<PROPERTYITEM*> &propertylist
  348. , QList<QENUMITEM*> &qenumlist
  349. , QList<ENUMITEM*> &enumlist
  350. , QList<QFLAGITEM*> &qflaglist
  351. , QList<QDECLAREFLAGSITEM*> &qdeclareflaglist
  352. , const QList<CLASSLISTITEM*> classitems
  353. , const CLASSLISTITEM* highestlevelclass)
  354. {
  355. foreach(CLASSLISTITEM* classitem, classitems){
  356. QString classname = "";
  357. if(classitem->classspec->name)
  358. classname = classitem->trlUnit->spell(classitem->classspec->name->firstToken());
  359. for (DeclarationListAST *pmemberlist = classitem->classspec->member_specifier_list; pmemberlist; pmemberlist = pmemberlist->next) {
  360. /**********
  361. Functions
  362. **********/
  363. if (FunctionDefinitionAST *pfctdef = pmemberlist->value->asFunctionDefinition()){
  364. FUNCTIONITEM* item = new FUNCTIONITEM;
  365. item->trlUnit = classitem->trlUnit;
  366. item->function = pfctdef->symbol;
  367. item->classAst = classitem->classspec;
  368. item->highestlevelclass = highestlevelclass;
  369. functionlist.push_back(item);
  370. if(isMetaObjFunction(item))
  371. Trace(" - " + getTraceFuntionString(item, classname) + " found");
  372. }
  373. SimpleDeclarationAST *pdecl = pmemberlist->value->asSimpleDeclaration();
  374. if(pdecl){
  375. for(List<Symbol*>* decllist = pdecl->symbols; decllist; decllist = decllist->next)
  376. {
  377. Function* pfct = decllist->value->type()->asFunctionType();
  378. if(pfct){
  379. FUNCTIONITEM* item = new FUNCTIONITEM();
  380. item->trlUnit = classitem->trlUnit;
  381. item->function = pfct;
  382. item->classAst = classitem->classspec;
  383. item->highestlevelclass = highestlevelclass;
  384. functionlist.push_back(item);
  385. if(isMetaObjFunction(item))
  386. Trace(" - " + getTraceFuntionString(item, classname) + " found");
  387. }
  388. }
  389. /******
  390. enum
  391. ******/
  392. for(List<SpecifierAST*>* decllist = pdecl->decl_specifier_list; decllist; decllist = decllist->next)
  393. {
  394. EnumSpecifierAST * penum = decllist->value->asEnumSpecifier();
  395. if(penum){
  396. ENUMITEM* item = new ENUMITEM();
  397. item->ast = penum;
  398. item->highestlevelclass = highestlevelclass;
  399. item->trlUnit = classitem->trlUnit;
  400. enumlist.push_back(item);
  401. }
  402. }
  403. }
  404. else{
  405. /**********
  406. Q_PROPERTY
  407. **********/
  408. if(QtPropertyDeclarationAST *ppdecl = pmemberlist->value->asQtPropertyDeclaration()) {
  409. propertylist.push_back(PROPERTYITEM::create(ppdecl, highestlevelclass));
  410. if (ppdecl->property_name && ppdecl->property_name->name && ppdecl->property_name->name->identifier()) {
  411. Trace(" - Q_PROPERTY: " + QLatin1String(ppdecl->property_name->name->identifier()->chars()) + " found");
  412. }
  413. } else{
  414. /**********
  415. Q_ENUM
  416. **********/
  417. if (QtEnumDeclarationAST *pqenum = pmemberlist->value->asQtEnumDeclaration()) {
  418. for (NameListAST *plist = pqenum->enumerator_list; plist; plist = plist->next) {
  419. QENUMITEM* item = new QENUMITEM;
  420. item->name = plist->value->name->identifier()->chars();
  421. item->highestlevelclass = highestlevelclass;
  422. qenumlist.push_back(item);
  423. Trace(" - Q_ENUM: " + classname + "::" + item->name + " found");
  424. }
  425. }
  426. else{
  427. /**********
  428. Q_FLAGS
  429. **********/
  430. if (QtFlagsDeclarationAST *pqflags = pmemberlist->value->asQtFlagsDeclaration()){
  431. for (NameListAST *plist = pqflags->flag_enums_list; plist; plist = plist->next) {
  432. QFLAGITEM* item = new QFLAGITEM;
  433. item->name = plist->value->name;
  434. item->highestlevelclass = highestlevelclass;
  435. qflaglist.push_back(item);
  436. Trace(" - Q_FLAGS: " + classname + "::" + item->name->identifier()->chars() + " found");
  437. }
  438. }
  439. #if 0
  440. /*The code for Q_DECLARE_FLAGS was wrong. It's optional, and only does a typedef.
  441. That means, if you do the typedef yourself and not use Q_DECLARE_FLAGS, that *is* valid.
  442. 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.*/
  443. else {
  444. /****************
  445. Q_DECLARE_FLAGS
  446. ****************/
  447. QtDeclareFlagsDeclarationAST *pqdeclflags = pmemberlist->value->asQDeclareFlagsDeclarationAST();
  448. if(pqdeclflags){
  449. QDECLAREFLAGSITEM* item = new QDECLAREFLAGSITEM();
  450. item->ast = pqdeclflags;
  451. item->highestlevelclass = highestlevelclass;
  452. item->trlUnit = classitem->trlUnit;
  453. qdeclareflaglist.push_back(item);
  454. }
  455. }
  456. #endif
  457. }
  458. }
  459. }
  460. }
  461. }
  462. }
  463. /*********************************************
  464. Function that starts the comare between the
  465. parser result and their metadata content.
  466. *********************************************/
  467. bool ParseManager::checkAllMetadatas(ParseManager* pInterfaceParserManager, QString resultfile)
  468. {
  469. bool ret = true;
  470. //Create output file
  471. if(resultfile != "" && ::m_resultFile == 0){
  472. ::m_resultFile = new QFile(resultfile);
  473. if (!::m_resultFile->open(QFile::WriteOnly | QFile::Truncate)) {
  474. delete ::m_resultFile;
  475. ::m_resultFile = 0;
  476. }
  477. }
  478. /************************************************
  479. Get all elements from the interface header file
  480. ************************************************/
  481. Trace("### Get all elements from the interface header file ###");
  482. QList<CLASSTREE*> ilookuplist = pInterfaceParserManager->CreateClassLists(true);
  483. QList<QList<FUNCTIONITEM*> > ifunctionslookuplist;
  484. QList<QList<PROPERTYITEM*> > ipropertieslookuplist;
  485. QList<QList<QENUMITEM*> > iqenumlookuplist;
  486. QList<QList<ENUMITEM*> > ienumlookuplist;
  487. QList<QList<QFLAGITEM*> > iqflaglookuplist;
  488. QList<QList<QDECLAREFLAGSITEM*> > iqdeclareflaglookuplist;
  489. Trace("Following MetaData found:");
  490. foreach(CLASSTREE* iclasstree, ilookuplist){
  491. QList<FUNCTIONITEM*>functionlist;
  492. QList<PROPERTYITEM*>propertylist;
  493. QList<QENUMITEM*>qenumlist;
  494. QList<ENUMITEM*>enumlist;
  495. QList<QFLAGITEM*> qflaglist;
  496. QList<QDECLAREFLAGSITEM*> qdeclareflag;
  497. getElements(functionlist
  498. , propertylist
  499. , qenumlist
  500. , enumlist
  501. , qflaglist
  502. , qdeclareflag
  503. , iclasstree->classlist
  504. , iclasstree->highestlevelclass);
  505. if(functionlist.size() > 0)
  506. ifunctionslookuplist.append(functionlist);
  507. if(propertylist.size() > 0)
  508. ipropertieslookuplist.append(propertylist);
  509. if(qenumlist.size() > 0)
  510. iqenumlookuplist.append(qenumlist);
  511. if(enumlist.size() > 0)
  512. ienumlookuplist.append(enumlist);
  513. if(qflaglist.size() > 0)
  514. iqflaglookuplist.append(qflaglist);
  515. if(qdeclareflag.size() > 0)
  516. iqdeclareflaglookuplist.append(qdeclareflag);
  517. }
  518. /************************************************
  519. Get all elements from the compare header file
  520. ************************************************/
  521. Trace("\n");
  522. Trace("### Get all elements from the compare header file ###");
  523. QList<CLASSTREE*> lookuplist = CreateClassLists(false);
  524. QList<QList<FUNCTIONITEM*> > functionslookuplist;
  525. QList<QList<PROPERTYITEM*> > propertieslookuplist;
  526. QList<QList<QENUMITEM*> > qenumlookuplist;
  527. QList<QList<ENUMITEM*> > enumlookuplist;
  528. QList<QList<QFLAGITEM*> > qflaglookuplist;
  529. QList<QList<QDECLAREFLAGSITEM*> > qdeclareflaglookuplist;
  530. Trace("Following MetaData found:");
  531. foreach(CLASSTREE* classtree, lookuplist){
  532. QList<FUNCTIONITEM*>functionlist;
  533. QList<PROPERTYITEM*>propertylist;
  534. QList<QENUMITEM*>qenumlist;
  535. QList<ENUMITEM*>enumlist;
  536. QList<QFLAGITEM*> qflaglist;
  537. QList<QDECLAREFLAGSITEM*> qdeclareflag;
  538. getElements(functionlist
  539. , propertylist
  540. , qenumlist
  541. , enumlist
  542. , qflaglist
  543. , qdeclareflag
  544. , classtree->classlist
  545. , classtree->highestlevelclass);
  546. if(functionlist.size() > 0)
  547. functionslookuplist.append(functionlist);
  548. if(propertylist.size() > 0)
  549. propertieslookuplist.append(propertylist);
  550. if(qenumlist.size() > 0)
  551. qenumlookuplist.append(qenumlist);
  552. if(enumlist.size() > 0)
  553. enumlookuplist.append(enumlist);
  554. if(qflaglist.size() > 0)
  555. qflaglookuplist.append(qflaglist);
  556. if(qdeclareflag.size() > 0)
  557. qdeclareflaglookuplist.append(qdeclareflag);
  558. }
  559. Trace("\n");
  560. Trace("### Result: ###");
  561. /******************************
  562. Check for function
  563. ******************************/
  564. Trace("Compare all interface MetaData functions:");
  565. QList<FUNCTIONITEM*> missingifcts = checkMetadataFunctions(functionslookuplist, ifunctionslookuplist);
  566. if(missingifcts.size() > 0){
  567. foreach(FUNCTIONITEM* ifct, missingifcts){
  568. m_errormsgs.append(getErrorMessage(ifct));
  569. }
  570. ret = false;
  571. Trace("- Failed!");
  572. }
  573. else{
  574. Trace("- OK");
  575. }
  576. /******************************
  577. Check for properies
  578. ******************************/
  579. Trace("Compare all interface MetaData properties:");
  580. QList<PROPERTYITEM*> missingippts = checkMetadataProperties(propertieslookuplist, functionslookuplist, ipropertieslookuplist, ifunctionslookuplist);
  581. if(missingippts.size() > 0){
  582. foreach(PROPERTYITEM* ippt, missingippts){
  583. m_errormsgs.append(getErrorMessage(ippt));
  584. }
  585. ret = false;
  586. Trace("- Failed!");
  587. }
  588. else{
  589. Trace("- OK");
  590. }
  591. /******************************
  592. Check for enums
  593. ******************************/
  594. Trace("Compare all interface MetaData enums:");
  595. QList<QENUMITEM*> missingiqenums = checkMetadataEnums(qenumlookuplist, enumlookuplist, iqenumlookuplist, ienumlookuplist);
  596. if(missingiqenums.size() > 0){
  597. foreach(QENUMITEM* ienum, missingiqenums){
  598. m_errormsgs.append(getErrorMessage(ienum));
  599. }
  600. ret = false;
  601. Trace("- Failed!");
  602. }
  603. else{
  604. Trace("- OK");
  605. }
  606. /******************************
  607. Check for flags
  608. ******************************/
  609. Trace("Compare all interface MetaData flags:");
  610. QList<QFLAGITEM*> missingiqflags = checkMetadataFlags(qflaglookuplist, qdeclareflaglookuplist, enumlookuplist
  611. , iqflaglookuplist, iqdeclareflaglookuplist, ienumlookuplist);
  612. if(missingiqflags.size() > 0){
  613. foreach(QFLAGITEM* iflags, missingiqflags){
  614. m_errormsgs.append(getErrorMessage(iflags));
  615. }
  616. ret = false;
  617. Trace("- Failed!");
  618. }
  619. else{
  620. Trace("- OK");
  621. }
  622. /******************************
  623. Add summary
  624. ******************************/
  625. Trace("\n");
  626. Trace("### summary ###");
  627. if(m_errormsgs.size() > 0){
  628. Trace("- Folowing interface items are missing:");
  629. foreach(QString msg, m_errormsgs)
  630. Trace(" - " + msg);
  631. }
  632. else
  633. Trace("Interface is full defined.");
  634. //now delet all Classitems
  635. foreach(CLASSTREE* l, ilookuplist){
  636. l->classlist.clear();
  637. }
  638. foreach(CLASSTREE* l, lookuplist){
  639. l->classlist.clear();
  640. }
  641. //delete all functionitems
  642. foreach(QList<FUNCTIONITEM*>l, ifunctionslookuplist){
  643. l.clear();
  644. }
  645. foreach(QList<FUNCTIONITEM*>l, functionslookuplist){
  646. l.clear();
  647. }
  648. //delete all properties
  649. foreach(QList<PROPERTYITEM*>l, ipropertieslookuplist){
  650. l.clear();
  651. }
  652. foreach(QList<PROPERTYITEM*>l, propertieslookuplist){
  653. l.clear();
  654. }
  655. //delete all qenums
  656. foreach(QList<QENUMITEM*>l, iqenumlookuplist){
  657. l.clear();
  658. }
  659. foreach(QList<QENUMITEM*>l, iqenumlookuplist){
  660. l.clear();
  661. }
  662. //delete all enums
  663. foreach(QList<ENUMITEM*>l, ienumlookuplist){
  664. l.clear();
  665. }
  666. foreach(QList<ENUMITEM*>l, enumlookuplist){
  667. l.clear();
  668. }
  669. //delete all qflags
  670. foreach(QList<QFLAGITEM*>l, iqflaglookuplist){
  671. l.clear();
  672. }
  673. foreach(QList<QFLAGITEM*>l, qflaglookuplist){
  674. l.clear();
  675. }
  676. //delete all qdeclareflags
  677. foreach(QList<QDECLAREFLAGSITEM*>l, iqdeclareflaglookuplist){
  678. l.clear();
  679. }
  680. foreach(QList<QDECLAREFLAGSITEM*>l, qdeclareflaglookuplist){
  681. l.clear();
  682. }
  683. return ret;
  684. }
  685. //<------------------------------------------------------- Start of MetaData functions
  686. /***********************************
  687. Function that checks all functions
  688. which will occur in the MetaData
  689. ***********************************/
  690. QList<FUNCTIONITEM*> ParseManager::checkMetadataFunctions(const QList<QList<FUNCTIONITEM*> > &classfctlist, const QList<QList<FUNCTIONITEM*> > &iclassfctlist)
  691. {
  692. QList<FUNCTIONITEM*> missingifcts;
  693. //Compare each function from interface with function from header (incl. baseclass functions)
  694. QList<FUNCTIONITEM*> ifcts;
  695. foreach(QList<FUNCTIONITEM*>ifunctionlist, iclassfctlist){
  696. ifcts.clear();
  697. //check if one header class contains all function from one interface header class
  698. if(classfctlist.count() > 0){
  699. foreach(QList<FUNCTIONITEM*>functionlist, classfctlist){
  700. QList<FUNCTIONITEM*> tmpl = containsAllMetadataFunction(functionlist, ifunctionlist);
  701. if(tmpl.size() == 0){
  702. ifcts.clear();
  703. break;
  704. }
  705. else
  706. ifcts.append(tmpl);
  707. }
  708. }
  709. else {
  710. foreach(FUNCTIONITEM *pfct, ifunctionlist)
  711. pfct->classWichIsNotFound << "<all classes>";
  712. ifcts.append(ifunctionlist);
  713. }
  714. missingifcts.append(ifcts);
  715. }
  716. return missingifcts;
  717. }
  718. /*********************************************
  719. Helper function to check if a function will
  720. occure in the MetaData.
  721. *********************************************/
  722. bool ParseManager::isMetaObjFunction(FUNCTIONITEM* fct)
  723. {
  724. if(fct->function->isInvokable()
  725. || fct->function->isSignal()
  726. || fct->function->isSlot())
  727. return true;
  728. return false;
  729. }
  730. /****************************************************
  731. Check if all function from iclassfctlist are defined
  732. in the classfctlist as well.
  733. It will return all the function they are missing.
  734. ****************************************************/
  735. QList<FUNCTIONITEM*> ParseManager::containsAllMetadataFunction(const QList<FUNCTIONITEM*> &classfctlist, const QList<FUNCTIONITEM*> &iclassfctlist)
  736. {
  737. QList<FUNCTIONITEM*> ret;
  738. foreach(FUNCTIONITEM* ifct, iclassfctlist){
  739. if(isMetaObjFunction(ifct)){
  740. bool found = false;
  741. QStringList missingimplinclasses;
  742. ClassSpecifierAST* clspec = 0;
  743. QString classname = "";
  744. foreach(FUNCTIONITEM* fct, classfctlist){
  745. if(clspec != fct->highestlevelclass->classspec){
  746. clspec = fct->highestlevelclass->classspec;
  747. //get the classname
  748. unsigned int firsttoken = clspec->name->firstToken();
  749. classname += fct->trlUnit->spell(firsttoken);
  750. if(missingimplinclasses.indexOf(classname) < 0)
  751. missingimplinclasses.push_back(classname);
  752. }
  753. if(fct->isEqualTo(ifct, false)){
  754. found = true;
  755. missingimplinclasses.clear();
  756. Trace("- " + getTraceFuntionString(fct, classname) + " implemented");
  757. break;
  758. }
  759. }
  760. if(!found){
  761. ifct->classWichIsNotFound.append(missingimplinclasses);
  762. ret.push_back(ifct);
  763. QString classname = ifct->trlUnit->spell(ifct->highestlevelclass->classspec->name->firstToken());
  764. Trace("- " + getTraceFuntionString(ifct, classname) + " not implemented!");
  765. }
  766. }
  767. }
  768. return ret;
  769. }
  770. /************************************
  771. Function that gives back an error
  772. string for a MetaData function
  773. mismatch.
  774. ************************************/
  775. QStringList ParseManager::getErrorMessage(FUNCTIONITEM* fct)
  776. {
  777. QStringList ret;
  778. QString fctstring = "";
  779. QString fcttype = "";
  780. foreach(QString classname, fct->classWichIsNotFound){
  781. QString tmp;
  782. QTextStream out(&tmp);
  783. fcttype = "";
  784. fctstring = classname;
  785. fctstring += "::";
  786. unsigned int token = fct->function->sourceLocation() - 1;
  787. while(fct->trlUnit->tokenAt(token).isNot(T_EOF_SYMBOL)){
  788. fctstring += fct->trlUnit->tokenAt(token).spell();
  789. if(*fct->trlUnit->tokenAt(token).spell() == ')')
  790. break;
  791. fctstring += " ";
  792. token++;
  793. }
  794. Function* pfct = fct->function;
  795. if(pfct){
  796. fcttype = "type: ";
  797. //Check for private, protected and public
  798. if(pfct->isPublic())
  799. fcttype = "public ";
  800. if(pfct->isProtected())
  801. fcttype = "protected ";
  802. if(pfct->isPrivate())
  803. fcttype = "private ";
  804. if(pfct->isVirtual())
  805. fcttype += "virtual ";
  806. if(pfct->isPureVirtual())
  807. fcttype += "pure virtual ";
  808. if(pfct->isSignal())
  809. fcttype += "Signal ";
  810. if(pfct->isSlot())
  811. fcttype += "Slot ";
  812. if(pfct->isNormal())
  813. fcttype += "Normal ";
  814. if(pfct->isInvokable())
  815. fcttype += "Invokable ";
  816. }
  817. out << fcttype << fctstring;
  818. ret << tmp;
  819. }
  820. return ret;
  821. }
  822. //--->
  823. //<------------------------------------------------------- Start of Q_PROPERTY checks
  824. /***********************************
  825. Function that checks all Property
  826. which will occur in the MetaData
  827. ***********************************/
  828. QList<PROPERTYITEM*> ParseManager::checkMetadataProperties(const QList<QList<PROPERTYITEM*> > &classproplist
  829. , const QList<QList<FUNCTIONITEM*> > &classfctlist
  830. , const QList<QList<PROPERTYITEM*> > &iclassproplist
  831. , const QList<QList<FUNCTIONITEM*> > &iclassfctlist)
  832. {
  833. QList<PROPERTYITEM*> missingiprops;
  834. //assign the property functions
  835. foreach(QList<PROPERTYITEM*>proplist, classproplist){
  836. foreach(PROPERTYITEM* prop, proplist){
  837. assignPropertyFunctions(prop, classfctlist);
  838. }
  839. }
  840. foreach(QList<PROPERTYITEM*>proplist, iclassproplist){
  841. foreach(PROPERTYITEM* prop, proplist){
  842. assignPropertyFunctions(prop, iclassfctlist);
  843. }
  844. }
  845. //Compare each qproperty from interface with qproperty from header (incl. baseclass functions)
  846. QList<PROPERTYITEM*> ippts;
  847. foreach(QList<PROPERTYITEM*>ipropertylist, iclassproplist){
  848. ippts.clear();
  849. //check if one header class contains all function from one interface header class
  850. if(classproplist.count() > 0){
  851. foreach(QList<PROPERTYITEM*>propertylist, classproplist){
  852. QList<PROPERTYITEM*> tmpl = containsAllPropertyFunction(propertylist, ipropertylist);
  853. if(tmpl.size() == 0)
  854. ippts.clear();
  855. else
  856. ippts.append(tmpl);
  857. }
  858. }
  859. else {
  860. foreach(PROPERTYITEM *pprop, ipropertylist){
  861. pprop->classWichIsNotFound << "<all classes>";
  862. QString name = pprop->ast->property_name->name->identifier()->chars();
  863. Trace("- Property: <all classes>::" + name + " not found!");
  864. }
  865. ippts.append(ipropertylist);
  866. }
  867. missingiprops.append(ippts);
  868. }
  869. return missingiprops;
  870. }
  871. static QString findName(ExpressionAST *ast)
  872. {
  873. // The "old" icheck code assumed that functions were only a single identifier, so I'll assume the same:
  874. if (NameAST *nameAST = ast->asName())
  875. return nameAST->name->identifier()->chars();
  876. else
  877. return QString();
  878. }
  879. /**************************************
  880. Function that resolves the dependensies
  881. between Q_PROPERTY
  882. and thier READ, WRITE, NOTIFY and RESET
  883. functions.
  884. ***************************************/
  885. void ParseManager::assignPropertyFunctions(PROPERTYITEM* prop, const QList<QList<FUNCTIONITEM*> > &fctlookuplist)
  886. {
  887. //get the name of the needed functions
  888. QString readfctname;
  889. QString writefctname;
  890. QString resetfctname;
  891. QString notifyfctname;
  892. int needtofind = 0;
  893. if(prop->readAst){
  894. readfctname = findName(prop->readAst);
  895. needtofind++;
  896. }
  897. if(prop->writeAst){
  898. writefctname = findName(prop->writeAst);
  899. needtofind++;
  900. }
  901. if(prop->resetAst){
  902. resetfctname = findName(prop->resetAst);
  903. needtofind++;
  904. }
  905. if(prop->notifyAst){
  906. notifyfctname = findName(prop->notifyAst);
  907. needtofind++;
  908. }
  909. //Now iterate over all function to find all functions wich are defined in the Q_PROPERTY macro
  910. if(needtofind > 0){
  911. prop->foundalldefinedfct = false;
  912. foreach(QList<FUNCTIONITEM*> fctlist, fctlookuplist){
  913. foreach(FUNCTIONITEM* pfct, fctlist){
  914. QString fctname = pfct->trlUnit->spell(pfct->function->sourceLocation());
  915. //check the function type against the property type
  916. FullySpecifiedType retTy = pfct->function->returnType();
  917. if (!fctname.isEmpty() && retTy.isValid()) {
  918. if(prop->readAst && fctname == readfctname){
  919. if (prop->type != retTy)
  920. continue;
  921. prop->readFct = pfct;
  922. needtofind--;
  923. }
  924. if(prop->writeAst && fctname == writefctname){
  925. prop->writeFct = pfct;
  926. needtofind--;
  927. }
  928. if(prop->resetAst && fctname == resetfctname){
  929. prop->resetFct = pfct;
  930. needtofind--;
  931. }
  932. if(prop->notifyAst && fctname == notifyfctname){
  933. prop->notifyFct = pfct;
  934. needtofind--;
  935. }
  936. if(needtofind <= 0){
  937. //a flag that indicates if a function was missing
  938. prop->foundalldefinedfct = true;
  939. return;
  940. }
  941. }
  942. }
  943. }
  944. }
  945. }
  946. /**************************************
  947. Function that checks if all functions
  948. dependencies in Q_PROPERTY have the
  949. same arguments and retunr value.
  950. ***************************************/
  951. QList<PROPERTYITEM*> ParseManager::containsAllPropertyFunction(const QList<PROPERTYITEM*> &classproplist, const QList<PROPERTYITEM*> &iclassproplist)
  952. {
  953. QList<PROPERTYITEM*> ret;
  954. foreach(PROPERTYITEM* ipropt, iclassproplist){
  955. if(ipropt->foundalldefinedfct){
  956. bool found = false;
  957. QStringList missingimplinclasses;
  958. ClassSpecifierAST* clspec = 0;
  959. QString classname = "";
  960. foreach(PROPERTYITEM* propt, classproplist){
  961. if(clspec != propt->highestlevelclass->classspec){
  962. clspec = propt->highestlevelclass->classspec;
  963. //get the classname
  964. unsigned int firsttoken = clspec->name->firstToken();
  965. classname += propt->trlUnit->spell(firsttoken);
  966. if(missingimplinclasses.indexOf(classname) < 0)
  967. missingimplinclasses.push_back(classname);
  968. }
  969. if(propt->isEqualTo(ipropt)){
  970. found = true;
  971. missingimplinclasses.clear();
  972. Trace("- Property: " + classname + "::" + propt->ast->property_name->name->identifier()->chars() + " found");
  973. break;
  974. }
  975. }
  976. if(!found){
  977. ipropt->classWichIsNotFound.append(missingimplinclasses);
  978. ret.push_back(ipropt);
  979. QString classname = ipropt->trlUnit->spell(ipropt->highestlevelclass->classspec->name->firstToken());
  980. Trace("- Property: " + classname + "::" + ipropt->ast->property_name->name->identifier()->chars() + " not found!");
  981. }
  982. }
  983. else{
  984. QString classname = ipropt->trlUnit->spell(ipropt->highestlevelclass->classspec->name->firstToken());
  985. Overview oo;
  986. QString proptype = oo(ipropt->type);
  987. Trace("- Property: " + classname + "::" + proptype + " functions are missing!");
  988. ret.push_back(ipropt);
  989. }
  990. }
  991. return ret;
  992. }
  993. /************************************
  994. Function that gives back an error
  995. string for a Q_PROPERTY mismatch.
  996. ************************************/
  997. QStringList ParseManager::getErrorMessage(PROPERTYITEM* ppt)
  998. {
  999. QStringList ret;
  1000. QString pptstring = "";
  1001. if(!ppt->foundalldefinedfct)
  1002. {
  1003. QString tmp;
  1004. QTextStream out(&tmp);
  1005. unsigned int firsttoken = ppt->highestlevelclass->classspec->name->firstToken();
  1006. unsigned int lasttoken = ppt->highestlevelclass->classspec->name->lastToken();
  1007. for(unsigned int i = firsttoken; i < lasttoken; i++){
  1008. out << ppt->trlUnit->spell(i);
  1009. }
  1010. out << "::";
  1011. firsttoken = ppt->ast->firstToken();
  1012. lasttoken = ppt->ast->lastToken();
  1013. for(unsigned int i = firsttoken; i <= lasttoken; i++){
  1014. out << ppt->trlUnit->spell(i) << " ";
  1015. }
  1016. out << endl << " -";
  1017. if(ppt->readAst && !ppt->readFct)
  1018. out << "READ ";
  1019. if(ppt->writeAst && !ppt->writeFct)
  1020. out << "WRITE ";
  1021. if(ppt->resetAst && !ppt->resetFct)
  1022. out << "RESET.";
  1023. if(ppt->notifyAst && !ppt->notifyFct)
  1024. out << "NOTIFY ";
  1025. out << "functions missing." << endl;
  1026. ret << tmp;
  1027. }
  1028. for(int i = 0; i < ppt->classWichIsNotFound.size(); i++){
  1029. QString tmp;
  1030. QTextStream out(&tmp);
  1031. pptstring = ppt->classWichIsNotFound[i];
  1032. pptstring += "::";
  1033. unsigned int firsttoken = ppt->ast->firstToken();
  1034. unsigned int lasttoken = ppt->ast->lastToken();
  1035. for(unsigned int i = firsttoken; i <= lasttoken; i++){
  1036. pptstring += ppt->trlUnit->spell(i);
  1037. pptstring += " ";
  1038. }
  1039. out << pptstring;
  1040. ret << tmp;
  1041. }
  1042. return ret;
  1043. }
  1044. //--->
  1045. //<------------------------------------------------------- Start of Q_ENUMS checks
  1046. /***********************************
  1047. Function that checks all enums
  1048. which will occur in the MetaData
  1049. ***********************************/
  1050. QList<QENUMITEM*> ParseManager::checkMetadataEnums(const QList<QList<QENUMITEM*> > &classqenumlist
  1051. , const QList<QList<ENUMITEM*> > &classenumlist
  1052. , const QList<QList<QENUMITEM*> > &iclassqenumlist
  1053. , const QList<QList<ENUMITEM*> > &iclassenumlist)
  1054. {
  1055. QList<QENUMITEM*> missingiqenums;
  1056. //assign the property functions
  1057. foreach(QList<QENUMITEM*>qenumlist, classqenumlist){
  1058. foreach(QENUMITEM* qenum, qenumlist){
  1059. assignEnumValues(qenum, classenumlist);
  1060. }
  1061. }
  1062. foreach(QList<QENUMITEM*>qenumlist, iclassqenumlist){
  1063. foreach(QENUMITEM* qenum, qenumlist){
  1064. assignEnumValues(qenum, iclassenumlist);
  1065. }
  1066. }
  1067. //Compare each qenum from interface with qenum from header (incl. baseclass functions)
  1068. QList<QENUMITEM*> iqenums;
  1069. foreach(QList<QENUMITEM*>iqenumlist, iclassqenumlist){
  1070. iqenums.clear();
  1071. //check if one header class contains all function from one interface header class
  1072. if(classqenumlist.count() > 0){
  1073. foreach(QList<QENUMITEM*>qenumlist, classqenumlist){
  1074. QList<QENUMITEM*> tmpl = containsAllEnums(qenumlist, iqenumlist);
  1075. if(tmpl.size() == 0)
  1076. iqenums.clear();
  1077. else
  1078. iqenums.append(tmpl);
  1079. }
  1080. }
  1081. else {
  1082. foreach(QENUMITEM *qenum, iqenumlist){
  1083. qenum->classWichIsNotFound << "<all classes>";
  1084. Trace("- Enum: <all classes>::" + qenum->name + " not found!");
  1085. }
  1086. iqenums.append(iqenumlist);
  1087. }
  1088. missingiqenums.append(iqenums);
  1089. }
  1090. return missingiqenums;
  1091. }
  1092. /*********************************************
  1093. Helper function which creates a string out of
  1094. an enumerator including its values.
  1095. *********************************************/
  1096. QStringList ParseManager::getEnumValueStringList(ENUMITEM *penum, QString mappedenumname/* = ""*/)
  1097. {
  1098. QStringList ret;
  1099. EnumSpecifierAST *penumsec = penum->ast;
  1100. QString enumname = penum->trlUnit->spell(penumsec->name->firstToken());
  1101. int enumvalue = 0;
  1102. //now iterrate over all enumitems and create a string like following:
  1103. //EnumName.EnumItemName.Value
  1104. //ConnectionState.disconnected.0
  1105. for (EnumeratorListAST *plist = penum->ast->enumerator_list; plist; plist = plist->next) {
  1106. QString value = enumname;
  1107. if(mappedenumname.size() > 0)
  1108. value = mappedenumname;
  1109. value += ".";
  1110. value += penum->trlUnit->spell(plist->value->identifier_token);
  1111. value += ".";
  1112. if(plist->value->equal_token > 0 && plist->value->expression){
  1113. QString v = penum->trlUnit->spell(plist->value->expression->firstToken());
  1114. bool ch;
  1115. int newval = enumvalue;
  1116. if(v.indexOf("0x") >= 0)
  1117. newval = v.toInt(&ch, 16);
  1118. else
  1119. newval = v.toInt(&ch, 10);
  1120. if(ch)
  1121. enumvalue = newval;
  1122. }
  1123. value += QString::number(enumvalue);
  1124. enumvalue++;
  1125. // now add this enumitem string in the VALUE list
  1126. ret << value;
  1127. }
  1128. return ret;
  1129. }
  1130. /**************************************
  1131. Function that resolves the dependensies
  1132. between Q_ENUMS and enums.
  1133. ***************************************/
  1134. void ParseManager::assignEnumValues(QENUMITEM* qenum, const QList<QList<ENUMITEM*> > &enumlookuplist)
  1135. {
  1136. //iterate over all enums and find the one with the same name like enumname
  1137. bool found = false;
  1138. foreach (QList<ENUMITEM*> penumlist, enumlookuplist) {
  1139. foreach(ENUMITEM *penum, penumlist){
  1140. EnumSpecifierAST *penumsec = penum->ast;
  1141. QString enumname1 = penum->trlUnit->spell(penumsec->name->firstToken());
  1142. if(qenum->name == enumname1){
  1143. qenum->values << getEnumValueStringList(penum);
  1144. found = true;
  1145. break;
  1146. }
  1147. }
  1148. if(!found)
  1149. qenum->foundallenums = false;
  1150. }
  1151. }
  1152. /***********************************
  1153. Function that checkt if the Q_ENUMS
  1154. are completed defined and if the
  1155. Enum values are the same.
  1156. ***********************************/
  1157. QList<QENUMITEM*> ParseManager::containsAllEnums(const QList<QENUMITEM*> &classqenumlist, const QList<QENUMITEM*> &iclassqenumlist)
  1158. {
  1159. Overview oo;
  1160. QList<QENUMITEM*> ret;
  1161. foreach(QENUMITEM* iqenum, iclassqenumlist){
  1162. bool found = false;
  1163. QStringList missingimplinclasses;
  1164. ClassSpecifierAST* clspec = 0;
  1165. QString classname = "";
  1166. foreach(QENUMITEM* qenum, classqenumlist){
  1167. if(clspec != qenum->highestlevelclass->classspec){
  1168. clspec = qenum->highestlevelclass->classspec;
  1169. //get the classname
  1170. classname += oo(clspec->symbol);
  1171. if(missingimplinclasses.indexOf(classname) < 0)
  1172. missingimplinclasses.push_back(classname);
  1173. }
  1174. if(qenum->isEqualTo(iqenum)){
  1175. found = true;
  1176. missingimplinclasses.clear();
  1177. Trace("- Enum: " + classname + "::" + qenum->name + " found");
  1178. break;
  1179. }
  1180. }
  1181. if(!found){
  1182. iqenum->classWichIsNotFound.append(missingimplinclasses);
  1183. ret.push_back(iqenum);
  1184. QString classname = oo(iqenum->highestlevelclass->classspec->symbol);
  1185. Trace("- Enum: " + classname + "::" + iqenum->name + " not found!");
  1186. }
  1187. }
  1188. return ret;
  1189. }
  1190. /************************************
  1191. Function that gives back an error
  1192. string for a Q_ENUMS mismatch.
  1193. ************************************/
  1194. QStringList ParseManager::getErrorMessage(QENUMITEM* qenum)
  1195. {
  1196. Overview oo;
  1197. QStringList ret;
  1198. if(!qenum->foundallenums)
  1199. {
  1200. QString tmp;
  1201. QTextStream out(&tmp);
  1202. out << oo(qenum->highestlevelclass->classspec->symbol);
  1203. out << "::Q_ENUMS " << qenum->name << " enum missing.";
  1204. ret << tmp;
  1205. }
  1206. for (int i = 0; i < qenum->classWichIsNotFound.size(); i++){
  1207. QString tmp;
  1208. QTextStream out(&tmp);
  1209. out << qenum->classWichIsNotFound[i] << "::Q_ENUMS "
  1210. << qenum->name;
  1211. ret << tmp;
  1212. }
  1213. return ret;
  1214. }
  1215. //--->
  1216. //<------------------------------------------------------- Start of Q_FLAGS checks
  1217. /***********************************
  1218. Function that checks all flags
  1219. which will occur in the MetaData
  1220. ***********************************/
  1221. QList<QFLAGITEM*> ParseManager::checkMetadataFlags(const QList<QList<QFLAGITEM*> > &classqflaglist
  1222. , const QList<QList<QDECLAREFLAGSITEM*> > &classqdeclareflaglist
  1223. , const QList<QList<ENUMITEM*> > &classenumlist
  1224. , const QList<QList<QFLAGITEM*> > &iclassqflaglist
  1225. , const QList<QList<QDECLAREFLAGSITEM*> > &iclassqdeclareflaglist
  1226. , con

Large files files are truncated, but you can click here to view the full file