identifiedtype.h 5.26 KB
Newer Older
1
/* This file is part of KDevelop
2
3
    Copyright 2002-2005 Roberto Raggi <roberto@kdevelop.org>
    Copyright 2006 Adam Treat <treat@kde.org>
Hamish Rodda's avatar
Hamish Rodda committed
4
    Copyright 2006-2008 Hamish Rodda <rodda@kde.org>
David Nolden's avatar
David Nolden committed
5
    Copyright 2007-2008 David Nolden <david.nolden.kdevelop@art-master.de>
6
7
8
9
10
11
12
13
14
15
16
17
18
19

   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.
20
 */
21

22
23
#ifndef KDEVPLATFORM_IDENTIFIEDTYPE_H
#define KDEVPLATFORM_IDENTIFIEDTYPE_H
24

Matt Rogers's avatar
Matt Rogers committed
25
26
#include "../identifier.h"
#include "../declarationid.h"
27

28
namespace KDevelop {
David Nolden's avatar
David Nolden committed
29
class DUContext;
30
class Declaration;
31
32
class DeclarationId;
class TopDUContext;
David Nolden's avatar
David Nolden committed
33
class AbstractType;
34

Hamish Rodda's avatar
Hamish Rodda committed
35
36
37
/**
 * Data structure for identified types.
 */
38
39
40
class IdentifiedTypeData
{
public:
41
    DeclarationId m_id;
42
43
};

44
/**
Hamish Rodda's avatar
Hamish Rodda committed
45
46
 * \short An IdentifiedType is a type that has a declaration.
 *
47
48
 * Example of an identified type:
 * - A class type
Hamish Rodda's avatar
Hamish Rodda committed
49
50
51
52
 *
 * Example of types which are not identified:
 * - Pointer types (they can point to identified types, but by themselves have no declaration)
 * - Reference types (the same)
53
 * */
54
55
56
class KDEVPLATFORMLANGUAGE_EXPORT IdentifiedType
{
public:
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
    /// Destructor
    virtual ~IdentifiedType();

    /**
     * Test for equivalence with another type.
     *
     * \param rhs other type to check for equivalence
     * \returns true if equal, otherwise false.
     */
    bool equals(const IdentifiedType* rhs) const;

    /// Clear the identifier
    void clear();

    /**
     * Determine the qualified identifier for this identified type.
     *
     * \note This is relatively expensive. Use declarationId() instead when possible!
     * \returns the type's qualified identifier
     */
    QualifiedIdentifier qualifiedIdentifier() const;

    /// Determine this identified type's hash value. \returns the hash value
    uint hash() const;

    /**
     * Access the identified type's declaration id, which is a unique global identifier for the
     * type even when the same identifier represents a different type in a different context
     * or source file.
     *
     * \returns the declaration identifier.
     * \sa DeclarationId
     */
    DeclarationId declarationId() const;

    /**
     * Set the globally unique declaration \a id.
     * \param id new identifier
     */
    void setDeclarationId(const DeclarationId& id);

    /**
     * Look up the declaration of this type in the given \a top context.
     *
     * \param top Top context to search for the declaration within
     * \returns the declaration corresponding to this identified type
     */
    Declaration* declaration(const TopDUContext* top) const;

    /**
     * \param top Top context to search for the declaration within
     * Convenience function that returns the internal context of the attached declaration,
     * or zero if no declaration is found, or if it does not have an internal context.
     */
    DUContext* internalContext(const TopDUContext* top) const;

    /**
     * Set the declaration which created this type.
     *
     * \note You should be careful when setting this, because it also changes the meaning of the declaration.
     *
     * The logic is:
     * If a declaration has a set abstractType(), and that abstractType() has set the same declaration as declaration(),
     * then the declaration declares the type(thus it is a type-declaration, see Declaration::kind())
     *
     * \param declaration Declaration which created the type
     * */
    void setDeclaration(Declaration* declaration);

    /// Allow IdentifiedType to access its data.
    virtual IdentifiedTypeData* idData() = 0;
    /// Allow IdentifiedType to access its data.
    virtual const IdentifiedTypeData* idData() const = 0;
130
};
131

132
133
///Implements everything necessary to merge the given Parent class with IdentifiedType
///Your used Data class must be based on the Data member class
134
135
136
137
138
139
template <class Parent>
class MergeIdentifiedType
    : public Parent
    , public IdentifiedType
{
public:
Hamish Rodda's avatar
Hamish Rodda committed
140

141
142
143
144
    class Data
        : public Parent::Data
        , public IdentifiedTypeData
    {
145
    };
Hamish Rodda's avatar
Hamish Rodda committed
146

147
148
    MergeIdentifiedType()
    {
149
150
    }

151
152
    explicit MergeIdentifiedType(Data& data) : Parent(data)
    {
153
    }
Hamish Rodda's avatar
Hamish Rodda committed
154

155
156
    MergeIdentifiedType(const MergeIdentifiedType& rhs) = delete;

157
158
159
    IdentifiedTypeData* idData() override
    {
        return static_cast<Data*>(this->d_func_dynamic());
160
    }
Hamish Rodda's avatar
Hamish Rodda committed
161

162
163
164
    const IdentifiedTypeData* idData() const override
    {
        return static_cast<const Data*>(this->d_func());
165
    }
Hamish Rodda's avatar
Hamish Rodda committed
166

167
    bool equals(const KDevelop::AbstractType* rhs) const override
Hamish Rodda's avatar
Hamish Rodda committed
168
    {
169
170
        if (!Parent::equals(rhs))
            return false;
Hamish Rodda's avatar
Hamish Rodda committed
171

172
        const auto* rhsId = dynamic_cast<const IdentifiedType*>(rhs);
173
        Q_ASSERT(rhsId);
Hamish Rodda's avatar
Hamish Rodda committed
174

175
        return IdentifiedType::equals(static_cast<const IdentifiedType*>(rhsId));
Hamish Rodda's avatar
Hamish Rodda committed
176
    }
177
178
179
180
};
}

#endif