- 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 spaces"
- 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
- 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
if (isPointInSelection(pos))
return TipType::Selection;
} else if (mParser && mParser->isIncludeLine(lineText(pos.line))) {
return TipType::Preprocessor;
} else if (attr->tokenType() == QSynedit::TokenType::Identifier) {
return TipType::Identifier;
} else if (mParser && mParser->isIncludeLine(lineText(pos.line))) {
return TipType::Preprocessor;
} else if (attr->tokenType() == QSynedit::TokenType::Number) {
return TipType::Number;
} 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)
{
mOpeningFiles=true;
auto action=finally([this]{
mOpeningFiles=false;
});
mEditorList->beginUpdate();
mOpenningFiles = true;
auto end = finally([this] {
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
for (const QString& file:files) {
@ -1704,14 +1707,6 @@ void MainWindow::openFiles(const QStringList &files)
if (files.length()>0) {
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)

View File

@ -995,22 +995,40 @@ void CppParser::parseFile(const QString &fileName, bool inProject, bool onlyIfNo
return;
{
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;
updateSerialId();
mParsing = true;
updateSerialId();
if (updateView)
emit onBusy();
emit onStartParsing();
}
{
auto action = finally([&,this]{
mParsing = false;
QMutexLocker locker(&mMutex);
if (updateView)
emit onEndParsing(mFilesScannedCount,1);
else
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;
if (onlyIfNotParsed && mPreprocessor.fileScanned(fName))
@ -1040,15 +1058,6 @@ void CppParser::parseFile(const QString &fileName, bool inProject, bool onlyIfNo
emit onProgress(fileName,mFilesToScanCount,mFilesScannedCount);
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()
{
if (mParser && !mParser->parsing()) {
if (mParser) {
mParser->parseFile(mFileName,mInProject,mOnlyIfNotParsed,mUpdateView);
}
}

View File

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

View File

@ -380,9 +380,27 @@ void CppPreprocessor::handleInclude(const QString &line, bool fromNext)
includes = mIncludePathList;
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(
file->fileName,
line,
s,
includes,
projectIncludes);