File: codehighlighting.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 (227 lines) | stat: -rw-r--r-- 7,550 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
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
/*
 * This file is part of KDevelop
 *
 * Copyright 2007-2010 David Nolden <david.nolden.kdevelop@art-master.de>
 * Copyright 2006 Hamish Rodda <rodda@kde.org>
 * Copyright 2009 Milian Wolff <mail@milianw.de>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Library General Public License as
 * published by the Free Software Foundation; either version 2 of the
 * License, or (at your option) any later version.
 *
 * This program 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 General Public License for more details.
 *
 * You should have received a copy of the GNU General Public
 * License along with this program; if not, write to the
 * Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 */

#ifndef KDEVPLATFORM_CODEHIGHLIGHTING_H
#define KDEVPLATFORM_CODEHIGHLIGHTING_H

#include <QObject>
#include <QHash>

#include <serialization/indexedstring.h>
#include <language/duchain/ducontext.h>
#include <language/interfaces/icodehighlighting.h>
#include <language/backgroundparser/documentchangetracker.h>

#include <KTextEditor/Attribute>
#include <KTextEditor/MovingRange>

namespace KDevelop {
class DUContext;
class Declaration;

using ColorMap = QVector<KDevelop::Declaration*>;

class CodeHighlighting;

struct HighlightingEnumContainer
{
    enum Types {
        UnknownType,
        //Primary highlighting:
        LocalClassMemberType,
        InheritedClassMemberType,
        LocalVariableType,

        //Other highlighting:
        ClassType,
        FunctionType,
        ForwardDeclarationType,
        EnumType,
        EnumeratorType,
        TypeAliasType,
        MacroType, /// Declaration of a macro such as "#define FOO"
        MacroFunctionLikeType, /// Declaration of a function like macro such as "#define FOO()"

        //If none of the above match:
        MemberVariableType,
        NamespaceVariableType,
        GlobalVariableType,

        //Most of these are currently not used:
        ArgumentType,
        CodeType,
        FileType,
        NamespaceType,
        ScopeType,
        TemplateType,
        TemplateParameterType,
        FunctionVariableType,
        ErrorVariableType
    };

    enum Contexts {
        DefinitionContext,
        DeclarationContext,
        ReferenceContext
    };
};

struct HighlightedRange
{
    RangeInRevision range;
    KTextEditor::Attribute::Ptr attribute;
    bool operator<(const HighlightedRange& rhs) const
    {
        return range.start < rhs.range.start;
    }
};

/**
 * Code highlighting instance that is used to apply code highlighting to one specific top context
 * */

class KDEVPLATFORMLANGUAGE_EXPORT CodeHighlightingInstance
    : public HighlightingEnumContainer
{
public:
    explicit CodeHighlightingInstance(const CodeHighlighting* highlighting) : m_useClassCache(false)
        , m_highlighting(highlighting)
    {
    }
    virtual ~CodeHighlightingInstance()
    {
    }

    virtual void highlightDeclaration(KDevelop::Declaration* declaration, const QColor& color);
    virtual void highlightUse(KDevelop::DUContext* context, int index, const QColor& color);
    virtual void highlightUses(KDevelop::DUContext* context);

    void highlightDUChain(KDevelop::TopDUContext* context);
    void highlightDUChain(KDevelop::DUContext* context, QHash<KDevelop::Declaration*, uint> colorsForDeclarations,
        ColorMap);

    KDevelop::Declaration* localClassFromCodeContext(KDevelop::DUContext* context) const;
    /**
     * @param context Should be the context from where the declaration is used, if a use is highlighted.
     * */
    virtual Types typeForDeclaration(KDevelop::Declaration* dec, KDevelop::DUContext* context) const;
    /**
     * Decides whether to apply auto-generated rainbow colors to @p dec.
     * Default implementation only applies that to local variables in functions.
     */
    virtual bool useRainbowColor(KDevelop::Declaration* dec) const;

    //A temporary hash for speedup
    mutable QHash<KDevelop::DUContext*, KDevelop::Declaration*> m_contextClasses;

    //Here the colors of function context are stored until they are merged into the function body
    mutable QMap<KDevelop::IndexedDUContext, QHash<KDevelop::Declaration*, uint>> m_functionColorsForDeclarations;
    mutable QMap<KDevelop::IndexedDUContext, ColorMap> m_functionDeclarationsForColors;

    mutable bool m_useClassCache;
    const CodeHighlighting* m_highlighting;

    QVector<HighlightedRange> m_highlight;
};

/**
 * General class representing the code highlighting for one language
 * */
class KDEVPLATFORMLANGUAGE_EXPORT CodeHighlighting
    : public QObject
    , public KDevelop::ICodeHighlighting
    , public HighlightingEnumContainer
{
    Q_OBJECT
    Q_INTERFACES(KDevelop::ICodeHighlighting)

public:

    explicit CodeHighlighting(QObject* parent);
    ~CodeHighlighting() override;

    /// This function is thread-safe
    /// @warning The duchain must not be locked when this is called (->possible deadlock)
    void highlightDUChain(ReferencedTopDUContext context) override;

    //color should be zero when undecided
    KTextEditor::Attribute::Ptr attributeForType(Types type, Contexts context, const QColor& color) const;
    KTextEditor::Attribute::Ptr attributeForDepth(int depth) const;

    /// This function is thread-safe
    /// Returns whether a highlighting is already given for the given url
    bool hasHighlighting(IndexedString url) const override;

private:
    //Returns whether the given attribute was set by the code highlighting, and not by something else
    //Always returns true when the attribute is zero
    bool isCodeHighlight(KTextEditor::Attribute::Ptr attr) const;

protected:
    //Can be overridden to create an own instance type
    virtual CodeHighlightingInstance* createInstance() const;

private:

    /// Highlighting of one specific document
    struct DocumentHighlighting
    {
        IndexedString m_document;
        qint64 m_waitingRevision;
        // The ranges are sorted by range start, so they can easily be matched
        QVector<HighlightedRange> m_waiting;
        QVector<KTextEditor::MovingRange*> m_highlightedRanges;
    };

    QMap<DocumentChangeTracker*, DocumentHighlighting*> m_highlights;

    friend class CodeHighlightingInstance;

    mutable QHash<Types, KTextEditor::Attribute::Ptr> m_definitionAttributes;
    mutable QHash<Types, KTextEditor::Attribute::Ptr> m_declarationAttributes;
    mutable QHash<Types, KTextEditor::Attribute::Ptr> m_referenceAttributes;
    mutable QList<KTextEditor::Attribute::Ptr> m_depthAttributes;
    // Should be used to enable/disable the colorization of local variables and their uses
    bool m_localColorization;
    // Should be used to enable/disable the colorization of global types and their uses
    bool m_globalColorization;

    mutable QMutex m_dataMutex;

private Q_SLOTS:
    void clearHighlightingForDocument(const KDevelop::IndexedString& document);
    void applyHighlighting(void* highlighting);

    void trackerDestroyed(QObject* object);

    /// when the colors change we must invalidate our local caches
    void adaptToColorChanges();

    void aboutToInvalidateMovingInterfaceContent(KTextEditor::Document*);
    void aboutToRemoveText(const KTextEditor::Range&);
};
}

Q_DECLARE_TYPEINFO(KDevelop::HighlightedRange, Q_MOVABLE_TYPE);

#endif