File indexing completed on 2024-05-05 04:35:34

0001 /*
0002     SPDX-FileCopyrightText: 2007 David Nolden <david.nolden.kdevelop@art-master.de>
0003     SPDX-FileCopyrightText: 2008 Hamish Rodda <rodda@kde.org>
0004     SPDX-FileCopyrightText: 2008 Niko Sams <niko.sams@gmail.com>
0005 
0006     SPDX-License-Identifier: LGPL-2.0-only
0007 */
0008 
0009 #ifndef PHPCODECOMPLETIONCONTEXT_H
0010 #define PHPCODECOMPLETIONCONTEXT_H
0011 
0012 #include <language/codecompletion/codecompletioncontext.h>
0013 #include <language/duchain/types/abstracttype.h>
0014 
0015 #include "phpcompletionexport.h"
0016 #include "item.h"
0017 #include "expressionevaluationresult.h"
0018 
0019 namespace KTextEditor
0020 {
0021 class View;
0022 class Cursor;
0023 }
0024 
0025 namespace KDevelop
0026 {
0027 class DUContext;
0028 class ClassDeclaration;
0029 
0030 class CompletionTreeItem;
0031 
0032 class SimpleCursor;
0033 }
0034 
0035 namespace Php
0036 {
0037 
0038 class TokenAccess;
0039 
0040 /**
0041  * This class is responsible for finding out what kind of completion is needed, what expression should be evaluated for the container-class of the completion, what conversion will be applied to the result of the completion, etc.
0042  * */
0043 class KDEVPHPCOMPLETION_EXPORT CodeCompletionContext : public KDevelop::CodeCompletionContext
0044 {
0045 public:
0046     typedef QExplicitlySharedDataPointer<CodeCompletionContext> Ptr;
0047 
0048     /**
0049      * To be used from the Worker. For parent/child contexts, use the private ctor that takes a TokenAccess.
0050      * That way we don't have to reparse the text over and over again.
0051      *
0052      * @param context The context in which code completion was requested.
0053      * @param text The text before @p position. It usually is the text in the range starting at the beginning of the context, and ending at the position where completion should start.
0054      * @param followingText When @p position is inside a word, followingText will contain the text that follows.
0055      * @param position The position where code completion was requested.
0056      * @param depth Simple recursion counter.
0057      *
0058      * @warning The du-chain must be unlocked when this is called.
0059      */
0060     CodeCompletionContext(KDevelop::DUContextPointer context, const QString& text,
0061                           const QString& followingText, const KDevelop::CursorInRevision& position,
0062                           int depth = 0);
0063     ~CodeCompletionContext() override;
0064 
0065     /// Computes the full set of completion items, using the information retrieved earlier.
0066     /// Should only be called on the first context, parent contexts are included in the computations.
0067     /// @param abort is checked regularly, and if it is false, the computation is aborted.
0068     QList<KDevelop::CompletionTreeItemPointer> completionItems(bool& abort, bool fullCompletion = true) override;
0069 
0070     enum MemberAccessOperation {
0071         NoMemberAccess,  ///With NoMemberAccess, a global completion should be done
0072         MemberAccess,      ///klass->
0073         FunctionCallAccess,  ///"function(". Will never appear as initial access-operation, but as parentContext() access-operation.
0074         StaticMemberAccess, ///klass::
0075         NewClassChoose, /// after the "new" keyword any non-abstract classes (not interfaces) should be shown
0076         ClassExtendsChoose, /// after "class XYZ extends" any non-final classes should be shown
0077         InterfaceChoose, /// after the "implements" keyword or after "interface XYZ extends" any interfaces should be shown
0078         InstanceOfChoose, /// after the "instanceof" operator, any class-type should be shown
0079         ExceptionChoose, /// after keywords "catch" and "throw new" only classes which extend Exception should be shown
0080         ExceptionInstanceChoose, /// after the "throw" keyword instancec of the exception class should be shown
0081         ClassMemberChoose, /// in class context show list of overloadable or implementable methods
0082         /// and typical keywords for classes, i.e. access modifiers, static etc.
0083         FileChoose, /// autocompletion for files
0084         NamespaceChoose, /// autocompletion after namespace keyword
0085         BackslashAccess /// autocompletion after backslash token
0086     };
0087 
0088     /// @return the used access-operation
0089     MemberAccessOperation memberAccessOperation() const;
0090 
0091     ExpressionEvaluationResult memberAccessContainer() const;
0092 
0093     /**
0094      * Returns the internal context of memberAccessContainer, if any.
0095      *
0096      * When memberAccessOperation is StaticMemberChoose, this returns all
0097      * fitting namespace-contexts.
0098      */
0099     QList<KDevelop::DUContext*> memberAccessContainers() const;
0100 
0101     /**
0102      * When memberAccessOperation is FunctionCallAccess,
0103      * this returns all functions available for matching, together with the argument-number that should be matched.
0104      */
0105     const QList<KDevelop::AbstractFunctionDeclaration*>& functions() const;
0106 
0107     virtual CodeCompletionContext* parentContext();
0108 
0109 protected:
0110     virtual QList<QSet<KDevelop::IndexedString> > completionFiles();
0111     inline bool isValidCompletionItem(KDevelop::Declaration* dec);
0112 
0113 private:
0114     /**
0115      * Internal ctor to use when you want to create parent contexts.
0116      *
0117      * NOTE: Since you pass the TokenAccess, it's not save to use
0118      *       it afterwards. Probably you don't want to do that anyway.
0119      *       Hence always return after creating the parent.
0120      */
0121     CodeCompletionContext(KDevelop::DUContextPointer context, const KDevelop::CursorInRevision& position,
0122                             TokenAccess& lastToken, const int depth);
0123 
0124     /**
0125      * Evaluate expression for the given @p lastToken.
0126      */
0127     void evaluateExpression(TokenAccess& lastToken);
0128 
0129     MemberAccessOperation m_memberAccessOperation;
0130     ExpressionEvaluationResult m_expressionResult;
0131     QString m_expression;
0132     bool m_parentAccess;
0133     /// If we do file completion after dirname(__FILE__) or in PHP 5.3 after __DIR__
0134     /// relative URLS have to start with a /
0135     bool m_isFileCompletionAfterDirname;
0136     /**
0137      * a list of indizes of identifiers which must not be added as completion items
0138      * examples:
0139      * class test implements foo, ...
0140      * => identifiers test and foo must not be proposed for completion
0141      **/
0142     QList<uint> m_forbiddenIdentifiers;
0143     /// filled only during BackslashAccess and NamespaceChoose
0144     KDevelop::QualifiedIdentifier m_namespace;
0145 
0146     void forbidIdentifier(const QString &identifier);
0147     void forbidIdentifier(KDevelop::ClassDeclaration* identifier);
0148 };
0149 }
0150 
0151 #endif