File indexing completed on 2024-05-19 04:41:58

0001 /*
0002     SPDX-FileCopyrightText: 2013 Sven Brauch <svenbrauch@googlemail.com>
0003 
0004     SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
0005 */
0006 
0007 #ifndef QMLJS_CONTEXT_H
0008 #define QMLJS_CONTEXT_H
0009 
0010 #include "codecompletionexport.h"
0011 #include "items/completionitem.h"
0012 
0013 #include <language/codecompletion/codecompletioncontext.h>
0014 #include <language/duchain/ducontext.h>
0015 
0016 namespace QmlJS {
0017 
0018 class KDEVQMLJSCOMPLETION_EXPORT CodeCompletionContext : public KDevelop::CodeCompletionContext
0019 {
0020 public:
0021     CodeCompletionContext(const KDevelop::DUContextPointer& context, const QString& text,
0022                           const KDevelop::CursorInRevision& position, int depth = 0);
0023     QList<KDevelop::CompletionTreeItemPointer> completionItems(bool& abort, bool fullCompletion = true) override;
0024 
0025     KDevelop::AbstractType::Ptr typeToMatch() const;
0026 
0027     enum CompletionInContextFlag {
0028         CompletionOnlyLocal = 1,        /*!< @brief Don't list the items available in parent contexts */
0029         CompletionHideWrappers = 2,     /*!< @brief Filter out QML component wrappers (Q... C++ classes) */
0030     };
0031     Q_DECLARE_FLAGS(CompletionInContextFlags, CompletionInContextFlag)
0032 
0033 private:
0034     /**
0035      * @brief Entry in the expression stack returned by expressionStack()
0036      *
0037      * Code-completion usually happens in partial expressions that cannot be
0038      * parsed using the QML/JS parser. expressionStack() can be used to build
0039      * a stack of unterminated partial expressions. This structure represents
0040      * an entry in this stack.
0041      *
0042      * Every expression stack entry contains information about where the
0043      * expression started (at the beginning of the string or just after a brace),
0044      * how many commas have been encountered in it (so that function call-tips
0045      * can know which is the current argument being edited), and where is the last
0046      * operator in the sub-expression. Normally, anything after the last operator
0047      * should be a valid sub-expression identifying a declaration.
0048      *
0049      * @code
0050      * foo(A, B, C
0051      * [   [   se
0052      * @endcode
0053      *
0054      * In the above snippet, the inner-most expression starts at A. However,
0055      * "A, B, C" is not a valid JS expression (or one that should be used for
0056      * code-completion). However, everything after the last comma, identified
0057      * by operatorStart and operatorEnd, is valid ("C" is a identifier). "s" is
0058      * operatorStart, and "e" is operatorEnd.
0059      */
0060     struct ExpressionStackEntry {
0061         int startPosition;
0062         int operatorStart;
0063         int operatorEnd;
0064         int commas;
0065     };
0066 
0067     QList<KDevelop::CompletionTreeItemPointer> normalCompletion();
0068     QList<KDevelop::CompletionTreeItemPointer> commentCompletion();
0069     QList<KDevelop::CompletionTreeItemPointer> importCompletion();
0070     QList<KDevelop::CompletionTreeItemPointer> nodeModuleCompletions();
0071 
0072     QList<KDevelop::CompletionTreeItemPointer> functionCallTips();
0073     QList<KDevelop::CompletionTreeItemPointer> completionsFromImports(CompletionInContextFlags flags);
0074     QList<KDevelop::CompletionTreeItemPointer> completionsFromNodeModule(CompletionInContextFlags flags,
0075                                                                          const QString& module);
0076     QList<KDevelop::CompletionTreeItemPointer> completionsInContext(const KDevelop::DUContextPointer& context,
0077                                                                     CompletionInContextFlags flags,
0078                                                                     CompletionItem::Decoration decoration);
0079     QList<KDevelop::CompletionTreeItemPointer> fieldCompletions(const QString &expression,
0080                                                                 CompletionItem::Decoration decoration);
0081 
0082     KDevelop::Stack<ExpressionStackEntry> expressionStack(const QString& expression);    /*!< @see ExpressionStackEntry */
0083     KDevelop::DeclarationPointer declarationAtEndOfString(const QString& expression);
0084 
0085 private:
0086     enum CompletionKind {
0087         NoCompletion,           /*!< @brief No code-completion at all */
0088         NormalCompletion,       /*!< @brief Completion in a code context */
0089         CommentCompletion,      /*!< @brief Completion in comments */
0090         StringCompletion,       /*!< @brief Completion in strings */
0091         ImportCompletion,       /*!< @brief Completion for import statements */
0092         NodeModulesCompletion   /*!< @brief Completion for node.js module names */
0093     };
0094 
0095     CompletionKind m_completionKind;
0096     KDevelop::AbstractType::Ptr m_typeToMatch;
0097 };
0098 
0099 Q_DECLARE_OPERATORS_FOR_FLAGS(CodeCompletionContext::CompletionInContextFlags)
0100 
0101 }
0102 
0103 #endif // QMLJS_CONTEXT_H