- enhancement: show completion for return type of lambda expressions.

This commit is contained in:
Roy Qu 2023-05-26 08:55:21 +08:00
parent 3440b08d8d
commit e44b2999e1
5 changed files with 76 additions and 21 deletions

View File

@ -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

View File

@ -714,3 +714,18 @@ bool isCppControlKeyword(const QString &word)
// counter--;
// qDebug()<<"statement deleted:"<<counter<<fullName<<kind<<extractFileName(fileName)<<line;
//}
bool isTypeKind(StatementKind kind)
{
switch(kind) {
case StatementKind::skClass:
case StatementKind::skNamespace:
case StatementKind::skEnumType:
case StatementKind::skEnumClassType:
case StatementKind::skTypedef:
case StatementKind::skPreprocessor:
return true;
default:
return false;
}
}

View File

@ -329,6 +329,7 @@ bool isCppFile(const QString& filename);
bool isCppKeyword(const QString& word);
bool isCppControlKeyword(const QString& word);
bool isScopeTypeKind(StatementKind kind);
bool isTypeKind(StatementKind kind);
MemberOperatorType getOperatorType(const QString& phrase, int index);
QStringList getOwnerExpressionAndMember(
const QStringList expression,

View File

@ -183,7 +183,10 @@ PStatement CodeCompletionPopup::selectedStatement()
return PStatement();
}
void CodeCompletionPopup::addChildren(const PStatement& scopeStatement, const QString &fileName, int line)
void CodeCompletionPopup::addChildren(const PStatement& scopeStatement,
const QString &fileName,
int line,
bool onlyTypes)
{
if (scopeStatement && !isIncluded(scopeStatement->fileName)
&& !isIncluded(scopeStatement->definitionFileName))
@ -192,6 +195,30 @@ void CodeCompletionPopup::addChildren(const PStatement& scopeStatement, const QS
if (children.isEmpty())
return;
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 {
if (!scopeStatement) { //Global scope
for (const PStatement& childStatement: children) {
if (childStatement->fileName.isEmpty()) {
@ -210,6 +237,8 @@ void CodeCompletionPopup::addChildren(const PStatement& scopeStatement, const QS
addStatement(childStatement,fileName,line);
}
}
}
}
void CodeCompletionPopup::addFunctionWithoutDefinitionChildren(const PStatement& scopeStatement, const QString &fileName, int 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);
}
}

View File

@ -129,7 +129,7 @@ public:
void setCodeSnippets(const QList<PCodeSnippet> &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);