aboutsummaryrefslogtreecommitdiffstats
path: root/tests
diff options
context:
space:
mode:
authorSemih Yavuz <semih.yavuz@qt.io>2024-04-30 12:43:11 +0200
committerSemih Yavuz <semih.yavuz@qt.io>2024-05-07 13:35:56 +0200
commit04751e1cf86647554d69c014c2c423f3c6c89ead (patch)
tree406c87d2fd4f0d0426683e216234ee4596bd1a4e /tests
parentdcd948c0bbbef9bd9f01d6b401f466aaaa14ad84 (diff)
qmlls: Add range support for semantic highlighting
Clients might ask only a range of the text document to be highlighted. Then, we should perform highlighting for that particular range. Introduce an optional data member m_range in the highlighting visitor. If m_range has value, then highlight the current item only by checking if it is overlapping with the requested range. Task-number: QTBUG-120000 Change-Id: I635765d3d8831f7717edb96331db414f3813308f Reviewed-by: Sami Shalayel <sami.shalayel@qt.io>
Diffstat (limited to 'tests')
-rw-r--r--tests/auto/qmlls/modules/tst_qmlls_modules.cpp100
-rw-r--r--tests/auto/qmlls/modules/tst_qmlls_modules.h2
-rw-r--r--tests/auto/qmlls/utils/tst_qmlls_highlighting.cpp28
-rw-r--r--tests/auto/qmlls/utils/tst_qmlls_highlighting.h3
4 files changed, 107 insertions, 26 deletions
diff --git a/tests/auto/qmlls/modules/tst_qmlls_modules.cpp b/tests/auto/qmlls/modules/tst_qmlls_modules.cpp
index 717b61cc28..6b9eb87d7d 100644
--- a/tests/auto/qmlls/modules/tst_qmlls_modules.cpp
+++ b/tests/auto/qmlls/modules/tst_qmlls_modules.cpp
@@ -1495,6 +1495,31 @@ void tst_qmlls_modules::quickFixes()
QTRY_VERIFY_WITH_TIMEOUT(codeActionOk, 5000);
}
+static QQmlJS::Dom::DomItem fileObject(const QString &filePath)
+{
+ QFile f(filePath);
+ DomItem file;
+ if (!f.open(QIODevice::ReadOnly))
+ return file;
+ QString code = f.readAll();
+ QQmlJS::Dom::DomCreationOptions options;
+ options.setFlag(QQmlJS::Dom::DomCreationOption::WithScriptExpressions);
+ options.setFlag(QQmlJS::Dom::DomCreationOption::WithSemanticAnalysis);
+ options.setFlag(QQmlJS::Dom::DomCreationOption::WithRecovery);
+
+ QStringList dirs = {QLibraryInfo::path(QLibraryInfo::Qml2ImportsPath)};
+ auto envPtr = QQmlJS::Dom::DomEnvironment::create(dirs,
+ QQmlJS::Dom::DomEnvironment::Option::SingleThreaded
+ | QQmlJS::Dom::DomEnvironment::Option::NoDependencies, options);
+ envPtr->loadBuiltins();
+ envPtr->loadFile(QQmlJS::Dom::FileToLoad::fromMemory(envPtr, filePath, code),
+ [&file](QQmlJS::Dom::Path, const QQmlJS::Dom::DomItem &, const QQmlJS::Dom::DomItem &newIt) {
+ file = newIt.fileObject();
+ });
+ envPtr->loadPendingDependencies();
+ return file;
+};
+
void tst_qmlls_modules::semanticHighlightingFull_data()
{
QTest::addColumn<QString>("filePath");
@@ -1504,39 +1529,63 @@ void tst_qmlls_modules::semanticHighlightingFull_data()
void tst_qmlls_modules::semanticHighlightingFull()
{
QFETCH(QString, filePath);
+ const auto item = fileObject(testFile(filePath));
+ Highlights highlights;
+ const auto expectedData = highlights.collectTokens(item, std::nullopt);
- const auto fileObject = [](const QString &filePath){
- QFile f(filePath);
- DomItem file;
- if (!f.open(QIODevice::ReadOnly))
- return file;
- QString code = f.readAll();
- QQmlJS::Dom::DomCreationOptions options;
- options.setFlag(QQmlJS::Dom::DomCreationOption::WithScriptExpressions);
- options.setFlag(QQmlJS::Dom::DomCreationOption::WithSemanticAnalysis);
- options.setFlag(QQmlJS::Dom::DomCreationOption::WithRecovery);
-
- QStringList dirs = {QLibraryInfo::path(QLibraryInfo::Qml2ImportsPath)};
- auto envPtr = QQmlJS::Dom::DomEnvironment::create(dirs,
- QQmlJS::Dom::DomEnvironment::Option::SingleThreaded
- | QQmlJS::Dom::DomEnvironment::Option::NoDependencies, options);
- envPtr->loadBuiltins();
- envPtr->loadFile(QQmlJS::Dom::FileToLoad::fromMemory(envPtr, filePath, code),
- [&file](QQmlJS::Dom::Path, const QQmlJS::Dom::DomItem &, const QQmlJS::Dom::DomItem &newIt) {
- file = newIt.fileObject();
- });
- envPtr->loadPendingDependencies();
- return file;
+ const auto uri = openFile(filePath);
+ QVERIFY(uri);
+ QLspSpecification::SemanticTokensParams params;
+ params.textDocument.uri = *uri;
+ std::shared_ptr<bool> didFinish = std::make_shared<bool>(false);
+ const auto cleanup = [didFinish]() { *didFinish = true; };
+
+ auto &&responseHandler = [&](auto res) {
+ QScopeGuard callAtExit(cleanup);
+ const auto *const result = std::get_if<QLspSpecification::SemanticTokens>(&res);
+ QVERIFY(result);
+ QList<int> data = result->data;
+ QCOMPARE(data.size(), expectedData.size());
+ QCOMPARE(data, expectedData);
};
+ auto &&errorHandler = [&](auto &error) {
+ QScopeGuard callAtExit(cleanup);
+ ProtocolBase::defaultResponseErrorHandler(error);
+ QVERIFY2(false, "error occurred on full semantic tokens");
+ };
+
+ m_protocol->requestSemanticTokens(params, std::move(responseHandler), std::move(errorHandler));
+ QTRY_VERIFY_WITH_TIMEOUT(*didFinish, 10000);
+}
+
+void tst_qmlls_modules::semanticHighlightingRange_data()
+{
+ QTest::addColumn<QString>("filePath");
+ QTest::addColumn<QLspSpecification::Range>("range");
+ QTest::addRow("bigfile") << u"highlighting/bigFile.qml"_s
+ << QLspSpecification::Range{ { 6, 0 }, { 15, 0 } };
+}
+
+void tst_qmlls_modules::semanticHighlightingRange()
+{
+ QFETCH(QString, filePath);
+ QFETCH(QLspSpecification::Range, range);
+
const auto item = fileObject(testFile(filePath));
Highlights highlights;
- const auto expectedData = highlights.collectTokens(item);
+ const auto qmlFile = item.as<QQmlJS::Dom::QmlFile>();
+ const auto code = qmlFile->code();
+ const int startOffset = int(QQmlLSUtils::textOffsetFrom(code, range.start.line, range.end.character));
+ const int endOffset = int(QQmlLSUtils::textOffsetFrom(code, range.end.line, range.end.character));
+ const auto expectedData = highlights.collectTokens(item, HighlightsRange{startOffset, endOffset});
const auto uri = openFile(filePath);
QVERIFY(uri);
- QLspSpecification::SemanticTokensParams params;
+ QLspSpecification::SemanticTokensRangeParams params;
params.textDocument.uri = *uri;
+ params.range = range;
+
std::shared_ptr<bool> didFinish = std::make_shared<bool>(false);
const auto cleanup = [didFinish]() { *didFinish = true; };
@@ -1555,7 +1604,8 @@ void tst_qmlls_modules::semanticHighlightingFull()
QVERIFY2(false, "error occurred on full semantic tokens");
};
- m_protocol->requestSemanticTokens(params, std::move(responseHandler), std::move(errorHandler));
+ m_protocol->requestSemanticTokensRange(params, std::move(responseHandler),
+ std::move(errorHandler));
QTRY_VERIFY_WITH_TIMEOUT(*didFinish, 10000);
}
diff --git a/tests/auto/qmlls/modules/tst_qmlls_modules.h b/tests/auto/qmlls/modules/tst_qmlls_modules.h
index 5ffbce6c5b..aa6263ccc6 100644
--- a/tests/auto/qmlls/modules/tst_qmlls_modules.h
+++ b/tests/auto/qmlls/modules/tst_qmlls_modules.h
@@ -71,6 +71,8 @@ private slots:
void checkQuickSnippets();
void semanticHighlightingFull_data();
void semanticHighlightingFull();
+ void semanticHighlightingRange_data();
+ void semanticHighlightingRange();
private:
QProcess m_server;
diff --git a/tests/auto/qmlls/utils/tst_qmlls_highlighting.cpp b/tests/auto/qmlls/utils/tst_qmlls_highlighting.cpp
index 203f8a8390..fe5d83c53d 100644
--- a/tests/auto/qmlls/utils/tst_qmlls_highlighting.cpp
+++ b/tests/auto/qmlls/utils/tst_qmlls_highlighting.cpp
@@ -501,7 +501,7 @@ void tst_qmlls_highlighting::highlights()
QFETCH(Token, expectedHighlightedToken);
Highlights h;
- HighlightingVisitor hv(h);
+ HighlightingVisitor hv(h, std::nullopt);
fileItem.visitTree(QQmlJS::Dom::Path(), hv, VisitOption::Default, emptyChildrenVisitor,
emptyChildrenVisitor);
@@ -513,4 +513,30 @@ void tst_qmlls_highlighting::highlights()
QCOMPARE(highlights.value(expectedHighlightedToken.offset), expectedHighlightedToken);
}
+void tst_qmlls_highlighting::rangeOverlapsWithSourceLocation_data()
+{
+ QTest::addColumn<QQmlJS::SourceLocation>("sourceLocation");
+ QTest::addColumn<HighlightsRange>("range");
+ QTest::addColumn<bool>("overlaps");
+
+ QTest::addRow("sl-inside-range")
+ << QQmlJS::SourceLocation(5, 1, 1, 1) << HighlightsRange{ 0, 100 } << true;
+ QTest::addRow("sl-exceeds-rightBoundRange")
+ << QQmlJS::SourceLocation(5, 1000, 1, 1) << HighlightsRange{ 0, 100 } << true;
+ QTest::addRow("sl-exceeds-leftRightBoundRange")
+ << QQmlJS::SourceLocation(5, 1000, 1, 1) << HighlightsRange{ 8, 100 } << true;
+ QTest::addRow("sl-exceeds-leftBoundRange")
+ << QQmlJS::SourceLocation(5, 100, 1, 1) << HighlightsRange{ 8, 1000 } << true;
+ QTest::addRow("no-overlaps") << QQmlJS::SourceLocation(5, 100, 1, 1)
+ << HighlightsRange{ 8000, 100000 } << false;
+}
+
+void tst_qmlls_highlighting::rangeOverlapsWithSourceLocation()
+{
+ QFETCH(QQmlJS::SourceLocation, sourceLocation);
+ QFETCH(HighlightsRange, range);
+ QFETCH(bool, overlaps);
+ QVERIFY(overlaps == HighlightingUtils::rangeOverlapsWithSourceLocation(sourceLocation, range));
+}
+
QTEST_MAIN(tst_qmlls_highlighting)
diff --git a/tests/auto/qmlls/utils/tst_qmlls_highlighting.h b/tests/auto/qmlls/utils/tst_qmlls_highlighting.h
index 7e6c6431ac..f9d2b24afe 100644
--- a/tests/auto/qmlls/utils/tst_qmlls_highlighting.h
+++ b/tests/auto/qmlls/utils/tst_qmlls_highlighting.h
@@ -22,6 +22,9 @@ private slots:
void highlights_data();
void highlights();
+ void rangeOverlapsWithSourceLocation_data();
+ void rangeOverlapsWithSourceLocation();
+
private:
QString m_highlightingDataDir;
};