From 055859f93f6f0090a456c813f5b4931b25172aea Mon Sep 17 00:00:00 2001 From: Sami Shalayel Date: Tue, 8 Aug 2023 17:36:12 +0200 Subject: qmlls: highlight names inside of inline component definitions Instead of highlighting the base type of the inline component, highlight the name of the inline component, e.g. highlight 'C' in ``` component C: Item {} ``` instead of 'Item'. This requires changing QQmlLSUtils::findTypeDefinitionOf's signature to return a QQmlLSUtilsLocation instead of a DomItem. QQmlLSUtils::findDefinitionOf already returns a QQmlLSUtilsLocation. Also, the QQmlJS::UiInlineComponent parser class did not know about its identifier token. Add it, so the corresponding DomItem knows where its identifier lies. Fix the tests that finds definitions of inline components by removing the QEXPECT_FAIL and adjusting the column numbers. Also simplify the test by removing the "name" that is not related to the actual test. Fix other failing tests by setting their QEXPECT_FAIL at the right place (they fail earlier because of this change, when looking for the type definition of int for example). Change-Id: I00b2f73c2357b7e7fb74619bbc7b948e67619420 Reviewed-by: Fabian Kosmale --- src/qml/parser/qqmljs.g | 1 + src/qml/parser/qqmljsast_p.h | 1 + src/qmldom/qqmldomastcreator.cpp | 1 + src/qmlls/qqmlgototypedefinitionsupport.cpp | 22 +--- src/qmlls/qqmllsutils.cpp | 81 ++++++++++----- src/qmlls/qqmllsutils_p.h | 2 +- tests/auto/qmlls/utils/tst_qmlls_utils.cpp | 149 +++++++++++----------------- 7 files changed, 122 insertions(+), 135 deletions(-) diff --git a/src/qml/parser/qqmljs.g b/src/qml/parser/qqmljs.g index 9a10015cbc..902e8290b4 100644 --- a/src/qml/parser/qqmljs.g +++ b/src/qml/parser/qqmljs.g @@ -1494,6 +1494,7 @@ UiObjectMember: T_COMPONENT T_IDENTIFIER T_COLON UiObjectDefinition; } auto inlineComponent = new (pool) AST::UiInlineComponent(stringRef(2), sym(4).UiObjectDefinition); inlineComponent->componentToken = loc(1); + inlineComponent->identifierToken = loc(2); sym(1).Node = inlineComponent; } break; ./ diff --git a/src/qml/parser/qqmljsast_p.h b/src/qml/parser/qqmljsast_p.h index 5f718c4c62..494fca9e28 100644 --- a/src/qml/parser/qqmljsast_p.h +++ b/src/qml/parser/qqmljsast_p.h @@ -3538,6 +3538,7 @@ public: QStringView name; UiObjectDefinition* component; SourceLocation componentToken; + SourceLocation identifierToken; }; class QML_PARSER_EXPORT UiSourceElement: public UiObjectMember diff --git a/src/qmldom/qqmldomastcreator.cpp b/src/qmldom/qqmldomastcreator.cpp index 54b72e4d1f..06f380b63f 100644 --- a/src/qmldom/qqmldomastcreator.cpp +++ b/src/qmldom/qqmldomastcreator.cpp @@ -1111,6 +1111,7 @@ bool QQmlDomAstCreator::visit(AST::UiInlineComponent *el) Path p = qmlFilePtr->addComponent(QmlComponent(cName), AddOption::KeepExisting, &compPtr); pushEl(p, *compPtr, el); FileLocations::addRegion(nodeStack.last().fileLocations, u"component", el->componentToken); + FileLocations::addRegion(nodeStack.last().fileLocations, u"identifier", el->identifierToken); loadAnnotations(el); return true; } diff --git a/src/qmlls/qqmlgototypedefinitionsupport.cpp b/src/qmlls/qqmlgototypedefinitionsupport.cpp index 7e2a123af2..d8a0277a62 100644 --- a/src/qmlls/qqmlgototypedefinitionsupport.cpp +++ b/src/qmlls/qqmlgototypedefinitionsupport.cpp @@ -48,28 +48,14 @@ void QmlGoToTypeDefinitionSupport::process(RequestPointerArgument request) QQmlLSUtilsItemLocation &front = std::get>(itemsFound).front(); - QQmlJS::Dom::DomItem base = QQmlLSUtils::findTypeDefinitionOf(front.domItem); - if (base.domKind() == QQmlJS::Dom::DomKind::Empty) { - qWarning() << u"Could not obtain the type definition, was the type correctly resolved?"_s - << u"\n Obtained type was:\n"_s << base.toString() - << u"\nbut selected item was:\n" - << front.domItem.toString(); - return; - } + auto base = QQmlLSUtils::findTypeDefinitionOf(front.domItem); - if (base.domKind() == QQmlJS::Dom::DomKind::Empty) { + if (!base) { qDebug() << u"Could not obtain the base from the item"_s; return; } - auto locationInfo = QQmlJS::Dom::FileLocations::fileLocationsOf(base); - if (!locationInfo) { - qDebug() - << u"Could not obtain the text location from the base item, was it correctly resolved?\nBase was "_s - << base.toString(); - return; - } - QQmlJS::Dom::DomItem fileOfBase = base.containingFile(); + QQmlJS::Dom::DomItem fileOfBase = front.domItem.goToFile(base->filename); auto fileOfBasePtr = fileOfBase.ownerAs(); if (!fileOfBasePtr) { qDebug() << u"Could not obtain the file of the base."_s; @@ -80,7 +66,7 @@ void QmlGoToTypeDefinitionSupport::process(RequestPointerArgument request) l.uri = QUrl::fromLocalFile(fileOfBasePtr->canonicalFilePath()).toEncoded(); const QString qmlCode = fileOfBasePtr->code(); - l.range = QQmlLSUtils::qmlLocationToLspLocation(qmlCode, locationInfo->fullRegion); + l.range = QQmlLSUtils::qmlLocationToLspLocation(qmlCode, base->sourceLocation); results.append(l); } diff --git a/src/qmlls/qqmllsutils.cpp b/src/qmlls/qqmllsutils.cpp index 6bb3ceeb7b..2a93000bd4 100644 --- a/src/qmlls/qqmllsutils.cpp +++ b/src/qmlls/qqmllsutils.cpp @@ -289,29 +289,48 @@ DomItem QQmlLSUtils::baseObject(DomItem object) return base; } +static std::optional locationFromDomItem(DomItem &item, + const QString ®ionName = QString()) +{ + QQmlLSUtilsLocation location; + location.filename = item.canonicalFilePath(); + + auto tree = FileLocations::treeOf(item); + // tree is null for C++ defined types, for example + if (!tree) + return {}; + + auto info = tree->info(); + if (!regionName.isEmpty() && info.regions.contains(regionName)) { + location.sourceLocation = info.regions[regionName]; + } else { + location.sourceLocation = info.fullRegion; + } + return location; +} + /*! \internal - \brief Extracts the QML object type of an \l DomItem. - - For a \c PropertyDefinition, return the type of the property. - For a \c Binding, return the bound item's type if an QmlObject is bound, and otherwise the type - of the property. - For a \c QmlObject, do nothing and return it. - For an \c Id, return the object to - which the id resolves. - For a \c Methodparameter, return the type of the parameter. = - Otherwise, return an empty item. + \brief Returns the location of the type definition pointed by object. + + For a \c PropertyDefinition, return the location of the type of the property. + For a \c Binding, return the bound item's type location if an QmlObject is bound, and otherwise + the type of the property. + For a \c QmlObject, return the location of the QmlObject's base. + For an \c Id, return the location of the object to which the id resolves. + For a \c Methodparameter, return the location of the type of the parameter. + Otherwise, return std::nullopt. */ -DomItem QQmlLSUtils::findTypeDefinitionOf(DomItem object) +std::optional QQmlLSUtils::findTypeDefinitionOf(DomItem object) { - DomItem result; + DomItem typeDefinition; switch (object.internalKind()) { case QQmlJS::Dom::DomType::QmlComponent: - result = object.field(Fields::objects).index(0); + typeDefinition = object.field(Fields::objects).index(0); break; case QQmlJS::Dom::DomType::QmlObject: - result = baseObject(object); + typeDefinition = baseObject(object); break; case QQmlJS::Dom::DomType::Binding: { auto binding = object.as(); @@ -319,7 +338,8 @@ DomItem QQmlLSUtils::findTypeDefinitionOf(DomItem object) // try to grab the type from the bound object if (binding->valueKind() == BindingValueKind::Object) { - result = baseObject(object.field(Fields::value)); + typeDefinition = baseObject(object.field(Fields::value)); + break; } else { // use the type of the property it is bound on for scriptexpression etc. DomItem propertyDefinition; @@ -334,17 +354,18 @@ DomItem QQmlLSUtils::findTypeDefinitionOf(DomItem object) return true; }, LookupType::PropertyDef); - result = propertyDefinition.field(Fields::type).proceedToScope(); + typeDefinition = propertyDefinition.field(Fields::type).proceedToScope(); + break; } - break; + Q_UNREACHABLE(); } case QQmlJS::Dom::DomType::Id: - result = object.field(Fields::referredObject).proceedToScope(); + typeDefinition = object.field(Fields::referredObject).proceedToScope(); break; case QQmlJS::Dom::DomType::PropertyDefinition: case QQmlJS::Dom::DomType::MethodParameter: case QQmlJS::Dom::DomType::MethodInfo: - result = object.field(Fields::type).proceedToScope(); + typeDefinition = object.field(Fields::type).proceedToScope(); break; case QQmlJS::Dom::DomType::ScriptIdentifierExpression: { if (object.directParent().internalKind() == DomType::ScriptType) { @@ -353,26 +374,34 @@ DomItem QQmlLSUtils::findTypeDefinitionOf(DomItem object) FilterUpOptions::ReturnOuter); const QString name = type.field(Fields::typeName).value().toString(); - result = object.path(Paths::lookupTypePath(name)); + typeDefinition = object.path(Paths::lookupTypePath(name)); break; } + auto scope = QQmlLSUtils::resolveExpressionType( object, QQmlLSUtilsResolveOptions::ResolveActualTypeForFieldMemberExpression); if (!scope) return {}; - return QQmlLSUtils::sourceLocationToDomItem(object.containingFile(), - scope->semanticScope->sourceLocation()); + typeDefinition = QQmlLSUtils::sourceLocationToDomItem( + object.containingFile(), scope->semanticScope->sourceLocation()); + + switch (scope->type) { + case QmlObjectIdIdentifier: + break; + default: + typeDefinition = typeDefinition.component(); + } + + return locationFromDomItem(typeDefinition, u"identifier"_s); } - case QQmlJS::Dom::DomType::Empty: - break; default: qDebug() << "QQmlLSUtils::findTypeDefinitionOf: Found unimplemented Type" << object.internalKindStr(); - result = {}; + return {}; } - return result; + return locationFromDomItem(typeDefinition); } static DomItem findJSIdentifierDefinition(DomItem item, const QString &name) diff --git a/src/qmlls/qqmllsutils_p.h b/src/qmlls/qqmllsutils_p.h index e74021c23d..c83e889870 100644 --- a/src/qmlls/qqmllsutils_p.h +++ b/src/qmlls/qqmllsutils_p.h @@ -126,7 +126,7 @@ public: static QLspSpecification::Range qmlLocationToLspLocation(const QString &code, QQmlJS::SourceLocation qmlLocation); static QQmlJS::Dom::DomItem baseObject(QQmlJS::Dom::DomItem qmlObject); - static QQmlJS::Dom::DomItem findTypeDefinitionOf(QQmlJS::Dom::DomItem item); + static std::optional findTypeDefinitionOf(QQmlJS::Dom::DomItem item); static std::optional findDefinitionOf(QQmlJS::Dom::DomItem item); static QList findUsagesOf(QQmlJS::Dom::DomItem item); diff --git a/tests/auto/qmlls/utils/tst_qmlls_utils.cpp b/tests/auto/qmlls/utils/tst_qmlls_utils.cpp index 6eecda6a11..166689e2b5 100644 --- a/tests/auto/qmlls/utils/tst_qmlls_utils.cpp +++ b/tests/auto/qmlls/utils/tst_qmlls_utils.cpp @@ -299,7 +299,6 @@ void tst_qmlls_utils::findTypeDefinitionFromLocation_data() // item to be checked against QTest::addColumn("resultIndex"); QTest::addColumn("expectedItemsCount"); - QTest::addColumn("expectedTypeName"); QTest::addColumn("expectedFilePath"); // set to -1 when unchanged from above line and character. 0-based. QTest::addColumn("expectedLine"); @@ -309,80 +308,74 @@ void tst_qmlls_utils::findTypeDefinitionFromLocation_data() const QString TypeQml = testFile(u"Type.qml"_s); // pass this as file when no result is expected, e.g. for type definition of "var". - QTest::addRow("onCProperty") << file1Qml << 11 << 16 << firstResult << outOfOne << "file1.C" - << file1Qml << 7 << positionAfterOneIndent; + QTest::addRow("onCProperty") << file1Qml << 11 << 16 << firstResult << outOfOne << file1Qml << 7 + << positionAfterOneIndent; - QTest::addRow("onCProperty2") << file1Qml << 28 << 37 << firstResult << outOfOne << "file1.C" - << file1Qml << 7 << positionAfterOneIndent; + QTest::addRow("onCProperty2") << file1Qml << 28 << 37 << firstResult << outOfOne << file1Qml + << 7 << positionAfterOneIndent; - QTest::addRow("onCProperty3") << file1Qml << 28 << 35 << firstResult << outOfOne << "file1.C" - << file1Qml << 7 << positionAfterOneIndent; + QTest::addRow("onCProperty3") << file1Qml << 28 << 35 << firstResult << outOfOne << file1Qml + << 7 << positionAfterOneIndent; - QTest::addRow("onCBinding") << file1Qml << 46 << 8 << firstResult << outOfOne << "file1.C" - << file1Qml << 7 << positionAfterOneIndent; + QTest::addRow("onCBinding") << file1Qml << 46 << 8 << firstResult << outOfOne << file1Qml << 7 + << positionAfterOneIndent; - QTest::addRow("onDefaultBinding") - << file1Qml << 16 << positionAfterOneIndent << firstResult << outOfOne << "file1.C" - << file1Qml << 7 << positionAfterOneIndent; + QTest::addRow("onDefaultBinding") << file1Qml << 16 << positionAfterOneIndent << firstResult + << outOfOne << file1Qml << 7 << positionAfterOneIndent; QTest::addRow("onDefaultBindingId") - << file1Qml << 16 << 28 << firstResult << outOfOne << "firstD" << file1Qml << 16 << 20; + << file1Qml << 16 << 28 << firstResult << outOfOne << file1Qml << 16 << 20; - QTest::addRow("findIntProperty") << file1Qml << 9 << 18 << firstResult << outOfOne << u"int"_s - << file1Qml << -1 << positionAfterOneIndent; - - QTest::addRow("colorBinding") << file1Qml << 39 << 8 << firstResult << outOfOne << u"QColor"_s - << file1Qml << -1 << positionAfterOneIndent; + QTest::addRow("findIntProperty") << file1Qml << 9 << 18 << firstResult << outOfOne << file1Qml + << -1 << positionAfterOneIndent; + QTest::addRow("colorBinding") << file1Qml << 39 << 8 << firstResult << outOfOne << file1Qml + << -1 << positionAfterOneIndent; // check what happens between items (it should not crash) - QTest::addRow("onWhitespaceBeforeC") << file1Qml << 16 << 1 << firstResult << outOfOne - << noResultExpected << noResultExpected << -1 << -1; + QTest::addRow("onWhitespaceBeforeC") + << file1Qml << 16 << 1 << firstResult << outOfOne << noResultExpected << -1 << -1; - QTest::addRow("onWhitespaceAfterC") << file1Qml << 17 << 23 << firstResult << outOfOne - << noResultExpected << noResultExpected << -1 << -1; + QTest::addRow("onWhitespaceAfterC") + << file1Qml << 17 << 23 << firstResult << outOfOne << noResultExpected << -1 << -1; - QTest::addRow("onWhitespaceBetweenCAndD") << file1Qml << 17 << 24 << firstResult << outOfOne - << noResultExpected << noResultExpected << -1 << -1; + QTest::addRow("onWhitespaceBetweenCAndD") + << file1Qml << 17 << 24 << firstResult << outOfOne << noResultExpected << -1 << -1; - QTest::addRow("ic") << file1Qml << 15 << 15 << firstResult << outOfOne << u"icid"_s << file1Qml - << -1 << 18; - QTest::addRow("icBase") << file1Qml << 15 << 20 << firstResult << outOfOne << u"QQuickItem"_s + QTest::addRow("ic") << file1Qml << 15 << 15 << firstResult << outOfOne << file1Qml << -1 << 18; + QTest::addRow("icBase") << file1Qml << 15 << 20 << firstResult << outOfOne << u"TODO: file location for C++ defined types?"_s << -1 << -1; - QTest::addRow("ic3") << file1Qml << 15 << 33 << firstResult << outOfOne << u"icid"_s << file1Qml - << -1 << 18; + QTest::addRow("ic3") << file1Qml << 15 << 33 << firstResult << outOfOne << file1Qml << -1 << 18; // TODO: type definition of function = type definition of return type? // if not, this might need fixing: // currently, asking the type definition of the "function" keyword returns // the type definitin of the return type (when available). - QTest::addRow("function-keyword") << file1Qml << 33 << 5 << firstResult << outOfOne - << u"file1.C"_s << file1Qml << 7 << positionAfterOneIndent; + QTest::addRow("function-keyword") << file1Qml << 33 << 5 << firstResult << outOfOne << file1Qml + << 7 << positionAfterOneIndent; QTest::addRow("function-parameter-builtin") - << file1Qml << 33 << 20 << firstResult << outOfOne << "a" << file1Qml << -1 << -1; - QTest::addRow("function-parameter-item") - << file1Qml << 33 << 36 << firstResult << outOfOne << "file1.C" << file1Qml << 7 - << positionAfterOneIndent; + << file1Qml << 33 << 20 << firstResult << outOfOne << file1Qml << -1 << -1; + QTest::addRow("function-parameter-item") << file1Qml << 33 << 36 << firstResult << outOfOne + << file1Qml << 7 << positionAfterOneIndent; - QTest::addRow("function-return") << file1Qml << 33 << 41 << firstResult << outOfOne << "file1.C" - << file1Qml << 7 << positionAfterOneIndent; + QTest::addRow("function-return") << file1Qml << 33 << 41 << firstResult << outOfOne << file1Qml + << 7 << positionAfterOneIndent; - QTest::addRow("void-function") << file1Qml << 36 << 17 << firstResult << outOfOne << "void" - << noResultExpected << -1 << -1; + QTest::addRow("void-function") + << file1Qml << 36 << 17 << firstResult << outOfOne << noResultExpected << -1 << -1; - QTest::addRow("rectangle-property") - << file1Qml << 44 << 31 << firstResult << outOfOne << "QQuickRectangle" - << "TODO: c++ type location" << -1 << -1; + QTest::addRow("rectangle-property") << file1Qml << 44 << 31 << firstResult << outOfOne + << "TODO: c++ type location" << -1 << -1; QTest::addRow("functionParameterICUsage") - << file1Qml << 34 << 16 << firstResult << outOfOne << "file1.C" << file1Qml << 7 << 18; + << file1Qml << 34 << 16 << firstResult << outOfOne << file1Qml << 7 << 15; QTest::addRow("ICBindingUsage") - << file1Qml << 47 << 21 << firstResult << outOfOne << "file1.C" << file1Qml << 7 << 18; + << file1Qml << 47 << 21 << firstResult << outOfOne << file1Qml << 7 << 15; QTest::addRow("ICBindingUsage2") - << file1Qml << 49 << 11 << firstResult << outOfOne << "file1.C" << file1Qml << 7 << 18; + << file1Qml << 49 << 11 << firstResult << outOfOne << file1Qml << 7 << 15; QTest::addRow("ICBindingUsage3") - << file1Qml << 52 << 17 << firstResult << outOfOne << "file1.C" << file1Qml << 7 << 18; + << file1Qml << 52 << 17 << firstResult << outOfOne << file1Qml << 7 << 15; } void tst_qmlls_utils::findTypeDefinitionFromLocation() @@ -392,7 +385,6 @@ void tst_qmlls_utils::findTypeDefinitionFromLocation() QFETCH(int, character); QFETCH(int, resultIndex); QFETCH(int, expectedItemsCount); - QFETCH(QString, expectedTypeName); QFETCH(QString, expectedFilePath); QFETCH(int, expectedLine); QFETCH(int, expectedCharacter); @@ -419,67 +411,39 @@ void tst_qmlls_utils::findTypeDefinitionFromLocation() QCOMPARE(locations.size(), expectedItemsCount); - QQmlJS::Dom::DomItem type = QQmlLSUtils::findTypeDefinitionOf(locations[resultIndex].domItem); + auto base = QQmlLSUtils::findTypeDefinitionOf(locations[resultIndex].domItem); // if expectedFilePath is empty, we probably just want to make sure that it does // not crash if (expectedFilePath == noResultExpected) { - QCOMPARE(type.internalKind(), QQmlJS::Dom::DomType::Empty); + QVERIFY(!base); return; } - QVERIFY(type); - - QQmlJS::Dom::FileLocations::Tree typeLocationToTest = QQmlJS::Dom::FileLocations::treeOf(type); - QEXPECT_FAIL("findIntProperty", "Builtins not supported yet", Abort); QEXPECT_FAIL("function-parameter-builtin", "Base types defined in C++ are not supported yet", Abort); QEXPECT_FAIL("colorBinding", "Types from C++ bases not supported yet", Abort); QEXPECT_FAIL("rectangle-property", "Types from C++ bases not supported yet", Abort); QEXPECT_FAIL("icBase", "Base types defined in C++ are not supported yet", Abort); + QVERIFY(base); - auto fileObject = type.containingFile().as(); + auto fileObject = + locations[resultIndex].domItem.goToFile(base->filename).as(); // print some debug message when failing, instead of using QVERIFY2 // (printing the type every time takes a lot of time). if constexpr (enable_debug_output) { if (!fileObject) - qDebug() << "This has no file: " << type.containingFile() << " for type " - << type.field(QQmlJS::Dom::Fields::type).get().component(); + qDebug() << "Could not find the file" << base->filename << "in the Dom."; } QVERIFY(fileObject); + QCOMPARE(base->filename, expectedFilePath); QCOMPARE(fileObject->canonicalFilePath(), expectedFilePath); - QCOMPARE(typeLocationToTest->info().fullRegion.startLine, quint32(expectedLine)); - QCOMPARE(typeLocationToTest->info().fullRegion.startColumn, quint32(expectedCharacter)); - - if (auto object = type.as()) { - const std::vector except = { - "functionParameterICUsage", - "ICBindingUsage", - "ICBindingUsage2", - "ICBindingUsage3", - }; - for (const QString &functionName : except) { - QEXPECT_FAIL( - functionName.toStdString().c_str(), - "Types for JS-identifiers point to the type inside inline components instead " - "of the inline component itself", - Continue); - } - QCOMPARE(object->idStr(), expectedTypeName); - } else if (auto exported = type.as()) { - QCOMPARE(exported->typeName, expectedTypeName); - } else { - if constexpr (enable_debug_output) { - if (type.name() != expectedTypeName) - qDebug() << " has not the unexpected name " << type.name() - << " instead of expected " << expectedTypeName << " in " << type; - } - QCOMPARE(type.name(), expectedTypeName); - } + QCOMPARE(base->sourceLocation.startLine, quint32(expectedLine)); + QCOMPARE(base->sourceLocation.startColumn, quint32(expectedCharacter)); } void tst_qmlls_utils::findLocationOfItem_data() @@ -624,6 +588,9 @@ void tst_qmlls_utils::findBaseObject_data() void tst_qmlls_utils::findBaseObject() { + const QByteArray failOnInlineComponentsMessage = + "The Dom cannot resolve inline components from the basetype yet."; + QFETCH(QString, filePath); QFETCH(int, line); QFETCH(int, character); @@ -650,15 +617,17 @@ void tst_qmlls_utils::findBaseObject() } QCOMPARE(locations.size(), 1); - auto type = QQmlLSUtils::findTypeDefinitionOf(locations.front().domItem); - auto base = QQmlLSUtils::baseObject(type); - QByteArray failOnInlineComponentsMessage = - "The Dom cannot resolve inline components from the basetype yet."; - + auto typeLocation = QQmlLSUtils::findTypeDefinitionOf(locations.front().domItem); QEXPECT_FAIL("inline-ic", failOnInlineComponentsMessage, Abort); - QEXPECT_FAIL("inline-ic-from-id", failOnInlineComponentsMessage, Abort); QEXPECT_FAIL("inline-ic2", failOnInlineComponentsMessage, Abort); QEXPECT_FAIL("inline-ic2-from-id", failOnInlineComponentsMessage, Abort); + QVERIFY(typeLocation); + QQmlJS::Dom::DomItem type = QQmlLSUtils::sourceLocationToDomItem( + locations.front().domItem.goToFile(typeLocation->filename), + typeLocation->sourceLocation); + auto base = QQmlLSUtils::baseObject(type); + + QEXPECT_FAIL("inline-ic-from-id", failOnInlineComponentsMessage, Abort); if constexpr (enable_debug_output) { if (!base) -- cgit v1.2.3