File: coderepresentation.h

package info (click to toggle)
kdevelop 4%3A5.6.2-4
  • links: PTS, VCS
  • area: main
  • in suites: bullseye
  • size: 57,892 kB
  • sloc: cpp: 278,773; javascript: 3,558; python: 3,385; sh: 1,317; ansic: 689; xml: 273; php: 95; makefile: 40; lisp: 13; sed: 12
file content (199 lines) | stat: -rw-r--r-- 6,821 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
/*
   Copyright 2008 David Nolden <david.nolden.kdevelop@art-master.de>

   This library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Library General Public
   License version 2 as published by the Free Software Foundation.

   This library is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   Library General Public License for more details.

   You should have received a copy of the GNU Library General Public License
   along with this library; see the file COPYING.LIB.  If not, write to
   the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
   Boston, MA 02110-1301, USA.
 */

#ifndef KDEVPLATFORM_CODEREPRESENTATION_H
#define KDEVPLATFORM_CODEREPRESENTATION_H

#include <language/languageexport.h>
#include <serialization/indexedstring.h>

#include <KTextEditor/ConfigInterface>
#include <KTextEditor/Document>

#include <memory>

class QString;

namespace KTextEditor {
class Range;
}

namespace KDevelop {
struct KDevEditingTransaction;

class IndexedString;

//NOTE: this is ugly, but otherwise kate might remove tabs again :-/
// see also: https://bugs.kde.org/show_bug.cgi?id=291074
struct EditorDisableReplaceTabs
{
    explicit EditorDisableReplaceTabs(KTextEditor::Document* document) : m_iface(qobject_cast<KTextEditor::ConfigInterface*>(
                document))
        , m_count(0)
    {
        ++m_count;
        if (m_count > 1)
            return;
        if (m_iface) {
            m_oldReplaceTabs = m_iface->configValue(configKey());
            m_iface->setConfigValue(configKey(), false);
        }
    }

    ~EditorDisableReplaceTabs()
    {
        --m_count;
        if (m_count > 0)
            return;

        Q_ASSERT(m_count == 0);

        if (m_iface)
            m_iface->setConfigValue(configKey(), m_oldReplaceTabs);
    }

    inline QString configKey() const
    {
        return QStringLiteral("replace-tabs");
    }

private:
    Q_DISABLE_COPY(EditorDisableReplaceTabs)

    KTextEditor::ConfigInterface* m_iface;
    int m_count;
    QVariant m_oldReplaceTabs;
};

struct KDevEditingTransaction
{
    explicit KDevEditingTransaction(KTextEditor::Document* document)
        : edit(document)
        , disableReplaceTabs(document)
    {}
    // NOTE: It's important to close the transaction first and only then destroy the EditorDisableReplaceTabs. Otherwise we hit asserts in KTextEditor.
    KTextEditor::Document::EditingTransaction edit;
    EditorDisableReplaceTabs disableReplaceTabs;
    using Ptr = std::unique_ptr<KDevEditingTransaction>;
};

/**
 * Allows getting code-lines conveniently, either through an open editor, or from a disk-loaded file.
 */
class KDEVPLATFORMLANGUAGE_EXPORT CodeRepresentation
    : public QSharedData
{
public:
    virtual ~CodeRepresentation()
    {
    }
    virtual QString line(int line) const = 0;
    virtual int lines() const = 0;
    virtual QString text() const = 0;
    virtual QString rangeText(const KTextEditor::Range& range) const;
    /**
     * Search for the given identifier in the document, and returns all ranges
     * where it was found.
     * @param identifier The identifier to search for
     * @param surroundedByBoundary Whether only matches that are surrounded by typical word-boundaries
     *                             should be acceded. Everything except letters, numbers, and the _ character
     *                             counts as word boundary.
     * */
    virtual QVector<KTextEditor::Range> grep(const QString& identifier, bool surroundedByBoundary = true) const = 0;
    /**
     * Overwrites the text in the file with the new given one
     *
     * @return true on success
     */
    virtual bool setText(const QString&) = 0;
    /** @return true if this representation represents an actual file on disk */
    virtual bool fileExists() const = 0;

    /**
     * Can be used for example from tests to disallow on-disk changes. When such a change is done, an assertion is triggered.
     * You should enable this within tests, unless you really want to work on the disk.
     */
    static void setDiskChangesForbidden(bool changesForbidden);

    /**
     * Returns the specified name as a url for artificial source code
     * suitable for code being inserted into the parser
     */
    static QString artificialPath(const QString& name);

    using Ptr = QExplicitlySharedDataPointer<CodeRepresentation>;
};

class KDEVPLATFORMLANGUAGE_EXPORT DynamicCodeRepresentation
    : public CodeRepresentation
{
public:
    /** Used to group edit-history together. Call this optionally before a bunch
     *  of replace() calls, to group them together. */
    virtual KDevEditingTransaction::Ptr makeEditTransaction() = 0;
    virtual bool replace(const KTextEditor::Range& range, const QString& oldText,
                         const QString& newText, bool ignoreOldText = false) = 0;

    using Ptr = QExplicitlySharedDataPointer<DynamicCodeRepresentation>;
};

/**
 * Creates a code-representation for the given url, that allows conveniently accessing its data. Returns zero on failure.
 */
KDEVPLATFORMLANGUAGE_EXPORT CodeRepresentation::Ptr createCodeRepresentation(const IndexedString& url);

/**
 * @return true if an artificial code representation already exists for the specified URL
 */
KDEVPLATFORMLANGUAGE_EXPORT bool artificialCodeRepresentationExists(const IndexedString& url);

/**
 *   Allows inserting artificial source-code into the code-representation and parsing framework.
 *  The source-code logically represents a file.
 *
 *  The artificial code is automatically removed when the object is destroyed.
 */
class KDEVPLATFORMLANGUAGE_EXPORT InsertArtificialCodeRepresentation
    : public QSharedData
{
public:
    /**
     * Inserts an artificial source-code representation with filename @p file and the contents @p text
     * If @p file is not an absolute path or url, it will be made absolute using the CodeRepresentation::artificialUrl()
     * function, while ensuring that the name is unique.
     */
    InsertArtificialCodeRepresentation(const IndexedString& file, const QString& text);
    ~InsertArtificialCodeRepresentation();
    InsertArtificialCodeRepresentation(const InsertArtificialCodeRepresentation&) = delete;
    InsertArtificialCodeRepresentation& operator=(const InsertArtificialCodeRepresentation&) = delete;

    void setText(const QString& text);
    QString text() const;
    /**
     * Returns the file-name for this code-representation.
     */
    IndexedString file();

private:
    IndexedString m_file;
};

using InsertArtificialCodeRepresentationPointer = QExplicitlySharedDataPointer<InsertArtificialCodeRepresentation>;
}

#endif