- 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:
Roy Qu 2022-10-18 12:24:59 +08:00
parent 3509c25fc8
commit a62910e1a3
16 changed files with 241 additions and 147 deletions

View File

@ -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

View File

@ -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);
isIncludeLine = mParser->isIncludeLine(s);
if (!isIncludeLine)
isIncludeNextLine = mParser->isIncludeNextLine(s);
if (!isIncludeNextLine)
isIncludeLine = mParser->isIncludeLine(s);
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();

View File

@ -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);

View File

@ -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();
}
}
@ -2254,7 +2254,7 @@ void MainWindow::scanActiveProject(bool parse)
//UpdateClassBrowsing;
if (parse) {
resetCppParser(mProject->cppParser(),mProject->options().compilerSet);
resetCppParser(mProject->cppParser(), mProject->options().compilerSet);
mProject->resetParserProjectFiles();
parseFileList(mProject->cppParser());
} else {
@ -4815,26 +4815,28 @@ void MainWindow::onCompilerSetChanged(int index)
{
if (index<0)
return;
if (mProject) {
Editor *e = mEditorList->getEditor();
if (!e || e->inProject()) {
if(QMessageBox::warning(
e,
tr("Change Project Compiler Set"),
tr("Change the project's compiler set will lose all custom compiler set options.")
+"<br />"
+ tr("Do you really want to do that?"),
QMessageBox::Yes | QMessageBox::No,
QMessageBox::No) != QMessageBox::Yes) {
return;
}
mProject->setCompilerSet(index);
mProject->saveOptions();
Editor *e = mEditorList->getEditor();
if (mProject && (!e || e->inProject())) {
if(QMessageBox::warning(
e,
tr("Change Project Compiler Set"),
tr("Change the project's compiler set will lose all custom compiler set options.")
+"<br />"
+ tr("Do you really want to do that?"),
QMessageBox::Yes | QMessageBox::No,
QMessageBox::No) != QMessageBox::Yes) {
return;
}
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();
}

View File

@ -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);

View File

@ -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();
}
}
}

View File

@ -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;

View File

@ -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,26 +467,27 @@ void CppPreprocessor::handleInclude(const QString &line, bool fromNext)
QStringList includes;
QStringList projectIncludes;
bool found;
if (fromNext && mIncludePaths.contains(currentDir))
found = false;
else
found = true;
foreach(const QString& s, mIncludePathList) {
if (found) {
includes.append(s);
if (fromNext && mIncludePaths.contains(currentDir)) {
foreach(const QString& s, mIncludePathList) {
if (found) {
includes.append(s);
continue;
} else if (s == currentDir)
found = true;
}
if (s == currentDir)
found = true;
}
if (fromNext && mProjectIncludePaths.contains(currentDir))
found = false;
else
found = true;
foreach(const QString& s, mProjectIncludePathList) {
if (found)
projectIncludes.append(s);
if (s == currentDir)
found = true;
projectIncludes = mProjectIncludePathList;
} else if (fromNext && mProjectIncludePaths.contains(currentDir)) {
includes = mIncludePathList;
foreach(const QString& s, mProjectIncludePathList) {
if (found) {
includes.append(s);
continue;
} else if (s == currentDir)
found = true;
}
} else {
includes = mIncludePathList;
projectIncludes = mProjectIncludePathList;
}
fileName = getHeaderFilename(
file->fileName,

View File

@ -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

View File

@ -29,6 +29,7 @@ void CppTokenizer::reset()
mTokenList.clear();
mBuffer.clear();
mBufferStr.clear();
mLastToken.clear();
}
void CppTokenizer::tokenize(const QStringList &buffer)

View File

@ -94,4 +94,6 @@ private:
TokenList mTokenList;
};
using PCppTokenizer = std::shared_ptr<CppTokenizer>;
#endif // CPPTOKENIZER_H

View File

@ -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)

View File

@ -71,7 +71,7 @@ std::shared_ptr<Project> Project::load(const QString &filename, EditorList *edit
parent);
project->open();
project->mModified = false;
resetCppParser(project->mParser,project->mOptions.compilerSet);
resetCppParser(project->mParser, project->mOptions.compilerSet);
return project;
}
@ -94,7 +94,7 @@ std::shared_ptr<Project> Project::create(
project->mParser->setEnabled(false);
if (!project->assignTemplate(pTemplate,useCpp))
return std::shared_ptr<Project>();
resetCppParser(project->mParser,project->mOptions.compilerSet);
resetCppParser(project->mParser, project->mOptions.compilerSet);
project->mModified = true;
return project;

View File

@ -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>

View File

@ -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,21 +288,25 @@ 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) {
foreach (const QString& file,compilerSet->CppIncludeDirs()) {
parser->addIncludePath(file);
if (isCpp) {
foreach (const QString& file,compilerSet->CppIncludeDirs()) {
parser->addIncludePath(file);
}
}
foreach (const QString& file,compilerSet->CIncludeDirs()) {
parser->addIncludePath(file);
}
foreach (const QString& file,compilerSet->defaultCppIncludeDirs()) {
parser->addIncludePath(file);
if (isCpp) {
foreach (const QString& file,compilerSet->defaultCppIncludeDirs()) {
parser->addIncludePath(file);
}
}
foreach (const QString& file,compilerSet->defaultCIncludeDirs()) {
parser->addIncludePath(file);

View 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;
}