aboutsummaryrefslogtreecommitdiffstats
path: root/src/plugins/cppeditor/baseeditordocumentparser.h
blob: 189c3952e0055935b72faf577fdd7637ad96d83f (plain)
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
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0

#pragma once

#include "cppeditor_global.h"
#include "cpptoolsreuse.h"
#include "cppworkingcopy.h"
#include "projectpart.h"

#include <projectexplorer/project.h>
#include <utils/cpplanguage_details.h>

#include <QObject>
#include <QMutex>

QT_BEGIN_NAMESPACE
template <typename T>
class QPromise;
QT_END_NAMESPACE

namespace ProjectExplorer { class Project; }

namespace CppEditor {

class CPPEDITOR_EXPORT BaseEditorDocumentParser : public QObject
{
    Q_OBJECT

public:
    using Ptr = QSharedPointer<BaseEditorDocumentParser>;
    static Ptr get(const Utils::FilePath &filePath);

    class Configuration {
    public:
        QString effectivePreferredProjectPartId() const
        {
            if (!m_preferredProjectPartId.isEmpty())
                return m_preferredProjectPartId;
            return m_softPreferredProjectPartId;
        }

        // "Preferred" means interactively set by the user.
        bool setPreferredProjectPartId(const QString &id)
        {
            return set(m_preferredProjectPartId, id);
        }

        // "Soft preferred" means deduced from the current node in the project tree.
        bool setSoftPreferredProjectPartId(const QString &id)
        {
            return set(m_softPreferredProjectPartId, id);
        }

        bool usePrecompiledHeaders() const  { return m_usePrecompiledHeaders; }
        void setUsePrecompiledHeaders(bool use) { m_usePrecompiledHeaders = use; }

        const QByteArray &editorDefines() const { return m_editorDefines; }
        bool setEditorDefines(const QByteArray &defines) { return set(m_editorDefines, defines); }

    private:
        friend bool operator==(const Configuration &left, const Configuration &right)
        {
            return left.m_usePrecompiledHeaders == right.m_usePrecompiledHeaders
                   && left.m_editorDefines == right.m_editorDefines
                   && left.m_softPreferredProjectPartId == right.m_softPreferredProjectPartId
                   && left.m_preferredProjectPartId == right.m_preferredProjectPartId;
        }

        template<typename T> bool set(T &tgt, const T &src)
        {
            if (tgt == src)
                return false;
            tgt = src;
            return true;
        }

        bool m_usePrecompiledHeaders = false;
        QByteArray m_editorDefines;
        QString m_preferredProjectPartId;
        QString m_softPreferredProjectPartId;
    };

    struct UpdateParams {
        UpdateParams(const WorkingCopy &workingCopy,
                     const ProjectExplorer::Project *activeProject,
                     Utils::Language languagePreference,
                     bool projectsUpdated)
            : workingCopy(workingCopy)
            , activeProject(activeProject ? activeProject->projectFilePath() : Utils::FilePath())
            , languagePreference(languagePreference)
            , projectsUpdated(projectsUpdated)
        {
        }

        WorkingCopy workingCopy;
        const Utils::FilePath activeProject;
        Utils::Language languagePreference = Utils::Language::Cxx;
        bool projectsUpdated = false;
    };

public:
    BaseEditorDocumentParser(const Utils::FilePath &filePath);
    ~BaseEditorDocumentParser() override;

    const Utils::FilePath &filePath() const;
    Configuration configuration() const;
    void setConfiguration(const Configuration &configuration);

    void update(const UpdateParams &updateParams);
    void update(const QPromise<void> &promise, const UpdateParams &updateParams);

    ProjectPartInfo projectPartInfo() const;

signals:
    void projectPartInfoUpdated(const ProjectPartInfo &projectPartInfo);

protected:
    struct State {
        QByteArray editorDefines;
        ProjectPartInfo projectPartInfo;
    };
    State state() const;
    void setState(const State &state);

    static ProjectPartInfo determineProjectPart(const Utils::FilePath &filePath,
            const QString &preferredProjectPartId,
            const ProjectPartInfo &currentProjectPartInfo,
            const Utils::FilePath &activeProject,
            Utils::Language languagePreference,
            bool projectsUpdated);

    mutable QMutex m_stateAndConfigurationMutex;

private:
    virtual void updateImpl(const QPromise<void> &promise,
                            const UpdateParams &updateParams) = 0;

    const Utils::FilePath m_filePath;
    Configuration m_configuration;
    State m_state;
    mutable QMutex m_updateIsRunning;
};

} // CppEditor