File indexing completed on 2024-04-14 04:31:13

0001 /*
0002  * This file is part of KDevelop
0003  * Copyright (C) 2012-2015 Miquel Sabaté Solà <mikisabate@gmail.com>
0004  *
0005  * This program is free software: you can redistribute it and/or modify
0006  * it under the terms of the GNU General Public License as published by
0007  * the Free Software Foundation, either version 3 of the License, or
0008  * (at your option) any later version.
0009  *
0010  * This program is distributed in the hope that it will be useful,
0011  * but WITHOUT ANY WARRANTY; without even the implied warranty of
0012  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0013  * GNU General Public License for more details.
0014  *
0015  * You should have received a copy of the GNU General Public License
0016  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
0017  */
0018 
0019 #ifndef RUBY_EXPRESSION_VISITOR_H
0020 #define RUBY_EXPRESSION_VISITOR_H
0021 
0022 #include <duchain/duchainexport.h>
0023 #include <duchain/helpers.h>
0024 #include <duchain/types/classtype.h>
0025 #include <parser/astvisitor.h>
0026 
0027 namespace ruby {
0028 
0029 class EditorIntegrator;
0030 
0031 /**
0032  * @class ExpressionVisitor
0033  *
0034  * This class is used almost everywhere in the DUChain & Code Completion parts.
0035  * It's a visitor specialized in retrieving the types that can be extracted
0036  * for a particular AST. It also retrieves the last declaration that has been
0037  * found for a given expression.
0038  *
0039  * @note The DUChain should *never* be locked when calling a visit method of
0040  * this class. This class already takes care of locking issues.
0041  */
0042 class KDEVRUBYDUCHAIN_EXPORT ExpressionVisitor : public AstVisitor
0043 {
0044 public:
0045     ExpressionVisitor(KDevelop::DUContext *ctx, EditorIntegrator *editor);
0046     explicit ExpressionVisitor(ExpressionVisitor *parent);
0047 
0048     /// @returns the last type seen.
0049     inline KDevelop::AbstractType::Ptr lastType() const
0050     {
0051         return m_lastType;
0052     }
0053 
0054     /// @returns true if the last expression was an alias, false otherwise.
0055     inline const bool & lastAlias() const
0056     {
0057         return m_alias;
0058     }
0059 
0060     /// @returns the last declaration seen.
0061     inline const KDevelop::DeclarationPointer & lastDeclaration() const
0062     {
0063         return m_lastDeclaration;
0064     }
0065 
0066     /// Set the internal context to @p ctx and reset all the other attributes.
0067     void setContext(KDevelop::DUContext *ctx);
0068 
0069     /// Set whether the type for the last declaration.
0070     void setIsClassMethod(bool isClassMethod);
0071 
0072     /// Set the declaration kind to @param kind.
0073     void setDeclarationKind(const DeclarationKind kind);
0074 
0075     /// Re-implemented from AstVisitor.
0076     void visitParameter(Ast *node) override;
0077 
0078 protected:
0079     /// Visitor methods re-implemented from AstVisitor.
0080 
0081     bool declaredInContext(const QByteArray &name) const override;
0082 
0083     void visitString(Ast *node) override;
0084     void visitRegexp(Ast *node) override;
0085     void visitNumeric(Ast *node) override;
0086     void visitTrue(Ast *node) override;
0087     void visitFalse(Ast *node) override;
0088     void visitNil(Ast *node) override;
0089     void visitLine(Ast *node) override;
0090     void visitFile(Ast *node) override;
0091     void visitEncoding(Ast *node) override;
0092     void visitSelf(Ast *node) override;
0093     void visitRange(Ast *node) override;
0094     void visitSymbol(Ast *node) override;
0095     void visitName(Ast *node) override;
0096     void visitArray(Ast *node) override;
0097     void visitHash(Ast *node) override;
0098     void visitArrayValue(Ast *node) override;
0099     void visitMethodCall(Ast *node) override;
0100     void visitSuper(Ast *node) override;
0101     void visitLambda(Ast *node) override;
0102     void visitWhileStatement(Ast *node) override;
0103     void visitForStatement(Ast *node) override;
0104     void visitBinary(Ast *node) override;
0105     void visitBoolean(Ast *node) override;
0106     void visitIfStatement(Ast *node) override;
0107     void visitCaseStatement(Ast *node) override;
0108     void visitMethodStatement(Ast *node) override;
0109 
0110 private:
0111     /// Set the last type seen to @p type.
0112     inline void encounter(KDevelop::AbstractType::Ptr type)
0113     {
0114         m_lastType = type;
0115     }
0116 
0117     /**
0118      * Get the ClassType that can be guessed from the given parameters.
0119      * @param ptr The container type.
0120      * @param node The container. Used to retrieve the contents type.
0121      * @param hasKey False by default. Set to true if the container has
0122      * key values (i.e. Hash).
0123      * @return the ClassType retrieved from the given parameters or nullptr.
0124      */
0125     ClassType::Ptr getContainer(KDevelop::AbstractType::Ptr ptr,
0126                                 const Ast *node,
0127                                 bool hasKey = false);
0128 
0129     /// Visit the last statement from @p node. Used for the implicit return.
0130     void visitLastStatement(Ast *node);
0131 
0132     /// Visit the method call members from @p node.
0133     void visitMethodCallMembers(Ast *node);
0134 
0135 private:
0136     /// The DUContext that the visitor will use to find declarations.
0137     KDevelop::DUContext *m_ctx;
0138 
0139     /// The EditorIntegrator used to mess with the document.
0140     EditorIntegrator *m_editor;
0141 
0142     /// The last found DUContext. Used by the method call visitor.
0143     KDevelop::DUContext *m_lastCtx;
0144 
0145     /// The last AbstractType that has been found.
0146     KDevelop::AbstractType::Ptr m_lastType;
0147 
0148     /// The last DeclarationPointer that has been found.
0149     KDevelop::DeclarationPointer m_lastDeclaration;
0150 
0151     /// Tells us whether the last found declaration was an alias or not.
0152     bool m_alias;
0153 
0154     /// The kind for the last declaration.
0155     DeclarationKind m_declarationKind;
0156 };
0157 
0158 }
0159 
0160 #endif // RUBY_EXPRESSION_VISITOR_H