- fix: Current editor wouldn't get parsed, when it's switched from another editor being parsed.

- enhancement: Support macro in #include preprocessing statements. (Issue #497)
This commit is contained in:
Roy Qu 2024-05-02 16:58:01 +08:00
parent e9f7d42aa6
commit 67b2ec1bc7
6 changed files with 64 additions and 30 deletions

View File

@ -154,6 +154,7 @@ Red Panda C++ Version 2.27
- enhancement: New code format option: "Remove superfluous empty lines exceeding" - enhancement: New code format option: "Remove superfluous empty lines exceeding"
- enhancement: New code format option: "Remove superfluous spaces" - enhancement: New code format option: "Remove superfluous spaces"
- change: Remove code format option: "Delete continuous empty lines" - change: Remove code format option: "Delete continuous empty lines"
- fix: Current editor wouldn't get parsed, when it's switched from another editor being parsed.
Red Panda C++ Version 2.26 Red Panda C++ Version 2.26
- enhancement: Code suggestion for embedded std::vectors. - enhancement: Code suggestion for embedded std::vectors.

View File

@ -4064,10 +4064,10 @@ Editor::TipType Editor::getTipType(QPoint point, QSynedit::BufferCoord& pos)
// do not allow when dragging selection // do not allow when dragging selection
if (isPointInSelection(pos)) if (isPointInSelection(pos))
return TipType::Selection; return TipType::Selection;
} else if (mParser && mParser->isIncludeLine(lineText(pos.line))) {
return TipType::Preprocessor;
} else if (attr->tokenType() == QSynedit::TokenType::Identifier) { } else if (attr->tokenType() == QSynedit::TokenType::Identifier) {
return TipType::Identifier; return TipType::Identifier;
} else if (mParser && mParser->isIncludeLine(lineText(pos.line))) {
return TipType::Preprocessor;
} else if (attr->tokenType() == QSynedit::TokenType::Number) { } else if (attr->tokenType() == QSynedit::TokenType::Number) {
return TipType::Number; return TipType::Number;
} else if (attr->tokenType() == QSynedit::TokenType::Keyword) { } else if (attr->tokenType() == QSynedit::TokenType::Keyword) {

View File

@ -1681,14 +1681,17 @@ void MainWindow::setProjectCurrentFile(const QString &filename)
void MainWindow::openFiles(const QStringList &files) void MainWindow::openFiles(const QStringList &files)
{ {
mOpeningFiles=true; mOpeningFiles=true;
auto action=finally([this]{
mOpeningFiles=false;
});
mEditorList->beginUpdate(); mEditorList->beginUpdate();
mOpenningFiles = true;
auto end = finally([this] { auto end = finally([this] {
this->mEditorList->endUpdate(); this->mEditorList->endUpdate();
mOpenningFiles = false; mOpeningFiles=false;
Editor* e=mEditorList->getEditor();
if (e) {
e->reparse(false);
e->checkSyntaxInBack();
e->reparseTodo();
e->activate();
}
}); });
//Check if there is a project file in the list and open it //Check if there is a project file in the list and open it
for (const QString& file:files) { for (const QString& file:files) {
@ -1704,14 +1707,6 @@ void MainWindow::openFiles(const QStringList &files)
if (files.length()>0) { if (files.length()>0) {
openFile(files.last(),true); openFile(files.last(),true);
} }
mEditorList->endUpdate();
Editor* e=mEditorList->getEditor();
if (e) {
e->reparse(false);
e->checkSyntaxInBack();
e->reparseTodo();
e->activate();
}
} }
Editor* MainWindow::openFile(QString filename, bool activate, QTabWidget* page) Editor* MainWindow::openFile(QString filename, bool activate, QTabWidget* page)

View File

@ -995,22 +995,40 @@ void CppParser::parseFile(const QString &fileName, bool inProject, bool onlyIfNo
return; return;
{ {
QMutexLocker locker(&mMutex); QMutexLocker locker(&mMutex);
if (mParsing || mLockCount>0) if (mParsing) {
mLastParseFileCommand = std::make_unique<ParseFileCommand>();
mLastParseFileCommand->fileName = fileName;
mLastParseFileCommand->inProject = inProject;
mLastParseFileCommand->onlyIfNotParsed = onlyIfNotParsed;
mLastParseFileCommand->updateView = updateView;
return;
}
if (mLockCount>0)
return; return;
updateSerialId();
mParsing = true; mParsing = true;
updateSerialId();
if (updateView) if (updateView)
emit onBusy(); emit onBusy();
emit onStartParsing(); emit onStartParsing();
} }
{ {
auto action = finally([&,this]{ auto action = finally([&,this]{
mParsing = false; QMutexLocker locker(&mMutex);
if (updateView) if (updateView)
emit onEndParsing(mFilesScannedCount,1); emit onEndParsing(mFilesScannedCount,1);
else else
emit onEndParsing(mFilesScannedCount,0); emit onEndParsing(mFilesScannedCount,0);
if (mLastParseFileCommand) {
mParsing = false;
::parseFile(PCppParser{this},
mLastParseFileCommand->fileName,
mLastParseFileCommand->inProject,
mLastParseFileCommand->onlyIfNotParsed,
mLastParseFileCommand->updateView);
mLastParseFileCommand = nullptr;
}
mParsing = false;
}); });
QString fName = fileName; QString fName = fileName;
if (onlyIfNotParsed && mPreprocessor.fileScanned(fName)) if (onlyIfNotParsed && mPreprocessor.fileScanned(fName))
@ -1040,15 +1058,6 @@ void CppParser::parseFile(const QString &fileName, bool inProject, bool onlyIfNo
emit onProgress(fileName,mFilesToScanCount,mFilesScannedCount); emit onProgress(fileName,mFilesToScanCount,mFilesScannedCount);
internalParse(fileName); internalParse(fileName);
} }
// if (inProject)
// mProjectFiles.insert(fileName);
// else {
// mProjectFiles.remove(fileName);
// }
// Parse from disk or stream
} }
} }
@ -6758,7 +6767,7 @@ CppFileParserThread::CppFileParserThread(
void CppFileParserThread::run() void CppFileParserThread::run()
{ {
if (mParser && !mParser->parsing()) { if (mParser) {
mParser->parseFile(mFileName,mInProject,mOnlyIfNotParsed,mUpdateView); mParser->parseFile(mFileName,mInProject,mOnlyIfNotParsed,mUpdateView);
} }
} }

View File

@ -30,6 +30,15 @@ class CppParser : public QObject
Q_OBJECT Q_OBJECT
public: public:
struct ParseFileCommand {
QString fileName;
bool inProject;
bool onlyIfNotParsed;
bool updateView;
};
using PParseFileCommand = std::unique_ptr<ParseFileCommand>;
explicit CppParser(QObject *parent = nullptr); explicit CppParser(QObject *parent = nullptr);
CppParser(const CppParser&)=delete; CppParser(const CppParser&)=delete;
CppParser& operator=(const CppParser)=delete; CppParser& operator=(const CppParser)=delete;
@ -732,6 +741,8 @@ private:
QRecursiveMutex mMutex; QRecursiveMutex mMutex;
QMap<QString,KeywordType> mCppKeywords; QMap<QString,KeywordType> mCppKeywords;
QSet<QString> mCppTypeKeywords; QSet<QString> mCppTypeKeywords;
PParseFileCommand mLastParseFileCommand;
}; };
using PCppParser = std::shared_ptr<CppParser>; using PCppParser = std::shared_ptr<CppParser>;

View File

@ -380,9 +380,27 @@ void CppPreprocessor::handleInclude(const QString &line, bool fromNext)
includes = mIncludePathList; includes = mIncludePathList;
projectIncludes = mProjectIncludePathList; projectIncludes = mProjectIncludePathList;
} }
int i=1; // skip '#'
int len=line.length();
//skip spaces
while (i<len && isSpaceChar(line[i]))
i++;
//skip 'include'
while (i<len && isIdentChar(line[i]))
i++;
//skip spaces
while (i<len && isSpaceChar(line[i]))
i++;
if (i>=line.length())
return;
QString s=line.mid(i);
QSet<QString> usedMacros;
s = expandMacros(s, usedMacros);
fileName = getHeaderFilename( fileName = getHeaderFilename(
file->fileName, file->fileName,
line, s,
includes, includes,
projectIncludes); projectIncludes);