diff options
Diffstat (limited to 'src/qmlls/qqmllscompletion_p.h')
-rw-r--r-- | src/qmlls/qqmllscompletion_p.h | 226 |
1 files changed, 226 insertions, 0 deletions
diff --git a/src/qmlls/qqmllscompletion_p.h b/src/qmlls/qqmllscompletion_p.h new file mode 100644 index 0000000000..a31d3daebc --- /dev/null +++ b/src/qmlls/qqmllscompletion_p.h @@ -0,0 +1,226 @@ +// 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 <QtLanguageServer/private/qlanguageserverspectypes_p.h> +#include <QtQmlDom/private/qqmldomexternalitems_p.h> +#include <QtQmlDom/private/qqmldomtop_p.h> +#include <QtCore/private/qduplicatetracker_p.h> +#include <QtCore/private/qfactoryloader_p.h> +#include <QtCore/qpluginloader.h> +#include <QtCore/qxpfunctional.h> + +QT_BEGIN_NAMESPACE + +Q_DECLARE_LOGGING_CATEGORY(QQmlLSCompletionLog) + +enum QQmlLSUtilsAppendOption { AppendSemicolon, AppendNothing }; + +class QQmlLSCompletion +{ + using DomItem = QQmlJS::Dom::DomItem; +public: + QQmlLSCompletion(const QFactoryLoader &pluginLoader); + + using CompletionItem = QLspSpecification::CompletionItem; + using BackInsertIterator = std::back_insert_iterator<QList<CompletionItem>>; + QList<CompletionItem> 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, QQmlLSUtilsAppendOption option = AppendSemicolon) 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<QString> *usedNames, BackInsertIterator it) const; + + void methodCompletion(const QQmlJSScope::ConstPtr &scope, QDuplicateTracker<QString> *usedNames, + BackInsertIterator it) const; + void propertyCompletion(const QQmlJSScope::ConstPtr &scope, + QDuplicateTracker<QString> *usedNames, BackInsertIterator it) const; + void enumerationCompletion(const QQmlJSScope::ConstPtr &scope, + QDuplicateTracker<QString> *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 signalHandlerCompletion(const QQmlJSScope::ConstPtr &scope, + QDuplicateTracker<QString> *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<CompletionFromPluginFunction> f, + BackInsertIterator result) const; + + QStringList m_loadPaths; + + std::vector<std::unique_ptr<QQmlLSCompletionPlugin>> m_plugins; +}; + +QT_END_NAMESPACE + +#endif // QQMLLSCOMPLETION_H |