1
/***************************************************************************
2
* This file is part of KDevelop *
3
* Copyright 2008 Niko Sams <niko.sams@gmail.com> *
5
* This program is free software; you can redistribute it and/or modify *
6
* it under the terms of the GNU Library General Public License as *
7
* published by the Free Software Foundation; either version 2 of the *
8
* License, or (at your option) any later version. *
10
* This program is distributed in the hope that it will be useful, *
11
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13
* GNU General Public License for more details. *
15
* You should have received a copy of the GNU Library General Public *
16
* License along with this program; if not, write to the *
17
* Free Software Foundation, Inc., *
18
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
19
***************************************************************************/
21
#ifndef DECLARATIONBUILDER_H
22
#define DECLARATIONBUILDER_H
24
#include "typebuilder.h"
26
#include <language/duchain/classdeclaration.h>
27
#include <language/duchain/builders/abstractdeclarationbuilder.h>
36
class EditorIntegrator;
37
class ClassDeclaration;
38
class FunctionDeclaration;
40
typedef KDevelop::AbstractDeclarationBuilder<AstNode, IdentifierAst, Php::TypeBuilder> DeclarationBuilderBase;
43
* The DeclarationBuilder builds declarations, types and contexts for everything in a AST.
45
* \note Since PHP allows the usage of functions, classes and interfaces before definition,
46
* a \see PreDeclarationBuilder is used to get the declarations _and_ types for those.
47
* Thus type- and declaratoinbuilding for these is skipped in this class.
49
class KDEVPHPDUCHAIN_EXPORT DeclarationBuilder : public DeclarationBuilderBase
52
DeclarationBuilder(ParseSession* session)
53
: m_findVariable(false), m_variableIsArray(false), m_currentModifers(0) {
56
DeclarationBuilder(EditorIntegrator* editor)
57
: m_findVariable(false), m_variableIsArray(false), m_currentModifers(0) {
60
virtual KDevelop::ReferencedTopDUContext build(const KDevelop::IndexedString& url, Php::AstNode* node,
61
KDevelop::ReferencedTopDUContext updateContext
62
= KDevelop::ReferencedTopDUContext(), bool useSmart = true);
64
virtual void startVisiting(AstNode* node);
67
virtual void visitClassDeclarationStatement(ClassDeclarationStatementAst *node);
68
virtual void visitInterfaceDeclarationStatement(InterfaceDeclarationStatementAst *node);
69
virtual void visitClassStatement(ClassStatementAst *node);
70
virtual void visitClassExtends(ClassExtendsAst *node);
71
virtual void visitClassImplements(ClassImplementsAst *node);
72
virtual void visitParameter(ParameterAst *node);
73
virtual void visitFunctionDeclarationStatement(FunctionDeclarationStatementAst *node);
74
virtual void visitClassVariable(ClassVariableAst *node);
75
virtual void visitClassConstantDeclaration(ClassConstantDeclarationAst *node);
76
virtual void visitTopStatement(TopStatementAst* node);
77
virtual void visitAssignmentExpression(AssignmentExpressionAst* node);
78
virtual void visitAssignmentExpressionEqual(AssignmentExpressionEqualAst *node);
79
virtual void visitVariable(VariableAst* node);
80
virtual void visitFunctionCall(FunctionCallAst* node);
81
virtual void visitFunctionCallParameterList(FunctionCallParameterListAst* node);
82
virtual void visitFunctionCallParameterListElement(FunctionCallParameterListElementAst* node);
83
virtual void visitStatement(StatementAst* node);
84
virtual void visitStaticVar(StaticVarAst* node);
85
virtual void visitGlobalVar(GlobalVarAst* node);
86
virtual void visitCatchItem(CatchItemAst *node);
87
virtual void visitUnaryExpression( UnaryExpressionAst* node );
88
virtual void visitAssignmentListElement(AssignmentListElementAst* node);
90
/// checks whether the body is empty (i.e. equals ";" instead of "{...}")
91
bool isEmptyMethodBody(const Php::MethodBodyAst* body) const {
92
return !body || !body->statements;
95
virtual void closeDeclaration();
96
void classContextOpened(KDevelop::DUContext* context);
98
/// don't forget to closeDeclaration() afterwards
99
/// set m_currentModifers to your likings and reset it afterwards
100
void openClassMemberDeclaration(Php::AstNode* node, const KDevelop::QualifiedIdentifier& name);
102
virtual void updateCurrentType();
105
/// because the predeclarationbuilder runs before us,
106
/// we always "think" that we are recompiling, while this is not neccessarily true
107
bool m_actuallyRecompiling;
109
/// Set this to true if you want to catch any variable in the lower AST tree
111
/// If the found variable is accessed as an array ($var[...]) this is set to true.
112
/// @see m_findVariable
113
bool m_variableIsArray;
114
/// The identifier for the found variable.
115
/// @see m_findVariable
116
KDevelop::QualifiedIdentifier m_variable;
117
/// The identifier for the parent of the found variable. Empty if
118
/// the found variable is not a class member.
119
/// @see m_findVariable
120
KDevelop::QualifiedIdentifier m_variableParent;
121
/// The AstNode of the found variable. Use this for declarations.
122
/// @see m_findVariable
123
AstNode* m_variableNode;
125
/// The position of the current argument, will only be set inside function calls.
126
int m_functionCallParameterPos;
127
/// Type of the current function, will only be set inside function calls.
128
KDevelop::FunctionType::Ptr m_currentFunctionType;
130
unsigned int m_currentModifers;
131
QString m_lastTopStatementComment;
133
QHash<qint64, Php::ClassDeclaration*> m_types;
134
QHash<qint64, Php::FunctionDeclaration*> m_functions;
135
QList<KDevelop::QualifiedIdentifier> m_upcomingClassVariables;
137
/// handles common stuff for both interfaces and classes
138
Php::ClassDeclaration* openTypeDeclaration(IdentifierAst *name, KDevelop::ClassDeclarationData::ClassType type);
140
/// check if this declaration is already declared
141
bool isGlobalRedeclaration(const KDevelop::QualifiedIdentifier &identifier, AstNode *node,
142
DeclarationType type);
143
/// check if a non-abstract method declaration tries to overwrite a final base method
144
/// or whether a abstract method is redeclared
145
/// @param identifier The identifier for the current method
146
/// @param curClass the current class we are in
147
/// @param node the node we are processing, used to access modifiers and for error reporting
148
bool isBaseMethodRedeclaration(const IdentifierPair &ids, Php::ClassDeclaration *curClass,
149
ClassStatementAst *node);
150
/// reports a redeclaration error for the given node
151
/// @param declaration the old declaration
152
/// @param node the AstNode which resembles the redeclaration
153
void reportRedeclarationError(KDevelop::Declaration* declaration, AstNode *node);
156
* Get the interesting identifiers out of a VariableAst node:
157
* $var yields @p id = 'var', @p parent = ''
158
* $var->asdf yields @p id = 'asdf', @p parent = 'asdf'
159
* $var->...->foo->bar yields @p id = 'bar', @p parent => 'foo'
161
* @note If the parent or the identifier itself end on an array access, e.g. $var[0] or
162
* $var->...->parent[0]->bar, @p arrayAccess will be set to true.
164
* @param id the last identifier
165
* @param parent the parent of the last identifier
166
* @param lastNode the node of the last identifier
167
* @param arrayAccess the node actually ends on an array access, like $node->var->..->asdf[0]
169
void getVariableIdentifier(VariableAst *node,
170
KDevelop::QualifiedIdentifier &id,
171
KDevelop::QualifiedIdentifier &parent,
172
AstNode* &targetNode,
176
* Declare a class member in @p parentCtx. Validates whether the current context allowes
177
* redeclaration of private/protected members.
179
* @param parentCtx The class context you want to add the member to.
180
* @param type The type of the member.
181
* @param identifier The identifier of the member.
182
* @param node The node of the member.
184
void declareClassMember(KDevelop::DUContext *parentCtx, KDevelop::AbstractType::Ptr type,
185
const KDevelop::QualifiedIdentifier& identifier, AstNode* node );
188
* Declare a variable in @p parentCtx. If the the variable is already defined in the
189
* context and it's last type equals @p type, don't do anything.
191
* @param parentCtx The context you want to declare the variable in.
192
* @param type The type of the variable
193
* @param identifier The identifier for the variable.
194
* @param node The node for the variable.
196
void declareVariable(KDevelop::DUContext *parentCtx, KDevelop::AbstractType::Ptr type,
197
const KDevelop::QualifiedIdentifier& identifier, AstNode* node );
200
* Wrapper that operates declares the found variable. It will declare it
201
* either as a class member or as a variable, depending whether a parent was found.
203
* It will also check whether that var also exists and if so, won't do anything.
205
* @param type When the var gets declared, this will be it's type.
207
* @see m_findVariable
208
* @see declareClassMeember
209
* @see declareVariable
211
void declareFoundVariable(KDevelop::AbstractType* type);
216
#endif // DECLARATIONBUILDER_H