1 | /**************************************************************************** |
2 | ** |
3 | ** Copyright (C) 2016 The Qt Company Ltd. |
4 | ** Contact: https://www.qt.io/licensing/ |
5 | ** |
6 | ** This file is part of the QtXmlPatterns module of the Qt Toolkit. |
7 | ** |
8 | ** $QT_BEGIN_LICENSE:LGPL$ |
9 | ** Commercial License Usage |
10 | ** Licensees holding valid commercial Qt licenses may use this file in |
11 | ** accordance with the commercial license agreement provided with the |
12 | ** Software or, alternatively, in accordance with the terms contained in |
13 | ** a written agreement between you and The Qt Company. For licensing terms |
14 | ** and conditions see https://www.qt.io/terms-conditions. For further |
15 | ** information use the contact form at https://www.qt.io/contact-us. |
16 | ** |
17 | ** GNU Lesser General Public License Usage |
18 | ** Alternatively, this file may be used under the terms of the GNU Lesser |
19 | ** General Public License version 3 as published by the Free Software |
20 | ** Foundation and appearing in the file LICENSE.LGPL3 included in the |
21 | ** packaging of this file. Please review the following information to |
22 | ** ensure the GNU Lesser General Public License version 3 requirements |
23 | ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. |
24 | ** |
25 | ** GNU General Public License Usage |
26 | ** Alternatively, this file may be used under the terms of the GNU |
27 | ** General Public License version 2.0 or (at your option) the GNU General |
28 | ** Public license version 3 or any later version approved by the KDE Free |
29 | ** Qt Foundation. The licenses are as published by the Free Software |
30 | ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 |
31 | ** included in the packaging of this file. Please review the following |
32 | ** information to ensure the GNU General Public License requirements will |
33 | ** be met: https://www.gnu.org/licenses/gpl-2.0.html and |
34 | ** https://www.gnu.org/licenses/gpl-3.0.html. |
35 | ** |
36 | ** $QT_END_LICENSE$ |
37 | ** |
38 | ****************************************************************************/ |
39 | |
40 | // |
41 | // W A R N I N G |
42 | // ------------- |
43 | // |
44 | // This file is not part of the Qt API. It exists purely as an |
45 | // implementation detail. This header file may change from version to |
46 | // version without notice, or even be removed. |
47 | // |
48 | // We mean it. |
49 | |
50 | #ifndef Patternist_ItemType_H |
51 | #define Patternist_ItemType_H |
52 | |
53 | #include <QSharedData> |
54 | |
55 | #include <QtXmlPatterns/private/qnamepool_p.h> |
56 | |
57 | QT_BEGIN_NAMESPACE |
58 | |
59 | template<typename T> class QList; |
60 | |
61 | namespace QPatternist |
62 | { |
63 | class Item; |
64 | |
65 | /** |
66 | * @short Base class for the XPath Data Model's type hierarchy. |
67 | * |
68 | * It can not be instantiated, but it's possible via ItemType's two subtypes: |
69 | * Nodes, represented by QXmlNodeModelIndex, and atom types, represented by AtomicType. |
70 | * |
71 | * ItemType tries to by its design stay close to the notation used in Formal Semantics. |
72 | * The operator|() is a good example, it allow typing code to be written |
73 | * similar to how inference rules in the specification are written. |
74 | * |
75 | * @ingroup Patternist_types |
76 | * @author Frans Englich <frans.englich@nokia.com> |
77 | */ |
78 | class Q_AUTOTEST_EXPORT ItemType : public virtual QSharedData |
79 | { |
80 | public: |
81 | /** |
82 | * A smart pointer wrapping ItemType instances. |
83 | */ |
84 | typedef QExplicitlySharedDataPointer<ItemType> Ptr; |
85 | /** |
86 | * A list of ItemType instances, each wrapped in a smart pointer. |
87 | */ |
88 | typedef QList<ItemType::Ptr> List; |
89 | |
90 | virtual ~ItemType(); |
91 | |
92 | enum Category |
93 | { |
94 | NodeNameTest = 1, |
95 | Other = 2 |
96 | }; |
97 | |
98 | /** |
99 | * Determines whether this ItemType is equal to @p other. |
100 | * |
101 | * Many types are represented by singleton instances. For example, there |
102 | * exists only one instance of IntegerType. This operator==() takes advantage |
103 | * of that and uses equalness of object addresses for determining semantic |
104 | * equalness. This function is as a result fast. |
105 | * |
106 | * However, it's overridden in some cases, such as for name tests, where |
107 | * it's not guaranteed that there exists two types. |
108 | * |
109 | * @returns @c true if this ItemType is equal to @p other, otherwise @c false. |
110 | */ |
111 | virtual bool operator==(const ItemType &other) const; |
112 | |
113 | /** |
114 | * @returns the result of operator==() negated. |
115 | */ |
116 | inline bool operator!=(const ItemType &other) const; |
117 | |
118 | /** |
119 | * @returns a string representing the type. Used for diagnostic purposes. For a |
120 | * type whose name is a QName, a lexical representation should be returned |
121 | * with the prefix being a conventional one. Examples of a display names |
122 | * are "item()" and "xs:nonPositiveInteger". |
123 | */ |
124 | virtual QString displayName(const NamePool::Ptr &np) const = 0; |
125 | |
126 | /** |
127 | * @param item the item that is to be matched. This is guaranteed by the caller |
128 | * to never be @c null. |
129 | */ |
130 | virtual bool itemMatches(const Item &item) const = 0; |
131 | |
132 | /** |
133 | * @short Returns @c true if @p other matches this type. That is, if @p |
134 | * other is equal to this type or a subtype of this type. |
135 | * |
136 | * For instance this statements evaluates to @c true: |
137 | * |
138 | * @code |
139 | * BuiltinTypes::xsAnyAtomicType->xdtTypeMatches(BuiltinTypes::xsString); |
140 | * @endcode |
141 | * |
142 | * but this evaluates to @c false: |
143 | * |
144 | * @code |
145 | * BuiltinTypes::attribute->xdtTypeMatches(BuiltinTypes::node); |
146 | * @endcode |
147 | * |
148 | * @param other the other ItemType that is to be matched. This is guaranteed by the caller |
149 | * to never be @c null. |
150 | */ |
151 | virtual bool xdtTypeMatches(const ItemType::Ptr &other) const = 0; |
152 | |
153 | virtual bool isNodeType() const = 0; |
154 | virtual bool isAtomicType() const = 0; |
155 | |
156 | /** |
157 | * Determines the type's parent type in the XPath Data Model hierarchy. For example, |
158 | * for the type xs:anyAtomicType, the super type in the XPath Data Model is item(), not |
159 | * xs:anySimpleType. SchemaType::xdtSuperType navigates the schema hierarchy. |
160 | * |
161 | * @see SchemaType::wxsSuperType() |
162 | * @returns the type's super type. |
163 | */ |
164 | virtual ItemType::Ptr xdtSuperType() const = 0; |
165 | |
166 | /** |
167 | * @todo docs mention union, give if-expression example. |
168 | * |
169 | * Determines the super type that is closest to this ItemType and @p other. That is, |
170 | * the parent type of them both. For example, for the type xs:integer and xs:string |
171 | * the parent type is xs:anyAtomicType. For xs:NOTATION and processing-instruction(), it |
172 | * is item(), to name another example. |
173 | * |
174 | * This function can be seen as the type function prime(Type), defined in Formal Semantics. |
175 | * |
176 | * This walks the XPath Data Model type hierarchy, not the W3C XML Schema hierarchy. |
177 | * @param other the item type 'this' object, should be compared with. Invoking xdtSuperType |
178 | * on 'this' object with @p other as argument yields the same result as invoking the |
179 | * function on @p other with 'this' |
180 | * as argument. |
181 | * @returns the parent type of 'this' and @p other |
182 | * @see <a href="http://www.w3.org/TR/xquery-semantics/\#jd_prime">XQuery 1.0 and XPath 2.0 |
183 | * Formal Semantics, Prime Types, type function prime(Type)</a> |
184 | */ |
185 | virtual const ItemType &operator|(const ItemType &other) const; |
186 | |
187 | /** |
188 | * Determines the atomic type that the resulting sequence after |
189 | * atomization of this node would be an instance of. For example, for document node, |
190 | * xs:untypedAtomic is returned. Phrased differently, the returned type is the |
191 | * type of the result of the typed-value accessor. |
192 | * |
193 | * If the type cannot be atomized, it returns @c null. |
194 | * |
195 | * This function is also defined on SchemaType, because some schema types can also be |
196 | * atomized. |
197 | * |
198 | * @see SchemaType::atomizedType() |
199 | * @see <a href="http://www.w3.org/TR/xpath-datamodel/\#dm-typed-value">XQuery 1.0 |
200 | * and XPath 2.0 Data Model, 5.15 typed-value Accessor</a> |
201 | * @see <a href="http://www.w3.org/TR/xquery-semantics/#jd_data">XQuery 1.0 |
202 | * and XPath 2.0 Formal Semantics, data on auxiliary judgment</a> |
203 | * @returns the atomic type that the resulting sequence |
204 | * when performing atomization is an instance of. |
205 | */ |
206 | virtual ItemType::Ptr atomizedType() const = 0; |
207 | |
208 | /** |
209 | * @returns always Other |
210 | */ |
211 | virtual Category itemTypeCategory() const; |
212 | |
213 | enum InstanceOf |
214 | { |
215 | ClassLocalNameTest, |
216 | ClassNamespaceNameTest, |
217 | ClassQNameTest, |
218 | ClassOther |
219 | }; |
220 | |
221 | /** |
222 | * Determines what class this ItemType is an instance of. This |
223 | * is in needed in some implementations of operator operator==(). By |
224 | * default, Other is returned. |
225 | */ |
226 | virtual InstanceOf instanceOf() const; |
227 | |
228 | inline ItemType() |
229 | { |
230 | } |
231 | |
232 | private: |
233 | Q_DISABLE_COPY(ItemType) |
234 | }; |
235 | |
236 | /** |
237 | * This operator exists for making it easier to use the ItemType class, which |
238 | * always are wrapped in ItemType::Ptr, by taking care of the dereferencing |
239 | * of ItemType::Ptr instances. Semantically, it performs the same as |
240 | * ItemType's operator of the same name. |
241 | * |
242 | * @relates ItemType |
243 | * @see ItemType::operator|() |
244 | * @see operator|=(ItemType::Ptr &, const ItemType::Ptr &) |
245 | */ |
246 | inline ItemType::Ptr operator|(const ItemType::Ptr &op1, |
247 | const ItemType::Ptr &op2) |
248 | { |
249 | return ItemType::Ptr(const_cast<ItemType *>(&(*op1 | *op2))); |
250 | } |
251 | |
252 | bool ItemType::operator!=(const ItemType &other) const |
253 | { |
254 | return this != &other; |
255 | } |
256 | |
257 | /** |
258 | * @short Computes the union type of @p op1 and @p op2, and assigns it to @p op1. |
259 | * |
260 | * This operator exists for making it easier to use the ItemType class, which |
261 | * always are wrapped in ItemType::Ptr, by taking care of the dereferencing |
262 | * of the ItemType::Ptr instances. |
263 | * |
264 | * @relates ItemType |
265 | * @see operator|(const ItemType::Ptr &, const ItemType::Ptr &) |
266 | * @param op1 if @c null, @p op2 is returned unchanged |
267 | * @param op2 the other operand |
268 | */ |
269 | inline void operator|=(ItemType::Ptr &op1, const ItemType::Ptr &op2) |
270 | { |
271 | op1 = op1 | op2; |
272 | } |
273 | |
274 | } |
275 | |
276 | Q_DECLARE_TYPEINFO(QPatternist::ItemType::Ptr, Q_MOVABLE_TYPE); |
277 | |
278 | QT_END_NAMESPACE |
279 | |
280 | #endif |
281 | |