util/src/xmlpatterns/expr/qoptimizerframework_p.h
changeset 7 f7bc934e204c
equal deleted inserted replaced
3:41300fa6a67c 7:f7bc934e204c
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
       
     4 ** All rights reserved.
       
     5 ** Contact: Nokia Corporation (qt-info@nokia.com)
       
     6 **
       
     7 ** This file is part of the QtXmlPatterns module of the Qt Toolkit.
       
     8 **
       
     9 ** $QT_BEGIN_LICENSE:LGPL$
       
    10 ** No Commercial Usage
       
    11 ** This file contains pre-release code and may not be distributed.
       
    12 ** You may use this file in accordance with the terms and conditions
       
    13 ** contained in the Technology Preview License Agreement accompanying
       
    14 ** this package.
       
    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 ** If you have questions regarding the use of this file, please contact
       
    29 ** Nokia at qt-info@nokia.com.
       
    30 **
       
    31 **
       
    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 "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