- fix: Parser: invalidating file may break class inheritance infos.

This commit is contained in:
Roy Qu 2024-02-27 18:08:38 +08:00
parent 255e09de89
commit 1728e953bf
4 changed files with 72 additions and 13 deletions

View File

@ -11,6 +11,7 @@ Red Panda C++ Version 2.27
- enhancement: Don't force fixed-width when using non fixed-width fonts.
- change: Replace non-ascii font with fallback font.
- enhancement: Display ascii control chars.
- fix: Parser: invalidating file may break class inheritance infos.
Red Panda C++ Version 2.26
- enhancement: Code suggestion for embedded std::vectors.

View File

@ -1107,10 +1107,9 @@ void CppParser::resetParser()
mFilesToScan.clear(); // list of base files to scan
mNamespaces.clear(); // namespace and the statements in its scope
mInlineNamespaces.clear();
mClassInheritances.clear();
mPreprocessor.clear();
mTokenizer.clear();
}
}
@ -1436,8 +1435,6 @@ PStatement CppParser::addStatement(const PStatement& parent,
// if (result->command=="sync_with_stdio") {
// qDebug()<<result->fullName<<result->isStatic()<<(int)result->accessibility;
// }
return result;
}
@ -1605,13 +1602,17 @@ void CppParser::setInheritance(int index, const PStatement& classStatement, bool
}
}
// Find the corresponding PStatement
PStatement statement = doFindStatementOf(mCurrentFile,basename,
isGlobal?PStatement():classStatement->parentScope.lock());
PClassInheritanceInfo inheritanceInfo = std::make_shared<ClassInheritanceInfo>();
if (statement && statement->kind == StatementKind::skClass) {
inheritClassStatement(classStatement,isStruct,statement,lastInheritScopeType);
}
inheritanceInfo->derivedClass = classStatement;
inheritanceInfo->file = mCurrentFile;
inheritanceInfo->parentClassName = basename;
inheritanceInfo->isGlobal = isGlobal;
inheritanceInfo->isStruct = isStruct;
inheritanceInfo->visibility = lastInheritScopeType;
inheritanceInfo->handled = false;
mClassInheritances.append(inheritanceInfo);
}
}
@ -4372,6 +4373,39 @@ void CppParser::handleVar(const QString& typePrefix,bool isExtern,bool isStatic)
mIndex++;
}
void CppParser::handleInheritances()
{
for (int i=mClassInheritances.length()-1;i>=0;i--) {
PClassInheritanceInfo inheritanceInfo = mClassInheritances[i];
PStatement derivedStatement = inheritanceInfo->derivedClass.lock();
if (!derivedStatement) {
//the derived class is invalid, remove it
if (i<mClassInheritances.length()-1) {
mClassInheritances[i]=mClassInheritances.back();
} else {
mClassInheritances.pop_back();
}
continue;
}
if (inheritanceInfo->handled)
continue;
PStatement statement = doFindStatementOf(
inheritanceInfo->file,
inheritanceInfo->parentClassName,
inheritanceInfo->isGlobal?PStatement():derivedStatement->parentScope.lock());
if (statement && statement->kind == StatementKind::skClass) {
inheritClassStatement(derivedStatement,
inheritanceInfo->isStruct,
statement,
inheritanceInfo->visibility);
inheritanceInfo->parentClassFilename = statement->fileName;
inheritanceInfo->handled = true;
}
}
//mClassInheritances.clear();
}
void CppParser::skipRequires()
{
mIndex++; //skip 'requires';
@ -4459,10 +4493,12 @@ void CppParser::internalParse(const QString &fileName)
if (!handleStatement())
break;
}
handleInheritances();
// qDebug()<<"parse"<<timer.elapsed();
#ifdef QT_DEBUG
// mStatementList.dumpAll(QString("r:\\all-stats-%1.txt").arg(extractFileName(fileName)));
// mStatementList.dump(QString("r:\\stats-%1.txt").arg(extractFileName(fileName)));
mStatementList.dumpAll(QString("r:\\all-stats-%1.txt").arg(extractFileName(fileName)));
mStatementList.dump(QString("r:\\stats-%1.txt").arg(extractFileName(fileName)));
#endif
//reduce memory usage
internalClear();
@ -4483,6 +4519,8 @@ void CppParser::inheritClassStatement(const PStatement& derived, bool isStruct,
|| statement->kind == StatementKind::skConstructor
|| statement->kind == StatementKind::skDestructor)
continue;
if (derived->children.contains(statement->command))
continue;
StatementAccessibility m_acc;
switch(access) {
case StatementAccessibility::Public:
@ -5960,7 +5998,12 @@ void CppParser::internalInvalidateFile(const QString &fileName)
mNamespaces.remove(key);
}
}
// class inheritance
// invalid class inheritance infos (derived class is not valid) whould be auto removed in handleInheritances()
foreach (const PClassInheritanceInfo& info, mClassInheritances) {
if (info->handled && info->parentClassFilename == fileName)
info->handled = false;
}
// delete it from scannedfiles
mPreprocessor.removeScannedFile(fileName);
}

View File

@ -516,6 +516,7 @@ private:
void handleStructs(bool isTypedef = false);
void handleUsing();
void handleVar(const QString& typePrefix,bool isExtern,bool isStatic);
void handleInheritances();
void skipRequires();
void internalParse(const QString& fileName);
// function FindMacroDefine(const Command: AnsiString): PStatement;
@ -718,6 +719,7 @@ private:
int mLockCount; // lock(don't reparse) when we need to find statements in a batch
bool mParsing;
QHash<QString,PStatementList> mNamespaces; // namespace and the statements in its scope
QList<PClassInheritanceInfo> mClassInheritances;
QSet<QString> mInlineNamespaces;
#ifdef QT_DEBUG
int mLastIndex;

View File

@ -53,4 +53,17 @@ private:
#endif
};
struct ClassInheritanceInfo {
std::weak_ptr<Statement> derivedClass;
QString file;
QString parentClassName;
bool isGlobal;
bool isStruct;
StatementAccessibility visibility;
QString parentClassFilename;
bool handled;
};
using PClassInheritanceInfo = std::shared_ptr<ClassInheritanceInfo>;
#endif // STATEMENTMODEL_H