From e3145d680f6448b22b09959d57bf61ed8abf4e9d Mon Sep 17 00:00:00 2001 From: Roy Qu Date: Sat, 13 Apr 2024 10:39:55 +0800 Subject: [PATCH] - fix: Shouldn't consider preceeding '&'/'*' when popping completion suggest list for variable members. --- NEWS.md | 1 + RedPandaIDE/editor.cpp | 4 ++++ RedPandaIDE/parser/cppparser.cpp | 29 +++++++++++++++++------------ RedPandaIDE/parser/cppparser.h | 8 +++++++- 4 files changed, 29 insertions(+), 13 deletions(-) diff --git a/NEWS.md b/NEWS.md index 5ed6addd..70dc9de9 100644 --- a/NEWS.md +++ b/NEWS.md @@ -138,6 +138,7 @@ Red Panda C++ Version 2.27 - enhancement: Auto hide Project menu if no project openning. - fix: Toggle breakpoint by shortcut may use wrong line. - fix: Size of the icons in problem and problem set panel are not correct. + - fix: Shouldn't consider preceeding '&'/'*' when popping completion suggest list for variable members. Red Panda C++ Version 2.26 - enhancement: Code suggestion for embedded std::vectors. diff --git a/RedPandaIDE/editor.cpp b/RedPandaIDE/editor.cpp index ab73f887..85d6001e 100644 --- a/RedPandaIDE/editor.cpp +++ b/RedPandaIDE/editor.cpp @@ -2341,6 +2341,10 @@ QStringList Editor::getOwnerExpressionAndMemberAtPositionForCompletion( QStringList &memberExpression) { QStringList expression = getExpressionAtPosition(pos); + // *(Deference) and &(Address-of) has low precedence than '.'/'->', + // so don't includes them in the owner expression in comletion calculation + while (!expression.isEmpty() && (expression.front()=='*' || expression.front()=='&')) + expression.pop_front(); return getOwnerExpressionAndMember(expression,memberOperator,memberExpression); } diff --git a/RedPandaIDE/parser/cppparser.cpp b/RedPandaIDE/parser/cppparser.cpp index 9a12a39e..394835cd 100644 --- a/RedPandaIDE/parser/cppparser.cpp +++ b/RedPandaIDE/parser/cppparser.cpp @@ -4755,7 +4755,7 @@ PEvalStatement CppParser::doEvalPointerToMembers( if (pos>=phraseExpression.length()) return PEvalStatement(); //find the start scope statement - PEvalStatement currentResult = doEvalCCast( + PEvalStatement currentResult = doEvalTypeCast( fileName, phraseExpression, pos, @@ -4771,7 +4771,7 @@ PEvalStatement CppParser::doEvalPointerToMembers( || phraseExpression[pos]=="->*")) { pos++; currentResult = - doEvalCCast( + doEvalTypeCast( fileName, phraseExpression, pos, @@ -4788,7 +4788,7 @@ PEvalStatement CppParser::doEvalPointerToMembers( return currentResult; } -PEvalStatement CppParser::doEvalCCast(const QString &fileName, +PEvalStatement CppParser::doEvalTypeCast(const QString &fileName, const QStringList &phraseExpression, int &pos, const PStatement& scope, @@ -4799,8 +4799,9 @@ PEvalStatement CppParser::doEvalCCast(const QString &fileName, return PEvalStatement(); PEvalStatement result; if (phraseExpression[pos]=="*") { + //deference pos++; //skip "*" - result = doEvalCCast( + result = doEvalTypeCast( fileName, phraseExpression, pos, @@ -4862,8 +4863,9 @@ PEvalStatement CppParser::doEvalCCast(const QString &fileName, result->pointerLevel--; } } else if (phraseExpression[pos]=="&") { + //Address-of pos++; //skip "&" - result = doEvalCCast( + result = doEvalTypeCast( fileName, phraseExpression, pos, @@ -4875,8 +4877,9 @@ PEvalStatement CppParser::doEvalCCast(const QString &fileName, } } else if (phraseExpression[pos]=="++" || phraseExpression[pos]=="--") { + // Prefix increment and decrement pos++; //skip "++" or "--" - result = doEvalCCast( + result = doEvalTypeCast( fileName, phraseExpression, pos, @@ -4884,6 +4887,7 @@ PEvalStatement CppParser::doEvalCCast(const QString &fileName, previousResult, freeScoped); } else if (phraseExpression[pos]=="(") { + //Type Cast //parse int startPos = pos; pos++; @@ -4904,7 +4908,7 @@ PEvalStatement CppParser::doEvalCCast(const QString &fileName, pos++; // skip ")" // qDebug()<<"parse type cast exp"; //it's a type cast - result = doEvalCCast(fileName, + result = doEvalTypeCast(fileName, phraseExpression, pos, scope, @@ -4930,11 +4934,6 @@ PEvalStatement CppParser::doEvalCCast(const QString &fileName, scope, previousResult, freeScoped); -// if (result) { -// qDebug()<kind<baseType; -// } else { -// qDebug()<<"!!!!!!!!!!!not found"; -// } return result; } @@ -4963,8 +4962,10 @@ PEvalStatement CppParser::doEvalMemberAccess(const QString &fileName, if (!result) break; if (phraseExpression[pos]=="++" || phraseExpression[pos]=="--") { + //Suffix/postfix increment and decrement pos++; //just skip it } else if (phraseExpression[pos] == "(") { + // Function call if (result->kind == EvalStatementKind::Type) { doSkipInExpression(phraseExpression,pos,"(",")"); result->kind = EvalStatementKind::Variable; @@ -5025,11 +5026,13 @@ PEvalStatement CppParser::doEvalMemberAccess(const QString &fileName, result = PEvalStatement(); } } else if (phraseExpression[pos] == "{") { + // Varaible Initialization if (result->kind == EvalStatementKind::Type) { doSkipInExpression(phraseExpression,pos,"{","}"); result->kind = EvalStatementKind::Variable; } } else if (phraseExpression[pos] == "[") { + //Array subscripting //skip to "]" doSkipInExpression(phraseExpression,pos,"[","]"); if (result->kind == EvalStatementKind::Type) { @@ -5079,6 +5082,7 @@ PEvalStatement CppParser::doEvalMemberAccess(const QString &fileName, } } } else if (phraseExpression[pos] == ".") { + //Structure and union member access pos++; lastResult = result; result = doEvalScopeResolution( @@ -5089,6 +5093,7 @@ PEvalStatement CppParser::doEvalMemberAccess(const QString &fileName, result, false); } else if (phraseExpression[pos] == "->") { + // Structure and union member access through pointer pos++; if (result->pointerLevel==0) { // iterator diff --git a/RedPandaIDE/parser/cppparser.h b/RedPandaIDE/parser/cppparser.h index 40f02b19..0af6fe1e 100644 --- a/RedPandaIDE/parser/cppparser.h +++ b/RedPandaIDE/parser/cppparser.h @@ -339,13 +339,19 @@ private: const PStatement& scope, const PEvalStatement& previousResult, bool freeScoped) const; - PEvalStatement doEvalCCast( + + /* + * Dereference / Address-of / Type Cast / Prefix increment and decrement + * */ + PEvalStatement doEvalTypeCast( const QString& fileName, const QStringList& phraseExpression, int &pos, const PStatement& scope, const PEvalStatement& previousResult, bool freeScoped) const; + + PEvalStatement doEvalMemberAccess( const QString& fileName, const QStringList& phraseExpression,