File: breakpoint.h

package info (click to toggle)
kdevelop 4%3A24.12.3-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 71,888 kB
  • sloc: cpp: 290,869; python: 3,626; javascript: 3,518; sh: 1,316; ansic: 703; xml: 401; php: 95; lisp: 66; makefile: 31; sed: 12
file content (205 lines) | stat: -rw-r--r-- 7,166 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
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
/*
    SPDX-FileCopyrightText: 2002 Matthias Hoelzer-Kluepfel <hoelzer@kde.org>
    SPDX-FileCopyrightText: 2002 John Firebaugh <jfirebaugh@kde.org>
    SPDX-FileCopyrightText: 2007 Hamish Rodda <rodda@kde.org>

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

#ifndef KDEVPLATFORM_BREAKPOINT_H
#define KDEVPLATFORM_BREAKPOINT_H

#include <QUrl>

#include <debugger/debuggerexport.h>

class TestBreakpointModel;
class QVariant;
class KConfigGroup;
namespace KTextEditor {
class MovingCursor;
}
namespace KDevelop
{
class BreakpointModel;

class KDEVPLATFORMDEBUGGER_EXPORT Breakpoint
{
public:
    enum BreakpointKind {
        CodeBreakpoint = 0,
        WriteBreakpoint,
        ReadBreakpoint,
        AccessBreakpoint,
        LastBreakpointKind
    };
    enum BreakpointState {
        NotStartedState,
        DirtyState,
        PendingState,
        CleanState
    };
    ///Custom roles for retrieving data from breakpoint model.
    enum BreakpointRole{
        LocationRole = Qt::UserRole + 1 ///< Retrieves breakpoint's full path unlike Qt::DisplayRole. Note: it's only applicable to LocationColumn.
    };

    Q_DISABLE_COPY_MOVE(Breakpoint)

    Breakpoint(BreakpointModel *model, BreakpointKind kind);
    Breakpoint(BreakpointModel *model, const KConfigGroup& config);

    bool setData(int index, const QVariant& value);

    ///Note: to retrieve the full path use LocationRole, Qt::DisplayRole return only a file's name
    QVariant data(int column, int role) const;

    void save(KConfigGroup& config);

    // Moved to BreakpointModel; temporarily left here to ease API transition
    enum Column {
        EnableColumn,
        StateColumn,
        TypeColumn,
        LocationColumn,
        ConditionColumn,
        HitCountColumn,
        IgnoreHitsColumn
    };

    void setUrl(const QUrl &url);
    QUrl url() const;

    /**
     * Assign a line number to the breakpoint.
     */
    void setLine(int line);

    /**
     * Get the current breakpoint line number.
     * @note If movingCursor() is non-null, returns the cursor's line number,
     *       which may be different than savedLine().
     */
    int line() const;

    /**
     * Get the breakpoint saved line number.
     */
    int savedLine() const;

    void setLocation(const QUrl& url, int line);
    QString location();

    BreakpointKind kind() const;

    void setAddress(const QString& address);
    QString address() const;

    void setHitCount(int hits);
    int hitCount() const;

    /**
     * Check if the breakpoint is deleted.
     * @note This method exists to ease the API transition in IBreakpointController;
     *       it should be removed eventually, since check for already freed memory does not work.
     */
    bool deleted() const;
    
    bool enabled() const;

    // NOTE: A Breakpoint is represented in the UI by a row in the Breakpoints tool view table and a mark on its
    // document border. KTextEditor::Mark is a plain class that contains only two non-identifying data members: the
    // mark's line number and type. A document mark tracks the text on its line. So when lines are inserted or
    // removed above the mark's line in the document, the mark's line number is automatically adjusted to remain
    // attached to the tracked text. A Breakpoint needs to remain associated with its document mark. For this
    // purpose, it also tracks the mark's line number via a dedicated moving cursor. restartDocumentLineTrackingAt()
    // assigns and stopDocumentLineTracking() destroys this moving cursor. By tracking the same document text, the
    // breakpoint mark and moving cursor are associated. A Breakpoint uses the associated moving cursor's line
    // number to identify and locate its mark.
    // Unfortunately, this association between the breakpoint mark and moving cursor can be broken. When the user
    // removes a breakpoint's line, the breakpoint mark on it is deleted, but the moving cursor remains and keeps
    // tracking a line next to the removed one. Furthermore, when the user removes the end-of-line character between
    // two breakpoint-marked document lines (i.e. joins the two lines into one), the mark types on those lines are
    // bitwise-OR-ed (the last updated breakpoint mark is visible on the document border), and the two associated
    // moving cursors end up tracking the single joined document line (though their column numbers differ, which can
    // potentially help improve the current behavior).
    // If the user types some text on an empty line with a breakpoint and presses Enter, the breakpoint mark stays
    // on its now nonempty line, but the associated moving cursor tracks the newly inserted next line. Thus the
    // breakpoint mark's line gets out of sync with its associated moving cursor's tracked line.

    void stopDocumentLineTracking();
    void restartDocumentLineTrackingAt(KTextEditor::MovingCursor* cursor);

    KTextEditor::MovingCursor *movingCursor() const;

    void setIgnoreHits(int c);
    int ignoreHits() const;

    void setCondition(const QString &c);
    QString condition() const;

    void setExpression(const QString &c);
    QString expression() const;

    void setState(BreakpointState state);
    BreakpointState state() const;
    QString errorText() const;

protected:
    friend class BreakpointModel;
    friend class IBreakpointController;
    friend class ::TestBreakpointModel;

    /**
     * Return the model this breakpoint is attached to
     *
     * @note This might be null, e.g. after the breakpoint has been marked as deleted
     */
    BreakpointModel *breakpointModel();

    BreakpointModel *m_model;
    bool m_enabled;
    bool m_deleted;
    BreakpointState m_state;
    BreakpointKind m_kind;
    /* For watchpoints, the address it is set at.  */
    QString m_address;
    QUrl m_url;
    int m_line;
    QString m_condition;
    KTextEditor::MovingCursor *m_movingCursor;
    int m_hitCount;
    int m_ignoreHits;
    QString m_expression;
    QString m_errorText;

    uint markType() const;
    void updateMarkType() const;

    /**
     * Assign the document url that the breakpoint is associated with.
     * @pre If the breakpoint has a moving cursor, then movingCursor()->document()->url()
     *      must already be equal to @p url.
     * @note The calling code is responsible for updating the breakpoint's LocationColumn afterwards.
     */
    void assignUrl(const QUrl& url);

    /**
     * Destroy the associated moving cursor.
     * @pre Document line tracking is active, i.e. the moving cursor is valid.
     * @note The associated breakpoint mark is not touched. The calling code is
     *       responsible for keeping the mark in sync with the breakpoint.
     */
    void removeMovingCursor();
    void saveMovingCursorLine();
    void reportChange(Column c);
    /**
     * Update or replace the breakpoint mark and moving cursor for the specified new location.
     * @note Calls stopDocumentLineTracking() if the new location is invalid or if
     *       the breakpoint cannot have a moving cursor.
     */
    void updateMovingCursor(const QUrl& url, int line);
};

}
#endif