// Copyright (C) 2024 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only #ifndef QQMLLSCOMPLETION_H #define QQMLLSCOMPLETION_H // // W A R N I N G // ------------- // // This file is not part of the Qt API. It exists purely as an // implementation detail. This header file may change from version to // version without notice, or even be removed. // // We mean it. // #include "qqmlcompletioncontextstrings_p.h" #include "qqmllsutils_p.h" #include "qqmllsplugin_p.h" #include #include #include #include #include #include #include QT_BEGIN_NAMESPACE Q_DECLARE_LOGGING_CATEGORY(QQmlLSCompletionLog) class QQmlLSCompletion { using DomItem = QQmlJS::Dom::DomItem; public: enum class ImportCompletionType { None, Module, Version }; enum AppendOption { AppendSemicolon, AppendNothing }; QQmlLSCompletion(const QFactoryLoader &pluginLoader); using CompletionItem = QLspSpecification::CompletionItem; using BackInsertIterator = std::back_insert_iterator>; QList completions(const DomItem ¤tItem, const CompletionContextStrings &ctx) const; static CompletionItem makeSnippet(QUtf8StringView qualifier, QUtf8StringView label, QUtf8StringView insertText); static CompletionItem makeSnippet(QUtf8StringView label, QUtf8StringView insertText); private: struct QQmlLSCompletionPosition { DomItem itemAtPosition; CompletionContextStrings cursorPosition; qsizetype offset() const { return cursorPosition.offset(); } }; void collectCompletions(const DomItem ¤tItem, const CompletionContextStrings &ctx, BackInsertIterator result) const; bool betweenLocations(QQmlJS::SourceLocation left, const QQmlLSCompletionPosition &positionInfo, QQmlJS::SourceLocation right) const; bool afterLocation(QQmlJS::SourceLocation left, const QQmlLSCompletionPosition &positionInfo) const; bool beforeLocation(const QQmlLSCompletionPosition &ctx, QQmlJS::SourceLocation right) const; bool ctxBeforeStatement(const QQmlLSCompletionPosition &positionInfo, const DomItem &parentForContext, QQmlJS::Dom::FileLocationRegion firstRegion) const; bool isCaseOrDefaultBeforeCtx(const DomItem ¤tClause, const QQmlLSCompletionPosition &positionInfo, QQmlJS::Dom::FileLocationRegion keywordRegion) const; DomItem previousCaseOfCaseBlock(const DomItem &parentForContext, const QQmlLSCompletionPosition &positionInfo) const; void idsCompletions(const DomItem &component, BackInsertIterator it) const; void suggestReachableTypes(const DomItem &context, QQmlJS::Dom::LocalSymbolsTypes typeCompletionType, QLspSpecification::CompletionItemKind kind, BackInsertIterator it) const; void suggestJSStatementCompletion(const DomItem ¤tItem, BackInsertIterator it) const; void suggestCaseAndDefaultStatementCompletion(BackInsertIterator it) const; void suggestVariableDeclarationStatementCompletion( BackInsertIterator it, AppendOption option = AppendSemicolon) const; void suggestEnumerationsAndEnumerationValues(const QQmlJSScope::ConstPtr &scope, const QString &enumName, QDuplicateTracker &usedNames, BackInsertIterator result) const; DomItem ownerOfQualifiedExpression(const DomItem &qualifiedExpression) const; void suggestJSExpressionCompletion(const DomItem &context, BackInsertIterator it) const; void suggestBindingCompletion(const DomItem &itemAtPosition, BackInsertIterator it) const; void insideImportCompletionHelper(const DomItem &file, const QQmlLSCompletionPosition &positionInfo, BackInsertIterator it) const; void jsIdentifierCompletion(const QQmlJSScope::ConstPtr &scope, QDuplicateTracker *usedNames, BackInsertIterator it) const; void methodCompletion(const QQmlJSScope::ConstPtr &scope, QDuplicateTracker *usedNames, BackInsertIterator it) const; void propertyCompletion(const QQmlJSScope::ConstPtr &scope, QDuplicateTracker *usedNames, BackInsertIterator it) const; void enumerationCompletion(const QQmlJSScope::ConstPtr &scope, QDuplicateTracker *usedNames, BackInsertIterator it) const; void enumerationValueCompletionHelper(const QStringList &enumeratorKeys, BackInsertIterator it) const; void enumerationValueCompletion(const QQmlJSScope::ConstPtr &scope, const QString &enumeratorName, BackInsertIterator it) const; static bool cursorInFrontOfItem(const DomItem &parentForContext, const QQmlLSCompletionPosition &positionInfo); static bool cursorAfterColon(const DomItem ¤tItem, const QQmlLSCompletionPosition &positionInfo); void insidePragmaCompletion(QQmlJS::Dom::DomItem currentItem, const QQmlLSCompletionPosition &positionInfo, BackInsertIterator it) const; void insideQmlObjectCompletion(const DomItem &parentForContext, const QQmlLSCompletionPosition &positionInfo, BackInsertIterator it) const; void insidePropertyDefinitionCompletion(const DomItem ¤tItem, const QQmlLSCompletionPosition &positionInfo, BackInsertIterator it) const; void insideBindingCompletion(const DomItem ¤tItem, const QQmlLSCompletionPosition &positionInfo, BackInsertIterator it) const; void insideImportCompletion(const DomItem ¤tItem, const QQmlLSCompletionPosition &positionInfo, BackInsertIterator it) const; void insideQmlFileCompletion(const DomItem ¤tItem, const QQmlLSCompletionPosition &positionInfo, BackInsertIterator it) const; void suggestContinueAndBreakStatementIfNeeded(const DomItem &itemAtPosition, BackInsertIterator it) const; void insideScriptLiteralCompletion(const DomItem ¤tItem, const QQmlLSCompletionPosition &positionInfo, BackInsertIterator it) const; void insideCallExpression(const DomItem ¤tItem, const QQmlLSCompletionPosition &positionInfo, BackInsertIterator it) const; void insideIfStatement(const DomItem ¤tItem, const QQmlLSCompletionPosition &positionInfo, BackInsertIterator it) const; void insideReturnStatement(const DomItem ¤tItem, const QQmlLSCompletionPosition &positionInfo, BackInsertIterator it) const; void insideWhileStatement(const DomItem ¤tItem, const QQmlLSCompletionPosition &positionInfo, BackInsertIterator it) const; void insideDoWhileStatement(const DomItem &parentForContext, const QQmlLSCompletionPosition &positionInfo, BackInsertIterator it) const; void insideForStatementCompletion(const DomItem &parentForContext, const QQmlLSCompletionPosition &positionInfo, BackInsertIterator it) const; void insideForEachStatement(const DomItem &parentForContext, const QQmlLSCompletionPosition &positionInfo, BackInsertIterator it) const; void insideSwitchStatement(const DomItem &parentForContext, const QQmlLSCompletionPosition positionInfo, BackInsertIterator it) const; void insideCaseClause(const DomItem &parentForContext, const QQmlLSCompletionPosition &positionInfo, BackInsertIterator it) const; void insideCaseBlock(const DomItem &parentForContext, const QQmlLSCompletionPosition &positionInfo, BackInsertIterator it) const; void insideDefaultClause(const DomItem &parentForContext, const QQmlLSCompletionPosition &positionInfo, BackInsertIterator it) const; void insideBinaryExpressionCompletion(const DomItem &parentForContext, const QQmlLSCompletionPosition &positionInfo, BackInsertIterator it) const; void insideScriptPattern(const DomItem &parentForContext, const QQmlLSCompletionPosition &positionInfo, BackInsertIterator it) const; void insideVariableDeclarationEntry(const DomItem &parentForContext, const QQmlLSCompletionPosition &positionInfo, BackInsertIterator it) const; void insideThrowStatement(const DomItem &parentForContext, const QQmlLSCompletionPosition &positionInfo, BackInsertIterator it) const; void insideLabelledStatement(const DomItem &parentForContext, const QQmlLSCompletionPosition &positionInfo, BackInsertIterator it) const; void insideContinueStatement(const DomItem &parentForContext, const QQmlLSCompletionPosition &positionInfo, BackInsertIterator it) const; void insideBreakStatement(const DomItem &parentForContext, const QQmlLSCompletionPosition &positionInfo, BackInsertIterator it) const; void insideConditionalExpression(const DomItem &parentForContext, const QQmlLSCompletionPosition &positionInfo, BackInsertIterator it) const; void insideUnaryExpression(const DomItem &parentForContext, const QQmlLSCompletionPosition &positionInfo, BackInsertIterator it) const; void insidePostExpression(const DomItem &parentForContext, const QQmlLSCompletionPosition &positionInfo, BackInsertIterator it) const; void insideParenthesizedExpression(const DomItem &parentForContext, const QQmlLSCompletionPosition &positionInfo, BackInsertIterator it) const; void insideTemplateLiteral(const DomItem &parentForContext, const QQmlLSCompletionPosition &positionInfo, BackInsertIterator it) const; void insideNewExpression(const DomItem &parentForContext, const QQmlLSCompletionPosition &positionInfo, BackInsertIterator it) const; void insideNewMemberExpression(const DomItem &parentForContext, const QQmlLSCompletionPosition &positionInfo, BackInsertIterator it) const; void signalHandlerCompletion(const QQmlJSScope::ConstPtr &scope, QDuplicateTracker *usedNames, BackInsertIterator it) const; void suggestSnippetsForLeftHandSideOfBinding(const DomItem &items, BackInsertIterator result) const; void suggestSnippetsForRightHandSideOfBinding(const DomItem &items, BackInsertIterator result) const; private: using CompletionFromPluginFunction = void(QQmlLSCompletionPlugin *plugin, BackInsertIterator result); void collectFromPlugins(const qxp::function_ref f, BackInsertIterator result) const; QStringList m_loadPaths; std::vector> m_plugins; }; QT_END_NAMESPACE #endif // QQMLLSCOMPLETION_H