~ubuntu-branches/ubuntu/utopic/kdevelop-php/utopic

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
/*
   Copyright 2007 David Nolden <david.nolden.kdevelop@art-master.de>
   Copyright 2008 Hamish Rodda <rodda@kde.org>
   Copyright 2008 Niko Sams <niko.sams@gmail.com>

   This library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Library General Public
   License version 2 as published by the Free Software Foundation.

   This library is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   Library General Public License for more details.

   You should have received a copy of the GNU Library General Public License
   along with this library; see the file COPYING.LIB.  If not, write to
   the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
   Boston, MA 02110-1301, USA.
*/

#ifndef PHPCODECOMPLETIONCONTEXT_H
#define PHPCODECOMPLETIONCONTEXT_H

#include <ksharedptr.h>

#include <language/codecompletion/codecompletioncontext.h>
#include <language/duchain/types/abstracttype.h>

#include "phpcompletionexport.h"
#include "item.h"
#include "expressionevaluationresult.h"

namespace KTextEditor
{
class View;
class Cursor;
}

namespace KDevelop
{
class DUContext;
class ClassDeclaration;

class CompletionTreeItem;
typedef KSharedPtr<CompletionTreeItem> CompletionTreeItemPointer;

class SimpleCursor;
}

namespace Php
{

class TokenAccess;

/**
 * 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.
 * */
class KDEVPHPCOMPLETION_EXPORT CodeCompletionContext : public KDevelop::CodeCompletionContext
{
public:
    typedef KSharedPtr<CodeCompletionContext> Ptr;

    /**
     * To be used from the Worker. For parent/child contexts, use the private ctor that takes a TokenAccess.
     * That way we don't have to reparse the text over and over again.
     *
     * @param context The context in which code completion was requested.
     * @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.
     * @param followingText When @p position is inside a word, followingText will contain the text that follows.
     * @param position The position where code completion was requested.
     * @param depth Simple recursion counter.
     *
     * @warning The du-chain must be unlocked when this is called.
     * */
    CodeCompletionContext(KDevelop::DUContextPointer context, const QString& text,
                          const QString& followingText, const KDevelop::CursorInRevision& position,
                          int depth = 0);
    ~CodeCompletionContext();

    ///Computes the full set of completion items, using the information retrieved earlier.
    ///Should only be called on the first context, parent contexts are included in the computations.
    ///@param Abort is checked regularly, and if it is false, the computation is aborted.
    virtual QList<KDevelop::CompletionTreeItemPointer> completionItems(bool& abort, bool fullCompletion = true);

    enum MemberAccessOperation {
        NoMemberAccess,  ///With NoMemberAccess, a global completion should be done
        MemberAccess,      ///klass->
        FunctionCallAccess,  ///"function(". Will never appear as initial access-operation, but as parentContext() access-operation.
        StaticMemberAccess, ///klass::
        NewClassChoose, /// after the "new" keyword any non-abstract classes (not interfaces) should be shown
        ClassExtendsChoose, /// after "class XYZ extends" any non-final classes should be shown
        InterfaceChoose, /// after the "implements" keyword or after "interface XYZ extends" any interfaces should be shown
        InstanceOfChoose, /// after the "instanceof" operator, any class-type should be shown
        ExceptionChoose, /// after keywords "catch" and "throw new" only classes which extend Exception should be shown
        ExceptionInstanceChoose, /// after the "throw" keyword instancec of the exception class should be shown
        ClassMemberChoose, /// in class context show list of overloadable or implementable methods
        /// and typical keywords for classes, i.e. access modifiers, static etc.
        FileChoose, /// autocompletion for files
        NamespaceChoose, /// autocompletion after namespace keyword
        BackslashAccess /// autocompletion after backslash token
    };

    ///@return the used access-operation
    MemberAccessOperation memberAccessOperation() const;

    ExpressionEvaluationResult memberAccessContainer() const;

    /**
     * Returns the internal context of memberAccessContainer, if any.
     *
     * When memberAccessOperation is StaticMemberChoose, this returns all
     * fitting namespace-contexts.
     * */
    QList<KDevelop::DUContext*> memberAccessContainers() const;

    /**
     * When memberAccessOperation is FunctionCallAccess,
     * this returns all functions available for matching, together with the argument-number that should be matched.
     * */
    const QList<KDevelop::AbstractFunctionDeclaration*>& functions() const;

    virtual CodeCompletionContext* parentContext();

protected:
    virtual QList<QSet<KDevelop::IndexedString> > completionFiles();
    inline bool isValidCompletionItem(KDevelop::Declaration* dec);

private:
    /**
     * Internal ctor to use when you want to create parent contexts.
     *
     * NOTE: Since you pass the TokenAccess, it's not save to use
     *       it afterwards. Probably you don't want to do that anyway.
     *       Hence always return after creating the parent.
     */
    CodeCompletionContext(KDevelop::DUContextPointer context, const KDevelop::CursorInRevision& position,
                            TokenAccess& lastToken, const int depth);

    /**
     * Evaluate expression for the given @p lastToken.
     */
    void evaluateExpression(TokenAccess& lastToken);

    MemberAccessOperation m_memberAccessOperation;
    ExpressionEvaluationResult m_expressionResult;
    QString m_expression;
    bool m_parentAccess;
    /// If we do file completion after dirname(__FILE__) or in PHP 5.3 after __DIR__
    /// relative URLS have to start with a /
    bool m_isFileCompletionAfterDirname;
    /**
     * a list of indizes of identifiers which must not be added as completion items
     * examples:
     * class test implements foo, ...
     * => identifiers test and foo must not be proposed for completion
     **/
    QList<uint> m_forbiddenIdentifiers;
    /// filled only during BackslashAccess and NamespaceChoose
    KDevelop::QualifiedIdentifier m_namespace;

    void forbidIdentifier(const QString &identifier);
    void forbidIdentifier(KDevelop::ClassDeclaration* identifier);
};
}

#endif