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