support lambda expression captures.
This commit is contained in:
parent
d63aa1a58f
commit
09a61c4c32
2
NEWS.md
2
NEWS.md
|
@ -76,7 +76,7 @@ Red Panda C++ Version 2.27
|
|||
- enhancement: Show "std::function" in the completion list.
|
||||
- enhancement: Improvement in italic font support.
|
||||
- fix: History not correctly loaded with up/down arrow key in the debug console.
|
||||
- enhancement: Improve lambda support.
|
||||
- enhancement: Improve lambda expression support.
|
||||
- enhancement: Show type completion hint after "constexpr"/"extern"/"static"/"consteval"/"constinit"/"const"/"volatile" etc.
|
||||
- enhancement: Restore line position after file is modified outside and reloaded.
|
||||
|
||||
|
|
|
@ -1458,8 +1458,6 @@ PStatement CppParser::addStatement(const PStatement& parent,
|
|||
result->setInProject(false);
|
||||
result->setInSystemHeader(true);
|
||||
}
|
||||
//result->children;
|
||||
//result->friends;
|
||||
if (scope == StatementScope::Local)
|
||||
result->fullName = newCommand;
|
||||
else
|
||||
|
@ -2887,6 +2885,7 @@ void CppParser::handleKeyword(KeywordType skipType, int maxIndex)
|
|||
void CppParser::handleLambda(int index, int maxIndex)
|
||||
{
|
||||
Q_ASSERT(mTokenizer[index]->text.startsWith('['));
|
||||
QSet<QString> captures = parseLambdaCaptures(index);
|
||||
int startLine=mTokenizer[index]->line;
|
||||
int argStart=index+1;
|
||||
if (mTokenizer[argStart]->text!='(')
|
||||
|
@ -2910,10 +2909,11 @@ void CppParser::handleLambda(int index, int maxIndex)
|
|||
"",
|
||||
"",
|
||||
startLine,
|
||||
StatementKind::skBlock,
|
||||
StatementKind::skLambda,
|
||||
StatementScope::Local,
|
||||
StatementAccessibility::None,
|
||||
StatementProperty::spHasDefinition);
|
||||
lambdaBlock->lambdaCaptures = captures;
|
||||
scanMethodArgs(lambdaBlock,argStart);
|
||||
addSoloScopeLevel(lambdaBlock,mTokenizer[bodyStart]->line);
|
||||
int oldIndex = mIndex;
|
||||
|
@ -5979,8 +5979,35 @@ void CppParser::scanMethodArgs(const PStatement& functionStatement, int argStart
|
|||
}
|
||||
}
|
||||
addMethodParameterStatement(words,mTokenizer[i-1]->line,functionStatement);
|
||||
}
|
||||
|
||||
|
||||
QSet<QString> CppParser::parseLambdaCaptures(int index)
|
||||
{
|
||||
QString s = mTokenizer[index]->text;
|
||||
QString word;
|
||||
QSet<QString> result;
|
||||
//skip '[' ']'
|
||||
for (int i=1;i<s.length()-1;i++) {
|
||||
switch(s[i].unicode()){
|
||||
case ',':
|
||||
if (!word.isEmpty()) {
|
||||
result.insert(word);
|
||||
word.clear();
|
||||
}
|
||||
break;
|
||||
case ' ':
|
||||
case '\t':
|
||||
case '*':
|
||||
break;
|
||||
default:
|
||||
if (word=="&")
|
||||
word.clear();
|
||||
word+=s[i];
|
||||
}
|
||||
}
|
||||
if (!word.isEmpty())
|
||||
result.insert(word);
|
||||
return result;
|
||||
}
|
||||
|
||||
QString CppParser::splitPhrase(const QString &phrase, QString &sClazz,
|
||||
|
|
|
@ -531,16 +531,10 @@ private:
|
|||
void internalInvalidateFile(const QString& fileName);
|
||||
void internalInvalidateFiles(const QSet<QString>& files);
|
||||
QSet<QString> calculateFilesToBeReparsed(const QString& fileName);
|
||||
// int calcKeyLenForStruct(const QString& word);
|
||||
// {
|
||||
// function GetClass(const Phrase: AnsiString): AnsiString;
|
||||
// function GetMember(const Phrase: AnsiString): AnsiString;
|
||||
// function GetOperator(const Phrase: AnsiString): AnsiString;
|
||||
// function GetRemainder(const Phrase: AnsiString): AnsiString;
|
||||
// }
|
||||
void scanMethodArgs(
|
||||
const PStatement& functionStatement,
|
||||
int argStart);
|
||||
QSet<QString> parseLambdaCaptures(int index);
|
||||
QString splitPhrase(const QString& phrase, QString& sClazz,
|
||||
QString& sOperator, QString &sMember) const;
|
||||
QString removeTemplateParams(const QString& phrase) const;
|
||||
|
|
|
@ -107,6 +107,7 @@ enum StatementKind {
|
|||
skOperator,
|
||||
skParameter,
|
||||
skBlock,
|
||||
skLambda,
|
||||
skUserCodeSnippet, // user code template
|
||||
skKeyword, // keywords
|
||||
skKeywordType, //keywords for type (for color management)
|
||||
|
@ -197,6 +198,7 @@ struct Statement {
|
|||
QString fullName; // fullname(including class and namespace), ClassA::foo
|
||||
QSet<QString> usingList; // using namespaces
|
||||
QString noNameArgs;// Args without name
|
||||
QSet<QString> lambdaCaptures;
|
||||
StatementProperties properties;
|
||||
|
||||
// fields for code completion
|
||||
|
|
|
@ -363,7 +363,8 @@ void ClassBrowserModel::filterChildren(ClassBrowserNode *node, const StatementMa
|
|||
|
||||
if (statement->kind == StatementKind::skBlock)
|
||||
continue;
|
||||
|
||||
if (statement->kind == StatementKind::skLambda)
|
||||
continue;
|
||||
if (statement->isInherited() && !pSettings->ui().classBrowserShowInherited())
|
||||
continue;
|
||||
|
||||
|
|
|
@ -287,6 +287,7 @@ void CodeCompletionPopup::addStatement(const PStatement& statement, const QStrin
|
|||
if (statement->kind == StatementKind::skConstructor
|
||||
|| statement->kind == StatementKind::skDestructor
|
||||
|| statement->kind == StatementKind::skBlock
|
||||
|| statement->kind == StatementKind::skLambda
|
||||
|| statement->properties.testFlag(StatementProperty::spOperatorOverloading)
|
||||
|| statement->properties.testFlag(StatementProperty::spDummyStatement)
|
||||
)
|
||||
|
@ -687,6 +688,28 @@ void CodeCompletionPopup::getCompletionFor(
|
|||
addChildren(namespaceStatement, fileName, line, isLambdaReturnType);
|
||||
}
|
||||
}
|
||||
if (scopeStatement->kind == StatementKind::skLambda) {
|
||||
foreach (const QString& phrase, scopeStatement->lambdaCaptures) {
|
||||
if (phrase=="&" || phrase == "=" || phrase =="this")
|
||||
continue;
|
||||
PStatement statement = mParser->findStatementOf(
|
||||
scopeStatement->fileName,
|
||||
phrase,scopeStatement->line);
|
||||
if (statement)
|
||||
addStatement(statement,scopeStatement->fileName, scopeStatement->line);
|
||||
}
|
||||
if (scopeStatement->lambdaCaptures.contains("&")
|
||||
|| scopeStatement->lambdaCaptures.contains("=")) {
|
||||
scopeStatement = scopeStatement->parentScope.lock();
|
||||
continue;
|
||||
} else if (scopeStatement->lambdaCaptures.contains("this")) {
|
||||
do {
|
||||
scopeStatement = scopeStatement->parentScope.lock();
|
||||
} while (scopeStatement && scopeStatement->kind!=StatementKind::skClass);
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
scopeStatement=scopeStatement->parentScope.lock();
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue