From ebeea19794f6a427c61bd44d05c2161cec05d859 Mon Sep 17 00:00:00 2001 From: Roy Qu Date: Fri, 3 May 2024 10:39:44 +0800 Subject: [PATCH] - enhancement: support C++ 17 structured binding in stl map containers foreach loop. --- NEWS.md | 1 + RedPandaIDE/parser/cppparser.cpp | 83 +++++++++++++++++++++++++++++++- RedPandaIDE/parser/cppparser.h | 2 + 3 files changed, 84 insertions(+), 2 deletions(-) diff --git a/NEWS.md b/NEWS.md index c51db105..73923747 100644 --- a/NEWS.md +++ b/NEWS.md @@ -158,6 +158,7 @@ Red Panda C++ Version 2.27 - enhancement: Support macro in #include preprocessing statements. - fix: In options -> code format -> Program, Choose astyle path button doesn't work. - fix: project not correctly reparsed after rename unit. + - enhancement: support C++ 17 structured binding in stl map containers foreach loop. Red Panda C++ Version 2.26 - enhancement: Code suggestion for embedded std::vectors. diff --git a/RedPandaIDE/parser/cppparser.cpp b/RedPandaIDE/parser/cppparser.cpp index ab44b663..76136f11 100644 --- a/RedPandaIDE/parser/cppparser.cpp +++ b/RedPandaIDE/parser/cppparser.cpp @@ -2299,6 +2299,9 @@ void CppParser::checkAndHandleMethodOrVar(KeywordType keywordType, int maxIndex) mIndex, isStatic, maxIndex); return; + } else if (mTokenizer[mIndex]->text.startsWith("[")) { + handleStructredBinding(sType,maxIndex); + return; } else if (mTokenizer[mIndex + 1]->text == '(') { #ifdef ENABLE_SDCC if (mLanguage==ParserLanguage::SDCC && mTokenizer[mIndex]->text=="__at") { @@ -2627,6 +2630,32 @@ PStatement CppParser::getTypeDef(const PStatement& statement, return PStatement(); } +void CppParser::doAddVar(const QString &name, const QString &type, bool isConst, const QString& suffix) +{ + if (!isIdentifier(name)) + return; + if (type.isEmpty()) + return; + QString realType = type; + if (isConst) + realType = "const "+realType; + if (!suffix.isEmpty()) + realType += " "+suffix; + addChildStatement( + getCurrentScope(), + mCurrentFile, + realType, + name, + "", + "", + "", + mTokenizer[mIndex]->line, + StatementKind::Variable, + getScope(), + mCurrentMemberAccessibility, + StatementProperty::HasDefinition); +} + void CppParser::handleConcept(int maxIndex) { mIndex++; // skip 'concept'; @@ -3892,6 +3921,58 @@ void CppParser::handleStructs(bool isTypedef, int maxIndex) } } +void CppParser::handleStructredBinding(const QString &sType, int maxIndex) +{ + if (mIndex+1 < maxIndex + && AutoTypes.contains(sType) + && ((mTokenizer[mIndex+1]->text == ":") + || (mTokenizer[mIndex+1]->text == "="))) { + QString typeName; + QString templateParams; + int endIndex = indexOfNextSemicolon(mIndex+2, maxIndex); + QString expressionText; + for (int i=mIndex+2;itext+" "; + } + QStringList phraseExpression = splitExpression(expressionText); + int pos = 0; + PEvalStatement aliasStatement = doEvalExpression(mCurrentFile, + phraseExpression, + pos, + getCurrentScope(), + PEvalStatement(), + true,false); + if(aliasStatement && aliasStatement->effectiveTypeStatement) { + if ( mTokenizer[mIndex+1]->text == ":" ) { + if (STLMaps.contains(aliasStatement->effectiveTypeStatement->fullName)) { + typeName = "std::pair"; + templateParams = aliasStatement->templateParams; + } + } + if (typeName == "std::pair" && !templateParams.isEmpty()) { + QString firstType = doFindFirstTemplateParamOf(mCurrentFile,aliasStatement->templateParams, + getCurrentScope()); + QString secondType = doFindTemplateParamOf(mCurrentFile,aliasStatement->templateParams,1, + getCurrentScope()); + QString s = mTokenizer[mIndex]->text; + s = s.mid(1,s.length()-2); + QStringList lst = s.split(","); + if (lst.length()==2) { + QString firstVar = lst[0].trimmed(); + QString secondVar = lst[1].trimmed; + bool isConst = sType.startsWith("const"); + QString suffix; + if (sType.endsWith("&&")) suffix = "&&"; + else if (sType.endsWith("&")) suffix = "&"; + doAddVar(firstVar, firstType, isConst, suffix); + doAddVar(secondVar, secondType, isConst, suffix); + } + } + } + } + mIndex = indexOfNextPeriodOrSemicolon(mIndex+1, maxIndex); +} + void CppParser::handleUsing(int maxIndex) { int startLine = mTokenizer[mIndex]->line; @@ -4185,7 +4266,6 @@ void CppParser::handleVar(const QString& typePrefix,bool isExtern,bool isStatic, StatementKind::Variable, getScope(), mCurrentMemberAccessibility, - //True, (isExtern?StatementProperty::None:StatementProperty::HasDefinition) | (isStatic?StatementProperty::Static:StatementProperty::None) | StatementProperty::FunctionPointer); @@ -4273,7 +4353,6 @@ void CppParser::handleVar(const QString& typePrefix,bool isExtern,bool isStatic, StatementKind::Variable, getScope(), mCurrentMemberAccessibility, - //True, (isExtern?StatementProperty::None:StatementProperty::HasDefinition) | (isStatic?StatementProperty::Static:StatementProperty::None)); tempType=""; diff --git a/RedPandaIDE/parser/cppparser.h b/RedPandaIDE/parser/cppparser.h index 91c99fa4..99aba6d6 100644 --- a/RedPandaIDE/parser/cppparser.h +++ b/RedPandaIDE/parser/cppparser.h @@ -508,6 +508,7 @@ private: PStatement getTypeDef(const PStatement& statement, const QString& fileName, const QString& aType) const; // void handleCatchBlock(); + void doAddVar(const QString& name, const QString& type, bool isConst, const QString& suffix); void handleConcept(int maxIndex); void handleEnum(bool isTypedef, int maxIndex); void handleForBlock(int maxIndex); @@ -532,6 +533,7 @@ private: void handleAccessibilitySpecifiers(KeywordType keywordType, int maxIndex); bool handleStatement(int maxIndex); void handleStructs(bool isTypedef, int maxIndex); + void handleStructredBinding(const QString& sType, int maxIndex); void handleUsing(int maxIndex); void handleVar(const QString& typePrefix,bool isExtern,bool isStatic, int maxIndex); void handleInheritance(PStatement derivedClass, PClassInheritanceInfo pInfo);