File indexing completed on 2024-05-05 16:42:28
0001 /* 0002 SPDX-FileCopyrightText: 2010 Miquel Canes Gonzalez <miquelcanes@gmail.com> 0003 SPDX-FileCopyrightText: 2011-2014 Sven Brauch <svenbrauch@googlemail.com> 0004 0005 SPDX-License-Identifier: GPL-2.0-or-later 0006 */ 0007 0008 #ifndef EXPRESSIONVISITOR_H 0009 #define EXPRESSIONVISITOR_H 0010 0011 #include <QHash> 0012 #include <KLocalizedString> 0013 0014 #include <language/duchain/types/abstracttype.h> 0015 #include <language/duchain/types/integraltype.h> 0016 #include <language/duchain/types/typesystemdata.h> 0017 #include <language/duchain/types/typeregister.h> 0018 #include <language/duchain/types/containertypes.h> 0019 #include <language/duchain/duchainpointer.h> 0020 #include <language/duchain/declaration.h> 0021 #include <language/duchain/types/structuretype.h> 0022 #include <language/duchain/classdeclaration.h> 0023 #include <language/duchain/functiondeclaration.h> 0024 #include <language/duchain/builders/dynamiclanguageexpressionvisitor.h> 0025 0026 #include "astdefaultvisitor.h" 0027 #include "pythonduchainexport.h" 0028 #include "pythoneditorintegrator.h" 0029 0030 #include "duchain/declarations/functiondeclaration.h" 0031 #include "duchain/helpers.h" 0032 0033 using namespace KDevelop; 0034 class Identifier; 0035 0036 namespace Python 0037 { 0038 0039 typedef DUChainPointer<FunctionDeclaration> FunctionDeclarationPointer; 0040 0041 class KDEVPYTHONDUCHAIN_EXPORT ExpressionVisitor : public AstDefaultVisitor, public DynamicLanguageExpressionVisitor 0042 { 0043 public: 0044 ExpressionVisitor(const KDevelop::DUContext* ctx); 0045 /// Use this to construct the expression-visitor recursively 0046 ExpressionVisitor(Python::ExpressionVisitor* parent, const DUContext* overrideContext=nullptr); 0047 0048 void visitBinaryOperation(BinaryOperationAst* node) override; 0049 void visitUnaryOperation(UnaryOperationAst* node) override; 0050 void visitBooleanOperation(BooleanOperationAst* node) override; 0051 void visitCompare(CompareAst* node) override; 0052 0053 void visitString(StringAst* node) override; 0054 void visitBytes(BytesAst* node) override; 0055 void visitFormattedValue(FormattedValueAst * node) override; 0056 void visitJoinedString(JoinedStringAst* node) override; 0057 void visitNumber(NumberAst* node) override; 0058 void visitName(NameAst* node) override; 0059 void visitList(ListAst* node) override; 0060 void visitDict(DictAst* node) override; 0061 void visitSet(SetAst* node) override; 0062 void visitSubscript(SubscriptAst* node) override; 0063 void visitCall(CallAst* node) override; 0064 void visitAttribute(AttributeAst* node) override; 0065 void visitTuple(TupleAst* node) override; 0066 void visitLambda(LambdaAst* node) override; 0067 void visitListComprehension(ListComprehensionAst* node) override; 0068 void visitDictionaryComprehension(DictionaryComprehensionAst* node) override; 0069 void visitSetComprehension(SetComprehensionAst* node) override; 0070 void visitIfExpression(IfExpressionAst* node) override; 0071 void visitNameConstant(NameConstantAst* node) override; 0072 void visitAssignmentExpression(AssignmentExpressionAst* node) override; 0073 0074 /** 0075 * @brief Checks for magic docstrings that override a call's return type. 0076 * 0077 * @param node The node to visit. 0078 * @param normalType The return type as determined without docstrings. 0079 * @param docstring Docstring of the function. 0080 */ 0081 AbstractType::Ptr docstringTypeOverride(CallAst* node, const AbstractType::Ptr normalType, 0082 const QString& docstring); 0083 0084 bool isAlias() const { 0085 return m_isAlias; 0086 } 0087 0088 void enableGlobalSearching() { 0089 m_forceGlobalSearching = true; 0090 } 0091 0092 void enableUnknownNameReporting() { 0093 m_reportUnknownNames = true; 0094 } 0095 0096 void scanUntil(const CursorInRevision& end) { 0097 m_scanUntilCursor = end; 0098 } 0099 0100 QSet<QString> unknownNames() const { 0101 return m_unknownNames; 0102 } 0103 0104 template<typename T> 0105 static TypePtr<T> typeObjectForIntegralType(const QString& typeDescriptor) { 0106 auto context = Helper::getDocumentationFileContext(); 0107 if ( ! context ) { 0108 return {}; 0109 } 0110 auto decls = context->findDeclarations(QualifiedIdentifier(typeDescriptor)); 0111 auto decl = decls.isEmpty() ? nullptr : dynamic_cast<Declaration*>(decls.first()); 0112 if ( ! decl ) { 0113 return {}; 0114 } 0115 return decl->abstractType().dynamicCast<T>(); 0116 } 0117 0118 private: 0119 AbstractType::Ptr fromBinaryOperator(AbstractType::Ptr lhs, AbstractType::Ptr rhs, const QString& op); 0120 AbstractType::Ptr encounterPreprocess(AbstractType::Ptr type, bool merge=false); 0121 void encounter(AbstractType::Ptr type, DeclarationPointer declaration=DeclarationPointer(), bool alias=false); 0122 0123 void addUnknownName(const QString& name); 0124 0125 AbstractType::Ptr encounterPreprocess(AbstractType::Ptr type) override; 0126 0127 void setLastIsAlias(bool alias) { 0128 m_isAlias = alias; 0129 } 0130 0131 private: 0132 /// tells whether the returned declaration is an alias 0133 bool m_isAlias = false; 0134 /// used by code completion to disable range checks on declaration searches 0135 bool m_forceGlobalSearching = false; 0136 /// used by code completion to detect unknown NameAst elements in expressions 0137 bool m_reportUnknownNames = false; 0138 CursorInRevision m_scanUntilCursor = CursorInRevision::invalid(); 0139 static QHash<NameConstantAst::NameConstantTypes, KDevelop::AbstractType::Ptr> m_defaultTypes; 0140 QSet<QString> m_unknownNames; 0141 }; 0142 0143 } 0144 0145 #endif // EXPRESSIONVISITOR_H