work save

This commit is contained in:
royqh1979@gmail.com 2021-08-22 05:50:26 +08:00
parent 7b59e6a9ea
commit da157eb218
4 changed files with 172 additions and 11 deletions

View File

@ -110,6 +110,89 @@ void CppParser::fillListOfFunctions(const QString &fileName, const QString &phra
fillListOfFunctions(fileName,line,statement,parentScope,list);
}
PStatement CppParser::findAndScanBlockAt(const QString &filename, int line)
{
QMutexLocker locker(&mMutex);
if (mParsing)
return PStatement();
PFileIncludes fileIncludes = findFileIncludes(filename);
if (!fileIncludes)
return PStatement();
PStatement statement = fileIncludes->scopes.findScopeAtLine(line);
return statement;
}
PFileIncludes CppParser::findFileIncludes(const QString &filename, bool deleteIt)
{
QMutexLocker locker(&mMutex);
PFileIncludes fileIncludes = mIncludesList->value(filename,PFileIncludes());
if (deleteIt && fileIncludes)
mIncludesList->remove(filename);
return fileIncludes;
}
QString CppParser::findFirstTemplateParamOf(const QString &fileName, const QString &phrase, PStatement currentScope)
{
QMutexLocker locker(&mMutex);
QString result = "";
if (mParsing)
return "";
// Remove pointer stuff from type
QString s = phrase; // 'Type' is a keyword
int i = s.indexOf('<');
if (i>=0) {
int t=getFirstTemplateParamEnd(s,i);
return s.mid(i+1,t-i-1);
}
int position = s.length()-1;
while ((position >= 0) && (s[position] == '*'
|| s[position] == ' '
|| s[position] == '&'))
position--;
if (position != s.length()-1)
s.truncate(position+1);
PStatement scopeStatement = currentScope;
PStatement statement = findStatementOf(fileName,s,currentScope);
return getFirstTemplateParam(statement,fileName, phrase, currentScope);
}
QString CppParser::getFirstTemplateParam(PStatement statement, const QString& filename, const QString& phrase, PStatement currentScope)
{
if (!statement)
return "";
if (statement->kind != StatementKind::skTypedef)
return "";
if (statement->type == phrase) // prevent infinite loop
return "";
return findFirstTemplateParamOf(filename,statement->type, currentScope);
}
int CppParser::getFirstTemplateParamEnd(const QString &s, int startAt)
{
int i = startAt;
int level = 0; // assume we start on top of '<'
while (i < s.length()) {
switch (s[i].unicode()) {
case '<':
level++;
break;
case ',':
if (level == 1)
return i;
case '>':
level--;
if (level==0)
return i;
}
i++;
}
return startAt;
}
void CppParser::addFileToScan(QString value, bool inProject)
{
QMutexLocker locker(&mMutex);
@ -334,7 +417,7 @@ void CppParser::addSoloScopeLevel(PStatement statement, int line)
PFileIncludes fileIncludes = findFileIncludes(mCurrentFile);
if (fileIncludes) {
fileIncludes->scopes.insert(line,statement);
fileIncludes->scopes.addScope(line,statement);
}
// Set new scope
@ -359,8 +442,8 @@ void CppParser::removeScopeLevel(int line)
if (currentScope && (currentScope->kind == StatementKind::skBlock)) {
if (currentScope->children.isEmpty()) {
// remove no children block
if (fileIncludes && !fileIncludes->scopes.isEmpty()) {
fileIncludes->scopes.remove(currentScope->line);
if (fileIncludes) {
fileIncludes->scopes.removeLastScope();
}
mStatementList.deleteStatement(currentScope);
} else {
@ -374,9 +457,8 @@ void CppParser::removeScopeLevel(int line)
// Set new scope
currentScope = getCurrentScope();
// fileIncludes:=FindFileIncludes(fCurrentFile);
if (fileIncludes && !fileIncludes->scopes.isEmpty()
&& fileIncludes->scopes.value(fileIncludes->scopes.keys().back())!=currentScope) {
fileIncludes->scopes.insert(line,currentScope);
if (fileIncludes && fileIncludes->scopes.lastScope()!=currentScope) {
fileIncludes->scopes.addScope(line,currentScope);
}
if (!currentScope) {

View File

@ -24,7 +24,6 @@ public:
void clearProjectIncludePaths();
void clearProjectFiles();
void parseHardDefines();
PFileIncludes findFileIncludes(const QString &filename, bool deleteIt = false);
void invalidateFile(const QString& fileName);
QStringList getFileDirectIncludes(const QString& filename) const;
const QList<QString>& getFileIncludes(const QString& filename) const;
@ -57,6 +56,11 @@ public:
int line,
QStringList& list);
PStatement findAndScanBlockAt(const QString& filename, int line);
PFileIncludes findFileIncludes(const QString &filename, bool deleteIt = false);
QString findFirstTemplateParamOf(const QString& fileName,
const QString& phrase,
PStatement currentScope);
PStatement findStatementOf(const QString& fileName,
const QString& phrase,
int line);
@ -84,9 +88,6 @@ public:
PStatement findTypeDefinitionOf(const QString& fileName,
const QString& phrase,
PStatement currentClass);
QString FindFirstTemplateParamOf(const QString& fileName,
const QString& phrase,
PStatement currentClass);
int findLastOperator(const QString& phrase) const;
PStatementList findNamespace(const QString& name); // return a list of PSTATEMENTS (of the namespace)
bool freeze(); // Freeze/Lock (stop reparse while searching)
@ -182,6 +183,9 @@ private:
int getCurrentBlockEndSkip();
int getCurrentInlineNamespaceEndSkip();
PStatement getCurrentScope(); // gets last item from last level
QString getFirstTemplateParam(PStatement statement, const QString& filename,
const QString& phrase, PStatement currentScope);
int getFirstTemplateParamEnd(const QString& s, int startAt);
void getFullNameSpace(
const QString& phrase,
QString& sNamespace,

View File

@ -3,6 +3,7 @@
#include <QDir>
#include <QFile>
#include <QFileInfo>
#include <QDebug>
QStringList CppDirectives;
QStringList JavadocTags;
@ -369,3 +370,59 @@ bool isCfile(const QString filename)
QFileInfo fileInfo(filename);
return CppSourceExts.contains(fileInfo.suffix().toLower());
}
PStatement CppScopes::findScopeAtLine(int line)
{
if (mScopes.isEmpty())
return PStatement();
int start = 0;
int end = mScopes.size()-1;
while (start<=end) {
int mid = (start+end)/2;
PCppScope midScope = mScopes[mid];
if (midScope->startLine == line) {
while (mid-1>=0 && (mScopes[mid-1]->startLine == line)) {
mid--;
}
return mScopes[mid]->statement;
} else if (midScope->startLine > line) {
end = mid-1;
} else {
start = mid+1;
}
}
if (start<mScopes.size())
return mScopes[start]->statement;
else
return mScopes.back()->statement;
}
void CppScopes::addScope(int line, PStatement scopeStatement)
{
PCppScope scope = std::make_shared<CppScope>();
scope->startLine = line;
scope->statement = scopeStatement;
mScopes.append(scope);
if (!mScopes.isEmpty() && mScopes.back()->startLine>line) {
qDebug()<<QString("Error: new scope %1 at %2 which is less that last scope %3")
.arg(scopeStatement->fullName, line,mScopes.back()->startLine>line);
}
}
PStatement CppScopes::lastScope()
{
if (mScopes.isEmpty())
return PStatement();
return mScopes.back()->statement;
}
void CppScopes::removeLastScope()
{
if (!mScopes.isEmpty())
mScopes.pop_back();
}
void CppScopes::clear()
{
mScopes.clear();
}

View File

@ -139,13 +139,31 @@ struct IncompleteClass {
};
using PIncompleteClass = std::shared_ptr<IncompleteClass>;
struct CppScope {
int startLine;
PStatement statement;
};
using PCppScope = std::shared_ptr<CppScope>;
class CppScopes {
public:
PStatement findScopeAtLine(int line);
void addScope(int line, PStatement scopeStatement);
PStatement lastScope();
void removeLastScope();
void clear();
private:
QVector<PCppScope> mScopes;
};
struct FileIncludes {
QString baseFile;
QMap<QString,bool> includeFiles; // true means the file is directly included, false means included indirectly
QSet<QString> usings; // namespaces it usings
StatementMap statements; // but we don't save temporary statements (full name as key)
StatementMap declaredStatements; // statements declared in this file (full name as key)
QMap<int, PStatement> scopes; // int is start line of the statement scope
CppScopes scopes; // int is start line of the statement scope
QSet<QString> dependingFiles; // The files I depeneds on
QSet<QString> dependedFiles; // the files depends on me
};