1 /*
2     This file is part of KDevelop
3     SPDX-FileCopyrightText: 2008 Niko Sams <niko.sams@gmail.com>
4 
5     SPDX-License-Identifier: LGPL-2.0-or-later
6 */
7 
8 #ifndef CONTEXTBUILDER_H
9 #define CONTEXTBUILDER_H
10 
11 #include "phpdefaultvisitor.h"
12 #include <language/duchain/builders/abstractcontextbuilder.h>
13 #include <language/duchain/problem.h>
14 
15 #include "phpduchainexport.h"
16 #include "editorintegrator.h"
17 #include "helper.h"
18 
19 
20 namespace Php
21 {
22 class EditorIntegrator;
23 class ParseSession;
24 
25 typedef KDevelop::AbstractContextBuilder<AstNode, IdentifierAst> ContextBuilderBase;
26 
27 /// first is the "pretty" identifier used for printing
28 /// second comes the all-lowercase identifier used for storage
29 typedef QPair<KDevelop::IndexedString, KDevelop::QualifiedIdentifier> IdentifierPair;
30 
31 class KDEVPHPDUCHAIN_EXPORT ContextBuilder: public ContextBuilderBase, public DefaultVisitor
32 {
33 
34 public:
35     ContextBuilder();
36     virtual ~ContextBuilder();
37 
38     virtual KDevelop::ReferencedTopDUContext build(const KDevelop::IndexedString& url, AstNode* node,
39             KDevelop::ReferencedTopDUContext updateContext
40             = KDevelop::ReferencedTopDUContext());
41 
42     bool hadUnresolvedIdentifiers() const;
43 
44     EditorIntegrator* editor() const;
45 
46 protected:
47     virtual KDevelop::DUContext* newContext(const KDevelop::RangeInRevision& range);
48     virtual KDevelop::TopDUContext* newTopContext(const KDevelop::RangeInRevision& range, KDevelop::ParsingEnvironmentFile* file = 0);
49 
50     virtual void startVisiting(AstNode* node);
51     virtual void setContextOnNode(AstNode* node, KDevelop::DUContext* ctx);
52     virtual KDevelop::DUContext* contextFromNode(AstNode* node);
53     virtual KDevelop::RangeInRevision editorFindRange(AstNode* fromRange, AstNode* toRange = 0);
54     /// Find Cursor for start of a node, useful to limit findLocalDeclarations() searches.
55     KDevelop::CursorInRevision startPos( AstNode* node);
56 
57     virtual KDevelop::QualifiedIdentifier identifierForNode(IdentifierAst* id);
58     KDevelop::QualifiedIdentifier identifierForNode(VariableIdentifierAst* id);
59     IdentifierPair identifierPairForNode(IdentifierAst* id);
60     QString stringForNode(IdentifierAst* node) const;
61     QString stringForNode(VariableIdentifierAst* node) const;
62 
63     virtual void visitClassDeclarationStatement(ClassDeclarationStatementAst*);
64     virtual void visitInterfaceDeclarationStatement(InterfaceDeclarationStatementAst* node);
65     virtual void visitTraitDeclarationStatement(TraitDeclarationStatementAst* node);
66     virtual void visitClassStatement(ClassStatementAst *node);
67     virtual void visitFunctionDeclarationStatement(FunctionDeclarationStatementAst* node);
68     virtual void visitClosure(ClosureAst* node);
69     virtual void visitUnaryExpression(UnaryExpressionAst* node);
70     /**
71      * don't overload in other builders, use @c openNamespace and @c closeNamespace instead.
72      */
73     virtual void visitNamespaceDeclarationStatement(NamespaceDeclarationStatementAst* node);
74     virtual void openNamespace(NamespaceDeclarationStatementAst* parent, IdentifierAst* node, const IdentifierPair& identifier, const KDevelop::RangeInRevision& range);
75     virtual void closeNamespace(NamespaceDeclarationStatementAst* parent, IdentifierAst* node, const IdentifierPair& identifier);
76 
77     virtual void addBaseType(NamespacedIdentifierAst * identifier);
78 
79     virtual void classContextOpened(KDevelop::DUContext* context);
80 
81     /// Report @p errorMsg with the range of @p node
82     /// @see void reportError(const QString& errorMsg, KDevelop::SimpleRange range);
83     void reportError(const QString& errorMsg, AstNode* node,
84                         KDevelop::ProblemData::Severity severity = KDevelop::ProblemData::Error);
85     /// Report @p errorMsg with the range encompassing all nodes in @p nodes
86     /// @see void reportError(const QString& errorMsg, KDevelop::SimpleRange range);
87     void reportError(const QString& errorMsg, QList<AstNode*> nodes,
88                         KDevelop::ProblemData::Severity severity = KDevelop::ProblemData::Error);
89     /// Report @p errorMsg with range @p range
90     void reportError(const QString& errorMsg, KDevelop::RangeInRevision range,
91                         KDevelop::ProblemData::Severity severity = KDevelop::ProblemData::Error);
92 
93     KDevelop::DeclarationPointer findDeclarationImport(DeclarationType declarationType, IdentifierAst* node);
94     KDevelop::DeclarationPointer findDeclarationImport(DeclarationType declarationType, VariableIdentifierAst* node);
95     KDevelop::DeclarationPointer findDeclarationImport(DeclarationType declarationType,
96                                                        const KDevelop::QualifiedIdentifier &identifier);
97 
98     /// internal functions file should not be checked for errors and can get some optimizations
99     bool m_isInternalFunctions;
100     /// Whether semantic problems should get reported
101     bool m_reportErrors;
102     ///TODO: push this into kdevplatform
103     bool m_mapAst;
104     bool m_hadUnresolvedIdentifiers;
105 
106     EditorIntegrator* m_editor;
107 
108 private:
109     void closeNamespaces(NamespaceDeclarationStatementAst* namespaces);
110     NamespaceDeclarationStatementAst* m_openNamespaces;
111 
112 };
113 
114 }
115 
116 #endif
117