65f6978130de2f7a0bc5d6e401d76aa17a26bc64
[profile/ivi/qtxmlpatterns.git] / src / xmlpatterns / expr / qoptimizerframework_p.h
1 /****************************************************************************
2 **
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/
5 **
6 ** This file is part of the QtXmlPatterns module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** GNU Lesser General Public License Usage
10 ** This file may be used under the terms of the GNU Lesser General Public
11 ** License version 2.1 as published by the Free Software Foundation and
12 ** appearing in the file LICENSE.LGPL included in the packaging of this
13 ** file. Please review the following information to ensure the GNU Lesser
14 ** General Public License version 2.1 requirements will be met:
15 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
16 **
17 ** In addition, as a special exception, Nokia gives you certain additional
18 ** rights. These rights are described in the Nokia Qt LGPL Exception
19 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
20 **
21 ** GNU General Public License Usage
22 ** Alternatively, this file may be used under the terms of the GNU General
23 ** Public License version 3.0 as published by the Free Software Foundation
24 ** and appearing in the file LICENSE.GPL included in the packaging of this
25 ** file. Please review the following information to ensure the GNU General
26 ** Public License version 3.0 requirements will be met:
27 ** http://www.gnu.org/copyleft/gpl.html.
28 **
29 ** Other Usage
30 ** Alternatively, this file may be used in accordance with the terms and
31 ** conditions contained in a signed written agreement between you and Nokia.
32 **
33 **
34 **
35 **
36 **
37 **
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_OptimizerFramework_H
53 #define Patternist_OptimizerFramework_H
54
55 #include <QSharedData>
56
57 #include <private/qexpression_p.h>
58
59 QT_BEGIN_HEADER
60
61 QT_BEGIN_NAMESPACE
62
63 namespace QPatternist
64 {
65     /**
66      * @short A factory for creating Expression instances.
67      *
68      * ExpressionIdentifier is one of the building block of Patternist's
69      * optimizer framework. An ExpressionIdentifier sub-class has
70      * the responsibility of creating the Expression that should be
71      * the result of the optimization.
72      *
73      * This class and sub-classes are never used on their own,
74      * but in cooperation with OptimizationPass.
75      *
76      * @author Frans englich <frans.englich@nokia.com>
77      * @ingroup Patternist_expressions
78      */
79     class ExpressionCreator : public QSharedData
80     {
81     public:
82         typedef QExplicitlySharedDataPointer<ExpressionCreator> Ptr;
83
84         /**
85          * For some reason this constructor cannot be synthesized.
86          */
87         inline ExpressionCreator()
88         {
89         }
90
91         virtual ~ExpressionCreator();
92         /**
93          * Creates an expression that has @p operands as operands.
94          *
95          * The Expression that is returned is guaranteed, by the caller,
96          * to get a treatment identical to if the expression was created
97          * in an ordinary compilation(via the parser, and so forth). That is,
98          * Expression::typeCheck() and Expression::compress() stages will be
99          * carried out on the returned expression.
100          *
101          * @returns an Expression::Ptr that never is non @c null, valid pointer
102          */
103         virtual Expression::Ptr create(const Expression::List &operands,
104                                        const StaticContext::Ptr &context,
105                                        const SourceLocationReflection *const) const = 0;
106
107     private:
108         Q_DISABLE_COPY(ExpressionCreator)
109     };
110
111     /**
112      * @short Abstract base class for all classes that identify Expressions
113      * based on some criteria.
114      *
115      * ExpressionIdentifier is one of the building block of Patternist's
116      * optimizer framework. An ExpressionIdentifier sub-class has
117      * the responsibility of determining whether a particular Expression
118      * is the one an OptimizationPass should apply for.
119      *
120      * This class and sub-classes are never used on their own,
121      * but in cooperation with OptimizationPass.
122      *
123      * @author Frans englich <frans.englich@nokia.com>
124      * @ingroup Patternist_expressions
125      */
126     class ExpressionIdentifier : public QSharedData
127     {
128     public:
129         typedef QExplicitlySharedDataPointer<ExpressionIdentifier> Ptr;
130         typedef QList<ExpressionIdentifier::Ptr> List;
131
132         /**
133          * For some reason this constructor cannot be synthesized.
134          */
135         inline ExpressionIdentifier()
136         {
137         }
138
139         virtual ~ExpressionIdentifier();
140         /**
141          * @param expr the Expression to be tested. This is guranteed
142          * to always be a non @c null, valid pointer.
143          *
144          * @returns @c true if @p expr matches as according to this ExpressionIdentifier,
145          * otherwise @c false.
146          */
147         virtual bool matches(const Expression::Ptr &expr) const = 0;
148
149     private:
150         Q_DISABLE_COPY(ExpressionIdentifier)
151     };
152
153     /**
154      * @short Describes how a particular optimization pass should be carried out.
155      *
156      * OptimizationPass is essentially a declaration, which describes
157      * how an optimization pass in the form of an AST rewrite should be done,
158      * by describing what that should be rewritten into what how.
159      *
160      * Each OptimizationPass is applied to a "start" Expression. The Expression
161      * that qualifies as a start Expression for the OptimizationPass in question is
162      * determined by startIdentifier; if its ExpressionIdentifier::matches() function
163      * returns @c true, the optimizer continues to apply this OptimizationPass.
164      *
165      * After a start Expression has been found, it is verified if the operands matches
166      * as well by applying the ExpressionIdentifiers in operandIdentifiers to the
167      * start Expression's operands. Similarly, if the operands matches what
168      * operandIdentifiers requires, the optimizer continues to apply this OptimizationPass.
169      *
170      * At this stage, it has been concluded that the OptimizationPass validly applies, and
171      * what now remains is to carry out the actual rewrite. The Expression rewritten
172      * to is the one returned by ExpressionCreator::create(), when invoked via the resultCreator
173      * variable.
174      *
175      * How these components, startIdentifier, operandIdentifiers, sourceExpression,
176      * and resultCreator interacts with one another is described in more detail
177      * in the member documentation as well as the classes they are instances of.
178      *
179      * @author Frans englich <frans.englich@nokia.com>
180      * @ingroup Patternist_expressions
181      */
182     class OptimizationPass : public QSharedData
183     {
184     public:
185         typedef QExplicitlySharedDataPointer<OptimizationPass> Ptr;
186         typedef QList<OptimizationPass::Ptr> List;
187
188         enum OperandsMatchMethod
189         {
190             /**
191              * All operands must match in the same order the ExpressionMarkers do.
192              */
193             Sequential = 1,
194
195             /**
196              * Matches if all operands are matched, regardless of their order. This is
197              * useful when an OptimizationPass is matching an Expression that has two operands
198              * and that both of them can appear on the left or right hand as long as it is those
199              * two.
200              *
201              * This comparison method only works when two operands
202              * needs to be matched.
203              */
204             AnyOrder
205         };
206
207         /**
208          * An ExpressionMarker identifies an operand Expression relatively
209          * the start Expression by that each integer identifies a step
210          * in a descending AST walk. For example an ExpressionMarker with
211          * only one entry that is 0(zero), identifies the first operand of the
212          * start Expression. An ExpressionMarker containing 1, 2 in that order
213          * identifies the third operand of the second operand of the start Expression.
214          */
215         typedef QList<qint8> ExpressionMarker;
216
217         /**
218          * Creates an OptimizationPass and sets its public variables
219          * to the corresponding values passed in this constructor.
220          */
221         OptimizationPass(const ExpressionIdentifier::Ptr &startID,
222                          const ExpressionIdentifier::List &operandIDs,
223                          const ExpressionMarker &sourceExpr,
224                          const ExpressionCreator::Ptr &resultCtor = ExpressionCreator::Ptr(),
225                          const OperandsMatchMethod matchMethod = Sequential);
226
227         /**
228          * The ExpressionIdentifier that must the Expression this OptimizationPass concerns.
229          *
230          * If this variable is @c null, it means that the start Expression does
231          * not have to match any particular ExpressionIdentifier, but is fine as is.
232          *
233          * One might wonder what the purpose of this startIdentifier is, considering
234          * that what start Expression an OptimizationPass can at all apply to is
235          * naturally determined by what Expression::optimizationPasses() re-implementation that
236          * returns this OptimizationPass. The reason is that in some cases an OptimizationPass
237          * nevertheless doesn't apply. For example, optimizations applying to a ValueComparison
238          * might depend on what operator that is in use.
239          *
240          * May be @c null or point to an ExpressionIdentifier.
241          */
242         const ExpressionIdentifier::Ptr startIdentifier;
243
244         /**
245          * In order for an OptimizationPass to apply, the start Expression's
246          * operands must be matched with this list of ExpressionIdentifier instances.
247          * The first ExpressionIdentifier is applied to the first operand, the second
248          * ExpressionIdentifier to the second operand, and so forth until all operands
249          * have been iterated.
250          *
251          * Entries in this list may be @c null, and those signals that the corresponding
252          * operand is not constrained. For example, if the third ExpressionIdentifier in
253          * the list is @c null, it signals that the third operand may be anykind of expression.
254          *
255          * May be empty or contain an arbitrary amount of objects or @c null pointers.
256          */
257         const ExpressionIdentifier::List operandIdentifiers;
258
259         /**
260          * Identifies the expression that should be part of the new expression
261          * that this OptimizationPass rewrites to. If this list is empty, it
262          * means that the result is not derived from the existing tree, and
263          * that resultCreator will exclusively be used for creating the result
264          * Expression.
265          *
266          * How the ExpressionMarker identifies an Expression is document in
267          * its documentation.
268          *
269          * May be empty.
270          */
271         const ExpressionMarker sourceExpression;
272
273         /**
274          * This is the ExpressionCreator that will be used to create the
275          * Expression which is the result. ExpressionCreator::create()
276          * will be passed as operands the Expression that sourceExpression
277          * specify, if any.
278          *
279          * If this variable is @c null, the result Expression will be the one
280          * sourceExpression identifies.
281          */
282         const ExpressionCreator::Ptr resultCreator;
283
284         const OperandsMatchMethod operandsMatchMethod;
285     private:
286         Q_DISABLE_COPY(OptimizationPass)
287     };
288 }
289
290 QT_END_NAMESPACE
291
292 QT_END_HEADER
293
294 #endif