File indexing completed on 2024-05-19 15:46:44
0001 /* 0002 SPDX-FileCopyrightText: 2013 Andrea Scarpino <scarpino@kde.org> 0003 0004 SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 #ifndef EXPRESSIONVISITOR_H 0008 #define EXPRESSIONVISITOR_H 0009 0010 #include <util/stack.h> 0011 0012 #include <language/duchain/builders/dynamiclanguageexpressionvisitor.h> 0013 #include <language/duchain/types/integraltype.h> 0014 #include <language/duchain/ducontext.h> 0015 0016 #include <util/path.h> 0017 0018 #include <qmljs/parser/qmljsast_p.h> 0019 0020 #include "duchainexport.h" 0021 0022 class KDEVQMLJSDUCHAIN_EXPORT ExpressionVisitor : public KDevelop::DynamicLanguageExpressionVisitor, public QmlJS::AST::Visitor 0023 { 0024 public: 0025 explicit ExpressionVisitor(KDevelop::DUContext* context); 0026 0027 /** 0028 * Return whether the expression ends with a prototype member. 0029 * 0030 * Example of such expressions are: 0031 * 0032 * @code 0033 * Class.prototype 0034 * Module.Class.prototype 0035 * object.__proto__ 0036 * @endcode 0037 * 0038 * These expressions don't point to a prototype: 0039 * 0040 * @code 0041 * Class.prototype.method 0042 * object.__proto__.member 0043 * @endcode 0044 */ 0045 bool isPrototype() const; 0046 0047 using Visitor::visit; 0048 using Visitor::endVisit; 0049 0050 protected: 0051 bool visit(QmlJS::AST::NumericLiteral* node) override; 0052 bool visit(QmlJS::AST::StringLiteral* node) override; 0053 bool visit(QmlJS::AST::RegExpLiteral* node) override; 0054 bool visit(QmlJS::AST::TrueLiteral* node) override; 0055 bool visit(QmlJS::AST::FalseLiteral* node) override; 0056 0057 bool visit(QmlJS::AST::ArrayLiteral* node) override; 0058 bool visit(QmlJS::AST::ObjectLiteral* node) override; 0059 bool visit(QmlJS::AST::ArrayMemberExpression* node) override; 0060 bool visit(QmlJS::AST::FieldMemberExpression* node) override; 0061 0062 bool visit(QmlJS::AST::BinaryExpression* node) override; 0063 bool visit(QmlJS::AST::IdentifierExpression* node) override; 0064 bool visit(QmlJS::AST::UiQualifiedId* node) override; 0065 bool visit(QmlJS::AST::ThisExpression* node) override; 0066 0067 bool visit(QmlJS::AST::FunctionExpression* node) override; 0068 bool visit(QmlJS::AST::CallExpression* node) override; 0069 bool visit(QmlJS::AST::NewMemberExpression* node) override; 0070 0071 void postVisit(QmlJS::AST::Node* node) override; 0072 0073 private: 0074 using KDevelop::DynamicLanguageExpressionVisitor::encounter; 0075 0076 void encounterNothing(); 0077 void encounter(KDevelop::IntegralType::CommonIntegralTypes type); 0078 0079 void encounter(const QString &declaration, KDevelop::DUContext* context = nullptr); 0080 bool encounterParent(const QString& declaration); // "parent" QML identifier 0081 bool encounterDeclarationInContext(const KDevelop::QualifiedIdentifier& id, 0082 KDevelop::DUContext* context); 0083 bool encounterDeclarationInNodeModule(const KDevelop::QualifiedIdentifier& id, 0084 const QString& module); 0085 bool encounterGlobalDeclaration(const KDevelop::QualifiedIdentifier& id); 0086 0087 void encounterFieldMember(const QString &name); 0088 void encounterObjectAtLocation(const QmlJS::AST::SourceLocation &location); 0089 void instantiateCurrentDeclaration(); /*!< @brief Encounter a StructureType whose declaration is currentDeclaration() */ 0090 0091 private: 0092 int m_prototypeDepth; // 2 = the current node is "prototype" or "__proto__". 1 = we have just closed this node. <= 0 : "__proto__" is not the last node (as in "foo.prototype.bar") 0093 KDevelop::Path m_currentDir; 0094 }; 0095 0096 #endif // EXPRESSIONVISITOR_H