From 9ef6d1f3e6ae36d46148f5dc52a9cad83fda49d4 Mon Sep 17 00:00:00 2001 From: Roy Qu Date: Tue, 9 Apr 2024 18:10:44 +0800 Subject: [PATCH] refactor: ParsedFileInfo --- RedPandaIDE/parser/cppparser.cpp | 57 ++++++----- RedPandaIDE/parser/cpppreprocessor.cpp | 24 +++-- RedPandaIDE/parser/cpppreprocessor.h | 4 +- RedPandaIDE/parser/parserutils.cpp | 126 ++++++++++++++++++++++--- RedPandaIDE/parser/parserutils.h | 57 ++++++++--- RedPandaIDE/widgets/classbrowser.cpp | 4 +- 6 files changed, 197 insertions(+), 75 deletions(-) diff --git a/RedPandaIDE/parser/cppparser.cpp b/RedPandaIDE/parser/cppparser.cpp index a31654b3..63f276c7 100644 --- a/RedPandaIDE/parser/cppparser.cpp +++ b/RedPandaIDE/parser/cppparser.cpp @@ -204,7 +204,7 @@ PStatement CppParser::doFindScopeStatement(const QString &filename, int line) co if (!fileInfo) return PStatement(); - return fileInfo->scopes.findScopeAtLine(line); + return fileInfo->findScopeAtLine(line); } PParsedFileInfo CppParser::findFileIncludes(const QString &filename, bool deleteIt) @@ -237,7 +237,7 @@ PStatement CppParser::findFunctionAt(const QString &fileName, int line) PParsedFileInfo fileInfo = mPreprocessor.findFileInfo(fileName); if (!fileInfo) return PStatement(); - for (PStatement& statement : fileInfo->statements) { + for (const PStatement& statement : fileInfo->statements()) { if (statement->kind != StatementKind::Function && statement->kind != StatementKind::Constructor && statement->kind != StatementKind::Destructor) @@ -672,7 +672,7 @@ PStatement CppParser::doFindAliasedStatement(const PStatement &statement, QSet resultList = findMembersOfStatement(name,PStatement()); foreach(const PStatement& resultStatement,resultList) { - if (fileInfo->includes.contains(resultStatement->fileName)) { + if (fileInfo->including(resultStatement->fileName)) { result = resultStatement; break; } @@ -685,7 +685,7 @@ PStatement CppParser::doFindAliasedStatement(const PStatement &statement, QSet resultList = findMembersOfStatement(name,namespaceStatement); foreach(const PStatement& resultStatement,resultList) { - if (fileInfo->includes.contains(resultStatement->fileName)) { + if (fileInfo->including(resultStatement->fileName)) { result = resultStatement; break; } @@ -841,7 +841,7 @@ QStringList CppParser::getFileDirectIncludes(const QString &filename) PParsedFileInfo fileInfo = mPreprocessor.findFileInfo(filename); if (fileInfo) { - return fileInfo->directIncludes; + return fileInfo->directIncludes(); } return QStringList(); @@ -857,7 +857,7 @@ QSet CppParser::internalGetIncludedFiles(const QString &filename) const PParsedFileInfo fileInfo = mPreprocessor.findFileInfo(filename); if (fileInfo) { - foreach (const QString& file, fileInfo->includes.keys()) { + foreach (const QString& file, fileInfo->includes()) { list.insert(file); } } @@ -885,13 +885,13 @@ QSet CppParser::internalGetFileUsings(const QString &filename) const // return result; PParsedFileInfo fileInfo= mPreprocessor.findFileInfo(filename); if (fileInfo) { - foreach (const QString& usingName, fileInfo->usings) { + foreach (const QString& usingName, fileInfo->usings()) { result.insert(usingName); } - foreach (const QString& subFile,fileInfo->includes.keys()){ + foreach (const QString& subFile,fileInfo->includes()){ PParsedFileInfo subIncludes = mPreprocessor.findFileInfo(subFile); if (subIncludes) { - foreach (const QString& usingName, subIncludes->usings) { + foreach (const QString& usingName, subIncludes->usings()) { result.insert(usingName); } } @@ -1438,8 +1438,7 @@ PStatement CppParser::addStatement(const PStatement& parent, if (oldStatement->fileName!=fileName) { PParsedFileInfo fileInfo = mPreprocessor.findFileInfo(fileName); if (fileInfo) { - fileInfo->statements.insert(oldStatement->fullName, - oldStatement); + fileInfo->addStatement(oldStatement); } } oldStatement->definitionLine = line; @@ -1499,7 +1498,7 @@ PStatement CppParser::addStatement(const PStatement& parent, if (result->kind!= StatementKind::Block) { PParsedFileInfo fileInfo = mPreprocessor.findFileInfo(fileName); if (fileInfo) { - fileInfo->statements.insert(result->fullName,result); + fileInfo->addStatement(result); } } return result; @@ -1747,7 +1746,7 @@ void CppParser::addSoloScopeLevel(PStatement& statement, int line, bool shouldRe PParsedFileInfo fileInfo = mPreprocessor.findFileInfo(mCurrentFile); if (fileInfo) { - fileInfo->scopes.addScope(line,statement); + fileInfo->addScope(line,statement); } // Set new scope @@ -1782,11 +1781,11 @@ void CppParser::removeScopeLevel(int line, int maxIndex) if (currentScope->children.isEmpty()) { // remove no children block if (fileInfo) - fileInfo->scopes.removeLastScope(); + fileInfo->removeLastScope(); mStatementList.deleteStatement(currentScope); } else { if (fileInfo) - fileInfo->statements.insert(currentScope->fullName,currentScope); + fileInfo->addStatement(currentScope); } } else if (currentScope->kind == StatementKind::Class) { mIndex=indexOfNextSemicolon(mIndex, maxIndex); @@ -1797,8 +1796,8 @@ void CppParser::removeScopeLevel(int line, int maxIndex) // Set new scope currentScope = getCurrentScope(); - if (fileInfo && fileInfo->scopes.lastScope()!=currentScope) { - fileInfo->scopes.addScope(line,currentScope); + if (fileInfo && fileInfo->lastScope()!=currentScope) { + fileInfo->addScope(line,currentScope); } if (!currentScope) { @@ -1843,7 +1842,7 @@ QStringList CppParser::sortFilesByIncludeRelations(const QSet &files) PParsedFileInfo fileInfo = mPreprocessor.findFileInfo(file); bool hasInclude=false; if (fileInfo) { - foreach(const QString& inc,fileInfo->includes.keys()) { + foreach(const QString& inc,fileInfo->includes()) { if (fileSet.contains(inc)) { hasInclude=true; break; @@ -3397,7 +3396,7 @@ void CppParser::handlePreprocessor() mCurrentFile = s.mid(0,delimPos).trimmed(); PParsedFileInfo fileInfo = mPreprocessor.findFileInfo(mCurrentFile); if (fileInfo) { - mCurrentFile = fileInfo->fileName; + mCurrentFile = fileInfo->fileName(); } else { mCurrentFile.squeeze(); } @@ -3982,7 +3981,7 @@ void CppParser::handleUsing(int maxIndex) if (!fileInfo) return; if (mNamespaces.contains(usingName)) { - fileInfo->usings.insert(usingName); + fileInfo->addUsing(usingName); } } //skip ; @@ -4287,7 +4286,7 @@ void CppParser::handleInheritance(PStatement derivedStatement, PClassInheritance inheritanceInfo->handled = true; PParsedFileInfo fileInfo = mPreprocessor.findFileInfo(statement->fileName); Q_ASSERT(fileInfo!=nullptr); - fileInfo->handledInheritances.append(inheritanceInfo); + fileInfo->addHandledInheritances(inheritanceInfo); } } @@ -4486,7 +4485,7 @@ PStatement CppParser::findMacro(const QString &phrase, const QString &fileName) PParsedFileInfo includes = mPreprocessor.findFileInfo(fileName); foreach (const PStatement& s, statements) { if (s->kind == StatementKind::Preprocessor) { - if (includes && fileName != s->fileName && !includes->includes.contains(s->fileName)) + if (includes && fileName != s->fileName && !includes->including(s->fileName)) continue; return s; } @@ -4552,8 +4551,8 @@ PStatement CppParser::findMemberOfStatement(const QString& filename, return s; // hard defines } if (s->fileName == filename || s->definitionFileName==filename) { return s; - } else if (fileInfo && (fileInfo->includes.contains(s->fileName) - || fileInfo->includes.contains(s->definitionFileName))) { + } else if (fileInfo && (fileInfo->including(s->fileName) + || fileInfo->including(s->definitionFileName))) { return s; } } @@ -5909,7 +5908,7 @@ void CppParser::internalInvalidateFile(const QString &fileName) //fPreprocessor.InvalidDefinesInFile(FileName); //we don't need this, since we reset defines after each parse //p->includes.clear(); //p->usings.clear(); - for (PStatement& statement:p->statements) { + for(PStatement statement:p->statements()) { if (statement->fileName==fileName) { mStatementList.deleteStatement(statement); } else { @@ -5918,16 +5917,16 @@ void CppParser::internalInvalidateFile(const QString &fileName) statement->definitionLine = statement->line; } } - p->statements.clear(); + p->clearStatements(); //invalidate all handledInheritances - for (std::weak_ptr &pWeakInfo: p->handledInheritances) { + for (std::weak_ptr pWeakInfo: p->handledInheritances()) { PClassInheritanceInfo info = pWeakInfo.lock(); if (info) { info->handled = false; } } - p->handledInheritances.clear(); + p->clearHandledInheritances(); } //remove all statements from namespace cache @@ -5968,7 +5967,7 @@ QSet CppParser::calculateFilesToBeReparsed(const QString &fileName) result.insert(fileName); foreach (const QString& file, mProjectFiles) { PParsedFileInfo fileInfo = mPreprocessor.findFileInfo(file); - if (fileInfo && fileInfo->includes.contains(fileName)) { + if (fileInfo && fileInfo->including(fileName)) { result.insert(file); } } diff --git a/RedPandaIDE/parser/cpppreprocessor.cpp b/RedPandaIDE/parser/cpppreprocessor.cpp index 0acf9fd9..2bd619bc 100644 --- a/RedPandaIDE/parser/cpppreprocessor.cpp +++ b/RedPandaIDE/parser/cpppreprocessor.cpp @@ -225,7 +225,7 @@ void CppPreprocessor::dumpIncludesListTo(const QString &fileName) const if (file.open(QIODevice::WriteOnly|QIODevice::Truncate)) { QTextStream stream(&file); for (const PParsedFileInfo& fileInfo:mFileInfos) { - stream<fileName<<" : " + stream<fileName()<<" : " #if QT_VERSION >= QT_VERSION_CHECK(5,15,0) <includes.keys()) { + foreach (const QString& s,fileInfo->includes()) { stream<<"\t--"+s #if QT_VERSION >= QT_VERSION_CHECK(5,15,0) <fileName; + fileName = fileInfo->fileName(); } else { fileName.squeeze(); } @@ -775,15 +775,14 @@ void CppPreprocessor::openInclude(QString fileName) // } bool alreadyIncluded = false; for (PParsedFile& parsedFile:mIncludes) { - if (parsedFile->fileInfo->includes.contains(fileName)) { + if (parsedFile->fileInfo->including(fileName)) { alreadyIncluded = true; - continue; } - parsedFile->fileInfo->includes.insert(fileName,false); + parsedFile->fileInfo->include(fileName); } PParsedFile innerMostFile = mIncludes.back(); - innerMostFile->fileInfo->includes.insert(fileName,true); - innerMostFile->fileInfo->directIncludes.append(fileName); + innerMostFile->fileInfo->include(fileName); + innerMostFile->fileInfo->directInclude(fileName); if (alreadyIncluded) return; // Backup old position if we're entering a new file @@ -804,8 +803,7 @@ void CppPreprocessor::openInclude(QString fileName) mCurrentFileInfo = findFileInfo(fileName); if (!mCurrentFileInfo) { // do NOT create a new item for a file that's already in the list - mCurrentFileInfo = std::make_shared(); - mCurrentFileInfo->fileName = fileName; + mCurrentFileInfo = std::make_shared(fileName); mFileInfos.insert(fileName,mCurrentFileInfo); } parsedFile->fileInfo = mCurrentFileInfo; @@ -832,8 +830,8 @@ void CppPreprocessor::openInclude(QString fileName) PParsedFileInfo fileInfo = findFileInfo(fileName); if (fileInfo) { for (PParsedFile& file:mIncludes) { - foreach (const QString& incFile,fileInfo->includes.keys()) { - file->fileInfo->includes.insert(incFile,false); + foreach (const QString& incFile,fileInfo->includes()) { + file->fileInfo->include(incFile); } } } @@ -917,7 +915,7 @@ void CppPreprocessor::addDefinesInFile(const QString &fileName) PParsedFileInfo fileInfo = findFileInfo(fileName); if (fileInfo) { - foreach (const QString& file, fileInfo->includes.keys()) { + foreach (const QString& file, fileInfo->includes()) { addDefinesInFile(file); } } diff --git a/RedPandaIDE/parser/cpppreprocessor.h b/RedPandaIDE/parser/cpppreprocessor.h index 2cb1afb3..ae795535 100644 --- a/RedPandaIDE/parser/cpppreprocessor.h +++ b/RedPandaIDE/parser/cpppreprocessor.h @@ -170,7 +170,7 @@ private: } void setCurrentBranch(BranchResult value){ if (!sameResultWithCurrentBranch(value)) { - mCurrentFileInfo->branches.insert(mIndex+1,value==BranchResult::isTrue); + mCurrentFileInfo->insertBranch(mIndex+1,value==BranchResult::isTrue); } mBranchResults.append(value); } @@ -180,7 +180,7 @@ private: mBranchResults.pop_back(); } if (!sameResultWithCurrentBranch(value)) { - mCurrentFileInfo->branches.insert(mIndex,getCurrentBranch()==BranchResult::isTrue); + mCurrentFileInfo->insertBranch(mIndex,getCurrentBranch()==BranchResult::isTrue); } } void addDefinesInFile(const QString& fileName); diff --git a/RedPandaIDE/parser/parserutils.cpp b/RedPandaIDE/parser/parserutils.cpp index 3d9eef01..17657eeb 100644 --- a/RedPandaIDE/parser/parserutils.cpp +++ b/RedPandaIDE/parser/parserutils.cpp @@ -544,7 +544,7 @@ bool isCFile(const QString& filename) return CppSourceExts->contains(fileInfo.suffix().toLower()); } -PStatement CppScopes::findScopeAtLine(int line) +PStatement CppScopes::findScopeAtLine(int line) const { if (mScopes.isEmpty()) return PStatement(); @@ -582,7 +582,7 @@ void CppScopes::addScope(int line, PStatement scopeStatement) } } -PStatement CppScopes::lastScope() +PStatement CppScopes::lastScope() const { if (mScopes.isEmpty()) return PStatement(); @@ -767,31 +767,129 @@ bool isTypeKind(StatementKind kind) } } -bool ParsedFileInfo::isLineVisible(int line) +ParsedFileInfo::ParsedFileInfo(const QString &fileName): + mFileName { fileName } +{ + +} + +void ParsedFileInfo::insertBranch(int level, bool branchTrue) +{ + mBranches.insert(level, branchTrue); +} + +bool ParsedFileInfo::isLineVisible(int line) const { int lastI=-1; - foreach(int i,branches.keys()) { + foreach(int i,mBranches.keys()) { if (line& ParsedFileInfo::includes() const +{ + return mIncludes; +} + +const QList >& ParsedFileInfo::handledInheritances() const +{ + return mHandledInheritances; +} + +QString ParsedFileInfo::fileName() const +{ + return mFileName; +} + +PStatement ParsedFileInfo::findScopeAtLine(int line) const +{ + return mScopes.findScopeAtLine(line); +} + +void ParsedFileInfo::addStatement(const PStatement &statement) +{ + mStatements.insert(statement->fullName,statement); +} + +void ParsedFileInfo::clearStatements() +{ + mStatements.clear(); +} + +void ParsedFileInfo::addScope(int line, const PStatement &scope) +{ + mScopes.addScope(line,scope); +} + +void ParsedFileInfo::removeLastScope() +{ + mScopes.removeLastScope(); +} + +PStatement ParsedFileInfo::lastScope() const +{ + return mScopes.lastScope(); +} + +void ParsedFileInfo::addUsing(const QString &usingSymbol) +{ + mUsings.insert(usingSymbol); +} + +void ParsedFileInfo::addHandledInheritances(std::weak_ptr classInheritanceInfo) +{ + mHandledInheritances.append(classInheritanceInfo); +} + +void ParsedFileInfo::clearHandledInheritances() +{ + mHandledInheritances.clear(); +} + +const StatementMap& ParsedFileInfo::statements() const +{ + return mStatements; +} + +const QSet& ParsedFileInfo::usings() const +{ + return mUsings; +} + +const QStringList& ParsedFileInfo::directIncludes() const +{ + return mDirectIncludes; } diff --git a/RedPandaIDE/parser/parserutils.h b/RedPandaIDE/parser/parserutils.h index efd52478..7693f7a4 100644 --- a/RedPandaIDE/parser/parserutils.h +++ b/RedPandaIDE/parser/parserutils.h @@ -295,9 +295,9 @@ using PCppScope = std::shared_ptr; class CppScopes { public: - PStatement findScopeAtLine(int line); + PStatement findScopeAtLine(int line) const; void addScope(int line, PStatement scopeStatement); - PStatement lastScope(); + PStatement lastScope() const; void removeLastScope(); void clear(); private: @@ -317,19 +317,46 @@ struct ClassInheritanceInfo { using PClassInheritanceInfo = std::shared_ptr; -struct ParsedFileInfo { - QString fileName; - QMap includes; - QStringList directIncludes; // - QSet usings; // namespaces it usings - StatementMap statements; // but we don't save temporary statements (full name as key) - StatementMap declaredStatements; // statements declared in this file (full name as key) - CppScopes scopes; // int is start line of the statement scope - QMap branches; - QList> handledInheritances; - bool isLineVisible(int line); - void includeFile(const QString &fileName); - void unincludeFile(const QString& fileName); +class ParsedFileInfo { +public: + ParsedFileInfo(const QString& fileName); + ParsedFileInfo(const ParsedFileInfo&)=delete; + ParsedFileInfo& operator=(const ParsedFileInfo&)=delete; + void insertBranch(int level, bool branchTrue); + bool isLineVisible(int line) const; + void include(const QString &fileName); + void uninclude(const QString &fileName); + void directInclude(const QString &fileName); + bool including(const QString &fileName) const; + PStatement findScopeAtLine(int line) const; + void addStatement(const PStatement &statement); + void clearStatements(); + void addScope(int line, const PStatement &scope); + void removeLastScope(); + PStatement lastScope() const; + void addUsing(const QString &usingSymbol); + void addHandledInheritances(std::weak_ptr classInheritanceInfo); + void clearHandledInheritances(); + + QString fileName() const; + const StatementMap& statements() const; + const QSet& usings() const; + const QStringList& directIncludes() const; + const QSet& includes() const; + const QList >& handledInheritances() const; + +private: + QString mFileName; + QMap mIncludeCounts; + QSet mIncludes; + QStringList mDirectIncludes; //We need order here. + QSet mUsings; // namespaces it usings + StatementMap mStatements; // but we don't save temporary statements (full name as key) + StatementMap mDeclaredStatements; // statements declared in this file (full name as key) + CppScopes mScopes; // int is start line of the statement scope + QMap mBranches; + QList> mHandledInheritances; + }; using PParsedFileInfo = std::shared_ptr; diff --git a/RedPandaIDE/widgets/classbrowser.cpp b/RedPandaIDE/widgets/classbrowser.cpp index a181950a..1ae52883 100644 --- a/RedPandaIDE/widgets/classbrowser.cpp +++ b/RedPandaIDE/widgets/classbrowser.cpp @@ -286,7 +286,7 @@ void ClassBrowserModel::addMembers() PParsedFileInfo p = mParser->findFileIncludes(mCurrentFile); if (!p) return; - filterChildren(mRoot,p->statements); + filterChildren(mRoot,p->statements()); } else { if (mParser->projectFiles().isEmpty()) return; @@ -294,7 +294,7 @@ void ClassBrowserModel::addMembers() PParsedFileInfo p = mParser->findFileIncludes(file); if (!p) return; - filterChildren(mRoot,p->statements); + filterChildren(mRoot,p->statements()); } } sortNode(mRoot);