File: expressionvisitor.h

package info (click to toggle)
kdevelop-python 24.12.3-1
  • links: PTS, VCS
  • area: main
  • in suites: sid, trixie
  • size: 12,640 kB
  • sloc: python: 183,048; cpp: 18,798; xml: 140; sh: 14; makefile: 9
file content (145 lines) | stat: -rw-r--r-- 5,334 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
/*
    SPDX-FileCopyrightText: 2010 Miquel Canes Gonzalez <miquelcanes@gmail.com>
    SPDX-FileCopyrightText: 2011-2014 Sven Brauch <svenbrauch@googlemail.com>

    SPDX-License-Identifier: GPL-2.0-or-later
*/

#ifndef EXPRESSIONVISITOR_H
#define EXPRESSIONVISITOR_H

#include <QHash>
#include <KLocalizedString>

#include <language/duchain/types/abstracttype.h>
#include <language/duchain/types/integraltype.h>
#include <language/duchain/types/typesystemdata.h>
#include <language/duchain/types/typeregister.h>
#include <language/duchain/types/containertypes.h>
#include <language/duchain/duchainpointer.h>
#include <language/duchain/declaration.h>
#include <language/duchain/types/structuretype.h>
#include <language/duchain/classdeclaration.h>
#include <language/duchain/functiondeclaration.h>
#include <language/duchain/builders/dynamiclanguageexpressionvisitor.h>

#include "astdefaultvisitor.h"
#include "pythonduchainexport.h"
#include "pythoneditorintegrator.h"

#include "duchain/declarations/functiondeclaration.h"
#include "duchain/helpers.h"

using namespace KDevelop;
class Identifier;

namespace Python
{

typedef DUChainPointer<FunctionDeclaration> FunctionDeclarationPointer;

class KDEVPYTHONDUCHAIN_EXPORT ExpressionVisitor : public AstDefaultVisitor, public DynamicLanguageExpressionVisitor
{
public:
    ExpressionVisitor(const KDevelop::DUContext* ctx);
    /// Use this to construct the expression-visitor recursively
    ExpressionVisitor(Python::ExpressionVisitor* parent, const DUContext* overrideContext=nullptr);

    void visitBinaryOperation(BinaryOperationAst* node) override;
    void visitUnaryOperation(UnaryOperationAst* node) override;
    void visitBooleanOperation(BooleanOperationAst* node) override;
    void visitCompare(CompareAst* node) override;

    void visitString(StringAst* node) override;
    void visitBytes(BytesAst* node) override;
    void visitFormattedValue(FormattedValueAst * node) override;
    void visitJoinedString(JoinedStringAst* node) override;
    void visitNumber(NumberAst* node) override;
    void visitName(NameAst* node) override;
    void visitList(ListAst* node) override;
    void visitDict(DictAst* node) override;
    void visitSet(SetAst* node) override;
    void visitSubscript(SubscriptAst* node) override;
    void visitCall(CallAst* node) override;
    void visitAttribute(AttributeAst* node) override;
    void visitTuple(TupleAst* node) override;
    void visitLambda(LambdaAst* node) override;
    void visitListComprehension(ListComprehensionAst* node) override;
    void visitDictionaryComprehension(DictionaryComprehensionAst* node) override;
    void visitSetComprehension(SetComprehensionAst* node) override;
    void visitIfExpression(IfExpressionAst* node) override;
    void visitNameConstant(NameConstantAst* node) override;
    void visitAssignmentExpression(AssignmentExpressionAst* node) override;

    /**
     * @brief Checks for magic docstrings that override a call's return type.
     *
     * @param node The node to visit.
     * @param normalType The return type as determined without docstrings.
     * @param docstring Docstring of the function.
     */
    AbstractType::Ptr docstringTypeOverride(CallAst* node, const AbstractType::Ptr normalType,
                                              const QString& docstring);

    bool isAlias() const {
        return m_isAlias;
    }

    void enableGlobalSearching() {
        m_forceGlobalSearching = true;
    }

    void enableUnknownNameReporting() {
        m_reportUnknownNames = true;
    }

    void scanUntil(const CursorInRevision& end) {
        m_scanUntilCursor = end;
    }

    QSet<QString> unknownNames() const {
        return m_unknownNames;
    }

    template<typename T>
    static TypePtr<T> typeObjectForIntegralType(const QString& typeDescriptor) {
        auto context = Helper::getDocumentationFileContext();
        if ( ! context ) {
            return {};
        }
        auto decls = context->findDeclarations(QualifiedIdentifier(typeDescriptor));
        auto decl = decls.isEmpty() ? nullptr : dynamic_cast<Declaration*>(decls.first());
        if ( ! decl ) {
            return {};
        }
        return decl->abstractType().dynamicCast<T>();
    }

private:
    AbstractType::Ptr fromBinaryOperator(AbstractType::Ptr lhs, AbstractType::Ptr rhs, const QString& op);
    AbstractType::Ptr encounterPreprocess(AbstractType::Ptr type, bool merge=false);
    void encounter(AbstractType::Ptr type, DeclarationPointer declaration=DeclarationPointer(), bool alias=false);

    void addUnknownName(const QString& name);

    AbstractType::Ptr encounterPreprocess(AbstractType::Ptr type) override;

    void setLastIsAlias(bool alias) {
        m_isAlias = alias;
    }

private:
    /// tells whether the returned declaration is an alias
    bool m_isAlias = false;
    /// used by code completion to disable range checks on declaration searches
    bool m_forceGlobalSearching = false;
    /// used by code completion to detect unknown NameAst elements in expressions
    bool m_reportUnknownNames = false;
    CursorInRevision m_scanUntilCursor = CursorInRevision::invalid();
    static QHash<NameConstantAst::NameConstantTypes, KDevelop::AbstractType::Ptr> m_defaultTypes;
    QSet<QString> m_unknownNames;
};

}

#endif // EXPRESSIONVISITOR_H