File: parsingenvironment.h

package info (click to toggle)
kdevelop 4%3A22.12.2-1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 70,096 kB
  • sloc: cpp: 284,635; javascript: 3,558; python: 3,422; sh: 1,319; ansic: 685; xml: 331; php: 95; lisp: 66; makefile: 39; sed: 12
file content (221 lines) | stat: -rw-r--r-- 9,525 bytes parent folder | download | duplicates (3)
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
/*
    SPDX-FileCopyrightText: 2007 David Nolden <david.nolden.kdevelop@art-master.de>

    SPDX-License-Identifier: LGPL-2.0-only
*/

#ifndef KDEVPLATFORM_PARSINGENVIRONMENT_H
#define KDEVPLATFORM_PARSINGENVIRONMENT_H

#include <serialization/indexedstring.h>

#include <language/languageexport.h>
#include "duchainbase.h"
#include "topducontext.h"
#include <language/editor/modificationrevisionset.h>

namespace KDevelop {
/**
 * Just an enumeration of a few parsing-environment types.
 * Enumerate a few possible future parsing-environment types.
 * A parsing-environment could also have a type not in this enumeration,
 * the only important thing is that it's unique for the type.
 *
 * The type is needed to match ParsingEnvironment, ParsingEnvironmentFile, and ParsingEnvironmentManager together so they fit.
 * For example the c++-versions would have their specific type.
 *
 * The type must be unique(no other language may have the same type),
 * and the type must be persistent.(it must be same after restarting kdevelop)
 *
 * */
enum ParsingEnvironmentType
{
    StandardParsingEnvironment /**< a basic standard parsing environment */,
    CppParsingEnvironment /**< a C++ parsing environment */,
    PythonParsingEnvironment /**< a python parsing environment */,
    CMakeParsingEnvironment /**< a CMake parsing environment */,
    CSharpParsingEnvironment /**< a CSharp parsing environment */,
    JavaParsingEnvironment /**< a JAva parsing environment */,
    RubyParsingEnvironment /**< a Ruby parsing environment */,
    PhpParsingEnvironment    /**< a PHP parsing environment */
};

///Internal
struct StaticParsingEnvironmentData
{
    TopDUContext::IndexedRecursiveImports simplifiedVisibleDeclarationsSatisfied;
    TopDUContext::IndexedRecursiveImports visibleDeclarationsSatisfied;
    TopDUContext::IndexedRecursiveImports allDeclarationsSatisfied;
    TopDUContext::IndexedRecursiveImports allDeclarationsAndUsesSatisfied;
    TopDUContext::IndexedRecursiveImports ASTSatisfied;
};

/**
 * Use this as base-class to define new parsing-environments.
 *
 * Parsing-environments are needed for languages that create different
 * parsing-results depending on the environment. For example in c++,
 * the environment mainly consists of macros. The include-path can
 * be considered to be a part of the parsing-environment too, because
 * different files may be included using another include-path.
 *
 * The classes have to use the serialization scheme from the duchain.
 * Each class must be registered using REGISTER_DUCHAIN_ITEM with a unique id.
 *
 * \warning Access to this class must be serialized through du-chain locking
 * */
class KDEVPLATFORMLANGUAGE_EXPORT ParsingEnvironment
{
public:
    ParsingEnvironment();
    virtual ~ParsingEnvironment();

    ///@see ParsingEnvironmentType
    virtual int type() const;
};

///The data class used for storing. Use this as base-class of your custom data classes for classes derived from
///ParsingEnvironmentFile
class KDEVPLATFORMLANGUAGE_EXPORT ParsingEnvironmentFileData
    : public DUChainBaseData
{
public:
    bool m_isProxyContext = false;
    TopDUContext::Features m_features = TopDUContext::VisibleDeclarationsAndContexts;
    KDevelop::ModificationRevision m_modificationTime;
    ModificationRevisionSet m_allModificationRevisions;
    KDevelop::IndexedString m_url;
    KDevelop::IndexedTopDUContext m_topContext;
    IndexedString m_language;

    ///If this is not empty, it means that the cache is used instead of the implicit structure.
    TopDUContext::IndexedRecursiveImports m_importsCache;
};

using ParsingEnvironmentFilePointer = QExplicitlySharedDataPointer<ParsingEnvironmentFile>;

/**
 * This represents all information about a specific parsed file that is needed
 * to match the file to a parsing-environment.
 *
 * It is QSharedData because it is embedded into top-du-contexts and at the same time
 * references may be held by ParsingEnvironmentManager.
 *
 * \warning Access to this class must be serialized through du-chain locking
 * */
class KDEVPLATFORMLANGUAGE_EXPORT ParsingEnvironmentFile
    : public DUChainBase
    , public QSharedData
{
public:
    ~ParsingEnvironmentFile() override;
    explicit ParsingEnvironmentFile(const IndexedString& url);
    ParsingEnvironmentFile(ParsingEnvironmentFileData& data, const IndexedString& url);
    explicit ParsingEnvironmentFile(ParsingEnvironmentFileData& data);

    ParsingEnvironmentFile& operator=(const ParsingEnvironmentFile& rhs) = delete;

    ///@see ParsingEnvironmentType
    virtual int type() const;

    ///Should return whether this file matches into the given environment. The default-implementation always returns true.
    virtual bool matchEnvironment(const ParsingEnvironment* environment) const;

    ///Convenience-function that returns the top-context
    TopDUContext* topContext() const override;

    KDevelop::IndexedTopDUContext indexedTopContext() const;

    KDevelop::IndexedString url() const override;

    ///Can additionally use language-specific information to decide whether the top-context that has this data attached needs to be reparsed.
    ///The standard-implementation checks the modification-time of this file stored using setModificationRevision, and all other modification-times
    ///stored with addModificationRevision(..).
    virtual bool needsUpdate(const ParsingEnvironment* environment = nullptr) const;

    /**
     * A language-specific flag used by C++ to mark one context as a proxy of another.
     * If this flag is set on a context, the first imported context should be used for any computations
     * like searches, listing, etc. instead of using this context.
     *
     * The problems should be stored within the proxy-contexts, and optionally there may be
     * any count of imported proxy-contexts imported behind the content-context(This can be used for tracking problems)
     *
     * Note: This flag does not directly change the behavior of the language-independent du-chain.
     */
    bool isProxyContext() const;

    ///Sets the flag
    void setIsProxyContext(bool);

    ///The features of the attached top-context. They are automatically replicated here by the top-context, so they
    ///are accessible even without the top-context loaded.
    TopDUContext::Features features() const;

    ///Returns the parsing-environment information of all importers of the coupled TopDUContext. This is more efficient than
    ///loading the top-context and finding out, because when a top-context is loaded, also all its recursive imports are loaded
    QList<QExplicitlySharedDataPointer<ParsingEnvironmentFile>> importers() const;

    ///Returns the parsing-environment information of all imports of the coupled TopDUContext. This is more efficient than
    ///loading the top-context and finding out
    QList<QExplicitlySharedDataPointer<ParsingEnvironmentFile>> imports() const;

    ///Returns true if this top-context satisfies at least the given minimum features.
    ///If there is static minimum features set up in ParseJob, this also checks against those.
    ///Features like "ForceUpdate" are treated specially.
    ///@p minimumFeatures The features that must be satisfied. May be an arbitrary combination of features.
    bool featuresSatisfied(TopDUContext::Features minimumFeatures) const;

    ///Should return a correctly filled ModificationRevision of the source it was created from.
    void setModificationRevision(const KDevelop::ModificationRevision& rev);

    KDevelop::ModificationRevision modificationRevision() const;

    ///Clears the modification times of all dependencies
    void clearModificationRevisions();

    void addModificationRevision(const IndexedString& url, const ModificationRevision& revision);

    const ModificationRevisionSet& allModificationRevisions() const;

    void addModificationRevisions(const ModificationRevisionSet&);

    /// Returns the language for this top-context. If the string is empty, the language is unknown.
    IndexedString language() const;

    /// If the recursive imports of the attached TopDUContext are cached, this returns the cached imports.
    /// This works without loading the top-context.
    const TopDUContext::IndexedRecursiveImports& importsCache() const;

    ///Sets the language for this top-context. Each top-context should get the language assigned that can by used
    ///in order to load the language using ILanguageController.
    void setLanguage(const IndexedString& language);

    enum {
        Identity = 11
    };

    DUCHAIN_DECLARE_DATA(ParsingEnvironmentFile)

private:
    friend class TopDUContext;
    friend class DUChainPrivate;
    static StaticParsingEnvironmentData* m_staticData;
    ///The features are managed by TopDUContext. They are set to TopDUContext::Empty when the top-context is persistently destroyed,
    ///so the persistent feature-satisfaction cache can be cleared.
    void setFeatures(TopDUContext::Features);
    void setTopContext(KDevelop::IndexedTopDUContext context);
    bool featuresMatch(KDevelop::TopDUContext::Features minimumFeatures,
                       QSet<const KDevelop::ParsingEnvironmentFile*>& checked) const;
    void setImportsCache(const TopDUContext::IndexedRecursiveImports&);
};

// TODO: why is this needed/what is it supposed to print? just the pointer value?
inline QDebug operator<<(QDebug s, const QExplicitlySharedDataPointer<ParsingEnvironmentFile>& p)
{
    s.nospace() << p->url();
    return s.space();
}
}

#endif