Qt 6.x
The Qt SDK
Loading...
Searching...
No Matches
qqmllsutils.cpp
Go to the documentation of this file.
1// Copyright (C) 2023 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#include "qqmllsutils_p.h"
5
6#include <QtLanguageServer/private/qlanguageserverspectypes_p.h>
7#include <QtCore/qthreadpool.h>
8#include <QtCore/private/qduplicatetracker_p.h>
9#include <QtCore/QRegularExpression>
10#include <QtQmlDom/private/qqmldomexternalitems_p.h>
11#include <QtQmlDom/private/qqmldomtop_p.h>
12#include <QtQmlDom/private/qqmldomscriptelements_p.h>
13#include <QtQmlDom/private/qqmldom_utils_p.h>
14#include <memory>
15#include <optional>
16#include <stack>
17#include <type_traits>
18#include <utility>
19#include <variant>
20
21using namespace QLspSpecification;
22using namespace QQmlJS::Dom;
23using namespace Qt::StringLiterals;
24
26
27Q_LOGGING_CATEGORY(QQmlLSUtilsLog, "qt.languageserver.utils")
28
29
34{
35 return item.internalKind() == DomType::ScriptBinaryExpression
36 && item.field(Fields::operation).value().toInteger()
38}
39
46{
47 auto parent = item.directParent();
49 return false;
50
51 DomItem rightHandSide = parent.field(Fields::right);
52 return item == rightHandSide;
53}
54
70{
71 return uri;
72}
73
75{
76 return url;
77}
78
88QLspSpecification::Range QQmlLSUtils::qmlLocationToLspLocation(const QString &code,
89 QQmlJS::SourceLocation qmlLocation)
90{
91 Range range;
92
93 range.start.line = qmlLocation.startLine - 1;
94 range.start.character = qmlLocation.startColumn - 1;
95
96 auto end = QQmlLSUtils::textRowAndColumnFrom(code, qmlLocation.end());
97 range.end.line = end.line;
98 range.end.character = end.character;
99 return range;
100}
101
112{
113 int targetLine = row;
114 qsizetype i = 0;
115 while (i != text.size() && targetLine != 0) {
116 QChar c = text.at(i++);
117 if (c == u'\n') {
118 --targetLine;
119 }
120 if (c == u'\r') {
121 if (i != text.size() && text.at(i) == u'\n')
122 ++i;
123 --targetLine;
124 }
125 }
126 qsizetype leftChars = column;
127 while (i != text.size() && leftChars) {
128 QChar c = text.at(i);
129 if (c == u'\n' || c == u'\r')
130 break;
131 ++i;
132 if (!c.isLowSurrogate())
133 --leftChars;
134 }
135 return i;
136}
137
149{
150 int row = 0;
151 int column = 0;
152 qsizetype currentLineOffset = 0;
153 for (qsizetype i = 0; i < offset; i++) {
154 QChar c = text[i];
155 if (c == u'\n') {
156 row++;
157 currentLineOffset = i + 1;
158 } else if (c == u'\r') {
159 if (i > 0 && text[i - 1] == u'\n')
160 currentLineOffset++;
161 }
162 }
163 column = offset - currentLineOffset;
164
165 return { row, column };
166}
167
177 int character)
178{
180 std::shared_ptr<QmlFile> filePtr = file.ownerAs<QmlFile>();
181 if (!filePtr)
182 return itemsFound;
183 FileLocations::Tree t = filePtr->fileLocationsTree();
184 Q_ASSERT(t);
185 QString code = filePtr->code(); // do something more advanced wrt to changes wrt to this->code?
187 qsizetype targetPos = textOffsetFrom(code, line, character);
188 Q_ASSERT(targetPos >= 0);
189 auto containsTarget = [targetPos](QQmlJS::SourceLocation l) {
190 if constexpr (sizeof(qsizetype) <= sizeof(quint32)) {
191 return l.begin() <= quint32(targetPos) && quint32(targetPos) <= l.end();
192 } else {
193 return l.begin() <= targetPos && targetPos <= l.end();
194 }
195 };
196 if (containsTarget(t->info().fullRegion)) {
198 loc.domItem = file;
199 loc.fileLocation = t;
200 toDo.append(loc);
201 }
202 while (!toDo.isEmpty()) {
203 QQmlLSUtilsItemLocation iLoc = toDo.last();
204 toDo.removeLast();
205
206 bool inParentButOutsideChildren = true;
207
208 auto subEls = iLoc.fileLocation->subItems();
209 for (auto it = subEls.begin(); it != subEls.end(); ++it) {
210 auto subLoc = std::static_pointer_cast<AttachedInfoT<FileLocations>>(it.value());
211 Q_ASSERT(subLoc);
212
213 if (containsTarget(subLoc->info().fullRegion)) {
215 subItem.domItem = iLoc.domItem.path(it.key());
216 if (!subItem.domItem) {
217 qCDebug(QQmlLSUtilsLog)
218 << "A DomItem child is missing or the FileLocationsTree structure does "
219 "not follow the DomItem Structure.";
220 continue;
221 }
222 subItem.fileLocation = subLoc;
223 toDo.append(subItem);
224 inParentButOutsideChildren = false;
225 }
226 }
227 if (inParentButOutsideChildren) {
228 itemsFound.append(iLoc);
229 }
230 }
231
232 // filtering step:
233 if (itemsFound.size() > 1) {
234 // if there are multiple items, take the smallest one + its neighbors
235 // this allows to prefer inline components over main components, when both contain the
236 // current textposition, and to disregard internal structures like property maps, which
237 // "contain" everything from their first-appearing to last-appearing property (e.g. also
238 // other stuff in between those two properties).
239 auto smallest = std::min_element(
240 itemsFound.begin(), itemsFound.end(),
242 return a.fileLocation->info().fullRegion.length
243 < b.fileLocation->info().fullRegion.length;
244 });
245 QList<QQmlLSUtilsItemLocation> filteredItems;
246 filteredItems.append(*smallest);
247
248 const QQmlJS::SourceLocation smallestLoc = smallest->fileLocation->info().fullRegion;
249 const quint32 smallestBegin = smallestLoc.begin();
250 const quint32 smallestEnd = smallestLoc.end();
251
252 for (auto it = itemsFound.begin(); it != itemsFound.end(); it++) {
253 if (it == smallest)
254 continue;
255
256 const QQmlJS::SourceLocation itLoc = it->fileLocation->info().fullRegion;
257 const quint32 itBegin = itLoc.begin();
258 const quint32 itEnd = itLoc.end();
259 if (itBegin == smallestEnd || smallestBegin == itEnd) {
260 filteredItems.append(*it);
261 }
262 }
263 itemsFound = filteredItems;
264 }
265 return itemsFound;
266}
267
269{
270 if (!object.as<QmlObject>())
271 return {};
272
273 auto prototypes = object.field(QQmlJS::Dom::Fields::prototypes);
274 switch (prototypes.indexes()) {
275 case 0:
276 return {};
277 case 1:
278 break;
279 default:
280 qDebug() << "Multiple prototypes found for " << object.name() << ", taking the first one.";
281 break;
282 }
283 QQmlJS::Dom::DomItem base = prototypes.index(0).proceedToScope();
284 return base;
285}
286
301{
303
304 switch (object.internalKind()) {
306 result = object.field(Fields::objects).index(0);
307 break;
309 result = baseObject(object);
310 break;
312 auto binding = object.as<Binding>();
313 Q_ASSERT(binding);
314
315 // try to grab the type from the bound object
316 if (binding->valueKind() == BindingValueKind::Object) {
317 result = baseObject(object.field(Fields::value));
318 } else {
319 // use the type of the property it is bound on for scriptexpression etc.
320 DomItem propertyDefinition;
321 const QString bindingName = binding->name();
322 object.containingObject().visitLookup(
323 bindingName,
324 [&propertyDefinition](DomItem &item) {
325 if (item.internalKind() == QQmlJS::Dom::DomType::PropertyDefinition) {
326 propertyDefinition = item;
327 return false;
328 }
329 return true;
330 },
331 LookupType::PropertyDef);
332 result = propertyDefinition.field(Fields::type).proceedToScope();
333 }
334 break;
335 }
337 result = object.field(Fields::referredObject).proceedToScope();
338 break;
342 result = object.field(Fields::type).proceedToScope();
343 break;
345 if (object.directParent().internalKind() == DomType::ScriptType) {
346 DomItem type =
347 object.filterUp([](DomType k, DomItem &) { return k == DomType::ScriptType; },
348 FilterUpOptions::ReturnOuter);
349
350 const QString name = type.field(Fields::typeName).value().toString();
351 result = object.path(Paths::lookupTypePath(name));
352 break;
353 }
354 auto scope =
356 if (!scope)
357 return {};
358
359 return QQmlLSUtils::sourceLocationToDomItem(object.containingFile(),
360 scope->sourceLocation());
361 }
363 break;
364 default:
365 qDebug() << "QQmlLSUtils::findTypeDefinitionOf: Found unimplemented Type"
366 << object.internalKindStr();
367 result = {};
368 }
369
370 return result;
371}
372
374{
375 DomItem definitionOfItem;
376 item.visitUp([&name, &definitionOfItem](DomItem &i) {
377 if (std::optional<QQmlJSScope::Ptr> scope = i.semanticScope(); scope) {
378 qCDebug(QQmlLSUtilsLog) << "Searching for definition in" << i.internalKindStr();
379 if (auto jsIdentifier = scope.value()->JSIdentifier(name)) {
380 qCDebug(QQmlLSUtilsLog) << "Found scope" << scope.value()->baseTypeName();
381 definitionOfItem = i;
382 return false;
383 }
384 }
385 // early exit: no JS definitions/usages outside the ScriptExpression DOM element.
386 if (i.internalKind() == DomType::ScriptExpression)
387 return false;
388 return true;
389 });
390
391 return definitionOfItem;
392}
393
396{
397 QQmlJSScope::ConstPtr targetType;
399 if (!targetType)
400 return;
401
402 auto findUsages = [&targetType, &result, &name](Path, DomItem &current, bool) -> bool {
403 bool resolveType = false;
404 bool continueForChildren = true;
405 DomItem toBeResolved = current;
406 QString subRegion;
407
408 if (auto scope = current.semanticScope()) {
409 // is the current property shadowed by some JS identifier? ignore current + its children
410 if (scope.value()->JSIdentifier(name)) {
411 return false;
412 }
413 }
414
415 switch (current.internalKind()) {
416 case DomType::PropertyDefinition: {
417 const QString propertyName = current.field(Fields::name).value().toString();
418 if (name == propertyName) {
419 resolveType = true;
420 } else {
421 return true;
422 }
423 break;
424 }
425 case DomType::ScriptIdentifierExpression: {
426 const QString propertyName = current.field(Fields::identifier).value().toString();
427 if (name != propertyName)
428 return true;
429
430 resolveType = true;
431 break;
432 }
433 case DomType::MethodInfo: {
434 const QString methodName = current.field(Fields::name).value().toString();
435 if (name != methodName)
436 return true;
437
438 subRegion = u"identifier"_s;
439 resolveType = true;
440 break;
441 }
442 default:
443 break;
444 };
445
446 if (resolveType) {
447 auto currentType = QQmlLSUtils::resolveExpressionType(
449 qCDebug(QQmlLSUtilsLog) << "Will resolve type of" << toBeResolved.internalKindStr();
450 if (currentType == targetType) {
451 auto tree = FileLocations::treeOf(current);
452 QQmlJS::SourceLocation sourceLocation;
453
454 if (subRegion.isEmpty()) {
455 sourceLocation = tree->info().fullRegion;
456 } else {
457 auto regions = tree->info().regions;
458 auto it = regions.constFind(subRegion);
459 if (it == regions.constEnd())
460 return continueForChildren;
461 sourceLocation = *it;
462 }
463
464 QQmlLSUtilsLocation location{ current.canonicalFilePath(), sourceLocation };
465 result.append(location);
466 }
467 }
468 return continueForChildren;
469 };
470
471 item.containingFile()
472 .field(Fields::components)
473 .visitTree(Path(), emptyChildrenVisitor, VisitOption::Recurse | VisitOption::VisitSelf,
474 findUsages);
475}
476
478{
479 qCDebug(QQmlLSUtilsLog) << "Looking for JS identifier with name" << name;
480 DomItem definitionOfItem = findJSIdentifierDefinition(item, name);
481
482 // if there is no definition found: check if name was a property or an id instead
483 if (!definitionOfItem) {
484 qCDebug(QQmlLSUtilsLog) << "No defining JS-Scope found!";
486 return;
487 }
488
489 definitionOfItem.visitTree(
490 Path(), emptyChildrenVisitor, VisitOption::VisitAdopted | VisitOption::Recurse,
491 [&name, &result](Path, DomItem &item, bool) -> bool {
492 qCDebug(QQmlLSUtilsLog) << "Visiting a " << item.internalKindStr();
493 if (item.internalKind() == DomType::ScriptIdentifierExpression
494 && item.field(Fields::identifier).value().toString() == name) {
495 // add this usage
496 auto fileLocation = FileLocations::treeOf(item);
497 if (!fileLocation) {
498 qCWarning(QQmlLSUtilsLog) << "Failed finding filelocation of found usage";
499 return true;
500 }
501 const QQmlJS::SourceLocation location = fileLocation->info().fullRegion;
502 const QString fileName = item.canonicalFilePath();
503 result.append({ fileName, location });
504 return true;
505 } else if (std::optional<QQmlJSScope::Ptr> scope = item.semanticScope();
506 scope && scope.value()->JSIdentifier(name)) {
507 // current JS identifier has been redefined, do not visit children
508 return false;
509 }
510 return true;
511 });
512}
513
515{
517
518 switch (item.internalKind()) {
519 case DomType::ScriptIdentifierExpression: {
520 const QString name = item.field(Fields::identifier).value().toString();
522 break;
523 }
524 case DomType::ScriptVariableDeclarationEntry: {
525 const QString name = item.field(Fields::identifier).value().toString();
527 break;
528 }
529 case DomType::PropertyDefinition:
530 case DomType::MethodInfo: {
531 const QString name = item.field(Fields::name).value().toString();
533 break;
534 }
535 default:
536 qCDebug(QQmlLSUtilsLog) << item.internalKindStr()
537 << "was not implemented for QQmlLSUtils::findUsagesOf";
538 return result;
539 }
540
541 std::sort(result.begin(), result.end());
542
543 if (QQmlLSUtilsLog().isDebugEnabled()) {
544 qCDebug(QQmlLSUtilsLog) << "Found following usages:";
545 for (auto r : result) {
546 qCDebug(QQmlLSUtilsLog)
547 << r.filename << " @ " << r.location.startLine << ":" << r.location.startColumn
548 << " with length " << r.location.length;
549 }
550 }
551
552 return result;
553}
554
556 const QString &name)
557{
558 for (QQmlJSScope::Ptr current = referrerScope; current; current = current->parentScope()) {
559 if (current->hasMethod(name)) {
560 return current;
561 }
562 }
563 return {};
564}
565
567 const QString &propertyName,
569{
570 for (QQmlJSScope::Ptr current = referrerScope; current; current = current->parentScope()) {
571 if (auto property = current->property(propertyName); property.isValid()) {
572 switch (options) {
573 case JustOwner:
574 return current;
575 case Everything:
576 return property.type();
577 }
578 }
579 }
580 return {};
581}
582
590{
591 switch (item.internalKind()) {
592 case DomType::ScriptIdentifierExpression: {
593 auto referrerScope = item.nearestSemanticScope();
594 if (!referrerScope)
595 return {};
596
597 const QString name = item.field(Fields::identifier).value().toString();
598
600 DomItem parent = item.directParent();
601 auto owner = QQmlLSUtils::resolveExpressionType(parent.field(Fields::left),
603 if (owner) {
604 if (owner->hasMethod(name)) {
605 switch (options) {
606 case JustOwner:
607 return owner;
608 case Everything:
609 // not implemented yet, but JS functions have methods and properties
610 // see
611 // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function
612 // for the list of properties/methods of functions
613 break;
614 }
615 }
616 if (auto property = owner->property(name); property.isValid()) {
617 switch (options) {
618 case JustOwner:
619 return owner;
620 case Everything:
621 return property.type();
622 }
623 }
624 } else {
625 return {};
626 }
627 } else {
628 DomItem definitionOfItem = findJSIdentifierDefinition(item, name);
629 if (definitionOfItem) {
630 Q_ASSERT_X(definitionOfItem.semanticScope().has_value()
631 && definitionOfItem.semanticScope()
632 .value()
633 ->JSIdentifier(name)
634 .has_value(),
635 "QQmlLSUtils::findDefinitionOf",
636 "JS definition does not actually define the JS identifer. "
637 "It should be empty.");
638 auto scope = definitionOfItem.semanticScope().value()->JSIdentifier(name)->scope.toStrongRef();;
639 return scope;
640 }
641
642 // check if its a method
643 if (QQmlJSScope::ConstPtr scope = findMethodIn(*referrerScope, name)) {
644 return scope;
645 }
646
647 // check if its an (unqualified) property
648 if (QQmlJSScope::ConstPtr scope = findPropertyIn(*referrerScope, name, options)) {
649 return scope;
650 }
651 }
652
653 // check if its an id
654 auto resolver = item.containingFile().ownerAs<QmlFile>()->typeResolver();
655 if (!resolver)
656 return {};
657 QQmlJSScope::ConstPtr fromId = resolver.value()->scopeForId(name, referrerScope.value());
658 if (fromId)
659 return fromId;
660
661 return {};
662 }
663 case DomType::PropertyDefinition: {
664 auto propertyDefinition = item.as<PropertyDefinition>();
665 if (propertyDefinition && propertyDefinition->scope) {
666 switch (options) {
667 case JustOwner:
668 return propertyDefinition->scope.value();
669 case Everything:
670 return propertyDefinition->scope.value()->property(propertyDefinition->name).type();
671 }
672 }
673
674 return {};
675 }
676 case DomType::QmlObject: {
677 auto object = item.as<QmlObject>();
678 if (object && object->semanticScope())
679 return object->semanticScope().value();
680
681 return {};
682 }
683 case DomType::MethodInfo: {
684 auto object = item.as<MethodInfo>();
685 if (object && object->semanticScope())
686 // return the owner of the method
687 return object->semanticScope().value()->parentScope();
688
689 return {};
690 }
691 case DomType::ScriptBinaryExpression: {
693 DomItem owner = item.field(Fields::left);
694 QString propertyName =
695 item.field(Fields::right).field(Fields::identifier).value().toString();
696 auto ownerType = QQmlLSUtils::resolveExpressionType(
698 if (!ownerType)
699 return ownerType;
700 switch (options) {
701 case JustOwner:
702 return ownerType;
703 case Everything:
704 return ownerType->property(propertyName).type();
705 }
706 }
707 return {};
708 }
709 default: {
710 qCDebug(QQmlLSUtilsLog) << "Type" << item.internalKindStr()
711 << "is unimplemented in QQmlLSUtils::resolveExpressionType";
712 return {};
713 }
714 }
715 Q_UNREACHABLE();
716}
717
719{
720 // QQmlJS::SourceLocation starts counting at 1 but the utils and the LSP start at 0.
722 location.startColumn - 1);
723 switch (items.size()) {
724 case 0:
725 return {};
726 case 1:
727 return items.front().domItem;
728 case 2: {
729 // special case: because location points to the beginning of the type definition,
730 // itemsFromTextLocation might also return the type on its left, in case it is directly
731 // adjacent to it. In this case always take the right (=with the higher column-number)
732 // item.
733 auto &first = items.front();
734 auto &second = items.back();
735 Q_ASSERT_X(first.fileLocation->info().fullRegion.startLine
736 == second.fileLocation->info().fullRegion.startLine,
737 "QQmlLSUtils::findTypeDefinitionOf(DomItem)",
738 "QQmlLSUtils::itemsFromTextLocation returned non-adjacent items.");
739 if (first.fileLocation->info().fullRegion.startColumn
740 > second.fileLocation->info().fullRegion.startColumn)
741 return first.domItem;
742 else
743 return second.domItem;
744 break;
745 }
746 default:
747 qDebug() << "Found multiple candidates for type of scriptidentifierexpression";
748 break;
749 }
750 return {};
751}
752
753static std::optional<QQmlLSUtilsLocation>
755{
757 DomItem method = owner.field(Fields::methods).key(name).index(0);
758 auto fileLocation = FileLocations::treeOf(method);
759 if (!fileLocation)
760 return {};
761
762 auto regions = fileLocation->info().regions;
763
764 if (auto it = regions.constFind(u"identifier"_s); it != regions.constEnd()) {
766 result.location = *it;
767 result.filename = method.canonicalFilePath();
768 return result;
769 }
770
771 return {};
772}
773
774static std::optional<QQmlLSUtilsLocation>
776 const QString &name)
777{
778 DomItem propertyOwner = QQmlLSUtils::sourceLocationToDomItem(file, propertyDefinitionLocation);
779 DomItem propertyDefinition = propertyOwner.field(Fields::propertyDefs).key(name).index(0);
780 if (!propertyDefinition)
781 return {};
782
784 result.location = FileLocations::treeOf(propertyDefinition)->info().fullRegion;
785 result.filename = propertyDefinition.canonicalFilePath();
786 return result;
787}
788
789std::optional<QQmlLSUtilsLocation> QQmlLSUtils::findDefinitionOf(DomItem item)
790{
791
792 switch (item.internalKind()) {
794 const QString name = item.value().toString();
796 if (auto ownerScope = QQmlLSUtils::resolveExpressionType(
798 const DomItem ownerFile = item.goToFile(ownerScope->filePath());
799 const QQmlJS::SourceLocation ownerLocation = ownerScope->sourceLocation();
800 if (auto methodDefinition =
801 findMethodDefinitionOf(ownerFile, ownerLocation, name)) {
802 return methodDefinition;
803 }
804 if (auto propertyDefinition =
805 findPropertyDefinitionOf(ownerFile, ownerLocation, name)) {
806 return propertyDefinition;
807 }
808 }
809 return {};
810 }
811
812 // check: is it a JS identifier?
813 if (DomItem definitionOfItem = findJSIdentifierDefinition(item, name)) {
814 Q_ASSERT_X(definitionOfItem.semanticScope().has_value()
815 && definitionOfItem.semanticScope()
816 .value()
817 ->JSIdentifier(name)
818 .has_value(),
819 "QQmlLSUtils::findDefinitionOf",
820 "JS definition does not actually define the JS identifer. "
821 "It should be empty.");
823 definitionOfItem.semanticScope().value()->JSIdentifier(name).value().location;
824
825 QQmlLSUtilsLocation result = { definitionOfItem.canonicalFilePath(), location };
826 return result;
827 }
828
829 // not a JS identifier, check for ids and properties and methods
830 auto referrerScope = item.nearestSemanticScope();
831 if (!referrerScope)
832 return {};
833
834 // check: is it a method name?
835 if (QQmlJSScope::ConstPtr scope = findMethodIn(*referrerScope, name)) {
836 const QString canonicalPath = scope->filePath();
837 DomItem file = item.goToFile(canonicalPath);
838 return findMethodDefinitionOf(file, scope->sourceLocation(), name);
839 }
840
841 if (QQmlJSScope::ConstPtr scope =
843 const QString canonicalPath = scope->filePath();
844 DomItem file = item.goToFile(canonicalPath);
845 return findPropertyDefinitionOf(file, scope->sourceLocation(), name);
846 }
847
848 // check if its an id
849 auto resolver = item.containingFile().ownerAs<QmlFile>()->typeResolver();
850 if (!resolver)
851 return {};
852 QQmlJSScope::ConstPtr fromId = resolver.value()->scopeForId(name, referrerScope.value());
853 if (fromId) {
855 result.location = fromId->sourceLocation();
856 result.filename = item.canonicalFilePath();
857 return result;
858 }
859 return {};
860 }
861 default:
862 qDebug() << "QQmlLSUtils::findDefinitionOf: Found unimplemented Type "
863 << item.internalKindStr();
864 return {};
865 }
866
867 Q_UNREACHABLE_RETURN(std::nullopt);
868}
869
\inmodule QtCore
Definition qbytearray.h:57
\inmodule QtCore
Definition qchar.h:48
Definition qlist.h:74
qsizetype size() const noexcept
Definition qlist.h:386
bool isEmpty() const noexcept
Definition qlist.h:390
T & last()
Definition qlist.h:631
reference back()
Definition qlist.h:686
iterator end()
Definition qlist.h:609
reference front()
Definition qlist.h:684
iterator begin()
Definition qlist.h:608
void removeLast() noexcept
Definition qlist.h:808
void append(parameter_type t)
Definition qlist.h:441
QQmlJSScope::Ptr parentScope()
QQmlJS::SourceLocation sourceLocation() const
DomItem proceedToScope(ErrorHandler h=nullptr, QList< Path > *visitedRefs=nullptr)
std::optional< QQmlJSScope::Ptr > semanticScope()
DomItem filterUp(function_ref< bool(DomType k, DomItem &)> filter, FilterUpOptions options)
DomItem path(Path p, ErrorHandler h=&defaultErrorHandler)
DomItem field(QStringView name)
static FileLocations::Tree treeOf(DomItem &)
std::shared_ptr< AttachedInfoT< FileLocations > > Tree
std::optional< QQmlJSScope::Ptr > semanticScope() const
std::optional< QQmlJSScope::Ptr > semanticScope() const
static QQmlJS::Dom::DomItem findTypeDefinitionOf(QQmlJS::Dom::DomItem item)
Extracts the QML object type of an \l DomItem.
static QQmlJS::Dom::DomItem sourceLocationToDomItem(QQmlJS::Dom::DomItem file, const QQmlJS::SourceLocation &location)
static QQmlJSScope::ConstPtr resolveExpressionType(QQmlJS::Dom::DomItem item, QQmlLSUtilsResolveOptions)
static std::optional< QQmlLSUtilsLocation > findDefinitionOf(QQmlJS::Dom::DomItem item)
static QByteArray lspUriToQmlUrl(const QByteArray &uri)
static QQmlJS::Dom::DomItem baseObject(QQmlJS::Dom::DomItem qmlObject)
static QByteArray qmlUrlToLspUri(const QByteArray &url)
static QList< QQmlLSUtilsLocation > findUsagesOf(QQmlJS::Dom::DomItem item)
static QLspSpecification::Range qmlLocationToLspLocation(const QString &code, QQmlJS::SourceLocation qmlLocation)
Converts a QQmlJS::SourceLocation to a LSP Range.
static qsizetype textOffsetFrom(const QString &code, int row, int character)
Convert a text position from (line, column) into an offset.
static QList< QQmlLSUtilsItemLocation > itemsFromTextLocation(QQmlJS::Dom::DomItem file, int line, int character)
Find the DomItem representing the object situated in file at given line and character/column.
static QQmlLSUtilsTextPosition textRowAndColumnFrom(const QString &code, qsizetype offset)
Convert a text position from an offset into (line, column).
iterator begin()
Definition qset.h:136
iterator end()
Definition qset.h:140
const_iterator constEnd() const noexcept
Definition qset.h:143
const_iterator constFind(const T &value) const
Definition qset.h:161
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:127
qsizetype size() const
Returns the number of characters in this string.
Definition qstring.h:182
const QChar at(qsizetype i) const
Returns the character at the given index position in the string.
Definition qstring.h:1079
bool isEmpty() const
Returns true if the string has no characters; otherwise returns false.
Definition qstring.h:1083
QString text
QSet< QString >::iterator it
Path lookupTypePath(QString name)
bool emptyChildrenVisitor(Path, DomItem &, bool)
Combined button and popup list for selecting options.
DBusConnection const char DBusError DBusBusType DBusError return DBusConnection DBusHandleMessageFunction void DBusFreeFunction return DBusConnection return DBusConnection return const char DBusError return DBusConnection DBusMessage dbus_uint32_t return DBusConnection dbus_bool_t DBusConnection DBusAddWatchFunction DBusRemoveWatchFunction DBusWatchToggledFunction void DBusFreeFunction return DBusConnection DBusDispatchStatusFunction void DBusFreeFunction DBusTimeout return DBusTimeout return DBusWatch return DBusWatch unsigned int return DBusError const DBusError return const DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessageIter int const void return DBusMessageIter DBusMessageIter return DBusMessageIter void DBusMessageIter void int return DBusMessage DBusMessageIter return DBusMessageIter return DBusMessageIter DBusMessageIter const char const char const char const char * method
static QString methodName(const QDBusIntrospection::Method &method)
#define qDebug
[1]
Definition qlogging.h:160
#define Q_LOGGING_CATEGORY(name,...)
#define qCWarning(category,...)
#define qCDebug(category,...)
GLint location
GLboolean GLboolean GLboolean b
GLboolean GLboolean GLboolean GLboolean a
[7]
GLboolean r
[2]
GLuint GLuint end
GLuint object
[3]
GLsizei range
GLenum type
GLenum GLuint GLintptr offset
GLuint name
GLint first
GLenum GLenum GLsizei void GLsizei void * column
const GLubyte * c
GLdouble GLdouble t
Definition qopenglext.h:243
GLenum GLenum GLsizei void * row
GLuint64EXT * result
[6]
static void findUsagesHelper(DomItem item, const QString &name, QList< QQmlLSUtilsLocation > &result)
static std::optional< QQmlLSUtilsLocation > findMethodDefinitionOf(DomItem file, QQmlJS::SourceLocation location, const QString &name)
static QT_BEGIN_NAMESPACE bool isFieldMemberExpression(DomItem &item)
static QQmlJSScope::ConstPtr findPropertyIn(const QQmlJSScope::Ptr &referrerScope, const QString &propertyName, QQmlLSUtilsResolveOptions options)
static bool isFieldMemberAccess(DomItem &item)
static DomItem findJSIdentifierDefinition(DomItem item, const QString &name)
static std::optional< QQmlLSUtilsLocation > findPropertyDefinitionOf(DomItem file, QQmlJS::SourceLocation propertyDefinitionLocation, const QString &name)
static QQmlJSScope::ConstPtr findMethodIn(const QQmlJSScope::Ptr &referrerScope, const QString &name)
static void findUsagesOfNonJSIdentifiers(DomItem item, const QString &name, QList< QQmlLSUtilsLocation > &result)
QQmlLSUtilsResolveOptions
@ Everything
@ JustOwner
#define Q_ASSERT(cond)
Definition qrandom.cpp:47
#define Q_ASSERT_X(cond, x, msg)
Definition qrandom.cpp:48
static QString canonicalPath(const QString &rootPath)
unsigned int quint32
Definition qtypes.h:45
ptrdiff_t qsizetype
Definition qtypes.h:70
const char property[13]
Definition qwizard.cpp:101
QFile file
[0]
QUrl url("example.com")
[constructor-url-reference]
QGraphicsItem * item
QList< QTreeWidgetItem * > items
QQmlJS::Dom::DomItem domItem
QQmlJS::Dom::FileLocations::Tree fileLocation
IUIAutomationTreeWalker __RPC__deref_out_opt IUIAutomationElement ** parent