qmlls: auto completion for inside for each statements
Save the source location of the parenthesis and the `in` or `of` token. With these locations, provide support for for..in and for..of statements. Task-number: QTBUG-117445 Change-Id: I642e252caa5e8fc9152bcd233d14ce4680e41e32 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io> Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
This commit is contained in:
parent
9776460553
commit
aada41a2f1
|
@ -2157,6 +2157,9 @@ void QQmlDomAstCreator::endVisit(AST::ForEachStatement *exp)
|
|||
return;
|
||||
|
||||
auto current = makeGenericScriptElement(exp, DomType::ScriptForEachStatement);
|
||||
current->addLocation(FileLocationRegion::InOfTokenRegion, exp->inOfToken);
|
||||
current->addLocation(FileLocationRegion::LeftParenthesisRegion, exp->lparenToken);
|
||||
current->addLocation(FileLocationRegion::RightParenthesisRegion, exp->rparenToken);
|
||||
|
||||
if (exp->statement) {
|
||||
Q_SCRIPTELEMENT_EXIT_IF(scriptNodeStack.isEmpty());
|
||||
|
|
|
@ -2757,6 +2757,33 @@ static QList<CompletionItem> insideDoWhileStatement(const DomItem ¤tItem,
|
|||
return {};
|
||||
}
|
||||
|
||||
static QList<CompletionItem> insideForEachStatement(const DomItem ¤tItem,
|
||||
const CompletionContextStrings &ctx)
|
||||
{
|
||||
const auto regions = FileLocations::treeOf(currentItem)->info().regions;
|
||||
|
||||
const QQmlJS::SourceLocation inOf = regions[InOfTokenRegion];
|
||||
const QQmlJS::SourceLocation leftParenthesis = regions[LeftParenthesisRegion];
|
||||
const QQmlJS::SourceLocation rightParenthesis = regions[RightParenthesisRegion];
|
||||
|
||||
if (betweenLocations(leftParenthesis, ctx, inOf)) {
|
||||
QList<CompletionItem> res;
|
||||
res << QQmlLSUtils::scriptIdentifierCompletion(currentItem, ctx)
|
||||
<< QQmlLSUtils::suggestVariableDeclarationStatementCompletion();
|
||||
return res;
|
||||
}
|
||||
if (betweenLocations(inOf, ctx, rightParenthesis)) {
|
||||
const QList<CompletionItem> res = QQmlLSUtils::scriptIdentifierCompletion(currentItem, ctx);
|
||||
return res;
|
||||
}
|
||||
|
||||
if (afterLocation(rightParenthesis, ctx)) {
|
||||
return QQmlLSUtils::suggestJSStatementCompletion(currentItem);
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
QList<CompletionItem> QQmlLSUtils::completions(const DomItem ¤tItem,
|
||||
const CompletionContextStrings &ctx)
|
||||
{
|
||||
|
@ -2828,6 +2855,8 @@ QList<CompletionItem> QQmlLSUtils::completions(const DomItem ¤tItem,
|
|||
return insideWhileStatement(currentParent, ctx);
|
||||
case DomType::ScriptDoWhileStatement:
|
||||
return insideDoWhileStatement(currentParent, ctx);
|
||||
case DomType::ScriptForEachStatement:
|
||||
return insideForEachStatement(currentParent, ctx);
|
||||
|
||||
// TODO: Implement those statements.
|
||||
// In the meanwhile, suppress completions to avoid weird behaviors.
|
||||
|
@ -2844,7 +2873,6 @@ QList<CompletionItem> QQmlLSUtils::completions(const DomItem ¤tItem,
|
|||
case DomType::ScriptCaseClauses:
|
||||
case DomType::ScriptCaseClause:
|
||||
case DomType::ScriptDefaultClause:
|
||||
case DomType::ScriptForEachStatement:
|
||||
return {};
|
||||
|
||||
default:
|
||||
|
|
|
@ -130,4 +130,8 @@ Zzz {
|
|||
function helloDoWhileStatement(hello) {
|
||||
do --hello; while (hello);
|
||||
}
|
||||
function helloForEachStatement(hello) {
|
||||
for(variable in hello) ++hello;
|
||||
for(element of hello) ++hello;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2440,6 +2440,84 @@ void tst_qmlls_utils::completions_data()
|
|||
<< ExpectedCompletions{ { u"hello"_s, CompletionItemKind::Variable },
|
||||
{ letStatementCompletion, CompletionItemKind::Snippet } }
|
||||
<< QStringList{ propertyCompletion } << None;
|
||||
|
||||
QTest::newRow("forInStatementLet")
|
||||
<< file << 134 << 13
|
||||
<< ExpectedCompletions{
|
||||
{ letStatementCompletion, CompletionItemKind::Snippet },
|
||||
{ constStatementCompletion, CompletionItemKind::Snippet },
|
||||
{ varStatementCompletion, CompletionItemKind::Snippet },
|
||||
{ u"helloJSStatements"_s, CompletionItemKind::Method }
|
||||
}
|
||||
<< QStringList{
|
||||
u"property"_s,
|
||||
u"readonly"_s,
|
||||
u"required"_s,
|
||||
forStatementCompletion,
|
||||
ifStatementCompletion,
|
||||
} << None;
|
||||
|
||||
QTest::newRow("forOfStatementLet")
|
||||
<< file << 135 << 13
|
||||
<< ExpectedCompletions{
|
||||
{ letStatementCompletion, CompletionItemKind::Snippet },
|
||||
{ constStatementCompletion, CompletionItemKind::Snippet },
|
||||
{ varStatementCompletion, CompletionItemKind::Snippet },
|
||||
{ u"helloJSStatements"_s, CompletionItemKind::Method }
|
||||
}
|
||||
<< QStringList{
|
||||
u"property"_s,
|
||||
u"readonly"_s,
|
||||
u"required"_s,
|
||||
forStatementCompletion,
|
||||
ifStatementCompletion,
|
||||
} << None;
|
||||
|
||||
QTest::newRow("forInStatementTarget")
|
||||
<< file << 134 << 25
|
||||
<< ExpectedCompletions{
|
||||
{ u"helloJSStatements"_s, CompletionItemKind::Method },
|
||||
{ u"hello"_s, CompletionItemKind::Variable },
|
||||
}
|
||||
<< QStringList{ u"property"_s, u"readonly"_s, u"required"_s,
|
||||
forStatementCompletion, ifStatementCompletion, varStatementCompletion,
|
||||
letStatementCompletion, constStatementCompletion, }
|
||||
<< None;
|
||||
|
||||
QTest::newRow("forOfStatementTarget")
|
||||
<< file << 135 << 24
|
||||
<< ExpectedCompletions{
|
||||
{ u"helloJSStatements"_s, CompletionItemKind::Method },
|
||||
{ u"hello"_s, CompletionItemKind::Variable },
|
||||
}
|
||||
<< QStringList{ u"property"_s, u"readonly"_s, u"required"_s,
|
||||
forStatementCompletion, ifStatementCompletion, varStatementCompletion,
|
||||
letStatementCompletion, constStatementCompletion, }
|
||||
<< None;
|
||||
|
||||
QTest::newRow("forInStatementConsequence")
|
||||
<< file << 134 << 31
|
||||
<< ExpectedCompletions{ { letStatementCompletion, CompletionItemKind::Snippet },
|
||||
{ constStatementCompletion, CompletionItemKind:: Snippet },
|
||||
{ varStatementCompletion, CompletionItemKind::Snippet },
|
||||
{ u"helloJSStatements"_s, CompletionItemKind::Method },
|
||||
{ u"hello"_s, CompletionItemKind::Variable },
|
||||
{ forStatementCompletion, CompletionItemKind::Snippet }
|
||||
}
|
||||
<< QStringList{ propertyCompletion }
|
||||
<< None;
|
||||
|
||||
QTest::newRow("forOfStatementConsequence")
|
||||
<< file << 135 << 33
|
||||
<< ExpectedCompletions{ { letStatementCompletion, CompletionItemKind::Snippet },
|
||||
{ constStatementCompletion, CompletionItemKind:: Snippet },
|
||||
{ varStatementCompletion, CompletionItemKind::Snippet },
|
||||
{ u"helloJSStatements"_s, CompletionItemKind::Method },
|
||||
{ u"hello"_s, CompletionItemKind::Variable },
|
||||
{ forStatementCompletion, CompletionItemKind::Snippet }
|
||||
}
|
||||
<< QStringList{ propertyCompletion }
|
||||
<< None;
|
||||
}
|
||||
|
||||
void tst_qmlls_utils::completions()
|
||||
|
|
Loading…
Reference in New Issue