File indexing completed on 2024-04-14 04:31:09

0001 /*
0002  * This file is part of KDevelop
0003  * Copyright (C) 2012-2015 Miquel Sabaté Solà <mikisabate@gmail.com>
0004  *
0005  * This program is free software: you can redistribute it and/or modify
0006  * it under the terms of the GNU General Public License as published by
0007  * the Free Software Foundation, either version 3 of the License, or
0008  * (at your option) any later version.
0009  *
0010  * This program is distributed in the hope that it will be useful,
0011  * but WITHOUT ANY WARRANTY; without even the implied warranty of
0012  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0013  * GNU General Public License for more details.
0014  *
0015  * You should have received a copy of the GNU General Public License
0016  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
0017  */
0018 
0019 
0020 #ifndef RUBY_COMPLETION_CONTEXT_H
0021 #define RUBY_COMPLETION_CONTEXT_H
0022 
0023 
0024 #include <language/codecompletion/codecompletioncontext.h>
0025 #include <language/duchain/types/abstracttype.h>
0026 #include <completion/completionexport.h>
0027 
0028 
0029 namespace KDevelop {
0030     class IncludeItem;
0031 }
0032 
0033 namespace ruby {
0034 
0035 enum class ContextType;
0036 
0037 /**
0038  * @class CodeCompletionContext
0039  *
0040  * This class handles the completion context for the Ruby language support.
0041  * It's responsible for finding out what kind of completion is needed, what
0042  * expression should be evaluated for the container-class of the completion,
0043  * what conversion will be applied to the result of the completion, etc.
0044  */
0045 class KDEVRUBYCOMPLETION_EXPORT CodeCompletionContext : public KDevelop::CodeCompletionContext
0046 {
0047     using DeclarationPair = QPair<KDevelop::Declaration *, int>;
0048     using Ptr = QExplicitlySharedDataPointer<CodeCompletionContext>;
0049 
0050 public:
0051     CodeCompletionContext(KDevelop::DUContextPointer ctxt,
0052                           const QString &text,
0053                           const QString &followingText,
0054                           const KDevelop::CursorInRevision &pos,
0055                           int depth = 0);
0056 
0057     ~CodeCompletionContext() override;
0058 
0059     /// Re-implemented from KDevelop::CodeCompletionContext.
0060     QList<KDevelop::CompletionTreeItemPointer> completionItems(bool &abort,
0061                                                                bool fullCompletion = true) override;
0062 
0063     /// Re-implemented from KDevelop::CodeCompletionContext.
0064     QList<KDevelop::CompletionTreeElementPointer> ungroupedElements() override;
0065 
0066 private:
0067     /**
0068      * @returns true if it's ok to offer code completion in the current
0069      * position. Returns false otherwise.
0070      */
0071     bool isValidPosition();
0072 
0073     /**
0074      * @returns true if this is a require/require_relative completion. If so,
0075      * it then fills the m_includeItems attribute with the requirable files.
0076      */
0077     bool doRequireCompletion();
0078 
0079     /**
0080      * @returns the type of the last expression from m_text that is at the
0081      * left side of the given @p token.
0082      */
0083     KDevelop::AbstractType::Ptr getExpressionType(const QString &token);
0084 
0085     /**
0086      * @returns the completion items for the given @p type. Set @p scoped to
0087      * true if you want to handle the case of MyModule::. Otherwise, it will
0088      * assume the case of obj.method.
0089      * @note that the type can be anything, even unsure.
0090      */
0091     QList<KDevelop::CompletionTreeItemPointer> getCompletionItemsFromType(KDevelop::AbstractType::Ptr type,
0092                                                                           bool scoped = false);
0093 
0094     /**
0095      * @returns the completion items for the given @p type which is not unsure.
0096      * @note this is just a helper method for the previous one, so you
0097      * shouldn't call this directly.
0098      */
0099     QList<KDevelop::CompletionTreeItemPointer> getCompletionItemsForOneType(KDevelop::AbstractType::Ptr type,
0100                                                                             bool scoped);
0101 
0102     /// @returns true if the parent items should be added to this one.
0103     bool shouldAddParentItems(bool fullCompletion);
0104 
0105     /// Item creation methods for various completion types.
0106 
0107     QList<KDevelop::CompletionTreeItemPointer> memberAccessItems();
0108     QList<KDevelop::CompletionTreeItemPointer> moduleMemberAccessItems();
0109     QList<KDevelop::CompletionTreeItemPointer> baseClassItems();
0110     QList<KDevelop::CompletionTreeItemPointer> moduleMixinItems();
0111     QList<KDevelop::CompletionTreeItemPointer> classMemberItems();
0112     QList<KDevelop::CompletionTreeItemPointer> fileChooseItems();
0113     QList<KDevelop::CompletionTreeItemPointer> standardAccessItems();
0114 
0115     /**
0116      * Creates the group and adds it to m_ungroupedItems.
0117      * @param name The name of the group. You should call i18n() first.
0118      * @param priority The given priority for this new group.
0119      * @param items The items that should constitute this new group.
0120      */
0121     void eventuallyAddGroup(const QString &name, int priority,
0122                             QList<KDevelop::CompletionTreeItemPointer> items);
0123 
0124     /// Group adding methods.
0125     void addRubyKeywords();
0126     void addRubySpecialBuiltins();
0127 
0128 private:
0129     bool m_valid;
0130     char m_closing;
0131     QString m_following;
0132     ContextType m_kind;
0133     QVector<KDevelop::IncludeItem> m_includeItems;
0134     QList<KDevelop::CompletionTreeElementPointer> m_ungroupedItems;
0135 };
0136 
0137 }
0138 
0139 
0140 #endif /* RUBY_COMPLETION_CONTEXT_H */