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
|
/*
SPDX-FileCopyrightText: 2008 Niko Sams <niko.sams@gmail.com>
SPDX-License-Identifier: LGPL-2.0-or-later
*/
#ifndef EXPRESSIONVISITOR_H
#define EXPRESSIONVISITOR_H
#include "phpdefaultvisitor.h"
#include "phpduchainexport.h"
#include "expressionevaluationresult.h"
#include "helper.h"
#include <language/duchain/types/abstracttype.h>
#include <language/duchain/identifier.h>
namespace KDevelop
{
class TopDUContext;
class Declaration;
}
namespace Php
{
class EditorIntegrator;
class KDEVPHPDUCHAIN_EXPORT ExpressionVisitor : public DefaultVisitor
{
public:
ExpressionVisitor(EditorIntegrator* editor);
ExpressionEvaluationResult result() {
return m_result;
}
void setCreateProblems(bool v);
void setOffset(const KDevelop::CursorInRevision& offset);
void visitNode(AstNode *node) override;
protected:
KDevelop::DeclarationPointer processVariable( VariableIdentifierAst* variable);
void visitAssignmentExpression(AssignmentExpressionAst *node) override;
void visitArrayIndexSpecifier(ArrayIndexSpecifierAst* node) override;
void visitCompoundVariableWithSimpleIndirectReference(CompoundVariableWithSimpleIndirectReferenceAst *node) override;
void visitVarExpression(VarExpressionAst *node) override;
void visitVarExpressionNewObject(VarExpressionNewObjectAst *node) override;
void visitVarExpressionArray(VarExpressionArrayAst *node) override;
void visitClosure(ClosureAst* node) override;
void visitFunctionCall(FunctionCallAst* node) override;
void visitConstantOrClassConst(ConstantOrClassConstAst *node) override;
void visitScalar(ScalarAst *node) override;
void visitStaticScalar(StaticScalarAst *node) override;
void visitEncapsVar(EncapsVarAst *node) override;
void visitVariableProperty(VariablePropertyAst *node) override;
void visitStaticMember(StaticMemberAst* node) override;
void visitClassNameReference(ClassNameReferenceAst* node) override;
void visitClassNameReferenceDimListItems(ClassPropertyAst* node);
void visitUnaryExpression(UnaryExpressionAst* node) override;
void visitAdditiveExpressionRest(AdditiveExpressionRestAst* node) override;
void visitVariable(VariableAst* node) override;
void visitFunctionCallParameterList( FunctionCallParameterListAst* node ) override;
void visitFunctionCallParameterListElement(FunctionCallParameterListElementAst* node) override;
void visitRelationalExpression(RelationalExpressionAst* node) override;
void visitRelationalExpressionRest(RelationalExpressionRestAst* node) override;
void visitEqualityExpressionRest(EqualityExpressionRestAst* node) override;
void visitStatement(StatementAst* node) override;
void visitGenericTypeHint(GenericTypeHintAst* node) override;
QString stringForNode(AstNode* id);
KDevelop::QualifiedIdentifier identifierForNode(IdentifierAst* id);
QString stringForNode(VariableIdentifierAst* id);
KDevelop::QualifiedIdentifier identifierForNode(VariableIdentifierAst* id);
virtual void usingDeclaration(AstNode* node, const KDevelop::DeclarationPointer& decl) {
Q_UNUSED(node) Q_UNUSED(decl)
}
KDevelop::DeclarationPointer findDeclarationImport(DeclarationType declarationType, IdentifierAst* node);
KDevelop::DeclarationPointer findDeclarationImport(DeclarationType declarationType, VariableIdentifierAst* node);
KDevelop::DeclarationPointer findDeclarationImport(DeclarationType declarationType,
const KDevelop::QualifiedIdentifier& identifier);
KDevelop::Declaration* findVariableDeclaration(KDevelop::DUContext* context, KDevelop::Identifier identifier,
KDevelop::CursorInRevision position, KDevelop::DUContext::SearchFlag flag);
protected:
EditorIntegrator* m_editor;
/**
* Opens the given closure return type, and sets it to be the current closure return type.
*/
void openClosureReturnType(const KDevelop::AbstractType::Ptr& type)
{
m_closureReturnTypes.append(type);
}
/**
* Close the current closure return type.
*/
void closeClosureReturnType()
{
// And the reference will be lost...
m_closureReturnTypes.pop();
}
/**
* Retrieve the return type of the current closure.
*
* \returns the abstract type of the current context.
*/
inline KDevelop::AbstractType::Ptr currentClosureReturnType()
{
if (m_closureReturnTypes.isEmpty()) {
return KDevelop::AbstractType::Ptr();
} else {
return m_closureReturnTypes.top();
}
}
/// 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.
inline bool hasCurrentClosureReturnType() { return !m_closureReturnTypes.isEmpty(); }
private:
KDevelop::DUContext* findClassContext(NamespacedIdentifierAst* className);
KDevelop::DUContext* findClassContext(IdentifierAst* className);
void buildNamespaceUses(NamespacedIdentifierAst* namespaces, const KDevelop::QualifiedIdentifier& identifier);
void useDeclaration(VariableIdentifierAst* node, KDevelop::DUContext* context);
void useDeclaration(IdentifierAst* node, KDevelop::DUContext* context);
bool m_createProblems;
KDevelop::CursorInRevision m_offset;
KDevelop::DUContext* m_currentContext;
ExpressionEvaluationResult m_result;
KDevelop::Stack<KDevelop::AbstractType::Ptr> m_closureReturnTypes;
bool m_isAssignmentExpressionEqual;
bool m_inDefine;
};
}
#endif
|