File indexing completed on 2024-04-14 14:47:47
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 EXPRESSIONVISITOR_H 0008 #define EXPRESSIONVISITOR_H 0009 0010 #include "phpdefaultvisitor.h" 0011 #include "phpduchainexport.h" 0012 #include "expressionevaluationresult.h" 0013 #include "helper.h" 0014 0015 #include <language/duchain/types/abstracttype.h> 0016 #include <language/duchain/identifier.h> 0017 0018 namespace KDevelop 0019 { 0020 class TopDUContext; 0021 class Declaration; 0022 } 0023 0024 namespace Php 0025 { 0026 class EditorIntegrator; 0027 0028 class KDEVPHPDUCHAIN_EXPORT ExpressionVisitor : public DefaultVisitor 0029 { 0030 public: 0031 ExpressionVisitor(EditorIntegrator* editor); 0032 ExpressionEvaluationResult result() { 0033 return m_result; 0034 } 0035 void setCreateProblems(bool v); 0036 void setOffset(const KDevelop::CursorInRevision& offset); 0037 0038 void visitNode(AstNode *node) override; 0039 0040 protected: 0041 KDevelop::DeclarationPointer processVariable( VariableIdentifierAst* variable); 0042 0043 void visitAssignmentExpression(AssignmentExpressionAst *node) override; 0044 void visitArrayIndexSpecifier(ArrayIndexSpecifierAst* node) override; 0045 void visitCompoundVariableWithSimpleIndirectReference(CompoundVariableWithSimpleIndirectReferenceAst *node) override; 0046 void visitVarExpression(VarExpressionAst *node) override; 0047 void visitVarExpressionNewObject(VarExpressionNewObjectAst *node) override; 0048 void visitVarExpressionArray(VarExpressionArrayAst *node) override; 0049 void visitClosure(ClosureAst* node) override; 0050 void visitFunctionCall(FunctionCallAst* node) override; 0051 void visitConstantOrClassConst(ConstantOrClassConstAst *node) override; 0052 void visitScalar(ScalarAst *node) override; 0053 void visitStaticScalar(StaticScalarAst *node) override; 0054 void visitEncapsVar(EncapsVarAst *node) override; 0055 void visitVariableProperty(VariablePropertyAst *node) override; 0056 void visitStaticMember(StaticMemberAst* node) override; 0057 void visitClassNameReference(ClassNameReferenceAst* node) override; 0058 void visitClassNameReferenceDimListItems(ClassPropertyAst* node); 0059 void visitUnaryExpression(UnaryExpressionAst* node) override; 0060 void visitAdditiveExpressionRest(AdditiveExpressionRestAst* node) override; 0061 void visitVariable(VariableAst* node) override; 0062 void visitFunctionCallParameterList( FunctionCallParameterListAst* node ) override; 0063 void visitFunctionCallParameterListElement(FunctionCallParameterListElementAst* node) override; 0064 void visitRelationalExpression(RelationalExpressionAst* node) override; 0065 void visitRelationalExpressionRest(RelationalExpressionRestAst* node) override; 0066 void visitEqualityExpressionRest(EqualityExpressionRestAst* node) override; 0067 void visitStatement(StatementAst* node) override; 0068 void visitGenericTypeHint(GenericTypeHintAst* node) override; 0069 0070 QString stringForNode(AstNode* id); 0071 KDevelop::QualifiedIdentifier identifierForNode(IdentifierAst* id); 0072 QString stringForNode(VariableIdentifierAst* id); 0073 KDevelop::QualifiedIdentifier identifierForNode(VariableIdentifierAst* id); 0074 0075 0076 virtual void usingDeclaration(AstNode* node, const KDevelop::DeclarationPointer& decl) { 0077 Q_UNUSED(node) Q_UNUSED(decl) 0078 } 0079 0080 KDevelop::DeclarationPointer findDeclarationImport(DeclarationType declarationType, IdentifierAst* node); 0081 KDevelop::DeclarationPointer findDeclarationImport(DeclarationType declarationType, VariableIdentifierAst* node); 0082 KDevelop::DeclarationPointer findDeclarationImport(DeclarationType declarationType, 0083 const KDevelop::QualifiedIdentifier& identifier); 0084 KDevelop::Declaration* findVariableDeclaration(KDevelop::DUContext* context, KDevelop::Identifier identifier, 0085 KDevelop::CursorInRevision position, KDevelop::DUContext::SearchFlag flag); 0086 protected: 0087 EditorIntegrator* m_editor; 0088 0089 /** 0090 * Opens the given closure return type, and sets it to be the current closure return type. 0091 */ 0092 void openClosureReturnType(const KDevelop::AbstractType::Ptr& type) 0093 { 0094 m_closureReturnTypes.append(type); 0095 } 0096 0097 /** 0098 * Close the current closure return type. 0099 */ 0100 void closeClosureReturnType() 0101 { 0102 // And the reference will be lost... 0103 m_closureReturnTypes.pop(); 0104 } 0105 0106 /** 0107 * Retrieve the return type of the current closure. 0108 * 0109 * \returns the abstract type of the current context. 0110 */ 0111 inline KDevelop::AbstractType::Ptr currentClosureReturnType() 0112 { 0113 if (m_closureReturnTypes.isEmpty()) { 0114 return KDevelop::AbstractType::Ptr(); 0115 } else { 0116 return m_closureReturnTypes.top(); 0117 } 0118 } 0119 0120 /// Determine if the expression visitor has a return type for the current closure. \returns true if there is a current closure return type, else returns false. 0121 inline bool hasCurrentClosureReturnType() { return !m_closureReturnTypes.isEmpty(); } 0122 0123 private: 0124 KDevelop::DUContext* findClassContext(NamespacedIdentifierAst* className); 0125 KDevelop::DUContext* findClassContext(IdentifierAst* className); 0126 void buildNamespaceUses(NamespacedIdentifierAst* namespaces, const KDevelop::QualifiedIdentifier& identifier); 0127 void useDeclaration(VariableIdentifierAst* node, KDevelop::DUContext* context); 0128 void useDeclaration(IdentifierAst* node, KDevelop::DUContext* context); 0129 0130 bool m_createProblems; 0131 KDevelop::CursorInRevision m_offset; 0132 KDevelop::DUContext* m_currentContext; 0133 0134 ExpressionEvaluationResult m_result; 0135 KDevelop::Stack<KDevelop::AbstractType::Ptr> m_closureReturnTypes; 0136 0137 bool m_isAssignmentExpressionEqual; 0138 bool m_inDefine; 0139 }; 0140 0141 } 0142 #endif