From e44b2999e1708030ce720e22533cca397450bde5 Mon Sep 17 00:00:00 2001 From: Roy Qu Date: Fri, 26 May 2023 08:55:21 +0800 Subject: [PATCH] - enhancement: show completion for return type of lambda expressions. --- NEWS.md | 3 +- RedPandaIDE/parser/parserutils.cpp | 15 ++++ RedPandaIDE/parser/parserutils.h | 1 + RedPandaIDE/widgets/codecompletionpopup.cpp | 76 +++++++++++++++------ RedPandaIDE/widgets/codecompletionpopup.h | 2 +- 5 files changed, 76 insertions(+), 21 deletions(-) diff --git a/NEWS.md b/NEWS.md index 01e8180b..f0ffa060 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,11 +1,12 @@ Red Panda C++ Version 2.22 - - enhancement: ignore '__extension__' when parsing C/C++ codes. - fix: Crash at startup when current problem in the problem set is connected with source file. - fix: Double-clicking on touchpad can't select current word. - fix: foreach-loops are not correctly parsed. - fix: '^' is not correctly handled as operator. - fix: lambda expression is not correctly handled. + - fix: '__extension__' should be ignored when parsing C/C++ codes. + - enhancement: show completion for return type of lambda expressions. Red Panda C++ Version 2.21 diff --git a/RedPandaIDE/parser/parserutils.cpp b/RedPandaIDE/parser/parserutils.cpp index 3536af94..ee16ce8f 100644 --- a/RedPandaIDE/parser/parserutils.cpp +++ b/RedPandaIDE/parser/parserutils.cpp @@ -714,3 +714,18 @@ bool isCppControlKeyword(const QString &word) // counter--; // qDebug()<<"statement deleted:"<fileName) && !isIncluded(scopeStatement->definitionFileName)) @@ -192,23 +195,49 @@ void CodeCompletionPopup::addChildren(const PStatement& scopeStatement, const QS if (children.isEmpty()) return; - if (!scopeStatement) { //Global scope - for (const PStatement& childStatement: children) { - if (childStatement->fileName.isEmpty()) { - // hard defines - addStatement(childStatement,fileName,-1); - } else if ( - isIncluded(childStatement->fileName) - || isIncluded(childStatement->definitionFileName) - ) { - //we must check if the statement is included by the file + if (onlyTypes) { + if (!scopeStatement) { //Global scope + for (const PStatement& childStatement: children) { + if (!isTypeKind(childStatement->kind)) + continue; + if (childStatement->fileName.isEmpty()) { + // hard defines + addStatement(childStatement,fileName,-1); + } else if ( + isIncluded(childStatement->fileName) + || isIncluded(childStatement->definitionFileName) + ) { + //we must check if the statement is included by the file + addStatement(childStatement,fileName,line); + } + } + } else { + for (const PStatement& childStatement: children) { + if (!isTypeKind(childStatement->kind)) + continue; addStatement(childStatement,fileName,line); } } } else { - for (const PStatement& childStatement: children) { - addStatement(childStatement,fileName,line); + if (!scopeStatement) { //Global scope + for (const PStatement& childStatement: children) { + if (childStatement->fileName.isEmpty()) { + // hard defines + addStatement(childStatement,fileName,-1); + } else if ( + isIncluded(childStatement->fileName) + || isIncluded(childStatement->definitionFileName) + ) { + //we must check if the statement is included by the file + addStatement(childStatement,fileName,line); + } + } + } else { + for (const PStatement& childStatement: children) { + addStatement(childStatement,fileName,line); + } } + } } @@ -557,6 +586,11 @@ void CodeCompletionPopup::getCompletionFor( if (memberOperator.isEmpty() && ownerExpression.isEmpty() && memberExpression.isEmpty()) return; + bool isLambdaReturnType = ( + memberOperator=="->" + && ownerExpression.startsWith("[") + && ownerExpression.endsWith(")")); + if (memberOperator.isEmpty()) { //C++ preprocessor directives if (mMemberPhrase.startsWith('#')) { @@ -602,6 +636,10 @@ void CodeCompletionPopup::getCompletionFor( } } } + } else if (isLambdaReturnType) { + foreach (const QString& keyword,CppTypeKeywords) { + addKeyword(keyword); + } } if (!mParser || !mParser->enabled()) @@ -614,15 +652,15 @@ void CodeCompletionPopup::getCompletionFor( mParser->unFreeze(); }); - if (memberOperator.isEmpty()) { + if (memberOperator.isEmpty() || isLambdaReturnType) { PStatement scopeStatement = mCurrentScope; // repeat until reach global while (scopeStatement) { //add members of current scope that not added before if (scopeStatement->kind == StatementKind::skClass) { - addChildren(scopeStatement, fileName, -1); + addChildren(scopeStatement, fileName, -1, isLambdaReturnType); } else { - addChildren(scopeStatement, fileName, line); + addChildren(scopeStatement, fileName, line, isLambdaReturnType); } // add members of all usings (in current scope ) and not added before @@ -632,14 +670,14 @@ void CodeCompletionPopup::getCompletionFor( if (!namespaceStatementsList) continue; foreach (const PStatement& namespaceStatement,*namespaceStatementsList) { - addChildren(namespaceStatement, fileName, line); + addChildren(namespaceStatement, fileName, line, isLambdaReturnType); } } scopeStatement=scopeStatement->parentScope.lock(); } // add all global members and not added before - addChildren(nullptr, fileName, line); + addChildren(nullptr, fileName, line, isLambdaReturnType); // add members of all fusings mUsings = mParser->getFileUsings(fileName); @@ -649,7 +687,7 @@ void CodeCompletionPopup::getCompletionFor( if (!namespaceStatementsList) continue; foreach (const PStatement& namespaceStatement, *namespaceStatementsList) { - addChildren(namespaceStatement, fileName, line); + addChildren(namespaceStatement, fileName, line, isLambdaReturnType); } } diff --git a/RedPandaIDE/widgets/codecompletionpopup.h b/RedPandaIDE/widgets/codecompletionpopup.h index ac942f43..54fc3430 100644 --- a/RedPandaIDE/widgets/codecompletionpopup.h +++ b/RedPandaIDE/widgets/codecompletionpopup.h @@ -129,7 +129,7 @@ public: void setCodeSnippets(const QList &newCodeSnippets); private: void addChildren(const PStatement& scopeStatement, const QString& fileName, - int line); + int line, bool onlyTypes=false); void addFunctionWithoutDefinitionChildren(const PStatement& scopeStatement, const QString& fileName, int line); void addStatement(const PStatement& statement, const QString& fileName, int line);