1 | /****************************************************************************
|
---|
2 | **
|
---|
3 | ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
|
---|
4 | ** All rights reserved.
|
---|
5 | ** Contact: Nokia Corporation ([email protected])
|
---|
6 | **
|
---|
7 | ** This file is part of the QtXmlPatterns module of the Qt Toolkit.
|
---|
8 | **
|
---|
9 | ** $QT_BEGIN_LICENSE:LGPL$
|
---|
10 | ** Commercial Usage
|
---|
11 | ** Licensees holding valid Qt Commercial licenses may use this file in
|
---|
12 | ** accordance with the Qt Commercial License Agreement provided with the
|
---|
13 | ** Software or, alternatively, in accordance with the terms contained in
|
---|
14 | ** a written agreement between you and Nokia.
|
---|
15 | **
|
---|
16 | ** GNU Lesser General Public License Usage
|
---|
17 | ** Alternatively, this file may be used under the terms of the GNU Lesser
|
---|
18 | ** General Public License version 2.1 as published by the Free Software
|
---|
19 | ** Foundation and appearing in the file LICENSE.LGPL included in the
|
---|
20 | ** packaging of this file. Please review the following information to
|
---|
21 | ** ensure the GNU Lesser General Public License version 2.1 requirements
|
---|
22 | ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
---|
23 | **
|
---|
24 | ** In addition, as a special exception, Nokia gives you certain additional
|
---|
25 | ** rights. These rights are described in the Nokia Qt LGPL Exception
|
---|
26 | ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
---|
27 | **
|
---|
28 | ** GNU General Public License Usage
|
---|
29 | ** Alternatively, this file may be used under the terms of the GNU
|
---|
30 | ** General Public License version 3.0 as published by the Free Software
|
---|
31 | ** Foundation and appearing in the file LICENSE.GPL included in the
|
---|
32 | ** packaging of this file. Please review the following information to
|
---|
33 | ** ensure the GNU General Public License version 3.0 requirements will be
|
---|
34 | ** met: http://www.gnu.org/copyleft/gpl.html.
|
---|
35 | **
|
---|
36 | ** If you have questions regarding the use of this file, please contact
|
---|
37 | ** Nokia at [email protected].
|
---|
38 | ** $QT_END_LICENSE$
|
---|
39 | **
|
---|
40 | ****************************************************************************/
|
---|
41 |
|
---|
42 | //
|
---|
43 | // W A R N I N G
|
---|
44 | // -------------
|
---|
45 | //
|
---|
46 | // This file is not part of the Qt API. It exists purely as an
|
---|
47 | // implementation detail. This header file may change from version to
|
---|
48 | // version without notice, or even be removed.
|
---|
49 | //
|
---|
50 | // We mean it.
|
---|
51 |
|
---|
52 | #ifndef Patternist_Expression_H
|
---|
53 | #define Patternist_Expression_H
|
---|
54 |
|
---|
55 | #include <QFlags>
|
---|
56 | #include <QSharedData>
|
---|
57 |
|
---|
58 | #include "qcppcastinghelper_p.h"
|
---|
59 | #include "qdebug_p.h"
|
---|
60 | #include "qdynamiccontext_p.h"
|
---|
61 | #include "qexpressiondispatch_p.h"
|
---|
62 | #include "qitem_p.h"
|
---|
63 | #include "qsequencetype_p.h"
|
---|
64 | #include "qsourcelocationreflection_p.h"
|
---|
65 | #include "qstaticcontext_p.h"
|
---|
66 |
|
---|
67 | QT_BEGIN_HEADER
|
---|
68 |
|
---|
69 | QT_BEGIN_NAMESPACE
|
---|
70 |
|
---|
71 | template<typename T> class QList;
|
---|
72 | template<typename T> class QVector;
|
---|
73 |
|
---|
74 | namespace QPatternist
|
---|
75 | {
|
---|
76 | template<typename T, typename ListType> class ListIterator;
|
---|
77 | class OptimizationPass;
|
---|
78 |
|
---|
79 | /**
|
---|
80 | * @short Base class for all AST nodes in an XPath/XQuery/XSL-T expression.
|
---|
81 | *
|
---|
82 | * @section ExpressionCreation Expression Compilation
|
---|
83 | *
|
---|
84 | * @subsection ExpressionCreationParser The process of creating an Expression
|
---|
85 | *
|
---|
86 | * The initial step of creating an internal representation(in some circles
|
---|
87 | * called an IR tree) of the XPath string follows classic compiler design: a scanner
|
---|
88 | * is invoked, resulting in tokens, which sub-sequently are consumed by a parser
|
---|
89 | * which groups the tokens into rules, resulting in the creation of
|
---|
90 | * Abstract Syntax Tree(AST) nodes that are arranged in a hierarchical structure
|
---|
91 | * similar to the EBNF.
|
---|
92 | *
|
---|
93 | * More specifically, ExpressionFactory::createExpression() is called with a
|
---|
94 | * pointer to a static context, and the string for the expression. This is subsequently
|
---|
95 | * tokenized by a Flex scanner. Mistakes detected at this stage is syntax
|
---|
96 | * errors, as well as a few semantical errors. Syntax errors can be divided
|
---|
97 | * in two types:
|
---|
98 | *
|
---|
99 | * - The scanner detects it. An example is the expression "23Eb3" which
|
---|
100 | * is not a valid number literal, or "1prefix:my-element" which is not a
|
---|
101 | * valid QName.
|
---|
102 | * - The parser detects it. This means a syntax error at a
|
---|
103 | * higher level, that a group of tokens couldn't be reduced to a
|
---|
104 | * rule(expression). An example is the expression "if(a = b) 'match' else
|
---|
105 | * 'no match'"; the tokenizer would handle it fine, but the parser would
|
---|
106 | * fail because the tokens could not be reduced to a rule due to the token
|
---|
107 | * for the "then" word was missing.
|
---|
108 | *
|
---|
109 | * Apart from the syntax errors, the actions in the parser also detects
|
---|
110 | * errors when creating the corresponding expressions. This is for example
|
---|
111 | * that no namespace binding for a prefix could be found, or that a function
|
---|
112 | * call was used which no function implementation could be found for.
|
---|
113 | *
|
---|
114 | * When the parser has finished, the result is an AST. That is, a
|
---|
115 | * hierarchical structure consisting of Expression sub-classes. The
|
---|
116 | * individual expressions haven't at this point done anything beyond
|
---|
117 | * receiving their child-expressions(if any), and hence reminds of a
|
---|
118 | * "construction scaffold". In other words, a tree for the expression
|
---|
119 | * <tt>'string' + 1 and xs:date('2001-03-13')</tt> could have been created, even if
|
---|
120 | * that expression contains errors(one can't add a xs:integer to a xs:string,
|
---|
121 | * and the Effective %Boolean Value cannot be extracted for date types).
|
---|
122 | *
|
---|
123 | * @subsection ExpressionCreationTypeChecking Type Checking
|
---|
124 | *
|
---|
125 | * After the AST creation, ExpressionFactory::createExpression continues with
|
---|
126 | * calling the AST node(which is an Expression instance)'s typeCheck()
|
---|
127 | * function. This step ensures that the static types of the operands matches
|
---|
128 | * the operators, and in the cases where it doesn't, modifies the AST such
|
---|
129 | * that the necessary conversions are done -- if possible, otherwise the
|
---|
130 | * result is a type error.
|
---|
131 | *
|
---|
132 | *
|
---|
133 | * This step corresponds roughly to what <a
|
---|
134 | * href="http://www.w3.org/TR/xpath20/#id-static-analysis">2.2.3.1 Static Analysis Phase</a>
|
---|
135 | * labels operation tree normalization; step SQ5.
|
---|
136 | *
|
---|
137 | * @subsection ExpressionCreationCompression Compressing -- Optimization and Fixup
|
---|
138 | *
|
---|
139 | * The last step is calling compress(). This function is not called
|
---|
140 | * 'optimize', 'simplify' or the like, because although it performs all
|
---|
141 | * optimization, it also involves mandatory stages.
|
---|
142 | *
|
---|
143 | * One such is const folding, which while being an efficient optimization,
|
---|
144 | * also is a necessity for many XSL-T constructs. Another important step is
|
---|
145 | * that functions which had an evaluation dependency on the static context(as
|
---|
146 | * opposed to the dynamic) performs their "fixup".
|
---|
147 | *
|
---|
148 | * In other words, this stage potentially performs AST re-writes. For example,
|
---|
149 | * the expression <tt>3 + 3, concat('foo', '-', 'bar'), true() and false()</tt> would
|
---|
150 | * result in an AST corresponding to <tt>6, 'foo-bar', false()</tt>. This process
|
---|
151 | * is done backwards; each expression asks its operands to compress before it
|
---|
152 | * performs its own compression(and so forth, until the root expression's call
|
---|
153 | * returns to the caller).
|
---|
154 | *
|
---|
155 | * @see <a href="http://www.w3.org/TR/xpath20/#id-errors-and-opt">XML Path Language
|
---|
156 | * (XPath) 2.0, 2.3.4 Errors and Optimization</a>
|
---|
157 | * @see <a href="http://www.w3.org/TR/xpath20/#id-expression-processing">XML Path
|
---|
158 | * Language (XPath) 2.0, 2.2.3 Expression Processing</a>
|
---|
159 | * @see <a href="http://www.w3.org/TR/xquery-xpath-parsing/">Building a Tokenizer
|
---|
160 | * for XPath or XQuery</a>
|
---|
161 | * @see ExpressionFactory
|
---|
162 | * @author Frans Englich <[email protected]>
|
---|
163 | * @ingroup Patternist_expressions
|
---|
164 | */
|
---|
165 | class Q_AUTOTEST_EXPORT Expression : public QSharedData
|
---|
166 | , public CppCastingHelper<Expression>
|
---|
167 | , public SourceLocationReflection
|
---|
168 | {
|
---|
169 | public:
|
---|
170 | /**
|
---|
171 | * @short A smart pointer wrapping mutable Expression instances.
|
---|
172 | */
|
---|
173 | typedef QExplicitlySharedDataPointer<Expression> Ptr;
|
---|
174 |
|
---|
175 | /**
|
---|
176 | * @short A smart pointer wrapping @c const Expression instances.
|
---|
177 | */
|
---|
178 | typedef QExplicitlySharedDataPointer<const Expression> ConstPtr;
|
---|
179 |
|
---|
180 | /**
|
---|
181 | * A list of Expression instances, each wrapped in a smart pointer.
|
---|
182 | */
|
---|
183 | typedef QList<Expression::Ptr> List;
|
---|
184 |
|
---|
185 | /**
|
---|
186 | * A vector of Expression instances, each wrapped in a smart pointer.
|
---|
187 | */
|
---|
188 | typedef QVector<Expression::Ptr> Vector;
|
---|
189 |
|
---|
190 | typedef QT_PREPEND_NAMESPACE(QAbstractXmlForwardIterator<Expression::Ptr>)
|
---|
191 | QAbstractXmlForwardIterator;
|
---|
192 |
|
---|
193 | /**
|
---|
194 | * Enum flags describing the characteristics of the expression.
|
---|
195 | *
|
---|
196 | * @see Expression::properties()
|
---|
197 | */
|
---|
198 | enum Property
|
---|
199 | {
|
---|
200 | /**
|
---|
201 | * This flag applies for functions, and results in the expression <tt>.</tt>
|
---|
202 | * being appended to its operands if its operand count is lower than the
|
---|
203 | * maximum amount of arguments.
|
---|
204 | *
|
---|
205 | * In effect, it result in a modification of the function's arguments to have
|
---|
206 | * appended the context item.
|
---|
207 | *
|
---|
208 | * One function which has this property is <tt>fn:number()</tt>.
|
---|
209 | *
|
---|
210 | * @see ContextItem
|
---|
211 | * @see <a href="http://www.w3.org/TR/xpath-functions/#func-signatures">XQuery 1.0 and
|
---|
212 | * XPath 2.0 Functions and Operators, 1.3 Function Signatures and Descriptions</a>
|
---|
213 | */
|
---|
214 | UseContextItem = 1,
|
---|
215 |
|
---|
216 | /**
|
---|
217 | * Disables compression(evaluation at compile time), such that the
|
---|
218 | * Expression isn't const-folded, but ensured to be run at runtime. The
|
---|
219 | * operands are still attempted to be compressed, unless
|
---|
220 | * they override compression as well.
|
---|
221 | *
|
---|
222 | * @see compress()
|
---|
223 | */
|
---|
224 | DisableElimination = 1 << 1,
|
---|
225 |
|
---|
226 | /**
|
---|
227 | * Signals that the expression is already evaluated and can be considered
|
---|
228 | * a constant value.
|
---|
229 | * For example, atomic values return this flag in their
|
---|
230 | * implementations of the properties() functions.
|
---|
231 | *
|
---|
232 | * @see isEvaluated()
|
---|
233 | */
|
---|
234 | IsEvaluated = 1 << 2,
|
---|
235 |
|
---|
236 | /**
|
---|
237 | * Signals that the expression cannot be optimized away by judging
|
---|
238 | * its static type.
|
---|
239 | *
|
---|
240 | * This is currently used for properly handling the @c none type, in
|
---|
241 | * the <tt>fn:error()</tt> function. In type operations, the none type doesn't show
|
---|
242 | * up and that can make expressions, such as InstanceOf, believe
|
---|
243 | * it is safe to const fold, while it in fact is not.
|
---|
244 | */
|
---|
245 | DisableTypingDeduction = 1 << 3,
|
---|
246 |
|
---|
247 | /**
|
---|
248 | * This property affects the static type -- staticType() -- of an expression. It
|
---|
249 | * is implemented in FunctionCall::staticType() and therefore only work for FunctionCall
|
---|
250 | * sub-classes and when that function is not re-implemented in an inhibiting way.
|
---|
251 | *
|
---|
252 | * When set, the cardinality of the static type is zero if the Expression's first
|
---|
253 | * operand allows an empty sequence, otherwise it is the cardinality of the Expression's
|
---|
254 | * static type modulo Cardinality::empty(). This is used for specifying proper static
|
---|
255 | * type inference for functions that have "If $arg is the empty sequence,
|
---|
256 | * the empty sequence is returned." However, before setting this property one
|
---|
257 | * must be aware that no other conditions can lead to the empty sequence, since
|
---|
258 | * otherwise the static type would be wrong.
|
---|
259 | */
|
---|
260 | EmptynessFollowsChild = 1 << 4,
|
---|
261 |
|
---|
262 | /**
|
---|
263 | * This is similar to EmptynessFollowsChild, and also implemented in FunctionCall.
|
---|
264 | * When set, it makes FunctionCall::typeCheck() rewrite itself into an empty sequence
|
---|
265 | * if the first operand is the empty sequence.
|
---|
266 | *
|
---|
267 | * This property is often used together with EmptynessFollowsChild.
|
---|
268 | */
|
---|
269 | RewriteToEmptyOnEmpty = 1 << 5,
|
---|
270 |
|
---|
271 | /**
|
---|
272 | * When set, it signals that the focus cannot be undefined. For example,
|
---|
273 | * the <tt>fn:position()</tt> function extracts information from the focus. Setting
|
---|
274 | * this flag ensures type checking is carried out appropriately.
|
---|
275 | *
|
---|
276 | * However, setting RequiresFocus does not imply this Expression requires the context
|
---|
277 | * item to be defined. It only means the focus, of somekind, needs to be defined.
|
---|
278 | *
|
---|
279 | * @see RequiresContextItem
|
---|
280 | */
|
---|
281 | RequiresFocus = 1 << 6,
|
---|
282 |
|
---|
283 | /**
|
---|
284 | * An Expression with this Property set, signals that it only affects
|
---|
285 | * the order of its return value.
|
---|
286 | */
|
---|
287 | AffectsOrderOnly = 1 << 7,
|
---|
288 |
|
---|
289 | /**
|
---|
290 | * When set, signals that the context item, must be defined for this Expression. When
|
---|
291 | * setting this property, expectedContextItemType() must be re-implemented.
|
---|
292 | *
|
---|
293 | * Setting this property also sets RequiresFocus.
|
---|
294 | *
|
---|
295 | * @see DynamicContext::contextItem()
|
---|
296 | */
|
---|
297 | RequiresContextItem = (1 << 8) | RequiresFocus,
|
---|
298 |
|
---|
299 | /**
|
---|
300 | * When set, signals that this expression creates a focus for its last operand.
|
---|
301 | * When set, newFocusType() must be overridden to return the static type
|
---|
302 | * of the context item.
|
---|
303 | *
|
---|
304 | * @see announceFocusType()
|
---|
305 | * @see newFocusType()
|
---|
306 | */
|
---|
307 | CreatesFocusForLast = 1 << 9,
|
---|
308 |
|
---|
309 | /**
|
---|
310 | * Signals that the last operand is a collation argument. This ensures
|
---|
311 | * that the necessary code is generated for checking that the collation
|
---|
312 | * is supported.
|
---|
313 | *
|
---|
314 | * This only applies to sub-classes of FunctionCall.
|
---|
315 | */
|
---|
316 | LastOperandIsCollation = 1 << 10,
|
---|
317 |
|
---|
318 | /**
|
---|
319 | * When set, the Expression depends on local variables such as
|
---|
320 | * those found in @c for expressions. However, this does not
|
---|
321 | * include let bindings.
|
---|
322 | */
|
---|
323 | DependsOnLocalVariable = (1 << 11) | DisableElimination,
|
---|
324 |
|
---|
325 | /**
|
---|
326 | * When set, it signals that the Expression does not need
|
---|
327 | * an evaluation cache, despite what other flags might imply.
|
---|
328 | */
|
---|
329 | EvaluationCacheRedundant = (1 << 12),
|
---|
330 |
|
---|
331 | /**
|
---|
332 | * Signals that the Expression constructs nodes, either directly
|
---|
333 | * or computationally. For example, AttributeConstructor has this property
|
---|
334 | * set.
|
---|
335 | *
|
---|
336 | * Since node constructors constructs nodes which have node
|
---|
337 | * identities, node constructors are considered creative on
|
---|
338 | * evaluation.
|
---|
339 | */
|
---|
340 | IsNodeConstructor = 1 << 13,
|
---|
341 |
|
---|
342 | /**
|
---|
343 | * Whether this expression requires the current item, as returned
|
---|
344 | * from @c fn:current().
|
---|
345 | *
|
---|
346 | * CurrentFN uses this flag.
|
---|
347 | */
|
---|
348 | RequiresCurrentItem = 1 << 14
|
---|
349 | };
|
---|
350 |
|
---|
351 | /**
|
---|
352 | * A QFlags template for type-safe handling of ExpressionProperty values. If
|
---|
353 | * Expression::Property flags needs to be stored in a class, declared the variable
|
---|
354 | * to be of type Expression::Properties.
|
---|
355 | *
|
---|
356 | * @see QFlags
|
---|
357 | */
|
---|
358 | typedef QFlags<Property> Properties;
|
---|
359 |
|
---|
360 | /**
|
---|
361 | * Enumerators that identifies Expression sub-classes.
|
---|
362 | *
|
---|
363 | * @see id()
|
---|
364 | */
|
---|
365 | enum ID
|
---|
366 | {
|
---|
367 | /**
|
---|
368 | * Identifies Boolean.
|
---|
369 | */
|
---|
370 | IDBooleanValue = 1,
|
---|
371 |
|
---|
372 | /**
|
---|
373 | * Identifies CountFN.
|
---|
374 | */
|
---|
375 | IDCountFN,
|
---|
376 |
|
---|
377 | /**
|
---|
378 | * Identifies EmptyFN.
|
---|
379 | */
|
---|
380 | IDEmptyFN,
|
---|
381 |
|
---|
382 | /**
|
---|
383 | * Identifies ExistsFN.
|
---|
384 | */
|
---|
385 | IDExistsFN,
|
---|
386 |
|
---|
387 | /**
|
---|
388 | * Identifies ExpressionSequence and LiteralSequence.
|
---|
389 | */
|
---|
390 | IDExpressionSequence,
|
---|
391 |
|
---|
392 | /**
|
---|
393 | * Identifies GeneralComparison.
|
---|
394 | */
|
---|
395 | IDGeneralComparison,
|
---|
396 |
|
---|
397 | /**
|
---|
398 | * Identifies IfThenClause.
|
---|
399 | */
|
---|
400 | IDIfThenClause,
|
---|
401 |
|
---|
402 | /**
|
---|
403 | * Identifies nothing in particular. The default implementation
|
---|
404 | * of id() returns this, which is suitable for Expression instances
|
---|
405 | * which never needs to be identified in this aspect.
|
---|
406 | */
|
---|
407 | IDIgnorableExpression,
|
---|
408 |
|
---|
409 | /**
|
---|
410 | * Identifies Integer.
|
---|
411 | */
|
---|
412 | IDIntegerValue,
|
---|
413 |
|
---|
414 | /**
|
---|
415 | * Identifies PositionFN.
|
---|
416 | */
|
---|
417 | IDPositionFN,
|
---|
418 |
|
---|
419 | /**
|
---|
420 | * Identifies AtomicString, AnyURI, and UntypedAtomic.
|
---|
421 | */
|
---|
422 | IDStringValue,
|
---|
423 |
|
---|
424 | /**
|
---|
425 | * Identifies ValueComparison.
|
---|
426 | */
|
---|
427 | IDValueComparison,
|
---|
|
---|