- fix: editor tooltip for #include_next is not correctly calculated
- fix: ctrl+click on #include_next header name doesn't open the right file - enhancement: parser used for non-project C files won't find header files in C++ include folders.
This commit is contained in:
parent
3509c25fc8
commit
a62910e1a3
4
NEWS.md
4
NEWS.md
|
@ -25,6 +25,10 @@ Red Panda C++ Version 1.5
|
|||
- fix: project files openned by double click in bookmark/breakpoint panel may cause app crash when closed.
|
||||
- fix: When open a project that's already openned, shouldn't close it.
|
||||
- enhancement: When open a project, let user choose weither open it in new window or replace the already openned project
|
||||
- fix: editor tooltip for #include_next is not correctly calculated
|
||||
- fix: ctrl+click on #include_next header name doesn't open the right file
|
||||
- enhancement: parser used for non-project C files won't find header files in C++ include folders.
|
||||
- fix: when physical memory is less than 16G or "Auto clearn
|
||||
|
||||
Red Panda C++ Version 1.4
|
||||
|
||||
|
|
|
@ -223,7 +223,7 @@ void Editor::loadFile(QString filename) {
|
|||
mUseCppSyntax = pSettings->editor().defaultFileCpp();
|
||||
}
|
||||
if (highlighter()) {
|
||||
reparse();
|
||||
reparse(true);
|
||||
if (pSettings->editor().syntaxCheckWhenLineChanged()) {
|
||||
checkSyntaxInBack();
|
||||
}
|
||||
|
@ -278,7 +278,7 @@ bool Editor::save(bool force, bool doReparse) {
|
|||
}
|
||||
|
||||
if (doReparse && mParser) {
|
||||
reparse();
|
||||
reparse(false);
|
||||
}
|
||||
if (doReparse && pSettings->editor().syntaxCheckWhenSave())
|
||||
checkSyntaxInBack();
|
||||
|
@ -387,7 +387,7 @@ bool Editor::saveAs(const QString &name, bool fromProject){
|
|||
}
|
||||
applyColorScheme(pSettings->editor().colorScheme());
|
||||
|
||||
reparse();
|
||||
reparse(false);
|
||||
|
||||
if (pSettings->editor().syntaxCheckWhenSave())
|
||||
pMainWindow->checkSyntaxInBack(this);
|
||||
|
@ -1054,6 +1054,7 @@ bool Editor::event(QEvent *event)
|
|||
|
||||
// Get subject
|
||||
bool isIncludeLine = false;
|
||||
bool isIncludeNextLine = false;
|
||||
QSynedit::BufferCoord pBeginPos,pEndPos;
|
||||
QString s;
|
||||
QStringList expression;
|
||||
|
@ -1061,8 +1062,10 @@ bool Editor::event(QEvent *event)
|
|||
case TipType::Preprocessor:
|
||||
// When hovering above a preprocessor line, determine if we want to show an include or a identifier hint
|
||||
s = document()->getString(p.line - 1);
|
||||
isIncludeNextLine = mParser->isIncludeNextLine(s);
|
||||
if (!isIncludeNextLine)
|
||||
isIncludeLine = mParser->isIncludeLine(s);
|
||||
if (!isIncludeLine)
|
||||
if (!isIncludeNextLine &&!isIncludeLine)
|
||||
s = wordAtRowCol(p);
|
||||
break;
|
||||
case TipType::Identifier:
|
||||
|
@ -1116,9 +1119,9 @@ bool Editor::event(QEvent *event)
|
|||
QString hint = "";
|
||||
switch (reason) {
|
||||
case TipType::Preprocessor:
|
||||
if (isIncludeLine) {
|
||||
if (isIncludeNextLine || isIncludeLine) {
|
||||
if (pSettings->editor().enableHeaderToolTips())
|
||||
hint = getFileHint(s);
|
||||
hint = getFileHint(s, isIncludeNextLine);
|
||||
} else if (//devEditor.ParserHints and
|
||||
!mCompletionPopup->isVisible()
|
||||
&& !mHeaderCompletionPopup->isVisible()) {
|
||||
|
@ -1204,7 +1207,14 @@ void Editor::mouseReleaseEvent(QMouseEvent *event)
|
|||
QSynedit::BufferCoord p;
|
||||
if (pointToCharLine(event->pos(),p)) {
|
||||
QString s = document()->getString(p.line - 1);
|
||||
if (mParser->isIncludeLine(s)) {
|
||||
if (mParser->isIncludeNextLine(s)) {
|
||||
QString filename = mParser->getHeaderFileName(mFilename,s, true);
|
||||
Editor * e = pMainWindow->editorList()->getEditorByFilename(filename);
|
||||
if (e) {
|
||||
e->setCaretPositionAndActivate(1,1);
|
||||
return;
|
||||
}
|
||||
} if (mParser->isIncludeLine(s)) {
|
||||
QString filename = mParser->getHeaderFileName(mFilename,s);
|
||||
Editor * e = pMainWindow->editorList()->getEditorByFilename(filename);
|
||||
if (e) {
|
||||
|
@ -1288,8 +1298,7 @@ void Editor::showEvent(QShowEvent */*event*/)
|
|||
&CppParser::onEndParsing,
|
||||
this,
|
||||
&QSynedit::SynEdit::invalidate);
|
||||
resetCppParser(mParser);
|
||||
reparse();
|
||||
reparse(false);
|
||||
}
|
||||
pMainWindow->debugger()->setIsForProject(inProject());
|
||||
pMainWindow->bookmarkModel()->setIsForProject(inProject());
|
||||
|
@ -1303,17 +1312,18 @@ void Editor::showEvent(QShowEvent */*event*/)
|
|||
|
||||
void Editor::hideEvent(QHideEvent */*event*/)
|
||||
{
|
||||
if (pSettings->codeCompletion().clearWhenEditorHidden()
|
||||
&& !inProject() && mParser
|
||||
&& !pMainWindow->isMinimized()) {
|
||||
//recreate a parser, to totally clean memories the parse uses;
|
||||
initParser();
|
||||
}
|
||||
if (mParser) {
|
||||
disconnect(mParser.get(),
|
||||
&CppParser::onEndParsing,
|
||||
this,
|
||||
&QSynedit::SynEdit::invalidate);
|
||||
}
|
||||
if (pSettings->codeCompletion().clearWhenEditorHidden()
|
||||
&& !inProject() && mParser
|
||||
&& !pMainWindow->isMinimized()) {
|
||||
mParser->reset();
|
||||
}
|
||||
setHideTime(QDateTime::currentDateTime());
|
||||
}
|
||||
|
||||
|
@ -1548,7 +1558,7 @@ void Editor::onStatusChanged(QSynedit::StatusChanges changes)
|
|||
&& changes.testFlag(QSynedit::StatusChange::scCaretY))) {
|
||||
mCurrentLineModified = false;
|
||||
if (!changes.testFlag(QSynedit::StatusChange::scOpenFile))
|
||||
reparse();
|
||||
reparse(false);
|
||||
// if (pSettings->codeCompletion().clearWhenEditorHidden()
|
||||
// && changes.testFlag(SynStatusChange::scOpenFile)) {
|
||||
// } else{
|
||||
|
@ -2681,7 +2691,7 @@ Editor::QuoteStatus Editor::getQuoteStatus()
|
|||
return Result;
|
||||
}
|
||||
|
||||
void Editor::reparse()
|
||||
void Editor::reparse(bool resetParser)
|
||||
{
|
||||
if (!pSettings->codeCompletion().enabled())
|
||||
return;
|
||||
|
@ -2699,6 +2709,8 @@ void Editor::reparse()
|
|||
if (language!=mParser->language() && !inProject()) {
|
||||
mParser->setLanguage(language);
|
||||
resetCppParser(mParser);
|
||||
} else if (resetParser && !inProject()) {
|
||||
resetCppParser(mParser);
|
||||
}
|
||||
parseFile(mParser,mFilename, inProject());
|
||||
}
|
||||
|
@ -3438,9 +3450,9 @@ void Editor::cancelHint()
|
|||
updateMouseCursor();
|
||||
}
|
||||
|
||||
QString Editor::getFileHint(const QString &s)
|
||||
QString Editor::getFileHint(const QString &s, bool fromNext)
|
||||
{
|
||||
QString fileName = mParser->getHeaderFileName(mFilename, s);
|
||||
QString fileName = mParser->getHeaderFileName(mFilename, s, fromNext);
|
||||
if (fileExists(fileName)) {
|
||||
return fileName + " - " + tr("Ctrl+click for more info");
|
||||
}
|
||||
|
@ -4333,7 +4345,7 @@ void Editor::reformat()
|
|||
setTopLine(oldTopLine);
|
||||
setOptions(oldOptions);
|
||||
endUndoBlock();
|
||||
reparse();
|
||||
reparse(true);
|
||||
checkSyntaxInBack();
|
||||
reparseTodo();
|
||||
pMainWindow->updateEditorActions();
|
||||
|
|
|
@ -199,7 +199,7 @@ public:
|
|||
void checkSyntaxInBack();
|
||||
void gotoDeclaration(const QSynedit::BufferCoord& pos);
|
||||
void gotoDefinition(const QSynedit::BufferCoord& pos);
|
||||
void reparse();
|
||||
void reparse(bool resetParser);
|
||||
void reparseTodo();
|
||||
void insertString(const QString& value, bool moveCursor);
|
||||
void insertCodeSnippet(const QString& code);
|
||||
|
@ -277,7 +277,7 @@ private:
|
|||
|
||||
TipType getTipType(QPoint point, QSynedit::BufferCoord& pos);
|
||||
void cancelHint();
|
||||
QString getFileHint(const QString& s);
|
||||
QString getFileHint(const QString& s, bool fromNext);
|
||||
QString getParserHint(const QStringList& expression,const QString& s, int line);
|
||||
void showDebugHint(const QString& s,int line);
|
||||
QString getErrorHint(const PSyntaxIssue& issue);
|
||||
|
|
|
@ -1394,7 +1394,7 @@ void MainWindow::changeOptions(const QString &widgetName, const QString &groupNa
|
|||
} else if (mProject && e && e->inProject()) {
|
||||
scanActiveProject(true);
|
||||
} else if (e) {
|
||||
e->reparse();
|
||||
reparseNonProjectEditors();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -4815,9 +4815,8 @@ void MainWindow::onCompilerSetChanged(int index)
|
|||
{
|
||||
if (index<0)
|
||||
return;
|
||||
if (mProject) {
|
||||
Editor *e = mEditorList->getEditor();
|
||||
if (!e || e->inProject()) {
|
||||
if (mProject && (!e || e->inProject())) {
|
||||
if(QMessageBox::warning(
|
||||
e,
|
||||
tr("Change Project Compiler Set"),
|
||||
|
@ -4830,11 +4829,14 @@ void MainWindow::onCompilerSetChanged(int index)
|
|||
}
|
||||
mProject->setCompilerSet(index);
|
||||
mProject->saveOptions();
|
||||
scanActiveProject(true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
pSettings->compilerSets().setDefaultIndex(index);
|
||||
pSettings->compilerSets().saveDefaultIndex();
|
||||
|
||||
reparseNonProjectEditors();
|
||||
}
|
||||
|
||||
void MainWindow::logToolsOutput(const QString& msg)
|
||||
|
@ -6501,6 +6503,19 @@ void MainWindow::setProjectViewCurrentUnit(std::shared_ptr<ProjectUnit> unit) {
|
|||
}
|
||||
}
|
||||
|
||||
void MainWindow::reparseNonProjectEditors()
|
||||
{
|
||||
for (int i=0;i<mEditorList->pageCount();i++) {
|
||||
Editor* e=(*mEditorList)[i];
|
||||
if (!e->inProject()) {
|
||||
if (!pSettings->codeCompletion().clearWhenEditorHidden() || e->isVisible()) {
|
||||
e->reparse(true);
|
||||
e->checkSyntaxInBack();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::onProjectViewNodeRenamed()
|
||||
{
|
||||
updateProjectView();
|
||||
|
@ -6807,8 +6822,8 @@ void MainWindow::on_actionRename_Symbol_triggered()
|
|||
CppRefacter refactor;
|
||||
|
||||
refactor.renameSymbol(editor,oldCaretXY,newWord);
|
||||
editor->reparse();
|
||||
|
||||
editor->reparse(true);
|
||||
editor->checkSyntaxInBack();
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -279,6 +279,8 @@ private:
|
|||
void setProjectViewCurrentNode(std::shared_ptr<ProjectModelNode> node);
|
||||
void setProjectViewCurrentUnit(std::shared_ptr<ProjectUnit> unit);
|
||||
|
||||
void reparseNonProjectEditors();
|
||||
|
||||
private slots:
|
||||
void onProjectViewNodeRenamed();
|
||||
void setDockExplorerToArea(const Qt::DockWidgetArea &area);
|
||||
|
|
|
@ -54,6 +54,8 @@ CppParser::CppParser(QObject *parent) : QObject(parent),
|
|||
mCppKeywords = CppKeywords;
|
||||
mCppTypeKeywords = CppTypeKeywords;
|
||||
mEnabled = true;
|
||||
|
||||
mPreprocessor = std::make_shared<CppPreprocessor>();
|
||||
//mNamespaces;
|
||||
//mBlockBeginSkips;
|
||||
//mBlockEndSkips;
|
||||
|
@ -82,34 +84,34 @@ void CppParser::addHardDefineByLine(const QString &line)
|
|||
{
|
||||
QMutexLocker locker(&mMutex);
|
||||
if (line.startsWith('#')) {
|
||||
mPreprocessor.addHardDefineByLine(line.mid(1).trimmed());
|
||||
mPreprocessor->addHardDefineByLine(line.mid(1).trimmed());
|
||||
} else {
|
||||
mPreprocessor.addHardDefineByLine(line);
|
||||
mPreprocessor->addHardDefineByLine(line);
|
||||
}
|
||||
}
|
||||
|
||||
void CppParser::addIncludePath(const QString &value)
|
||||
{
|
||||
QMutexLocker locker(&mMutex);
|
||||
mPreprocessor.addIncludePath(includeTrailingPathDelimiter(value));
|
||||
mPreprocessor->addIncludePath(includeTrailingPathDelimiter(value));
|
||||
}
|
||||
|
||||
void CppParser::addProjectIncludePath(const QString &value)
|
||||
{
|
||||
QMutexLocker locker(&mMutex);
|
||||
mPreprocessor.addProjectIncludePath(includeTrailingPathDelimiter(value));
|
||||
mPreprocessor->addProjectIncludePath(includeTrailingPathDelimiter(value));
|
||||
}
|
||||
|
||||
void CppParser::clearIncludePaths()
|
||||
{
|
||||
QMutexLocker locker(&mMutex);
|
||||
mPreprocessor.clearIncludePaths();
|
||||
mPreprocessor->clearIncludePaths();
|
||||
}
|
||||
|
||||
void CppParser::clearProjectIncludePaths()
|
||||
{
|
||||
QMutexLocker locker(&mMutex);
|
||||
mPreprocessor.clearProjectIncludePaths();
|
||||
mPreprocessor->clearProjectIncludePaths();
|
||||
}
|
||||
|
||||
void CppParser::clearProjectFiles()
|
||||
|
@ -154,7 +156,7 @@ PStatement CppParser::findAndScanBlockAt(const QString &filename, int line)
|
|||
if (mParsing) {
|
||||
return PStatement();
|
||||
}
|
||||
PFileIncludes fileIncludes = mPreprocessor.includesList().value(filename);
|
||||
PFileIncludes fileIncludes = mPreprocessor->includesList().value(filename);
|
||||
if (!fileIncludes)
|
||||
return PStatement();
|
||||
|
||||
|
@ -165,9 +167,9 @@ PStatement CppParser::findAndScanBlockAt(const QString &filename, int line)
|
|||
PFileIncludes CppParser::findFileIncludes(const QString &filename, bool deleteIt)
|
||||
{
|
||||
QMutexLocker locker(&mMutex);
|
||||
PFileIncludes fileIncludes = mPreprocessor.includesList().value(filename,PFileIncludes());
|
||||
PFileIncludes fileIncludes = mPreprocessor->includesList().value(filename,PFileIncludes());
|
||||
if (deleteIt && fileIncludes)
|
||||
mPreprocessor.includesList().remove(filename);
|
||||
mPreprocessor->includesList().remove(filename);
|
||||
return fileIncludes;
|
||||
}
|
||||
QString CppParser::findFirstTemplateParamOf(const QString &fileName, const QString &phrase, const PStatement& currentScope)
|
||||
|
@ -199,7 +201,7 @@ QString CppParser::findFirstTemplateParamOf(const QString &fileName, const QStri
|
|||
PStatement CppParser::findFunctionAt(const QString &fileName, int line)
|
||||
{
|
||||
QMutexLocker locker(&mMutex);
|
||||
PFileIncludes fileIncludes = mPreprocessor.includesList().value(fileName);
|
||||
PFileIncludes fileIncludes = mPreprocessor->includesList().value(fileName);
|
||||
if (!fileIncludes)
|
||||
return PStatement();
|
||||
for (PStatement& statement : fileIncludes->statements) {
|
||||
|
@ -648,7 +650,7 @@ QStringList CppParser::getFileDirectIncludes(const QString &filename)
|
|||
return QStringList();
|
||||
if (filename.isEmpty())
|
||||
return QStringList();
|
||||
PFileIncludes fileIncludes = mPreprocessor.includesList().value(filename,PFileIncludes());
|
||||
PFileIncludes fileIncludes = mPreprocessor->includesList().value(filename,PFileIncludes());
|
||||
|
||||
if (fileIncludes) {
|
||||
return fileIncludes->directIncludes;
|
||||
|
@ -666,7 +668,7 @@ QSet<QString> CppParser::getFileIncludes(const QString &filename)
|
|||
if (filename.isEmpty())
|
||||
return list;
|
||||
list.insert(filename);
|
||||
PFileIncludes fileIncludes = mPreprocessor.includesList().value(filename,PFileIncludes());
|
||||
PFileIncludes fileIncludes = mPreprocessor->includesList().value(filename,PFileIncludes());
|
||||
|
||||
if (fileIncludes) {
|
||||
foreach (const QString& file, fileIncludes->includeFiles.keys()) {
|
||||
|
@ -684,13 +686,13 @@ QSet<QString> CppParser::getFileUsings(const QString &filename)
|
|||
return result;
|
||||
if (mParsing)
|
||||
return result;
|
||||
PFileIncludes fileIncludes= mPreprocessor.includesList().value(filename,PFileIncludes());
|
||||
PFileIncludes fileIncludes= mPreprocessor->includesList().value(filename,PFileIncludes());
|
||||
if (fileIncludes) {
|
||||
foreach (const QString& usingName, fileIncludes->usings) {
|
||||
result.insert(usingName);
|
||||
}
|
||||
foreach (const QString& subFile,fileIncludes->includeFiles.keys()){
|
||||
PFileIncludes subIncludes = mPreprocessor.includesList().value(subFile,PFileIncludes());
|
||||
PFileIncludes subIncludes = mPreprocessor->includesList().value(subFile,PFileIncludes());
|
||||
if (subIncludes) {
|
||||
foreach (const QString& usingName, subIncludes->usings) {
|
||||
result.insert(usingName);
|
||||
|
@ -701,11 +703,37 @@ QSet<QString> CppParser::getFileUsings(const QString &filename)
|
|||
return result;
|
||||
}
|
||||
|
||||
QString CppParser::getHeaderFileName(const QString &relativeTo, const QString &line)
|
||||
QString CppParser::getHeaderFileName(const QString &relativeTo, const QString &headerName, bool fromNext)
|
||||
{
|
||||
QMutexLocker locker(&mMutex);
|
||||
return ::getHeaderFilename(relativeTo, line, mPreprocessor.includePathList(),
|
||||
mPreprocessor.projectIncludePathList());
|
||||
QString currentDir = includeTrailingPathDelimiter(extractFileDir(relativeTo));
|
||||
QStringList includes;
|
||||
QStringList projectIncludes;
|
||||
bool found;
|
||||
if (fromNext && mPreprocessor->includePaths().contains(currentDir)) {
|
||||
foreach(const QString& s, mPreprocessor->includePathList()) {
|
||||
if (found) {
|
||||
includes.append(s);
|
||||
continue;
|
||||
} else if (s == currentDir)
|
||||
found = true;
|
||||
}
|
||||
projectIncludes = mPreprocessor->projectIncludePathList();
|
||||
} else if (fromNext && mPreprocessor->projectIncludePaths().contains(currentDir)) {
|
||||
includes = mPreprocessor->includePathList();
|
||||
foreach(const QString& s, mPreprocessor->projectIncludePathList()) {
|
||||
if (found) {
|
||||
includes.append(s);
|
||||
continue;
|
||||
} else if (s == currentDir)
|
||||
found = true;
|
||||
}
|
||||
} else {
|
||||
includes = mPreprocessor->includePathList();
|
||||
projectIncludes = mPreprocessor->projectIncludePathList();
|
||||
}
|
||||
return ::getHeaderFilename(relativeTo, headerName, includes,
|
||||
projectIncludes);
|
||||
}
|
||||
|
||||
void CppParser::invalidateFile(const QString &fileName)
|
||||
|
@ -735,16 +763,27 @@ bool CppParser::isIncludeLine(const QString &line)
|
|||
return false;
|
||||
}
|
||||
|
||||
bool CppParser::isIncludeNextLine(const QString &line)
|
||||
{
|
||||
QString trimmedLine = line.trimmed();
|
||||
if ((trimmedLine.length() > 0)
|
||||
&& trimmedLine.startsWith('#')) { // it's a preprocessor line
|
||||
if (trimmedLine.mid(1).trimmed().startsWith("include_next"))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CppParser::isProjectHeaderFile(const QString &fileName)
|
||||
{
|
||||
QMutexLocker locker(&mMutex);
|
||||
return ::isSystemHeaderFile(fileName,mPreprocessor.projectIncludePaths());
|
||||
return ::isSystemHeaderFile(fileName,mPreprocessor->projectIncludePaths());
|
||||
}
|
||||
|
||||
bool CppParser::isSystemHeaderFile(const QString &fileName)
|
||||
{
|
||||
QMutexLocker locker(&mMutex);
|
||||
return ::isSystemHeaderFile(fileName,mPreprocessor.includePaths());
|
||||
return ::isSystemHeaderFile(fileName,mPreprocessor->includePaths());
|
||||
}
|
||||
|
||||
void CppParser::parseFile(const QString &fileName, bool inProject, bool onlyIfNotParsed, bool updateView)
|
||||
|
@ -771,7 +810,7 @@ void CppParser::parseFile(const QString &fileName, bool inProject, bool onlyIfNo
|
|||
emit onEndParsing(mFilesScannedCount,0);
|
||||
});
|
||||
QString fName = fileName;
|
||||
if (onlyIfNotParsed && mPreprocessor.scannedFiles().contains(fName))
|
||||
if (onlyIfNotParsed && mPreprocessor->scannedFiles().contains(fName))
|
||||
return;
|
||||
|
||||
QSet<QString> files = calculateFilesToBeReparsed(fileName);
|
||||
|
@ -792,7 +831,7 @@ void CppParser::parseFile(const QString &fileName, bool inProject, bool onlyIfNo
|
|||
if (isHFile(file)) {
|
||||
mFilesScannedCount++;
|
||||
emit onProgress(file,mFilesToScanCount,mFilesScannedCount);
|
||||
if (!mPreprocessor.scannedFiles().contains(file)) {
|
||||
if (!mPreprocessor->scannedFiles().contains(file)) {
|
||||
internalParse(file);
|
||||
}
|
||||
}
|
||||
|
@ -802,7 +841,7 @@ void CppParser::parseFile(const QString &fileName, bool inProject, bool onlyIfNo
|
|||
if (!isHFile(file)) {
|
||||
mFilesScannedCount++;
|
||||
emit onProgress(file,mFilesToScanCount,mFilesScannedCount);
|
||||
if (!mPreprocessor.scannedFiles().contains(file)) {
|
||||
if (!mPreprocessor->scannedFiles().contains(file)) {
|
||||
internalParse(file);
|
||||
}
|
||||
}
|
||||
|
@ -840,7 +879,7 @@ void CppParser::parseFileList(bool updateView)
|
|||
if (isHFile(file)) {
|
||||
mFilesScannedCount++;
|
||||
emit onProgress(mCurrentFile,mFilesToScanCount,mFilesScannedCount);
|
||||
if (!mPreprocessor.scannedFiles().contains(file)) {
|
||||
if (!mPreprocessor->scannedFiles().contains(file)) {
|
||||
internalParse(file);
|
||||
}
|
||||
}
|
||||
|
@ -850,7 +889,7 @@ void CppParser::parseFileList(bool updateView)
|
|||
if (isCFile(file)) {
|
||||
mFilesScannedCount++;
|
||||
emit onProgress(mCurrentFile,mFilesToScanCount,mFilesScannedCount);
|
||||
if (!mPreprocessor.scannedFiles().contains(file)) {
|
||||
if (!mPreprocessor->scannedFiles().contains(file)) {
|
||||
internalParse(file);
|
||||
}
|
||||
}
|
||||
|
@ -872,7 +911,7 @@ void CppParser::parseHardDefines()
|
|||
mParsing = false;
|
||||
mIsSystemHeader=oldIsSystemHeader;
|
||||
});
|
||||
for (const PDefine& define:mPreprocessor.hardDefines()) {
|
||||
for (const PDefine& define:mPreprocessor->hardDefines()) {
|
||||
addStatement(
|
||||
PStatement(), // defines don't belong to any scope
|
||||
"",
|
||||
|
@ -895,7 +934,7 @@ bool CppParser::parsing() const
|
|||
return mParsing;
|
||||
}
|
||||
|
||||
void CppParser::reset()
|
||||
void CppParser::resetParser()
|
||||
{
|
||||
while (true) {
|
||||
{
|
||||
|
@ -914,38 +953,34 @@ void CppParser::reset()
|
|||
mParsing = false;
|
||||
});
|
||||
emit onBusy();
|
||||
mPreprocessor.clear();
|
||||
mPreprocessor->clear();
|
||||
mUniqId = 0;
|
||||
mSkipList.clear();
|
||||
mBlockBeginSkips.clear();
|
||||
mBlockEndSkips.clear();
|
||||
mInlineNamespaceEndSkips.clear();
|
||||
|
||||
mParseLocalHeaders = true;
|
||||
mParseGlobalHeaders = true;
|
||||
mIsSystemHeader = false;
|
||||
mIsHeader = false;
|
||||
mIsProjectFile = false;
|
||||
mFilesScannedCount=0;
|
||||
mFilesToScanCount = 0;
|
||||
|
||||
mCurrentScope.clear();
|
||||
mCurrentClassScope.clear();
|
||||
mProjectFiles.clear();
|
||||
mFilesToScan.clear();
|
||||
mTokenizer.reset();
|
||||
// Remove all statements
|
||||
mSkipList.clear();
|
||||
mStatementList.clear();
|
||||
|
||||
// We haven't scanned anything anymore
|
||||
mPreprocessor.scannedFiles().clear();
|
||||
|
||||
// We don't include anything anymore
|
||||
mPreprocessor.includesList().clear();
|
||||
|
||||
mNamespaces.clear();
|
||||
mProjectFiles.clear();
|
||||
mBlockBeginSkips.clear(); //list of for/catch block begin token index;
|
||||
mBlockEndSkips.clear(); //list of for/catch block end token index;
|
||||
mInlineNamespaceEndSkips.clear(); // list for inline namespace end token index;
|
||||
mFilesToScan.clear(); // list of base files to scan
|
||||
mNamespaces.clear(); //TStringList<String,List<Statement>> namespace and the statements in its scope
|
||||
mInlineNamespaces.clear();
|
||||
|
||||
mPreprocessor.clearProjectIncludePaths();
|
||||
mPreprocessor.clearIncludePaths();
|
||||
mProjectFiles.clear();
|
||||
// We haven't scanned anything anymore
|
||||
mPreprocessor = std::make_shared<CppPreprocessor>();
|
||||
mTokenizer.reset();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -957,12 +992,12 @@ void CppParser::unFreeze()
|
|||
|
||||
QSet<QString> CppParser::scannedFiles()
|
||||
{
|
||||
return mPreprocessor.scannedFiles();
|
||||
return mPreprocessor->scannedFiles();
|
||||
}
|
||||
|
||||
bool CppParser::isFileParsed(const QString &filename)
|
||||
{
|
||||
return mPreprocessor.scannedFiles().contains(filename);
|
||||
return mPreprocessor->scannedFiles().contains(filename);
|
||||
}
|
||||
|
||||
QString CppParser::getScopePrefix(const PStatement& statement){
|
||||
|
@ -1099,7 +1134,7 @@ void CppParser::addFileToScan(const QString& value, bool inProject)
|
|||
mProjectFiles.insert(value);
|
||||
|
||||
// Only parse given file
|
||||
if (!mPreprocessor.scannedFiles().contains(value)) {
|
||||
if (!mPreprocessor->scannedFiles().contains(value)) {
|
||||
mFilesToScan.insert(value);
|
||||
}
|
||||
|
||||
|
@ -1179,12 +1214,12 @@ PStatement CppParser::addStatement(const PStatement& parent,
|
|||
if (oldStatement && !oldStatement->hasDefinition) {
|
||||
oldStatement->hasDefinition = true;
|
||||
if (oldStatement->fileName!=fileName) {
|
||||
PFileIncludes fileIncludes1=mPreprocessor.includesList().value(fileName);
|
||||
PFileIncludes fileIncludes1=mPreprocessor->includesList().value(fileName);
|
||||
if (fileIncludes1) {
|
||||
fileIncludes1->statements.insert(oldStatement->fullName,
|
||||
oldStatement);
|
||||
fileIncludes1->dependingFiles.insert(oldStatement->fileName);
|
||||
PFileIncludes fileIncludes2=mPreprocessor.includesList().value(oldStatement->fileName);
|
||||
PFileIncludes fileIncludes2=mPreprocessor->includesList().value(oldStatement->fileName);
|
||||
if (fileIncludes2) {
|
||||
fileIncludes2->dependedFiles.insert(fileName);
|
||||
}
|
||||
|
@ -1242,7 +1277,7 @@ PStatement CppParser::addStatement(const PStatement& parent,
|
|||
}
|
||||
|
||||
if (result->kind!= StatementKind::skBlock) {
|
||||
PFileIncludes fileIncludes = mPreprocessor.includesList().value(fileName);
|
||||
PFileIncludes fileIncludes = mPreprocessor->includesList().value(fileName);
|
||||
if (fileIncludes) {
|
||||
fileIncludes->statements.insert(result->fullName,result);
|
||||
fileIncludes->declaredStatements.insert(result->fullName,result);
|
||||
|
@ -1323,7 +1358,7 @@ void CppParser::addSoloScopeLevel(PStatement& statement, int line, bool shouldRe
|
|||
|
||||
mCurrentScope.append(statement);
|
||||
|
||||
PFileIncludes fileIncludes = mPreprocessor.includesList().value(mCurrentFile);
|
||||
PFileIncludes fileIncludes = mPreprocessor->includesList().value(mCurrentFile);
|
||||
|
||||
if (fileIncludes) {
|
||||
fileIncludes->scopes.addScope(line,statement);
|
||||
|
@ -1347,7 +1382,7 @@ void CppParser::removeScopeLevel(int line)
|
|||
if (mCurrentScope.isEmpty())
|
||||
return; // TODO: should be an exception
|
||||
PStatement currentScope = mCurrentScope.back();;
|
||||
PFileIncludes fileIncludes = mPreprocessor.includesList().value(mCurrentFile);
|
||||
PFileIncludes fileIncludes = mPreprocessor->includesList().value(mCurrentFile);
|
||||
if (currentScope && (currentScope->kind == StatementKind::skBlock)) {
|
||||
if (currentScope->children.isEmpty()) {
|
||||
// remove no children block
|
||||
|
@ -2562,7 +2597,7 @@ void CppParser::handlePreprocessor()
|
|||
s = s.trimmed();
|
||||
// Ask the preprocessor to cut parts up
|
||||
QString name,args,value;
|
||||
mPreprocessor.getDefineParts(s,name,args,value);
|
||||
mPreprocessor->getDefineParts(s,name,args,value);
|
||||
|
||||
addStatement(
|
||||
nullptr, // defines don't belong to any scope
|
||||
|
@ -3044,7 +3079,7 @@ void CppParser::handleUsing()
|
|||
scopeStatement->usingList.insert(fullName);
|
||||
}
|
||||
} else {
|
||||
PFileIncludes fileInfo = mPreprocessor.includesList().value(mCurrentFile);
|
||||
PFileIncludes fileInfo = mPreprocessor->includesList().value(mCurrentFile);
|
||||
if (!fileInfo)
|
||||
return;
|
||||
if (mNamespaces.contains(usingName)) {
|
||||
|
@ -3232,24 +3267,24 @@ void CppParser::internalParse(const QString &fileName)
|
|||
// Preprocess the file...
|
||||
{
|
||||
auto action = finally([this]{
|
||||
mPreprocessor.reset();
|
||||
mPreprocessor->reset();
|
||||
mTokenizer.reset();
|
||||
});
|
||||
// Let the preprocessor augment the include records
|
||||
// mPreprocessor.setIncludesList(mIncludesList);
|
||||
// mPreprocessor.setScannedFileList(mScannedFiles);
|
||||
// mPreprocessor.setIncludePaths(mIncludePaths);
|
||||
// mPreprocessor.setProjectIncludePaths(mProjectIncludePaths);
|
||||
mPreprocessor.setScanOptions(mParseGlobalHeaders, mParseLocalHeaders);
|
||||
mPreprocessor.preprocess(fileName, buffer);
|
||||
// mPreprocessor->setIncludesList(mIncludesList);
|
||||
// mPreprocessor->setScannedFileList(mScannedFiles);
|
||||
// mPreprocessor->setIncludePaths(mIncludePaths);
|
||||
// mPreprocessor->setProjectIncludePaths(mProjectIncludePaths);
|
||||
mPreprocessor->setScanOptions(mParseGlobalHeaders, mParseLocalHeaders);
|
||||
mPreprocessor->preprocess(fileName, buffer);
|
||||
|
||||
QStringList preprocessResult = mPreprocessor.result();
|
||||
QStringList preprocessResult = mPreprocessor->result();
|
||||
//reduce memory usage
|
||||
mPreprocessor.clearResult();
|
||||
mPreprocessor->clearResult();
|
||||
#ifdef QT_DEBUG
|
||||
// stringsToFile(mPreprocessor.result(),"r:\\preprocess.txt");
|
||||
// mPreprocessor.dumpDefinesTo("r:\\defines.txt");
|
||||
// mPreprocessor.dumpIncludesListTo("r:\\includes.txt");
|
||||
// stringsToFile(mPreprocessor->result(),"r:\\preprocess.txt");
|
||||
// mPreprocessor->dumpDefinesTo("r:\\defines.txt");
|
||||
// mPreprocessor->dumpIncludesListTo("r:\\includes.txt");
|
||||
#endif
|
||||
|
||||
// Tokenize the preprocessed buffer file
|
||||
|
@ -3280,8 +3315,8 @@ void CppParser::internalParse(const QString &fileName)
|
|||
void CppParser::inheritClassStatement(const PStatement& derived, bool isStruct,
|
||||
const PStatement& base, StatementClassScope access)
|
||||
{
|
||||
PFileIncludes fileIncludes1=mPreprocessor.includesList().value(derived->fileName);
|
||||
PFileIncludes fileIncludes2=mPreprocessor.includesList().value(base->fileName);
|
||||
PFileIncludes fileIncludes1=mPreprocessor->includesList().value(derived->fileName);
|
||||
PFileIncludes fileIncludes2=mPreprocessor->includesList().value(base->fileName);
|
||||
if (fileIncludes1 && fileIncludes2) {
|
||||
//derived class depeneds on base class
|
||||
fileIncludes1->dependingFiles.insert(base->fileName);
|
||||
|
@ -4245,7 +4280,7 @@ void CppParser::internalInvalidateFile(const QString &fileName)
|
|||
}
|
||||
}
|
||||
// delete it from scannedfiles
|
||||
mPreprocessor.scannedFiles().remove(fileName);
|
||||
mPreprocessor->scannedFiles().remove(fileName);
|
||||
|
||||
// remove its include files list
|
||||
PFileIncludes p = findFileIncludes(fileName, true);
|
||||
|
@ -4291,7 +4326,7 @@ QSet<QString> CppParser::calculateFilesToBeReparsed(const QString &fileName)
|
|||
while (!queue.isEmpty()) {
|
||||
QString name = queue.dequeue();
|
||||
processed.insert(name);
|
||||
PFileIncludes p=mPreprocessor.includesList().value(name);
|
||||
PFileIncludes p=mPreprocessor->includesList().value(name);
|
||||
if (!p)
|
||||
continue;
|
||||
foreach (const QString& s,p->dependedFiles) {
|
||||
|
@ -4680,12 +4715,12 @@ void CppParser::setParseGlobalHeaders(bool newParseGlobalHeaders)
|
|||
|
||||
const QSet<QString> &CppParser::includePaths()
|
||||
{
|
||||
return mPreprocessor.includePaths();
|
||||
return mPreprocessor->includePaths();
|
||||
}
|
||||
|
||||
const QSet<QString> &CppParser::projectIncludePaths()
|
||||
{
|
||||
return mPreprocessor.projectIncludePaths();
|
||||
return mPreprocessor->projectIncludePaths();
|
||||
}
|
||||
|
||||
bool CppParser::parseLocalHeaders() const
|
||||
|
@ -4733,7 +4768,7 @@ void CppParser::setEnabled(bool newEnabled)
|
|||
if (mEnabled!=newEnabled) {
|
||||
mEnabled = newEnabled;
|
||||
if (!mEnabled) {
|
||||
this->reset();
|
||||
resetParser();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -97,10 +97,11 @@ public:
|
|||
QSet<QString> getFileIncludes(const QString& filename);
|
||||
QSet<QString> getFileUsings(const QString& filename);
|
||||
|
||||
QString getHeaderFileName(const QString& relativeTo, const QString& line);// both
|
||||
QString getHeaderFileName(const QString& relativeTo, const QString& headerName, bool fromNext=false);// both
|
||||
|
||||
void invalidateFile(const QString& fileName);
|
||||
bool isIncludeLine(const QString &line);
|
||||
bool isIncludeNextLine(const QString &line);
|
||||
bool isProjectHeaderFile(const QString& fileName);
|
||||
bool isSystemHeaderFile(const QString& fileName);
|
||||
void parseFile(const QString& fileName, bool inProject,
|
||||
|
@ -108,7 +109,7 @@ public:
|
|||
void parseFileList(bool updateView = true);
|
||||
void parseHardDefines();
|
||||
bool parsing() const;
|
||||
void reset();
|
||||
void resetParser();
|
||||
void unFreeze(); // UnFree/UnLock (reparse while searching)
|
||||
QSet<QString> scannedFiles();
|
||||
|
||||
|
@ -534,7 +535,7 @@ private:
|
|||
//It's used in preprocessor, so we can't use fIncludeList instead
|
||||
|
||||
CppTokenizer mTokenizer;
|
||||
CppPreprocessor mPreprocessor;
|
||||
PCppPreprocessor mPreprocessor;
|
||||
//{ List of current project's file }
|
||||
QSet<QString> mProjectFiles;
|
||||
QVector<int> mBlockBeginSkips; //list of for/catch block begin token index;
|
||||
|
|
|
@ -334,6 +334,16 @@ void CppPreprocessor::clearProjectIncludePaths()
|
|||
mProjectIncludePathList.clear();
|
||||
}
|
||||
|
||||
void CppPreprocessor::clearScannedFiles()
|
||||
{
|
||||
mScannedFiles.clear();
|
||||
}
|
||||
|
||||
void CppPreprocessor::clearIncludeList()
|
||||
{
|
||||
mIncludesList.clear();
|
||||
}
|
||||
|
||||
QString CppPreprocessor::getNextPreprocessor()
|
||||
{
|
||||
skipToPreprocessor(); // skip until # at start of line
|
||||
|
@ -457,27 +467,28 @@ void CppPreprocessor::handleInclude(const QString &line, bool fromNext)
|
|||
QStringList includes;
|
||||
QStringList projectIncludes;
|
||||
bool found;
|
||||
if (fromNext && mIncludePaths.contains(currentDir))
|
||||
found = false;
|
||||
else
|
||||
found = true;
|
||||
if (fromNext && mIncludePaths.contains(currentDir)) {
|
||||
foreach(const QString& s, mIncludePathList) {
|
||||
if (found) {
|
||||
includes.append(s);
|
||||
}
|
||||
if (s == currentDir)
|
||||
continue;
|
||||
} else if (s == currentDir)
|
||||
found = true;
|
||||
}
|
||||
if (fromNext && mProjectIncludePaths.contains(currentDir))
|
||||
found = false;
|
||||
else
|
||||
found = true;
|
||||
projectIncludes = mProjectIncludePathList;
|
||||
} else if (fromNext && mProjectIncludePaths.contains(currentDir)) {
|
||||
includes = mIncludePathList;
|
||||
foreach(const QString& s, mProjectIncludePathList) {
|
||||
if (found)
|
||||
projectIncludes.append(s);
|
||||
if (s == currentDir)
|
||||
if (found) {
|
||||
includes.append(s);
|
||||
continue;
|
||||
} else if (s == currentDir)
|
||||
found = true;
|
||||
}
|
||||
} else {
|
||||
includes = mIncludePathList;
|
||||
projectIncludes = mProjectIncludePathList;
|
||||
}
|
||||
fileName = getHeaderFilename(
|
||||
file->fileName,
|
||||
line,
|
||||
|
|
|
@ -75,6 +75,8 @@ public:
|
|||
void addProjectIncludePath(const QString& fileName);
|
||||
void clearIncludePaths();
|
||||
void clearProjectIncludePaths();
|
||||
void clearScannedFiles();
|
||||
void clearIncludeList();
|
||||
QStringList result() const;
|
||||
|
||||
QHash<QString, PFileIncludes> &includesList();
|
||||
|
@ -217,4 +219,6 @@ private:
|
|||
QSet<QString> mScannedFiles;
|
||||
};
|
||||
|
||||
using PCppPreprocessor = std::shared_ptr<CppPreprocessor>;
|
||||
|
||||
#endif // CPPPREPROCESSOR_H
|
||||
|
|
|
@ -29,6 +29,7 @@ void CppTokenizer::reset()
|
|||
mTokenList.clear();
|
||||
mBuffer.clear();
|
||||
mBufferStr.clear();
|
||||
mLastToken.clear();
|
||||
}
|
||||
|
||||
void CppTokenizer::tokenize(const QStringList &buffer)
|
||||
|
|
|
@ -94,4 +94,6 @@ private:
|
|||
TokenList mTokenList;
|
||||
};
|
||||
|
||||
using PCppTokenizer = std::shared_ptr<CppTokenizer>;
|
||||
|
||||
#endif // CPPTOKENIZER_H
|
||||
|
|
|
@ -79,6 +79,9 @@ const StatementMap &StatementModel::childrenStatements(std::weak_ptr<Statement>
|
|||
void StatementModel::clear() {
|
||||
mCount=0;
|
||||
mGlobalStatements.clear();
|
||||
#ifdef QT_DEBUG
|
||||
mAllStatements.clear();
|
||||
#endif
|
||||
}
|
||||
|
||||
void StatementModel::dump(const QString &logFile)
|
||||
|
|
|
@ -110,7 +110,7 @@
|
|||
<item>
|
||||
<widget class="QTabWidget" name="settingTabs">
|
||||
<property name="currentIndex">
|
||||
<number>4</number>
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="movable">
|
||||
<bool>false</bool>
|
||||
|
|
|
@ -280,7 +280,7 @@ void resetCppParser(std::shared_ptr<CppParser> parser, int compilerSetIndex)
|
|||
if (!parser)
|
||||
return;
|
||||
// Configure parser
|
||||
parser->reset();
|
||||
parser->resetParser();
|
||||
//paser->enabled = pSettings-> devCodeCompletion.Enabled;
|
||||
// CppParser.ParseLocalHeaders := devCodeCompletion.ParseLocalHeaders;
|
||||
// CppParser.ParseGlobalHeaders := devCodeCompletion.ParseGlobalHeaders;
|
||||
|
@ -288,22 +288,26 @@ void resetCppParser(std::shared_ptr<CppParser> parser, int compilerSetIndex)
|
|||
parser->setParseGlobalHeaders(true);
|
||||
parser->setParseLocalHeaders(true);
|
||||
// Set options depending on the current compiler set
|
||||
// TODO: do this every time OnCompilerSetChanged
|
||||
if (compilerSetIndex<0) {
|
||||
compilerSetIndex=pSettings->compilerSets().defaultIndex();
|
||||
}
|
||||
Settings::PCompilerSet compilerSet = pSettings->compilerSets().getSet(compilerSetIndex);
|
||||
parser->clearIncludePaths();
|
||||
bool isCpp = parser->language()==ParserLanguage::CPlusPlus;
|
||||
if (compilerSet) {
|
||||
if (isCpp) {
|
||||
foreach (const QString& file,compilerSet->CppIncludeDirs()) {
|
||||
parser->addIncludePath(file);
|
||||
}
|
||||
}
|
||||
foreach (const QString& file,compilerSet->CIncludeDirs()) {
|
||||
parser->addIncludePath(file);
|
||||
}
|
||||
if (isCpp) {
|
||||
foreach (const QString& file,compilerSet->defaultCppIncludeDirs()) {
|
||||
parser->addIncludePath(file);
|
||||
}
|
||||
}
|
||||
foreach (const QString& file,compilerSet->defaultCIncludeDirs()) {
|
||||
parser->addIncludePath(file);
|
||||
}
|
||||
|
|
|
@ -133,7 +133,7 @@ DWORD ExecuteCommand(string& command,bool reInp) {
|
|||
}
|
||||
WINBOOL bSuccess = AssignProcessToJobObject( hJob, pi.hProcess );
|
||||
if ( bSuccess == FALSE ) {
|
||||
printf( "AssignProcessToJobObject failed: error %d\n", GetLastError() );
|
||||
printf( "AssignProcessToJobObject failed: error %u\n", GetLastError() );
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue