- 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 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: 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: Double-clicking on touchpad can't select current word.
- fix: foreach-loops are not correctly parsed. - fix: foreach-loops are not correctly parsed.
- fix: '^' is not correctly handled as operator. - fix: '^' is not correctly handled as operator.
- fix: lambda expression is not correctly handled. - 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 Red Panda C++ Version 2.21

View File

@ -714,3 +714,18 @@ bool isCppControlKeyword(const QString &word)
// counter--; // counter--;
// qDebug()<<"statement deleted:"<<counter<<fullName<<kind<<extractFileName(fileName)<<line; // 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 isCppKeyword(const QString& word);
bool isCppControlKeyword(const QString& word); bool isCppControlKeyword(const QString& word);
bool isScopeTypeKind(StatementKind kind); bool isScopeTypeKind(StatementKind kind);
bool isTypeKind(StatementKind kind);
MemberOperatorType getOperatorType(const QString& phrase, int index); MemberOperatorType getOperatorType(const QString& phrase, int index);
QStringList getOwnerExpressionAndMember( QStringList getOwnerExpressionAndMember(
const QStringList expression, const QStringList expression,

View File

@ -183,7 +183,10 @@ PStatement CodeCompletionPopup::selectedStatement()
return PStatement(); 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) if (scopeStatement && !isIncluded(scopeStatement->fileName)
&& !isIncluded(scopeStatement->definitionFileName)) && !isIncluded(scopeStatement->definitionFileName))
@ -192,23 +195,49 @@ void CodeCompletionPopup::addChildren(const PStatement& scopeStatement, const QS
if (children.isEmpty()) if (children.isEmpty())
return; return;
if (!scopeStatement) { //Global scope if (onlyTypes) {
for (const PStatement& childStatement: children) { if (!scopeStatement) { //Global scope
if (childStatement->fileName.isEmpty()) { for (const PStatement& childStatement: children) {
// hard defines if (!isTypeKind(childStatement->kind))
addStatement(childStatement,fileName,-1); continue;
} else if ( if (childStatement->fileName.isEmpty()) {
isIncluded(childStatement->fileName) // hard defines
|| isIncluded(childStatement->definitionFileName) addStatement(childStatement,fileName,-1);
) { } else if (
//we must check if the statement is included by the file 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); addStatement(childStatement,fileName,line);
} }
} }
} else { } else {
for (const PStatement& childStatement: children) { if (!scopeStatement) { //Global scope
addStatement(childStatement,fileName,line); 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()) if (memberOperator.isEmpty() && ownerExpression.isEmpty() && memberExpression.isEmpty())
return; return;
bool isLambdaReturnType = (
memberOperator=="->"
&& ownerExpression.startsWith("[")
&& ownerExpression.endsWith(")"));
if (memberOperator.isEmpty()) { if (memberOperator.isEmpty()) {
//C++ preprocessor directives //C++ preprocessor directives
if (mMemberPhrase.startsWith('#')) { if (mMemberPhrase.startsWith('#')) {
@ -602,6 +636,10 @@ void CodeCompletionPopup::getCompletionFor(
} }
} }
} }
} else if (isLambdaReturnType) {
foreach (const QString& keyword,CppTypeKeywords) {
addKeyword(keyword);
}
} }
if (!mParser || !mParser->enabled()) if (!mParser || !mParser->enabled())
@ -614,15 +652,15 @@ void CodeCompletionPopup::getCompletionFor(
mParser->unFreeze(); mParser->unFreeze();
}); });
if (memberOperator.isEmpty()) { if (memberOperator.isEmpty() || isLambdaReturnType) {
PStatement scopeStatement = mCurrentScope; PStatement scopeStatement = mCurrentScope;
// repeat until reach global // repeat until reach global
while (scopeStatement) { while (scopeStatement) {
//add members of current scope that not added before //add members of current scope that not added before
if (scopeStatement->kind == StatementKind::skClass) { if (scopeStatement->kind == StatementKind::skClass) {
addChildren(scopeStatement, fileName, -1); addChildren(scopeStatement, fileName, -1, isLambdaReturnType);
} else { } else {
addChildren(scopeStatement, fileName, line); addChildren(scopeStatement, fileName, line, isLambdaReturnType);
} }
// add members of all usings (in current scope ) and not added before // add members of all usings (in current scope ) and not added before
@ -632,14 +670,14 @@ void CodeCompletionPopup::getCompletionFor(
if (!namespaceStatementsList) if (!namespaceStatementsList)
continue; continue;
foreach (const PStatement& namespaceStatement,*namespaceStatementsList) { foreach (const PStatement& namespaceStatement,*namespaceStatementsList) {
addChildren(namespaceStatement, fileName, line); addChildren(namespaceStatement, fileName, line, isLambdaReturnType);
} }
} }
scopeStatement=scopeStatement->parentScope.lock(); scopeStatement=scopeStatement->parentScope.lock();
} }
// add all global members and not added before // add all global members and not added before
addChildren(nullptr, fileName, line); addChildren(nullptr, fileName, line, isLambdaReturnType);
// add members of all fusings // add members of all fusings
mUsings = mParser->getFileUsings(fileName); mUsings = mParser->getFileUsings(fileName);
@ -649,7 +687,7 @@ void CodeCompletionPopup::getCompletionFor(
if (!namespaceStatementsList) if (!namespaceStatementsList)
continue; continue;
foreach (const PStatement& namespaceStatement, *namespaceStatementsList) { 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); void setCodeSnippets(const QList<PCodeSnippet> &newCodeSnippets);
private: private:
void addChildren(const PStatement& scopeStatement, const QString& fileName, void addChildren(const PStatement& scopeStatement, const QString& fileName,
int line); int line, bool onlyTypes=false);
void addFunctionWithoutDefinitionChildren(const PStatement& scopeStatement, const QString& fileName, void addFunctionWithoutDefinitionChildren(const PStatement& scopeStatement, const QString& fileName,
int line); int line);
void addStatement(const PStatement& statement, const QString& fileName, int line); void addStatement(const PStatement& statement, const QString& fileName, int line);