From 41336cf31f0a122f09d6faea938560abdbc436e8 Mon Sep 17 00:00:00 2001 From: Roy Qu Date: Sat, 18 Dec 2021 23:36:58 +0800 Subject: [PATCH] add a function to find statement by expression in the parser --- RedPandaIDE/cpprefacter.cpp | 7 ++-- RedPandaIDE/editor.cpp | 64 ++---------------------------- RedPandaIDE/editor.h | 4 +- RedPandaIDE/parser/cppparser.cpp | 42 +++++++++++++++----- RedPandaIDE/parser/cppparser.h | 12 ++---- RedPandaIDE/parser/parserutils.cpp | 62 +++++++++++++++++++++++++++++ RedPandaIDE/parser/parserutils.h | 6 +++ 7 files changed, 114 insertions(+), 83 deletions(-) diff --git a/RedPandaIDE/cpprefacter.cpp b/RedPandaIDE/cpprefacter.cpp index 1fcb5958..6f4b6e7f 100644 --- a/RedPandaIDE/cpprefacter.cpp +++ b/RedPandaIDE/cpprefacter.cpp @@ -24,13 +24,12 @@ bool CppRefacter::findOccurence(Editor *editor, const BufferCoord &pos) editor->parser()->unFreeze(); }); // get full phrase (such as s.name instead of name) - BufferCoord pBeginPos,pEndPos; - QString phrase = getWordAtPosition(editor,pos,pBeginPos,pEndPos,Editor::WordPurpose::wpInformation); + QStringList expression = editor->getExpressionAtPosition(pos); // Find it's definition PStatement statement = editor->parser()->findStatementOf( editor->filename(), - phrase, - pos.Line); + expression, + editor->parser()->findAndScanBlockAt(editor->filename(),pos.Line)); // definition of the symbol not found if (!statement) return false; diff --git a/RedPandaIDE/editor.cpp b/RedPandaIDE/editor.cpp index 2a5fbc95..52130df6 100644 --- a/RedPandaIDE/editor.cpp +++ b/RedPandaIDE/editor.cpp @@ -1631,51 +1631,7 @@ QStringList Editor::getOwnerExpressionAndMemberAtPositionForCompletion( QStringList &memberExpression) { QStringList expression = getExpressionAtPosition(pos); - //find position of the last member operator - int lastMemberOperatorPos = -1; - int currentMatchingLevel = 0; - QString matchingSignLeft; - QString matchingSignRight; - for (int i=0;iisMemberOperator(token)) { - lastMemberOperatorPos = i; - } else if (token == "(") { - matchingSignLeft = "("; - matchingSignRight = ")"; - currentMatchingLevel++; - } else if (token == "[") { - matchingSignLeft = "["; - matchingSignRight = "]"; - currentMatchingLevel++; - } else if (token == "<") { - matchingSignLeft = "<"; - matchingSignRight = ">"; - currentMatchingLevel++; - } - } else { - if (token == matchingSignLeft) { - currentMatchingLevel++; - } else if (token == matchingSignRight) { - currentMatchingLevel--; - } - } - } - - QStringList ownerExpression; - if (lastMemberOperatorPos<0) { - memberOperator = ""; - memberExpression = expression; - } else { - memberOperator = expression[lastMemberOperatorPos]; - memberExpression = expression.mid(lastMemberOperatorPos+1); - ownerExpression = expression.mid(0,lastMemberOperatorPos); - } - if (memberExpression.length()>1) { - memberExpression = memberExpression.mid(memberExpression.length()-1,1); - } - return ownerExpression; + return getOwnerExpressionAndMember(expression,memberOperator,memberExpression); } QStringList Editor::getExpressionAtPosition( @@ -3099,21 +3055,9 @@ QString Editor::getParserHint(const QStringList& expression,const QString &s, in { // This piece of code changes the parser database, possibly making hints and code completion invalid... QString result; - PStatement statement; - if (expression.count()>1) { - PEvalStatement evalStatement = mParser->evalExpression( - mFilename,expression, - mParser->findAndScanBlockAt(mFilename,line)); - if (evalStatement) { - if (evalStatement->kind == EvalStatementKind::Type) { - statement = evalStatement->effectiveTypeStatement; - } else { - statement = evalStatement->baseStatement; - } - } - } else { - statement = mParser->findStatementOf(mFilename, s, line); - } + PStatement statement = mParser->findStatementOf( + mFilename,expression, + mParser->findAndScanBlockAt(mFilename,line)); if (!statement) return result; if (statement->kind == StatementKind::skFunction diff --git a/RedPandaIDE/editor.h b/RedPandaIDE/editor.h index 3ccbe2c2..be4e1f16 100644 --- a/RedPandaIDE/editor.h +++ b/RedPandaIDE/editor.h @@ -199,6 +199,8 @@ public: QString& memberOperator, QStringList& memberExpression); QString getWordForCompletionSearch(const BufferCoord& pos,bool permitTilde); + QStringList getExpressionAtPosition( + const BufferCoord& pos); const PCppParser &parser(); @@ -260,8 +262,6 @@ private: void popUserCodeInTabStops(); void onExportedFormatToken(PSynHighlighter syntaxHighlighter, int Line, int column, const QString& token, PSynHighlighterAttribute &attr); - QStringList getExpressionAtPosition( - const BufferCoord& pos); private: QByteArray mEncodingOption; // the encoding type set by the user QByteArray mFileEncoding; // the real encoding of the file (auto detected) diff --git a/RedPandaIDE/parser/cppparser.cpp b/RedPandaIDE/parser/cppparser.cpp index ce176499..8edad39e 100644 --- a/RedPandaIDE/parser/cppparser.cpp +++ b/RedPandaIDE/parser/cppparser.cpp @@ -39,11 +39,6 @@ CppParser::CppParser(QObject *parent) : QObject(parent) //mBlockBeginSkips; //mBlockEndSkips; //mInlineNamespaceEndSkips; - mMemberOperators.insert("."); - mMemberOperators.insert("::"); - mMemberOperators.insert("->"); - mMemberOperators.insert("->*"); - mMemberOperators.insert(".*"); } CppParser::~CppParser() @@ -420,6 +415,38 @@ PStatement CppParser::findStatementOf(const QString &fileName, const QString &ph return findStatementOf(fileName,phrase,currentClass,statementParentType,force); } +PStatement CppParser::findStatementOf(const QString &fileName, const QStringList &expression, const PStatement ¤tScope) +{ + QMutexLocker locker(&mMutex); + if (mParsing) + return PStatement(); + QString memberOperator; + QStringList memberExpression; + QStringList ownerExpression = getOwnerExpressionAndMember(expression,memberOperator,memberExpression); + if (memberExpression.isEmpty()) { + return PStatement(); + } + QString phrase = memberExpression[0]; + if (memberOperator.isEmpty()) { + return findStatementStartingFrom(fileName,phrase,currentScope); + } else if (ownerExpression.isEmpty()) { + return findMemberOfStatement(phrase,PStatement()); + } else { + int pos = 0; + PEvalStatement ownerEvalStatement = doEvalExpression(fileName, + ownerExpression, + pos, + currentScope, + PEvalStatement(), + true); + if (!ownerEvalStatement) { + return PStatement(); + } + return findMemberOfStatement(phrase, ownerEvalStatement->effectiveTypeStatement); + } + +} + PStatement CppParser::findStatementStartingFrom(const QString &fileName, const QString &phrase, const PStatement& startScope) { PStatement scopeStatement = startScope; @@ -4608,10 +4635,7 @@ void CppParser::updateSerialId() mSerialId = QString("%1 %2").arg(mParserId).arg(mSerialCount); } -bool CppParser::isMemberOperator(QString token) const -{ - return mMemberOperators.contains(token); -} + const StatementModel &CppParser::statementList() const { diff --git a/RedPandaIDE/parser/cppparser.h b/RedPandaIDE/parser/cppparser.h index 9c973d8b..bad138e8 100644 --- a/RedPandaIDE/parser/cppparser.h +++ b/RedPandaIDE/parser/cppparser.h @@ -49,6 +49,10 @@ public: const QString& phrase, const PStatement& currentClass, bool force = false); + + PStatement findStatementOf(const QString& fileName, + const QStringList& expression, + const PStatement& currentScope); /** * @brief evaluate the expression * @param fileName @@ -86,13 +90,6 @@ public: QString prettyPrintStatement(const PStatement& statement, const QString& filename, int line = -1); - /** - * @brief test if the token is a member/scope operator - * @param token - * @return true if it is, false if not - */ - bool isMemberOperator(QString token) const; - bool enabled() const; void setEnabled(bool newEnabled); @@ -452,7 +449,6 @@ private: GetFileStreamCallBack mOnGetFileStream; QMap mCppKeywords; QSet mCppTypeKeywords; - QSet mMemberOperators; }; using PCppParser = std::shared_ptr; diff --git a/RedPandaIDE/parser/parserutils.cpp b/RedPandaIDE/parser/parserutils.cpp index ac44890f..cf8cea8a 100644 --- a/RedPandaIDE/parser/parserutils.cpp +++ b/RedPandaIDE/parser/parserutils.cpp @@ -15,6 +15,7 @@ QSet CKeywords; QSet STLPointers; QSet STLContainers; QSet STLElementMethods; +QSet MemberOperators; Q_GLOBAL_STATIC(QSet,CppHeaderExts) Q_GLOBAL_STATIC(QSet,CppSourceExts) @@ -293,6 +294,12 @@ void initParser() JavadocTags.append("@throws"); JavadocTags.append("@value"); JavadocTags.append("@version"); + + MemberOperators.insert("."); + MemberOperators.insert("::"); + MemberOperators.insert("->"); + MemberOperators.insert("->*"); + MemberOperators.insert(".*"); } QString getHeaderFilename(const QString &relativeTo, const QString &line, @@ -520,3 +527,58 @@ void EvalStatement::assignType(const PEvalStatement &typeStatement) pointerLevel = typeStatement->pointerLevel; effectiveTypeStatement = typeStatement->effectiveTypeStatement; } + +QStringList getOwnerExpressionAndMember(const QStringList expression, QString &memberOperator, QStringList &memberExpression) +{ + //find position of the last member operator + int lastMemberOperatorPos = -1; + int currentMatchingLevel = 0; + QString matchingSignLeft; + QString matchingSignRight; + for (int i=0;i1) { + memberExpression = memberExpression.mid(memberExpression.length()-1,1); + } + return ownerExpression; + +} + +bool isMemberOperator(QString token) +{ + return MemberOperators.contains(token); +} diff --git a/RedPandaIDE/parser/parserutils.h b/RedPandaIDE/parser/parserutils.h index ab1a2903..6ce12fc6 100644 --- a/RedPandaIDE/parser/parserutils.h +++ b/RedPandaIDE/parser/parserutils.h @@ -225,6 +225,7 @@ extern QSet CppTypeKeywords; extern QSet STLPointers; extern QSet STLContainers; extern QSet STLElementMethods; +extern QSet MemberOperators; void initParser(); @@ -240,5 +241,10 @@ bool isCfile(const QString& filename); bool isKeyword(const QString& word); bool isScopeTypeKind(StatementKind kind); MemberOperatorType getOperatorType(const QString& phrase, int index); +QStringList getOwnerExpressionAndMember( + const QStringList expression, + QString& memberOperator, + QStringList& memberExpression); +bool isMemberOperator(QString token); #endif // PARSER_UTILS_H