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