File indexing completed on 2024-05-05 16:41:06
0001 /* 0002 SPDX-FileCopyrightText: 2008 Niko Sams <niko.sams@gmail.com> 0003 0004 SPDX-License-Identifier: LGPL-2.0-or-later 0005 */ 0006 0007 #ifndef DECLARATIONBUILDER_H 0008 #define DECLARATIONBUILDER_H 0009 0010 #include "typebuilder.h" 0011 #include "helper.h" 0012 #include <language/duchain/classdeclaration.h> 0013 #include <language/duchain/builders/abstractdeclarationbuilder.h> 0014 0015 namespace KDvelop 0016 { 0017 class Declaration; 0018 } 0019 namespace Php 0020 { 0021 class ParseSession; 0022 class EditorIntegrator; 0023 class ClassDeclaration; 0024 class FunctionDeclaration; 0025 class NamespaceDeclaration; 0026 0027 typedef KDevelop::AbstractDeclarationBuilder<AstNode, IdentifierAst, TypeBuilder> DeclarationBuilderBase; 0028 0029 /** 0030 * The DeclarationBuilder builds declarations, types and contexts for everything in a AST. 0031 * 0032 * \note Since PHP allows the usage of functions, classes and interfaces before definition, 0033 * a \see PreDeclarationBuilder is used to get the declarations _and_ types for those. 0034 * Thus type- and declaratoinbuilding for these is skipped in this class. 0035 */ 0036 class KDEVPHPDUCHAIN_EXPORT DeclarationBuilder : public DeclarationBuilderBase 0037 { 0038 public: 0039 DeclarationBuilder(EditorIntegrator* editor) 0040 : m_currentModifers(0) 0041 { 0042 m_editor = editor; 0043 m_findVariable.find = false; 0044 m_useNamespaceType = ClassDeclarationType; 0045 } 0046 KDevelop::ReferencedTopDUContext build(const KDevelop::IndexedString& url, AstNode* node, 0047 const KDevelop::ReferencedTopDUContext& updateContext 0048 = KDevelop::ReferencedTopDUContext()) override; 0049 0050 void startVisiting(AstNode* node) override; 0051 0052 protected: 0053 void visitClassDeclarationStatement(ClassDeclarationStatementAst *node) override; 0054 void visitInterfaceDeclarationStatement(InterfaceDeclarationStatementAst *node) override; 0055 void visitTraitDeclarationStatement(TraitDeclarationStatementAst *node) override; 0056 void visitClassStatement(ClassStatementAst *node) override; 0057 virtual void importTraitMethods(ClassStatementAst *node); 0058 void visitClassExtends(ClassExtendsAst *node) override; 0059 void visitClassImplements(ClassImplementsAst *node) override; 0060 void visitParameterList(ParameterListAst *node) override; 0061 void visitParameter(ParameterAst *node) override; 0062 void visitFunctionDeclarationStatement(FunctionDeclarationStatementAst *node) override; 0063 void visitGenericTypeHint(GenericTypeHintAst *node) override; 0064 void visitClassVariable(ClassVariableAst *node) override; 0065 void visitConstantDeclaration(ConstantDeclarationAst *node) override; 0066 void visitClassConstantDeclaration(ClassConstantDeclarationAst *node) override; 0067 void visitTraitAliasStatement(TraitAliasStatementAst *node) override; 0068 virtual void createTraitAliasDeclarations(TraitAliasStatementAst *node, KDevelop::DeclarationPointer dec); 0069 void visitOuterTopStatement(OuterTopStatementAst* node) override; 0070 void visitAssignmentExpression(AssignmentExpressionAst* node) override; 0071 void visitAssignmentExpressionEqual(AssignmentExpressionEqualAst *node) override; 0072 void visitVariable(VariableAst* node) override; 0073 void visitFunctionCall(FunctionCallAst* node) override; 0074 void visitFunctionCallParameterList(FunctionCallParameterListAst* node) override; 0075 void visitFunctionCallParameterListElement(FunctionCallParameterListElementAst* node) override; 0076 void visitStatement(StatementAst* node) override; 0077 void visitStaticVar(StaticVarAst* node) override; 0078 void visitGlobalVar(GlobalVarAst* node) override; 0079 void visitCatchItem(CatchItemAst *node) override; 0080 void visitUnaryExpression( UnaryExpressionAst* node ) override; 0081 void visitAssignmentListElement(AssignmentListElementAst* node) override; 0082 void openNamespace(NamespaceDeclarationStatementAst* parent, IdentifierAst* node, const IdentifierPair& identifier, const KDevelop::RangeInRevision& range) override; 0083 void closeNamespace(NamespaceDeclarationStatementAst* parent, IdentifierAst* node, const IdentifierPair& identifier) override; 0084 void visitUseStatement(UseStatementAst* node) override; 0085 void visitUseNamespaceOrUseGroupedNamespace(UseNamespaceOrUseGroupedNamespaceAst* node) override; 0086 void visitNonGroupedUseNamespace(UseNamespaceOrUseGroupedNamespaceAst* node); 0087 void visitClosure(ClosureAst* node) override; 0088 void visitLexicalVar(LexicalVarAst* node) override; 0089 void visitVarExpression(VarExpressionAst* node) override; 0090 0091 /// checks whether the body is empty (i.e. equals ";" instead of "{...}") 0092 bool isEmptyMethodBody(const MethodBodyAst* body) const { 0093 return !body || !body->statements; 0094 } 0095 0096 void closeDeclaration() override; 0097 void classContextOpened(KDevelop::DUContext* context) override; 0098 0099 void supportBuild(AstNode* node, KDevelop::DUContext* context = nullptr) override; 0100 void closeContext() override; 0101 0102 /// don't forget to closeDeclaration() afterwards 0103 /// set m_currentModifers to your likings and reset it afterwards 0104 void openClassMemberDeclaration(AstNode* node, const KDevelop::QualifiedIdentifier& name); 0105 0106 void updateCurrentType() override; 0107 0108 private: 0109 /// because the predeclarationbuilder runs before us, 0110 /// we always "think" that we are recompiling, while this is not necessarily true 0111 bool m_actuallyRecompiling; 0112 0113 struct FindVariableResults { 0114 /// Set this to true if you want to catch any variable in the lower AST tree 0115 bool find; 0116 /// If the found variable is accessed as an array ($var[...]) this is set to true. 0117 /// @see m_findVariable 0118 bool isArray; 0119 /// The identifier for the found variable. 0120 /// @see m_findVariable 0121 KDevelop::QualifiedIdentifier identifier; 0122 /// The identifier for the parent of the found variable. Empty if 0123 /// the found variable is not a class member. 0124 /// @see m_findVariable 0125 KDevelop::QualifiedIdentifier parentIdentifier; 0126 /// The AstNode of the found variable. Use this for declarations. 0127 /// @see m_findVariable 0128 AstNode* node; 0129 0130 FindVariableResults(); 0131 }; 0132 FindVariableResults m_findVariable; 0133 0134 /// The position of the current argument, will only be set inside function calls. 0135 int m_functionCallParameterPos; 0136 /// Type of the current function, will only be set inside function calls. 0137 KDevelop::FunctionType::Ptr m_currentFunctionType; 0138 /// The AstNode of the previous function declaration argument 0139 ParameterAst *m_functionDeclarationPreviousArgument = nullptr; 0140 /// The AstNode of the previous function call argument 0141 FunctionCallParameterListElementAst *m_functionCallPreviousArgument = nullptr; 0142 /// Type of use 0143 DeclarationType m_useNamespaceType; 0144 0145 unsigned int m_currentModifers; 0146 QString m_lastTopStatementComment; 0147 0148 QHash<qint64, ClassDeclaration*> m_types; 0149 QHash<qint64, FunctionDeclaration*> m_functions; 0150 QHash<qint64, NamespaceDeclaration*> m_namespaces; 0151 QVector<KDevelop::QualifiedIdentifier> m_upcomingClassVariables; 0152 0153 /// handles common stuff for both interfaces and classes 0154 ClassDeclaration* openTypeDeclaration(IdentifierAst *name, KDevelop::ClassDeclarationData::ClassType type); 0155 0156 /// check if this declaration is already declared 0157 bool isGlobalRedeclaration(const KDevelop::QualifiedIdentifier &identifier, AstNode *node, 0158 DeclarationType type); 0159 /// check if a non-abstract method declaration tries to overwrite a final base method 0160 /// or whether a abstract method is redeclared 0161 /// @param ids The identifier for the current method 0162 /// @param curClass the current class we are in 0163 /// @param node the node we are processing, used to access modifiers and for error reporting 0164 bool isBaseMethodRedeclaration(const IdentifierPair &ids, ClassDeclaration *curClass, 0165 ClassStatementAst *node); 0166 /// reports a redeclaration error for the given node 0167 /// @param declaration the old declaration 0168 /// @param node the AstNode which resembles the redeclaration 0169 void reportRedeclarationError(KDevelop::Declaration* declaration, AstNode *node); 0170 0171 /** 0172 * Get the interesting identifiers out of a VariableAst node: 0173 * $var yields @p id = 'var', @p parent = '' 0174 * $var->asdf yields @p id = 'asdf', @p parent = 'asdf' 0175 * $var->...->foo->bar yields @p id = 'bar', @p parent => 'foo' 0176 * 0177 * @note If the parent or the identifier itself end on an array access, e.g. $var[0] or 0178 * $var->...->parent[0]->bar, @p arrayAccess will be set to true. 0179 * 0180 * @param id the last identifier 0181 * @param parent the parent of the last identifier 0182 * @param targetNode the node of the last identifier 0183 * @param arrayAccess the node actually ends on an array access, like $node->var->..->asdf[0] 0184 */ 0185 void getVariableIdentifier(VariableAst *node, 0186 KDevelop::QualifiedIdentifier &id, 0187 KDevelop::QualifiedIdentifier &parent, 0188 AstNode* &targetNode, 0189 bool &arrayAccess); 0190 0191 /** 0192 * Declare a class member in @p parentCtx. Validates whether the current context allows 0193 * redeclaration of private/protected members. 0194 * 0195 * @param parentCtx The class context you want to add the member to. 0196 * @param type The type of the member. 0197 * @param identifier The identifier of the member. 0198 * @param node The node of the member. 0199 */ 0200 void declareClassMember(KDevelop::DUContext *parentCtx, KDevelop::AbstractType::Ptr type, 0201 const KDevelop::QualifiedIdentifier& identifier, AstNode* node ); 0202 0203 /** 0204 * Declare a variable in @p parentCtx. If the variable is already defined in the 0205 * context and it's last type equals @p type, don't do anything. 0206 * 0207 * @param parentCtx The context you want to declare the variable in. 0208 * @param type The type of the variable 0209 * @param identifier The identifier for the variable. 0210 * @param node The node for the variable. 0211 */ 0212 void declareVariable(KDevelop::DUContext *parentCtx, KDevelop::AbstractType::Ptr type, 0213 const KDevelop::QualifiedIdentifier& identifier, AstNode* node ); 0214 0215 /** 0216 * Wrapper that operates declares the found variable. It will declare it 0217 * either as a class member or as a variable, depending whether a parent was found. 0218 * 0219 * It will also check whether that var also exists and if so, won't do anything. 0220 * 0221 * @param type When the var gets declared, this will be it's type. 0222 * 0223 * @see m_findVariable 0224 * @see declareClassMeember 0225 * @see declareVariable 0226 */ 0227 void declareFoundVariable(KDevelop::AbstractType::Ptr type); 0228 0229 /** 0230 * Sets encountered and updates the comment when we are recompiling. 0231 */ 0232 void encounter(KDevelop::Declaration* dec); 0233 0234 bool isReservedClassName(QString className); 0235 }; 0236 0237 } 0238 0239 #endif // DECLARATIONBUILDER_H 0240