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_Expression_H |
51 | #define Patternist_Expression_H |
52 | |
53 | #include <QFlags> |
54 | #include <QSharedData> |
55 | |
56 | #include <private/qcppcastinghelper_p.h> |
57 | #include <private/qxmldebug_p.h> |
58 | #include <private/qdynamiccontext_p.h> |
59 | #include <private/qexpressiondispatch_p.h> |
60 | #include <private/qitem_p.h> |
61 | #include <private/qsequencetype_p.h> |
62 | #include <private/qsourcelocationreflection_p.h> |
63 | #include <private/qstaticcontext_p.h> |
64 | |
65 | QT_BEGIN_NAMESPACE |
66 | |
67 | template<typename T> class QList; |
68 | template<typename T> class QVector; |
69 | |
70 | namespace QPatternist |
71 | { |
72 | template<typename T, typename ListType> class ListIterator; |
73 | class OptimizationPass; |
74 | |
75 | /** |
76 | * @short Base class for all AST nodes in an XPath/XQuery/XSL-T expression. |
77 | * |
78 | * @section ExpressionCreation Expression Compilation |
79 | * |
80 | * @subsection ExpressionCreationParser The process of creating an Expression |
81 | * |
82 | * The initial step of creating an internal representation(in some circles |
83 | * called an IR tree) of the XPath string follows classic compiler design: a scanner |
84 | * is invoked, resulting in tokens, which sub-sequently are consumed by a parser |
85 | * which groups the tokens into rules, resulting in the creation of |
86 | * Abstract Syntax Tree(AST) nodes that are arranged in a hierarchical structure |
87 | * similar to the EBNF. |
88 | * |
89 | * More specifically, ExpressionFactory::createExpression() is called with a |
90 | * pointer to a static context, and the string for the expression. This is subsequently |
91 | * tokenized by a Flex scanner. Mistakes detected at this stage is syntax |
92 | * errors, as well as a few semantical errors. Syntax errors can be divided |
93 | * in two types: |
94 | * |
95 | * - The scanner detects it. An example is the expression "23Eb3" which |
96 | * is not a valid number literal, or "1prefix:my-element" which is not a |
97 | * valid QName. |
98 | * - The parser detects it. This means a syntax error at a |
99 | * higher level, that a group of tokens couldn't be reduced to a |
100 | * rule(expression). An example is the expression "if(a = b) 'match' else |
101 | * 'no match'"; the tokenizer would handle it fine, but the parser would |
102 | * fail because the tokens could not be reduced to a rule due to the token |
103 | * for the "then" word was missing. |
104 | * |
105 | * Apart from the syntax errors, the actions in the parser also detects |
106 | * errors when creating the corresponding expressions. This is for example |
107 | * that no namespace binding for a prefix could be found, or that a function |
108 | * call was used which no function implementation could be found for. |
109 | * |
110 | * When the parser has finished, the result is an AST. That is, a |
111 | * hierarchical structure consisting of Expression sub-classes. The |
112 | * individual expressions haven't at this point done anything beyond |
113 | * receiving their child-expressions(if any), and hence reminds of a |
114 | * "construction scaffold". In other words, a tree for the expression |
115 | * <tt>'string' + 1 and xs:date('2001-03-13')</tt> could have been created, even if |
116 | * that expression contains errors(one can't add a xs:integer to a xs:string, |
117 | * and the Effective %Boolean Value cannot be extracted for date types). |
118 | * |
119 | * @subsection ExpressionCreationTypeChecking Type Checking |
120 | * |
121 | * After the AST creation, ExpressionFactory::createExpression continues with |
122 | * calling the AST node(which is an Expression instance)'s typeCheck() |
123 | * function. This step ensures that the static types of the operands matches |
124 | * the operators, and in the cases where it doesn't, modifies the AST such |
125 | * that the necessary conversions are done -- if possible, otherwise the |
126 | * result is a type error. |
127 | * |
128 | * |
129 | * This step corresponds roughly to what <a |
130 | * href="http://www.w3.org/TR/xpath20/#id-static-analysis">2.2.3.1 Static Analysis Phase</a> |
131 | * labels operation tree normalization; step SQ5. |
132 | * |
133 | * @subsection ExpressionCreationCompression Compressing -- Optimization and Fixup |
134 | * |
135 | * The last step is calling compress(). This function is not called |
136 | * 'optimize', 'simplify' or the like, because although it performs all |
137 | * optimization, it also involves mandatory stages. |
138 | * |
139 | * One such is const folding, which while being an efficient optimization, |
140 | * also is a necessity for many XSL-T constructs. Another important step is |
141 | * that functions which had an evaluation dependency on the static context(as |
142 | * opposed to the dynamic) performs their "fixup". |
143 | * |
144 | * In other words, this stage potentially performs AST re-writes. For example, |
145 | * the expression <tt>3 + 3, concat('foo', '-', 'bar'), true() and false()</tt> would |
146 | * result in an AST corresponding to <tt>6, 'foo-bar', false()</tt>. This process |
147 | * is done backwards; each expression asks its operands to compress before it |
148 | * performs its own compression(and so forth, until the root expression's call |
149 | * returns to the caller). |
150 | * |
151 | * @see <a href="http://www.w3.org/TR/xpath20/#id-errors-and-opt">XML Path Language |
152 | * (XPath) 2.0, 2.3.4 Errors and Optimization</a> |
153 | * @see <a href="http://www.w3.org/TR/xpath20/#id-expression-processing">XML Path |
154 | * Language (XPath) 2.0, 2.2.3 Expression Processing</a> |
155 | * @see <a href="http://www.w3.org/TR/xquery-xpath-parsing/">Building a Tokenizer |
156 | * for XPath or XQuery</a> |
157 | * @see ExpressionFactory |
158 | * @author Frans Englich <frans.englich@nokia.com> |
159 | * @ingroup Patternist_expressions |
160 | */ |
161 | class Q_AUTOTEST_EXPORT Expression : public QSharedData |
162 | , public CppCastingHelper<Expression> |
163 | , public SourceLocationReflection |
164 | { |
165 | public: |
166 | /** |
167 | * @short A smart pointer wrapping mutable Expression instances. |
168 | */ |
169 | typedef QExplicitlySharedDataPointer<Expression> Ptr; |
170 | |
171 | /** |
172 | * @short A smart pointer wrapping @c const Expression instances. |
173 | */ |
174 | typedef QExplicitlySharedDataPointer<const Expression> ConstPtr; |
175 | |
176 | /** |
177 | * A list of Expression instances, each wrapped in a smart pointer. |
178 | */ |
179 | typedef QList<Expression::Ptr> List; |
180 | |
181 | /** |
182 | * A vector of Expression instances, each wrapped in a smart pointer. |
183 | */ |
184 | typedef QVector<Expression::Ptr> Vector; |
185 | |
186 | typedef QT_PREPEND_NAMESPACE(QAbstractXmlForwardIterator<Expression::Ptr>) |
187 | QAbstractXmlForwardIterator; |
188 | |
189 | /** |
190 | * Enum flags describing the characteristics of the expression. |
191 | * |
192 | * @see Expression::properties() |
193 | */ |
194 | enum Property |
195 | { |
196 | /** |
197 | * This flag applies for functions, and results in the expression <tt>.</tt> |
198 | * being appended to its operands if its operand count is lower than the |
199 | * maximum amount of arguments. |
200 | * |
201 | * In effect, it result in a modification of the function's arguments to have |
202 | * appended the context item. |
203 | * |
204 | * One function which has this property is <tt>fn:number()</tt>. |
205 | * |
206 | * @see ContextItem |
207 | * @see <a href="http://www.w3.org/TR/xpath-functions/#func-signatures">XQuery 1.0 and |
208 | * XPath 2.0 Functions and Operators, 1.3 Function Signatures and Descriptions</a> |
209 | */ |
210 | UseContextItem = 1, |
211 | |
212 | /** |
213 | * Disables compression(evaluation at compile time), such that the |
214 | * Expression isn't const-folded, but ensured to be run at runtime. The |
215 | * operands are still attempted to be compressed, unless |
216 | * they override compression as well. |
217 | * |
218 | * @see compress() |
219 | */ |
220 | DisableElimination = 1 << 1, |
221 | |
222 | /** |
223 | * Signals that the expression is already evaluated and can be considered |
224 | * a constant value. |
225 | * For example, atomic values return this flag in their |
226 | * implementations of the properties() functions. |
227 | * |
228 | * @see isEvaluated() |
229 | */ |
230 | IsEvaluated = 1 << 2, |
231 | |
232 | /** |
233 | * Signals that the expression cannot be optimized away by judging |
234 | * its static type. |
235 | * |
236 | * This is currently used for properly handling the @c none type, in |
237 | * the <tt>fn:error()</tt> function. In type operations, the none type doesn't show |
238 | * up and that can make expressions, such as InstanceOf, believe |
239 | * it is safe to const fold, while it in fact is not. |
240 | */ |
241 | DisableTypingDeduction = 1 << 3, |
242 | |
243 | /** |
244 | * This property affects the static type -- staticType() -- of an expression. It |
245 | * is implemented in FunctionCall::staticType() and therefore only work for FunctionCall |
246 | * sub-classes and when that function is not re-implemented in an inhibiting way. |
247 | * |
248 | * When set, the cardinality of the static type is zero if the Expression's first |
249 | * operand allows an empty sequence, otherwise it is the cardinality of the Expression's |
250 | * static type modulo Cardinality::empty(). This is used for specifying proper static |
251 | * type inference for functions that have "If $arg is the empty sequence, |
252 | * the empty sequence is returned." However, before setting this property one |
253 | * must be aware that no other conditions can lead to the empty sequence, since |
254 | * otherwise the static type would be wrong. |
255 | */ |
256 | EmptynessFollowsChild = 1 << 4, |
257 | |
258 | /** |
259 | * This is similar to EmptynessFollowsChild, and also implemented in FunctionCall. |
260 | * When set, it makes FunctionCall::typeCheck() rewrite itself into an empty sequence |
261 | * if the first operand is the empty sequence. |
262 | * |
263 | * This property is often used together with EmptynessFollowsChild. |
264 | */ |
265 | RewriteToEmptyOnEmpty = 1 << 5, |
266 | |
267 | /** |
268 | * When set, it signals that the focus cannot be undefined. For example, |
269 | * the <tt>fn:position()</tt> function extracts information from the focus. Setting |
270 | * this flag ensures type checking is carried out appropriately. |
271 | * |
272 | * However, setting RequiresFocus does not imply this Expression requires the context |
273 | * item to be defined. It only means the focus, of somekind, needs to be defined. |
274 | * |
275 | * @see RequiresContextItem |
276 | */ |
277 | RequiresFocus = 1 << 6, |
278 | |
279 | /** |
280 | * An Expression with this Property set, signals that it only affects |
281 | * the order of its return value. |
282 | */ |
283 | AffectsOrderOnly = 1 << 7, |
284 | |
285 | /** |
286 | * When set, signals that the context item, must be defined for this Expression. When |
287 | * setting this property, expectedContextItemType() must be re-implemented. |
288 | * |
289 | * Setting this property also sets RequiresFocus. |
290 | * |
291 | * @see DynamicContext::contextItem() |
292 | */ |
293 | RequiresContextItem = (1 << 8) | RequiresFocus, |
294 | |
295 | /** |
296 | * When set, signals that this expression creates a focus for its last operand. |
297 | * When set, newFocusType() must be overridden to return the static type |
298 | * of the context item. |
299 | * |
300 | * @see announceFocusType() |
301 | * @see newFocusType() |
302 | */ |
303 | CreatesFocusForLast = 1 << 9, |
304 | |
305 | /** |
306 | * Signals that the last operand is a collation argument. This ensures |
307 | * that the necessary code is generated for checking that the collation |
308 | * is supported. |
309 | * |
310 | * This only applies to sub-classes of FunctionCall. |
311 | */ |
312 | LastOperandIsCollation = 1 << 10, |
313 | |
314 | /** |
315 | * When set, the Expression depends on local variables such as |
316 | * those found in @c for expressions. However, this does not |
317 | * include let bindings. |
318 | */ |
319 | DependsOnLocalVariable = (1 << 11) | DisableElimination, |
320 | |
321 | /** |
322 | * When set, it signals that the Expression does not need |
323 | * an evaluation cache, despite what other flags might imply. |
324 | */ |
325 | EvaluationCacheRedundant = (1 << 12), |
326 | |
327 | /** |
328 | * Signals that the Expression constructs nodes, either directly |
329 | * or computationally. For example, AttributeConstructor has this property |
330 | * set. |
331 | * |
332 | * Since node constructors constructs nodes which have node |
333 | * identities, node constructors are considered creative on |
334 | * evaluation. |
335 | */ |
336 | IsNodeConstructor = 1 << 13, |
337 | |
338 | /** |
339 | * Whether this expression requires the current item, as returned |
340 | * from @c fn:current(). |
341 | * |
342 | * CurrentFN uses this flag. |
343 | */ |
344 | RequiresCurrentItem = 1 << 14 |
345 | }; |
346 | |
347 | /** |
348 | * A QFlags template for type-safe handling of ExpressionProperty values. If |
349 | * Expression::Property flags needs to be stored in a class, declared the variable |
350 | * to be of type Expression::Properties. |
351 | * |
352 | * @see QFlags |
353 | */ |
354 | typedef QFlags<Property> Properties; |
355 | |
356 | /** |
357 | * Enumerators that identifies Expression sub-classes. |
358 | * |
359 | * @see id() |
360 | */ |
361 | enum ID |
362 | { |
363 | /** |
364 | * Identifies Boolean. |
365 | */ |
366 | IDBooleanValue = 1, |
367 | |
368 | /** |
369 | * Identifies CountFN. |
370 | */ |
371 | IDCountFN, |
372 | |
373 | /** |
374 | * Identifies EmptyFN. |
375 | */ |
376 | IDEmptyFN, |
377 | |
378 | /** |
379 | * Identifies ExistsFN. |
380 | */ |
381 | IDExistsFN, |
382 | |
383 | /** |
384 | * Identifies ExpressionSequence. |
385 | */ |
386 | IDExpressionSequence, |
387 | |
388 | /** |
389 | * Identifies LiteralSequence. |
390 | */ |
391 | IDLiteralSequence, |
392 | |
393 | /** |
394 | * Identifies GeneralComparison. |
395 | */ |
396 | IDGeneralComparison, |
397 | |
398 | /** |
399 | * Identifies IfThenClause. |
400 | */ |
401 | IDIfThenClause, |
402 | |
403 | /** |
404 | * Identifies nothing in particular. The default implementation |
405 | * of id() returns this, which is suitable for Expression instances |
406 | * which never needs to be identified in this aspect. |
407 | */ |
408 | IDIgnorableExpression, |
409 | |
410 | /** |
411 | * Identifies Integer. |
412 | */ |
413 | IDIntegerValue, |
414 | |
415 | /** |
416 | * Identifies PositionFN. |
417 | */ |
418 | IDPositionFN, |
419 | |
420 | /** |
421 | * Identifies AtomicString, AnyURI, and UntypedAtomic. |
422 | */ |
423 | IDStringValue, |
424 | |
425 | /** |
426 | * Identifies ValueComparison. |
427 | */ |
428 | IDValueComparison, |
429 | |
430 | /** |
431 | * Identifies VariableReference. |
432 | */ |
433 | IDRangeVariableReference, |
434 | |
435 | /** |
436 | * Identifies ContextItem. |
437 | */ |
438 | IDContextItem, |
439 | |
440 | /** |
441 | * Identifies UserFunctionCallsite. |
442 | */ |
443 | IDUserFunctionCallsite, |
444 | |
445 | /** |
446 | * Identifies ExpressionVariableReference. |
447 | */ |
448 | IDExpressionVariableReference, |
449 | |
450 | /** |
451 | * Identifies ExpressionVariableReference. |
452 | */ |
453 | IDAttributeConstructor, |
454 | |
455 | /** |
456 | * Identifies UpperCaseFN. |
457 | */ |
458 | IDUpperCaseFN, |
459 | |
460 | /** |
461 | * Identifies LowerCaseFN. |
462 | */ |
463 | IDLowerCaseFN, |
464 | |
465 | /** |
466 | * Identifies FirstItemPredicate. |
467 | */ |
468 | IDFirstItemPredicate, |
469 | IDEmptySequence, |
470 | IDReturnOrderBy, |
471 | IDLetClause, |
472 | IDForClause, |
473 | IDPath, |
474 | IDNamespaceConstructor, |
475 | IDArgumentReference, |
476 | IDGenericPredicate, |
477 | IDAxisStep, |
478 | |
479 | /** |
480 | * A literal which is either @c xs:float or |
481 | * @c xs:double. |
482 | */ |
483 | IDFloat, |
484 | |
485 | IDCombineNodes, |
486 | IDUnresolvedVariableReference, |
487 | IDCardinalityVerifier |
488 | }; |
489 | |
490 | inline Expression() |
491 | { |
492 | } |
493 | virtual ~Expression(); |
494 | |
495 | /** |
496 | * Evaluate this Expression by iterating over it. This is a central function |
497 | * for evaluating expressions. |
498 | * |
499 | * Expressions must always always return a valid QAbstractXmlForwardIterator and may |
500 | * never return 0. If an empty result is of interest to be returned, the |
501 | * EmptyIterator should be returned. |
502 | * |
503 | * The default implementation returns a SingletonIterator over the |
504 | * item returned from evaluateSingleton(). |
505 | * |
506 | * @note This function may raise an exception when calling, not only |
507 | * when QAbstractXmlForwardIterator::next() is called on the return value. This is because |
508 | * in some cases evaluateSingleton() is called directly. |
509 | */ |
510 | virtual Item::Iterator::Ptr evaluateSequence(const DynamicContext::Ptr &context) const; |
511 | |
512 | /** |
513 | * @todo Docs |
514 | */ |
515 | virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const; |
516 | |
517 | /** |
518 | * Determines the Effective %Boolean Value of the expression. |
519 | * |
520 | * The Effective %Boolean Value of a value is not necessarily the same |
521 | * as converting the value to a new value of type xs:boolean. |
522 | * |
523 | * Note that this function cannot return the empty sequence, |
524 | * evaluateSingleton() must be overridden in order to be able to do |
525 | * that. |
526 | * |
527 | * The default implementation results in a type error. Hence, this function |
528 | * must be overridden if such behavior is not of interest. |
529 | * |
530 | * @see <a href="http://www.w3.org/TR/xpath20/#id-ebv">XML Path Language (XPath) 2.0, |
531 | * 2.4.3 Effective Boolean Value</a> |
532 | */ |
533 | virtual bool evaluateEBV(const DynamicContext::Ptr &context) const; |
534 | |
535 | /** |
536 | * Evaluates this Expression by sending its output to DynamicContext::outputReceiver(). |
537 | */ |
538 | virtual void evaluateToSequenceReceiver(const DynamicContext::Ptr &context) const; |
539 | |
540 | /** |
541 | * @returns the expression's child expressions. For example, a function's |
542 | * arguments is returned here. |
543 | * |
544 | * If this Expression has no operands, an empty list should be returned. |
545 | */ |
546 | virtual Expression::List operands() const = 0; |
547 | |
548 | virtual void setOperands(const Expression::List &operands) = 0; |
549 | |
550 | /** |
551 | * @returns the static type of this Expression. For example, an 'and' expression |
552 | * have as static type xs:boolean |
553 | */ |
554 | virtual SequenceType::Ptr staticType() const = 0; |
555 | |
556 | /** |
557 | * Returns a list of Sequence Types, describing the type of each of the |
558 | * expression's operands. Hence, this function has a relationship to |
559 | * the operands() function: |
560 | * |
561 | * - The lengths of the lists returned by expectedOperandTypes() |
562 | * and operands() should always be equal in length, since one |
563 | * cannot describe the type of a non-existent operand(and all |
564 | * operands must have type information). |
565 | * - A significant difference between the two functions is that while |
566 | * the type of objects in the list returned by operands() may vary |
567 | * between compilations/static context, simply because the particular |
568 | * Expression is part of different XPath expressions, the |
569 | * types in the list returned by expectedOperandTypes is always the same |
570 | * since the function/operator signature never changes. |
571 | * |
572 | * This function should not be confused with staticType(), |
573 | * which returns the static type of the expression itself, not its operands. The |
574 | * function call is an expression where this is clear: the type of the return |
575 | * value is not the same as the arguments' types. The static type of the |
576 | * operands supplied to the expression can be determined via the staticType() |
577 | * function of the instances returned by operands(). |
578 | * |
579 | * If the expression has no operands, an empty list should be returned. |
580 | */ |
581 | virtual SequenceType::List expectedOperandTypes() const = 0; |
582 | |
583 | /** |
584 | * This implementation guarantees to never rewrite away this Expression, but |
585 | * at most rewrite it as a child of another expression(that presumably have a |
586 | * type checking role). It is therefore always safe to override this |
587 | * function and call this implementation and not worry about that this Expression |
588 | * becomes deleted. |
589 | * |
590 | * Many Expressions override typeCheck() and performs optimizations, as opposed |
591 | * to doing it in the compress() stage. This is due to that the design |
592 | * of those Expressions often are tied to that certain simplifications |
593 | * are done at the typeCheck() stage of the compilation process or that |
594 | * it in some other way is related to what the typeCheck() do. Also, the earlier |
595 | * the AST can be simplified, the better the chances are for subsequent |
596 | * optimizations. |
597 | * |
598 | * It is important that the super class's typeCheck() is called before doing |
599 | * any custom type checking, since the call can change the children(notably, |
600 | * the childrens' static types). For example, if the Expression, MyExpression |
601 | * in the example, does not match the required type, typeCheck returns the Expression |
602 | * wrapped in for example ItemVerifier, CardinalityVerifier, or both. |
603 | * |
604 | * typeCheck() may be called many times. typeCheck() must either raise an error |
605 | * if this Expression is an invalid expression. Thus, it is guaranteed that an Expression |
606 | * is valid after typeCheck() is called. |
607 | * |
608 | * @param context supplies information, such as namespace bindings and |
609 | * available function signatures, that can be needed at compilation time. @p context is |
610 | * guaranteed by the caller to never null. |
611 | * @param reqType the static type that this Expression must match when evaluated. @p reqType is |
612 | * guaranteed by the caller to never null. |
613 | * @returns an Expression that can be this Expression, or another expression, |
614 | * which somehow is necessary for making this Expression conforming to |
615 | * @p reqType |
616 | */ |
617 | virtual Expression::Ptr typeCheck(const StaticContext::Ptr &context, |
618 | const SequenceType::Ptr &reqType); |
619 | |
620 | /** |
621 | * compress() is the last stage performs in compiling an expression, done after |
622 | * the initial AST build and calling typeCheck(). compress() performs crucial |
623 | * simplifications, either by having drastic performance implications or that |
624 | * some expressions depend on it for proper behavior. |
625 | * |
626 | * The default implementation performs a sparse conditional constant |
627 | * propagation. In short, a recursive process is performed in the AST |
628 | * which examines if the Expression's operands are constant values, and if so, |
629 | * performs a const fold(AST rewrite) into the result of evaluating the expression |
630 | * in question. This default behavior can be disabled by letting properties() return |
631 | * DisableElimination. |
632 | * |
633 | * This compress() stage can be relative effective due to the design of XPath, in |
634 | * part because intrinsic functions are heavily used. Many Expressions override compress() |
635 | * and do optimizations specific to what they do. Also, many Expressions performs |
636 | * optimizations in their typeCheck(). |
637 | * |
638 | * @param context the static context. Supplies compile time information, and is |
639 | * the channel for communicating error messages. |
640 | * @see <a href="http://en.wikipedia.org/wiki/Sparse_conditional_constant_propagation">Wikipedia, |
641 | * the free encyclopedia, Sparse conditional constant propagation</a> |
642 | * @see <a href="http://en.wikipedia.org/wiki/Intrinsic_function">Wikipedia, |
643 | * the free encyclopedia, Intrinsic function</a> |
644 | * @see <a href="http://en.wikipedia.org/wiki/Compiler_optimization">Wikipedia, the |
645 | * free encyclopedia, Compiler optimization</a> |
646 | */ |
647 | virtual Expression::Ptr compress(const StaticContext::Ptr &context); |
648 | |
649 | /** |
650 | * @returns a bitwise OR'd value of properties, describing the |
651 | * characteristics of the expression. These properties affects how |
652 | * this Expression is treated in for example type checking stages. |
653 | * |
654 | * The default implementation returns 0. Override and let the function return |
655 | * a different value, if that's of interest. |
656 | * |
657 | * An important decision when re-implementing properties() is whether |
658 | * to OR in the properties() of ones operands. For instance, if an |
659 | * operand has RequiresFocus set, that flag nost likely applies to the |
660 | * apparent as well, since it depends on its operand. |
661 | * |
662 | * @see deepProperties() |
663 | * @returns Expression::None, meaning no special properties |
664 | */ |
665 | virtual Properties properties() const; |
666 | |
667 | /** |
668 | * Recursively computes through all descendants until a Property |
669 | * is encount |
670 | */ |
671 | virtual Properties dependencies() const; |
672 | |
673 | /** |
674 | * @short Computes the union of properties for this Expression and all |
675 | * its descending children. |
676 | * |
677 | * @see properties() |
678 | */ |
679 | Properties deepProperties() const; |
680 | |
681 | /** |
682 | * This function is a utility function, which performs bitwise logic |
683 | * on properties() in order to find out whether the Expression::IsEvaluated |
684 | * flag is set. |
685 | * |
686 | * @note Do not attempt to re-implement this function. Instead, return the |
687 | * IsEvaluated flag by re-implementing the properties() function. |
688 | */ |
689 | inline bool isEvaluated() const; |
690 | |
691 | /** |
692 | * This function is a utility function, syntactic sugar for determining |
693 | * whether this Expression is @p id. For example, calling <tt>is(IDIfThenClause)</tt> |
694 | * is equivalent to <tt>id() == IDIfThenClause</tt> |
695 | * |
696 | * @note Do not attempt to re-implement this function. Instead, return the |
697 | * appropriate flag in the virtual id() function. |
698 | */ |
699 | inline bool is(const ID id) const; |
700 | |
701 | /** |
702 | * Determines whether this Expression has Property @p prop set. |
703 | * |
704 | * Calling <tt>expr->has(MyProperty)</tt> is semantically equivalent |
705 | * to <tt>expr->properties().testFlag(MyProperty)</tt>. In |
706 | * other words, has(), as well as is(), provides syntacti sugar |
707 | * and makes code more readable. |
708 | * |
709 | * @note Do not attempt to re-implement this function. Instead, return |
710 | * the appropriate flag by re-implementing the properties() function. |
711 | */ |
712 | inline bool has(const Property prop) const; |
713 | |
714 | inline bool hasDependency(const Property prop) const; |
715 | |
716 | virtual ExpressionVisitorResult::Ptr accept(const ExpressionVisitor::Ptr &visitor) const = 0; |
717 | |
718 | /** |
719 | * This property, which has no setter, returns an enum value that uniquely identifies |
720 | * this Expression. Patternist makes no use of C++'s dynamic_cast feature, but uses this |
721 | * polymorphic function instead. |
722 | * |
723 | * @returns always IgnorableExpression. |
724 | */ |
725 | virtual ID id() const; |
726 | |
727 | /** |
728 | * Returns the OptimizationPasses that applies for this Expression. The |
729 | * default implementation returns an empty list. Sub-classes can re-implement |
730 | * this function and return actual OptimizationPasses. |
731 | * |
732 | * @returns always an empty list. |
733 | */ |
734 | virtual QList<QExplicitlySharedDataPointer<OptimizationPass> > optimizationPasses() const; |
735 | |
736 | /** |
737 | * Returns the required type the context item must be an instance of. |
738 | * |
739 | * If this Expression requires a focus, meaning its properties() |
740 | * function returns RequiresContextItem, |
741 | * it must return a type from this function. If any type is ok, BuiltinTypes::item should be |
742 | * returned. |
743 | * |
744 | * In other words, this function must only be re-implemented if the focus is used. The default |
745 | * implementation performs an assert crash. |
746 | */ |
747 | virtual ItemType::Ptr expectedContextItemType() const; |
748 | |
749 | /** |
750 | * If an Expression creates a focus because it has set the property CreatesFocusForLast, |
751 | * it should override this function and make it return the ItemType that |
752 | * the context item in the focus has. |
753 | * |
754 | * @returns never @c null. |
755 | * @see announceFocusType() |
756 | */ |
757 | virtual ItemType::Ptr newFocusType() const; |
758 | |
759 | /** |
760 | * @short Returns @c this. |
761 | */ |
762 | virtual const SourceLocationReflection *actualReflection() const; |
763 | |
764 | /** |
765 | * Reimplementation of SourceLocationReflection::description(). |
766 | */ |
767 | virtual QString description() const; |
768 | |
769 | /** |
770 | * When this function is called, it signals that the parent will create |
771 | * a focus of type @p itemType. |
772 | * |
773 | * This type can also be retrieved through StaticContext::contextItemType() |
774 | * when inside typeCheck(), but in some cases this is too late. For |
775 | * instance, a parent needs to have the static type of its child |
776 | * properly reported before it calls its typeCheck()(and the child's |
777 | * type is inferred from the focus). |
778 | * |
779 | * The default implementation delegates the call on to the children. |
780 | * |
781 | * This function may be called at arbitrary times, in arbitrary |
782 | * amounts. |
783 | * |
784 | * If the AST node overriding this call has children, it should be |
785 | * considered whether the default implementation should be called, such |
786 | * that they type is announced to them too. |
787 | * |
788 | * The caller guarantees that @p itemType is not @c null. |
789 | */ |
790 | virtual void announceFocusType(const ItemType::Ptr &itemType); |
791 | |
792 | /** |
793 | * This function take the two Expression pointers @p old and @p New, and |
794 | * in a safe way, by handling reference counting and being aware of whether |
795 | * the two pointers actually are different, switches the two. When compiling |
796 | * in debug mode, informative debug messages are printed. |
797 | * |
798 | * This function is conceptually similar to Qt's qSwap(), but has |
799 | * debugging functionality and also handles source locations. |
800 | */ |
801 | static inline void rewrite(Expression::Ptr &old, |
802 | const Expression::Ptr &New, |
803 | const StaticContext::Ptr &context); |
804 | |
805 | /** |
806 | * @short Rewrites this Expression to @p to, and return @p to. |
807 | * |
808 | * Source location annotations are adjusted appropriately. |
809 | */ |
810 | inline const Expression::Ptr &rewrite(const Expression::Ptr &to, |
811 | const StaticContext::Ptr &context) const; |
812 | |
813 | /** |
814 | * By default 0.5 is returned. |
815 | */ |
816 | virtual PatternPriority patternPriority() const; |
817 | |
818 | protected: |
819 | |
820 | /** |
821 | * @returns @c true if all operands are constant values of somekind, and are already |
822 | * evaluated. A string literal, is a typical example. |
823 | */ |
824 | virtual bool compressOperands(const StaticContext::Ptr &) = 0; |
825 | |
826 | void typeCheckOperands(const StaticContext::Ptr &context); |
827 | |
828 | private: |
829 | static Expression::Ptr invokeOptimizers(const Expression::Ptr &expr, |
830 | const StaticContext::Ptr &context); |
831 | /** |
832 | * @return a StaticContext that has adopted the context item type properly |
833 | * for this Expression. |
834 | */ |
835 | inline StaticContext::Ptr finalizeStaticContext(const StaticContext::Ptr &context) const; |
836 | |
837 | /** |
838 | * @short Performs constant propagation, also called constant folding, on this expression. |
839 | * |
840 | * This means that it attempts to evaluate this expression at compile and returns the result value |
841 | * appropriately as an Expression. For example, for the XPath expression |
842 | * <tt>1 + 3</tt> would an Integer of value 4 would be returned. |
843 | * |
844 | * It is not checked whether constant propagation is possible, the |
845 | * caller is responsible for this. |
846 | * |
847 | * @see <a href="http://en.wikipedia.org/wiki/Constant_propagation">Constant folding, |
848 | * From Wikipedia, the free encyclopedia</a> |
849 | */ |
850 | Expression::Ptr constantPropagate(const StaticContext::Ptr &context) const; |
851 | |
852 | Q_DISABLE_COPY(Expression) |
853 | }; |
854 | |
855 | Q_DECLARE_OPERATORS_FOR_FLAGS(Expression::Properties) |
856 | |
857 | inline bool Expression::is(const Expression::ID i) const |
858 | { |
859 | return id() == i; |
860 | } |
861 | |
862 | inline bool Expression::isEvaluated() const |
863 | { |
864 | return has(prop: IsEvaluated); |
865 | } |
866 | |
867 | inline bool Expression::has(const Expression::Property prop) const |
868 | { |
869 | return properties().testFlag(flag: prop); |
870 | } |
871 | |
872 | inline bool Expression::hasDependency(const Expression::Property prop) const |
873 | { |
874 | return dependencies().testFlag(flag: prop); |
875 | } |
876 | |
877 | inline void Expression::rewrite(Expression::Ptr &old, |
878 | const Expression::Ptr &New, |
879 | const StaticContext::Ptr &context) |
880 | { |
881 | Q_ASSERT(old); |
882 | Q_ASSERT(New); |
883 | |
884 | if(old != New) |
885 | { |
886 | pDebug() << "AST REWRITE:" << old.data() << "to" << New.data() |
887 | << '(' << old->actualReflection() << "to" << New->actualReflection() << ", " |
888 | << old->description() << "to" << New->description() << ')'; |
889 | |
890 | /* The order of these two lines is significant.. */ |
891 | context->addLocation(reflection: New.data(), location: context->locationFor(reflection: old->actualReflection())); |
892 | old = New; |
893 | } |
894 | } |
895 | |
896 | inline const Expression::Ptr &Expression::rewrite(const Expression::Ptr &to, |
897 | const StaticContext::Ptr &context) const |
898 | { |
899 | context->addLocation(reflection: to.data(), location: context->locationFor(reflection: this)); |
900 | return to; |
901 | } |
902 | } |
903 | |
904 | Q_DECLARE_TYPEINFO(QPatternist::Expression::Ptr, Q_MOVABLE_TYPE); |
905 | |
906 | QT_END_NAMESPACE |
907 | |
908 | #endif |
909 | |