RedPanda-CPP/RedPandaIDE/parser/cppparser.h

424 lines
16 KiB
C
Raw Normal View History

2021-08-14 22:52:37 +08:00
#ifndef CPPPARSER_H
#define CPPPARSER_H
2021-08-15 04:31:57 +08:00
#include <QMutex>
2021-08-14 22:52:37 +08:00
#include <QObject>
2021-08-23 10:16:06 +08:00
#include <QThread>
2021-08-14 22:52:37 +08:00
#include "statementmodel.h"
#include "cpptokenizer.h"
#include "cpppreprocessor.h"
class CppParser : public QObject
{
Q_OBJECT
2021-08-15 04:31:57 +08:00
using GetFileStreamCallBack = std::function<bool (const QString&, QStringList&)>;
2021-08-14 22:52:37 +08:00
public:
explicit CppParser(QObject *parent = nullptr);
2021-08-20 01:06:10 +08:00
~CppParser();
2021-08-14 22:52:37 +08:00
2021-08-20 01:06:10 +08:00
void addHardDefineByLine(const QString& line);
2021-08-29 00:48:23 +08:00
void addFileToScan(const QString& value, bool inProject = false);
2021-08-20 01:06:10 +08:00
void addIncludePath(const QString& value);
void addProjectIncludePath(const QString& value);
void clearIncludePaths();
void clearProjectIncludePaths();
void clearProjectFiles();
2021-08-22 16:08:46 +08:00
void fillListOfFunctions(const QString& fileName,
const QString& phrase,
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,
2021-08-29 00:48:23 +08:00
const PStatement& currentScope);
2021-08-22 16:08:46 +08:00
PStatement findFunctionAt(const QString& fileName,
int line);
int findLastOperator(const QString& phrase) const;
PStatementList findNamespace(const QString& name); // return a list of PSTATEMENTS (of the namespace)
PStatement findStatementOf(const QString& fileName,
const QString& phrase,
int line);
PStatement findStatementOf(const QString& fileName,
const QString& phrase,
2021-08-29 00:48:23 +08:00
const PStatement& currentScope,
2021-08-25 00:20:07 +08:00
PStatement& parentScopeType,
2021-08-22 16:08:46 +08:00
bool force = false);
PStatement findStatementOf(const QString& fileName,
const QString& phrase,
2021-08-29 00:48:23 +08:00
const PStatement& currentClass,
2021-08-22 16:08:46 +08:00
bool force = false);
2021-08-22 21:23:58 +08:00
//{Find statement starting from startScope}
PStatement findStatementStartingFrom(const QString& fileName,
const QString& phrase,
2021-08-29 00:48:23 +08:00
const PStatement& startScope,
2021-08-22 21:23:58 +08:00
bool force = false);
PStatement findTypeDefinitionOf(const QString& fileName,
const QString& aType,
2021-08-29 00:48:23 +08:00
const PStatement& currentClass);
2021-08-22 21:23:58 +08:00
bool freeze(); // Freeze/Lock (stop reparse while searching)
bool freeze(const QString& serialId); // Freeze/Lock (stop reparse while searching)
QStringList getClassesList();
QSet<QString> getFileDirectIncludes(const QString& filename);
QSet<QString> getFileIncludes(const QString& filename);
QSet<QString> getFileUsings(const QString& filename);
2021-08-22 16:08:46 +08:00
2021-08-22 21:23:58 +08:00
QString getHeaderFileName(const QString& relativeTo, const QString& line);// both
2021-08-29 00:48:23 +08:00
StatementKind getKindOfStatement(const PStatement& statement);
2021-08-15 16:49:37 +08:00
void invalidateFile(const QString& fileName);
2021-08-22 23:48:00 +08:00
bool isIncludeLine(const QString &line);
2021-08-15 16:49:37 +08:00
bool isProjectHeaderFile(const QString& fileName);
2021-08-22 21:23:58 +08:00
bool isSystemHeaderFile(const QString& fileName);
void parseFile(const QString& fileName, bool inProject,
bool onlyIfNotParsed = false, bool updateView = true);
void parseFileList(bool updateView = true);
void parseHardDefines();
2021-08-22 23:48:00 +08:00
bool parsing() const;
void reset();
void unFreeze(); // UnFree/UnLock (reparse while searching)
2021-08-22 21:23:58 +08:00
2021-08-29 00:48:23 +08:00
2021-08-22 23:48:00 +08:00
//void getSourcePair(const QString& fName, QString& CFile, QString& HFile);
// int suggestMemberInsertionLine(PStatement parentStatement,
// StatementClassScope Scope,
// bool addScopeStr);
2021-08-15 16:49:37 +08:00
// {
// function GetSystemHeaderFileName(const FileName: AnsiString): AnsiString; // <file.h>
// function GetProjectHeaderFileName(const FileName: AnsiString): AnsiString; // <file.h>
// function GetLocalHeaderFileName(const RelativeTo, FileName: AnsiString): AnsiString; // "file.h"
// }
2021-08-22 23:48:00 +08:00
//QString statementKindStr(StatementKind value);
//QString statementClassScopeStr(StatementClassScope value);
2021-08-20 01:06:10 +08:00
2021-08-29 17:23:40 +08:00
QString prettyPrintStatement(const PStatement& statement, const QString& filename, int line = -1);
2021-08-22 05:50:26 +08:00
2021-08-22 16:08:46 +08:00
2021-08-15 04:31:57 +08:00
2021-08-22 21:23:58 +08:00
// StatementKind findKindOfStatementOf(const QString& fileName,
// const QString& phrase,
// int line);
2021-08-22 23:48:00 +08:00
// QString getHintFromStatement(const QString& fileName,
// const QString& phrase,
// int line);
2021-08-21 22:15:44 +08:00
bool enabled() const;
void setEnabled(bool newEnabled);
const QSet<QString> &filesToScan() const;
void setFilesToScan(const QSet<QString> &newFilesToScan);
2021-08-22 21:23:58 +08:00
void setOnGetFileStream(const GetFileStreamCallBack &newOnGetFileStream);
2021-08-22 23:48:00 +08:00
int parserId() const;
2021-08-23 03:47:28 +08:00
const QString &serialId() const;
2021-08-23 10:16:06 +08:00
bool parseLocalHeaders() const;
void setParseLocalHeaders(bool newParseLocalHeaders);
bool parseGlobalHeaders() const;
void setParseGlobalHeaders(bool newParseGlobalHeaders);
2021-08-29 00:48:23 +08:00
const QSet<QString>& includePaths();
const QSet<QString>& projectIncludePaths();
2021-08-24 15:05:10 +08:00
const StatementModel &statementList() const;
2021-08-14 22:52:37 +08:00
signals:
2021-08-19 23:49:23 +08:00
void onProgress(const QString& fileName, int total, int current);
void onBusy();
void onStartParsing();
void onEndParsing(int total, int updateView);
2021-08-15 04:31:57 +08:00
private:
PStatement addInheritedStatement(
2021-08-29 00:48:23 +08:00
const PStatement& derived,
const PStatement& inherit,
2021-08-15 04:31:57 +08:00
StatementClassScope access);
PStatement addChildStatement(
// support for multiple parents (only typedef struct/union use multiple parents)
2021-08-29 00:48:23 +08:00
const PStatement& parent,
2021-08-15 04:31:57 +08:00
const QString& fileName,
const QString& hintText,
const QString& aType, // "Type" is already in use
const QString& command,
const QString& args,
const QString& value,
int line,
StatementKind kind,
2021-08-29 00:48:23 +08:00
const StatementScope& scope,
const StatementClassScope& classScope,
2021-08-15 04:31:57 +08:00
bool isDefinition,
bool isStatic); // TODO: InheritanceList not supported
PStatement addStatement(
2021-08-29 00:48:23 +08:00
const PStatement& parent,
2021-08-15 04:31:57 +08:00
const QString &fileName,
const QString &hintText,
const QString &aType, // "Type" is already in use
const QString &command,
const QString &args,
const QString& value,
int line,
StatementKind kind,
2021-08-29 00:48:23 +08:00
const StatementScope& scope,
const StatementClassScope& classScope,
2021-08-15 04:31:57 +08:00
bool isDefinition,
bool isStatic);
2021-08-29 00:48:23 +08:00
void setInheritance(int index, const PStatement& classStatement, bool isStruct);
2021-08-19 23:49:23 +08:00
bool isCurrentScope(const QString& command);
2021-08-29 00:48:23 +08:00
void addSoloScopeLevel(PStatement& statement, int line); // adds new solo level
2021-08-15 04:31:57 +08:00
void removeScopeLevel(int line); // removes level
int skipBraces(int startAt);
int skipBracket(int startAt);
2021-08-15 16:49:37 +08:00
bool checkForCatchBlock();
bool checkForEnum();
bool checkForForBlock();
2021-08-15 04:31:57 +08:00
bool checkForKeyword();
2021-08-15 16:49:37 +08:00
bool checkForMethod(QString &sType, QString &sName, QString &sArgs,
bool &isStatic, bool &isFriend); // caching of results
2021-08-15 04:31:57 +08:00
bool checkForNamespace();
2021-08-15 16:49:37 +08:00
bool checkForPreprocessor();
bool checkForScope();
2021-08-15 20:25:54 +08:00
void checkForSkipStatement();
2021-08-19 12:01:01 +08:00
bool checkForStructs();
2021-08-15 04:31:57 +08:00
bool checkForTypedef();
bool checkForTypedefEnum();
bool checkForTypedefStruct();
2021-08-15 17:52:39 +08:00
bool checkForUsing();
2021-08-15 04:31:57 +08:00
bool checkForVar();
2021-08-16 00:47:35 +08:00
QString expandMacroType(const QString& name);
//{procedure ResetDefines;}
2021-08-29 00:48:23 +08:00
void fillListOfFunctions(const QString& fileName, int line,
const PStatement& statement,
const PStatement& scopeStatement, QStringList& list);
2021-08-16 00:47:35 +08:00
PStatement findMemberOfStatement(
const QString& phrase,
2021-08-29 00:48:23 +08:00
const PStatement& scopeStatement);
2021-08-16 00:47:35 +08:00
PStatement findStatementInScope(
const QString& name,
const QString& noNameArgs,
StatementKind kind,
2021-08-29 00:48:23 +08:00
const PStatement& scope);
2021-08-22 21:23:58 +08:00
PStatement findStatementInScope(
const QString& name,
2021-08-29 00:48:23 +08:00
const PStatement& scope);
2021-08-22 21:23:58 +08:00
PStatement findStatementInNamespace(
const QString& name,
const QString& namespaceName);
int getBracketEnd(const QString& s, int startAt);
2021-08-19 23:49:23 +08:00
StatementClassScope getClassScope(int index);
2021-08-15 04:31:57 +08:00
int getCurrentBlockBeginSkip();
2021-08-16 00:47:35 +08:00
int getCurrentBlockEndSkip();
2021-08-15 04:31:57 +08:00
int getCurrentInlineNamespaceEndSkip();
2021-08-16 00:47:35 +08:00
PStatement getCurrentScope(); // gets last item from last level
2021-08-29 00:48:23 +08:00
QString getFirstTemplateParam(const PStatement& statement, const QString& filename,
const QString& phrase, const PStatement& currentScope);
2021-08-22 05:50:26 +08:00
int getFirstTemplateParamEnd(const QString& s, int startAt);
2021-08-22 21:23:58 +08:00
2021-08-22 16:08:46 +08:00
void getFullNamespace(
2021-08-16 00:47:35 +08:00
const QString& phrase,
QString& sNamespace,
QString& member);
2021-08-17 23:30:14 +08:00
QString getFullStatementName(
const QString& command,
2021-08-29 00:48:23 +08:00
const PStatement& parent);
2021-08-16 00:47:35 +08:00
PStatement getIncompleteClass(
const QString& command,
2021-08-29 00:48:23 +08:00
const PStatement& parentScope);
2021-08-29 22:08:43 +08:00
QString getScopePrefix(const PStatement& statement);
2021-08-16 00:47:35 +08:00
StatementScope getScope();
2021-08-17 23:30:14 +08:00
QString getStatementKey(const QString& sName,
const QString& sType,
const QString& sNoNameArgs);
2021-08-29 00:48:23 +08:00
PStatement getTypeDef(const PStatement& statement,
const QString& fileName, const QString& aType);
2021-08-17 23:30:14 +08:00
void handleCatchBlock();
void handleEnum();
void handleForBlock();
2021-08-18 17:02:57 +08:00
void handleKeyword();
2021-08-19 12:01:01 +08:00
void handleMethod(
2021-08-15 04:31:57 +08:00
const QString& sType,
const QString& sName,
const QString& sArgs,
bool isStatic,
bool isFriend);
void handleNamespace();
2021-08-17 23:30:14 +08:00
void handleOtherTypedefs();
void handlePreprocessor();
void handleScope();
2021-08-15 04:31:57 +08:00
bool handleStatement();
2021-08-17 23:30:14 +08:00
void handleStructs(bool isTypedef = false);
void handleUsing();
void handleVar();
2021-08-19 23:49:23 +08:00
void internalParse(const QString& fileName);
2021-08-15 04:31:57 +08:00
// function FindMacroDefine(const Command: AnsiString): PStatement;
void inheritClassStatement(
2021-08-29 00:48:23 +08:00
const PStatement& derived,
2021-08-15 04:31:57 +08:00
bool isStruct,
2021-08-29 00:48:23 +08:00
const PStatement& base,
2021-08-15 04:31:57 +08:00
StatementClassScope access);
2021-08-16 00:47:35 +08:00
PStatement doFindStatementInScope(const QString& name,
const QString& noNameArgs,
StatementKind kind,
2021-08-29 00:48:23 +08:00
const PStatement& scope);
2021-08-15 04:31:57 +08:00
void internalInvalidateFile(const QString& fileName);
2021-08-22 21:23:58 +08:00
void internalInvalidateFiles(const QSet<QString>& files);
QSet<QString> calculateFilesToBeReparsed(const QString& fileName);
2021-08-16 00:47:35 +08:00
int calcKeyLenForStruct(const QString& word);
2021-08-15 04:31:57 +08:00
// {
// function GetClass(const Phrase: AnsiString): AnsiString;
// function GetMember(const Phrase: AnsiString): AnsiString;
// function GetOperator(const Phrase: AnsiString): AnsiString;
// function GetRemainder(const Phrase: AnsiString): AnsiString;
// }
2021-08-17 23:30:14 +08:00
void scanMethodArgs(
2021-08-29 00:48:23 +08:00
const PStatement& functionStatement,
2021-08-17 23:30:14 +08:00
const QString& argStr);
2021-08-15 04:31:57 +08:00
QString splitPhrase(const QString& phrase, QString& sClazz, QString &sMember,
QString& sOperator);
2021-08-15 16:49:37 +08:00
QString removeArgNames(const QString& args);
2021-08-15 17:52:39 +08:00
bool isSpaceChar(const QChar& ch);
2021-08-15 20:25:54 +08:00
bool isWordChar(const QChar& ch);
2021-08-15 17:52:39 +08:00
bool isLetterChar(const QChar& ch);
bool isDigitChar(const QChar& ch);
/*'(', ';', ':', '{', '}', '#' */
bool isSeperator(const QChar& ch);
2021-08-18 05:34:04 +08:00
/*';', '{', '}'*/
bool isblockChar(const QChar& ch);
2021-08-16 00:47:35 +08:00
/* '#', ',', ';', ':', '{', '}', '!', '/', '+', '-', '<', '>' */
bool isInvalidVarPrefixChar(const QChar& ch);
2021-08-18 17:02:57 +08:00
/*'{', '}' */
bool isBraceChar(const QChar& ch);
2021-08-15 20:25:54 +08:00
bool isLineChar(const QChar& ch);
bool isNotFuncArgs(const QString& args);
2021-08-17 23:30:14 +08:00
/**
* @brief Test if a statement is a class/struct/union/namespace/function
* @param kind
* @return
*/
bool isNamedScope(StatementKind kind);
/**
* @brief Test if a statement is a class/struct/union/enum/enum class/typedef
* @param kind
* @return
*/
bool isTypeStatement(StatementKind kind);
2021-08-15 04:31:57 +08:00
void updateSerialId();
2021-08-17 23:30:14 +08:00
2021-08-14 22:52:37 +08:00
private:
int mParserId;
int mSerialCount;
2021-08-19 23:49:23 +08:00
QString mSerialId;
2021-08-14 22:52:37 +08:00
int mUniqId;
bool mEnabled;
int mIndex;
bool mIsHeader;
bool mIsSystemHeader;
QString mCurrentFile;
// stack list , each element is a list of one/many scopes(like intypedef struct s1,s2;
// It's used for store scope nesting infos
QVector<PStatement> mCurrentScope;
QVector<StatementClassScope> mCurrentClassScope;
// the start index in tokens to skip to ; when parsing typedef struct we need to skip
// the names after the closing bracket because we have processed it
QVector<int> mSkipList; // TList<Integer>
StatementClassScope mClassScope;
StatementModel mStatementList;
//It's used in preprocessor, so we can't use fIncludeList instead
2021-08-22 21:23:58 +08:00
2021-08-14 22:52:37 +08:00
CppTokenizer mTokenizer;
CppPreprocessor mPreprocessor;
2021-08-21 22:15:44 +08:00
//{ List of current project's file }
2021-08-15 04:31:57 +08:00
QSet<QString> mProjectFiles;
QVector<int> mBlockBeginSkips; //list of for/catch block begin token index;
QVector<int> mBlockEndSkips; //list of for/catch block end token index;
QVector<int> mInlineNamespaceEndSkips; // list for inline namespace end token index;
2021-08-19 23:49:23 +08:00
QSet<QString> mFilesToScan; // list of base files to scan
2021-08-15 04:31:57 +08:00
int mFilesScannedCount; // count of files that have been scanned
int mFilesToScanCount; // count of files and files included in files that have to be scanned
bool mParseLocalHeaders;
bool mParseGlobalHeaders;
bool mIsProjectFile;
2021-08-14 22:52:37 +08:00
//fMacroDefines : TList;
2021-08-15 04:31:57 +08:00
int mLockCount; // lock(don't reparse) when we need to find statements in a batch
bool mParsing;
QHash<QString,PStatementList> mNamespaces; //TStringList<String,List<Statement>> namespace and the statements in its scope
2021-08-28 09:01:40 +08:00
QSet<QString> mInlineNamespaces;
2021-08-14 22:52:37 +08:00
//fRemovedStatements: THashedStringList; //THashedStringList<String,PRemovedStatements>
2021-08-15 04:31:57 +08:00
2021-08-19 23:49:23 +08:00
QRecursiveMutex mMutex;
2021-08-15 04:31:57 +08:00
GetFileStreamCallBack mOnGetFileStream;
2021-08-14 22:52:37 +08:00
};
2021-08-23 03:47:28 +08:00
using PCppParser = std::shared_ptr<CppParser>;
2021-08-23 10:16:06 +08:00
class CppFileParserThread : public QThread {
Q_OBJECT
public:
explicit CppFileParserThread(
PCppParser parser,
QString fileName,
bool inProject,
bool onlyIfNotParsed = false,
bool updateView = true,
QObject *parent = nullptr);
private:
PCppParser mParser;
QString mFileName;
bool mInProject;
bool mOnlyIfNotParsed;
bool mUpdateView;
// QThread interface
protected:
void run() override;
};
using PCppParserThread = std::shared_ptr<CppFileParserThread>;
class CppFileListParserThread: public QThread {
Q_OBJECT
public:
explicit CppFileListParserThread(
PCppParser parser,
bool updateView = true,
QObject *parent = nullptr);
private:
PCppParser mParser;
bool mUpdateView;
// QThread interface
protected:
void run() override;
};
void parseFile(
PCppParser parser,
2021-08-29 00:48:23 +08:00
const QString& fileName,
2021-08-23 10:16:06 +08:00
bool inProject,
bool onlyIfNotParsed = false,
bool updateView = true);
void parseFileList(
PCppParser parser,
bool updateView = true);
2021-08-14 22:52:37 +08:00
#endif // CPPPARSER_H