File indexing completed on 2024-05-05 16:41:31

0001 /*
0002     SPDX-FileCopyrightText: 2011-2013 Sven Brauch <svenbrauch@googlemail.com>
0003 
0004     SPDX-License-Identifier: GPL-2.0-or-later
0005 */
0006 
0007 #ifndef PYTHONCODECOMPLETIONCONTEXT_H
0008 #define PYTHONCODECOMPLETIONCONTEXT_H
0009 
0010 #include <language/codecompletion/codecompletioncontext.h>
0011 #include <language/duchain/duchainpointer.h>
0012 #include <QStack>
0013 
0014 #include <QObject>
0015 
0016 #include "items/importfile.h"
0017 #include "worker.h"
0018 #include "pythoncompletionexport.h"
0019 #include "helpers.h"
0020 #include "types/unsuretype.h"
0021 
0022 using namespace KDevelop;
0023 
0024 namespace KDevelop {
0025     class IProject;
0026     class ProjectFolderItem;
0027 }
0028 
0029 namespace Python {
0030     
0031 typedef QPair<Declaration*, int> DeclarationDepthPair;
0032 
0033 /**
0034  * @brief Represents a single pair of directory and remaining identifiers, for include completion.
0035  * 
0036  * In the directory, the functions in PythonCodeCompletionContext try to resolve the remaining
0037  * identifiers. If the identifier list is empty, the __init__.py file will be read.
0038  **/
0039 class IncludeSearchTarget {
0040 public:
0041     IncludeSearchTarget(QUrl d_, QStringList r_) : directory(d_), remainingIdentifiers(r_) {
0042         directory.setPath(QDir::cleanPath(directory.path()));
0043     };
0044     QUrl directory;
0045     QStringList remainingIdentifiers;
0046 };
0047 
0048 class KDEVPYTHONCOMPLETION_EXPORT PythonCodeCompletionContext : public KDevelop::CodeCompletionContext
0049 {
0050 public:
0051     enum CompletionContextType {
0052         ImportFileCompletion,
0053         MemberAccessCompletion,
0054         DefaultCompletion,
0055         ImportSubCompletion,
0056         NoCompletion,
0057         NewStatementCompletion,
0058         DefineCompletion,
0059         ShebangLineCompletion,
0060         FunctionCallCompletion,
0061         InheritanceCompletion,
0062         RaiseExceptionCompletion,
0063         GeneratorVariableCompletion,
0064         StringFormattingCompletion
0065     };
0066     
0067     enum ItemTypeHint {
0068         NoHint,
0069         IterableRequested, // < the requested item should be iterable, e.g. a list
0070         ClassTypeRequested // < the requested item should be a class type
0071     };
0072     
0073     PythonCodeCompletionContext(DUContextPointer context, const QString& text, const QString& followingText,
0074                                 const KDevelop::CursorInRevision& position,
0075                                 int depth, const PythonCodeCompletionWorker* parent);
0076 
0077     CompletionContextType completionContextType();
0078 
0079     ItemTypeHint itemTypeHint();
0080 
0081     /**
0082      * @brief The "interface method" which returns all the completion items to kdevelop.
0083      **/
0084     QList< KDevelop::CompletionTreeItemPointer > completionItems(bool& abort, bool fullCompletion = true) override;
0085 
0086     QList< CompletionTreeElementPointer > ungroupedElements() override;
0087     
0088     /**
0089      * @brief Get all possible items matching the specified dot-separated search string.
0090      **/
0091     QList<CompletionTreeItemPointer> includeItemsForSubmodule(QString submodule);
0092     
0093     /**
0094      * @brief Get all include items for the given target list.
0095      **/
0096     QList< CompletionTreeItemPointer > findIncludeItems(IncludeSearchTarget);
0097     /**
0098      * @brief Get all include items for the given single target.
0099      **/
0100     QList< CompletionTreeItemPointer > findIncludeItems(QList< Python::IncludeSearchTarget > items);
0101     
0102     /**
0103      * @brief Get all contexts to list declarations from for the given item.
0104      **/
0105     DUContext* internalContextForDeclaration(TopDUContext* topContext, QStringList remainingIdentifiers);
0106     
0107     /**
0108      * @brief Get all items that are attributes of the given type. @param type might be any type.
0109      **/
0110     QList<CompletionTreeItemPointer> getCompletionItemsForType(AbstractType::Ptr type);
0111     /**
0112      * @brief Get all items that are attributes of the given type. @param type must be non-unsure.
0113      **/
0114     QList<CompletionTreeItemPointer> getCompletionItemsForOneType(AbstractType::Ptr type);
0115     
0116     /**
0117      * @brief Convert the given list of declarations to a list of include-items.
0118      * Convenience function.
0119      **/
0120     QList<CompletionTreeItemPointer> declarationListToItemList(const QVector<DeclarationDepthPair>& declarations, int maxDepth = 0);
0121     QList<CompletionTreeItemPointer> declarationListToItemList(QList<Declaration*> declarations);
0122     
0123 private:
0124     /// This constructor is only used for recursive calltips
0125     PythonCodeCompletionContext(DUContextPointer context, const QString& remainingText,
0126                                 QString calledFunction, int depth, int alreadyGivenParameters, CodeCompletionContext* child);
0127     void summonParentForEventualCall(TokenList tokens, const QString& text);
0128     /// Get possible "add import..." items for an expression.
0129     QList< CompletionTreeItemPointer > getMissingIncludeItems(QString forString);
0130     void eventuallyAddGroup(QString name, int priority, QList<CompletionTreeItemPointer> items);
0131 
0132 private:
0133     /// Item generating functions
0134     using ItemList = QList<CompletionTreeItemPointer>;
0135     ItemList shebangItems();
0136     ItemList generatorItems();
0137     ItemList functionCallItems();
0138     ItemList defineItems();
0139     ItemList raiseItems();
0140     ItemList importFileItems();
0141     ItemList inheritanceItems();
0142     ItemList memberAccessItems();
0143     ItemList stringFormattingItems();
0144     ItemList keywordItems();
0145     ItemList classMemberInitItems();
0146 
0147 private:
0148     CompletionContextType m_operation;
0149     ItemTypeHint m_itemTypeHint;
0150     QStack<ProjectFolderItem*> m_folderStack;
0151     int m_maxFolderScanDepth;
0152     QStringList m_searchingForModule;
0153     QString m_searchImportItemsInModule;
0154     QUrl m_workingOnDocument;
0155     
0156     CodeCompletionContext* m_child;
0157     
0158     QString m_guessTypeOfExpression;
0159     QString m_followingText;
0160     
0161     QString m_indent;
0162     KDevelop::CursorInRevision m_position;
0163     
0164     QString m_calledFunction;
0165     int m_alreadyGivenParametersCount;
0166 
0167     QString m_matchAgainst;
0168 
0169     bool m_fullCompletion;
0170 
0171     QList<CompletionTreeElementPointer> m_storedGroups;
0172 };
0173 
0174 }
0175 
0176 #endif // PYTHONCODECOMPLETIONCONTEXT_H