summaryrefslogtreecommitdiff
path: root/src/xmlpatterns/expr
diff options
context:
space:
mode:
Diffstat (limited to 'src/xmlpatterns/expr')
-rw-r--r--src/xmlpatterns/expr/expr.pri173
-rw-r--r--src/xmlpatterns/expr/qandexpression.cpp97
-rw-r--r--src/xmlpatterns/expr/qandexpression_p.h98
-rw-r--r--src/xmlpatterns/expr/qapplytemplate.cpp210
-rw-r--r--src/xmlpatterns/expr/qapplytemplate_p.h144
-rw-r--r--src/xmlpatterns/expr/qargumentreference.cpp86
-rw-r--r--src/xmlpatterns/expr/qargumentreference_p.h94
-rw-r--r--src/xmlpatterns/expr/qarithmeticexpression.cpp363
-rw-r--r--src/xmlpatterns/expr/qarithmeticexpression_p.h133
-rw-r--r--src/xmlpatterns/expr/qattributeconstructor.cpp127
-rw-r--r--src/xmlpatterns/expr/qattributeconstructor_p.h108
-rw-r--r--src/xmlpatterns/expr/qattributenamevalidator.cpp109
-rw-r--r--src/xmlpatterns/expr/qattributenamevalidator_p.h99
-rw-r--r--src/xmlpatterns/expr/qaxisstep.cpp247
-rw-r--r--src/xmlpatterns/expr/qaxisstep_p.h168
-rw-r--r--src/xmlpatterns/expr/qcachecells_p.h157
-rw-r--r--src/xmlpatterns/expr/qcallsite.cpp68
-rw-r--r--src/xmlpatterns/expr/qcallsite_p.h111
-rw-r--r--src/xmlpatterns/expr/qcalltargetdescription.cpp107
-rw-r--r--src/xmlpatterns/expr/qcalltargetdescription_p.h120
-rw-r--r--src/xmlpatterns/expr/qcalltemplate.cpp153
-rw-r--r--src/xmlpatterns/expr/qcalltemplate_p.h117
-rw-r--r--src/xmlpatterns/expr/qcastableas.cpp157
-rw-r--r--src/xmlpatterns/expr/qcastableas_p.h111
-rw-r--r--src/xmlpatterns/expr/qcastas.cpp204
-rw-r--r--src/xmlpatterns/expr/qcastas_p.h148
-rw-r--r--src/xmlpatterns/expr/qcastingplatform.cpp221
-rw-r--r--src/xmlpatterns/expr/qcastingplatform_p.h206
-rw-r--r--src/xmlpatterns/expr/qcollationchecker.cpp79
-rw-r--r--src/xmlpatterns/expr/qcollationchecker_p.h99
-rw-r--r--src/xmlpatterns/expr/qcombinenodes.cpp172
-rw-r--r--src/xmlpatterns/expr/qcombinenodes_p.h116
-rw-r--r--src/xmlpatterns/expr/qcommentconstructor.cpp124
-rw-r--r--src/xmlpatterns/expr/qcommentconstructor_p.h100
-rw-r--r--src/xmlpatterns/expr/qcomparisonplatform.cpp199
-rw-r--r--src/xmlpatterns/expr/qcomparisonplatform_p.h208
-rw-r--r--src/xmlpatterns/expr/qcomputednamespaceconstructor.cpp136
-rw-r--r--src/xmlpatterns/expr/qcomputednamespaceconstructor_p.h102
-rw-r--r--src/xmlpatterns/expr/qcontextitem.cpp114
-rw-r--r--src/xmlpatterns/expr/qcontextitem_p.h128
-rw-r--r--src/xmlpatterns/expr/qcopyof.cpp134
-rw-r--r--src/xmlpatterns/expr/qcopyof_p.h121
-rw-r--r--src/xmlpatterns/expr/qcurrentitemstore.cpp139
-rw-r--r--src/xmlpatterns/expr/qcurrentitemstore_p.h104
-rw-r--r--src/xmlpatterns/expr/qdocumentconstructor.cpp116
-rw-r--r--src/xmlpatterns/expr/qdocumentconstructor_p.h103
-rw-r--r--src/xmlpatterns/expr/qdocumentcontentvalidator.cpp148
-rw-r--r--src/xmlpatterns/expr/qdocumentcontentvalidator_p.h117
-rw-r--r--src/xmlpatterns/expr/qdynamiccontextstore.cpp96
-rw-r--r--src/xmlpatterns/expr/qdynamiccontextstore_p.h97
-rw-r--r--src/xmlpatterns/expr/qelementconstructor.cpp160
-rw-r--r--src/xmlpatterns/expr/qelementconstructor_p.h107
-rw-r--r--src/xmlpatterns/expr/qemptycontainer.cpp69
-rw-r--r--src/xmlpatterns/expr/qemptycontainer_p.h101
-rw-r--r--src/xmlpatterns/expr/qemptysequence.cpp112
-rw-r--r--src/xmlpatterns/expr/qemptysequence_p.h136
-rw-r--r--src/xmlpatterns/expr/qevaluationcache.cpp274
-rw-r--r--src/xmlpatterns/expr/qevaluationcache_p.h146
-rw-r--r--src/xmlpatterns/expr/qexpression.cpp414
-rw-r--r--src/xmlpatterns/expr/qexpression_p.h909
-rw-r--r--src/xmlpatterns/expr/qexpressiondispatch_p.h241
-rw-r--r--src/xmlpatterns/expr/qexpressionfactory.cpp473
-rw-r--r--src/xmlpatterns/expr/qexpressionfactory_p.h187
-rw-r--r--src/xmlpatterns/expr/qexpressionsequence.cpp206
-rw-r--r--src/xmlpatterns/expr/qexpressionsequence_p.h127
-rw-r--r--src/xmlpatterns/expr/qexpressionvariablereference.cpp93
-rw-r--r--src/xmlpatterns/expr/qexpressionvariablereference_p.h114
-rw-r--r--src/xmlpatterns/expr/qexternalvariableloader.cpp94
-rw-r--r--src/xmlpatterns/expr/qexternalvariableloader_p.h139
-rw-r--r--src/xmlpatterns/expr/qexternalvariablereference.cpp88
-rw-r--r--src/xmlpatterns/expr/qexternalvariablereference_p.h103
-rw-r--r--src/xmlpatterns/expr/qfirstitempredicate.cpp97
-rw-r--r--src/xmlpatterns/expr/qfirstitempredicate_p.h114
-rw-r--r--src/xmlpatterns/expr/qforclause.cpp200
-rw-r--r--src/xmlpatterns/expr/qforclause_p.h122
-rw-r--r--src/xmlpatterns/expr/qgeneralcomparison.cpp297
-rw-r--r--src/xmlpatterns/expr/qgeneralcomparison_p.h136
-rw-r--r--src/xmlpatterns/expr/qgenericpredicate.cpp218
-rw-r--r--src/xmlpatterns/expr/qgenericpredicate_p.h148
-rw-r--r--src/xmlpatterns/expr/qifthenclause.cpp152
-rw-r--r--src/xmlpatterns/expr/qifthenclause_p.h101
-rw-r--r--src/xmlpatterns/expr/qinstanceof.cpp129
-rw-r--r--src/xmlpatterns/expr/qinstanceof_p.h101
-rw-r--r--src/xmlpatterns/expr/qletclause.cpp142
-rw-r--r--src/xmlpatterns/expr/qletclause_p.h109
-rw-r--r--src/xmlpatterns/expr/qliteral.cpp114
-rw-r--r--src/xmlpatterns/expr/qliteral_p.h148
-rw-r--r--src/xmlpatterns/expr/qliteralsequence.cpp92
-rw-r--r--src/xmlpatterns/expr/qliteralsequence_p.h104
-rw-r--r--src/xmlpatterns/expr/qnamespaceconstructor.cpp87
-rw-r--r--src/xmlpatterns/expr/qnamespaceconstructor_p.h109
-rw-r--r--src/xmlpatterns/expr/qncnameconstructor.cpp96
-rw-r--r--src/xmlpatterns/expr/qncnameconstructor_p.h154
-rw-r--r--src/xmlpatterns/expr/qnodecomparison.cpp184
-rw-r--r--src/xmlpatterns/expr/qnodecomparison_p.h127
-rw-r--r--src/xmlpatterns/expr/qnodesort.cpp142
-rw-r--r--src/xmlpatterns/expr/qnodesort_p.h98
-rw-r--r--src/xmlpatterns/expr/qoperandsiterator_p.h193
-rw-r--r--src/xmlpatterns/expr/qoptimizationpasses.cpp182
-rw-r--r--src/xmlpatterns/expr/qoptimizationpasses_p.h143
-rw-r--r--src/xmlpatterns/expr/qoptimizerblocks.cpp179
-rw-r--r--src/xmlpatterns/expr/qoptimizerblocks_p.h226
-rw-r--r--src/xmlpatterns/expr/qoptimizerframework.cpp71
-rw-r--r--src/xmlpatterns/expr/qoptimizerframework_p.h294
-rw-r--r--src/xmlpatterns/expr/qorderby.cpp261
-rw-r--r--src/xmlpatterns/expr/qorderby_p.h183
-rw-r--r--src/xmlpatterns/expr/qorexpression.cpp83
-rw-r--r--src/xmlpatterns/expr/qorexpression_p.h88
-rw-r--r--src/xmlpatterns/expr/qpaircontainer.cpp85
-rw-r--r--src/xmlpatterns/expr/qpaircontainer_p.h89
-rw-r--r--src/xmlpatterns/expr/qparentnodeaxis.cpp77
-rw-r--r--src/xmlpatterns/expr/qparentnodeaxis_p.h103
-rw-r--r--src/xmlpatterns/expr/qpath.cpp271
-rw-r--r--src/xmlpatterns/expr/qpath_p.h176
-rw-r--r--src/xmlpatterns/expr/qpositionalvariablereference.cpp84
-rw-r--r--src/xmlpatterns/expr/qpositionalvariablereference_p.h100
-rw-r--r--src/xmlpatterns/expr/qprocessinginstructionconstructor.cpp144
-rw-r--r--src/xmlpatterns/expr/qprocessinginstructionconstructor_p.h109
-rw-r--r--src/xmlpatterns/expr/qqnameconstructor.cpp114
-rw-r--r--src/xmlpatterns/expr/qqnameconstructor_p.h182
-rw-r--r--src/xmlpatterns/expr/qquantifiedexpression.cpp140
-rw-r--r--src/xmlpatterns/expr/qquantifiedexpression_p.h114
-rw-r--r--src/xmlpatterns/expr/qrangeexpression.cpp170
-rw-r--r--src/xmlpatterns/expr/qrangeexpression_p.h112
-rw-r--r--src/xmlpatterns/expr/qrangevariablereference.cpp92
-rw-r--r--src/xmlpatterns/expr/qrangevariablereference_p.h100
-rw-r--r--src/xmlpatterns/expr/qreturnorderby.cpp133
-rw-r--r--src/xmlpatterns/expr/qreturnorderby_p.h136
-rw-r--r--src/xmlpatterns/expr/qsimplecontentconstructor.cpp114
-rw-r--r--src/xmlpatterns/expr/qsimplecontentconstructor_p.h96
-rw-r--r--src/xmlpatterns/expr/qsinglecontainer.cpp76
-rw-r--r--src/xmlpatterns/expr/qsinglecontainer_p.h88
-rw-r--r--src/xmlpatterns/expr/qsourcelocationreflection.cpp65
-rw-r--r--src/xmlpatterns/expr/qsourcelocationreflection_p.h131
-rw-r--r--src/xmlpatterns/expr/qstaticbaseuristore.cpp82
-rw-r--r--src/xmlpatterns/expr/qstaticbaseuristore_p.h96
-rw-r--r--src/xmlpatterns/expr/qstaticcompatibilitystore.cpp79
-rw-r--r--src/xmlpatterns/expr/qstaticcompatibilitystore_p.h92
-rw-r--r--src/xmlpatterns/expr/qtemplate.cpp232
-rw-r--r--src/xmlpatterns/expr/qtemplate_p.h146
-rw-r--r--src/xmlpatterns/expr/qtemplateinvoker.cpp106
-rw-r--r--src/xmlpatterns/expr/qtemplateinvoker_p.h119
-rw-r--r--src/xmlpatterns/expr/qtemplatemode.cpp61
-rw-r--r--src/xmlpatterns/expr/qtemplatemode_p.h128
-rw-r--r--src/xmlpatterns/expr/qtemplateparameterreference.cpp91
-rw-r--r--src/xmlpatterns/expr/qtemplateparameterreference_p.h105
-rw-r--r--src/xmlpatterns/expr/qtemplatepattern_p.h161
-rw-r--r--src/xmlpatterns/expr/qtextnodeconstructor.cpp115
-rw-r--r--src/xmlpatterns/expr/qtextnodeconstructor_p.h97
-rw-r--r--src/xmlpatterns/expr/qtreatas.cpp92
-rw-r--r--src/xmlpatterns/expr/qtreatas_p.h122
-rw-r--r--src/xmlpatterns/expr/qtriplecontainer.cpp87
-rw-r--r--src/xmlpatterns/expr/qtriplecontainer_p.h92
-rw-r--r--src/xmlpatterns/expr/qtruthpredicate.cpp71
-rw-r--r--src/xmlpatterns/expr/qtruthpredicate_p.h112
-rw-r--r--src/xmlpatterns/expr/qunaryexpression.cpp79
-rw-r--r--src/xmlpatterns/expr/qunaryexpression_p.h114
-rw-r--r--src/xmlpatterns/expr/qunlimitedcontainer.cpp79
-rw-r--r--src/xmlpatterns/expr/qunlimitedcontainer_p.h149
-rw-r--r--src/xmlpatterns/expr/qunresolvedvariablereference.cpp91
-rw-r--r--src/xmlpatterns/expr/qunresolvedvariablereference_p.h111
-rw-r--r--src/xmlpatterns/expr/quserfunction.cpp62
-rw-r--r--src/xmlpatterns/expr/quserfunction_p.h135
-rw-r--r--src/xmlpatterns/expr/quserfunctioncallsite.cpp245
-rw-r--r--src/xmlpatterns/expr/quserfunctioncallsite_p.h182
-rw-r--r--src/xmlpatterns/expr/qvalidate.cpp77
-rw-r--r--src/xmlpatterns/expr/qvalidate_p.h106
-rw-r--r--src/xmlpatterns/expr/qvaluecomparison.cpp163
-rw-r--r--src/xmlpatterns/expr/qvaluecomparison_p.h138
-rw-r--r--src/xmlpatterns/expr/qvariabledeclaration.cpp63
-rw-r--r--src/xmlpatterns/expr/qvariabledeclaration_p.h203
-rw-r--r--src/xmlpatterns/expr/qvariablereference.cpp58
-rw-r--r--src/xmlpatterns/expr/qvariablereference_p.h121
-rw-r--r--src/xmlpatterns/expr/qwithparam_p.h123
-rw-r--r--src/xmlpatterns/expr/qxsltsimplecontentconstructor.cpp158
-rw-r--r--src/xmlpatterns/expr/qxsltsimplecontentconstructor_p.h89
176 files changed, 24538 insertions, 0 deletions
diff --git a/src/xmlpatterns/expr/expr.pri b/src/xmlpatterns/expr/expr.pri
new file mode 100644
index 0000000..81c3994
--- /dev/null
+++ b/src/xmlpatterns/expr/expr.pri
@@ -0,0 +1,173 @@
+HEADERS += $$PWD/qandexpression_p.h \
+ $$PWD/qapplytemplate_p.h \
+ $$PWD/qargumentreference_p.h \
+ $$PWD/qarithmeticexpression_p.h \
+ $$PWD/qattributeconstructor_p.h \
+ $$PWD/qattributenamevalidator_p.h \
+ $$PWD/qaxisstep_p.h \
+ $$PWD/qcachecells_p.h \
+ $$PWD/qcallsite_p.h \
+ $$PWD/qcalltargetdescription_p.h \
+ $$PWD/qcalltemplate_p.h \
+ $$PWD/qcastableas_p.h \
+ $$PWD/qcastas_p.h \
+ $$PWD/qcastingplatform_p.h \
+ $$PWD/qcollationchecker_p.h \
+ $$PWD/qcombinenodes_p.h \
+ $$PWD/qcommentconstructor_p.h \
+ $$PWD/qcomparisonplatform_p.h \
+ $$PWD/qcomputednamespaceconstructor_p.h \
+ $$PWD/qcontextitem_p.h \
+ $$PWD/qcopyof_p.h \
+ $$PWD/qcurrentitemstore_p.h \
+ $$PWD/qdocumentconstructor_p.h \
+ $$PWD/qdocumentcontentvalidator_p.h \
+ $$PWD/qdynamiccontextstore_p.h \
+ $$PWD/qelementconstructor_p.h \
+ $$PWD/qemptycontainer_p.h \
+ $$PWD/qemptysequence_p.h \
+ $$PWD/qevaluationcache_p.h \
+ $$PWD/qexpressiondispatch_p.h \
+ $$PWD/qexpressionfactory_p.h \
+ $$PWD/qexpression_p.h \
+ $$PWD/qexpressionsequence_p.h \
+ $$PWD/qexpressionvariablereference_p.h \
+ $$PWD/qexternalvariableloader_p.h \
+ $$PWD/qexternalvariablereference_p.h \
+ $$PWD/qfirstitempredicate_p.h \
+ $$PWD/qforclause_p.h \
+ $$PWD/qgeneralcomparison_p.h \
+ $$PWD/qgenericpredicate_p.h \
+ $$PWD/qifthenclause_p.h \
+ $$PWD/qinstanceof_p.h \
+ $$PWD/qletclause_p.h \
+ $$PWD/qliteral_p.h \
+ $$PWD/qliteralsequence_p.h \
+ $$PWD/qnamespaceconstructor_p.h \
+ $$PWD/qncnameconstructor_p.h \
+ $$PWD/qnodecomparison_p.h \
+ $$PWD/qnodesort_p.h \
+ $$PWD/qoperandsiterator_p.h \
+ $$PWD/qoptimizationpasses_p.h \
+ $$PWD/qoptimizerblocks_p.h \
+ $$PWD/qoptimizerframework_p.h \
+ $$PWD/qorderby_p.h \
+ $$PWD/qorexpression_p.h \
+ $$PWD/qpaircontainer_p.h \
+ $$PWD/qparentnodeaxis_p.h \
+ $$PWD/qpath_p.h \
+ $$PWD/qpositionalvariablereference_p.h \
+ $$PWD/qprocessinginstructionconstructor_p.h \
+ $$PWD/qqnameconstructor_p.h \
+ $$PWD/qquantifiedexpression_p.h \
+ $$PWD/qrangeexpression_p.h \
+ $$PWD/qrangevariablereference_p.h \
+ $$PWD/qreturnorderby_p.h \
+ $$PWD/qsimplecontentconstructor_p.h \
+ $$PWD/qsinglecontainer_p.h \
+ $$PWD/qsourcelocationreflection_p.h \
+ $$PWD/qstaticbaseuristore_p.h \
+ $$PWD/qstaticcompatibilitystore_p.h \
+ $$PWD/qtemplatemode_p.h \
+ $$PWD/qtemplateparameterreference_p.h \
+ $$PWD/qtemplatepattern_p.h \
+ $$PWD/qtemplatepattern_p.h \
+ $$PWD/qtemplate_p.h \
+ $$PWD/qtextnodeconstructor_p.h \
+ $$PWD/qtreatas_p.h \
+ $$PWD/qtriplecontainer_p.h \
+ $$PWD/qtruthpredicate_p.h \
+ $$PWD/qunaryexpression_p.h \
+ $$PWD/qunlimitedcontainer_p.h \
+ $$PWD/qunresolvedvariablereference_p.h \
+ $$PWD/quserfunctioncallsite_p.h \
+ $$PWD/quserfunction_p.h \
+ $$PWD/qvalidate_p.h \
+ $$PWD/qvaluecomparison_p.h \
+ $$PWD/qvariabledeclaration_p.h \
+ $$PWD/qvariablereference_p.h \
+ $$PWD/qwithparam_p.h \
+ $$PWD/qxsltsimplecontentconstructor_p.h
+
+SOURCES += $$PWD/qandexpression.cpp \
+ $$PWD/qapplytemplate.cpp \
+ $$PWD/qargumentreference.cpp \
+ $$PWD/qarithmeticexpression.cpp \
+ $$PWD/qattributeconstructor.cpp \
+ $$PWD/qattributenamevalidator.cpp \
+ $$PWD/qaxisstep.cpp \
+ $$PWD/qcallsite.cpp \
+ $$PWD/qcalltargetdescription.cpp \
+ $$PWD/qcalltemplate.cpp \
+ $$PWD/qcastableas.cpp \
+ $$PWD/qcastas.cpp \
+ $$PWD/qcollationchecker.cpp \
+ $$PWD/qcombinenodes.cpp \
+ $$PWD/qcommentconstructor.cpp \
+ $$PWD/qcomputednamespaceconstructor.cpp \
+ $$PWD/qcontextitem.cpp \
+ $$PWD/qcopyof.cpp \
+ $$PWD/qcurrentitemstore.cpp \
+ $$PWD/qdocumentconstructor.cpp \
+ $$PWD/qdocumentcontentvalidator.cpp \
+ $$PWD/qdynamiccontextstore.cpp \
+ $$PWD/qelementconstructor.cpp \
+ $$PWD/qemptycontainer.cpp \
+ $$PWD/qemptysequence.cpp \
+ $$PWD/qexpression.cpp \
+ $$PWD/qexpressionfactory.cpp \
+ $$PWD/qexpressionsequence.cpp \
+ $$PWD/qexpressionvariablereference.cpp \
+ $$PWD/qexternalvariableloader.cpp \
+ $$PWD/qexternalvariablereference.cpp \
+ $$PWD/qfirstitempredicate.cpp \
+ $$PWD/qforclause.cpp \
+ $$PWD/qgeneralcomparison.cpp \
+ $$PWD/qgenericpredicate.cpp \
+ $$PWD/qifthenclause.cpp \
+ $$PWD/qinstanceof.cpp \
+ $$PWD/qletclause.cpp \
+ $$PWD/qliteral.cpp \
+ $$PWD/qliteralsequence.cpp \
+ $$PWD/qnamespaceconstructor.cpp \
+ $$PWD/qncnameconstructor.cpp \
+ $$PWD/qnodecomparison.cpp \
+ $$PWD/qnodesort.cpp \
+ $$PWD/qoptimizationpasses.cpp \
+ $$PWD/qoptimizerblocks.cpp \
+ $$PWD/qoptimizerframework.cpp \
+ $$PWD/qorderby.cpp \
+ $$PWD/qorexpression.cpp \
+ $$PWD/qpaircontainer.cpp \
+ $$PWD/qparentnodeaxis.cpp \
+ $$PWD/qpath.cpp \
+ $$PWD/qpositionalvariablereference.cpp \
+ $$PWD/qprocessinginstructionconstructor.cpp \
+ $$PWD/qqnameconstructor.cpp \
+ $$PWD/qquantifiedexpression.cpp \
+ $$PWD/qrangeexpression.cpp \
+ $$PWD/qrangevariablereference.cpp \
+ $$PWD/qreturnorderby.cpp \
+ $$PWD/qsimplecontentconstructor.cpp \
+ $$PWD/qsinglecontainer.cpp \
+ $$PWD/qsourcelocationreflection.cpp \
+ $$PWD/qstaticbaseuristore.cpp \
+ $$PWD/qstaticcompatibilitystore.cpp \
+ $$PWD/qtemplate.cpp \
+ $$PWD/qtemplateinvoker.cpp \
+ $$PWD/qtemplatemode.cpp \
+ $$PWD/qtemplateparameterreference.cpp \
+ $$PWD/qtextnodeconstructor.cpp \
+ $$PWD/qtreatas.cpp \
+ $$PWD/qtriplecontainer.cpp \
+ $$PWD/qtruthpredicate.cpp \
+ $$PWD/qunaryexpression.cpp \
+ $$PWD/qunlimitedcontainer.cpp \
+ $$PWD/qunresolvedvariablereference.cpp \
+ $$PWD/quserfunctioncallsite.cpp \
+ $$PWD/quserfunction.cpp \
+ $$PWD/qvalidate.cpp \
+ $$PWD/qvaluecomparison.cpp \
+ $$PWD/qvariabledeclaration.cpp \
+ $$PWD/qvariablereference.cpp \
+ $$PWD/qxsltsimplecontentconstructor.cpp
diff --git a/src/xmlpatterns/expr/qandexpression.cpp b/src/xmlpatterns/expr/qandexpression.cpp
new file mode 100644
index 0000000..ae1d6f2
--- /dev/null
+++ b/src/xmlpatterns/expr/qandexpression.cpp
@@ -0,0 +1,97 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qboolean_p.h"
+#include "qcommonsequencetypes_p.h"
+#include "qcommonvalues_p.h"
+#include "qliteral_p.h"
+
+#include "qandexpression_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+AndExpression::AndExpression(const Expression::Ptr &operand1,
+ const Expression::Ptr &operand2) : PairContainer(operand1, operand2)
+{
+}
+
+bool AndExpression::evaluateEBV(const DynamicContext::Ptr &context) const
+{
+ return m_operand1->evaluateEBV(context) && m_operand2->evaluateEBV(context);
+}
+
+Expression::Ptr AndExpression::compress(const StaticContext::Ptr &context)
+{
+ const Expression::Ptr newMe(PairContainer::compress(context));
+
+ if(newMe != this)
+ return newMe;
+
+ /* Both operands mustn't be evaluated in order to be able to compress. */
+ if(m_operand1->isEvaluated() && !m_operand1->evaluateEBV(context->dynamicContext()))
+ return wrapLiteral(CommonValues::BooleanFalse, context, this);
+ else if(m_operand2->isEvaluated() && !m_operand2->evaluateEBV(context->dynamicContext()))
+ return wrapLiteral(CommonValues::BooleanFalse, context, this);
+ else
+ return Expression::Ptr(this);
+}
+
+SequenceType::List AndExpression::expectedOperandTypes() const
+{
+ SequenceType::List result;
+ result.append(CommonSequenceTypes::EBV);
+ result.append(CommonSequenceTypes::EBV);
+ return result;
+}
+
+SequenceType::Ptr AndExpression::staticType() const
+{
+ return CommonSequenceTypes::ExactlyOneBoolean;
+}
+
+ExpressionVisitorResult::Ptr AndExpression::accept(const ExpressionVisitor::Ptr &visitor) const
+{
+ return visitor->visit(this);
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/expr/qandexpression_p.h b/src/xmlpatterns/expr/qandexpression_p.h
new file mode 100644
index 0000000..b4fd87c
--- /dev/null
+++ b/src/xmlpatterns/expr/qandexpression_p.h
@@ -0,0 +1,98 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_AndExpression_H
+#define Patternist_AndExpression_H
+
+#include "qpaircontainer_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+
+ /**
+ * @short Implements XPath 2.0's logical expression @c and.
+ *
+ * The @c and expression is the same in XQuery 1.0 as in XPath 2.0.
+ *
+ * @see <a href="http://www.w3.org/TR/xpath20/#id-logical-expressions">XML Path Language
+ * (XPath) 2.0, 3.6 Logical Expressions</a>
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_expressions
+ */
+ class AndExpression : public PairContainer
+ {
+ public:
+ AndExpression(const Expression::Ptr &operand1,
+ const Expression::Ptr &operand2);
+
+ virtual bool evaluateEBV(const DynamicContext::Ptr &context) const;
+
+ virtual SequenceType::List expectedOperandTypes() const;
+
+ virtual Expression::Ptr compress(const StaticContext::Ptr &context);
+ /**
+ * @returns always CommonSequenceTypes::ExactlyOneBoolean
+ */
+ virtual SequenceType::Ptr staticType() const;
+
+ virtual ExpressionVisitorResult::Ptr accept(const ExpressionVisitor::Ptr &visitor) const;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/expr/qapplytemplate.cpp b/src/xmlpatterns/expr/qapplytemplate.cpp
new file mode 100644
index 0000000..2a9f501
--- /dev/null
+++ b/src/xmlpatterns/expr/qapplytemplate.cpp
@@ -0,0 +1,210 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtDebug>
+
+#include "qaxisstep_p.h"
+#include "qcommonsequencetypes_p.h"
+#include "qcommonvalues_p.h"
+#include "qitemmappingiterator_p.h"
+#include "qsequencemappingiterator_p.h"
+#include "qpatternistlocale_p.h"
+
+#include "qapplytemplate_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+ApplyTemplate::ApplyTemplate(const TemplateMode::Ptr &mode,
+ const WithParam::Hash &withParams,
+ const TemplateMode::Ptr &defaultMode) : TemplateInvoker(withParams)
+ , m_mode(mode)
+ , m_defaultMode(defaultMode)
+{
+ Q_ASSERT_X(m_mode || m_defaultMode, Q_FUNC_INFO,
+ "Either a mode, or the default mode must be supplied.");
+}
+
+Item ApplyTemplate::mapToItem(const QXmlNodeModelIndex &node,
+ const DynamicContext::Ptr &) const
+{
+ return Item(node);
+}
+
+Item::Iterator::Ptr ApplyTemplate::mapToSequence(const Item &item,
+ const DynamicContext::Ptr &context) const
+{
+ Q_UNUSED(item);
+ return evaluateSequence(context);
+}
+
+TemplateMode::Ptr ApplyTemplate::effectiveMode(const DynamicContext::Ptr &context) const
+{
+ if(m_mode)
+ return m_mode;
+ else
+ {
+ const TemplateMode::Ptr currentMode(context->currentTemplateMode());
+
+ if(currentMode)
+ return currentMode;
+ else
+ return m_defaultMode;
+ }
+}
+
+Template::Ptr ApplyTemplate::findTemplate(const DynamicContext::Ptr &context,
+ const TemplateMode::Ptr &templateMode) const
+{
+ const int count = templateMode->templatePatterns.count();
+ Template::Ptr result;
+ /* It's redundant to initialize these values, but it suppresses false
+ * positives with GCC. */
+ PatternPriority priority = 0;
+ TemplatePattern::ID id = -1;
+
+ /* Possible optimization: detecting ambiguous rule matches could be forked off to a
+ * low prioirity thread. */
+ for(int i = 0; i < count; ++i)
+ {
+ const TemplatePattern::Ptr &candidate = templateMode->templatePatterns.at(i);
+ if(candidate->matchPattern()->evaluateEBV(context))
+ {
+ if(result)
+ {
+ if( candidate->id() != id
+ && candidate->priority() == priority
+ && candidate->templateTarget()->importPrecedence ==
+ result->importPrecedence)
+ {
+ context->error(QtXmlPatterns::tr("Ambiguous rule match."),
+ ReportContext::XTRE0540, this);
+ }
+ else
+ break;
+ }
+ else
+ {
+ result = candidate->templateTarget();
+ priority = candidate->priority();
+ id = candidate->id();
+ }
+ }
+ }
+
+ return result;
+}
+
+Item::Iterator::Ptr ApplyTemplate::evaluateSequence(const DynamicContext::Ptr &context) const
+{
+ const TemplateMode::Ptr templateMode(effectiveMode(context));
+ const Template::Ptr &templateMatch = findTemplate(context, templateMode);
+
+ if(templateMatch)
+ return templateMatch->body->evaluateSequence(templateMatch->createContext(this, context, false));
+ else
+ {
+ /* None of our templates matched. Proceed with a built-in. */
+ const Item current(context->contextItem());
+ // TODO it can be an atomic value?
+ const QXmlNodeModelIndex::NodeKind kind(current.asNode().kind());
+
+ if(kind == QXmlNodeModelIndex::Element || kind == QXmlNodeModelIndex::Document)
+ {
+ pDebug() << "No template match, using builtin template for element() | document-node()";
+
+ const Item::Iterator::Ptr focusIterator(makeItemMappingIterator<Item>(ConstPtr(this),
+ current.asNode().iterate(QXmlNodeModelIndex::AxisChild),
+ context));
+
+ const DynamicContext::Ptr focus(context->createFocus());
+ focus->setFocusIterator(focusIterator);
+ return makeSequenceMappingIterator<Item>(ConstPtr(this), focusIterator, focus);
+ }
+ return CommonValues::emptyIterator;
+ }
+}
+
+Expression::Ptr ApplyTemplate::compress(const StaticContext::Ptr &context)
+{
+ /* If we have a mode, we will never need the default mode. */
+ if(m_mode)
+ m_defaultMode.reset();
+
+ return TemplateInvoker::compress(context);
+}
+
+SequenceType::Ptr ApplyTemplate::staticType() const
+{
+ return CommonSequenceTypes::ZeroOrMoreItems;
+}
+
+ExpressionVisitorResult::Ptr ApplyTemplate::accept(const ExpressionVisitor::Ptr &visitor) const
+{
+ return visitor->visit(this);
+}
+
+Expression::Properties ApplyTemplate::properties() const
+{
+ return RequiresFocus | DisableElimination;
+}
+
+bool ApplyTemplate::configureRecursion(const CallTargetDescription::Ptr &sign)
+{
+ Q_ASSERT_X(false, Q_FUNC_INFO, "We're not expected to be called.");
+ Q_UNUSED(sign);
+ return false;
+}
+
+Expression::Ptr ApplyTemplate::body() const
+{
+ Q_ASSERT_X(false, Q_FUNC_INFO, "We're not expected to be called.");
+ return Expression::Ptr();
+}
+
+CallTargetDescription::Ptr ApplyTemplate::callTargetDescription() const
+{
+ Q_ASSERT_X(false, Q_FUNC_INFO, "We're not expected to be called.");
+ return CallTargetDescription::Ptr();
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/expr/qapplytemplate_p.h b/src/xmlpatterns/expr/qapplytemplate_p.h
new file mode 100644
index 0000000..1398945
--- /dev/null
+++ b/src/xmlpatterns/expr/qapplytemplate_p.h
@@ -0,0 +1,144 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_ApplyTemplate_H
+#define Patternist_ApplyTemplate_H
+
+#include "qtemplatemode_p.h"
+
+QT_BEGIN_HEADER
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short When combined with other components, implements
+ * @c xsl:apply-templates.
+ *
+ * Note that ApplyTemplate isn't named ApplyTemplates. The reason for this
+ * is that ApplyTemplate doesn't do the iteration part. An @c
+ * <xsl:apply-templates/> instruction is rewritten into:
+ *
+ * @code
+ * child::node/() map apply-template()
+ * @endcode
+ *
+ * Hence, this expression requires a focus, although it can consist of
+ * atomic values.
+ *
+ * @since 4.5
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_expressions
+ */
+ class ApplyTemplate : public TemplateInvoker
+ {
+ public:
+ typedef QExplicitlySharedDataPointer<ApplyTemplate> Ptr;
+
+ /**
+ * @short @p mode may be @c null. If it is, ApplyTemplate interprets
+ * that as that it should use the #current mode.
+ *
+ * @see StaticContext::currentTemplateMode()
+ */
+ ApplyTemplate(const TemplateMode::Ptr &mode,
+ const WithParam::Hash &withParams,
+ const TemplateMode::Ptr &defaultMode);
+
+ virtual Item::Iterator::Ptr evaluateSequence(const DynamicContext::Ptr &context) const;
+
+ virtual SequenceType::Ptr staticType() const;
+ virtual ExpressionVisitorResult::Ptr accept(const ExpressionVisitor::Ptr &visitor) const;
+ virtual Properties properties() const;
+
+ /**
+ * The only reason this function exists, is in order to convert
+ * QXmlNodeModelIndex to QPatternist::Item. So, this is a huge
+ * performance setback. It applies for one of the builtin templates.
+ */
+ inline Item mapToItem(const QXmlNodeModelIndex &node,
+ const DynamicContext::Ptr &context) const;
+ inline Item::Iterator::Ptr mapToSequence(const Item &item,
+ const DynamicContext::Ptr &context) const;
+
+ inline TemplateMode::Ptr mode() const;
+
+ virtual bool configureRecursion(const CallTargetDescription::Ptr &sign);
+ virtual Expression::Ptr body() const;
+ virtual CallTargetDescription::Ptr callTargetDescription() const;
+
+ Expression::Ptr compress(const StaticContext::Ptr &context);
+
+ private:
+ typedef QExplicitlySharedDataPointer<const ApplyTemplate> ConstPtr;
+
+ Template::Ptr findTemplate(const DynamicContext::Ptr &context,
+ const TemplateMode::Ptr &templateMode) const;
+ /**
+ * @note You typically want to use effectiveMode().
+ */
+ const TemplateMode::Ptr m_mode;
+
+ TemplateMode::Ptr m_defaultMode;
+
+ inline TemplateMode::Ptr effectiveMode(const DynamicContext::Ptr &context) const;
+ };
+
+ TemplateMode::Ptr ApplyTemplate::mode() const
+ {
+ return m_mode;
+ }
+}
+
+QT_END_NAMESPACE
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/expr/qargumentreference.cpp b/src/xmlpatterns/expr/qargumentreference.cpp
new file mode 100644
index 0000000..d4c1bc6
--- /dev/null
+++ b/src/xmlpatterns/expr/qargumentreference.cpp
@@ -0,0 +1,86 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#include "qargumentreference_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+ArgumentReference::ArgumentReference(const SequenceType::Ptr &sourceType,
+ const VariableSlotID slotP) : VariableReference(slotP),
+ m_type(sourceType)
+{
+ Q_ASSERT(m_type);
+}
+
+bool ArgumentReference::evaluateEBV(const DynamicContext::Ptr &context) const
+{
+ return context->expressionVariable(slot())->evaluateEBV(context);
+}
+
+Item ArgumentReference::evaluateSingleton(const DynamicContext::Ptr &context) const
+{
+ return context->expressionVariable(slot())->evaluateSingleton(context);
+}
+
+Item::Iterator::Ptr ArgumentReference::evaluateSequence(const DynamicContext::Ptr &context) const
+{
+ return context->expressionVariable(slot())->evaluateSequence(context);
+}
+
+SequenceType::Ptr ArgumentReference::staticType() const
+{
+ return m_type;
+}
+
+ExpressionVisitorResult::Ptr ArgumentReference::accept(const ExpressionVisitor::Ptr &visitor) const
+{
+ return visitor->visit(this);
+}
+
+Expression::ID ArgumentReference::id() const
+{
+ return IDArgumentReference;
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/expr/qargumentreference_p.h b/src/xmlpatterns/expr/qargumentreference_p.h
new file mode 100644
index 0000000..0fc51d3
--- /dev/null
+++ b/src/xmlpatterns/expr/qargumentreference_p.h
@@ -0,0 +1,94 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_ArgumentReference_H
+#define Patternist_ArgumentReference_H
+
+#include "qvariablereference_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short A reference to an argument declared in a UserFunction.
+ *
+ * This is in other words a variable reference in side a function
+ * body, that references a function argument.
+ *
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_expressions
+ */
+ class ArgumentReference : public VariableReference
+ {
+ public:
+ ArgumentReference(const SequenceType::Ptr &sourceType,
+ const VariableSlotID slot);
+
+ virtual bool evaluateEBV(const DynamicContext::Ptr &context) const;
+ virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const;
+ virtual Item::Iterator::Ptr evaluateSequence(const DynamicContext::Ptr &context) const;
+ virtual SequenceType::Ptr staticType() const;
+ virtual ExpressionVisitorResult::Ptr accept(const ExpressionVisitor::Ptr &visitor) const;
+ virtual ID id() const;
+
+ private:
+ const SequenceType::Ptr m_type;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/expr/qarithmeticexpression.cpp b/src/xmlpatterns/expr/qarithmeticexpression.cpp
new file mode 100644
index 0000000..e424dc0
--- /dev/null
+++ b/src/xmlpatterns/expr/qarithmeticexpression.cpp
@@ -0,0 +1,363 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qboolean_p.h"
+#include "qbuiltintypes_p.h"
+#include "qcommonsequencetypes_p.h"
+#include "qemptysequence_p.h"
+#include "qgenericsequencetype_p.h"
+#include "qliteral_p.h"
+#include "qpatternistlocale_p.h"
+#include "qschemanumeric_p.h"
+#include "quntypedatomicconverter_p.h"
+
+#include "qarithmeticexpression_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+ArithmeticExpression::ArithmeticExpression(const Expression::Ptr &op1,
+ const AtomicMathematician::Operator op,
+ const Expression::Ptr &op2) : PairContainer(op1, op2)
+ , m_op(op)
+ , m_isCompat(false)
+{
+}
+
+Item ArithmeticExpression::evaluateSingleton(const DynamicContext::Ptr &context) const
+{
+ const Item op1(m_operand1->evaluateSingleton(context));
+ if(!op1)
+ return Item();
+
+ const Item op2(m_operand2->evaluateSingleton(context));
+ if(!op2)
+ return Item();
+
+ return flexiblyCalculate(op1, m_op, op2, m_mather, context, this,
+ ReportContext::XPTY0004, m_isCompat);
+}
+
+/**
+ * Since ArithmeticExpression::flexiblyCalculate() creates Expression instances
+ * at runtime, we have the problem of having SourceLocationReflections for them
+ * in the case that we run into a runtime error, since the locations are always
+ * located at compile time.
+ *
+ * This class simply delegates the reflection over to an existing expression.
+ *
+ * I only managed to trigger this with "current() + 1", where current()
+ * evaluates to an invalid representation for @c xs:double.
+ *
+ * @since 4.5
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+class DelegatingReflectionExpression : public Literal
+{
+public:
+ DelegatingReflectionExpression(const Item &item,
+ const SourceLocationReflection *const reflection) : Literal(item)
+ , m_reflection(reflection)
+ {
+ }
+
+ virtual const SourceLocationReflection *actualReflection() const
+ {
+ return m_reflection;
+ }
+
+private:
+ const SourceLocationReflection *const m_reflection;
+};
+
+Item ArithmeticExpression::flexiblyCalculate(const Item &op1,
+ const AtomicMathematician::Operator op,
+ const Item &op2,
+ const AtomicMathematician::Ptr &mather,
+ const DynamicContext::Ptr &context,
+ const SourceLocationReflection *const reflection,
+ const ReportContext::ErrorCode code,
+ const bool isCompat)
+{
+ if(mather)
+ return mather->calculate(op1, op, op2, context);
+
+ /* This is a very heavy code path. */
+ Expression::Ptr a1(new DelegatingReflectionExpression(op1, reflection));
+ Expression::Ptr a2(new DelegatingReflectionExpression(op2, reflection));
+
+ const AtomicMathematician::Ptr ingela(fetchMathematician(a1, a2, op, true, context, reflection, code, isCompat));
+
+ return ingela->calculate(a1->evaluateSingleton(context),
+ op,
+ a2->evaluateSingleton(context),
+ context);
+}
+
+Expression::Ptr ArithmeticExpression::typeCheck(const StaticContext::Ptr &context,
+ const SequenceType::Ptr &reqType)
+{
+ m_isCompat = context->compatModeEnabled();
+
+ const Expression::Ptr me(PairContainer::typeCheck(context, reqType));
+ const ItemType::Ptr t1(m_operand1->staticType()->itemType());
+ const ItemType::Ptr t2(m_operand2->staticType()->itemType());
+
+ if(*CommonSequenceTypes::Empty == *t1 ||
+ *CommonSequenceTypes::Empty == *t2)
+ {
+ return EmptySequence::create(this, context);
+ }
+
+ if(*BuiltinTypes::xsAnyAtomicType == *t1 ||
+ *BuiltinTypes::xsAnyAtomicType == *t2 ||
+ *BuiltinTypes::numeric == *t1 ||
+ *BuiltinTypes::numeric == *t2)
+ {
+ /* The static type of (at least) one of the operands could not
+ * be narrowed further than xs:anyAtomicType, so we do the operator
+ * lookup at runtime. */
+ return me;
+ }
+
+ m_mather = fetchMathematician(m_operand1, m_operand2, m_op, true, context, this,
+ ReportContext::XPTY0004, m_isCompat);
+
+ return me;
+}
+
+AtomicMathematician::Ptr
+ArithmeticExpression::fetchMathematician(Expression::Ptr &op1,
+ Expression::Ptr &op2,
+ const AtomicMathematician::Operator op,
+ const bool issueError,
+ const ReportContext::Ptr &context,
+ const SourceLocationReflection *const reflection,
+ const ReportContext::ErrorCode code,
+ const bool isCompat)
+{
+ ItemType::Ptr t1(op1->staticType()->itemType());
+ ItemType::Ptr t2(op2->staticType()->itemType());
+
+ if(BuiltinTypes::xsUntypedAtomic->xdtTypeMatches(t1)
+ || (isCompat && (BuiltinTypes::xsString->xdtTypeMatches(t1)
+ || BuiltinTypes::xsDecimal->xdtTypeMatches(t1))))
+ {
+ op1 = Expression::Ptr(new UntypedAtomicConverter(op1, BuiltinTypes::xsDouble));
+ /* The types might have changed, reload. */
+ t1 = op1->staticType()->itemType();
+ }
+
+ if(BuiltinTypes::xsUntypedAtomic->xdtTypeMatches(t2)
+ || (isCompat && (BuiltinTypes::xsString->xdtTypeMatches(t1)
+ || BuiltinTypes::xsDecimal->xdtTypeMatches(t1))))
+ {
+ op2 = Expression::Ptr(new UntypedAtomicConverter(op2, BuiltinTypes::xsDouble));
+ /* The types might have changed, reload. */
+ t2 = op2->staticType()->itemType();
+ }
+
+ const AtomicMathematicianLocator::Ptr locator
+ (static_cast<const AtomicType *>(t1.data())->mathematicianLocator());
+
+ if(!locator)
+ {
+ if(!issueError)
+ return AtomicMathematician::Ptr();
+
+ context->error(QtXmlPatterns::tr(
+ "Operator %1 cannot be used on type %2.")
+ .arg(formatKeyword(AtomicMathematician::displayName(op)))
+ .arg(formatType(context->namePool(), t1)),
+ code, reflection);
+ return AtomicMathematician::Ptr();
+ }
+
+ const AtomicMathematician::Ptr comp
+ (static_cast<const AtomicType *>(t2.data())->accept(locator, op, reflection));
+
+ if(comp)
+ return comp;
+
+ if(!issueError)
+ return AtomicMathematician::Ptr();
+
+ context->error(QtXmlPatterns::tr("Operator %1 cannot be used on "
+ "atomic values of type %2 and %3.")
+ .arg(formatKeyword(AtomicMathematician::displayName(op)))
+ .arg(formatType(context->namePool(), t1))
+ .arg(formatType(context->namePool(), t2)),
+ code, reflection);
+ return AtomicMathematician::Ptr();
+}
+
+SequenceType::Ptr ArithmeticExpression::staticType() const
+{
+ Cardinality card;
+
+ /* These variables are important because they ensure staticType() only
+ * gets called once from this function. Before, this lead to strange
+ * semi-infinite recursion involving many arithmetic expressions. */
+ const SequenceType::Ptr st1(m_operand1->staticType());
+ const SequenceType::Ptr st2(m_operand2->staticType());
+
+ if(st1->cardinality().allowsEmpty() ||
+ st2->cardinality().allowsEmpty())
+ {
+ card = Cardinality::zeroOrOne();
+ }
+ else
+ card = Cardinality::exactlyOne();
+
+ if(m_op == AtomicMathematician::IDiv)
+ return makeGenericSequenceType(BuiltinTypes::xsInteger, card);
+
+ const ItemType::Ptr t1(st1->itemType());
+ const ItemType::Ptr t2(st2->itemType());
+ ItemType::Ptr returnType;
+
+ /* Please, make this beautiful? */
+ if(BuiltinTypes::xsTime->xdtTypeMatches(t1) ||
+ BuiltinTypes::xsDate->xdtTypeMatches(t1) ||
+ BuiltinTypes::xsDateTime->xdtTypeMatches(t1))
+ {
+ if(BuiltinTypes::xsDuration->xdtTypeMatches(t2))
+ returnType = t1;
+ else
+ returnType = BuiltinTypes::xsDayTimeDuration;
+ }
+ else if(BuiltinTypes::xsYearMonthDuration->xdtTypeMatches(t1))
+ {
+ if(m_op == AtomicMathematician::Div &&
+ BuiltinTypes::xsYearMonthDuration->xdtTypeMatches(t2))
+ {
+ returnType = BuiltinTypes::xsDecimal;
+ }
+ else if(BuiltinTypes::numeric->xdtTypeMatches(t2))
+ returnType = BuiltinTypes::xsYearMonthDuration;
+ else
+ returnType = t2;
+ }
+ else if(BuiltinTypes::xsYearMonthDuration->xdtTypeMatches(t2))
+ {
+ returnType = BuiltinTypes::xsYearMonthDuration;
+ }
+ else if(BuiltinTypes::xsDayTimeDuration->xdtTypeMatches(t1))
+ {
+ if(m_op == AtomicMathematician::Div &&
+ BuiltinTypes::xsDayTimeDuration->xdtTypeMatches(t2))
+ {
+ returnType = BuiltinTypes::xsDecimal;
+ }
+ else if(BuiltinTypes::numeric->xdtTypeMatches(t2))
+ returnType = BuiltinTypes::xsDayTimeDuration;
+ else
+ returnType = t2;
+ }
+ else if(BuiltinTypes::xsDayTimeDuration->xdtTypeMatches(t2))
+ {
+ returnType = BuiltinTypes::xsDayTimeDuration;
+ }
+ else if(BuiltinTypes::xsDouble->xdtTypeMatches(t1) ||
+ BuiltinTypes::xsDouble->xdtTypeMatches(t2))
+ {
+ returnType = BuiltinTypes::xsDouble;
+ }
+ else if(BuiltinTypes::xsFloat->xdtTypeMatches(t1) ||
+ BuiltinTypes::xsFloat->xdtTypeMatches(t2))
+ {
+ if(m_isCompat)
+ returnType = BuiltinTypes::xsFloat;
+ else
+ returnType = BuiltinTypes::xsDouble;
+ }
+ else if(BuiltinTypes::xsInteger->xdtTypeMatches(t1) &&
+ BuiltinTypes::xsInteger->xdtTypeMatches(t2))
+ {
+ if(m_isCompat)
+ returnType = BuiltinTypes::xsDouble;
+ else
+ {
+ /* "A div B numeric numeric op:numeric-divide(A, B)
+ * numeric; but xs:decimal if both operands are xs:integer" */
+ if(m_op == AtomicMathematician::Div)
+ returnType = BuiltinTypes::xsDecimal;
+ else
+ returnType = BuiltinTypes::xsInteger;
+ }
+ }
+ else if(m_isCompat && (BuiltinTypes::xsInteger->xdtTypeMatches(t1) &&
+ BuiltinTypes::xsInteger->xdtTypeMatches(t2)))
+ {
+ returnType = BuiltinTypes::xsDouble;
+ }
+ else
+ {
+ /* If typeCheck() has been called, our operands conform to expectedOperandTypes(), and
+ * the types are hence either xs:decimals, or xs:anyAtomicType(meaning the static type could
+ * not be inferred), or empty-sequence(). So we use the union of the two types. The combinations
+ * could also be wrong.*/
+ returnType = t1 | t2;
+
+ /* However, if we're called before typeCheck(), we could potentially have nodes, so we need to make
+ * sure that the type is at least atomic. */
+ if(!BuiltinTypes::xsAnyAtomicType->xdtTypeMatches(returnType))
+ returnType = BuiltinTypes::xsAnyAtomicType;
+ }
+
+ return makeGenericSequenceType(returnType, card);
+}
+
+SequenceType::List ArithmeticExpression::expectedOperandTypes() const
+{
+ SequenceType::List result;
+ result.append(CommonSequenceTypes::ZeroOrOneAtomicType);
+ result.append(CommonSequenceTypes::ZeroOrOneAtomicType);
+ return result;
+}
+
+ExpressionVisitorResult::Ptr ArithmeticExpression::accept(const ExpressionVisitor::Ptr &visitor) const
+{
+ return visitor->visit(this);
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/expr/qarithmeticexpression_p.h b/src/xmlpatterns/expr/qarithmeticexpression_p.h
new file mode 100644
index 0000000..a1621f7
--- /dev/null
+++ b/src/xmlpatterns/expr/qarithmeticexpression_p.h
@@ -0,0 +1,133 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_ArithmeticExpression_H
+#define Patternist_ArithmeticExpression_H
+
+#include "qatomicmathematician_p.h"
+#include "qpaircontainer_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Implements arithmetics, such as multiplication and subtraction.
+ *
+ *
+ * Optimizations: there's some operator/value combos that are no ops. For
+ * instance, 0 + <value>, which is the case of unary plus. We can't compile
+ * those away early due to that type checks needs to be done but one can
+ * check for them in compress().
+ *
+ * @see <a href="http://www.w3.org/TR/xpath20/#id-arithmetic">XML Path Language
+ * (XPath) 2.0, 3.4 Arithmetic Expressions</a>
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_expressions
+ */
+ class Q_AUTOTEST_EXPORT ArithmeticExpression : public PairContainer
+ {
+ public:
+ ArithmeticExpression(const Expression::Ptr &operand1,
+ const AtomicMathematician::Operator op,
+ const Expression::Ptr &operand2);
+
+ virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const;
+
+ virtual SequenceType::Ptr staticType() const;
+ virtual SequenceType::List expectedOperandTypes() const;
+ AtomicMathematician::Operator operatorID() const;
+
+ virtual Expression::Ptr typeCheck(const StaticContext::Ptr &context,
+ const SequenceType::Ptr &reqType);
+
+ static Item flexiblyCalculate(const Item &op1,
+ const AtomicMathematician::Operator op,
+ const Item &op2,
+ const AtomicMathematician::Ptr &mather,
+ const DynamicContext::Ptr &context,
+ const SourceLocationReflection *const reflection,
+ const ReportContext::ErrorCode code = ReportContext::XPTY0004,
+ const bool isCompat = false);
+
+ static AtomicMathematician::Ptr
+ fetchMathematician(Expression::Ptr &t1,
+ Expression::Ptr &t2,
+ const AtomicMathematician::Operator op,
+ const bool issueError,
+ const ReportContext::Ptr &context,
+ const SourceLocationReflection *const reflection,
+ const ReportContext::ErrorCode code = ReportContext::XPTY0004,
+ const bool isCompat = false);
+ virtual ExpressionVisitorResult::Ptr accept(const ExpressionVisitor::Ptr &visitor) const;
+
+ protected:
+
+ private:
+ const AtomicMathematician::Operator m_op;
+ AtomicMathematician::Ptr m_mather;
+ bool m_isCompat;
+ };
+
+ inline AtomicMathematician::Operator ArithmeticExpression::operatorID() const
+ {
+ return m_op;
+ }
+
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/expr/qattributeconstructor.cpp b/src/xmlpatterns/expr/qattributeconstructor.cpp
new file mode 100644
index 0000000..fa41afd
--- /dev/null
+++ b/src/xmlpatterns/expr/qattributeconstructor.cpp
@@ -0,0 +1,127 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QUrl>
+
+#include "qcommonsequencetypes_p.h"
+#include "qnodebuilder_p.h"
+#include "qqnamevalue_p.h"
+
+#include "qattributeconstructor_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+AttributeConstructor::AttributeConstructor(const Expression::Ptr &op1,
+ const Expression::Ptr &op2) : PairContainer(op1, op2)
+{
+}
+
+QString AttributeConstructor::processValue(const QXmlName name,
+ const Item &value)
+{
+ if(!value)
+ return QString();
+ else if(name == QXmlName(StandardNamespaces::xml, StandardLocalNames::id))
+ return value.stringValue().simplified();
+ else
+ return value.stringValue();
+}
+
+Item AttributeConstructor::evaluateSingleton(const DynamicContext::Ptr &context) const
+{
+ const Item nameItem(m_operand1->evaluateSingleton(context));
+ const Item content(m_operand2->evaluateSingleton(context));
+
+ const QXmlName name(nameItem.as<QNameValue>()->qName());
+ const QString value(processValue(name, content));
+ const NodeBuilder::Ptr nodeBuilder(context->nodeBuilder(QUrl()));
+
+ nodeBuilder->attribute(name, QStringRef(&value));
+
+ const QAbstractXmlNodeModel::Ptr nm(nodeBuilder->builtDocument());
+ context->addNodeModel(nm);
+ return nm->root(QXmlNodeModelIndex());
+}
+
+void AttributeConstructor::evaluateToSequenceReceiver(const DynamicContext::Ptr &context) const
+{
+ QAbstractXmlReceiver *const receiver = context->outputReceiver();
+ const Item nameItem(m_operand1->evaluateSingleton(context));
+
+ const Item content(m_operand2->evaluateSingleton(context));
+ const QXmlName name(nameItem.as<QNameValue>()->qName());
+ const QString value(processValue(name, content));
+
+ receiver->attribute(name, QStringRef(&value));
+}
+
+SequenceType::Ptr AttributeConstructor::staticType() const
+{
+ return CommonSequenceTypes::ExactlyOneAttribute;
+}
+
+SequenceType::List AttributeConstructor::expectedOperandTypes() const
+{
+ SequenceType::List result;
+ result.append(CommonSequenceTypes::ExactlyOneQName);
+ result.append(CommonSequenceTypes::ZeroOrMoreItems);
+ return result;
+}
+
+Expression::Properties AttributeConstructor::properties() const
+{
+ return DisableElimination | IsNodeConstructor;
+}
+
+ExpressionVisitorResult::Ptr
+AttributeConstructor::accept(const ExpressionVisitor::Ptr &visitor) const
+{
+ return visitor->visit(this);
+}
+
+Expression::ID AttributeConstructor::id() const
+{
+ return IDAttributeConstructor;
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/expr/qattributeconstructor_p.h b/src/xmlpatterns/expr/qattributeconstructor_p.h
new file mode 100644
index 0000000..055ad7f
--- /dev/null
+++ b/src/xmlpatterns/expr/qattributeconstructor_p.h
@@ -0,0 +1,108 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_AttributeConstructor_H
+#define Patternist_AttributeConstructor_H
+
+#include "qpaircontainer_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Constructs an element node. This covers both computed and directly constructed
+ * element nodes.
+ *
+ * @see <a href="http://www.w3.org/TR/xquery/#id-constructors">XQuery
+ * 1.0: An XML Query Language, 3.7 Constructors</a>
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_expressions
+ */
+ class AttributeConstructor : public PairContainer
+ {
+ public:
+ AttributeConstructor(const Expression::Ptr &operand1,
+ const Expression::Ptr &operand2);
+
+ virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const;
+ virtual void evaluateToSequenceReceiver(const DynamicContext::Ptr &context) const;
+
+ virtual SequenceType::Ptr staticType() const;
+
+ /**
+ * The first operand must be exactly one @c xs:QName, and the second
+ * argument can be zero or more items.
+ */
+ virtual SequenceType::List expectedOperandTypes() const;
+
+ virtual ExpressionVisitorResult::Ptr accept(const ExpressionVisitor::Ptr &visitor) const;
+
+ /**
+ * @returns always IDAttributeConstructor.
+ */
+ virtual ID id() const;
+
+ virtual Properties properties() const;
+
+ private:
+ static inline QString processValue(const QXmlName name,
+ const Item &value);
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/expr/qattributenamevalidator.cpp b/src/xmlpatterns/expr/qattributenamevalidator.cpp
new file mode 100644
index 0000000..1625bc1
--- /dev/null
+++ b/src/xmlpatterns/expr/qattributenamevalidator.cpp
@@ -0,0 +1,109 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qbuiltintypes_p.h"
+#include "qcommonnamespaces_p.h"
+#include "qcommonsequencetypes_p.h"
+#include "qpatternistlocale_p.h"
+#include "qqnamevalue_p.h"
+#include "qatomicstring_p.h"
+
+#include "qattributenamevalidator_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+AttributeNameValidator::AttributeNameValidator(const Expression::Ptr &source) : SingleContainer(source)
+{
+}
+
+Item AttributeNameValidator::evaluateSingleton(const DynamicContext::Ptr &context) const
+{
+ const Item name(m_operand->evaluateSingleton(context));
+ const QXmlName qName(name.as<QNameValue>()->qName());
+
+ if(qName.namespaceURI() == StandardNamespaces::xmlns)
+ {
+ context->error(QtXmlPatterns::tr("The namespace URI in the name for a "
+ "computed attribute cannot be %1.")
+ .arg(formatURI(CommonNamespaces::XMLNS)),
+ ReportContext::XQDY0044, this);
+ return Item(); /* Silence warning. */
+ }
+ else if(qName.namespaceURI() == StandardNamespaces::empty &&
+ qName.localName() == StandardLocalNames::xmlns)
+ {
+ context->error(QtXmlPatterns::tr("The name for a computed attribute "
+ "cannot have the namespace URI %1 "
+ "with the local name %2.")
+ .arg(formatURI(CommonNamespaces::XMLNS))
+ .arg(formatKeyword("xmlns")),
+ ReportContext::XQDY0044, this);
+ return Item(); /* Silence warning. */
+ }
+ else if(!qName.hasPrefix() && qName.hasNamespace())
+ {
+ return Item(QNameValue::fromValue(context->namePool(),
+ QXmlName(qName.namespaceURI(), qName.localName(), StandardPrefixes::ns0)));
+ }
+ else
+ return name;
+}
+
+SequenceType::Ptr AttributeNameValidator::staticType() const
+{
+ return m_operand->staticType();
+}
+
+SequenceType::List AttributeNameValidator::expectedOperandTypes() const
+{
+ SequenceType::List result;
+ result.append(CommonSequenceTypes::ExactlyOneQName);
+ return result;
+}
+
+ExpressionVisitorResult::Ptr AttributeNameValidator::accept(const ExpressionVisitor::Ptr &visitor) const
+{
+ return visitor->visit(this);
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/expr/qattributenamevalidator_p.h b/src/xmlpatterns/expr/qattributenamevalidator_p.h
new file mode 100644
index 0000000..ddf05ec
--- /dev/null
+++ b/src/xmlpatterns/expr/qattributenamevalidator_p.h
@@ -0,0 +1,99 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_AttributeNameValidator_H
+#define Patternist_AttributeNameValidator_H
+
+#include "qsinglecontainer_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Ensures the lexical space of the string value of the Item returned
+ * from its child Expression is an NCName. Also possibly changes the name
+ * by generating a prefix if one is needed.
+ *
+ * @note It doesn't actually construct an @c xs:NCName. It only ensures the lexical
+ * space is an @c NCName. The atomic value can be of any string type, such as @c xs:untypedAtomic
+ * of @c xs:string.
+ *
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_expressions
+ */
+ class AttributeNameValidator : public SingleContainer
+ {
+ public:
+ AttributeNameValidator(const Expression::Ptr &source);
+
+ virtual Item evaluateSingleton(const DynamicContext::Ptr &) const;
+
+ virtual SequenceType::List expectedOperandTypes() const;
+
+ /**
+ * @returns the static type of its operand. This is returned as opposed
+ * CommonSequenceTypes::ExactlyOneQName, since the operand might return a subtype
+ * of @c xs:QName.
+ */
+ virtual SequenceType::Ptr staticType() const;
+
+ virtual ExpressionVisitorResult::Ptr accept(const ExpressionVisitor::Ptr &visitor) const;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/expr/qaxisstep.cpp b/src/xmlpatterns/expr/qaxisstep.cpp
new file mode 100644
index 0000000..40fe694
--- /dev/null
+++ b/src/xmlpatterns/expr/qaxisstep.cpp
@@ -0,0 +1,247 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qbuiltintypes_p.h"
+#include "qcommonsequencetypes_p.h"
+#include "qitemmappingiterator_p.h"
+#include "qgenericsequencetype_p.h"
+#include "qparentnodeaxis_p.h"
+
+#include "qaxisstep_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+namespace QPatternist
+{
+ /**
+ * This operator is needed for the s_whenAxisNodeKindEmpty array. The @c int constructors
+ * ensure we invoke another operator| such that we don't get an infinite loop.
+ */
+ static inline QXmlNodeModelIndex::NodeKind operator|(const QXmlNodeModelIndex::NodeKind &op1, const QXmlNodeModelIndex::NodeKind &op2)
+ {
+ return QXmlNodeModelIndex::NodeKind(int(op1) | int(op2));
+ }
+}
+
+/**
+ * @note The order is significant. It is of the same order as the values in QXmlNodeModelIndex::Axis is declared.
+ */
+const QXmlNodeModelIndex::NodeKind AxisStep::s_whenAxisNodeKindEmpty[] =
+{
+ QXmlNodeModelIndex::Attribute|QXmlNodeModelIndex::Text|QXmlNodeModelIndex::ProcessingInstruction|QXmlNodeModelIndex::Comment|QXmlNodeModelIndex::Namespace, // child;
+ QXmlNodeModelIndex::Attribute|QXmlNodeModelIndex::Text|QXmlNodeModelIndex::ProcessingInstruction|QXmlNodeModelIndex::Comment|QXmlNodeModelIndex::Namespace, // descendant;
+ QXmlNodeModelIndex::Document|QXmlNodeModelIndex::Attribute|QXmlNodeModelIndex::Text|QXmlNodeModelIndex::ProcessingInstruction|QXmlNodeModelIndex::Comment|QXmlNodeModelIndex::Namespace,// attribute;
+ QXmlNodeModelIndex::NodeKind(0), // self;
+ QXmlNodeModelIndex::NodeKind(0), // descendant-or-self;
+ QXmlNodeModelIndex::Document|QXmlNodeModelIndex::Attribute|QXmlNodeModelIndex::Text|QXmlNodeModelIndex::ProcessingInstruction|QXmlNodeModelIndex::Comment|QXmlNodeModelIndex::Namespace, // namespace;
+ QXmlNodeModelIndex::Document, // following;
+ QXmlNodeModelIndex::Document, // parent;
+ QXmlNodeModelIndex::Document, // ancestor
+ QXmlNodeModelIndex::Document|QXmlNodeModelIndex::Attribute|QXmlNodeModelIndex::Namespace, // preceding-sibling;
+ QXmlNodeModelIndex::Document|QXmlNodeModelIndex::Attribute|QXmlNodeModelIndex::Namespace, // following-sibling;
+ QXmlNodeModelIndex::Document, // preceding;
+ QXmlNodeModelIndex::NodeKind(0) // ancestor-or-self;
+};
+
+bool AxisStep::isAlwaysEmpty(const QXmlNodeModelIndex::Axis axis, const QXmlNodeModelIndex::NodeKind nodeKind)
+{
+ return (s_whenAxisNodeKindEmpty[(1 >> axis) - 1] & nodeKind) != 0;
+}
+
+AxisStep::AxisStep(const QXmlNodeModelIndex::Axis a,
+ const ItemType::Ptr &nt) : m_axis(a),
+ m_nodeTest(nt)
+{
+ Q_ASSERT(m_nodeTest);
+ Q_ASSERT_X(BuiltinTypes::node->xdtTypeMatches(m_nodeTest), Q_FUNC_INFO,
+ "We assume we're a node type.");
+}
+
+Item AxisStep::mapToItem(const QXmlNodeModelIndex &node,
+ const DynamicContext::Ptr &context) const
+{
+ Q_ASSERT(!node.isNull());
+ Q_ASSERT(Item(node).isNode());
+ Q_ASSERT(Item(node));
+ Q_UNUSED(context);
+
+ if(m_nodeTest->itemMatches(Item(node)))
+ return Item(node);
+ else
+ return Item();
+}
+
+Item::Iterator::Ptr AxisStep::evaluateSequence(const DynamicContext::Ptr &context) const
+{
+ /* If we don't have a focus, it's either a bug or our parent isn't a Path
+ * that have advanced the focus iterator. Hence, attempt to advance the focus on our own. */
+ if(!context->contextItem())
+ context->focusIterator()->next();
+
+ Q_ASSERT(context->contextItem());
+
+ const QXmlNodeModelIndex::Iterator::Ptr source(context->contextItem().asNode().iterate(m_axis));
+
+ return makeItemMappingIterator<Item>(ConstPtr(this), source, context);
+}
+
+Item AxisStep::evaluateSingleton(const DynamicContext::Ptr &context) const
+{
+ /* If we don't have a focus, it's either a bug or our parent isn't a Path
+ * that have advanced the focus iterator. Hence, attempt to advance the focus on our own. */
+ if(!context->contextItem())
+ context->focusIterator()->next();
+
+ Q_ASSERT(context->contextItem());
+
+ const QXmlNodeModelIndex::Iterator::Ptr it(context->contextItem().asNode().iterate(m_axis));
+ QXmlNodeModelIndex next(it->next());
+
+ while(!next.isNull())
+ {
+ const Item candidate(mapToItem(next, context));
+
+ if(candidate)
+ return candidate;
+ else
+ next = it->next();
+ };
+
+ return Item();
+}
+
+Expression::Ptr AxisStep::typeCheck(const StaticContext::Ptr &context,
+ const SequenceType::Ptr &reqType)
+{
+ if(m_axis == QXmlNodeModelIndex::AxisParent && *m_nodeTest == *BuiltinTypes::node)
+ {
+ /* We only rewrite parent::node() to ParentNodeAxis. */
+ return rewrite(Expression::Ptr(new ParentNodeAxis()), context)->typeCheck(context, reqType);
+ }
+ /* TODO temporarily disabled
+ else if(isAlwaysEmpty(m_axis, static_cast<const AnyNodeType *>(m_nodeTest.data())->nodeKind()))
+ return EmptySequence::create(this, context);
+ */
+ else
+ return EmptyContainer::typeCheck(context, reqType);
+}
+
+SequenceType::Ptr AxisStep::staticType() const
+{
+ Cardinality cardinality;
+
+ if(m_axis == QXmlNodeModelIndex::AxisSelf || m_axis == QXmlNodeModelIndex::AxisParent)
+ cardinality = Cardinality::zeroOrOne();
+ else
+ cardinality = Cardinality::zeroOrMore();
+
+ return makeGenericSequenceType(m_nodeTest,
+ cardinality);
+}
+
+SequenceType::List AxisStep::expectedOperandTypes() const
+{
+ SequenceType::List result;
+ result.append(CommonSequenceTypes::ZeroOrMoreNodes);
+ return result;
+}
+
+Expression::Properties AxisStep::properties() const
+{
+ return RequiresContextItem | DisableElimination;
+}
+
+ItemType::Ptr AxisStep::expectedContextItemType() const
+{
+ return BuiltinTypes::node;
+}
+
+ExpressionVisitorResult::Ptr AxisStep::accept(const ExpressionVisitor::Ptr &visitor) const
+{
+ return visitor->visit(this);
+}
+
+QXmlNodeModelIndex::Axis AxisStep::axis() const
+{
+ return m_axis;
+}
+
+QString AxisStep::axisName(const QXmlNodeModelIndex::Axis axis)
+{
+ const char *result = 0;
+
+ switch(axis)
+ {
+ /* These must not be translated. */
+ case QXmlNodeModelIndex::AxisAncestorOrSelf: result = "ancestor-or-self"; break;
+ case QXmlNodeModelIndex::AxisAncestor: result = "ancestor"; break;
+ case QXmlNodeModelIndex::AxisAttributeOrTop: result = "attribute-or-top"; break;
+ case QXmlNodeModelIndex::AxisAttribute: result = "attribute"; break;
+ case QXmlNodeModelIndex::AxisChildOrTop: result = "child-or-top"; break;
+ case QXmlNodeModelIndex::AxisChild: result = "child"; break;
+ case QXmlNodeModelIndex::AxisDescendantOrSelf: result = "descendant-or-self"; break;
+ case QXmlNodeModelIndex::AxisDescendant: result = "descendant"; break;
+ case QXmlNodeModelIndex::AxisFollowing: result = "following"; break;
+ case QXmlNodeModelIndex::AxisFollowingSibling: result = "following-sibling"; break;
+ case QXmlNodeModelIndex::AxisNamespace: result = "namespace"; break;
+ case QXmlNodeModelIndex::AxisParent: result = "parent"; break;
+ case QXmlNodeModelIndex::AxisPreceding: result = "preceding"; break;
+ case QXmlNodeModelIndex::AxisPrecedingSibling: result = "preceding-sibling"; break;
+ case QXmlNodeModelIndex::AxisSelf: result = "self"; break;
+ }
+
+ Q_ASSERT_X(result, Q_FUNC_INFO, "An unknown axis type was apparently encountered.");
+ return QString::fromLatin1(result);
+}
+
+PatternPriority AxisStep::patternPriority() const
+{
+ return static_cast<const AnyNodeType *>(m_nodeTest.data())->patternPriority();
+}
+
+Expression::ID AxisStep::id() const
+{
+ return IDAxisStep;
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/expr/qaxisstep_p.h b/src/xmlpatterns/expr/qaxisstep_p.h
new file mode 100644
index 0000000..8f2ae27
--- /dev/null
+++ b/src/xmlpatterns/expr/qaxisstep_p.h
@@ -0,0 +1,168 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_AxisStep_H
+#define Patternist_AxisStep_H
+
+#include "qemptycontainer_p.h"
+#include "qitem_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short A step in a path expression that with an axis and a node test evaluates
+ * to a sequence of nodes from the context item.
+ *
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_expressions
+ */
+ class Q_AUTOTEST_EXPORT AxisStep : public EmptyContainer
+ {
+ public:
+ AxisStep(const QXmlNodeModelIndex::Axis axis,
+ const ItemType::Ptr &nodeTest);
+
+ virtual Item::Iterator::Ptr evaluateSequence(const DynamicContext::Ptr &) const;
+ virtual Item evaluateSingleton(const DynamicContext::Ptr &) const;
+
+ /**
+ * Returns @p node if it matches the node test this step is using, otherwise @c null.
+ */
+ inline Item mapToItem(const QXmlNodeModelIndex &node,
+ const DynamicContext::Ptr &context) const;
+
+ virtual SequenceType::List expectedOperandTypes() const;
+ virtual SequenceType::Ptr staticType() const;
+
+ /**
+ * Rewrites to ParentNodeAxis, if possible.
+ */
+ virtual Expression::Ptr typeCheck(const StaticContext::Ptr &context,
+ const SequenceType::Ptr &reqType);
+
+ /**
+ * @returns always BuiltinTypes::node;
+ */
+ virtual ItemType::Ptr expectedContextItemType() const;
+
+ virtual ExpressionVisitorResult::Ptr accept(const ExpressionVisitor::Ptr &visitor) const;
+
+ virtual Properties properties() const;
+
+ /**
+ * @returns the axis this step is using.
+ */
+ QXmlNodeModelIndex::Axis axis() const;
+
+ /**
+ * @returns the node test this step is using.
+ */
+ inline ItemType::Ptr nodeTest() const
+ {
+ return m_nodeTest;
+ }
+
+ void setNodeTest(const ItemType::Ptr &nev)
+ {
+ m_nodeTest = nev;
+ }
+
+ /**
+ * @short Prints the EBNF name corresponding to @p axis.
+ *
+ * For instance, for QXmlNodeModelIndex::Child, "child" is returned.
+ *
+ * Apart from being used in this class, it is used in the SDK.
+ */
+ static QString axisName(const QXmlNodeModelIndex::Axis axis);
+
+ virtual ID id() const;
+ virtual PatternPriority patternPriority() const;
+
+ inline void setAxis(const QXmlNodeModelIndex::Axis newAxis);
+
+ private:
+ typedef QExplicitlySharedDataPointer<const AxisStep> ConstPtr;
+
+ static const QXmlNodeModelIndex::NodeKind s_whenAxisNodeKindEmpty[];
+
+ /**
+ * @returns @c true when the axis @p axis and a node test testing node of
+ * type @p nodeKind always produces an empty sequence. One such example
+ * is <tt>attribute::comment()</tt>.
+ */
+ static bool isAlwaysEmpty(const QXmlNodeModelIndex::Axis axis,
+ const QXmlNodeModelIndex::NodeKind nodeKind);
+
+ /**
+ * The reason this variable is mutable, is that in the case of XSL-T patterns,
+ * we do quite some reordering.
+ */
+ QXmlNodeModelIndex::Axis m_axis;
+ ItemType::Ptr m_nodeTest;
+ };
+
+ void AxisStep::setAxis(const QXmlNodeModelIndex::Axis newAxis)
+ {
+ m_axis = newAxis;
+ }
+
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/expr/qcachecells_p.h b/src/xmlpatterns/expr/qcachecells_p.h
new file mode 100644
index 0000000..ec9ea8e
--- /dev/null
+++ b/src/xmlpatterns/expr/qcachecells_p.h
@@ -0,0 +1,157 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_CacheCells_H
+#define Patternist_CacheCells_H
+
+#include <QList>
+#include <QVector>
+
+#include "qitem_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+
+ /**
+ * @short Represents a cache entry for a single Item,
+ * as opposed to for a sequence of items.
+ *
+ * A characteristic of the ItemCacheCell is that it has two states:
+ * either its full or it's not, since it only deals with a single
+ * item.
+ *
+ * Remember that cachedItem doesn't tell the state of the ItemCacheCell.
+ * For instance, it can have a null pointer, the empty sequence, and that
+ * can be the value of its cache.
+ *
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class ItemCacheCell
+ {
+ public:
+ typedef QList<ItemCacheCell> List;
+ typedef QVector<ItemCacheCell> Vector;
+ enum CacheState
+ {
+ Full,
+ Empty
+ };
+
+ inline ItemCacheCell() : cacheState(Empty)
+ {
+ }
+
+ Item cachedItem;
+ CacheState cacheState;
+ };
+
+ /**
+ * @short Represents a cache entry for a sequence of items.
+ *
+ * As opposed to ItemCacheCell, ItemSequenceCacheCell can be partially
+ * populated: e.g, four items is in the cache while three remains in the
+ * source. For that reason ItemSequenceCacheCell in addition to the source
+ * also carried an QAbstractXmlForwardIterator which is the source, such
+ * that it can continue to populate the cache when it runs out.
+ *
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class ItemSequenceCacheCell
+ {
+ public:
+ typedef QList<ItemSequenceCacheCell> List;
+ typedef QVector<ItemSequenceCacheCell> Vector;
+
+ enum CacheState
+ {
+ Full,
+ Empty,
+ PartiallyPopulated
+ };
+
+ inline ItemSequenceCacheCell() : cacheState(Empty)
+ , inUse(false)
+ {
+ }
+
+ Item::List cachedItems;
+ Item::Iterator::Ptr sourceIterator;
+ CacheState cacheState;
+ /**
+ * In XSL-T, we can have circularity which we cannot detect statically.
+ * For instance, a global variable invokes a template, and the template
+ * uses the variable. We can't detect that, because we can't figure out
+ * what template will be invoked.
+ *
+ * For solution we have this toggle, which is set temporarily on the
+ * cell such that EvaluationCache can detect whether it's trashing
+ * itself.
+ *
+ * One might think that it would be sufficient to flag usage of the
+ * variable in an arbitrary template, but that would also flag valid
+ * cases.
+ */
+ bool inUse;
+ };
+}
+
+Q_DECLARE_TYPEINFO(QPatternist::ItemCacheCell, Q_MOVABLE_TYPE);
+Q_DECLARE_TYPEINFO(QPatternist::ItemSequenceCacheCell, Q_MOVABLE_TYPE);
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/expr/qcallsite.cpp b/src/xmlpatterns/expr/qcallsite.cpp
new file mode 100644
index 0000000..7137bb4
--- /dev/null
+++ b/src/xmlpatterns/expr/qcallsite.cpp
@@ -0,0 +1,68 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qcallsite_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+CallSite::CallSite(const QXmlName &name) : m_isRecursive(false)
+ , m_name(name)
+{
+}
+
+QXmlName CallSite::name() const
+{
+ return m_name;
+}
+
+bool CallSite::isRecursive() const
+{
+ return m_isRecursive;
+}
+
+void CallSite::setIsRecursive(const bool value)
+{
+ m_isRecursive = value;
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/expr/qcallsite_p.h b/src/xmlpatterns/expr/qcallsite_p.h
new file mode 100644
index 0000000..6c0013c
--- /dev/null
+++ b/src/xmlpatterns/expr/qcallsite_p.h
@@ -0,0 +1,111 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_CallSite_H
+#define Patternist_CallSite_H
+
+#include "qunlimitedcontainer_p.h"
+#include "qcalltargetdescription_p.h"
+#include "qxmlname.h"
+
+QT_BEGIN_HEADER
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Abstract base-class for Expression instances that are callsites
+ * to other components, such as templates or user functions.
+ *
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_expressions
+ * @since 4.5
+ */
+ class CallSite : public UnlimitedContainer
+ {
+ public:
+ QXmlName name() const;
+ bool isRecursive() const;
+ void setIsRecursive(const bool value);
+
+ /**
+ * Called in the earliest stages of the compilation process. @p sign can
+ * be any function signature for a user declared function. If @p sign
+ * matches this UserFunctionCallsite, it means the UserFunction represented
+ * by @p sign is recursive and that this UserFunctionCallsite should take
+ * appropriate measures.
+ *
+ * @returns @c true if is recursive, otherwise @c false
+ */
+ virtual bool configureRecursion(const CallTargetDescription::Ptr &sign) = 0;
+
+ /**
+ * @short Returns the body of the function/template/component that is
+ * being called.
+ */
+ virtual Expression::Ptr body() const = 0;
+
+ virtual CallTargetDescription::Ptr callTargetDescription() const = 0;
+
+ protected:
+ CallSite(const QXmlName &name = QXmlName());
+
+ private:
+ Q_DISABLE_COPY(CallSite)
+ bool m_isRecursive;
+ const QXmlName m_name;
+ };
+}
+
+QT_END_NAMESPACE
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/expr/qcalltargetdescription.cpp b/src/xmlpatterns/expr/qcalltargetdescription.cpp
new file mode 100644
index 0000000..0e14469
--- /dev/null
+++ b/src/xmlpatterns/expr/qcalltargetdescription.cpp
@@ -0,0 +1,107 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qcallsite_p.h"
+
+#include "qcalltargetdescription_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+CallTargetDescription::CallTargetDescription(const QXmlName &name) : m_name(name)
+{
+ Q_ASSERT(!m_name.isNull());
+}
+
+QXmlName CallTargetDescription::name() const
+{
+ return m_name;
+}
+
+void CallTargetDescription::checkArgumentsCircularity(CallTargetDescription::List &signList,
+ const Expression::Ptr callsite)
+{
+ /* Check the arguments. */
+ const Expression::List ops(callsite->operands());
+ const Expression::List::const_iterator end(ops.constEnd());
+ Expression::List::const_iterator it(ops.constBegin());
+
+ for(; it != end; ++it)
+ checkCallsiteCircularity(signList, *it);
+}
+
+void CallTargetDescription::checkCallsiteCircularity(CallTargetDescription::List &signList,
+ const Expression::Ptr expr)
+{
+ Q_ASSERT(expr);
+
+ if(expr->is(Expression::IDUserFunctionCallsite))
+ {
+ CallTargetDescription::List::const_iterator it(signList.constBegin());
+ const CallTargetDescription::List::const_iterator end(signList.constEnd());
+ CallSite *const callsite = static_cast<CallSite *>(expr.data());
+
+ for(; it != end; ++it)
+ {
+ if(callsite->configureRecursion(*it))
+ {
+ /* A callsite inside the function body to the function. This user function
+ * is recursive if it's to the same function, in other words. Which it was
+ * if configureRecursion() returned true. */
+
+ /* Now we continue and check the arguments of the callsite. That is, the arguments.
+ * This catches for instance local:foo(local:foo(3)). */
+ checkArgumentsCircularity(signList, expr);
+ return;
+ }
+ }
+ /* Check the body of the function so this callsite isn't "indirectly" a
+ * recursive call to the function we're checking. XQTS test case
+ * default_namespace-011 is an example of this. */
+ signList.append(callsite->callTargetDescription());
+ checkCallsiteCircularity(signList, callsite->body());
+ }
+
+ checkArgumentsCircularity(signList, expr); /* We're done in this case. */
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/expr/qcalltargetdescription_p.h b/src/xmlpatterns/expr/qcalltargetdescription_p.h
new file mode 100644
index 0000000..ac614be
--- /dev/null
+++ b/src/xmlpatterns/expr/qcalltargetdescription_p.h
@@ -0,0 +1,120 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_CallTargetDescription_H
+#define Patternist_CallTargetDescription_H
+
+template<typename Key, typename Value> class QHash;
+template<typename T> class QList;
+
+#include <QSharedData>
+
+#include "qexpression_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ class CallSite;
+
+ /**
+ * @short Contains metadata for a callable component, such as a function or
+ * template.
+ *
+ * CallTargetDescription can be used directly and is so for templates, but
+ * can also be sub-classed which FunctionSignature do.
+ *
+ * @ingroup Patternist_expr
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class Q_AUTOTEST_EXPORT CallTargetDescription : public QSharedData
+ {
+ public:
+ typedef QExplicitlySharedDataPointer<CallTargetDescription> Ptr;
+ typedef QList<Ptr> List;
+
+ CallTargetDescription(const QXmlName &name);
+
+ /**
+ * The function's name. For example, the name of the signature
+ * <tt>fn:string() as xs:string</tt> is <tt>fn:string</tt>.
+ */
+ QXmlName name() const;
+
+ /**
+ * Flags callsites to be aware of their recursion by calling
+ * UserFunctionCallsite::configureRecursion(), if that is the case.
+ *
+ * @note We pass @p expr by value here intentionally.
+ */
+ static void checkCallsiteCircularity(CallTargetDescription::List &signList,
+ const Expression::Ptr expr);
+ private:
+ /**
+ * Helper function for checkCallsiteCircularity(). If C++ allowed it,
+ * it would have been local to it.
+ */
+ static void checkArgumentsCircularity(CallTargetDescription::List &signList,
+ const Expression::Ptr callsite);
+
+ Q_DISABLE_COPY(CallTargetDescription)
+ const QXmlName m_name;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
+
diff --git a/src/xmlpatterns/expr/qcalltemplate.cpp b/src/xmlpatterns/expr/qcalltemplate.cpp
new file mode 100644
index 0000000..f16ffcf
--- /dev/null
+++ b/src/xmlpatterns/expr/qcalltemplate.cpp
@@ -0,0 +1,153 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qcommonsequencetypes_p.h"
+
+#include "qcalltemplate_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+CallTemplate::CallTemplate(const QXmlName &name,
+ const WithParam::Hash &withParams) : TemplateInvoker(withParams, name)
+{
+}
+
+Item::Iterator::Ptr CallTemplate::evaluateSequence(const DynamicContext::Ptr &context) const
+{
+ Q_ASSERT(m_template);
+ return m_template->body->evaluateSequence(m_template->createContext(this, context, true));
+}
+
+bool CallTemplate::evaluateEBV(const DynamicContext::Ptr &context) const
+{
+ Q_ASSERT(m_template);
+ return m_template->body->evaluateEBV(m_template->createContext(this, context, true));
+}
+
+void CallTemplate::evaluateToSequenceReceiver(const DynamicContext::Ptr &context) const
+{
+ Q_ASSERT(m_template);
+ m_template->body->evaluateToSequenceReceiver(m_template->createContext(this, context, true));
+}
+
+Expression::Ptr CallTemplate::typeCheck(const StaticContext::Ptr &context,
+ const SequenceType::Ptr &reqType)
+{
+ /* Check XTSE0680, that every @c xsl:with-param has a corresponding @c
+ * xsl:param declaration. */
+ {
+ const WithParam::Hash::const_iterator end(m_withParams.constEnd());
+
+ for(WithParam::Hash::const_iterator it(m_withParams.constBegin());
+ it != end;
+ ++it)
+ {
+ if(!VariableDeclaration::contains(m_template->templateParameters, it.value()->name()))
+ Template::raiseXTSE0680(context, it.value()->name(), this);
+ }
+ }
+
+ const Expression::Ptr me(TemplateInvoker::typeCheck(context, reqType));
+
+ const VariableDeclaration::List args(m_template->templateParameters);
+ const VariableDeclaration::List::const_iterator end(args.constEnd());
+ VariableDeclaration::List::const_iterator it(args.constBegin());
+
+ for(; it != end; ++it)
+ {
+ // TODO
+ Q_ASSERT((*it)->sequenceType);
+ }
+
+ return me;
+}
+
+Expression::Properties CallTemplate::properties() const
+{
+ Q_ASSERT(!m_template || m_template->body);
+
+ /* We may be called before our m_template is resolved, namely when we're
+ * the body of a variable. In that case querytransformparser.ypp will
+ * manually call TypeChecker::applyFunctionConversion(), which is before
+ * ExpressionFactory::createExpression() has resolved us. */
+ if(m_template && !isRecursive())
+ return m_template->properties();
+ else
+ return Properties();
+}
+
+Expression::Properties CallTemplate::dependencies() const
+{
+ if(m_template && !isRecursive())
+ return m_template->dependencies();
+ else
+ return Properties();
+}
+
+SequenceType::Ptr CallTemplate::staticType() const
+{
+ return CommonSequenceTypes::ZeroOrMoreItems;
+}
+
+ExpressionVisitorResult::Ptr CallTemplate::accept(const ExpressionVisitor::Ptr &visitor) const
+{
+ return visitor->visit(this);
+}
+
+bool CallTemplate::configureRecursion(const CallTargetDescription::Ptr &sign)
+{
+ Q_UNUSED(sign);
+ return false;
+}
+
+Expression::Ptr CallTemplate::body() const
+{
+ return m_template->body;
+}
+
+CallTargetDescription::Ptr CallTemplate::callTargetDescription() const
+{
+ return CallTargetDescription::Ptr();
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/expr/qcalltemplate_p.h b/src/xmlpatterns/expr/qcalltemplate_p.h
new file mode 100644
index 0000000..df67121
--- /dev/null
+++ b/src/xmlpatterns/expr/qcalltemplate_p.h
@@ -0,0 +1,117 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_CallTemplate_H
+#define Patternist_CallTemplate_H
+
+#include "qcallsite_p.h"
+#include "qtemplateinvoker_p.h"
+#include "qtemplate_p.h"
+
+QT_BEGIN_HEADER
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Implements @c xsl:call-template.
+ *
+ * @since 4.5
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_expressions
+ */
+ class CallTemplate : public TemplateInvoker
+ {
+ public:
+ typedef QExplicitlySharedDataPointer<CallTemplate> Ptr;
+
+ CallTemplate(const QXmlName &name,
+ const WithParam::Hash &withParams);
+
+ virtual Item::Iterator::Ptr evaluateSequence(const DynamicContext::Ptr &context) const;
+ virtual bool evaluateEBV(const DynamicContext::Ptr &context) const;
+ virtual void evaluateToSequenceReceiver(const DynamicContext::Ptr &context) const;
+
+ virtual SequenceType::Ptr staticType() const;
+ virtual ExpressionVisitorResult::Ptr accept(const ExpressionVisitor::Ptr &visitor) const;
+ virtual Properties properties() const;
+ virtual Properties dependencies() const;
+
+ /**
+ * This is a bit complicated by that we have two required types, one
+ * specified by @c xsl:param in the template declaration, and one on @c
+ * xsl:with-param.
+ *
+ * @see UserFunctionCallsite::expectedOperandTypes()
+ * @see <a href="http://www.w3.org/TR/xslt20/#with-param">XSL
+ * Transformations (XSLT) Version 2.0, 10.1.1 Passing Parameters to Templates</a>
+ */
+ virtual Expression::Ptr typeCheck(const StaticContext::Ptr &context,
+ const SequenceType::Ptr &reqType);
+
+
+ inline void setTemplate(const Template::Ptr &templ)
+ {
+ m_template = templ;
+ }
+
+ virtual bool configureRecursion(const CallTargetDescription::Ptr &sign);
+ virtual Expression::Ptr body() const;
+ virtual CallTargetDescription::Ptr callTargetDescription() const;
+ private:
+ Template::Ptr m_template;
+ };
+}
+
+QT_END_NAMESPACE
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/expr/qcastableas.cpp b/src/xmlpatterns/expr/qcastableas.cpp
new file mode 100644
index 0000000..65b5305
--- /dev/null
+++ b/src/xmlpatterns/expr/qcastableas.cpp
@@ -0,0 +1,157 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qatomictype_p.h"
+#include "qitem_p.h"
+#include "qboolean_p.h"
+#include "qbuiltintypes_p.h"
+#include "qcommonsequencetypes_p.h"
+#include "qcommonvalues_p.h"
+#include "qliteral_p.h"
+
+#include "qcastableas_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+CastableAs::CastableAs(const Expression::Ptr &operand,
+ const SequenceType::Ptr &tType) : SingleContainer(operand),
+ m_targetType(tType)
+{
+ Q_ASSERT(tType);
+ Q_ASSERT(!tType->cardinality().allowsMany());
+ Q_ASSERT(tType->itemType()->isAtomicType());
+}
+
+bool CastableAs::evaluateEBV(const DynamicContext::Ptr &context) const
+{
+ Item item;
+
+ if(m_operand->staticType()->cardinality().allowsMany())
+ {
+ const Item::Iterator::Ptr it(m_operand->evaluateSequence(context));
+ item = it->next();
+
+ if(it->next())
+ return false;
+ }
+ else
+ item = m_operand->evaluateSingleton(context);
+
+ if(item)
+ return !cast(item, context).as<AtomicValue>()->hasError();
+ else
+ return m_targetType->cardinality().allowsEmpty();
+}
+
+Expression::Ptr CastableAs::compress(const StaticContext::Ptr &context)
+{
+ const Expression::Ptr me(SingleContainer::compress(context));
+
+ if(me != this) /* We already managed to const fold, how convenient. */
+ return me;
+
+ const AtomicType::Ptr t(m_targetType->itemType());
+
+ const SequenceType::Ptr opType(m_operand->staticType());
+
+ /* Casting to these always succeeds, assuming the cardinality also matches,
+ * although the cardinality can fail. */
+ if(( *t == *BuiltinTypes::xsString
+ || *t == *BuiltinTypes::xsUntypedAtomic
+ || *t == *opType->itemType())
+ &&(m_targetType->cardinality().isMatch(opType->cardinality())))
+ {
+ return wrapLiteral(CommonValues::BooleanTrue, context, this);
+ }
+ else
+ return me;
+}
+
+Expression::Ptr CastableAs::typeCheck(const StaticContext::Ptr &context,
+ const SequenceType::Ptr &reqType)
+{
+ checkTargetType(context);
+ const Expression::Ptr me(SingleContainer::typeCheck(context, reqType));
+
+ return me;
+ if(BuiltinTypes::xsQName->xdtTypeMatches(m_targetType->itemType()))
+ {
+ const SequenceType::Ptr seqt(m_operand->staticType());
+ /* We can cast a string literal, an xs:QName value, and an
+ * empty sequence(if empty is allowed), to xs:QName. */
+ if(m_operand->is(IDStringValue) ||
+ BuiltinTypes::xsQName->xdtTypeMatches(seqt->itemType()) ||
+ (*seqt->itemType() == *CommonSequenceTypes::Empty && m_targetType->cardinality().allowsEmpty()))
+ {
+ return wrapLiteral(CommonValues::BooleanTrue, context, this)->typeCheck(context, reqType);
+ }
+ else
+ return wrapLiteral(CommonValues::BooleanFalse, context, this)->typeCheck(context, reqType);
+ }
+ else
+ {
+ /* Let the CastingPlatform look up its AtomicCaster. */
+ prepareCasting(context, m_operand->staticType()->itemType());
+
+ return me;
+ }
+}
+
+SequenceType::List CastableAs::expectedOperandTypes() const
+{
+ SequenceType::List result;
+ result.append(CommonSequenceTypes::ZeroOrMoreAtomicTypes);
+ return result;
+}
+
+SequenceType::Ptr CastableAs::staticType() const
+{
+ return CommonSequenceTypes::ExactlyOneBoolean;
+}
+
+ExpressionVisitorResult::Ptr CastableAs::accept(const ExpressionVisitor::Ptr &visitor) const
+{
+ return visitor->visit(this);
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/expr/qcastableas_p.h b/src/xmlpatterns/expr/qcastableas_p.h
new file mode 100644
index 0000000..fe216b1
--- /dev/null
+++ b/src/xmlpatterns/expr/qcastableas_p.h
@@ -0,0 +1,111 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_CastableAs_H
+#define Patternist_CastableAs_H
+
+#include "qsinglecontainer_p.h"
+#include "qcastingplatform_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+
+ /**
+ * @short Implements XPath 2.0's <tt>castable as</tt> expression.
+ *
+ * @see <a href="http://www.w3.org/TR/xpath20/#id-castable">XML Path Language
+ * (XPath) 2.0, 3.10.3 Castable</a>
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_expressions
+ */
+ class CastableAs : public SingleContainer,
+ public CastingPlatform<CastableAs, false>
+ {
+ public:
+ CastableAs(const Expression::Ptr &operand,
+ const SequenceType::Ptr &targetType);
+
+ virtual bool evaluateEBV(const DynamicContext::Ptr &) const;
+
+ /**
+ * Overridden to const fold to @c true when the target type
+ * is a type which casting to always succeeds. This is
+ * the type identical to the target type, <tt>xs:string</tt>,
+ * and <tt>xs:untypedAtomic</tt>.
+ */
+ virtual Expression::Ptr compress(const StaticContext::Ptr &context);
+ virtual Expression::Ptr typeCheck(const StaticContext::Ptr &context,
+ const SequenceType::Ptr &reqType);
+
+ virtual SequenceType::List expectedOperandTypes() const;
+ virtual SequenceType::Ptr staticType() const;
+
+ virtual ExpressionVisitorResult::Ptr accept(const ExpressionVisitor::Ptr &visitor) const;
+
+ inline ItemType::Ptr targetType() const
+ {
+ return m_targetType->itemType();
+ }
+
+ private:
+ const SequenceType::Ptr m_targetType;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/expr/qcastas.cpp b/src/xmlpatterns/expr/qcastas.cpp
new file mode 100644
index 0000000..741d052
--- /dev/null
+++ b/src/xmlpatterns/expr/qcastas.cpp
@@ -0,0 +1,204 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qitem_p.h"
+#include "qbuiltintypes_p.h"
+#include "qcardinalityverifier_p.h"
+#include "qcommonsequencetypes_p.h"
+#include "qemptysequence_p.h"
+#include "qgenericsequencetype_p.h"
+#include "qliteral_p.h"
+#include "qpatternistlocale_p.h"
+#include "qnamespaceresolver_p.h"
+#include "qqnameconstructor_p.h"
+#include "qqnamevalue_p.h"
+#include "qatomicstring_p.h"
+#include "qvalidationerror_p.h"
+
+#include "qcastas_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+CastAs::CastAs(const Expression::Ptr &source,
+ const SequenceType::Ptr &tType) : SingleContainer(source),
+ m_targetType(tType)
+{
+ Q_ASSERT(source);
+ Q_ASSERT(tType);
+ Q_ASSERT(!tType->cardinality().allowsMany());
+ Q_ASSERT(tType->itemType()->isAtomicType());
+}
+
+Item CastAs::evaluateSingleton(const DynamicContext::Ptr &context) const
+{
+ Q_ASSERT(context);
+ const Item val(m_operand->evaluateSingleton(context));
+
+ if(val)
+ return cast(val, context);
+ else
+ {
+ /* No item supplied, let's handle the cardinality part. */
+
+ if(m_targetType->cardinality().allowsEmpty())
+ return Item();
+ else
+ {
+ Q_ASSERT(context);
+ context->error(QtXmlPatterns::tr("Type error in cast, expected %1, "
+ "received %2.")
+ .arg(formatType(Cardinality::exactlyOne()))
+ .arg(formatType(Cardinality::empty())),
+ ReportContext::XPTY0004, this);
+ return Item();
+ }
+ }
+}
+
+Expression::Ptr CastAs::typeCheck(const StaticContext::Ptr &context,
+ const SequenceType::Ptr &reqType)
+{
+ checkTargetType(context);
+ const SequenceType::Ptr seqt(m_operand->staticType());
+ ItemType::Ptr t(seqt->itemType());
+
+ /* Special case xs:QName */
+ if(BuiltinTypes::xsQName->xdtTypeMatches(m_targetType->itemType()))
+ {
+ /* Ok, We're casting to xs:QName. */
+ if(m_operand->is(IDStringValue)) /* A valid combination, let's do the cast. */
+ return castToQName(context)->typeCheck(context, reqType);
+ else if(BuiltinTypes::xsQName->xdtTypeMatches(t))
+ return m_operand->typeCheck(context, reqType);
+ else if(seqt->cardinality().isEmpty() && m_targetType->cardinality().allowsEmpty())
+ return EmptySequence::create(this, context);
+ else if(!(seqt->cardinality().isEmpty() && !m_targetType->cardinality().allowsEmpty()))
+ {
+ context->error(QtXmlPatterns::tr("When casting to %1 or types "
+ "derived from it, the source "
+ "value must be of the same type, "
+ "or it must be a string literal. "
+ "Type %2 is not allowed.")
+ .arg(formatType(context->namePool(), BuiltinTypes::xsQName))
+ .arg(formatType(context->namePool(), seqt)),
+ ReportContext::XPTY0004, this);
+ return Expression::Ptr(this);
+ }
+ }
+
+ const Expression::Ptr me(SingleContainer::typeCheck(context, reqType));
+ /* Type may have changed, such as that atomization has been applied. */
+ t = m_operand->staticType()->itemType();
+
+ if(m_targetType->itemType()->xdtTypeMatches(t) &&
+ !BuiltinTypes::xsDayTimeDuration->xdtTypeMatches(t) &&
+ !BuiltinTypes::xsYearMonthDuration->xdtTypeMatches(t))
+ { /* At least casting is superflorous. */
+ if(m_operand->staticType()->cardinality().isMatch(m_targetType->cardinality()))
+ return m_operand; /* The whole cast expression is redundant. */
+ else
+ { /* Only cardinality check is needed, rewrite to CardinalityVerifier. */
+ return Expression::Ptr(new CardinalityVerifier(m_operand,
+ m_targetType->cardinality(),
+ ReportContext::FORG0001));
+ }
+ }
+
+ /* Let the CastingPlatform look up its AtomicCaster. */
+ prepareCasting(context, t);
+
+ return me;
+}
+
+Expression::Ptr CastAs::compress(const StaticContext::Ptr &context)
+{
+ /* Simplify casts to itself. */
+ if(*m_targetType->itemType() == *m_operand->staticType()->itemType())
+ return m_operand->compress(context);
+ else
+ return SingleContainer::compress(context);
+}
+
+Expression::Ptr CastAs::castToQName(const StaticContext::Ptr &context) const
+{
+ /* Apply the whitespace facet by calling trimmed(). */
+ /* We can assume m_operand is an Expression because this is a requirement
+ * for casting to xs:QName. */
+ const QString lexQName(m_operand->as<Literal>()->item().as<AtomicValue>()->stringValue().trimmed());
+
+ const QXmlName
+ expName(QNameConstructor::expandQName<StaticContext::Ptr,
+ ReportContext::FORG0001,
+ ReportContext::FONS0004>(lexQName,
+ context,
+ context->namespaceBindings(), this));
+ return wrapLiteral(toItem(QNameValue::fromValue(context->namePool(), expName)), context, this);
+}
+
+SequenceType::Ptr CastAs::staticType() const
+{
+ if(m_operand->staticType()->cardinality().allowsEmpty())
+ return m_targetType;
+ else
+ return makeGenericSequenceType(m_targetType->itemType(),
+ Cardinality::exactlyOne());
+}
+
+SequenceType::List CastAs::expectedOperandTypes() const
+{
+ SequenceType::List result;
+
+ if(m_targetType->cardinality().allowsEmpty())
+ result.append(CommonSequenceTypes::ZeroOrOneAtomicType);
+ else
+ result.append(CommonSequenceTypes::ExactlyOneAtomicType);
+
+ return result;
+}
+
+ExpressionVisitorResult::Ptr CastAs::accept(const ExpressionVisitor::Ptr &visitor) const
+{
+ return visitor->visit(this);
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/expr/qcastas_p.h b/src/xmlpatterns/expr/qcastas_p.h
new file mode 100644
index 0000000..892b064
--- /dev/null
+++ b/src/xmlpatterns/expr/qcastas_p.h
@@ -0,0 +1,148 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_CastAs_H
+#define Patternist_CastAs_H
+
+#include "qsinglecontainer_p.h"
+#include "qcastingplatform_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Implements XPath 2.0's <tt>cast as</tt> expression.
+ *
+ * Implements the casting expression, such as <tt>'3' cast as xs:integer</tt>. This class also
+ * implements constructor functions, which are created in the ConstructorFunctionsFactory.
+ *
+ * CastAs uses CastingPlatform for carrying out the actual casting.
+ *
+ * @see <a href="http://www.w3.org/TR/xpath-functions/#casting">XQuery 1.0
+ * and XPath 2.0 Functions and Operators, 7 Casting</a>
+ * @see <a href="http://www.w3.org/TR/xpath20/#id-cast">XML Path Language
+ * (XPath) 2.0, 3.10.2 Cast</a>
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_expressions
+ */
+ class CastAs : public SingleContainer,
+ public CastingPlatform<CastAs, true /* issueError */>
+ {
+ public:
+
+ /**
+ * @todo Wrong/old documentation
+ *
+ * Creates a cast expression for the type @p name via the schema type
+ * factory @p factory. This function is used by parser when creating
+ * 'cast to' expressions, and the ConstructorFunctionsFactory, when creating
+ * constructor functions.
+ *
+ * @param targetType the type which the CastAs should cast to
+ * @param source the operand to evaluate and then cast from
+ */
+ CastAs(const Expression::Ptr &source,
+ const SequenceType::Ptr &targetType);
+
+ virtual Item evaluateSingleton(const DynamicContext::Ptr &) const;
+
+ virtual SequenceType::List expectedOperandTypes() const;
+
+ /**
+ * @returns a SequenceType where the ItemType is this CastAs's
+ * target type, as per targetType(), and the Cardinality is inferred from the
+ * source operand to reflect whether this CastAs always will evaluate to
+ * exactly-one or zero-or-one values.
+ */
+ virtual SequenceType::Ptr staticType() const;
+
+ /**
+ * Overridden in order to check that casting to an abstract type
+ * is not attempted.
+ */
+ virtual Expression::Ptr typeCheck(const StaticContext::Ptr &context,
+ const SequenceType::Ptr &reqType);
+
+ /**
+ * If the target type is the same as the source type, it is rewritten
+ * to the operand.
+ */
+ virtual Expression::Ptr compress(const StaticContext::Ptr &context);
+ virtual ExpressionVisitorResult::Ptr accept(const ExpressionVisitor::Ptr &visitor) const;
+
+ inline ItemType::Ptr targetType() const
+ {
+ return m_targetType->itemType();
+ }
+
+ inline SequenceType::Ptr targetSequenceType() const
+ {
+ return m_targetType;
+ }
+
+ private:
+ /**
+ * Performs casting to @c xs:QName. This case is special, and is always done at compile time.
+ */
+ Expression::Ptr castToQName(const StaticContext::Ptr &context) const;
+
+ const SequenceType::Ptr m_targetType;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/expr/qcastingplatform.cpp b/src/xmlpatterns/expr/qcastingplatform.cpp
new file mode 100644
index 0000000..04b6349
--- /dev/null
+++ b/src/xmlpatterns/expr/qcastingplatform.cpp
@@ -0,0 +1,221 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/**
+ * @file
+ * @short This file is included by qcastingplatform_p.h.
+ * If you need includes in this file, put them in CasttingPlatform.h, outside of the namespace.
+ */
+
+template <typename TSubClass, const bool issueError>
+Item CastingPlatform<TSubClass, issueError>::castWithCaster(const Item &sourceValue,
+ const AtomicCaster::Ptr &caster,
+ const ReportContext::Ptr &context) const
+{
+ Q_ASSERT(sourceValue);
+ Q_ASSERT(caster);
+ Q_ASSERT(context);
+
+ const Item retval(caster->castFrom(sourceValue, context));
+
+ if(issueError)
+ {
+ if(retval.template as<AtomicValue>()->hasError())
+ {
+ issueCastError(retval, sourceValue, context);
+ return Item();
+ }
+ else
+ return retval;
+ }
+ else
+ return retval;
+}
+
+template <typename TSubClass, const bool issueError>
+Item CastingPlatform<TSubClass, issueError>::cast(const Item &sourceValue,
+ const ReportContext::Ptr &context) const
+{
+ Q_ASSERT(sourceValue);
+ Q_ASSERT(context);
+ Q_ASSERT(targetType());
+
+ if(m_caster)
+ return castWithCaster(sourceValue, m_caster, context);
+ else
+ {
+ bool castImpossible = false;
+ const AtomicCaster::Ptr caster(locateCaster(sourceValue.type(), context, castImpossible, static_cast<const TSubClass *>(this), targetType()));
+
+ if(!issueError && castImpossible)
+ {
+ /* If we're supposed to issue an error(issueError) then this
+ * line will never be reached, because locateCaster() will in
+ * that case throw. */
+ return ValidationError::createError();
+ }
+ else
+ return castWithCaster(sourceValue, caster, context);
+ }
+}
+
+template <typename TSubClass, const bool issueError>
+bool CastingPlatform<TSubClass, issueError>::prepareCasting(const ReportContext::Ptr &context,
+ const ItemType::Ptr &sourceType)
+{
+ Q_ASSERT(sourceType);
+ Q_ASSERT(context);
+
+ if(*sourceType == *BuiltinTypes::xsAnyAtomicType ||
+ *sourceType == *BuiltinTypes::item ||
+ *sourceType == *CommonSequenceTypes::Empty ||
+ *sourceType == *BuiltinTypes::numeric)
+ return true; /* The type could not be narrowed better than xs:anyAtomicType
+ or numeric at compile time. We'll do lookup at runtime instead. */
+
+ bool castImpossible = false;
+ m_caster = locateCaster(sourceType, context, castImpossible, static_cast<const TSubClass *>(this), targetType());
+
+ return !castImpossible;
+}
+
+template <typename TSubClass, const bool issueError>
+AtomicCaster::Ptr CastingPlatform<TSubClass, issueError>::locateCaster(const ItemType::Ptr &sourceType,
+ const ReportContext::Ptr &context,
+ bool &castImpossible,
+ const SourceLocationReflection *const location,
+ const ItemType::Ptr &targetType)
+{
+ Q_ASSERT(sourceType);
+ Q_ASSERT(targetType);
+
+ const AtomicCasterLocator::Ptr locator(static_cast<AtomicType *>(
+ targetType.data())->casterLocator());
+ if(!locator)
+ {
+ if(issueError)
+ {
+ context->error(QtXmlPatterns::tr("No casting is possible with %1 as the target type.")
+ .arg(formatType(context->namePool(), targetType)),
+ ReportContext::XPTY0004, location);
+ }
+ else
+ castImpossible = true;
+
+ return AtomicCaster::Ptr();
+ }
+
+ const AtomicCaster::Ptr caster(static_cast<const AtomicType *>(sourceType.data())->accept(locator, location));
+ if(!caster)
+ {
+ if(issueError)
+ {
+ context->error(QtXmlPatterns::tr("It is not possible to cast from %1 to %2.")
+ .arg(formatType(context->namePool(), sourceType))
+ .arg(formatType(context->namePool(), targetType)),
+ ReportContext::XPTY0004, location);
+ }
+ else
+ castImpossible = true;
+
+ return AtomicCaster::Ptr();
+ }
+
+ return caster;
+}
+
+template <typename TSubClass, const bool issueError>
+void CastingPlatform<TSubClass, issueError>::checkTargetType(const ReportContext::Ptr &context) const
+{
+ Q_ASSERT(context);
+
+ const ItemType::Ptr tType(targetType());
+ Q_ASSERT(tType);
+ Q_ASSERT(tType->isAtomicType());
+ const AtomicType::Ptr asAtomic(tType);
+
+ /* This catches casting to xs:NOTATION and xs:anyAtomicType. */
+ if(asAtomic->isAbstract())
+ {
+ context->error(QtXmlPatterns::tr("Casting to %1 is not possible because it "
+ "is an abstract type, and can therefore never be instantiated.")
+ .arg(formatType(context->namePool(), tType)),
+ ReportContext::XPST0080,
+ static_cast<const TSubClass*>(this));
+ }
+}
+
+template <typename TSubClass, const bool issueError>
+void CastingPlatform<TSubClass, issueError>::issueCastError(const Item &validationError,
+ const Item &sourceValue,
+ const ReportContext::Ptr &context) const
+{
+ Q_ASSERT(validationError);
+ Q_ASSERT(context);
+ Q_ASSERT(validationError.isAtomicValue());
+ Q_ASSERT(validationError.template as<AtomicValue>()->hasError());
+
+ const ValidationError::Ptr err(validationError.template as<ValidationError>());
+ QString msg(err->message());
+
+ if(msg.isNull())
+ {
+ msg = QtXmlPatterns::tr("It's not possible to cast the value %1 of type %2 to %3")
+ .arg(formatData(sourceValue.stringValue()))
+ .arg(formatType(context->namePool(), sourceValue.type()))
+ .arg(formatType(context->namePool(), targetType()));
+ }
+ else
+ {
+ Q_ASSERT(!msg.isEmpty());
+ msg = QtXmlPatterns::tr("Failure when casting from %1 to %2: %3")
+ .arg(formatType(context->namePool(), sourceValue.type()))
+ .arg(formatType(context->namePool(), targetType()))
+ .arg(msg);
+ }
+
+ /* If m_errorCode is FORG0001, we assume our sub-classer doesn't have a
+ * special wish about error code, so then we use the error object's code.
+ */
+ context->error(msg, m_errorCode == ReportContext::FORG0001 ? err->errorCode() : m_errorCode,
+ static_cast<const TSubClass*>(this));
+}
+
diff --git a/src/xmlpatterns/expr/qcastingplatform_p.h b/src/xmlpatterns/expr/qcastingplatform_p.h
new file mode 100644
index 0000000..415003f
--- /dev/null
+++ b/src/xmlpatterns/expr/qcastingplatform_p.h
@@ -0,0 +1,206 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_CastingPlatform_H
+#define Patternist_CastingPlatform_H
+
+#include "qatomiccasterlocator_p.h"
+#include "qatomiccaster_p.h"
+#include "qatomicstring_p.h"
+#include "qatomictype_p.h"
+#include "qbuiltintypes_p.h"
+#include "qcommonsequencetypes_p.h"
+#include "qpatternistlocale_p.h"
+#include "qqnamevalue_p.h"
+#include "qschematypefactory_p.h"
+#include "qstaticcontext_p.h"
+#include "qvalidationerror_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Provides casting functionality for classes, such as CastAs or NumberFN, which
+ * needs to perform casting.
+ *
+ * Classes which need to perform casting can simply from this class and gain
+ * access to casting functinality wrapped in a convenient way. At the center of this
+ * class is the cast() function, which is used at runtime to perform the actual cast.
+ *
+ * The actual circumstances where casting is used, such as in the 'castable as'
+ * expression or the <tt>fn:number()</tt> function, often have other things to handle as well,
+ * error handling and cardinality checks for example. This class handles only casting
+ * and leaves the other case-specific details to the sub-class such that this class only
+ * do one thing well.
+ *
+ * This template class takes two parameters:
+ * - TSubClass This should be the class inheriting from CastingPlatform.
+ * - issueError if true, errors are issued via ReportContext, otherwise
+ * ValidationError instances are returned appropriately.
+ *
+ * The class inheriting CastingPlatform must implement the following function:
+ * @code
+ * ItemType::Ptr targetType() const
+ * @endcode
+ *
+ * that returns the type that should be cast to. The type must be an AtomicType.
+ * Typically, it is appropriate to declare this function @c inline.
+ *
+ * A sub-class calls prepareCasting() at compile time(such that CastingPlatform can attempt
+ * to lookup the proper AtomicCaster) and then it simply uses the cast() function at runtime. The
+ * function targetType() must be implemented such that CastingPlatform knows
+ * what type it shall cast to.
+ *
+ * @see ValueFactory
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_expressions
+ */
+ template<typename TSubClass, const bool issueError>
+ class CastingPlatform
+ {
+ protected:
+ /**
+ * @note issueCastError() depends on the default value.
+ */
+ inline CastingPlatform(const ReportContext::ErrorCode code = ReportContext::FORG0001) : m_errorCode(code)
+ {
+ }
+
+ /**
+ * Attempts to cast @p sourceValue to targetType(), and returns
+ * the created value. Remember that prepareCasting() should have been
+ * called at compile time, otherwise this function will be slow.
+ *
+ * Error reporting is done in two ways. If a cast fails because
+ * of an error in lexical representation a ValidationError is returned.
+ * If the cause of failure is that the casting combination is invalid(such as
+ * when attempting to cast @c xs:date to @c xs:integer), a ValidationError
+ * is returned if @c false was passed in the template instantiation,
+ * an error is issued via @p context.
+ *
+ * @param sourceValue the value to cast. Must be non @c null.
+ * @param context the usual ReportContext, used for error reporting.
+ * @returns the new value which was the result of the cast. If the
+ * cast failed, an ValidationError is returned.
+ */
+ Item cast(const Item &sourceValue,
+ const ReportContext::Ptr &context) const;
+
+ /**
+ * This function should be called at compiled time, it attempts to determine
+ * what AtomicCaster that should be used when casting from @p sourceType to
+ * targetType(). If that is not possible, because the @p sourceType is
+ * @c xs:anyAtomicType for instance, the AtomicCaster lookup will done at
+ * runtime on a case-per-case basis.
+ *
+ * @returns @c true if the requested casting combination is valid or might be valid.
+ * If it is guranteed to be invalid, @c false is returned.
+ */
+ bool prepareCasting(const ReportContext::Ptr &context,
+ const ItemType::Ptr &sourceType);
+
+ /**
+ * Checks that the targetType() is a valid target type for <tt>castable as</tt>
+ * and <tt>cast as</tt>. For example, that it is not abstract. If the type is
+ * invalid, an error is raised via the @p context. Note that it is assumed the type
+ * is atomic.
+ */
+ void checkTargetType(const ReportContext::Ptr &context) const;
+
+ private:
+ inline Item castWithCaster(const Item &sourceValue,
+ const AtomicCaster::Ptr &caster,
+ const ReportContext::Ptr &context) const;
+
+ /**
+ * Locates the caster for casting values of type @p sourceType to targetType(), if
+ * possible.
+ *
+ * @p castImpossible is not initialized. Initialize it to @c false.
+ */
+ static AtomicCaster::Ptr locateCaster(const ItemType::Ptr &sourceType,
+ const ReportContext::Ptr &context,
+ bool &castImpossible,
+ const SourceLocationReflection *const location,
+ const ItemType::Ptr &targetType);
+ private:
+ inline Item castWithCaster(const Item &sourceValue,
+ const AtomicCaster::Ptr &caster,
+ const DynamicContext::Ptr &context) const;
+
+
+ inline ItemType::Ptr targetType() const
+ {
+ Q_ASSERT(static_cast<const TSubClass *>(this)->targetType());
+ return static_cast<const TSubClass *>(this)->targetType();
+ }
+
+ void issueCastError(const Item &validationError,
+ const Item &sourceValue,
+ const ReportContext::Ptr &context) const;
+
+ Q_DISABLE_COPY(CastingPlatform)
+ AtomicCaster::Ptr m_caster;
+ const ReportContext::ErrorCode m_errorCode;
+ };
+
+#include "qcastingplatform.cpp"
+
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/expr/qcollationchecker.cpp b/src/xmlpatterns/expr/qcollationchecker.cpp
new file mode 100644
index 0000000..91e4848
--- /dev/null
+++ b/src/xmlpatterns/expr/qcollationchecker.cpp
@@ -0,0 +1,79 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qcommonsequencetypes_p.h"
+#include "qxpathhelper_p.h"
+
+#include "qcollationchecker_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+CollationChecker::CollationChecker(const Expression::Ptr &source) : SingleContainer(source)
+{
+}
+
+Item CollationChecker::evaluateSingleton(const DynamicContext::Ptr &context) const
+{
+ const Item val(m_operand->evaluateSingleton(context));
+ XPathHelper::checkCollationSupport<ReportContext::FOCH0002>(val.stringValue(), context, this);
+ return val;
+}
+
+SequenceType::List CollationChecker::expectedOperandTypes() const
+{
+ SequenceType::List list;
+ list.append(CommonSequenceTypes::ExactlyOneString);
+ return list;
+}
+
+SequenceType::Ptr CollationChecker::staticType() const
+{
+ return m_operand->staticType();
+}
+
+ExpressionVisitorResult::Ptr CollationChecker::accept(const ExpressionVisitor::Ptr &visitor) const
+{
+ return visitor->visit(this);
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/expr/qcollationchecker_p.h b/src/xmlpatterns/expr/qcollationchecker_p.h
new file mode 100644
index 0000000..b57e8c9
--- /dev/null
+++ b/src/xmlpatterns/expr/qcollationchecker_p.h
@@ -0,0 +1,99 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_CollationChecker_H
+#define Patternist_CollationChecker_H
+
+#include "qsinglecontainer_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Checks that its operand evaluates to a supported string collation.
+ *
+ * CollationChecker is inserted in the AST when an Expression has LastOperandIsCollation
+ * set. If the argument that CollationChecker is a string literal the CollationChecker
+ * will const-fold as usual, but otherwise will simply pipe through the value of its argument,
+ * if it's a supported collation. Otherwise it raise an error, with code ReportContext::FOCH0002.
+ *
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_expressions
+ */
+ class CollationChecker : public SingleContainer
+ {
+ public:
+ CollationChecker(const Expression::Ptr &source);
+
+ virtual Item evaluateSingleton(const DynamicContext::Ptr &) const;
+
+ /**
+ * Expects exactly one string.
+ */
+ virtual SequenceType::List expectedOperandTypes() const;
+
+ /**
+ * @returns its operand's static type.
+ */
+ virtual SequenceType::Ptr staticType() const;
+
+ virtual ExpressionVisitorResult::Ptr accept(const ExpressionVisitor::Ptr &visitor) const;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/expr/qcombinenodes.cpp b/src/xmlpatterns/expr/qcombinenodes.cpp
new file mode 100644
index 0000000..0670faf
--- /dev/null
+++ b/src/xmlpatterns/expr/qcombinenodes.cpp
@@ -0,0 +1,172 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qcommonsequencetypes_p.h"
+#include "qexceptiterator_p.h"
+#include "qgenericsequencetype_p.h"
+#include "qintersectiterator_p.h"
+#include "qitemmappingiterator_p.h"
+#include "qnodesort_p.h"
+#include "qunioniterator_p.h"
+
+#include "qcombinenodes_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+CombineNodes::CombineNodes(const Expression::Ptr &operand1,
+ const Operator op,
+ const Expression::Ptr &operand2) : PairContainer(operand1, operand2),
+ m_operator(op)
+{
+ Q_ASSERT(op == Union ||
+ op == Except ||
+ op == Intersect);
+}
+
+Item::Iterator::Ptr CombineNodes::evaluateSequence(const DynamicContext::Ptr &context) const
+{
+ const Item::Iterator::Ptr op1(m_operand1->evaluateSequence(context));
+ const Item::Iterator::Ptr op2(m_operand2->evaluateSequence(context));
+
+ switch(m_operator)
+ {
+ case Intersect:
+ return Item::Iterator::Ptr(new IntersectIterator(op1, op2));
+ case Except:
+ return Item::Iterator::Ptr(new ExceptIterator(op1, op2));
+ default:
+ {
+ Q_ASSERT(m_operator == Union);
+ return Item::Iterator::Ptr(new UnionIterator(op1, op2));
+ }
+ }
+}
+
+Item CombineNodes::evaluateSingleton(const DynamicContext::Ptr &context) const
+{
+ return evaluateSequence(context)->next();
+}
+
+Expression::Ptr CombineNodes::typeCheck(const StaticContext::Ptr &context,
+ const SequenceType::Ptr &reqType)
+{
+
+ const Expression::Ptr me(PairContainer::typeCheck(context, reqType));
+
+ m_operand1 = NodeSortExpression::wrapAround(m_operand1, context);
+ m_operand2 = NodeSortExpression::wrapAround(m_operand2, context);
+
+ return me;
+}
+
+bool CombineNodes::evaluateEBV(const DynamicContext::Ptr &context) const
+{
+ /* If it's the union operator, we can possibly avoid
+ * evaluating the second operand. */
+
+ if(m_operator == Union)
+ {
+ return m_operand1->evaluateEBV(context) ||
+ m_operand2->evaluateEBV(context);
+ }
+ else
+ return PairContainer::evaluateEBV(context);
+}
+
+QString CombineNodes::displayName(const Operator op)
+{
+ switch(op)
+ {
+ case Intersect:
+ return QLatin1String("intersect");
+ case Except:
+ return QLatin1String("except");
+ default:
+ {
+ Q_ASSERT(op == Union);
+ return QLatin1String("union");
+ }
+ }
+}
+
+SequenceType::Ptr CombineNodes::staticType() const
+{
+ const SequenceType::Ptr t1(m_operand1->staticType());
+ const SequenceType::Ptr t2(m_operand2->staticType());
+
+ Cardinality card;
+
+ /* Optimization: the cardinality can be better inferred for
+ * Intersect and Except, although it's not trivial code. */
+ if(m_operator == Union)
+ card = t1->cardinality() | t2->cardinality();
+ else /* Except. */
+ card = Cardinality::zeroOrMore();
+
+ return makeGenericSequenceType(t1->itemType() | t2->itemType(), card);
+}
+
+SequenceType::List CombineNodes::expectedOperandTypes() const
+{
+ SequenceType::List result;
+ result.append(CommonSequenceTypes::ZeroOrMoreNodes);
+ result.append(CommonSequenceTypes::ZeroOrMoreNodes);
+ return result;
+}
+
+CombineNodes::Operator CombineNodes::operatorID() const
+{
+ return m_operator;
+}
+
+ExpressionVisitorResult::Ptr CombineNodes::accept(const ExpressionVisitor::Ptr &visitor) const
+{
+ return visitor->visit(this);
+}
+
+Expression::ID CombineNodes::id() const
+{
+ return IDCombineNodes;
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/expr/qcombinenodes_p.h b/src/xmlpatterns/expr/qcombinenodes_p.h
new file mode 100644
index 0000000..4baf196
--- /dev/null
+++ b/src/xmlpatterns/expr/qcombinenodes_p.h
@@ -0,0 +1,116 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_CombineNodes_H
+#define Patternist_CombineNodes_H
+
+#include "qpaircontainer_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Implements XPath 2.0's operators for combining node sequences: @c union,
+ * @c intersect and @c except.
+ *
+ * @see <a href="http://www.w3.org/TR/xquery/#combining_seq">XQuery 1.0: An XML Query
+ * Language, 3.3.3 Combining QXmlNodeModelIndex Sequences</a>
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_expressions
+ */
+ class Q_AUTOTEST_EXPORT CombineNodes : public PairContainer
+ {
+ public:
+ enum Operator
+ {
+ Union = 1,
+ Intersect = 2,
+ Except = 4
+ };
+
+ CombineNodes(const Expression::Ptr &operand1,
+ const Operator op,
+ const Expression::Ptr &operand2);
+
+ virtual Item::Iterator::Ptr evaluateSequence(const DynamicContext::Ptr &context) const;
+ virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const;
+ virtual bool evaluateEBV(const DynamicContext::Ptr &context) const;
+ virtual SequenceType::Ptr staticType() const;
+ virtual SequenceType::List expectedOperandTypes() const;
+ virtual Expression::Ptr typeCheck(const StaticContext::Ptr &context,
+ const SequenceType::Ptr &reqType);
+
+ Operator operatorID() const;
+ virtual ID id() const;
+
+ /**
+ * Determines the string representation for operator @p op.
+ *
+ * @return "union" if @p op is Union, "intersect" if @p op
+ * is Intersect and "except" if @p op is Except.
+ */
+ static QString displayName(const Operator op);
+
+ virtual ExpressionVisitorResult::Ptr accept(const ExpressionVisitor::Ptr &visitor) const;
+
+ private:
+ const Operator m_operator;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/expr/qcommentconstructor.cpp b/src/xmlpatterns/expr/qcommentconstructor.cpp
new file mode 100644
index 0000000..8d7144f
--- /dev/null
+++ b/src/xmlpatterns/expr/qcommentconstructor.cpp
@@ -0,0 +1,124 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qcommonsequencetypes_p.h"
+#include "qpatternistlocale_p.h"
+#include "qnodebuilder_p.h"
+
+#include "qcommentconstructor_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+CommentConstructor::CommentConstructor(const Expression::Ptr &op) : SingleContainer(op)
+{
+}
+
+QString CommentConstructor::evaluateContent(const DynamicContext::Ptr &context) const
+{
+ const Item item(m_operand->evaluateSingleton(context));
+
+ if(!item)
+ return QString();
+
+ const QString content(item.stringValue());
+
+ if(content.contains(QLatin1String("--")))
+ {
+ context->error(QtXmlPatterns::tr("A comment cannot contain %1")
+ .arg(formatData("--")),
+ ReportContext::XQDY0072, this);
+ }
+ else if(content.endsWith(QLatin1Char('-')))
+ {
+ context->error(QtXmlPatterns::tr("A comment cannot end with a %1.")
+ .arg(formatData(QLatin1Char('-'))),
+ ReportContext::XQDY0072, this);
+ }
+
+ return content;
+}
+
+Item CommentConstructor::evaluateSingleton(const DynamicContext::Ptr &context) const
+{
+ const QString content(evaluateContent(context));
+ const NodeBuilder::Ptr nodeBuilder(context->nodeBuilder(QUrl()));
+ nodeBuilder->comment(content);
+
+ const QAbstractXmlNodeModel::Ptr nm(nodeBuilder->builtDocument());
+ context->addNodeModel(nm);
+
+ return nm->root(QXmlNodeModelIndex());
+}
+
+void CommentConstructor::evaluateToSequenceReceiver(const DynamicContext::Ptr &context) const
+{
+ const QString content(evaluateContent(context));
+ QAbstractXmlReceiver *const receiver = context->outputReceiver();
+
+ receiver->comment(content);
+}
+
+SequenceType::Ptr CommentConstructor::staticType() const
+{
+ return CommonSequenceTypes::ExactlyOneComment;
+}
+
+SequenceType::List CommentConstructor::expectedOperandTypes() const
+{
+ SequenceType::List result;
+ result.append(CommonSequenceTypes::ZeroOrOneString);
+ return result;
+}
+
+Expression::Properties CommentConstructor::properties() const
+{
+ return DisableElimination | IsNodeConstructor;
+}
+
+ExpressionVisitorResult::Ptr
+CommentConstructor::accept(const ExpressionVisitor::Ptr &visitor) const
+{
+ return visitor->visit(this);
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/expr/qcommentconstructor_p.h b/src/xmlpatterns/expr/qcommentconstructor_p.h
new file mode 100644
index 0000000..75467ec
--- /dev/null
+++ b/src/xmlpatterns/expr/qcommentconstructor_p.h
@@ -0,0 +1,100 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_CommentConstructor_H
+#define Patternist_CommentConstructor_H
+
+#include "qsinglecontainer_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Constructs a comment node. This covers both computed and directly constructed
+ * text nodes.
+ *
+ * @see <a href="http://www.w3.org/TR/xquery/#id-constructors">XQuery
+ * 1.0: An XML Query Language, 3.7 Constructors</a>
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_expressions
+ */
+ class CommentConstructor : public SingleContainer
+ {
+ public:
+ CommentConstructor(const Expression::Ptr &operand);
+
+ virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const;
+ virtual void evaluateToSequenceReceiver(const DynamicContext::Ptr &context) const;
+
+ virtual SequenceType::Ptr staticType() const;
+
+ /**
+ * The first operand must be exactly one @c xs:string.
+ */
+ virtual SequenceType::List expectedOperandTypes() const;
+
+ virtual ExpressionVisitorResult::Ptr accept(const ExpressionVisitor::Ptr &visitor) const;
+
+ virtual Properties properties() const;
+
+ private:
+ inline QString evaluateContent(const DynamicContext::Ptr &context) const;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/expr/qcomparisonplatform.cpp b/src/xmlpatterns/expr/qcomparisonplatform.cpp
new file mode 100644
index 0000000..625dd01
--- /dev/null
+++ b/src/xmlpatterns/expr/qcomparisonplatform.cpp
@@ -0,0 +1,199 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/**
+ * @file
+ * @short This file is included by qcomparisonplatform_p.h.
+ * If you need includes in this file, put them in qcomparisonplatform_p.h, outside of the namespace.
+ */
+
+template <typename TSubClass, bool issueError,
+ AtomicComparator::ComparisonType comparisonType, ReportContext::ErrorCode errorCode>
+bool ComparisonPlatform<TSubClass, issueError, comparisonType, errorCode>::
+flexibleCompare(const Item &it1,
+ const Item &it2,
+ const DynamicContext::Ptr &context) const
+{
+ if(m_comparator)
+ /* The comparator was located at compile time. */
+ return compare(it1, it2, m_comparator, operatorID());
+ else
+ {
+ const AtomicComparator::Ptr cp(fetchComparator(it1.type(),
+ it2.type(),
+ context));
+
+ return cp ? compare(it1, it2, cp, operatorID()) : false;
+ }
+}
+
+template <typename TSubClass, bool issueError,
+ AtomicComparator::ComparisonType comparisonType, ReportContext::ErrorCode errorCode>
+AtomicComparator::ComparisonResult
+ComparisonPlatform<TSubClass, issueError, comparisonType, errorCode>::
+detailedFlexibleCompare(const Item &it1,
+ const Item &it2,
+ const DynamicContext::Ptr &context) const
+{
+ AtomicComparator::Ptr comp;
+
+ if(m_comparator)
+ comp = m_comparator;
+ else
+ {
+ comp = fetchComparator(it1.type(),
+ it2.type(),
+ context);
+ }
+
+ Q_ASSERT_X(operatorID() == AtomicComparator::OperatorLessThanNaNLeast || operatorID() == AtomicComparator::OperatorLessThanNaNGreatest,
+ Q_FUNC_INFO, "Only OperatorLessThan is currently supported for this function.");
+ return comp->compare(it1, operatorID(), it2);
+}
+
+template <typename TSubClass, bool issueError,
+ AtomicComparator::ComparisonType comparisonType, ReportContext::ErrorCode errorCode>
+bool ComparisonPlatform<TSubClass, issueError, comparisonType, errorCode>::
+compare(const Item &oand1,
+ const Item &oand2,
+ const AtomicComparator::Ptr &comp,
+ const AtomicComparator::Operator op) const
+{
+ Q_ASSERT(oand1);
+ Q_ASSERT(oand2);
+ Q_ASSERT(comp);
+
+ switch(op)
+ {
+ case AtomicComparator::OperatorEqual:
+ return comp->equals(oand1, oand2);
+ case AtomicComparator::OperatorNotEqual:
+ return !comp->equals(oand1, oand2);
+ case AtomicComparator::OperatorLessThanNaNLeast:
+ case AtomicComparator::OperatorLessThanNaNGreatest:
+ /* Fallthrough. */
+ case AtomicComparator::OperatorLessThan:
+ return comp->compare(oand1, op, oand2) == AtomicComparator::LessThan;
+ case AtomicComparator::OperatorGreaterThan:
+ return comp->compare(oand1, op, oand2) == AtomicComparator::GreaterThan;
+ case AtomicComparator::OperatorLessOrEqual:
+ {
+ const AtomicComparator::ComparisonResult ret = comp->compare(oand1, op, oand2);
+ return ret == AtomicComparator::LessThan || ret == AtomicComparator::Equal;
+ }
+ case(AtomicComparator::OperatorGreaterOrEqual):
+ {
+ const AtomicComparator::ComparisonResult ret = comp->compare(oand1, op, oand2);
+ return ret == AtomicComparator::GreaterThan || ret == AtomicComparator::Equal;
+ }
+ }
+
+ /* GCC unbarfer, this line should never be reached. */
+ Q_ASSERT(false);
+ return false;
+}
+
+template <typename TSubClass, bool issueError,
+ AtomicComparator::ComparisonType comparisonType, ReportContext::ErrorCode errorCode>
+AtomicComparator::Ptr ComparisonPlatform<TSubClass, issueError, comparisonType, errorCode>::
+fetchComparator(const ItemType::Ptr &t1,
+ const ItemType::Ptr &t2,
+ const ReportContext::Ptr &context) const
+{
+ Q_ASSERT(t1);
+ Q_ASSERT(t2);
+
+ if(*BuiltinTypes::xsAnyAtomicType == *t1 ||
+ *BuiltinTypes::xsAnyAtomicType == *t2 ||
+ *BuiltinTypes::item == *t1 ||
+ *BuiltinTypes::item == *t2 ||
+ *BuiltinTypes::numeric == *t1 ||
+ *BuiltinTypes::numeric == *t2 ||
+ *CommonSequenceTypes::Empty == *t1 ||
+ *CommonSequenceTypes::Empty == *t2)
+ {
+ /* The static type of(at least) one of the operands could not
+ * be narrowed further, so we do the operator
+ * lookup at runtime.
+ */
+ return AtomicComparator::Ptr();
+ }
+
+ const AtomicComparatorLocator::Ptr locator
+ (static_cast<const AtomicType *>(t1.data())->comparatorLocator());
+
+ if(!locator)
+ {
+ if(issueError)
+ {
+ context->error(QtXmlPatterns::tr("No comparisons can be done involving the type %1.")
+ .arg(formatType(context->namePool(), t1)),
+ errorCode, static_cast<const TSubClass *>(this)->actualReflection());
+ }
+ return AtomicComparator::Ptr();
+ }
+
+ const AtomicComparator::Ptr comp(static_cast<const AtomicType *>(t2.data())->accept(locator, operatorID(),
+ static_cast<const TSubClass *>(this)->actualReflection()));
+
+ if(comp)
+ return comp;
+ else if(issueError)
+ {
+ context->error(QtXmlPatterns::tr("Operator %1 is not available between atomic values of type %2 and %3.")
+ .arg(formatKeyword(AtomicComparator::displayName(operatorID(),
+ comparisonType)),
+ formatType(context->namePool(), t1),
+ formatType(context->namePool(), t2)),
+ errorCode, static_cast<const TSubClass *>(this)->actualReflection());
+ }
+
+ return AtomicComparator::Ptr();
+}
+
+template <typename TSubClass, bool issueError,
+ AtomicComparator::ComparisonType comparisonType, ReportContext::ErrorCode errorCode>
+void ComparisonPlatform<TSubClass, issueError, comparisonType, errorCode>::
+prepareComparison(const AtomicComparator::Ptr &c)
+{
+ m_comparator = c;
+}
+
diff --git a/src/xmlpatterns/expr/qcomparisonplatform_p.h b/src/xmlpatterns/expr/qcomparisonplatform_p.h
new file mode 100644
index 0000000..359e247
--- /dev/null
+++ b/src/xmlpatterns/expr/qcomparisonplatform_p.h
@@ -0,0 +1,208 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_ComparisonPlatform_H
+#define Patternist_ComparisonPlatform_H
+
+#include "qatomiccomparators_p.h"
+#include "qitem_p.h"
+#include "qcommonsequencetypes_p.h"
+#include "qdynamiccontext_p.h"
+#include "qbuiltintypes_p.h"
+#include "qitemtype_p.h"
+#include "qpatternistlocale_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Provides comparison functionality for classes that compare Items,
+ * such as ValueComparison or MaxFN.
+ *
+ * Classes which need comparison functionalities should inherit from this class.
+ *
+ * The parameter of this template class is the class inheriting from ComparisonPlatform.
+ *
+ * The class inheriting ComparisonPlatform must implement the following function:
+ * @code
+ * AtomicComparator::Operator operatorID() const
+ * @endcode
+ *
+ * @author Vincent Ricard <magic@magicninja.org>
+ * @ingroup Patternist_expressions
+ */
+ template <typename TSubClass,
+ bool issueError,
+ AtomicComparator::ComparisonType comparisonType = AtomicComparator::AsValueComparison,
+ ReportContext::ErrorCode errorCode = ReportContext::XPTY0004>
+ class ComparisonPlatform
+ {
+ protected:
+ /**
+ * Makes ComparisonPlatform use the AtomicComparator @p comparator.
+ */
+ void prepareComparison(const AtomicComparator::Ptr &comparator);
+
+ /**
+ * Default constructor. Does nothing. It is implemented in order make template
+ * instantiation easier.
+ */
+ inline ComparisonPlatform()
+ {
+ }
+
+ /**
+ * Utility function for fetching the appropriate AtomicComparator
+ * for two atomic values of type @p type1 and @p type2, for the operator @p op.
+ *
+ * This function is used throughout the implementation, ranging from the ValueComparison
+ * itself, to for example the aggregate functions.
+ *
+ * @param context the ordinary ReportContext, used for issuing errors.
+ * @param type1 the type of the first operand value in a comparison for which the
+ * returned AtomicComparator is intended for
+ * @param type2 the type of the second operand value in a comparison for which the
+ * returned AtomicComparator is intended for. Whether @p type1 and @p type2 corresponds
+ * to what is the first second operand type does not have significance, the order
+ * can be arbitrary
+ */
+ AtomicComparator::Ptr
+ fetchComparator(const ItemType::Ptr &type1,
+ const ItemType::Ptr &type2,
+ const ReportContext::Ptr &context) const;
+
+ /**
+ * @short Compares @p i1 and @p i2 with operator @p op, using comparator @p
+ * comp. All input arguments must be valid, and not @c null.
+ *
+ * This is a fast, raw function which has the requirement that the
+ * caller knows what to compare and with what.
+ */
+ bool compare(const Item &i1,
+ const Item &i2,
+ const AtomicComparator::Ptr &comp,
+ const AtomicComparator::Operator op) const;
+
+ /**
+ * @short Compares @p it1 against @p it2, using comparator() and operatorID().
+ *
+ * If the comparator wasn't looked up at compile time, it will be
+ * attempted before comparing. If this fails, errors are reported via
+ * @p context.
+ */
+ bool
+ flexibleCompare(const Item &it1,
+ const Item &it2,
+ const DynamicContext::Ptr &context) const;
+
+ /**
+ * @short like flexibleCompare(), but returns the result
+ * as an AtomicComparator::Operator instead of @c bool.
+ *
+ * This is useful when it is significant how a less than comparison
+ * fails; whether the two values are equal or greater than.
+ */
+ AtomicComparator::ComparisonResult
+ detailedFlexibleCompare(const Item &it1,
+ const Item &it2,
+ const DynamicContext::Ptr &context) const;
+
+ /**
+ * @returns the AtomicComparator that has been allocated at compile time,
+ * with prepareComparison(). If no AtomicComparator has been allocated
+ * for some reason, this function returns @c null.
+ */
+ inline const AtomicComparator::Ptr &comparator() const
+ {
+ return m_comparator;
+ }
+
+ /**
+ * Calling this function makes ComparisonPlatform use a comparator that
+ * compares strings case insensitively.
+ *
+ * @see ValueComparison::isCaseInsensitiveCompare()
+ */
+ inline void useCaseInsensitiveComparator()
+ {
+ m_comparator = AtomicComparator::Ptr(new CaseInsensitiveStringComparator());
+ }
+
+ private:
+ /**
+ * @returns the operator that is used.
+ */
+ inline AtomicComparator::Operator operatorID() const
+ {
+ Q_ASSERT(static_cast<const TSubClass *>(this)->operatorID());
+ return static_cast<const TSubClass *>(this)->operatorID();
+ }
+
+ /**
+ * The comparator that is used for comparing atomic values. The AtomicComparator
+ * that is used, depends on the static type of the operands. m_comparator can be
+ * @c null if it wasn't possible to determine what comparator to use at compile time.
+ */
+ AtomicComparator::Ptr m_comparator;
+ };
+
+#include "qcomparisonplatform.cpp"
+
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/expr/qcomputednamespaceconstructor.cpp b/src/xmlpatterns/expr/qcomputednamespaceconstructor.cpp
new file mode 100644
index 0000000..6eb0c0e
--- /dev/null
+++ b/src/xmlpatterns/expr/qcomputednamespaceconstructor.cpp
@@ -0,0 +1,136 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qanyuri_p.h"
+#include "qbuiltintypes_p.h"
+#include "qcommonsequencetypes_p.h"
+#include "qpatternistlocale_p.h"
+#include "private/qxmlutils_p.h"
+
+#include "qcomputednamespaceconstructor_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+ComputedNamespaceConstructor::ComputedNamespaceConstructor(const Expression::Ptr &prefix,
+ const Expression::Ptr &namespaceURI) : PairContainer(prefix, namespaceURI)
+{
+}
+
+void ComputedNamespaceConstructor::evaluateToSequenceReceiver(const DynamicContext::Ptr &context) const
+{
+ const Item prefixItem(m_operand1->evaluateSingleton(context));
+ const QString prefix(prefixItem ? prefixItem.stringValue() : QString());
+
+ const Item namespaceItem(m_operand2->evaluateSingleton(context));
+ const QString namespaceURI(namespaceItem ? namespaceItem.stringValue() : QString());
+
+ if(namespaceURI.isEmpty())
+ {
+ context->error(QtXmlPatterns::tr("In a namespace constructor, the value for a namespace cannot be an empty string."),
+ ReportContext::XTDE0930,
+ this);
+ }
+
+ /* One optimization could be to store a pointer to
+ * the name pool as a member in order to avoid the virtual call(s). */
+ const NamePool::Ptr np(context->namePool());
+
+ if(!prefix.isEmpty() && !QXmlUtils::isNCName(prefix))
+ {
+ context->error(QtXmlPatterns::tr("The prefix must be a valid %1, which %2 is not.")
+ .arg(formatType(np, BuiltinTypes::xsNCName),
+ formatKeyword(prefix)),
+ ReportContext::XTDE0920,
+ this);
+ }
+ const QXmlName binding(np->allocateBinding(prefix, namespaceURI));
+
+ AnyURI::toQUrl<ReportContext::XTDE0905, DynamicContext::Ptr>(namespaceURI,
+ context,
+ this);
+
+ if(binding.prefix() == StandardPrefixes::xmlns)
+ {
+ context->error(QtXmlPatterns::tr("The prefix %1 cannot be bound.")
+ .arg(formatKeyword(prefix)),
+ ReportContext::XTDE0920,
+ this);
+ }
+
+ if((binding.prefix() == StandardPrefixes::xml && binding.namespaceURI() != StandardNamespaces::xml)
+ ||
+ (binding.prefix() != StandardPrefixes::xml && binding.namespaceURI() == StandardNamespaces::xml))
+ {
+ context->error(QtXmlPatterns::tr("Only the prefix %1 can be bound to %2 and vice versa.")
+ .arg(formatKeyword(prefix), formatKeyword(namespaceURI)),
+ ReportContext::XTDE0925,
+ this);
+ }
+
+ context->outputReceiver()->namespaceBinding(binding);
+}
+
+SequenceType::Ptr ComputedNamespaceConstructor::staticType() const
+{
+ return CommonSequenceTypes::ExactlyOneAttribute;
+}
+
+SequenceType::List ComputedNamespaceConstructor::expectedOperandTypes() const
+{
+ SequenceType::List result;
+ result.append(CommonSequenceTypes::ZeroOrOneString);
+ result.append(CommonSequenceTypes::ZeroOrOneString);
+ return result;
+}
+
+Expression::Properties ComputedNamespaceConstructor::properties() const
+{
+ return DisableElimination | IsNodeConstructor;
+}
+
+ExpressionVisitorResult::Ptr ComputedNamespaceConstructor::accept(const ExpressionVisitor::Ptr &visitor) const
+{
+ return visitor->visit(this);
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/expr/qcomputednamespaceconstructor_p.h b/src/xmlpatterns/expr/qcomputednamespaceconstructor_p.h
new file mode 100644
index 0000000..3950052
--- /dev/null
+++ b/src/xmlpatterns/expr/qcomputednamespaceconstructor_p.h
@@ -0,0 +1,102 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_ComputedNamespaceConstructor_H
+#define Patternist_ComputedNamespaceConstructor_H
+
+#include "qpaircontainer_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Constructs a namespace on an element, and naturally only appears
+ * as a child of ElementConstructor.
+ *
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_expressions
+ * @since 4.5
+ */
+ class ComputedNamespaceConstructor : public PairContainer
+ {
+ public:
+ ComputedNamespaceConstructor(const Expression::Ptr &prefix,
+ const Expression::Ptr &namespaceURI);
+
+ virtual void evaluateToSequenceReceiver(const DynamicContext::Ptr &context) const;
+
+ /**
+ * @returns a list containing one CommonSequenceTypes::ExactlyOneString instance.
+ */
+ virtual SequenceType::List expectedOperandTypes() const;
+
+ /**
+ * The static type is exactly one attribute node. It's unclear what
+ * affects the static type has, but specifying anything else could lead
+ * to complications wrt. node order, XQTY0024. Of course, it's not
+ * conceptually correct, since a namespace node isn't an attribute
+ * node.
+ */
+ virtual SequenceType::Ptr staticType() const;
+
+ virtual ExpressionVisitorResult::Ptr accept(const ExpressionVisitor::Ptr &visitor) const;
+ virtual Expression::Properties properties() const;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/expr/qcontextitem.cpp b/src/xmlpatterns/expr/qcontextitem.cpp
new file mode 100644
index 0000000..caa6653
--- /dev/null
+++ b/src/xmlpatterns/expr/qcontextitem.cpp
@@ -0,0 +1,114 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qbuiltintypes_p.h"
+#include "qcommonsequencetypes_p.h"
+#include "qgenericsequencetype_p.h"
+
+#include "qcontextitem_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+Item ContextItem::evaluateSingleton(const DynamicContext::Ptr &context) const
+{
+ return context->contextItem();
+}
+
+Expression::Ptr ContextItem::compress(const StaticContext::Ptr &context)
+{
+ m_itemType = context->contextItemType();
+ return EmptyContainer::compress(context);
+}
+
+Expression::Ptr ContextItem::typeCheck(const StaticContext::Ptr &context,
+ const SequenceType::Ptr &reqType)
+{
+ m_itemType = context->contextItemType();
+ return EmptyContainer::typeCheck(context, reqType);
+}
+
+SequenceType::Ptr ContextItem::staticType() const
+{
+ /* We test m_itemType here because Patternist View calls staticType() before the typeCheck()
+ * stage. */
+ if(m_itemType)
+ return makeGenericSequenceType(m_itemType, Cardinality::exactlyOne());
+ else
+ return CommonSequenceTypes::ExactlyOneItem;
+}
+
+Expression::Properties ContextItem::properties() const
+{
+ return DisableElimination | RequiresContextItem | EvaluationCacheRedundant;
+}
+
+ExpressionVisitorResult::Ptr ContextItem::accept(const ExpressionVisitor::Ptr &visitor) const
+{
+ return visitor->visit(this);
+}
+
+Expression::ID ContextItem::id() const
+{
+ return IDContextItem;
+}
+
+ItemType::Ptr ContextItem::expectedContextItemType() const
+{
+ return BuiltinTypes::item;
+}
+
+const SourceLocationReflection *ContextItem::actualReflection() const
+{
+ if(m_expr)
+ return m_expr.data();
+ else
+ return this;
+}
+
+void ContextItem::announceFocusType(const ItemType::Ptr &type)
+{
+ Q_ASSERT(type);
+ m_itemType = type;
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/expr/qcontextitem_p.h b/src/xmlpatterns/expr/qcontextitem_p.h
new file mode 100644
index 0000000..e3ae81e
--- /dev/null
+++ b/src/xmlpatterns/expr/qcontextitem_p.h
@@ -0,0 +1,128 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_ContextItem_H
+#define Patternist_ContextItem_H
+
+#include "qemptycontainer_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Implements the context item, the dot: <tt>.</tt>.
+ *
+ * @see <a href="http://www.w3.org/TR/xpath20/#id-context-item-expression">XML Path Language
+ * (XPath) 2.0, 3.1.4 Context Item Expression</a>
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_expressions
+ */
+ class ContextItem : public EmptyContainer
+ {
+ public:
+ /**
+ * @p expr is possibly used for error reporting. If this context item has been
+ * created implicitly, such as for the expression <tt>fn:string()</tt>, @p expr
+ * should be passed a valid pointer to the Expression that this context
+ * item is generated for.
+ */
+ inline ContextItem(const Expression::Ptr &expr = Expression::Ptr()) : m_expr(expr)
+ {
+ }
+
+ virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const;
+ virtual SequenceType::Ptr staticType() const;
+
+ /**
+ * @returns always DisableElimination and RequiresContextItem
+ */
+ virtual Expression::Properties properties() const;
+
+ virtual ExpressionVisitorResult::Ptr accept(const ExpressionVisitor::Ptr &visitor) const;
+
+ /**
+ * Overridden to store a pointer to StaticContext::contextItemType().
+ */
+ virtual Expression::Ptr compress(const StaticContext::Ptr &context);
+
+ /**
+ * Overridden to store a pointer to StaticContext::contextItemType().
+ */
+ virtual Expression::Ptr typeCheck(const StaticContext::Ptr &context,
+ const SequenceType::Ptr &reqType);
+
+ /**
+ * @returns always IDContextItem
+ */
+ virtual ID id() const;
+
+ /**
+ * @returns always BuiltinTypes::item;
+ */
+ virtual ItemType::Ptr expectedContextItemType() const;
+
+ virtual const SourceLocationReflection *actualReflection() const;
+ virtual void announceFocusType(const ItemType::Ptr &type);
+
+ private:
+ ItemType::Ptr m_itemType;
+ const Expression::Ptr m_expr;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/expr/qcopyof.cpp b/src/xmlpatterns/expr/qcopyof.cpp
new file mode 100644
index 0000000..ddb5a2c
--- /dev/null
+++ b/src/xmlpatterns/expr/qcopyof.cpp
@@ -0,0 +1,134 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qbuiltintypes_p.h"
+#include "qcommonsequencetypes_p.h"
+#include "qitemmappingiterator_p.h"
+
+#include "qcopyof_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+CopyOf::CopyOf(const Expression::Ptr &operand,
+ const bool inheritNSS,
+ const bool preserveNSS) : SingleContainer(operand)
+ , m_inheritNamespaces(inheritNSS)
+ , m_preserveNamespaces(preserveNSS)
+ , m_settings((m_inheritNamespaces ? QAbstractXmlNodeModel::InheritNamespaces : QAbstractXmlNodeModel::NodeCopySettings()) |
+ (m_preserveNamespaces ? QAbstractXmlNodeModel::PreserveNamespaces : QAbstractXmlNodeModel::NodeCopySettings()))
+{
+}
+
+Expression::Ptr CopyOf::compress(const StaticContext::Ptr &context)
+{
+ /* We have zero effect if we have these settings. */
+ if(m_inheritNamespaces && m_preserveNamespaces)
+ return m_operand->compress(context);
+ else
+ {
+ const ItemType::Ptr t(m_operand->staticType()->itemType());
+ /* We have no effect on the empty sequence or atomic values. */
+ if(BuiltinTypes::xsAnyAtomicType->xdtTypeMatches(t)
+ || *t == *CommonSequenceTypes::Empty)
+ return m_operand->compress(context);
+ else
+ return SingleContainer::compress(context);
+ }
+}
+
+void CopyOf::evaluateToSequenceReceiver(const DynamicContext::Ptr &context) const
+{
+ /* Optimization: this completely breaks streaming. We get a call to
+ * evaluateToSequenceReceiver() but we require heap allocations by calling
+ * evaluateSequence(). */
+
+ const Item::Iterator::Ptr it(m_operand->evaluateSequence(context));
+ QAbstractXmlReceiver *const receiver = context->outputReceiver();
+ Item next(it->next());
+
+ while(next)
+ {
+ if(next.isNode())
+ {
+ const QXmlNodeModelIndex &asNode = next.asNode();
+ asNode.model()->copyNodeTo(asNode, receiver, m_settings);
+ }
+ else
+ receiver->item(next);
+
+ next = it->next();
+ }
+}
+
+ExpressionVisitorResult::Ptr CopyOf::accept(const ExpressionVisitor::Ptr &visitor) const
+{
+ return visitor->visit(this);
+}
+
+SequenceType::Ptr CopyOf::staticType() const
+{
+ return m_operand->staticType();
+}
+
+SequenceType::List CopyOf::expectedOperandTypes() const
+{
+ SequenceType::List result;
+ result.append(CommonSequenceTypes::ZeroOrMoreItems);
+ return result;
+}
+
+Expression::Properties CopyOf::properties() const
+{
+ /* We have the content of node constructors as children, but even though
+ * createCopyOf() typically avoids creating us, we can still end up with an operand
+ * that allows compression. We must always avoid that, because we don't have
+ * implementation of evaluateSequence(), and so on. */
+ return (m_operand->properties() & ~CreatesFocusForLast) | DisableElimination;
+}
+
+ItemType::Ptr CopyOf::expectedContextItemType() const
+{
+ return m_operand->expectedContextItemType();
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/expr/qcopyof_p.h b/src/xmlpatterns/expr/qcopyof_p.h
new file mode 100644
index 0000000..7a89b69
--- /dev/null
+++ b/src/xmlpatterns/expr/qcopyof_p.h
@@ -0,0 +1,121 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_CopyOf_H
+#define Patternist_CopyOf_H
+
+#include "qsinglecontainer_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Does node copying in a parameterized way, in order to deal with
+ * namespace preservation/inheritance.
+ *
+ * If someone tries to call evaluateEBV(), evaluateSingleton() or
+ * evaluateSequence() on us, we will infinitely loop. But apparently
+ * that's not possible because we're always a child of ElementConstructor,
+ * currently.
+ *
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_expressions
+ */
+ class CopyOf : public SingleContainer
+ {
+ public:
+ /**
+ * Creats a CopyOf where it is checked that the expression @p operand conforms
+ * to the type @p reqType.
+ */
+ CopyOf(const Expression::Ptr &operand,
+ const bool inheritNSS,
+ const bool preserveNSS);
+
+ virtual void evaluateToSequenceReceiver(const DynamicContext::Ptr &context) const;
+
+ /**
+ * @returns always the SequenceType passed in the constructor to this class. That is, the
+ * SequenceType that the operand must conform to.
+ */
+ virtual SequenceType::Ptr staticType() const;
+
+ /**
+ * @returns a list containing one CommonSequenceTypes::ZeroOrMoreItems
+ */
+ virtual SequenceType::List expectedOperandTypes() const;
+
+ virtual ExpressionVisitorResult::Ptr accept(const ExpressionVisitor::Ptr &visitor) const;
+
+ inline Item mapToItem(const Item &source,
+ const DynamicContext::Ptr &context) const;
+
+ virtual Expression::Ptr compress(const StaticContext::Ptr &context);
+
+ virtual Properties properties() const;
+ virtual ItemType::Ptr expectedContextItemType() const;
+
+ private:
+ typedef QExplicitlySharedDataPointer<const CopyOf> ConstPtr;
+ const bool m_inheritNamespaces;
+ const bool m_preserveNamespaces;
+ const QAbstractXmlNodeModel::NodeCopySettings m_settings;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/expr/qcurrentitemstore.cpp b/src/xmlpatterns/expr/qcurrentitemstore.cpp
new file mode 100644
index 0000000..0bfab8b
--- /dev/null
+++ b/src/xmlpatterns/expr/qcurrentitemstore.cpp
@@ -0,0 +1,139 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qbuiltintypes_p.h"
+#include "qcommonsequencetypes_p.h"
+#include "qcurrentitemcontext_p.h"
+#include "qstaticcurrentcontext_p.h"
+
+#include "qcurrentitemstore_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+CurrentItemStore::CurrentItemStore(const Expression::Ptr &operand) : SingleContainer(operand)
+{
+}
+
+DynamicContext::Ptr CurrentItemStore::createContext(const DynamicContext::Ptr &old) const
+{
+ return DynamicContext::Ptr(new CurrentItemContext(old->contextItem(), old));
+}
+
+bool CurrentItemStore::evaluateEBV(const DynamicContext::Ptr &context) const
+{
+ return m_operand->evaluateEBV(createContext(context));
+}
+
+Item::Iterator::Ptr CurrentItemStore::evaluateSequence(const DynamicContext::Ptr &context) const
+{
+ return m_operand->evaluateSequence(createContext(context));
+}
+
+Item CurrentItemStore::evaluateSingleton(const DynamicContext::Ptr &context) const
+{
+ return m_operand->evaluateSingleton(createContext(context));
+}
+
+SequenceType::Ptr CurrentItemStore::staticType() const
+{
+ return m_operand->staticType();
+}
+
+SequenceType::List CurrentItemStore::expectedOperandTypes() const
+{
+ SequenceType::List result;
+ result.append(CommonSequenceTypes::ZeroOrMoreItems);
+ return result;
+}
+
+StaticContext::Ptr CurrentItemStore::newStaticContext(const StaticContext::Ptr &context)
+{
+ /* It might be we are generated despite there is no focus. In that case
+ * an error will reported in case current() is used, but in any case we cannot
+ * crash, so use item() in case we have no focus.
+ *
+ * Such a case is when we're inside a named template, and it's invoked
+ * without focus. */
+ const ItemType::Ptr t(context->contextItemType());
+ return StaticContext::Ptr(new StaticCurrentContext(t ? t : BuiltinTypes::item, context));
+}
+
+Expression::Ptr CurrentItemStore::compress(const StaticContext::Ptr &context)
+{
+ const Expression::Ptr me(SingleContainer::compress(newStaticContext(context)));
+
+ if(me != this)
+ return me;
+ else
+ {
+ /* If fn:current() isn't called, there's no point in us sticking
+ * around. */
+ if(m_operand->deepProperties().testFlag(RequiresCurrentItem))
+ return me;
+ else
+ return m_operand;
+ }
+}
+
+Expression::Ptr CurrentItemStore::typeCheck(const StaticContext::Ptr &context,
+ const SequenceType::Ptr &reqType)
+{
+ return SingleContainer::typeCheck(newStaticContext(context), reqType);
+}
+
+ExpressionVisitorResult::Ptr CurrentItemStore::accept(const ExpressionVisitor::Ptr &visitor) const
+{
+ return visitor->visit(this);
+}
+
+const SourceLocationReflection *CurrentItemStore::actualReflection() const
+{
+ return m_operand->actualReflection();
+}
+
+Expression::Properties CurrentItemStore::properties() const
+{
+ return m_operand->properties() & (RequiresFocus | IsEvaluated | DisableElimination);
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/expr/qcurrentitemstore_p.h b/src/xmlpatterns/expr/qcurrentitemstore_p.h
new file mode 100644
index 0000000..f7cc5d8
--- /dev/null
+++ b/src/xmlpatterns/expr/qcurrentitemstore_p.h
@@ -0,0 +1,104 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_CurrentItemStore_H
+#define Patternist_CurrentItemStore_H
+
+#include "qsinglecontainer_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Creates a DynamicContext which provides the focus item for the
+ * function @c fn:current().
+ *
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_expressions
+ * @since 4.5
+ */
+ class CurrentItemStore : public SingleContainer
+ {
+ public:
+ CurrentItemStore(const Expression::Ptr &operand);
+
+ virtual bool evaluateEBV(const DynamicContext::Ptr &) const;
+ virtual Item::Iterator::Ptr evaluateSequence(const DynamicContext::Ptr &) const;
+ virtual Item evaluateSingleton(const DynamicContext::Ptr &) const;
+
+ virtual SequenceType::List expectedOperandTypes() const;
+ virtual Expression::Ptr compress(const StaticContext::Ptr &context);
+ virtual Expression::Ptr typeCheck(const StaticContext::Ptr &context,
+ const SequenceType::Ptr &reqType);
+
+ virtual Properties properties() const;
+
+ /**
+ * @returns the staticType() of its operand.
+ */
+ virtual SequenceType::Ptr staticType() const;
+ virtual ExpressionVisitorResult::Ptr accept(const ExpressionVisitor::Ptr &visitor) const;
+ virtual const SourceLocationReflection *actualReflection() const;
+
+ private:
+ static inline StaticContext::Ptr newStaticContext(const StaticContext::Ptr &context);
+ inline DynamicContext::Ptr createContext(const DynamicContext::Ptr &old) const;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/expr/qdocumentconstructor.cpp b/src/xmlpatterns/expr/qdocumentconstructor.cpp
new file mode 100644
index 0000000..9dfbe09
--- /dev/null
+++ b/src/xmlpatterns/expr/qdocumentconstructor.cpp
@@ -0,0 +1,116 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qcommonsequencetypes_p.h"
+#include "qdocumentcontentvalidator_p.h"
+#include "qnodebuilder_p.h"
+
+#include "qdocumentconstructor_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+DocumentConstructor::DocumentConstructor(const Expression::Ptr &op) : SingleContainer(op)
+{
+}
+
+Item DocumentConstructor::evaluateSingleton(const DynamicContext::Ptr &context) const
+{
+ NodeBuilder::Ptr nodeBuilder(context->nodeBuilder(m_staticBaseURI));
+
+ DocumentContentValidator validator(nodeBuilder.data(), context, ConstPtr(this));
+ const DynamicContext::Ptr receiverContext(context->createReceiverContext(&validator));
+
+ validator.startDocument();
+ m_operand->evaluateToSequenceReceiver(receiverContext);
+ validator.endDocument();
+
+ const QAbstractXmlNodeModel::Ptr nm(nodeBuilder->builtDocument());
+ context->addNodeModel(nm);
+
+ return nm->root(QXmlNodeModelIndex());
+}
+
+void DocumentConstructor::evaluateToSequenceReceiver(const DynamicContext::Ptr &context) const
+{
+ QAbstractXmlReceiver *const receiver = context->outputReceiver();
+
+ DocumentContentValidator validator(receiver, context, ConstPtr(this));
+
+ const DynamicContext::Ptr receiverContext(context->createReceiverContext(&validator));
+
+ validator.startDocument();
+ m_operand->evaluateToSequenceReceiver(receiverContext);
+ validator.endDocument();
+}
+
+Expression::Ptr DocumentConstructor::typeCheck(const StaticContext::Ptr &context,
+ const SequenceType::Ptr &reqType)
+{
+ m_staticBaseURI = context->baseURI();
+ return SingleContainer::typeCheck(context, reqType);
+}
+
+SequenceType::Ptr DocumentConstructor::staticType() const
+{
+ return CommonSequenceTypes::ExactlyOneDocumentNode;
+}
+
+SequenceType::List DocumentConstructor::expectedOperandTypes() const
+{
+ SequenceType::List result;
+ result.append(CommonSequenceTypes::ZeroOrMoreItems);
+ return result;
+}
+
+Expression::Properties DocumentConstructor::properties() const
+{
+ return DisableElimination | IsNodeConstructor;
+}
+
+ExpressionVisitorResult::Ptr
+DocumentConstructor::accept(const ExpressionVisitor::Ptr &visitor) const
+{
+ return visitor->visit(this);
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/expr/qdocumentconstructor_p.h b/src/xmlpatterns/expr/qdocumentconstructor_p.h
new file mode 100644
index 0000000..8b685f9
--- /dev/null
+++ b/src/xmlpatterns/expr/qdocumentconstructor_p.h
@@ -0,0 +1,103 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_DocumentConstructor_H
+#define Patternist_DocumentConstructor_H
+
+#include <QUrl>
+
+#include "qsinglecontainer_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Constructs a text node. This covers both computed and directly constructed
+ * text nodes.
+ *
+ * @see <a href="http://www.w3.org/TR/xquery/#id-constructors">XQuery
+ * 1.0: An XML Query Language, 3.7 Constructors</a>
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_expressions
+ */
+ class DocumentConstructor : public SingleContainer
+ {
+ public:
+ DocumentConstructor(const Expression::Ptr &operand);
+
+ virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const;
+ virtual void evaluateToSequenceReceiver(const DynamicContext::Ptr &context) const;
+
+ /**
+ * The first operand must be exactly one @c xs:string.
+ */
+ virtual SequenceType::List expectedOperandTypes() const;
+
+ virtual ExpressionVisitorResult::Ptr accept(const ExpressionVisitor::Ptr &visitor) const;
+ virtual Expression::Ptr typeCheck(const StaticContext::Ptr &context,
+ const SequenceType::Ptr &reqType);
+
+ virtual Properties properties() const;
+ virtual SequenceType::Ptr staticType() const;
+
+ private:
+ QUrl m_staticBaseURI;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/expr/qdocumentcontentvalidator.cpp b/src/xmlpatterns/expr/qdocumentcontentvalidator.cpp
new file mode 100644
index 0000000..75e9ae6
--- /dev/null
+++ b/src/xmlpatterns/expr/qdocumentcontentvalidator.cpp
@@ -0,0 +1,148 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qpatternistlocale_p.h"
+
+#include "qdocumentcontentvalidator_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+DocumentContentValidator::
+DocumentContentValidator(QAbstractXmlReceiver *const receiver,
+ const DynamicContext::Ptr &context,
+ const Expression::ConstPtr &expr) : m_receiver(receiver)
+ , m_context(context)
+ , m_expr(expr)
+ , m_elementDepth(0)
+{
+ Q_ASSERT(receiver);
+ Q_ASSERT(m_expr);
+ Q_ASSERT(context);
+}
+
+void DocumentContentValidator::namespaceBinding(const QXmlName &nb)
+{
+ m_receiver->namespaceBinding(nb);
+}
+
+void DocumentContentValidator::startElement(const QXmlName &name)
+{
+ ++m_elementDepth;
+ m_receiver->startElement(name);
+}
+
+void DocumentContentValidator::endElement()
+{
+ Q_ASSERT(m_elementDepth > 0);
+ --m_elementDepth;
+ m_receiver->endElement();
+}
+
+void DocumentContentValidator::attribute(const QXmlName &name,
+ const QStringRef &value)
+{
+ if(m_elementDepth == 0)
+ {
+ m_context->error(QtXmlPatterns::tr("An attribute node cannot be a "
+ "child of a document node. "
+ "Therefore, the attribute %1 "
+ "is out of place.")
+ .arg(formatKeyword(m_context->namePool(), name)),
+ ReportContext::XPTY0004, m_expr.data());
+ }
+ else
+ m_receiver->attribute(name, value);
+}
+
+void DocumentContentValidator::comment(const QString &value)
+{
+ m_receiver->comment(value);
+}
+
+void DocumentContentValidator::characters(const QStringRef &value)
+{
+ m_receiver->characters(value);
+}
+
+void DocumentContentValidator::processingInstruction(const QXmlName &name,
+ const QString &value)
+{
+ m_receiver->processingInstruction(name, value);
+}
+
+void DocumentContentValidator::item(const Item &outputItem)
+{
+ /* We can't send outputItem directly to m_receiver since its item() function
+ * won't dispatch to this DocumentContentValidator, but to itself. We're not sub-classing here,
+ * we're delegating. */
+
+ if(outputItem.isNode())
+ sendAsNode(outputItem);
+ else
+ m_receiver->item(outputItem);
+}
+
+void DocumentContentValidator::startDocument()
+{
+ m_receiver->startDocument();
+}
+
+void DocumentContentValidator::endDocument()
+{
+ m_receiver->endDocument();
+}
+
+void DocumentContentValidator::atomicValue(const QVariant &value)
+{
+ Q_UNUSED(value);
+}
+
+void DocumentContentValidator::startOfSequence()
+{
+}
+
+void DocumentContentValidator::endOfSequence()
+{
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/expr/qdocumentcontentvalidator_p.h b/src/xmlpatterns/expr/qdocumentcontentvalidator_p.h
new file mode 100644
index 0000000..92bee3f
--- /dev/null
+++ b/src/xmlpatterns/expr/qdocumentcontentvalidator_p.h
@@ -0,0 +1,117 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_DocumentContentValidator_H
+#define Patternist_DocumentContentValidator_H
+
+#include "qdynamiccontext_p.h"
+#include "qexpression_p.h"
+#include "qabstractxmlreceiver.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Receives QAbstractXmlReceiver events and validates that they are correct,
+ * before sending them on to a second QAbstractXmlReceiver.
+ *
+ * @ingroup Patternist_xdm
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @todo Escape data
+ */
+ class DocumentContentValidator : public QAbstractXmlReceiver
+ {
+ public:
+ /**
+ * DocumentContentValidator does not own @p receiver.
+ */
+ DocumentContentValidator(QAbstractXmlReceiver *const receiver,
+ const DynamicContext::Ptr &context,
+ const Expression::ConstPtr &expr);
+
+ virtual void namespaceBinding(const QXmlName &nb);
+ virtual void characters(const QStringRef &value);
+ virtual void comment(const QString &value);
+
+ virtual void startElement(const QXmlName &name);
+
+ virtual void endElement();
+
+ virtual void attribute(const QXmlName &name,
+ const QStringRef &value);
+
+ virtual void processingInstruction(const QXmlName &name,
+ const QString &value);
+
+ virtual void item(const Item &item);
+
+ virtual void startDocument();
+ virtual void endDocument();
+ virtual void atomicValue(const QVariant &value);
+ virtual void startOfSequence();
+ virtual void endOfSequence();
+
+ private:
+ QAbstractXmlReceiver *const m_receiver;
+ const DynamicContext::Ptr m_context;
+ const Expression::ConstPtr m_expr;
+ xsInteger m_elementDepth;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/expr/qdynamiccontextstore.cpp b/src/xmlpatterns/expr/qdynamiccontextstore.cpp
new file mode 100644
index 0000000..762b7d6
--- /dev/null
+++ b/src/xmlpatterns/expr/qdynamiccontextstore.cpp
@@ -0,0 +1,96 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qboolean_p.h"
+#include "qcommonsequencetypes_p.h"
+#include "qcommonvalues_p.h"
+
+#include "qdynamiccontextstore_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+DynamicContextStore::DynamicContextStore(const Expression::Ptr &operand,
+ const DynamicContext::Ptr &context) : SingleContainer(operand),
+ m_context(context)
+{
+ Q_ASSERT(context);
+}
+
+bool DynamicContextStore::evaluateEBV(const DynamicContext::Ptr &) const
+{
+ return m_operand->evaluateEBV(m_context);
+}
+
+Item::Iterator::Ptr DynamicContextStore::evaluateSequence(const DynamicContext::Ptr &) const
+{
+ return m_operand->evaluateSequence(m_context);
+}
+
+Item DynamicContextStore::evaluateSingleton(const DynamicContext::Ptr &) const
+{
+ return m_operand->evaluateSingleton(m_context);
+}
+
+SequenceType::Ptr DynamicContextStore::staticType() const
+{
+ return m_operand->staticType();
+}
+
+SequenceType::List DynamicContextStore::expectedOperandTypes() const
+{
+ SequenceType::List result;
+ result.append(CommonSequenceTypes::ZeroOrMoreItems);
+ return result;
+}
+
+ExpressionVisitorResult::Ptr DynamicContextStore::accept(const ExpressionVisitor::Ptr &visitor) const
+{
+ return visitor->visit(this);
+}
+
+const SourceLocationReflection *DynamicContextStore::actualReflection() const
+{
+ return m_operand->actualReflection();
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/expr/qdynamiccontextstore_p.h b/src/xmlpatterns/expr/qdynamiccontextstore_p.h
new file mode 100644
index 0000000..1d5d035
--- /dev/null
+++ b/src/xmlpatterns/expr/qdynamiccontextstore_p.h
@@ -0,0 +1,97 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_DynamicContextStore_H
+#define Patternist_DynamicContextStore_H
+
+#include "qsinglecontainer_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Evaluates its operand with an assigned DynamicContext, not
+ * the one passed to one of the evaluation functions.
+ *
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_expressions
+ */
+ class DynamicContextStore : public SingleContainer
+ {
+ public:
+ DynamicContextStore(const Expression::Ptr &operand,
+ const DynamicContext::Ptr &context);
+
+ virtual bool evaluateEBV(const DynamicContext::Ptr &) const;
+ virtual Item::Iterator::Ptr evaluateSequence(const DynamicContext::Ptr &) const;
+ virtual Item evaluateSingleton(const DynamicContext::Ptr &) const;
+
+ virtual SequenceType::List expectedOperandTypes() const;
+ /**
+ * @returns the staticType() of its operand.
+ */
+ virtual SequenceType::Ptr staticType() const;
+ virtual ExpressionVisitorResult::Ptr accept(const ExpressionVisitor::Ptr &visitor) const;
+ virtual const SourceLocationReflection *actualReflection() const;
+
+ private:
+ const DynamicContext::Ptr m_context;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/expr/qelementconstructor.cpp b/src/xmlpatterns/expr/qelementconstructor.cpp
new file mode 100644
index 0000000..41f7b11
--- /dev/null
+++ b/src/xmlpatterns/expr/qelementconstructor.cpp
@@ -0,0 +1,160 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qcommonsequencetypes_p.h"
+#include "qdelegatingnamespaceresolver_p.h"
+#include "qnamespaceconstructor_p.h"
+#include "qnodebuilder_p.h"
+#include "qoutputvalidator_p.h"
+#include "qqnamevalue_p.h"
+#include "qstaticnamespacecontext_p.h"
+
+#include "qelementconstructor_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+ElementConstructor::ElementConstructor(const Expression::Ptr &op1,
+ const Expression::Ptr &op2,
+ const bool isXSLT) : PairContainer(op1, op2)
+ , m_isXSLT(isXSLT)
+{
+}
+
+Item ElementConstructor::evaluateSingleton(const DynamicContext::Ptr &context) const
+{
+ const Item name(m_operand1->evaluateSingleton(context));
+
+ const NodeBuilder::Ptr nodeBuilder(context->nodeBuilder(m_staticBaseURI));
+ OutputValidator validator(nodeBuilder.data(), context, this, m_isXSLT);
+
+ const DynamicContext::Ptr receiverContext(context->createReceiverContext(&validator));
+
+ nodeBuilder->startElement(name.as<QNameValue>()->qName());
+ m_operand2->evaluateToSequenceReceiver(receiverContext);
+ nodeBuilder->endElement();
+
+ const QAbstractXmlNodeModel::Ptr nm(nodeBuilder->builtDocument());
+ context->addNodeModel(nm);
+
+ return nm->root(QXmlNodeModelIndex());
+}
+
+void ElementConstructor::evaluateToSequenceReceiver(const DynamicContext::Ptr &context) const
+{
+ /* We create an OutputValidator here too. If we're serializing(a common
+ * case, unfortunately) the receiver is already validating in order to
+ * catch cases where a computed attribute constructor is followed by an
+ * element constructor, but in the cases where we're not serializing it's
+ * necessary that we validate in this step. */
+ const Item name(m_operand1->evaluateSingleton(context));
+ QAbstractXmlReceiver *const receiver = context->outputReceiver();
+
+ OutputValidator validator(receiver, context, this, m_isXSLT);
+ const DynamicContext::Ptr receiverContext(context->createReceiverContext(&validator));
+
+ receiver->startElement(name.as<QNameValue>()->qName());
+ m_operand2->evaluateToSequenceReceiver(receiverContext);
+ receiver->endElement();
+}
+
+Expression::Ptr ElementConstructor::typeCheck(const StaticContext::Ptr &context,
+ const SequenceType::Ptr &reqType)
+{
+ /* What does this code do? When type checking our children, our namespace
+ * bindings, which are also children of the form of NamespaceConstructor
+ * instances, must be statically in-scope for them, so find them and
+ * shuffle their bindings into the StaticContext. */
+
+ m_staticBaseURI = context->baseURI();
+
+ /* Namespace declarations changes the in-scope bindings, so let's
+ * first lookup our child NamespaceConstructors. */
+ const ID operandID = m_operand2->id();
+
+ NamespaceResolver::Bindings overrides;
+ if(operandID == IDExpressionSequence)
+ {
+ const Expression::List operands(m_operand2->operands());
+ const int len = operands.count();
+
+ for(int i = 0; i < len; ++i)
+ {
+ if(operands.at(i)->is(IDNamespaceConstructor))
+ {
+ const QXmlName &nb = operands.at(i)->as<NamespaceConstructor>()->namespaceBinding();
+ overrides.insert(nb.prefix(), nb.namespaceURI());
+ }
+ }
+ }
+
+ const NamespaceResolver::Ptr newResolver(new DelegatingNamespaceResolver(context->namespaceBindings(), overrides));
+ const StaticContext::Ptr augmented(new StaticNamespaceContext(newResolver, context));
+
+ return PairContainer::typeCheck(augmented, reqType);
+}
+
+SequenceType::Ptr ElementConstructor::staticType() const
+{
+ return CommonSequenceTypes::ExactlyOneElement;
+}
+
+SequenceType::List ElementConstructor::expectedOperandTypes() const
+{
+ SequenceType::List result;
+ result.append(CommonSequenceTypes::ExactlyOneQName);
+ result.append(CommonSequenceTypes::ZeroOrMoreItems);
+ return result;
+}
+
+Expression::Properties ElementConstructor::properties() const
+{
+ return DisableElimination | IsNodeConstructor;
+}
+
+ExpressionVisitorResult::Ptr
+ElementConstructor::accept(const ExpressionVisitor::Ptr &visitor) const
+{
+ return visitor->visit(this);
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/expr/qelementconstructor_p.h b/src/xmlpatterns/expr/qelementconstructor_p.h
new file mode 100644
index 0000000..55c18a2
--- /dev/null
+++ b/src/xmlpatterns/expr/qelementconstructor_p.h
@@ -0,0 +1,107 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_ElementConstructor_H
+#define Patternist_ElementConstructor_H
+
+#include <QUrl>
+
+#include "qpaircontainer_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Constructs an element node. This covers both computed and directly constructed
+ * element nodes.
+ *
+ * @see <a href="http://www.w3.org/TR/xquery/#id-constructors">XQuery
+ * 1.0: An XML Query Language, 3.7 Constructors</a>
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_expressions
+ */
+ class ElementConstructor : public PairContainer
+ {
+ public:
+ ElementConstructor(const Expression::Ptr &operand1,
+ const Expression::Ptr &operand2,
+ const bool isXSLT);
+
+ virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const;
+ virtual void evaluateToSequenceReceiver(const DynamicContext::Ptr &context) const;
+
+ virtual SequenceType::Ptr staticType() const;
+
+ /**
+ * The first operand must be exactly one @c xs:QName, and the second
+ * argument can be zero or more items.
+ */
+ virtual SequenceType::List expectedOperandTypes() const;
+
+ virtual ExpressionVisitorResult::Ptr accept(const ExpressionVisitor::Ptr &visitor) const;
+ virtual Expression::Ptr typeCheck(const StaticContext::Ptr &context,
+ const SequenceType::Ptr &reqType);
+ virtual Properties properties() const;
+
+ private:
+ QUrl m_staticBaseURI;
+ const bool m_isXSLT;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/expr/qemptycontainer.cpp b/src/xmlpatterns/expr/qemptycontainer.cpp
new file mode 100644
index 0000000..4681fc0
--- /dev/null
+++ b/src/xmlpatterns/expr/qemptycontainer.cpp
@@ -0,0 +1,69 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QList>
+
+#include "qemptycontainer_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+Expression::List EmptyContainer::operands() const
+{
+ return Expression::List();
+}
+
+SequenceType::List EmptyContainer::expectedOperandTypes() const
+{
+ return SequenceType::List();
+}
+
+void EmptyContainer::setOperands(const Expression::List &)
+{
+}
+
+bool EmptyContainer::compressOperands(const StaticContext::Ptr &)
+{
+ return true;
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/expr/qemptycontainer_p.h b/src/xmlpatterns/expr/qemptycontainer_p.h
new file mode 100644
index 0000000..d1eace6
--- /dev/null
+++ b/src/xmlpatterns/expr/qemptycontainer_p.h
@@ -0,0 +1,101 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_EmptyContainer_H
+#define Patternist_EmptyContainer_H
+
+#include "qexpression_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Base class for expressions that has no operands.
+ *
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_expressions
+ */
+ class Q_AUTOTEST_EXPORT EmptyContainer : public Expression
+ {
+ public:
+ /**
+ * @returns always an empty list.
+ */
+ virtual Expression::List operands() const;
+
+ /**
+ * Does nothing, since sub-classes has no operands. Calling
+ * it makes hence no sense, and it also results in an assert crash.
+ */
+ virtual void setOperands(const Expression::List &);
+
+ protected:
+ /**
+ * @returns always @c true
+ */
+ virtual bool compressOperands(const StaticContext::Ptr &context);
+
+ /**
+ * @returns always an empty list since it has no operands.
+ */
+ virtual SequenceType::List expectedOperandTypes() const;
+
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/expr/qemptysequence.cpp b/src/xmlpatterns/expr/qemptysequence.cpp
new file mode 100644
index 0000000..66b6381
--- /dev/null
+++ b/src/xmlpatterns/expr/qemptysequence.cpp
@@ -0,0 +1,112 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qcommonvalues_p.h"
+#include "qcommonsequencetypes_p.h"
+#include "qemptysequencetype_p.h"
+
+#include "qemptysequence_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+Expression::Ptr EmptySequence::create(const Expression *const replacementFor,
+ const StaticContext::Ptr &context)
+{
+ Q_ASSERT(replacementFor);
+ Q_ASSERT(context);
+
+ const Expression::Ptr retval(new EmptySequence());
+ context->wrapExpressionWith(replacementFor, retval);
+ return retval;
+}
+
+Item::Iterator::Ptr EmptySequence::evaluateSequence(const DynamicContext::Ptr &) const
+{
+ return CommonValues::emptyIterator;
+}
+
+Item EmptySequence::evaluateSingleton(const DynamicContext::Ptr &) const
+{
+ return Item();
+}
+
+void EmptySequence::evaluateToSequenceReceiver(const DynamicContext::Ptr &) const
+{
+}
+
+ItemType::Ptr EmptySequence::type() const
+{
+ return CommonSequenceTypes::Empty;
+}
+
+SequenceType::Ptr EmptySequence::staticType() const
+{
+ return CommonSequenceTypes::Empty;
+}
+
+bool EmptySequence::evaluateEBV(const DynamicContext::Ptr &) const
+{
+ return false;
+}
+
+QString EmptySequence::stringValue() const
+{
+ return QString();
+}
+
+ExpressionVisitorResult::Ptr EmptySequence::accept(const ExpressionVisitor::Ptr &visitor) const
+{
+ return visitor->visit(this);
+}
+
+Expression::ID EmptySequence::id() const
+{
+ return IDEmptySequence;
+}
+
+Expression::Properties EmptySequence::properties() const
+{
+ return IsEvaluated;
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/expr/qemptysequence_p.h b/src/xmlpatterns/expr/qemptysequence_p.h
new file mode 100644
index 0000000..d6a72a2
--- /dev/null
+++ b/src/xmlpatterns/expr/qemptysequence_p.h
@@ -0,0 +1,136 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_EmptySequence_H
+#define Patternist_EmptySequence_H
+
+#include "qemptycontainer_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Implements the value instance of empty sequence: <tt>()</tt>.
+ *
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_xdm
+ */
+ class EmptySequence : public EmptyContainer
+ {
+ public:
+ /**
+ * @short Creates an EmptySequence that is a replacement for @p
+ * replacementFor.
+ *
+ * @see EmptySequence()
+ */
+ static Expression::Ptr create(const Expression *const replacementFor,
+ const StaticContext::Ptr &context);
+
+
+ /**
+ * @short Creates an instance of EmptySequence.
+ *
+ * @note In most cases create() should be used, since it takes care of
+ * adjusting source location annotations.
+ *
+ * @see create()
+ */
+ inline EmptySequence()
+ {
+ }
+
+ virtual QString stringValue() const;
+
+ /**
+ * @returns always an empty iterator, an instance of EmptyIterator.
+ */
+ virtual Item::Iterator::Ptr evaluateSequence(const DynamicContext::Ptr &) const;
+
+ /**
+ * @returns always @c null.
+ */
+ virtual Item evaluateSingleton(const DynamicContext::Ptr &) const;
+
+ /**
+ * Does nothing.
+ */
+ virtual void evaluateToSequenceReceiver(const DynamicContext::Ptr &) const;
+
+ /**
+ * @returns always @c false.
+ */
+ virtual bool evaluateEBV(const DynamicContext::Ptr &context) const;
+
+ /**
+ * @returns always CommonSequenceTypes::Empty
+ */
+ virtual ItemType::Ptr type() const;
+
+ /**
+ * @returns always CommonSequenceTypes::Empty
+ */
+ virtual SequenceType::Ptr staticType() const;
+
+ virtual ExpressionVisitorResult::Ptr accept(const ExpressionVisitor::Ptr &visitor) const;
+ virtual ID id() const;
+ virtual Properties properties() const;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/expr/qevaluationcache.cpp b/src/xmlpatterns/expr/qevaluationcache.cpp
new file mode 100644
index 0000000..2d1bb56
--- /dev/null
+++ b/src/xmlpatterns/expr/qevaluationcache.cpp
@@ -0,0 +1,274 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/**
+ * @file
+ * @short This file is included by qevaluationcache_p.h.
+ * If you need includes in this file, put them in qevaluationcache_p.h, outside of the namespace.
+ */
+
+template<bool IsForGlobal>
+EvaluationCache<IsForGlobal>::EvaluationCache(const Expression::Ptr &op,
+ const VariableDeclaration::Ptr &varDecl,
+ const VariableSlotID aSlot) : SingleContainer(op)
+ , m_declaration(varDecl)
+ , m_varSlot(aSlot)
+{
+ Q_ASSERT(m_declaration);
+ Q_ASSERT(m_varSlot > -1);
+}
+
+template<bool IsForGlobal>
+DynamicContext::Ptr EvaluationCache<IsForGlobal>::topFocusContext(const DynamicContext::Ptr &context)
+{
+ DynamicContext::Ptr result(context);
+
+ while(true)
+ {
+ DynamicContext::Ptr candidate(result->previousContext());
+
+ /* We want the top focus, not GenericDynamicContext. */
+ if(candidate && candidate->focusIterator())
+ result = candidate;
+ else
+ return result;
+ }
+}
+
+template<bool IsForGlobal>
+Item EvaluationCache<IsForGlobal>::evaluateSingleton(const DynamicContext::Ptr &context) const
+{
+ ItemCacheCell &cell = IsForGlobal ? context->globalItemCacheCell(m_varSlot) : context->itemCacheCell(m_varSlot);
+
+ if(cell.cacheState == ItemCacheCell::Full)
+ return cell.cachedItem;
+ else
+ {
+ Q_ASSERT(cell.cacheState == ItemCacheCell::Empty);
+ cell.cachedItem = m_operand->evaluateSingleton(IsForGlobal ? topFocusContext(context) : context);
+ cell.cacheState = ItemCacheCell::Full;
+ return cell.cachedItem;
+ }
+}
+
+#if defined(Q_OS_IRIX) && defined(Q_CC_MIPS)
+/**
+ * @short Compile workaround for MIPSPro on IRIX.
+ *
+ * This function is never called.
+ *
+ * It's mere presence means the MIPSPro compiler can accept some other code below.
+ *
+ * I recommend Buddism.
+ */
+static inline Item::Iterator::Ptr workaroundIrixMIPSPro(const ItemSequenceCacheCell &cell)
+{
+ return Item::Iterator::Ptr(new ListIterator<Item, Item::List>(cell.cachedItems));
+}
+#endif
+
+template<bool IsForGlobal>
+Item::Iterator::Ptr EvaluationCache<IsForGlobal>::evaluateSequence(const DynamicContext::Ptr &context) const
+{
+ ItemSequenceCacheCell::Vector &cells = IsForGlobal ? context->globalItemSequenceCacheCells(m_varSlot) : context->itemSequenceCacheCells(m_varSlot);
+ ItemSequenceCacheCell &cell = cells[m_varSlot];
+
+
+ if(cell.inUse)
+ {
+ context->error(QtXmlPatterns::tr("Circularity detected"),
+ ReportContext::XTDE0640, this);
+ }
+
+ switch(cell.cacheState)
+ {
+ case ItemSequenceCacheCell::Full:
+ {
+ /**
+ * We don't use makeListIterator() here because the MIPSPro compiler can't handle it.
+ */
+ return Item::Iterator::Ptr(new ListIterator<Item, Item::List>(cell.cachedItems));
+ }
+ case ItemSequenceCacheCell::Empty:
+ {
+ cell.inUse = true;
+ cell.sourceIterator = m_operand->evaluateSequence(IsForGlobal ? topFocusContext(context) : context);
+ cell.cacheState = ItemSequenceCacheCell::PartiallyPopulated;
+ /* Fallthrough. */
+ }
+ case ItemSequenceCacheCell::PartiallyPopulated:
+ {
+ cell.inUse = false;
+ Q_ASSERT_X(cells.at(m_varSlot).sourceIterator, Q_FUNC_INFO,
+ "This trigger for a cache bug which hasn't yet been analyzed.");
+ return Item::Iterator::Ptr(new CachingIterator(cells, m_varSlot, IsForGlobal ? topFocusContext(context) : context));
+ }
+ default:
+ {
+ Q_ASSERT_X(false, Q_FUNC_INFO, "This path is not supposed to be run.");
+ return Item::Iterator::Ptr();
+ }
+ }
+}
+
+template<bool IsForGlobal>
+Expression::Ptr EvaluationCache<IsForGlobal>::typeCheck(const StaticContext::Ptr &context,
+ const SequenceType::Ptr &reqType)
+{
+ /* It's important that we do the typeCheck() before checking for the use of local variables,
+ * because ExpressionVariableReference can reference an expression that is a local variable,
+ * so it must rewrite itself to it operand before, and it does that in EvaluationCache::typeCheck(). */
+ const Expression::Ptr me(SingleContainer::typeCheck(context, reqType));
+
+ OperandsIterator it(me, OperandsIterator::ExcludeParent);
+ Expression::Ptr next(it.next());
+
+ /* If our operand or any sub operand gets its value from a for-loop, we cannot
+ * cache it since then our cache would be filled -- but not invalidated -- on the
+ * first for-iteration. Consider this query:
+ *
+ * <tt>for $i in expr
+ * let $v := $i/p
+ * return ($v, $v)</tt>
+ *
+ * An evaluation cache is inserted for the two operands in the return clause. However,
+ * $i changes for each iteration so the cache can only be active on a per-iteration basis,
+ * it it's possible(which it isn't).
+ *
+ * This means that for some queries we don't cache what we really should, and hence evaluate
+ * in a sub-optimal way, since this DependsOnLocalVariable don't communicate whether it references
+ * a loop that affects us. The correct fix for this would be to let ForExpression reset the
+ * relevant caches only, but we don't know which ones that are. */
+ while(next)
+ {
+ if(next->has(DependsOnLocalVariable))
+ return m_operand->typeCheck(context, reqType);
+
+ next = it.next();
+ }
+
+ return me;
+}
+
+template<bool IsForGlobal>
+Expression::Ptr EvaluationCache<IsForGlobal>::compress(const StaticContext::Ptr &context)
+{
+ const Expression::Ptr me(SingleContainer::compress(context));
+
+ if(me != this)
+ return me;
+
+ if(m_operand->is(IDRangeVariableReference))
+ return m_operand;
+
+ if(m_declaration->usedByMany())
+ {
+ /* If it's only an atomic value an EvaluationCache is overkill. However,
+ * it's still needed for functions like fn:current-time() that must adhere to
+ * query stability. */
+ const Properties props(m_operand->properties());
+
+ if(props.testFlag(EvaluationCacheRedundant) ||
+ ((props.testFlag(IsEvaluated)) &&
+ !props.testFlag(DisableElimination) &&
+ CommonSequenceTypes::ExactlyOneAtomicType->matches(m_operand->staticType())))
+ {
+ return m_operand;
+ }
+ else
+ return me;
+ }
+ else
+ {
+ /* If we're only used once, there's no need for an EvaluationCache. */
+ return m_operand;
+ }
+}
+
+template<bool IsForGlobal>
+SequenceType::Ptr EvaluationCache<IsForGlobal>::staticType() const
+{
+ return m_operand->staticType();
+}
+
+template<bool IsForGlobal>
+SequenceType::List EvaluationCache<IsForGlobal>::expectedOperandTypes() const
+{
+ /* Remember that EvaluationCache::typeCheck() will be called from multiple locations,
+ * which potentially have different type requirements. For instance, one wants a node,
+ * and another requires atomization and casting.
+ *
+ * Returning ZeroOrMoreItems is safe here because staticType() returns the operand's type
+ * and therefore the convertors like Atomizer will be parents to us, and hence only affect
+ * the relevant path.
+ *
+ * ZeroOrMoreItems also make sense logically since we're actually only used where the
+ * variable references reference us. */
+ SequenceType::List result;
+ result.append(CommonSequenceTypes::ZeroOrMoreItems);
+
+ return result;
+}
+
+template<bool IsForGlobal>
+Expression::Properties EvaluationCache<IsForGlobal>::properties() const
+{
+ /* We cannot return the operand's properties unconditionally, because some
+ * doesn't hold for this Expression.
+ *
+ * However, some of the properties must propagate through, which are the ones being OR'd here.
+ */
+ return m_operand->properties() & (DisableElimination | IsEvaluated | DisableTypingDeduction);
+}
+
+template<bool IsForGlobal>
+ExpressionVisitorResult::Ptr
+EvaluationCache<IsForGlobal>::accept(const ExpressionVisitor::Ptr &visitor) const
+{
+ return visitor->visit(this);
+}
+
+template<bool IsForGlobal>
+const SourceLocationReflection *EvaluationCache<IsForGlobal>::actualReflection() const
+{
+ return m_operand->actualReflection();
+}
+
diff --git a/src/xmlpatterns/expr/qevaluationcache_p.h b/src/xmlpatterns/expr/qevaluationcache_p.h
new file mode 100644
index 0000000..86aeaf8
--- /dev/null
+++ b/src/xmlpatterns/expr/qevaluationcache_p.h
@@ -0,0 +1,146 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_EvaluationCache_H
+#define Patternist_EvaluationCache_H
+
+#include "qcachingiterator_p.h"
+#include "qcommonsequencetypes_p.h"
+#include "qnodebuilder_p.h"
+#include "qoperandsiterator_p.h"
+#include "qsinglecontainer_p.h"
+#include "qvariabledeclaration_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Evaluates to the same result as its operand, but ensures the
+ * operand is evaluated once even if this Expression is evaluated several
+ * times.
+ *
+ * EvaluationCache does this in a pipelined way, by delivering items from
+ * its cache, which is stored in the DynamicContext. If the cache has less
+ * items than what the caller requests, EvaluationCache continues to
+ * deliver but this time from the source, which it also populates into the
+ * cache.
+ *
+ * EvaluationCache is used as an optimization in order to avoid running
+ * expensive code paths multiple times, but also is sometimes a necessity:
+ * for instance, when objects must be unique, such as potentially in the
+ * case of node identity.
+ *
+ * EvaluationCache is in particular used for variables, whose sole purpose
+ * is to store it once(at least conceptually) and then use it in multiple
+ * places.
+ *
+ * In some cases an EvaluationCache isn't necessary. For instance, when a
+ * variable is only referenced once. In those cases EvaluationCache removes
+ * itself as an optimization; implemented in compress().
+ *
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_expressions
+ */
+ template<bool IsForGlobal>
+ class EvaluationCache : public SingleContainer
+ {
+ public:
+ EvaluationCache(const Expression::Ptr &operand,
+ const VariableDeclaration::Ptr &varDecl,
+ const VariableSlotID slot);
+
+ virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const;
+ virtual Item::Iterator::Ptr evaluateSequence(const DynamicContext::Ptr &context) const;
+ virtual Expression::Ptr compress(const StaticContext::Ptr &context);
+
+ virtual SequenceType::Ptr staticType() const;
+
+ /**
+ * The first operand must be exactly one @c xs:string.
+ */
+ virtual SequenceType::List expectedOperandTypes() const;
+
+ virtual ExpressionVisitorResult::Ptr accept(const ExpressionVisitor::Ptr &visitor) const;
+ virtual Properties properties() const;
+ virtual Expression::Ptr typeCheck(const StaticContext::Ptr &context,
+ const SequenceType::Ptr &reqType);
+ virtual const SourceLocationReflection *actualReflection() const;
+
+ inline VariableSlotID slot() const
+ {
+ return m_varSlot;
+ }
+
+ private:
+ static DynamicContext::Ptr topFocusContext(const DynamicContext::Ptr &context);
+ const VariableDeclaration::Ptr m_declaration;
+ /**
+ * This variable must not be called m_slot. If it so, a compiler bug on
+ * HP-UX-aCC-64 is triggered in the constructor initializor. See the
+ * preprocessor output.
+ *
+ * Note that this is the cache slot, and is disjoint to any variable's
+ * regular slot.
+ */
+ const VariableSlotID m_varSlot;
+ };
+
+#include "qevaluationcache.cpp"
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/expr/qexpression.cpp b/src/xmlpatterns/expr/qexpression.cpp
new file mode 100644
index 0000000..7a045e8
--- /dev/null
+++ b/src/xmlpatterns/expr/qexpression.cpp
@@ -0,0 +1,414 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qboolean_p.h"
+#include "qcommonvalues_p.h"
+#include "qemptysequence_p.h"
+#include "qliteral_p.h"
+#include "qliteralsequence_p.h"
+#include "qoperandsiterator_p.h"
+#include "qoptimizerframework_p.h"
+#include "qstaticfocuscontext_p.h"
+#include "qtypechecker_p.h"
+
+#include "qexpression_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+Expression::~Expression()
+{
+}
+
+StaticContext::Ptr Expression::finalizeStaticContext(const StaticContext::Ptr &context) const
+{
+ Q_ASSERT(context);
+ const ItemType::Ptr focusType(newFocusType());
+ Q_ASSERT(focusType);
+ return StaticContext::Ptr(new StaticFocusContext(focusType, context));
+}
+
+Expression::Ptr Expression::typeCheck(const StaticContext::Ptr &context,
+ const SequenceType::Ptr &reqType)
+{
+ Q_ASSERT(reqType);
+ typeCheckOperands(context);
+ return TypeChecker::applyFunctionConversion(Expression::Ptr(this), reqType, context);
+}
+
+void Expression::typeCheckOperands(const StaticContext::Ptr &context)
+{
+ const Expression::List ops(operands());
+
+ /* Check if this expression has any operands at all. */
+ if(ops.isEmpty())
+ return; /* We're done, early exit. */
+
+ const SequenceType::List opTypes(expectedOperandTypes());
+ Expression::List result;
+
+ /* If we create a focus, we handle the last one specially, so avoid it in the loop. */
+ const bool createsFocus = has(CreatesFocusForLast);
+ const SequenceType::List::const_iterator typeEnd(createsFocus ? --opTypes.constEnd()
+ : opTypes.constEnd());
+ const Expression::List::const_iterator end(createsFocus ? --ops.constEnd()
+ : ops.constEnd());
+
+ SequenceType::List::const_iterator reqType(opTypes.constBegin());
+ SequenceType::Ptr t(*reqType);
+ // TODO we assign twice to t here(also below in loop) when ops.size() > 1
+
+ Expression::List::const_iterator it(ops.constBegin());
+
+ for(; it != end; ++it)
+ {
+ /* This ensures that the last expectedOperandType stays, and is
+ * used for all other operands. This is used for expressions that
+ * have an infinite amount of operands, such as the concat() function. */
+ if(reqType != typeEnd)
+ {
+ t = *reqType;
+ ++reqType;
+ }
+
+ /* Let the child & its children typecheck. */
+ result.append((*it)->typeCheck(context, t));
+ }
+
+ if(createsFocus)
+ {
+ const StaticContext::Ptr newContext(finalizeStaticContext(context));
+ result.append(ops.last()->typeCheck(newContext, opTypes.last()));
+ }
+
+ setOperands(result);
+}
+
+Expression::Ptr Expression::invokeOptimizers(const Expression::Ptr &expr,
+ const StaticContext::Ptr &context)
+{
+ Q_ASSERT(expr);
+
+ const OptimizationPass::List opts(expr->optimizationPasses());
+
+ if(opts.isEmpty()) /* Early exit. */
+ {
+ return expr;
+ }
+
+ const OptimizationPass::List::const_iterator passEnd(opts.constEnd());
+ const OptimizationPass::List::const_iterator end(opts.constEnd());
+ OptimizationPass::List::const_iterator passIt(opts.constBegin());
+
+ for(; passIt != passEnd; ++passIt) /* Invoke each optimization pass. */
+ {
+ const OptimizationPass::Ptr pass(*passIt); /* Alias, for readability. */
+ OptimizationPass::ExpressionMarker sourceMarker(pass->sourceExpression);
+
+ if(pass->startIdentifier && !pass->startIdentifier->matches(expr))
+ {
+ /* This pass specified a start identifier and it did
+ * not match -- let's try the next OptimizationPass. */
+ continue;
+ }
+
+ const ExpressionIdentifier::List::const_iterator idEnd(pass->operandIdentifiers.constEnd());
+ ExpressionIdentifier::List::const_iterator idIt(pass->operandIdentifiers.constBegin());
+ const Expression::List ops(expr->operands());
+ const Expression::List::const_iterator opEnd(ops.constEnd());
+ Expression::List::const_iterator opIt(ops.constBegin());
+
+ switch(pass->operandsMatchMethod)
+ {
+ case OptimizationPass::Sequential:
+ {
+ for(; opIt != opEnd; ++opIt)
+ {
+ const Expression::Ptr operand(*opIt); /* Alias, for readability. */
+ const ExpressionIdentifier::Ptr opIdentifier(*idIt); /* Alias, for readability. */
+ if(opIdentifier && !opIdentifier->matches(operand))
+ {
+ break;
+ }
+
+ ++idIt;
+ }
+
+ if(opIt == opEnd)
+ break; /* All operands matched, so this pass matched. */
+ else
+ {
+ /* The loop above did not finish which means all operands did not match.
+ Therefore, this OptimizationPass did not match -- let's try the next one. */
+ continue;
+ }
+ }
+ case OptimizationPass::AnyOrder:
+ {
+ Q_ASSERT_X(ops.count() == 2, Q_FUNC_INFO,
+ "AnyOrder is currently only supported for Expressions with two operands.");
+ if(pass->operandIdentifiers.first()->matches(ops.first()) &&
+ pass->operandIdentifiers.last()->matches(ops.last()))
+ {
+ break;
+ }
+ else if(pass->operandIdentifiers.first()->matches(ops.last()) &&
+ pass->operandIdentifiers.last()->matches(ops.first()))
+ {
+ sourceMarker.first() = 1;
+ sourceMarker[1] = 0;
+ break; /* This pass matched. */
+ }
+ else
+ continue; /* This pass didn't match, let's loop through the next pass. */
+ }
+ }
+
+ /* Figure out the source Expression, if any. */
+ Expression::List operands;
+ Expression::Ptr sourceExpr;
+
+ if(!sourceMarker.isEmpty())
+ {
+ const OptimizationPass::ExpressionMarker::const_iterator mEnd(sourceMarker.constEnd());
+ OptimizationPass::ExpressionMarker::const_iterator mIt(sourceMarker.constBegin());
+ sourceExpr = expr;
+
+ for(; mIt != mEnd; ++mIt)
+ {
+ Q_ASSERT(*mIt >= 0);
+ sourceExpr = sourceExpr->operands().at(*mIt);
+ }
+
+ operands.append(sourceExpr);
+ }
+
+ if(operands.isEmpty())
+ {
+ Q_ASSERT(pass->resultCreator);
+ return pass->resultCreator->create(Expression::List(), context, expr.data())->compress(context);
+ }
+ else if(pass->resultCreator)
+ return pass->resultCreator->create(operands, context, expr.data())->compress(context);
+ else
+ {
+ return sourceExpr;
+ }
+ }
+
+ return expr;
+}
+
+Expression::Ptr Expression::compress(const StaticContext::Ptr &context)
+{
+ if(!compressOperands(context))
+ {
+ /* At least one of the operands cannot be evaluated at compile, so
+ * 'this' Expression cannot const fold. */
+ return invokeOptimizers(Expression::Ptr(this), context);
+ }
+
+ Expression::Ptr retval;
+
+ if(hasDependency(DisableElimination))
+ retval = Expression::Ptr(this);
+ else
+ retval = constantPropagate(context);
+
+ return invokeOptimizers(retval, context);
+}
+
+Expression::Ptr Expression::constantPropagate(const StaticContext::Ptr &context) const
+{
+ Q_ASSERT(context);
+
+ /* Optimization: We rewrite literals to literals here, which is pointless.
+ * Maybe we should have a property which says "doesn't disable elimination
+ * but don't eliminate me." */
+ if(staticType()->cardinality().allowsMany())
+ {
+ Item::Iterator::Ptr it(evaluateSequence(context->dynamicContext()));
+ Item::List result;
+ Item item(it->next());
+
+ while(item)
+ {
+ result.append(item);
+ item = it->next();
+ }
+
+ switch(result.count())
+ {
+ case 0:
+ return EmptySequence::create(this, context);
+ case 1:
+ return rewrite(Expression::Ptr(new Literal(result.first())), context);
+ default:
+ return rewrite(Expression::Ptr(new LiteralSequence(result)), context);
+ }
+ }
+ else
+ {
+ const Item item(evaluateSingleton(context->dynamicContext()));
+
+ if(item)
+ return rewrite(Expression::Ptr(new Literal(item)), context);
+ else
+ return EmptySequence::create(this, context);
+ }
+}
+
+Item::Iterator::Ptr Expression::evaluateSequence(const DynamicContext::Ptr &context) const
+{
+ const Item item(evaluateSingleton(context));
+
+ if(item)
+ return makeSingletonIterator(item);
+ else
+ return CommonValues::emptyIterator;
+}
+
+Item Expression::evaluateSingleton(const DynamicContext::Ptr &context) const
+{
+ return Boolean::fromValue(evaluateEBV(context));
+}
+
+bool Expression::evaluateEBV(const DynamicContext::Ptr &context) const
+{
+ return Boolean::evaluateEBV(evaluateSequence(context), context);
+}
+
+void Expression::evaluateToSequenceReceiver(const DynamicContext::Ptr &context) const
+{
+ QAbstractXmlReceiver *const receiver = context->outputReceiver();
+ const Item::Iterator::Ptr it(evaluateSequence(context));
+ Item next(it->next());
+
+ while(next)
+ {
+ receiver->item(next);
+ next = it->next();
+ }
+}
+
+ItemType::Ptr Expression::expectedContextItemType() const
+{
+ Q_ASSERT_X(false, Q_FUNC_INFO,
+ "expectedContextItemType() must be overridden when RequiresContextItem is set.");
+ return ItemType::Ptr();
+}
+
+Expression::Properties Expression::properties() const
+{
+ return Properties();
+}
+
+Expression::Properties Expression::dependencies() const
+{
+ OperandsIterator it(Ptr(const_cast<Expression *>(this)), OperandsIterator::ExcludeParent);
+ Expression::Ptr next(it.next());
+
+ Properties dependencies(properties());
+
+ while(next)
+ {
+ dependencies |= next->dependencies();
+ next = it.next();
+ }
+
+ return dependencies & (Expression::RequiresFocus | Expression::IsEvaluated | Expression::DisableElimination);
+}
+
+void Expression::announceFocusType(const ItemType::Ptr &itemType)
+{
+ const Expression::List ops(operands());
+ const int len = ops.count();
+
+ for(int i = 0; i < len; ++i)
+ ops.at(i)->announceFocusType(itemType);
+}
+
+Expression::Properties Expression::deepProperties() const
+{
+ Properties props(properties());
+ const Expression::List ops(operands());
+ const int len = ops.count();
+
+ for(int i = 0; i < len; ++i)
+ props |= ops.at(i)->deepProperties();
+
+ return props;
+}
+
+Expression::ID Expression::id() const
+{
+ return IDIgnorableExpression;
+}
+
+OptimizationPass::List Expression::optimizationPasses() const
+{
+ return OptimizationPass::List();
+}
+
+ItemType::Ptr Expression::newFocusType() const
+{
+ Q_ASSERT_X(false, Q_FUNC_INFO,
+ "This function must be overridden when CreatesFocusForLast is set.");
+ return ItemType::Ptr();
+}
+
+const SourceLocationReflection *Expression::actualReflection() const
+{
+ return this;
+}
+
+QString Expression::description() const
+{
+ return QString::fromLatin1("Expression, id: %1").arg(QString::number(id()));
+}
+
+PatternPriority Expression::patternPriority() const
+{
+ return 0.5;
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/expr/qexpression_p.h b/src/xmlpatterns/expr/qexpression_p.h
new file mode 100644
index 0000000..8bf37df
--- /dev/null
+++ b/src/xmlpatterns/expr/qexpression_p.h
@@ -0,0 +1,909 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_Expression_H
+#define Patternist_Expression_H
+
+#include <QFlags>
+#include <QSharedData>
+
+#include "qcppcastinghelper_p.h"
+#include "qdebug_p.h"
+#include "qdynamiccontext_p.h"
+#include "qexpressiondispatch_p.h"
+#include "qitem_p.h"
+#include "qsequencetype_p.h"
+#include "qsourcelocationreflection_p.h"
+#include "qstaticcontext_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+template<typename T> class QList;
+template<typename T> class QVector;
+
+namespace QPatternist
+{
+ template<typename T, typename ListType> class ListIterator;
+ class OptimizationPass;
+
+ /**
+ * @short Base class for all AST nodes in an XPath/XQuery/XSL-T expression.
+ *
+ * @section ExpressionCreation Expression Compilation
+ *
+ * @subsection ExpressionCreationParser The process of creating an Expression
+ *
+ * The initial step of creating an internal representation(in some circles
+ * called an IR tree) of the XPath string follows classic compiler design: a scanner
+ * is invoked, resulting in tokens, which sub-sequently are consumed by a parser
+ * which groups the tokens into rules, resulting in the creation of
+ * Abstract Syntax Tree(AST) nodes that are arranged in a hierarchical structure
+ * similar to the EBNF.
+ *
+ * More specifically, ExpressionFactory::createExpression() is called with a
+ * pointer to a static context, and the string for the expression. This is subsequently
+ * tokenized by a Flex scanner. Mistakes detected at this stage is syntax
+ * errors, as well as a few semantical errors. Syntax errors can be divided
+ * in two types:
+ *
+ * - The scanner detects it. An example is the expression "23Eb3" which
+ * is not a valid number literal, or "1prefix:my-element" which is not a
+ * valid QName.
+ * - The parser detects it. This means a syntax error at a
+ * higher level, that a group of tokens couldn't be reduced to a
+ * rule(expression). An example is the expression "if(a = b) 'match' else
+ * 'no match'"; the tokenizer would handle it fine, but the parser would
+ * fail because the tokens could not be reduced to a rule due to the token
+ * for the "then" word was missing.
+ *
+ * Apart from the syntax errors, the actions in the parser also detects
+ * errors when creating the corresponding expressions. This is for example
+ * that no namespace binding for a prefix could be found, or that a function
+ * call was used which no function implementation could be found for.
+ *
+ * When the parser has finished, the result is an AST. That is, a
+ * hierarchical structure consisting of Expression sub-classes. The
+ * individual expressions haven't at this point done anything beyond
+ * receiving their child-expressions(if any), and hence reminds of a
+ * "construction scaffold". In other words, a tree for the expression
+ * <tt>'string' + 1 and xs:date('2001-03-13')</tt> could have been created, even if
+ * that expression contains errors(one can't add a xs:integer to a xs:string,
+ * and the Effective %Boolean Value cannot be extracted for date types).
+ *
+ * @subsection ExpressionCreationTypeChecking Type Checking
+ *
+ * After the AST creation, ExpressionFactory::createExpression continues with
+ * calling the AST node(which is an Expression instance)'s typeCheck()
+ * function. This step ensures that the static types of the operands matches
+ * the operators, and in the cases where it doesn't, modifies the AST such
+ * that the necessary conversions are done -- if possible, otherwise the
+ * result is a type error.
+ *
+ *
+ * This step corresponds roughly to what <a
+ * href="http://www.w3.org/TR/xpath20/#id-static-analysis">2.2.3.1 Static Analysis Phase</a>
+ * labels operation tree normalization; step SQ5.
+ *
+ * @subsection ExpressionCreationCompression Compressing -- Optimization and Fixup
+ *
+ * The last step is calling compress(). This function is not called
+ * 'optimize', 'simplify' or the like, because although it performs all
+ * optimization, it also involves mandatory stages.
+ *
+ * One such is const folding, which while being an efficient optimization,
+ * also is a necessity for many XSL-T constructs. Another important step is
+ * that functions which had an evaluation dependency on the static context(as
+ * opposed to the dynamic) performs their "fixup".
+ *
+ * In other words, this stage potentially performs AST re-writes. For example,
+ * the expression <tt>3 + 3, concat('foo', '-', 'bar'), true() and false()</tt> would
+ * result in an AST corresponding to <tt>6, 'foo-bar', false()</tt>. This process
+ * is done backwards; each expression asks its operands to compress before it
+ * performs its own compression(and so forth, until the root expression's call
+ * returns to the caller).
+ *
+ * @see <a href="http://www.w3.org/TR/xpath20/#id-errors-and-opt">XML Path Language
+ * (XPath) 2.0, 2.3.4 Errors and Optimization</a>
+ * @see <a href="http://www.w3.org/TR/xpath20/#id-expression-processing">XML Path
+ * Language (XPath) 2.0, 2.2.3 Expression Processing</a>
+ * @see <a href="http://www.w3.org/TR/xquery-xpath-parsing/">Building a Tokenizer
+ * for XPath or XQuery</a>
+ * @see ExpressionFactory
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_expressions
+ */
+ class Q_AUTOTEST_EXPORT Expression : public QSharedData
+ , public CppCastingHelper<Expression>
+ , public SourceLocationReflection
+ {
+ public:
+ /**
+ * @short A smart pointer wrapping mutable Expression instances.
+ */
+ typedef QExplicitlySharedDataPointer<Expression> Ptr;
+
+ /**
+ * @short A smart pointer wrapping @c const Expression instances.
+ */
+ typedef QExplicitlySharedDataPointer<const Expression> ConstPtr;
+
+ /**
+ * A list of Expression instances, each wrapped in a smart pointer.
+ */
+ typedef QList<Expression::Ptr> List;
+
+ /**
+ * A vector of Expression instances, each wrapped in a smart pointer.
+ */
+ typedef QVector<Expression::Ptr> Vector;
+
+ typedef QT_PREPEND_NAMESPACE(QAbstractXmlForwardIterator<Expression::Ptr>)
+ QAbstractXmlForwardIterator;
+
+ /**
+ * Enum flags describing the characteristics of the expression.
+ *
+ * @see Expression::properties()
+ */
+ enum Property
+ {
+ /**
+ * This flag applies for functions, and results in the expression <tt>.</tt>
+ * being appended to its operands if its operand count is lower than the
+ * maximum amount of arguments.
+ *
+ * In effect, it result in a modification of the function's arguments to have
+ * appended the context item.
+ *
+ * One function which has this property is <tt>fn:number()</tt>.
+ *
+ * @see ContextItem
+ * @see <a href="http://www.w3.org/TR/xpath-functions/#func-signatures">XQuery 1.0 and
+ * XPath 2.0 Functions and Operators, 1.3 Function Signatures and Descriptions</a>
+ */
+ UseContextItem = 1,
+
+ /**
+ * Disables compression(evaluation at compile time), such that the
+ * Expression isn't const-folded, but ensured to be run at runtime. The
+ * operands are still attempted to be compressed, unless
+ * they override compression as well.
+ *
+ * @see compress()
+ */
+ DisableElimination = 1 << 1,
+
+ /**
+ * Signals that the expression is already evaluated and can be considered
+ * a constant value.
+ * For example, atomic values return this flag in their
+ * implementations of the properties() functions.
+ *
+ * @see isEvaluated()
+ */
+ IsEvaluated = 1 << 2,
+
+ /**
+ * Signals that the expression cannot be optimized away by judging
+ * its static type.
+ *
+ * This is currently used for properly handling the @c none type, in
+ * the <tt>fn:error()</tt> function. In type operations, the none type doesn't show
+ * up and that can make expressions, such as InstanceOf, believe
+ * it is safe to const fold, while it in fact is not.
+ */
+ DisableTypingDeduction = 1 << 3,
+
+ /**
+ * This property affects the static type -- staticType() -- of an expression. It
+ * is implemented in FunctionCall::staticType() and therefore only work for FunctionCall
+ * sub-classes and when that function is not re-implemented in an inhibiting way.
+ *
+ * When set, the cardinality of the static type is zero if the Expression's first
+ * operand allows an empty sequence, otherwise it is the cardinality of the Expression's
+ * static type modulo Cardinality::empty(). This is used for specifying proper static
+ * type inference for functions that have "If $arg is the empty sequence,
+ * the empty sequence is returned." However, before setting this property one
+ * must be aware that no other conditions can lead to the empty sequence, since
+ * otherwise the static type would be wrong.
+ */
+ EmptynessFollowsChild = 1 << 4,
+
+ /**
+ * This is similar to EmptynessFollowsChild, and also implemented in FunctionCall.
+ * When set, it makes FunctionCall::typeCheck() rewrite itself into an empty sequence
+ * if the first operand is the empty sequence.
+ *
+ * This property is often used together with EmptynessFollowsChild.
+ */
+ RewriteToEmptyOnEmpty = 1 << 5,
+
+ /**
+ * When set, it signals that the focus cannot be undefined. For example,
+ * the <tt>fn:position()</tt> function extracts information from the focus. Setting
+ * this flag ensures type checking is carried out appropriately.
+ *
+ * However, setting RequiresFocus does not imply this Expression requires the context
+ * item to be defined. It only means the focus, of somekind, needs to be defined.
+ *
+ * @see RequiresContextItem
+ */
+ RequiresFocus = 1 << 6,
+
+ /**
+ * An Expression with this Property set, signals that it only affects
+ * the order of its return value.
+ */
+ AffectsOrderOnly = 1 << 7,
+
+ /**
+ * When set, signals that the context item, must be defined for this Expression. When
+ * setting this property, expectedContextItemType() must be re-implemented.
+ *
+ * Setting this property also sets RequiresFocus.
+ *
+ * @see DynamicContext::contextItem()
+ */
+ RequiresContextItem = (1 << 8) | RequiresFocus,
+
+ /**
+ * When set, signals that this expression creates a focus for its last operand.
+ * When set, newFocusType() must be overridden to return the static type
+ * of the context item.
+ *
+ * @see announceFocusType()
+ * @see newFocusType()
+ */
+ CreatesFocusForLast = 1 << 9,
+
+ /**
+ * Signals that the last operand is a collation argument. This ensures
+ * that the necessary code is generated for checking that the collation
+ * is supported.
+ *
+ * This only applies to sub-classes of FunctionCall.
+ */
+ LastOperandIsCollation = 1 << 10,
+
+ /**
+ * When set, the Expression depends on local variables such as
+ * those found in @c for expressions. However, this does not
+ * include let bindings.
+ */
+ DependsOnLocalVariable = (1 << 11) | DisableElimination,
+
+ /**
+ * When set, it signals that the Expression does not need
+ * an evaluation cache, despite what other flags might imply.
+ */
+ EvaluationCacheRedundant = (1 << 12),
+
+ /**
+ * Signals that the Expression constructs nodes, either directly
+ * or computationally. For example, AttributeConstructor has this property
+ * set.
+ *
+ * Since node constructors constructs nodes which have node
+ * identities, node constructors are considered creative on
+ * evaluation.
+ */
+ IsNodeConstructor = 1 << 13,
+
+ /**
+ * Whether this expression requires the current item, as returned
+ * from @c fn:current().
+ *
+ * CurrentFN uses this flag.
+ */
+ RequiresCurrentItem = 1 << 14
+ };
+
+ /**
+ * A QFlags template for type-safe handling of ExpressionProperty values. If
+ * Expression::Property flags needs to be stored in a class, declared the variable
+ * to be of type Expression::Properties.
+ *
+ * @see QFlags
+ */
+ typedef QFlags<Property> Properties;
+
+ /**
+ * Enumerators that identifies Expression sub-classes.
+ *
+ * @see id()
+ */
+ enum ID
+ {
+ /**
+ * Identifies Boolean.
+ */
+ IDBooleanValue = 1,
+
+ /**
+ * Identifies CountFN.
+ */
+ IDCountFN,
+
+ /**
+ * Identifies EmptyFN.
+ */
+ IDEmptyFN,
+
+ /**
+ * Identifies ExistsFN.
+ */
+ IDExistsFN,
+
+ /**
+ * Identifies ExpressionSequence and LiteralSequence.
+ */
+ IDExpressionSequence,
+
+ /**
+ * Identifies GeneralComparison.
+ */
+ IDGeneralComparison,
+
+ /**
+ * Identifies IfThenClause.
+ */
+ IDIfThenClause,
+
+ /**
+ * Identifies nothing in particular. The default implementation
+ * of id() returns this, which is suitable for Expression instances
+ * which never needs to be identified in this aspect.
+ */
+ IDIgnorableExpression,
+
+ /**
+ * Identifies Integer.
+ */
+ IDIntegerValue,
+
+ /**
+ * Identifies PositionFN.
+ */
+ IDPositionFN,
+
+ /**
+ * Identifies AtomicString, AnyURI, and UntypedAtomic.
+ */
+ IDStringValue,
+
+ /**
+ * Identifies ValueComparison.
+ */
+ IDValueComparison,
+
+ /**
+ * Identifies VariableReference.
+ */
+ IDRangeVariableReference,
+
+ /**
+ * Identifies ContextItem.
+ */
+ IDContextItem,
+
+ /**
+ * Identifies UserFunctionCallsite.
+ */
+ IDUserFunctionCallsite,
+
+ /**
+ * Identifies ExpressionVariableReference.
+ */
+ IDExpressionVariableReference,
+
+ /**
+ * Identifies ExpressionVariableReference.
+ */
+ IDAttributeConstructor,
+
+ /**
+ * Identifies UpperCaseFN.
+ */
+ IDUpperCaseFN,
+
+ /**
+ * Identifies LowerCaseFN.
+ */
+ IDLowerCaseFN,
+
+ /**
+ * Identifies FirstItemPredicate.
+ */
+ IDFirstItemPredicate,
+ IDEmptySequence,
+ IDReturnOrderBy,
+ IDLetClause,
+ IDForClause,
+ IDPath,
+ IDNamespaceConstructor,
+ IDArgumentReference,
+ IDGenericPredicate,
+ IDAxisStep,
+
+ /**
+ * A literal which is either @c xs:float or
+ * @c xs:double.
+ */
+ IDFloat,
+
+ IDCombineNodes,
+ IDUnresolvedVariableReference,
+ IDCardinalityVerifier
+ };
+
+ inline Expression()
+ {
+ }
+ virtual ~Expression();
+
+ /**
+ * Evaluate this Expression by iterating over it. This is a central function
+ * for evaluating expressions.
+ *
+ * Expressions must always always return a valid QAbstractXmlForwardIterator and may
+ * never return 0. If an empty result is of interest to be returned, the
+ * EmptyIterator should be returned.
+ *
+ * The default implementation returns a SingletonIterator over the
+ * item returned from evaluateSingleton().
+ *
+ * @note This function may raise an exception when calling, not only
+ * when QAbstractXmlForwardIterator::next() is called on the return value. This is because
+ * in some cases evaluateSingleton() is called directly.
+ */
+ virtual Item::Iterator::Ptr evaluateSequence(const DynamicContext::Ptr &context) const;
+
+ /**
+ * @todo Docs
+ */
+ virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const;
+
+ /**
+ * Determines the Effective %Boolean Value of the expression.
+ *
+ * The Effective %Boolean Value of a value is not necessarily the same
+ * as converting the value to a new value of type xs:boolean.
+ *
+ * Note that this function cannot return the empty sequence,
+ * evaluateSingleton() must be overridden in order to be able to do
+ * that.
+ *
+ * The default implementation results in a type error. Hence, this function
+ * must be overridden if such behavior is not of interest.
+ *
+ * @see <a href="http://www.w3.org/TR/xpath20/#id-ebv">XML Path Language (XPath) 2.0,
+ * 2.4.3 Effective Boolean Value</a>
+ */
+ virtual bool evaluateEBV(const DynamicContext::Ptr &context) const;
+
+ /**
+ * Evaluates this Expression by sending its output to DynamicContext::outputReceiver().
+ */
+ virtual void evaluateToSequenceReceiver(const DynamicContext::Ptr &context) const;
+
+ /**
+ * @returns the expression's child expressions. For example, a function's
+ * arguments is returned here.
+ *
+ * If this Expression has no operands, an empty list should be returned.
+ */
+ virtual Expression::List operands() const = 0;
+
+ virtual void setOperands(const Expression::List &operands) = 0;
+
+ /**
+ * @returns the static type of this Expression. For example, an 'and' expression
+ * have as static type xs:boolean
+ */
+ virtual SequenceType::Ptr staticType() const = 0;
+
+ /**
+ * Returns a list of Sequence Types, describing the type of each of the
+ * expression's operands. Hence, this function has a relationship to
+ * the operands() function:
+ *
+ * - The lengths of the lists returned by expectedOperandTypes()
+ * and operands() should always be equal in length, since one
+ * cannot describe the type of a non-existent operand(and all
+ * operands must have type information).
+ * - A significant difference between the two functions is that while
+ * the type of objects in the list returned by operands() may vary
+ * between compilations/static context, simply because the particular
+ * Expression is part of different XPath expressions, the
+ * types in the list returned by expectedOperandTypes is always the same
+ * since the function/operator signature never changes.
+ *
+ * This function should not be confused with staticType(),
+ * which returns the static type of the expression itself, not its operands. The
+ * function call is an expression where this is clear: the type of the return
+ * value is not the same as the arguments' types. The static type of the
+ * operands supplied to the expression can be determined via the staticType()
+ * function of the instances returned by operands().
+ *
+ * If the expression has no operands, an empty list should be returned.
+ */
+ virtual SequenceType::List expectedOperandTypes() const = 0;
+
+ /**
+ * This implementation guarantees to never rewrite away this Expression, but
+ * at most rewrite it as a child of another expression(that presumably have a
+ * type checking role). It is therefore always safe to override this
+ * function and call this implementation and not worry about that this Expression
+ * becomes deleted.
+ *
+ * Many Expressions override typeCheck() and performs optimizations, as opposed
+ * to doing it in the compress() stage. This is due to that the design
+ * of those Expressions often are tied to that certain simplifications
+ * are done at the typeCheck() stage of the compilation process or that
+ * it in some other way is related to what the typeCheck() do. Also, the earlier
+ * the AST can be simplified, the better the chances are for subsequent
+ * optimizations.
+ *
+ * It is important that the super class's typeCheck() is called before doing
+ * any custom type checking, since the call can change the children(notably,
+ * the childrens' static types). For example, if the Expression, MyExpression
+ * in the example, does not match the required type, typeCheck returns the Expression
+ * wrapped in for example ItemVerifier, CardinalityVerifier, or both.
+ *
+ * typeCheck() may be called many times. typeCheck() must either raise an error
+ * if this Expression is an invalid expression. Thus, it is guaranteed that an Expression
+ * is valid after typeCheck() is called.
+ *
+ * @param context supplies information, such as namespace bindings and
+ * available function signatures, that can be needed at compilation time. @p context is
+ * guaranteed by the caller to never null.
+ * @param reqType the static type that this Expression must match when evaluated. @p reqType is
+ * guaranteed by the caller to never null.
+ * @returns an Expression that can be this Expression, or another expression,
+ * which somehow is necessary for making this Expression conforming to
+ * @p reqType
+ */
+ virtual Expression::Ptr typeCheck(const StaticContext::Ptr &context,
+ const SequenceType::Ptr &reqType);
+
+ /**
+ * compress() is the last stage performs in compiling an expression, done after
+ * the initial AST build and calling typeCheck(). compress() performs crucial
+ * simplifications, either by having drastic performance implications or that
+ * some expressions depend on it for proper behavior.
+ *
+ * The default implementation performs a sparse conditional constant
+ * propagation. In short, a recursive process is performed in the AST
+ * which examines if the Expression's operands are constant values, and if so,
+ * performs a const fold(AST rewrite) into the result of evaluating the expression
+ * in question. This default behavior can be disabled by letting properties() return
+ * DisableElimination.
+ *
+ * This compress() stage can be relative effective due to the design of XPath, in
+ * part because intrinsic functions are heavily used. Many Expressions override compress()
+ * and do optimizations specific to what they do. Also, many Expressions performs
+ * optimizations in their typeCheck().
+ *
+ * @param context the static context. Supplies compile time information, and is
+ * the channel for communicating error messages.
+ * @see <a href="http://en.wikipedia.org/wiki/Sparse_conditional_constant_propagation">Wikipedia,
+ * the free encyclopedia, Sparse conditional constant propagation</a>
+ * @see <a href="http://en.wikipedia.org/wiki/Intrinsic_function">Wikipedia,
+ * the free encyclopedia, Intrinsic function</a>
+ * @see <a href="http://en.wikipedia.org/wiki/Compiler_optimization">Wikipedia, the
+ * free encyclopedia, Compiler optimization</a>
+ */
+ virtual Expression::Ptr compress(const StaticContext::Ptr &context);
+
+ /**
+ * @returns a bitwise OR'd value of properties, describing the
+ * characteristics of the expression. These properties affects how
+ * this Expression is treated in for example type checking stages.
+ *
+ * The default implementation returns 0. Override and let the function return
+ * a different value, if that's of interest.
+ *
+ * An important decision when re-implementing properties() is whether
+ * to OR in the properties() of ones operands. For instance, if an
+ * operand has RequiresFocus set, that flag nost likely applies to the
+ * apparent as well, since it depends on its operand.
+ *
+ * @see deepProperties()
+ * @returns Expression::None, meaning no special properties
+ */
+ virtual Properties properties() const;
+
+ /**
+ * Recursively computes through all descendants until a Property
+ * is encount
+ */
+ virtual Properties dependencies() const;
+
+ /**
+ * @short Computes the union of properties for this Expression and all
+ * its descending children.
+ *
+ * @see properties()
+ */
+ Properties deepProperties() const;
+
+ /**
+ * This function is a utility function, which performs bitwise logic
+ * on properties() in order to find out whether the Expression::IsEvaluated
+ * flag is set.
+ *
+ * @note Do not attempt to re-implement this function. Instead, return the
+ * IsEvaluated flag by re-implementing the properties() function.
+ */
+ inline bool isEvaluated() const;
+
+ /**
+ * This function is a utility function, syntactic sugar for determining
+ * whether this Expression is @p id. For example, calling <tt>is(IDIfThenClause)</tt>
+ * is equivalent to <tt>id() == IDIfThenClause</tt>
+ *
+ * @note Do not attempt to re-implement this function. Instead, return the
+ * appropriate flag in the virtual id() function.
+ */
+ inline bool is(const ID id) const;
+
+ /**
+ * Determines whether this Expression has Property @p prop set.
+ *
+ * Calling <tt>expr->has(MyProperty)</tt> is semantically equivalent
+ * to <tt>expr->properties().testFlag(MyProperty)</tt>. In
+ * other words, has(), as well as is(), provides syntacti sugar
+ * and makes code more readable.
+ *
+ * @note Do not attempt to re-implement this function. Instead, return
+ * the appropriate flag by re-implementing the properties() function.
+ */
+ inline bool has(const Property prop) const;
+
+ inline bool hasDependency(const Property prop) const;
+
+ virtual ExpressionVisitorResult::Ptr accept(const ExpressionVisitor::Ptr &visitor) const = 0;
+
+ /**
+ * This property, which has no setter, returns an enum value that uniquely identifies
+ * this Expression. Patternist makes no use of C++'s dynamic_cast feature, but uses this
+ * polymorphic function instead.
+ *
+ * @returns always IgnorableExpression.
+ */
+ virtual ID id() const;
+
+ /**
+ * Returns the OptimizationPasses that applies for this Expression. The
+ * default implementation returns an empty list. Sub-classes can re-implement
+ * this function and return actual OptimizationPasses.
+ *
+ * @returns always an empty list.
+ */
+ virtual QList<QExplicitlySharedDataPointer<OptimizationPass> > optimizationPasses() const;
+
+ /**
+ * Returns the required type the context item must be an instance of.
+ *
+ * If this Expression requires a focus, meaning its properties()
+ * function returns RequiresContextItem,
+ * it must return a type from this function. If any type is ok, BuiltinTypes::item should be
+ * returned.
+ *
+ * In other words, this function must only be re-implemented if the focus is used. The default
+ * implementation performs an assert crash.
+ */
+ virtual ItemType::Ptr expectedContextItemType() const;
+
+ /**
+ * If an Expression creates a focus because it has set the property CreatesFocusForLast,
+ * it should override this function and make it return the ItemType that
+ * the context item in the focus has.
+ *
+ * @returns never @c null.
+ * @see announceFocusType()
+ */
+ virtual ItemType::Ptr newFocusType() const;
+
+ /**
+ * @short Returns @c this.
+ */
+ virtual const SourceLocationReflection *actualReflection() const;
+
+ /**
+ * Reimplementation of SourceLocationReflection::description().
+ */
+ virtual QString description() const;
+
+ /**
+ * When this function is called, it signals that the parent will create
+ * a focus of type @p itemType.
+ *
+ * This type can also be retrieved through StaticContext::contextItemType()
+ * when inside typeCheck(), but in some cases this is too late. For
+ * instance, a parent needs to have the static type of its child
+ * properly reported before it calls its typeCheck()(and the child's
+ * type is inferred from the focus).
+ *
+ * The default implementation delegates the call on to the children.
+ *
+ * This function may be called at arbitrary times, in arbitrary
+ * amounts.
+ *
+ * If the AST node overriding this call has children, it should be
+ * considered whether the default implementation should be called, such
+ * that they type is announced to them too.
+ *
+ * The caller guarantees that @p itemType is not @c null.
+ */
+ virtual void announceFocusType(const ItemType::Ptr &itemType);
+
+ /**
+ * This function take the two Expression pointers @p old and @p New, and
+ * in a safe way, by handling reference counting and being aware of whether
+ * the two pointers actually are different, switches the two. When compiling
+ * in debug mode, informative debug messages are printed.
+ *
+ * This function is conceptually similar to Qt's qSwap(), but has
+ * debugging functionality and also handles source locations.
+ */
+ static inline void rewrite(Expression::Ptr &old,
+ const Expression::Ptr &New,
+ const StaticContext::Ptr &context);
+
+ /**
+ * @short Rewrites this Expression to @p to, and return @p to.
+ *
+ * Source location annotations are adjusted appropriately.
+ */
+ inline const Expression::Ptr &rewrite(const Expression::Ptr &to,
+ const StaticContext::Ptr &context) const;
+
+ /**
+ * By default 0.5 is returned.
+ */
+ virtual PatternPriority patternPriority() const;
+
+ protected:
+
+ /**
+ * @returns @c true if all operands are constant values of somekind, and are already
+ * evaluated. A string literal, is a typical example.
+ */
+ virtual bool compressOperands(const StaticContext::Ptr &) = 0;
+
+ void typeCheckOperands(const StaticContext::Ptr &context);
+
+ private:
+ static Expression::Ptr invokeOptimizers(const Expression::Ptr &expr,
+ const StaticContext::Ptr &context);
+ /**
+ * @return a StaticContext that has adopted the context item type properly
+ * for this Expression.
+ */
+ inline StaticContext::Ptr finalizeStaticContext(const StaticContext::Ptr &context) const;
+
+ /**
+ * @short Performs constant propagation, also called constant folding, on this expression.
+ *
+ * This means that it attempts to evaluate this expression at compile and returns the result value
+ * appropriately as an Expression. For example, for the XPath expression
+ * <tt>1 + 3</tt> would an Integer of value 4 would be returned.
+ *
+ * It is not checked whether constant propagation is possible, the
+ * caller is responsible for this.
+ *
+ * @see <a href="http://en.wikipedia.org/wiki/Constant_propagation">Constant folding,
+ * From Wikipedia, the free encyclopedia</a>
+ */
+ Expression::Ptr constantPropagate(const StaticContext::Ptr &context) const;
+
+ Q_DISABLE_COPY(Expression)
+ };
+
+ Q_DECLARE_OPERATORS_FOR_FLAGS(Expression::Properties)
+
+ inline bool Expression::is(const Expression::ID i) const
+ {
+ return id() == i;
+ }
+
+ inline bool Expression::isEvaluated() const
+ {
+ return has(IsEvaluated);
+ }
+
+ inline bool Expression::has(const Expression::Property prop) const
+ {
+ return properties().testFlag(prop);
+ }
+
+ inline bool Expression::hasDependency(const Expression::Property prop) const
+ {
+ return dependencies().testFlag(prop);
+ }
+
+ inline void Expression::rewrite(Expression::Ptr &old,
+ const Expression::Ptr &New,
+ const StaticContext::Ptr &context)
+ {
+ Q_ASSERT(old);
+ Q_ASSERT(New);
+
+ if(old != New)
+ {
+ pDebug() << "AST REWRITE:" << old.data() << "to" << New.data()
+ << '(' << old->actualReflection() << "to" << New->actualReflection() << ", "
+ << old->description() << "to" << New->description() << ')';
+
+ /* The order of these two lines is significant.. */
+ context->addLocation(New.data(), context->locationFor(old->actualReflection()));
+ old = New;
+ }
+ }
+
+ inline const Expression::Ptr &Expression::rewrite(const Expression::Ptr &to,
+ const StaticContext::Ptr &context) const
+ {
+ context->addLocation(to.data(), context->locationFor(this));
+ return to;
+ }
+}
+
+Q_DECLARE_TYPEINFO(QPatternist::Expression::Ptr, Q_MOVABLE_TYPE);
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/expr/qexpressiondispatch_p.h b/src/xmlpatterns/expr/qexpressiondispatch_p.h
new file mode 100644
index 0000000..23b2408
--- /dev/null
+++ b/src/xmlpatterns/expr/qexpressiondispatch_p.h
@@ -0,0 +1,241 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_ExpressionDispatch_H
+#define Patternist_ExpressionDispatch_H
+
+#include <QSharedData>
+
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ class AndExpression;
+ class ApplyTemplate;
+ class ArgumentConverter;
+ class ArgumentReference;
+ class ArithmeticExpression;
+ class Atomizer;
+ class AttributeConstructor;
+ class AttributeNameValidator;
+ class AxisStep;
+ class CallTemplate;
+ class CardinalityVerifier;
+ class CardinalityVerifier;
+ class CastableAs;
+ class CastableAs;
+ class CastAs;
+ class CastAs;
+ class CollationChecker;
+ class CollationChecker;
+ class CombineNodes;
+ class CombineNodes;
+ class CommentConstructor;
+ class CommentConstructor;
+ class ComputedNamespaceConstructor;
+ class ContextItem;
+ class CopyOf;
+ class CurrentItemStore;
+ class DocumentConstructor;
+ class DynamicContextStore;
+ class EBVExtractor;
+ class ElementConstructor;
+ class EmptySequence;
+ class ExpressionSequence;
+ class ExpressionVariableReference;
+ class ExternalVariableReference;
+ class FirstItemPredicate;
+ class ForClause;
+ class FunctionCall;
+ class GeneralComparison;
+ class GenericPredicate;
+ class IfThenClause;
+ class InstanceOf;
+ class ItemVerifier;
+ class LetClause;
+ class Literal;
+ class LiteralSequence;
+ class NamespaceConstructor;
+ class NCNameConstructor;
+ class NodeComparison;
+ class NodeSortExpression;
+ class OrderBy;
+ class OrExpression;
+ class ParentNodeAxis;
+ class Path;
+ class PositionalVariableReference;
+ class ProcessingInstructionConstructor;
+ class QNameConstructor;
+ class QuantifiedExpression;
+ class RangeExpression;
+ class RangeVariableReference;
+ class ReturnOrderBy;
+ class SimpleContentConstructor;
+ class StaticBaseURIStore;
+ class StaticCompatibilityStore;
+ class TemplateParameterReference;
+ class TextNodeConstructor;
+ class TreatAs;
+ class TruthPredicate;
+ class UnresolvedVariableReference;
+ class UntypedAtomicConverter;
+ class UserFunctionCallsite;
+ class ValidationError;
+ class ValueComparison;
+ template<bool IsForGlobal> class EvaluationCache;
+
+ /**
+ * @todo Documentation's missing
+ *
+ * @defgroup Patternist_expr_dispatch Expression Dispatching
+ */
+
+ /**
+ * @ingroup Patternist_expr_dispatch
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class ExpressionVisitorResult : public QSharedData
+ {
+ public:
+ typedef QExplicitlySharedDataPointer<ExpressionVisitorResult> Ptr;
+ ExpressionVisitorResult() {}
+ virtual ~ExpressionVisitorResult() {}
+ };
+
+ /**
+ * @ingroup Patternist_expr_dispatch
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class ExpressionVisitor : public QSharedData
+ {
+ public:
+ typedef QExplicitlySharedDataPointer<ExpressionVisitor> Ptr;
+ virtual ~ExpressionVisitor() {}
+
+ virtual ExpressionVisitorResult::Ptr visit(const AndExpression *) const = 0;
+ virtual ExpressionVisitorResult::Ptr visit(const ApplyTemplate *) const = 0;
+ virtual ExpressionVisitorResult::Ptr visit(const ArgumentConverter *) const = 0;
+ virtual ExpressionVisitorResult::Ptr visit(const ArgumentReference *) const = 0;
+ virtual ExpressionVisitorResult::Ptr visit(const ArithmeticExpression *) const = 0;
+ virtual ExpressionVisitorResult::Ptr visit(const Atomizer *) const = 0;
+ virtual ExpressionVisitorResult::Ptr visit(const AttributeConstructor *) const = 0;
+ virtual ExpressionVisitorResult::Ptr visit(const AttributeNameValidator *) const = 0;
+ virtual ExpressionVisitorResult::Ptr visit(const AxisStep *) const = 0;
+ virtual ExpressionVisitorResult::Ptr visit(const CallTemplate *) const = 0;
+ virtual ExpressionVisitorResult::Ptr visit(const CardinalityVerifier *) const = 0;
+ virtual ExpressionVisitorResult::Ptr visit(const CastableAs *) const = 0;
+ virtual ExpressionVisitorResult::Ptr visit(const CastAs *) const = 0;
+ virtual ExpressionVisitorResult::Ptr visit(const CollationChecker *) const = 0;
+ virtual ExpressionVisitorResult::Ptr visit(const CombineNodes *) const = 0;
+ virtual ExpressionVisitorResult::Ptr visit(const CommentConstructor *) const = 0;
+ virtual ExpressionVisitorResult::Ptr visit(const ComputedNamespaceConstructor *) const = 0;
+ virtual ExpressionVisitorResult::Ptr visit(const ContextItem *) const = 0;
+ virtual ExpressionVisitorResult::Ptr visit(const CopyOf *) const = 0;
+ virtual ExpressionVisitorResult::Ptr visit(const CurrentItemStore *) const = 0;
+ virtual ExpressionVisitorResult::Ptr visit(const DocumentConstructor *) const = 0;
+ virtual ExpressionVisitorResult::Ptr visit(const DynamicContextStore *) const = 0;
+ virtual ExpressionVisitorResult::Ptr visit(const EBVExtractor *) const = 0;
+ virtual ExpressionVisitorResult::Ptr visit(const ElementConstructor *) const = 0;
+ virtual ExpressionVisitorResult::Ptr visit(const EmptySequence *) const = 0;
+ virtual ExpressionVisitorResult::Ptr visit(const EvaluationCache<false> *) const = 0;
+ virtual ExpressionVisitorResult::Ptr visit(const EvaluationCache<true> *) const = 0;
+ virtual ExpressionVisitorResult::Ptr visit(const ExpressionSequence *) const = 0;
+ virtual ExpressionVisitorResult::Ptr visit(const ExpressionVariableReference *) const = 0;
+ virtual ExpressionVisitorResult::Ptr visit(const ExternalVariableReference *) const = 0;
+ virtual ExpressionVisitorResult::Ptr visit(const FirstItemPredicate *) const = 0;
+ virtual ExpressionVisitorResult::Ptr visit(const ForClause *) const = 0;
+ virtual ExpressionVisitorResult::Ptr visit(const FunctionCall *) const = 0;
+ virtual ExpressionVisitorResult::Ptr visit(const GeneralComparison *) const = 0;
+ virtual ExpressionVisitorResult::Ptr visit(const GenericPredicate *) const = 0;
+ virtual ExpressionVisitorResult::Ptr visit(const IfThenClause *) const = 0;
+ virtual ExpressionVisitorResult::Ptr visit(const InstanceOf *) const = 0;
+ virtual ExpressionVisitorResult::Ptr visit(const ItemVerifier *) const = 0;
+ virtual ExpressionVisitorResult::Ptr visit(const LetClause *) const = 0;
+ virtual ExpressionVisitorResult::Ptr visit(const Literal *) const = 0;
+ virtual ExpressionVisitorResult::Ptr visit(const LiteralSequence *) const = 0;
+ virtual ExpressionVisitorResult::Ptr visit(const NamespaceConstructor *) const = 0;
+ virtual ExpressionVisitorResult::Ptr visit(const NCNameConstructor *) const = 0;
+ virtual ExpressionVisitorResult::Ptr visit(const NodeComparison *) const = 0;
+ virtual ExpressionVisitorResult::Ptr visit(const NodeSortExpression *) const = 0;
+ virtual ExpressionVisitorResult::Ptr visit(const OrderBy *) const = 0;
+ virtual ExpressionVisitorResult::Ptr visit(const OrExpression *) const = 0;
+ virtual ExpressionVisitorResult::Ptr visit(const ParentNodeAxis *) const = 0;
+ virtual ExpressionVisitorResult::Ptr visit(const Path *) const = 0;
+ virtual ExpressionVisitorResult::Ptr visit(const PositionalVariableReference *) const = 0;
+ virtual ExpressionVisitorResult::Ptr visit(const ProcessingInstructionConstructor *) const = 0;
+ virtual ExpressionVisitorResult::Ptr visit(const QNameConstructor *) const = 0;
+ virtual ExpressionVisitorResult::Ptr visit(const QuantifiedExpression *) const = 0;
+ virtual ExpressionVisitorResult::Ptr visit(const RangeExpression *) const = 0;
+ virtual ExpressionVisitorResult::Ptr visit(const RangeVariableReference *) const = 0;
+ virtual ExpressionVisitorResult::Ptr visit(const ReturnOrderBy *) const = 0;
+ virtual ExpressionVisitorResult::Ptr visit(const SimpleContentConstructor *) const = 0;
+ virtual ExpressionVisitorResult::Ptr visit(const StaticBaseURIStore *) const = 0;
+ virtual ExpressionVisitorResult::Ptr visit(const StaticCompatibilityStore *) const = 0;
+ virtual ExpressionVisitorResult::Ptr visit(const TemplateParameterReference *) const = 0;
+ virtual ExpressionVisitorResult::Ptr visit(const TextNodeConstructor *) const = 0;
+ virtual ExpressionVisitorResult::Ptr visit(const TreatAs *) const = 0;
+ virtual ExpressionVisitorResult::Ptr visit(const TruthPredicate *) const = 0;
+ virtual ExpressionVisitorResult::Ptr visit(const UnresolvedVariableReference *) const = 0;
+ virtual ExpressionVisitorResult::Ptr visit(const UntypedAtomicConverter *) const = 0;
+ virtual ExpressionVisitorResult::Ptr visit(const UserFunctionCallsite *) const = 0;
+ virtual ExpressionVisitorResult::Ptr visit(const ValidationError *) const = 0;
+ virtual ExpressionVisitorResult::Ptr visit(const ValueComparison *) const = 0;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/expr/qexpressionfactory.cpp b/src/xmlpatterns/expr/qexpressionfactory.cpp
new file mode 100644
index 0000000..861b980
--- /dev/null
+++ b/src/xmlpatterns/expr/qexpressionfactory.cpp
@@ -0,0 +1,473 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QBuffer>
+#include <QByteArray>
+
+#include "qcalltemplate_p.h"
+#include "qcommonsequencetypes_p.h"
+#include "qdebug_p.h"
+#include "qexpression_p.h"
+#include "qgenericstaticcontext_p.h"
+#include "qoperandsiterator_p.h"
+#include "qoptimizationpasses_p.h"
+#include "qparsercontext_p.h"
+#include "qpath_p.h"
+#include "qquerytransformparser_p.h"
+#include "qstaticfocuscontext_p.h"
+#include "qtokenrevealer_p.h"
+#include "qxquerytokenizer_p.h"
+#include "qxslttokenizer_p.h"
+
+#include "qexpressionfactory_p.h"
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist {
+
+/**
+ * @short The entry point to the parser.
+ *
+ * @param info supplies the information the parser & scanner
+ * needs to create expressions. The created expression, if everything
+ * succeeds, can be retrieved via the object @p info points to.
+ * @returns non-negative if the parser fails.
+ * @see ExpressionFactory::createExpression()
+ */
+extern int XPathparse(QPatternist::ParserContext *const info);
+
+Expression::Ptr ExpressionFactory::createExpression(const QString &expr,
+ const StaticContext::Ptr &context,
+ const QXmlQuery::QueryLanguage lang,
+ const SequenceType::Ptr &requiredType,
+ const QUrl &queryURI,
+ const QXmlName &initialTemplateName)
+{
+ if(lang == QXmlQuery::XSLT20)
+ {
+ QByteArray query(expr.toUtf8());
+ QBuffer buffer(&query);
+ buffer.open(QIODevice::ReadOnly);
+
+ return createExpression(&buffer,
+ context,
+ lang,
+ requiredType,
+ queryURI,
+ initialTemplateName);
+ }
+ else
+ {
+ return createExpression(Tokenizer::Ptr(new XQueryTokenizer(expr, queryURI)),
+ context,
+ lang,
+ requiredType,
+ queryURI,
+ initialTemplateName);
+ }
+}
+
+Expression::Ptr ExpressionFactory::createExpression(QIODevice *const device,
+ const StaticContext::Ptr &context,
+ const QXmlQuery::QueryLanguage lang,
+ const SequenceType::Ptr &requiredType,
+ const QUrl &queryURI,
+ const QXmlName &initialTemplateName)
+{
+ Q_ASSERT(device);
+ Q_ASSERT(device->isReadable());
+
+ Tokenizer::Ptr tokenizer;
+
+ if(lang == QXmlQuery::XSLT20)
+ tokenizer = Tokenizer::Ptr(new XSLTTokenizer(device, queryURI, context, context->namePool()));
+ else
+ tokenizer = Tokenizer::Ptr(new XQueryTokenizer(QString::fromUtf8(device->readAll()), queryURI));
+
+ return createExpression(tokenizer, context, lang, requiredType, queryURI, initialTemplateName);
+}
+
+Expression::Ptr ExpressionFactory::createExpression(const Tokenizer::Ptr &tokenizer,
+ const StaticContext::Ptr &context,
+ const QXmlQuery::QueryLanguage lang,
+ const SequenceType::Ptr &requiredType,
+ const QUrl &queryURI,
+ const QXmlName &initialTemplateName)
+{
+ Q_ASSERT(context);
+ Q_ASSERT(requiredType);
+ Q_ASSERT(queryURI.isValid());
+
+ Tokenizer::Ptr effectiveTokenizer(tokenizer);
+#ifdef Patternist_DEBUG
+ effectiveTokenizer = Tokenizer::Ptr(new TokenRevealer(queryURI, tokenizer));
+#endif
+
+ OptimizationPasses::Coordinator::init();
+
+ const ParserContext::Ptr info(new ParserContext(context, lang, effectiveTokenizer.data()));
+ info->initialTemplateName = initialTemplateName;
+
+ effectiveTokenizer->setParserContext(info);
+
+ const int bisonRetval = XPathparse(info.data());
+
+ Q_ASSERT_X(bisonRetval == 0, Q_FUNC_INFO,
+ "We shouldn't be able to get an error, because we throw exceptions.");
+ Q_UNUSED(bisonRetval); /* Needed when not compiled in debug mode, since bisonRetval won't
+ * be used in the Q_ASSERT_X above. */
+
+ Expression::Ptr result(info->queryBody);
+
+ if(!result)
+ {
+ context->error(QtXmlPatterns::tr("A library module cannot be evaluated "
+ "directly. It must be imported from a "
+ "main module."),
+ ReportContext::XPST0003,
+ QSourceLocation(queryURI, 1, 1));
+ }
+
+ /* Optimization: I think many things are done in the wrong order below. We
+ * probably want everything typechecked before compressing, since we can
+ * have references all over the place(variable references, template
+ * invocations, function callsites). This could even be a source to bugs.
+ */
+
+ /* Here, we type check user declared functions and global variables. This
+ * means that variables and functions that are not used are type
+ * checked(which they otherwise wouldn't have been), and those which are
+ * used, are type-checked twice, unfortunately. */
+
+ const bool hasExternalFocus = context->contextItemType();
+
+ if(lang == QXmlQuery::XSLT20)
+ {
+ /* Bind xsl:call-template instructions to their template bodies.
+ *
+ * We do this before type checking and compressing them, because a
+ * CallTemplate obviously needs its template before being compressed.
+ *
+ * Also, we do this before type checking and compressing user
+ * functions, since they can contain template call sites.
+ */
+ for(int i = 0; i < info->templateCalls.count(); ++i)
+ {
+ CallTemplate *const site = info->templateCalls.at(i)->as<CallTemplate>();
+ const QXmlName targetName(site->name());
+ const Template::Ptr t(info->namedTemplates.value(targetName));
+
+ if(t)
+ site->setTemplate(t);
+ else
+ {
+ context->error(QtXmlPatterns::tr("No template by name %1 exists.").arg(formatKeyword(context->namePool(), targetName)),
+ ReportContext::XTSE0650,
+ site);
+ }
+ }
+ }
+
+ /* Type check and compress user functions. */
+ {
+ const UserFunction::List::const_iterator end(info->userFunctions.constEnd());
+ UserFunction::List::const_iterator it(info->userFunctions.constBegin());
+
+ /* If the query has a focus(which is common, in the case of a
+ * stylesheet), we must ensure that the focus isn't visible in the
+ * function body. */
+ StaticContext::Ptr effectiveContext;
+
+ if(hasExternalFocus)
+ {
+ effectiveContext = StaticContext::Ptr(new StaticFocusContext(ItemType::Ptr(),
+ context));
+ }
+ else
+ effectiveContext = context;
+
+ for(; it != end; ++it)
+ {
+ pDebug() << "----- User Function Typecheck -----";
+ registerLastPath((*it)->body());
+
+ /* We will most likely call body()->typeCheck() again, once for
+ * each callsite. That is, it will be called from
+ * UserFunctionCallsite::typeCheck(), which will be called
+ * indirectly when we check the query body. */
+ const Expression::Ptr typeCheck((*it)->body()->typeCheck(effectiveContext,
+ (*it)->signature()->returnType()));
+ /* We don't have to call (*it)->setBody(typeCheck) here since it's
+ * only used directly below. */
+ processTreePass(typeCheck, UserFunctionTypeCheck);
+ pDebug() << "------------------------------";
+
+ pDebug() << "----- User Function Compress -----";
+ const Expression::Ptr comp(typeCheck->compress(effectiveContext));
+ (*it)->setBody(comp);
+ processTreePass(comp, UserFunctionCompression);
+ pDebug() << "------------------------------";
+ }
+ }
+
+ /* Type check and compress global variables. */
+ {
+ const VariableDeclaration::Stack::const_iterator vend(info->variables.constEnd());
+ VariableDeclaration::Stack::const_iterator vit(info->variables.constBegin());
+ for(; vit != vend; ++vit)
+ {
+ Q_ASSERT(*vit);
+ /* This is a bit murky, the global variable will have it
+ * Expression::typeCheck() function called from all its references,
+ * but we also want to check it here globally, so we do
+ * typechecking using a proper focus. */
+ if((*vit)->type == VariableDeclaration::ExternalVariable)
+ continue;
+
+ pDebug() << "----- Global Variable Typecheck -----";
+ Q_ASSERT((*vit)->expression());
+ /* We supply ZeroOrMoreItems, meaning the variable can evaluate to anything. */
+ // FIXME which is a source to bugs
+ // TODO What about compressing variables?
+ const Expression::Ptr
+ nev((*vit)->expression()->typeCheck(context, CommonSequenceTypes::ZeroOrMoreItems));
+ processTreePass(nev, GlobalVariableTypeCheck);
+ pDebug() << "------------------------------";
+ }
+ }
+
+ /* Do all tests specific to XSL-T. */
+ if(lang == QXmlQuery::XSLT20)
+ {
+ /* Type check and compress named templates. */
+ {
+ pDebug() << "Have " << info->namedTemplates.count() << "named templates";
+
+ QMutableHashIterator<QXmlName, Template::Ptr> it(info->namedTemplates);
+
+ while(it.hasNext())
+ {
+ it.next();
+ processNamedTemplate(it.key(), it.value()->body, TemplateInitial);
+
+ it.value()->body = it.value()->body->typeCheck(context, CommonSequenceTypes::ZeroOrMoreItems);
+ processNamedTemplate(it.key(), it.value()->body, TemplateTypeCheck);
+
+ it.value()->body = it.value()->body->compress(context);
+ processNamedTemplate(it.key(), it.value()->body, TemplateCompress);
+
+ it.value()->compileParameters(context);
+ }
+ }
+
+ /* Type check and compress template rules. */
+ {
+ QHashIterator<QXmlName, TemplateMode::Ptr> it(info->templateRules);
+
+ /* Since a pattern can exist of AxisStep, its typeCheck() stage
+ * requires a focus. In the case that we're invoked with a name but
+ * no focus, this will yield a compile error, unless we declare a
+ * focus manually. This only needs to be done for the pattern
+ * expression, since the static type of the pattern is used as the
+ * static type for the focus of the template body. */
+ StaticContext::Ptr patternContext;
+ if(hasExternalFocus)
+ patternContext = context;
+ else
+ patternContext = StaticContext::Ptr(new StaticFocusContext(BuiltinTypes::node, context));
+
+ /* For each template pattern. */
+ while(it.hasNext())
+ {
+ it.next();
+ const TemplateMode::Ptr &mode = it.value();
+ const int len = mode->templatePatterns.count();
+ TemplatePattern::ID currentTemplateID = -1;
+ bool hasDoneItOnce = false;
+
+ /* For each template pattern. */
+ for(int i = 0; i < len; ++i)
+ {
+ /* We can't use references for these two members, since we
+ * assign to them. */
+ const TemplatePattern::Ptr &pattern = mode->templatePatterns.at(i);
+ Expression::Ptr matchPattern(pattern->matchPattern());
+
+ processTemplateRule(pattern->templateTarget()->body,
+ pattern, mode->name(), TemplateInitial);
+
+ matchPattern = matchPattern->typeCheck(patternContext, CommonSequenceTypes::ZeroOrMoreItems);
+ matchPattern = matchPattern->compress(patternContext);
+ pattern->setMatchPattern(matchPattern);
+
+ if(currentTemplateID == -1 && hasDoneItOnce)
+ {
+ currentTemplateID = pattern->id();
+ continue;
+ }
+ else if(currentTemplateID == pattern->id() && hasDoneItOnce)
+ {
+ hasDoneItOnce = false;
+ continue;
+ }
+
+ hasDoneItOnce = true;
+ currentTemplateID = pattern->id();
+ Expression::Ptr body(pattern->templateTarget()->body);
+
+ /* Patterns for a new template has started, we must
+ * deal with the body & parameters. */
+ {
+ /* TODO type is wrong, it has to be the union of all
+ * patterns. */
+ const StaticContext::Ptr focusContext(new StaticFocusContext(matchPattern->staticType()->itemType(),
+ context));
+ body = body->typeCheck(focusContext, CommonSequenceTypes::ZeroOrMoreItems);
+
+ pattern->templateTarget()->compileParameters(focusContext);
+ }
+
+ processTemplateRule(body, pattern, mode->name(), TemplateTypeCheck);
+
+ body = body->compress(context);
+
+ pattern->templateTarget()->body = body;
+ processTemplateRule(body, pattern, mode->name(), TemplateCompress);
+ }
+
+ mode->finalize();
+ }
+ }
+
+ /* Add templates in mode #all to all other modes.
+ *
+ * We do this after the templates has been typechecked and compressed,
+ * since otherwise it will be done N times for the built-in templates,
+ * where N is the count of different templates, instead of once. */
+ {
+ const QXmlName nameModeAll(QXmlName(StandardNamespaces::InternalXSLT,
+ StandardLocalNames::all));
+ const TemplateMode::Ptr &modeAll = info->templateRules[nameModeAll];
+
+ Q_ASSERT_X(modeAll, Q_FUNC_INFO,
+ "We should at least have the builtin templates.");
+ QHashIterator<QXmlName, TemplateMode::Ptr> it(info->templateRules);
+
+ while(it.hasNext())
+ {
+ it.next();
+
+ /* Don't add mode #all to mode #all. */
+ if(it.key() == nameModeAll)
+ continue;
+
+ it.value()->addMode(modeAll);
+ }
+ }
+ }
+
+ /* Type check and compress the query body. */
+ {
+ pDebug() << "----- Initial AST build. -----";
+ processTreePass(result, QueryBodyInitial);
+ pDebug() << "------------------------------";
+
+ pDebug() << "----- Type Check -----";
+ registerLastPath(result);
+ result->rewrite(result, result->typeCheck(context, requiredType), context);
+ processTreePass(result, QueryBodyTypeCheck);
+ pDebug() << "------------------------------";
+
+ pDebug() << "----- Compress -----";
+ result->rewrite(result, result->compress(context), context);
+ processTreePass(result, QueryBodyCompression);
+ pDebug() << "------------------------------";
+ }
+
+ return result;
+}
+
+void ExpressionFactory::registerLastPath(const Expression::Ptr &operand)
+{
+ OperandsIterator it(operand, OperandsIterator::IncludeParent);
+ Expression::Ptr next(it.next());
+
+ while(next)
+ {
+ if(next->is(Expression::IDPath))
+ {
+ next->as<Path>()->setLast();
+ next = it.skipOperands();
+ }
+ else
+ next = it.next();
+ }
+}
+
+void ExpressionFactory::processTreePass(const Expression::Ptr &,
+ const CompilationStage)
+{
+}
+
+void ExpressionFactory::processTemplateRule(const Expression::Ptr &body,
+ const TemplatePattern::Ptr &pattern,
+ const QXmlName &mode,
+ const TemplateCompilationStage stage)
+{
+ Q_UNUSED(body);
+ Q_UNUSED(pattern);
+ Q_UNUSED(mode);
+ Q_UNUSED(stage);
+}
+
+void ExpressionFactory::processNamedTemplate(const QXmlName &name,
+ const Expression::Ptr &tree,
+ const TemplateCompilationStage stage)
+{
+ Q_UNUSED(name);
+ Q_UNUSED(tree);
+ Q_UNUSED(stage);
+}
+
+} // namespace QPatternist
+
+QT_END_NAMESPACE
+
diff --git a/src/xmlpatterns/expr/qexpressionfactory_p.h b/src/xmlpatterns/expr/qexpressionfactory_p.h
new file mode 100644
index 0000000..07235bb
--- /dev/null
+++ b/src/xmlpatterns/expr/qexpressionfactory_p.h
@@ -0,0 +1,187 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_ExpressionFactory_H
+#define Patternist_ExpressionFactory_H
+
+#include <QXmlQuery>
+
+#include "qexpression_p.h"
+#include "qtokenizer_p.h"
+
+#include <QSharedData>
+#include <QUrl>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+class QIODevice;
+
+namespace QPatternist
+{
+ /**
+ * @short The central entry point for compiling expressions.
+ *
+ * @ingroup Patternist_expressions
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class Q_AUTOTEST_EXPORT ExpressionFactory : public QSharedData
+ {
+ public:
+ typedef QExplicitlySharedDataPointer<ExpressionFactory> Ptr;
+
+ /**
+ * @short This constructor cannot be synthesized since we
+ * use the Q_DISABLE_COPY macro.
+ */
+ inline ExpressionFactory()
+ {
+ }
+
+ virtual ~ExpressionFactory()
+ {
+ }
+
+ enum CompilationStage
+ {
+ QueryBodyInitial = 1,
+ QueryBodyTypeCheck = 1 << 1,
+ QueryBodyCompression = 1 << 2,
+ UserFunctionTypeCheck = 1 << 3,
+ UserFunctionCompression = 1 << 4,
+ GlobalVariableTypeCheck = 1 << 5
+ };
+
+ /**
+ * Creates a compiled representation of the XPath expression @p expr, with Static
+ * Context information supplied via @p context. This is for example whether the expression
+ * is an XPath 1.0 or XPath 2.0 expression, or what functions that are available.
+ *
+ * @p requiredType specifies what type results of the evaluating the expression
+ * must match. Passing CommonValues::ZeroOrMoreItems allows anything as result, while
+ * passing CommonSequenceTypes::EBV means anything but an Effective %Boolean Value extractable
+ * result is a type error, for example.
+ *
+ * @note An empty @p expr is an invalid XPath expression. It will be reported as such,
+ * but it is neverthless the caller's resonsibility to ensure that it's not that(since
+ * it is likely invalid already in the medium it was stored).
+ */
+ virtual Expression::Ptr createExpression(const QString &expr,
+ const StaticContext::Ptr &context,
+ const QXmlQuery::QueryLanguage lang,
+ const SequenceType::Ptr &requiredType,
+ const QUrl &queryURI,
+ const QXmlName &initialTemplateName);
+
+ virtual Expression::Ptr createExpression(QIODevice *const device,
+ const StaticContext::Ptr &context,
+ const QXmlQuery::QueryLanguage lang,
+ const SequenceType::Ptr &requiredType,
+ const QUrl &queryURI,
+ const QXmlName &initialTemplateName);
+
+ /**
+ * Finds the last paths of a set of paths(if any) and tells the Path
+ * so, such that it can generate the code for checking XPTY0018.
+ *
+ * Must be called before typeCheck() is called on the operand, since
+ * the typeCheck() uses the information for type checking.
+ */
+ static void registerLastPath(const Expression::Ptr &operand);
+
+ protected:
+ enum TemplateCompilationStage
+ {
+ TemplateInitial = 1,
+ TemplateTypeCheck = 1 << 1,
+ TemplateCompress = 1 << 2
+ };
+
+ /**
+ * This function is called by createExpression() each time
+ * after a pass on the AST has been completed. Under a typical
+ * compilation this function is thus called three times: after the initial
+ * build, after the Expression::typeCheck() stage, and after
+ * Expression::compress(). @p tree is the AST after each pass.
+ *
+ * This mechanism is currently used for debugging, since it provides a
+ * way of introspecting what the compilation process do to the tree. The
+ * current implementation do nothing.
+ */
+ virtual void processTreePass(const Expression::Ptr &tree,
+ const CompilationStage stage);
+
+ virtual void processTemplateRule(const Expression::Ptr &body,
+ const TemplatePattern::Ptr &pattern,
+ const QXmlName &mode,
+ const TemplateCompilationStage stage);
+
+ virtual void processNamedTemplate(const QXmlName &name,
+ const Expression::Ptr &tree,
+ const TemplateCompilationStage stage);
+
+ Expression::Ptr createExpression(const Tokenizer::Ptr &tokenizer,
+ const StaticContext::Ptr &context,
+ const QXmlQuery::QueryLanguage lang,
+ const SequenceType::Ptr &requiredType,
+ const QUrl &queryURI,
+ const QXmlName &initialTemplateName);
+ private:
+ Q_DISABLE_COPY(ExpressionFactory)
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/expr/qexpressionsequence.cpp b/src/xmlpatterns/expr/qexpressionsequence.cpp
new file mode 100644
index 0000000..a4d1ba6
--- /dev/null
+++ b/src/xmlpatterns/expr/qexpressionsequence.cpp
@@ -0,0 +1,206 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qcardinalityverifier_p.h"
+#include "qcommonsequencetypes_p.h"
+#include "qemptysequence_p.h"
+#include "qsequencemappingiterator_p.h"
+
+#include "qexpressionsequence_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+ExpressionSequence::ExpressionSequence(const Expression::List &ops) : UnlimitedContainer(ops)
+{
+ Q_ASSERT_X(1 < ops.count(), Q_FUNC_INFO,
+ "It makes no sense to have an ExpressionSequence containing less than two expressions.");
+}
+
+Item::Iterator::Ptr ExpressionSequence::mapToSequence(const Expression::Ptr &expr,
+ const DynamicContext::Ptr &context) const
+{
+ return expr->evaluateSequence(context);
+}
+
+Item::Iterator::Ptr ExpressionSequence::evaluateSequence(const DynamicContext::Ptr &context) const
+{
+ return makeSequenceMappingIterator<Item>(ConstPtr(this),
+ makeListIterator(m_operands),
+ context);
+}
+
+void ExpressionSequence::evaluateToSequenceReceiver(const DynamicContext::Ptr &context) const
+{
+ Expression::List::const_iterator it(m_operands.constBegin());
+ const Expression::List::const_iterator end(m_operands.constEnd());
+ Expression::List result;
+
+ for(; it != end; ++it)
+ (*it)->evaluateToSequenceReceiver(context);
+}
+
+Expression::Ptr ExpressionSequence::compress(const StaticContext::Ptr &context)
+{
+ const Expression::Ptr me(UnlimitedContainer::compress(context));
+
+ if(me != this)
+ return me;
+
+ Expression::List::const_iterator it(m_operands.constBegin());
+ const Expression::List::const_iterator end(m_operands.constEnd());
+ Expression::List result;
+
+ for(; it != end; ++it)
+ {
+ const ID Id = (*it)->id();
+
+ /* Remove empty sequences. This is rather important because we have some steps in the parser that
+ * intentionally, unconditionally and for temporary reasons create expressions like (expr, ()). Of course,
+ * empty sequences also occur as part of optimizations.
+ *
+ * User function call sites that are of type empty-sequence() must be avoided since
+ * they may contain calls to fn:error(), which we would rewrite away otherwise. */
+ if(Id != IDUserFunctionCallsite && (*it)->staticType()->cardinality().isEmpty())
+ {
+ /* Rewrite "(1, (), 2)" into "(1, 2)" by not
+ * adding (*it) to result. */
+ continue;
+ }
+ else if(Id == IDExpressionSequence)
+ {
+ /* Rewrite "(1, (2, 3), 4)" into "(1, 2, 3, 4)" */
+ Expression::List::const_iterator seqIt((*it)->operands().constBegin());
+ const Expression::List::const_iterator seqEnd((*it)->operands().constEnd());
+
+ for(; seqIt != seqEnd; ++seqIt)
+ result.append(*seqIt);
+ }
+ else
+ result.append(*it);
+ }
+
+ if(result.isEmpty())
+ return EmptySequence::create(this, context);
+ else if(result.count() == 1)
+ return result.first();
+ else
+ {
+ m_operands = result;
+ return me;
+ }
+}
+
+Expression::Ptr ExpressionSequence::typeCheck(const StaticContext::Ptr &context,
+ const SequenceType::Ptr &reqType)
+{
+ Q_ASSERT(reqType);
+ Expression::List::iterator it(m_operands.begin());
+ const Expression::List::iterator end(m_operands.end());
+
+ /* We treat the cardinality differently here by allowing the empty sequence
+ * for each individual Expression, since the Cardinality can be conformed to by
+ * the ExpressionSequence as a whole(which we check for at the end). */
+ const SequenceType::Ptr testOnlyIT(makeGenericSequenceType(reqType->itemType(),
+ Cardinality::empty() |
+ reqType->cardinality()));
+
+ for(; it != end; ++it)
+ *it = (*it)->typeCheck(context, testOnlyIT);
+
+ /* The above loop is only guaranteed to find item type errors, but the cardinality
+ * can still be wrong since the operands were treated individually. */
+ return CardinalityVerifier::verifyCardinality(Expression::Ptr(this), reqType->cardinality(), context);
+}
+
+Expression::Properties ExpressionSequence::properties() const
+{
+ const Expression::List::const_iterator end(m_operands.constEnd());
+ Expression::List::const_iterator it;
+ bool allEvaled = true;
+ Expression::Properties props(DisableElimination); /* Why do we have this flag? */
+
+ for(it = m_operands.constBegin(); it != end; ++it)
+ {
+ const Expression::Properties newp((*it)->properties());
+ props |= newp;
+
+ if((newp & IsEvaluated) != IsEvaluated)
+ {
+ allEvaled = false;
+ break;
+ }
+ }
+
+ if(!allEvaled)
+ props &= ~IsEvaluated; /* Remove IsEvaluated. */
+
+ /* One of our children might need the focus, but we don't, so
+ * cut it out. */
+ return props & ~RequiresFocus;
+}
+
+SequenceType::Ptr ExpressionSequence::staticType() const
+{
+ return operandsUnionType<ProductOfCardinality>();
+}
+
+SequenceType::List ExpressionSequence::expectedOperandTypes() const
+{
+ SequenceType::List result;
+ /* ExpressionSequence is a bit strange type wise since it has an
+ * infinite amount of operands. */
+ result.append(CommonSequenceTypes::ZeroOrMoreItems);
+ return result;
+}
+
+ExpressionVisitorResult::Ptr ExpressionSequence::accept(const ExpressionVisitor::Ptr &visitor) const
+{
+ return visitor->visit(this);
+}
+
+Expression::ID ExpressionSequence::id() const
+{
+ return IDExpressionSequence;
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/expr/qexpressionsequence_p.h b/src/xmlpatterns/expr/qexpressionsequence_p.h
new file mode 100644
index 0000000..5074489
--- /dev/null
+++ b/src/xmlpatterns/expr/qexpressionsequence_p.h
@@ -0,0 +1,127 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_ExpressionSequence_H
+#define Patternist_ExpressionSequence_H
+
+#include "qunlimitedcontainer_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Implements the comma(",") operator, the sequence constructor.
+ *
+ * For example, the expression <tt>alpha, beta</tt> evaluates to a sequence
+ * containing the items the nodetest @c alpha evaluates to, concatenated
+ * with the items the nodetest @c beta evaluates to.
+ *
+ * @see <a href="http://www.w3.org/TR/xpath20/#construct_seq">XML Path Language
+ * (XPath) 2.0, 3.3.1 Constructing Sequences</a>
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_expressions
+ */
+ class ExpressionSequence : public UnlimitedContainer
+ {
+ public:
+ /**
+ * Creates an ExpressionSequence with the operands @p operands. @p operands
+ * must contain two or more Expression instances.
+ */
+ ExpressionSequence(const Expression::List &operands);
+
+ virtual Item::Iterator::Ptr evaluateSequence(const DynamicContext::Ptr &) const;
+
+ /**
+ * Forwards the call to its children.
+ */
+ virtual void evaluateToSequenceReceiver(const DynamicContext::Ptr &context) const;
+
+ virtual SequenceType::List expectedOperandTypes() const;
+ virtual SequenceType::Ptr staticType() const;
+
+ /**
+ * Removes any empty sequences, typically "()", from its list of children. If
+ * after that rewrite has no children, it rewrites itself to the CommonValues::empty;
+ * if it has only one, it rewrites to the child.
+ *
+ * This optimization is not very usable by itself, but potentially becomes effective after other
+ * optimizations have rewritten themselves into empty sequences. Thus,
+ * saving memory consumption and runtime overhead.
+ */
+ virtual Expression::Ptr compress(const StaticContext::Ptr &context);
+
+ inline Item::Iterator::Ptr mapToSequence(const Expression::Ptr &,
+ const DynamicContext::Ptr &) const;
+
+ virtual Expression::Ptr typeCheck(const StaticContext::Ptr &context,
+ const SequenceType::Ptr &reqType);
+ /**
+ * @returns Expression::DisableElimination, plus the union
+ * of all this ExpressionSequence's children's properties. If any child
+ * does not have IsEvaluated, it is removed from the result.
+ */
+ virtual Expression::Properties properties() const;
+ virtual ExpressionVisitorResult::Ptr accept(const ExpressionVisitor::Ptr &visitor) const;
+ virtual ID id() const;
+ private:
+ typedef QExplicitlySharedDataPointer<const ExpressionSequence> ConstPtr;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/expr/qexpressionvariablereference.cpp b/src/xmlpatterns/expr/qexpressionvariablereference.cpp
new file mode 100644
index 0000000..3b9ecb1
--- /dev/null
+++ b/src/xmlpatterns/expr/qexpressionvariablereference.cpp
@@ -0,0 +1,93 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#include "qexpressionvariablereference_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+ExpressionVariableReference::ExpressionVariableReference(const VariableSlotID slotP,
+ const VariableDeclaration::Ptr &varDecl) : VariableReference(slotP)
+ , m_varDecl(varDecl)
+{
+}
+
+bool ExpressionVariableReference::evaluateEBV(const DynamicContext::Ptr &context) const
+{
+ return context->expressionVariable(slot())->evaluateEBV(context);
+}
+
+Item ExpressionVariableReference::evaluateSingleton(const DynamicContext::Ptr &context) const
+{
+ return context->expressionVariable(slot())->evaluateSingleton(context);
+}
+
+Item::Iterator::Ptr ExpressionVariableReference::evaluateSequence(const DynamicContext::Ptr &context) const
+{
+ return context->expressionVariable(slot())->evaluateSequence(context);
+}
+Expression::Ptr ExpressionVariableReference::typeCheck(const StaticContext::Ptr &context,
+ const SequenceType::Ptr &reqType)
+{
+ if(m_varDecl->canSourceRewrite)
+ return m_varDecl->expression()->typeCheck(context, reqType);
+ else
+ return VariableReference::typeCheck(context, reqType);
+}
+
+Expression::ID ExpressionVariableReference::id() const
+{
+ return IDExpressionVariableReference;
+}
+
+ExpressionVisitorResult::Ptr ExpressionVariableReference::accept(const ExpressionVisitor::Ptr &visitor) const
+{
+ return visitor->visit(this);
+}
+
+SequenceType::Ptr ExpressionVariableReference::staticType() const
+{
+ return m_varDecl->expression()->staticType();
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/expr/qexpressionvariablereference_p.h b/src/xmlpatterns/expr/qexpressionvariablereference_p.h
new file mode 100644
index 0000000..40c835e
--- /dev/null
+++ b/src/xmlpatterns/expr/qexpressionvariablereference_p.h
@@ -0,0 +1,114 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_ExpressionVariableReference_H
+#define Patternist_ExpressionVariableReference_H
+
+#include "qvariabledeclaration_p.h"
+#include "qvariablereference_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short A reference to a variable declared with <tt>declare variable</tt> or @c let.
+ *
+ * It's also used by variable bindings in @c case branches of the @c typeswitch
+ * expression.
+ *
+ * This AST node is only used up until the typeCheck() stage. Therefore it
+ * has no functions for evaluation, such as evaluateSequence().
+ *
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_expressions
+ */
+ class ExpressionVariableReference : public VariableReference
+ {
+ public:
+ ExpressionVariableReference(const VariableSlotID slot,
+ const VariableDeclaration::Ptr &varDecl);
+
+ virtual bool evaluateEBV(const DynamicContext::Ptr &context) const;
+ virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const;
+ virtual Item::Iterator::Ptr evaluateSequence(const DynamicContext::Ptr &context) const;
+
+ virtual Expression::Ptr typeCheck(const StaticContext::Ptr &context,
+ const SequenceType::Ptr &reqType);
+ virtual SequenceType::Ptr staticType() const;
+ virtual ID id() const;
+ virtual ExpressionVisitorResult::Ptr accept(const ExpressionVisitor::Ptr &visitor) const;
+
+ inline const Expression::Ptr &sourceExpression() const;
+ inline const VariableDeclaration::Ptr &variableDeclaration() const;
+ private:
+ const VariableDeclaration::Ptr m_varDecl;
+ };
+
+ inline const Expression::Ptr &ExpressionVariableReference::sourceExpression() const
+ {
+ return m_varDecl->expression();
+ }
+
+ inline const VariableDeclaration::Ptr &ExpressionVariableReference::variableDeclaration() const
+ {
+ return m_varDecl;
+ }
+
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/expr/qexternalvariableloader.cpp b/src/xmlpatterns/expr/qexternalvariableloader.cpp
new file mode 100644
index 0000000..2099cb6
--- /dev/null
+++ b/src/xmlpatterns/expr/qexternalvariableloader.cpp
@@ -0,0 +1,94 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qboolean_p.h"
+#include "qcommonvalues_p.h"
+#include "qdynamiccontext_p.h"
+
+#include "qexternalvariableloader_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+ExternalVariableLoader::~ExternalVariableLoader()
+{
+}
+
+
+SequenceType::Ptr ExternalVariableLoader::announceExternalVariable(const QXmlName name,
+ const SequenceType::Ptr &declaredType)
+{
+ Q_ASSERT(!name.isNull());
+ Q_ASSERT(declaredType);
+ Q_UNUSED(name); /* Needed when compiling in release mode. */
+ Q_UNUSED(declaredType); /* Needed when compiling in release mode. */
+
+ return SequenceType::Ptr();
+}
+
+Item::Iterator::Ptr ExternalVariableLoader::evaluateSequence(const QXmlName name,
+ const DynamicContext::Ptr &context)
+{
+ Q_ASSERT(!name.isNull());
+ const Item item(evaluateSingleton(name, context));
+
+ if(item)
+ return makeSingletonIterator(item);
+ else
+ return CommonValues::emptyIterator;
+}
+
+Item ExternalVariableLoader::evaluateSingleton(const QXmlName name,
+ const DynamicContext::Ptr &context)
+{
+ Q_ASSERT(!name.isNull());
+ return Boolean::fromValue(evaluateEBV(name, context));
+}
+
+bool ExternalVariableLoader::evaluateEBV(const QXmlName name,
+ const DynamicContext::Ptr &context)
+{
+ Q_ASSERT(!name.isNull());
+ return Boolean::evaluateEBV(evaluateSequence(name, context), context);
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/expr/qexternalvariableloader_p.h b/src/xmlpatterns/expr/qexternalvariableloader_p.h
new file mode 100644
index 0000000..5dc3af5
--- /dev/null
+++ b/src/xmlpatterns/expr/qexternalvariableloader_p.h
@@ -0,0 +1,139 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_ExternalVariableLoader_H
+#define Patternist_ExternalVariableLoader_H
+
+#include "qitem_p.h"
+#include "qsequencetype_p.h"
+#include "qxmlname.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ class DynamicContext;
+
+ /**
+ * @short Responsible for loading and declaring available external variables.
+ *
+ * An external variable in XQuery is a global variable that has been declared to receive
+ * its value from the XQuery implementation, as opposed to an initializing expression. Here
+ * is an example of a query with an external variable declaration, followed by a ordinary
+ * global variable:
+ *
+ * <tt> declare variable $theName external;
+ * declare variable $theName := "the value";
+ * "And here's the query body(a string literal)"</tt>
+ *
+ * An external variable declaration can also specify a sequence type:
+ *
+ * <tt>declare variable $theName as xs:integer external;</tt>
+ *
+ * This class allows the user to supply the values to external variables. When
+ * an external variable declaration occur in the query,
+ * announceExternalVariable() is called.
+ *
+ * @ingroup Patternist_xdm
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class Q_AUTOTEST_EXPORT ExternalVariableLoader : public QSharedData
+ {
+ public:
+ typedef QExplicitlySharedDataPointer<ExternalVariableLoader> Ptr;
+ inline ExternalVariableLoader() {}
+
+ virtual ~ExternalVariableLoader();
+
+ /**
+ * Called when Patternist encounters an external variable in the query. It is guaranteed
+ * to be called once for each external variable appearing in a query module.
+ *
+ * @param name the name of the variable. Quaranteed to never be @c null.
+ * @param declaredType the type that the user declared the variable to be of. Whether
+ * this type matches the actual value of the variable or not is irrelevant. Patternist
+ * will do the necessary error handling based on the sequence type that is returned from
+ * this function. If the user didn't declare a type, the type is <tt>item()*</tt>(zero or
+ * more items). Quaranteed to never be @c null.
+ * @returns the sequence type of the value this ExternalVariableLoader actually supplies. However,
+ * if the ExternalVariableLoader knows it cannot supply a variable by this name, @c null should be
+ * returned.
+ */
+ virtual SequenceType::Ptr announceExternalVariable(const QXmlName name,
+ const SequenceType::Ptr &declaredType);
+
+ /**
+ * This function is called at runtime when the external variable by name @p name needs
+ * to be evaluated. It is not defined how many times this function will be called. It
+ * depends on aspects such as how the query was optimized.
+ *
+ * @param name the name of the variable. Quaranteed to never be @c null.
+ * @param context the DynamicContext.
+ * @returns the value of the variable. Remember that this value must match the
+ * sequence type returned from announceExternalVariable() for the same name.
+ */
+ virtual Item::Iterator::Ptr evaluateSequence(const QXmlName name,
+ const QExplicitlySharedDataPointer<DynamicContext> &context);
+
+ virtual Item evaluateSingleton(const QXmlName name,
+ const QExplicitlySharedDataPointer<DynamicContext> &context);
+ virtual bool evaluateEBV(const QXmlName name,
+ const QExplicitlySharedDataPointer<DynamicContext> &context);
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/expr/qexternalvariablereference.cpp b/src/xmlpatterns/expr/qexternalvariablereference.cpp
new file mode 100644
index 0000000..8016cc5
--- /dev/null
+++ b/src/xmlpatterns/expr/qexternalvariablereference.cpp
@@ -0,0 +1,88 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#include "qexternalvariablereference_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+ExternalVariableReference::ExternalVariableReference(const QXmlName &name,
+ const SequenceType::Ptr &type) : m_name(name),
+ m_seqType(type)
+{
+ Q_ASSERT(!m_name.isNull());
+ Q_ASSERT(m_seqType);
+}
+
+Item::Iterator::Ptr ExternalVariableReference::evaluateSequence(const DynamicContext::Ptr &context) const
+{
+ Q_ASSERT(context->externalVariableLoader());
+ return context->externalVariableLoader()->evaluateSequence(m_name, context);
+}
+
+Item ExternalVariableReference::evaluateSingleton(const DynamicContext::Ptr &context) const
+{
+ return context->externalVariableLoader()->evaluateSingleton(m_name, context);
+}
+
+bool ExternalVariableReference::evaluateEBV(const DynamicContext::Ptr &context) const
+{
+ return context->externalVariableLoader()->evaluateEBV(m_name, context);
+}
+
+SequenceType::Ptr ExternalVariableReference::staticType() const
+{
+ return m_seqType;
+}
+
+Expression::Properties ExternalVariableReference::properties() const
+{
+ return DisableElimination;
+}
+
+ExpressionVisitorResult::Ptr ExternalVariableReference::accept(const ExpressionVisitor::Ptr &visitor) const
+{
+ return visitor->visit(this);
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/expr/qexternalvariablereference_p.h b/src/xmlpatterns/expr/qexternalvariablereference_p.h
new file mode 100644
index 0000000..96d0dd2
--- /dev/null
+++ b/src/xmlpatterns/expr/qexternalvariablereference_p.h
@@ -0,0 +1,103 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_ExternalVariableReference_H
+#define Patternist_ExternalVariableReference_H
+
+#include "qemptycontainer_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short A reference to an external variable.
+ *
+ * ExternalVariableReference does not sub-class VariableReference, because it
+ * works differently from how sub-classes of VariableReference do. This class
+ * uses DynamicContext::externalVariableLoader() for retrieving its value, while
+ * a VariableReference sub-class uses slots in the DynamicContext.
+ *
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_expressions
+ */
+ class ExternalVariableReference : public EmptyContainer
+ {
+ public:
+ ExternalVariableReference(const QXmlName &name,
+ const SequenceType::Ptr &type);
+
+ virtual Item::Iterator::Ptr evaluateSequence(const DynamicContext::Ptr &context) const;
+ virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const;
+ virtual bool evaluateEBV(const DynamicContext::Ptr &context) const;
+
+ virtual SequenceType::Ptr staticType() const;
+
+ /**
+ * @returns always DisableElimination
+ */
+ virtual Expression::Properties properties() const;
+
+ virtual ExpressionVisitorResult::Ptr accept(const ExpressionVisitor::Ptr &visitor) const;
+
+ private:
+ const QXmlName m_name;
+ const SequenceType::Ptr m_seqType;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/expr/qfirstitempredicate.cpp b/src/xmlpatterns/expr/qfirstitempredicate.cpp
new file mode 100644
index 0000000..651dff3
--- /dev/null
+++ b/src/xmlpatterns/expr/qfirstitempredicate.cpp
@@ -0,0 +1,97 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qcommonsequencetypes_p.h"
+#include "qgenericsequencetype_p.h"
+
+#include "qfirstitempredicate_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+FirstItemPredicate::FirstItemPredicate(const Expression::Ptr &source) : SingleContainer(source)
+{
+}
+
+Item FirstItemPredicate::evaluateSingleton(const DynamicContext::Ptr &context) const
+{
+ /* If our operand allows the empty sequence, this function can return Item(), otherwise
+ * it returns the first item. As simple as that. */
+ return m_operand->evaluateSequence(context)->next();
+}
+
+SequenceType::Ptr FirstItemPredicate::staticType() const
+{
+ const SequenceType::Ptr t(m_operand->staticType());
+ return makeGenericSequenceType(t->itemType(), t->cardinality().toWithoutMany());
+}
+
+Expression::Ptr FirstItemPredicate::compress(const StaticContext::Ptr &context)
+{
+ const Expression::Ptr me(SingleContainer::compress(context));
+ if(me != this)
+ return me;
+
+ if(m_operand->is(IDFirstItemPredicate))
+ m_operand = m_operand->operands().first();
+
+ return me;
+}
+
+SequenceType::List FirstItemPredicate::expectedOperandTypes() const
+{
+ SequenceType::List result;
+ result.append(CommonSequenceTypes::ZeroOrMoreItems);
+ return result;
+}
+
+ExpressionVisitorResult::Ptr FirstItemPredicate::accept(const ExpressionVisitor::Ptr &visitor) const
+{
+ return visitor->visit(this);
+}
+
+Expression::ID FirstItemPredicate::id() const
+{
+ return IDFirstItemPredicate;
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/expr/qfirstitempredicate_p.h b/src/xmlpatterns/expr/qfirstitempredicate_p.h
new file mode 100644
index 0000000..df44195
--- /dev/null
+++ b/src/xmlpatterns/expr/qfirstitempredicate_p.h
@@ -0,0 +1,114 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_FirstItemPredicate_H
+#define Patternist_FirstItemPredicate_H
+
+#include "qsinglecontainer_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short A predicate that always selects the first item from its sequence.
+ *
+ * FirstItemPredicate corresponds exactly to the predicate
+ * in the expression <tt>input[1]</tt>.
+ *
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_expressions
+ */
+ class FirstItemPredicate : public SingleContainer
+ {
+ public:
+ /**
+ * Creates a FirstItemPredicate that filters @p source.
+ */
+ FirstItemPredicate(const Expression::Ptr &source);
+
+ /**
+ * @returns the first item, if any, from evaluating the source expression.
+ */
+ virtual Item evaluateSingleton(const DynamicContext::Ptr &) const;
+
+ /**
+ * @returns a list containing one CommonSequenceTypes::ZeroOrMoreItems instance.
+ */
+ virtual SequenceType::List expectedOperandTypes() const;
+
+ /**
+ * @returns a SequenceType where the item type is the same as the source expression
+ * and where the cardinality is either Cardinality::zeroOrOne() or Cardinality::exactlyOne(),
+ * depending on the source expression.
+ */
+ virtual SequenceType::Ptr staticType() const;
+ virtual ExpressionVisitorResult::Ptr accept(const ExpressionVisitor::Ptr &visitor) const;
+
+ /**
+ * Rewrites <tt>expression[1][1]</tt> into <tt>expression[1]</tt>.
+ */
+ virtual Expression::Ptr compress(const StaticContext::Ptr &context);
+
+ /**
+ * @returns always IDFirstItemPredicate.
+ */
+ virtual ID id() const;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/expr/qforclause.cpp b/src/xmlpatterns/expr/qforclause.cpp
new file mode 100644
index 0000000..ad9262b
--- /dev/null
+++ b/src/xmlpatterns/expr/qforclause.cpp
@@ -0,0 +1,200 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qcommonsequencetypes_p.h"
+#include "qemptysequence_p.h"
+#include "qgenericsequencetype_p.h"
+#include "qitemmappingiterator_p.h"
+#include "qoptimizationpasses_p.h"
+#include "qsequencemappingiterator_p.h"
+
+#include "qforclause_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+ForClause::ForClause(const VariableSlotID varSlot,
+ const Expression::Ptr &bindingSequence,
+ const Expression::Ptr &returnExpression,
+ const VariableSlotID positionSlot) : PairContainer(bindingSequence, returnExpression),
+ m_varSlot(varSlot),
+ m_positionSlot(positionSlot),
+ m_allowsMany(true)
+{
+ Q_ASSERT(m_positionSlot > -2);
+}
+
+Item ForClause::mapToItem(const Item &item,
+ const DynamicContext::Ptr &context) const
+{
+ context->setRangeVariable(m_varSlot, item);
+ return m_operand2->evaluateSingleton(context);
+}
+
+Item::Iterator::Ptr ForClause::mapToSequence(const Item &item,
+ const DynamicContext::Ptr &context) const
+{
+ context->setRangeVariable(m_varSlot, item);
+ return m_operand2->evaluateSequence(context);
+}
+
+void ForClause::riggPositionalVariable(const DynamicContext::Ptr &context,
+ const Item::Iterator::Ptr &source) const
+{
+ if(m_positionSlot > -1)
+ context->setPositionIterator(m_positionSlot, source);
+}
+
+Item::Iterator::Ptr ForClause::evaluateSequence(const DynamicContext::Ptr &context) const
+{
+ const Item::Iterator::Ptr source(m_operand1->evaluateSequence(context));
+
+ riggPositionalVariable(context, source);
+
+ if(m_allowsMany)
+ {
+ return makeSequenceMappingIterator<Item>(ConstPtr(this),
+ source,
+ context);
+ }
+ else
+ {
+ return makeItemMappingIterator<Item>(ConstPtr(this),
+ source,
+ context);
+ }
+}
+
+Item ForClause::evaluateSingleton(const DynamicContext::Ptr &context) const
+{
+ return evaluateSequence(context)->next();
+}
+
+void ForClause::evaluateToSequenceReceiver(const DynamicContext::Ptr &context) const
+{
+ Item::Iterator::Ptr it;
+ const Item::Iterator::Ptr source(m_operand1->evaluateSequence(context));
+
+ riggPositionalVariable(context, source);
+
+ Item next(source->next());
+
+ while(next)
+ {
+ context->setRangeVariable(m_varSlot, next);
+ m_operand2->evaluateToSequenceReceiver(context);
+ next = source->next();
+ }
+}
+
+Expression::Ptr ForClause::typeCheck(const StaticContext::Ptr &context,
+ const SequenceType::Ptr &reqType)
+{
+ const Expression::Ptr me(PairContainer::typeCheck(context, reqType));
+ const Cardinality card(m_operand1->staticType()->cardinality());
+
+ /* If our source is empty we will always evaluate to the empty sequence, so rewrite. */
+ if(card.isEmpty())
+ return EmptySequence::create(this, context);
+ else
+ return me;
+
+ /* This breaks because the variable references haven't rewritten themselves, so
+ * they dangle. When this is fixed, evaluateSingleton can be removed. */
+ /*
+ else if(card->allowsMany())
+ return me;
+ else
+ return m_operand2;
+ */
+}
+
+Expression::Ptr ForClause::compress(const StaticContext::Ptr &context)
+{
+ const Expression::Ptr me(PairContainer::compress(context));
+ if(me != this)
+ return me;
+
+ /* This is done after calling PairContainer::typeCheck(). The advantage of this is that
+ * m_allowsMany is updated according to what the operand says after it has compressed. However,
+ * if it was initialized to false(as it once was..), ForClause::evaluateSequence()
+ * would potentially have been called by PairContainer::compress(), and it would have
+ * used an unsafe branch. */
+ m_allowsMany = m_operand2->staticType()->cardinality().allowsMany();
+
+ return me;
+}
+
+SequenceType::Ptr ForClause::staticType() const
+{
+ const SequenceType::Ptr returnType(m_operand2->staticType());
+
+ return makeGenericSequenceType(returnType->itemType(),
+ m_operand1->staticType()->cardinality()
+ * /* multiply operator */
+ returnType->cardinality());
+}
+
+SequenceType::List ForClause::expectedOperandTypes() const
+{
+ SequenceType::List result;
+ result.append(CommonSequenceTypes::ZeroOrMoreItems);
+ result.append(CommonSequenceTypes::ZeroOrMoreItems);
+ return result;
+}
+
+ExpressionVisitorResult::Ptr ForClause::accept(const ExpressionVisitor::Ptr &visitor) const
+{
+ return visitor->visit(this);
+}
+
+OptimizationPass::List ForClause::optimizationPasses() const
+{
+ return OptimizationPasses::forPasses;
+}
+
+Expression::ID ForClause::id() const
+{
+ return IDForClause;
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/expr/qforclause_p.h b/src/xmlpatterns/expr/qforclause_p.h
new file mode 100644
index 0000000..5799e0d
--- /dev/null
+++ b/src/xmlpatterns/expr/qforclause_p.h
@@ -0,0 +1,122 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_ForClause_H
+#define Patternist_ForClause_H
+
+#include "qpaircontainer_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+
+ /**
+ * @short Implements XPath 2.0's @c for expression.
+ *
+ * @see <a href="http://www.w3.org/TR/xpath20/#id-for-expressions">XML Path Language
+ * (XPath) 2.0, 3.7 For Expressions</a>
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_expressions
+ */
+ class ForClause : public PairContainer
+ {
+ public:
+ /**
+ * If @p positionSlot is -1, no positional variable will be used.
+ */
+ ForClause(const VariableSlotID varSlot,
+ const Expression::Ptr &bindingSequence,
+ const Expression::Ptr &returnExpression,
+ const VariableSlotID positionSlot);
+
+ virtual Item::Iterator::Ptr evaluateSequence(const DynamicContext::Ptr &context) const;
+ virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const;
+ virtual void evaluateToSequenceReceiver(const DynamicContext::Ptr &context) const;
+
+ virtual SequenceType::Ptr staticType() const;
+ virtual SequenceType::List expectedOperandTypes() const;
+ virtual Expression::Ptr typeCheck(const StaticContext::Ptr &context,
+ const SequenceType::Ptr &reqType);
+ virtual ExpressionVisitorResult::Ptr accept(const ExpressionVisitor::Ptr &visitor) const;
+ virtual QList<QExplicitlySharedDataPointer<OptimizationPass> > optimizationPasses() const;
+
+ inline Item mapToItem(const Item &item,
+ const DynamicContext::Ptr &context) const;
+ virtual ID id() const;
+ inline Item::Iterator::Ptr mapToSequence(const Item &item,
+ const DynamicContext::Ptr &context) const;
+
+ /**
+ * Sets m_allowsMany properly.
+ */
+ virtual Expression::Ptr compress(const StaticContext::Ptr &context);
+
+ private:
+ inline void riggPositionalVariable(const DynamicContext::Ptr &context,
+ const Item::Iterator::Ptr &source) const;
+ typedef QExplicitlySharedDataPointer<const ForClause> ConstPtr;
+ const VariableSlotID m_varSlot;
+ const VariableSlotID m_positionSlot;
+ /**
+ * Initialized to @c false. This default is always safe.
+ */
+ bool m_allowsMany;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/expr/qgeneralcomparison.cpp b/src/xmlpatterns/expr/qgeneralcomparison.cpp
new file mode 100644
index 0000000..a6d6399
--- /dev/null
+++ b/src/xmlpatterns/expr/qgeneralcomparison.cpp
@@ -0,0 +1,297 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qbuiltintypes_p.h"
+#include "qcommonsequencetypes_p.h"
+#include "qcommonvalues_p.h"
+#include "qebvextractor_p.h"
+#include "qitem_p.h"
+#include "qliteral_p.h"
+#include "qoptimizationpasses_p.h"
+#include "quntypedatomicconverter_p.h"
+#include "qvaluecomparison_p.h"
+
+#include "qgeneralcomparison_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+GeneralComparison::GeneralComparison(const Expression::Ptr &op1,
+ const AtomicComparator::Operator op,
+ const Expression::Ptr &op2,
+ const bool isBackwardsCompat) : PairContainer(op1, op2)
+ , m_operator(op)
+ , m_isBackwardsCompat(isBackwardsCompat)
+{
+}
+
+bool GeneralComparison::generalCompare(const Item &op1,
+ const Item &op2,
+ const DynamicContext::Ptr &context) const
+{
+ Q_ASSERT(op1);
+ Q_ASSERT(op2);
+
+ if(comparator())
+ return compare(op1, op2, comparator(), m_operator);
+
+ Expression::Ptr a1(new Literal(op1));
+ Expression::Ptr a2(new Literal(op2));
+
+ const AtomicComparator::Ptr comp(fetchGeneralComparator(a1, a2, context));
+ /* The fetchGeneralComparator call may rewrite a1 and/or a2. */
+ Q_ASSERT(a1);
+ Q_ASSERT(a2);
+ Q_ASSERT(comp);
+
+ return compare(a1->evaluateSingleton(context),
+ a2->evaluateSingleton(context),
+ comp,
+ m_operator);
+}
+
+bool GeneralComparison::evaluateEBV(const DynamicContext::Ptr &context) const
+{
+ const Item::Iterator::Ptr it1(m_operand1->evaluateSequence(context));
+ Item item1(it1->next());
+
+ if(!item1)
+ return false;
+
+ const Item::Iterator::Ptr it2(m_operand2->evaluateSequence(context));
+ Item::List cache;
+ Item item2;
+
+ while(true)
+ {
+ item2 = it2->next();
+ if(!item2)
+ break;
+
+ if(generalCompare(item1, item2, context))
+ return true;
+
+ cache.append(item2);
+ }
+
+ while(true)
+ {
+ item1 = it1->next();
+
+ if(!item1)
+ return false;
+
+ const Item::List::const_iterator end(cache.constEnd());
+ Item::List::const_iterator it(cache.constBegin());
+
+ for(; it != end; ++it)
+ if(generalCompare(item1, *it, context))
+ return true;
+ }
+
+ Q_ASSERT(false);
+ return false;
+}
+
+Expression::Ptr GeneralComparison::compress(const StaticContext::Ptr &context)
+{
+ const Expression::Ptr me(PairContainer::compress(context));
+
+ if(me != this)
+ return me;
+
+ if(ValueComparison::isCaseInsensitiveCompare(m_operand1, m_operand2))
+ useCaseInsensitiveComparator();
+
+ return me;
+}
+
+Expression::Ptr GeneralComparison::typeCheck(const StaticContext::Ptr &context,
+ const SequenceType::Ptr &reqType)
+{
+
+ const Expression::Ptr me(PairContainer::typeCheck(context, reqType));
+
+ const ItemType::Ptr t1(m_operand1->staticType()->itemType());
+ const ItemType::Ptr t2(m_operand2->staticType()->itemType());
+
+ if(*CommonSequenceTypes::Empty == *t1 ||
+ *CommonSequenceTypes::Empty == *t2)
+ {
+ return wrapLiteral(CommonValues::BooleanFalse, context, this);
+ }
+
+ if(*BuiltinTypes::xsAnyAtomicType == *t1 ||
+ *BuiltinTypes::xsAnyAtomicType == *t2)
+ return me;
+
+ prepareComparison(fetchGeneralComparator(m_operand1, m_operand2, context));
+
+ if(!m_operand1->staticType()->cardinality().allowsMany() &&
+ !m_operand2->staticType()->cardinality().allowsMany())
+ {
+ /* Rewrite to a ValueComparison whose operands uses typing rules
+ * as for an general comparison(that's what's done above). */
+ return rewrite(Expression::Ptr(new ValueComparison(m_operand1,
+ m_operator,
+ m_operand2))->typeCheck(context, reqType),
+ context);
+ }
+ else
+ return me;
+}
+
+void GeneralComparison::updateType(ItemType::Ptr &type,
+ const Expression::Ptr &source)
+{
+ type = source->staticType()->itemType();
+}
+
+AtomicComparator::Ptr GeneralComparison::fetchGeneralComparator(Expression::Ptr &op1,
+ Expression::Ptr &op2,
+ const ReportContext::Ptr &context) const
+{
+ ItemType::Ptr t1(op1->staticType()->itemType());
+ ItemType::Ptr t2(op2->staticType()->itemType());
+
+ /* a. "If one of the atomic values is an instance of xs:untypedAtomic and
+ * the other is an instance of a numeric type, then the xs:untypedAtomic
+ * value is cast to the type xs:double." */
+ if(BuiltinTypes::numeric->xdtTypeMatches(t1) &&
+ BuiltinTypes::xsUntypedAtomic->xdtTypeMatches(t2))
+ {
+ op2 = Expression::Ptr(new UntypedAtomicConverter(op2, BuiltinTypes::xsDouble));
+
+ /* The types might have changed, reload. */
+ updateType(t2, op2);
+ }
+ else if(BuiltinTypes::numeric->xdtTypeMatches(t2) &&
+ BuiltinTypes::xsUntypedAtomic->xdtTypeMatches(t1))
+ {
+ op1 = Expression::Ptr(new UntypedAtomicConverter(op1, BuiltinTypes::xsDouble));
+
+ /* The types might have changed, reload. */
+ updateType(t1, op1);
+ }
+ /* "If XPath 1.0 compatibility mode is true, a general comparison is
+ * evaluated by applying the following rules, in order:
+ * 1. If either operand is a single atomic value that is an instance of
+ * xs:boolean, then the other operand is converted to xs:boolean by taking
+ * its effective boolean value."
+ *
+ * Notably, it's not conversion to boolean, it is EBV extraction.
+ */
+ else if(m_isBackwardsCompat && BuiltinTypes::xsBoolean->xdtTypeMatches(t1))
+ {
+ op2 = Expression::Ptr(new EBVExtractor(op2));
+ updateType(t2, op2);
+ }
+ else if(m_isBackwardsCompat && BuiltinTypes::xsBoolean->xdtTypeMatches(t2))
+ {
+ op1 = Expression::Ptr(new EBVExtractor(op1));
+ updateType(t1, op1);
+ }
+ /* b. "If one of the atomic values is an instance of xs:untypedAtomic and
+ * the other is an instance of xs:untypedAtomic or xs:string, then the
+ * xs:untypedAtomic value (or values) is (are) cast to the type xs:string."
+ *
+ * c. "If one of the atomic values is an instance of xs:untypedAtomic and the
+ * other is not an instance of xs:string, xs:untypedAtomic, or any numeric
+ * type, then the xs:untypedAtomic value is cast to the dynamic type of the
+ * other value." */
+ else if(BuiltinTypes::xsUntypedAtomic->xdtTypeMatches(t1) &&
+ !BuiltinTypes::xsString->xdtTypeMatches(t2) &&
+ !BuiltinTypes::xsUntypedAtomic->xdtTypeMatches(t2) &&
+ !BuiltinTypes::xsAnyURI->xdtTypeMatches(t2))
+ {
+ op1 = Expression::Ptr(new UntypedAtomicConverter(op1, t2));
+ updateType(t1, op1);
+ }
+ else if(BuiltinTypes::xsUntypedAtomic->xdtTypeMatches(t2) &&
+ !BuiltinTypes::xsString->xdtTypeMatches(t1) &&
+ !BuiltinTypes::xsUntypedAtomic->xdtTypeMatches(t1) &&
+ !BuiltinTypes::xsAnyURI->xdtTypeMatches(t1))
+ {
+ op2 = Expression::Ptr(new UntypedAtomicConverter(op2, t1));
+ updateType(t2, op2);
+ }
+
+ /* d. "After performing the conversions described above, the atomic
+ * values are compared using one of the value comparison operators
+ * eq, ne, lt, le, gt, or ge, depending on whether the general comparison
+ * operator was =, !=, <, <=, >, or >=. The values have the required
+ * magnitude relationship if and only if the result of this value comparison
+ * is true." */
+
+ return fetchComparator(t1, t2, context);
+}
+
+OptimizationPass::List GeneralComparison::optimizationPasses() const
+{
+ Q_ASSERT(!OptimizationPasses::comparisonPasses.isEmpty());
+ return OptimizationPasses::comparisonPasses;
+}
+
+SequenceType::List GeneralComparison::expectedOperandTypes() const
+{
+ SequenceType::List result;
+ result.append(CommonSequenceTypes::ZeroOrMoreAtomicTypes);
+ result.append(CommonSequenceTypes::ZeroOrMoreAtomicTypes);
+ return result;
+}
+
+SequenceType::Ptr GeneralComparison::staticType() const
+{
+ return CommonSequenceTypes::ExactlyOneBoolean;
+}
+
+ExpressionVisitorResult::Ptr GeneralComparison::accept(const ExpressionVisitor::Ptr &visitor) const
+{
+ return visitor->visit(this);
+}
+
+Expression::ID GeneralComparison::id() const
+{
+ return IDGeneralComparison;
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/expr/qgeneralcomparison_p.h b/src/xmlpatterns/expr/qgeneralcomparison_p.h
new file mode 100644
index 0000000..cc83e22
--- /dev/null
+++ b/src/xmlpatterns/expr/qgeneralcomparison_p.h
@@ -0,0 +1,136 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_GeneralComparison_H
+#define Patternist_GeneralComparison_H
+
+#include "qatomiccomparator_p.h"
+#include "qpaircontainer_p.h"
+#include "qcomparisonplatform_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+
+ /**
+ * @short Implements XPath 2.0's general comparions, such as the <tt>=</tt> operator.
+ *
+ * ComparisonPlatform is inherited with @c protected scope because ComparisonPlatform
+ * must access members of GeneralComparison.
+ *
+ * @see <a href="http://www.w3.org/TR/xpath20/#id-general-comparisons">XML Path Language
+ * (XPath) 2.0, 3.5.2 General Comparisons</a>
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_expressions
+ */
+ class GeneralComparison : public PairContainer,
+ public ComparisonPlatform<GeneralComparison,
+ true /* We want to report errors. */,
+ AtomicComparator::AsGeneralComparison>
+ {
+ public:
+ GeneralComparison(const Expression::Ptr &op1,
+ const AtomicComparator::Operator op,
+ const Expression::Ptr &op2,
+ const bool isBackwardsCompat = false);
+
+ virtual bool evaluateEBV(const DynamicContext::Ptr &) const;
+ virtual Expression::Ptr typeCheck(const StaticContext::Ptr &context,
+ const SequenceType::Ptr &reqType);
+
+ virtual SequenceType::List expectedOperandTypes() const;
+ virtual SequenceType::Ptr staticType() const;
+
+ virtual ExpressionVisitorResult::Ptr accept(const ExpressionVisitor::Ptr &visitor) const;
+
+ /**
+ * @returns always IDGeneralComparison
+ */
+ virtual ID id() const;
+
+ virtual QList<QExplicitlySharedDataPointer<OptimizationPass> > optimizationPasses() const;
+
+ /**
+ * @returns the operator that this GeneralComparison is using.
+ */
+ inline AtomicComparator::Operator operatorID() const
+ {
+ return m_operator;
+ }
+
+ /**
+ * Overridden to optimize case-insensitive compares.
+ */
+ virtual Expression::Ptr compress(const StaticContext::Ptr &context);
+
+ private:
+ static inline void updateType(ItemType::Ptr &type,
+ const Expression::Ptr &source);
+ AtomicComparator::Ptr fetchGeneralComparator(Expression::Ptr &op1,
+ Expression::Ptr &op2,
+ const ReportContext::Ptr &context) const;
+ bool generalCompare(const Item &op1,
+ const Item &op2,
+ const DynamicContext::Ptr &context) const;
+
+ const AtomicComparator::Operator m_operator;
+ const bool m_isBackwardsCompat;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/expr/qgenericpredicate.cpp b/src/xmlpatterns/expr/qgenericpredicate.cpp
new file mode 100644
index 0000000..624d17d
--- /dev/null
+++ b/src/xmlpatterns/expr/qgenericpredicate.cpp
@@ -0,0 +1,218 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qabstractfloat_p.h"
+#include "qboolean_p.h"
+#include "qbuiltintypes_p.h"
+#include "qcommonsequencetypes_p.h"
+#include "qemptysequence_p.h"
+#include "qfirstitempredicate_p.h"
+#include "qgenericsequencetype_p.h"
+#include "qitemmappingiterator_p.h"
+#include "qliteral_p.h"
+#include "qpatternistlocale_p.h"
+#include "qtruthpredicate_p.h"
+
+#include "qgenericpredicate_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+GenericPredicate::GenericPredicate(const Expression::Ptr &sourceExpression,
+ const Expression::Ptr &predicate) : PairContainer(sourceExpression,
+ predicate)
+{
+}
+
+Expression::Ptr GenericPredicate::create(const Expression::Ptr &sourceExpression,
+ const Expression::Ptr &predicateExpression,
+ const StaticContext::Ptr &context,
+ const QSourceLocation &location)
+{
+ Q_ASSERT(sourceExpression);
+ Q_ASSERT(predicateExpression);
+ Q_ASSERT(context);
+ const ItemType::Ptr type(predicateExpression->staticType()->itemType());
+
+ if(predicateExpression->is(IDIntegerValue) &&
+ predicateExpression->as<Literal>()->item().as<Numeric>()->toInteger() == 1)
+ { /* Handle [1] */
+ return createFirstItem(sourceExpression);
+ }
+ else if(BuiltinTypes::numeric->xdtTypeMatches(type))
+ { /* A numeric predicate, other than [1]. */
+ /* TODO at somepoint we'll return a specialized expr here, NumericPredicate or so.
+ * Dependency analysis is a bit tricky, since the contained expression can depend on
+ * some loop component. */
+ return Expression::Ptr(new GenericPredicate(sourceExpression, predicateExpression));
+ }
+ else if(*CommonSequenceTypes::Empty == *type)
+ {
+ return EmptySequence::create(predicateExpression.data(), context);
+ }
+ else if(*BuiltinTypes::item == *type ||
+ *BuiltinTypes::xsAnyAtomicType == *type)
+ {
+ /* The type couldn't be narrowed at compile time, so we use
+ * a generic predicate. This check is before the CommonSequenceTypes::EBV check,
+ * because the latter matches these types as well. */
+ return Expression::Ptr(new GenericPredicate(sourceExpression, predicateExpression));
+ }
+ else if(CommonSequenceTypes::EBV->itemType()->xdtTypeMatches(type))
+ {
+ return Expression::Ptr(new TruthPredicate(sourceExpression, predicateExpression));
+ }
+ else
+ {
+ context->error(QtXmlPatterns::tr("A value of type %1 cannot be a "
+ "predicate. A predicate must have "
+ "either a numeric type or an "
+ "Effective Boolean Value type.")
+ .arg(formatType(context->namePool(),
+ sourceExpression->staticType())),
+ ReportContext::FORG0006, location);
+ return Expression::Ptr(); /* Silence compiler warning. */
+ }
+}
+
+Expression::Ptr GenericPredicate::createFirstItem(const Expression::Ptr &sourceExpression)
+
+{
+ return Expression::Ptr(new FirstItemPredicate(sourceExpression));
+}
+
+Item GenericPredicate::mapToItem(const Item &item,
+ const DynamicContext::Ptr &context) const
+{
+ const Item::Iterator::Ptr it(m_operand2->evaluateSequence(context));
+ const Item pcateItem(it->next());
+
+ if(!pcateItem)
+ return Item(); /* The predicate evaluated to the empty sequence */
+ else if(pcateItem.isNode())
+ return item;
+ /* Ok, now it must be an AtomicValue */
+ else if(BuiltinTypes::numeric->xdtTypeMatches(pcateItem.type()))
+ { /* It's a positional predicate. */
+ if(it->next())
+ {
+ context->error(QtXmlPatterns::tr("A positional predicate must "
+ "evaluate to a single numeric "
+ "value."),
+ ReportContext::FORG0006, this);
+ return Item();
+ }
+
+ if(Double::isEqual(static_cast<xsDouble>(context->contextPosition()),
+ pcateItem.as<Numeric>()->toDouble()))
+ {
+ return item;
+ }
+ else
+ return Item();
+ }
+ else if(Boolean::evaluateEBV(pcateItem, it, context)) /* It's a truth predicate. */
+ return item;
+ else
+ return Item();
+}
+
+Item::Iterator::Ptr GenericPredicate::evaluateSequence(const DynamicContext::Ptr &context) const
+{
+ const Item::Iterator::Ptr focus(m_operand1->evaluateSequence(context));
+ const DynamicContext::Ptr newContext(context->createFocus());
+ newContext->setFocusIterator(focus);
+
+ return makeItemMappingIterator<Item>(ConstPtr(this),
+ focus,
+ newContext);
+}
+
+Item GenericPredicate::evaluateSingleton(const DynamicContext::Ptr &context) const
+{
+ const Item::Iterator::Ptr focus(m_operand1->evaluateSequence(context));
+ const DynamicContext::Ptr newContext(context->createFocus());
+ newContext->setFocusIterator(focus);
+ return mapToItem(focus->next(), newContext);
+}
+
+SequenceType::List GenericPredicate::expectedOperandTypes() const
+{
+ SequenceType::List result;
+ result.append(CommonSequenceTypes::ZeroOrMoreItems);
+ result.append(CommonSequenceTypes::ZeroOrMoreItems);
+ return result;
+}
+
+SequenceType::Ptr GenericPredicate::staticType() const
+{
+ const SequenceType::Ptr type(m_operand1->staticType());
+ return makeGenericSequenceType(type->itemType(),
+ type->cardinality() | Cardinality::zeroOrOne());
+}
+
+ExpressionVisitorResult::Ptr GenericPredicate::accept(const ExpressionVisitor::Ptr &visitor) const
+{
+ return visitor->visit(this);
+}
+
+ItemType::Ptr GenericPredicate::newFocusType() const
+{
+ return m_operand1->staticType()->itemType();
+}
+
+Expression::Properties GenericPredicate::properties() const
+{
+ return CreatesFocusForLast;
+}
+
+QString GenericPredicate::description() const
+{
+ return QLatin1String("predicate");
+}
+
+Expression::ID GenericPredicate::id() const
+{
+ return IDGenericPredicate;
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/expr/qgenericpredicate_p.h b/src/xmlpatterns/expr/qgenericpredicate_p.h
new file mode 100644
index 0000000..d48e208
--- /dev/null
+++ b/src/xmlpatterns/expr/qgenericpredicate_p.h
@@ -0,0 +1,148 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_GenericPredicate_H
+#define Patternist_GenericPredicate_H
+
+#include "qpaircontainer_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short A predicate that can handle all kinds of predicates and
+ * is therefore not very efficient, but can cope with all the tricky scenarios.
+ *
+ * @see FirstItemPredicate
+ * @see TruthPredicate
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_expressions
+ */
+ class GenericPredicate : public PairContainer
+ {
+ public:
+
+ /**
+ * Creates a predicate expression that filters the items gained
+ * from evaluating @p sourceExpression through the filter @p predicateExpression.
+ *
+ * This function performs type analyzis on the passed expressions, and may
+ * return more specialized expressions depending on the analyzis.
+ *
+ * If @p predicateExpression is an invalid predicate, an error is issued
+ * via the @p context.
+ */
+ static Expression::Ptr create(const Expression::Ptr &sourceExpression,
+ const Expression::Ptr &predicateExpression,
+ const StaticContext::Ptr &context,
+ const QSourceLocation &location);
+
+ static Expression::Ptr createFirstItem(const Expression::Ptr &sourceExpression);
+
+ /**
+ * Creates a source iterator which is passed to the ItemMappingIterator
+ * and the Focus. The ItemMappingIterator modifies it with
+ * its QAbstractXmlForwardIterator::next() calls, and since the Focus references the same QAbstractXmlForwardIterator,
+ * the focus is automatically moved.
+ */
+ virtual Item::Iterator::Ptr evaluateSequence(const DynamicContext::Ptr &context) const;
+
+ /**
+ * Doesn't return the first item from calling evaluateSequence(), but does the mapping
+ * manually. This avoid allocating an ItemMappingIterator.
+ */
+ virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const;
+
+ inline Item mapToItem(const Item &subject,
+ const DynamicContext::Ptr &) const;
+
+ virtual SequenceType::List expectedOperandTypes() const;
+ virtual SequenceType::Ptr staticType() const;
+ virtual ExpressionVisitorResult::Ptr accept(const ExpressionVisitor::Ptr &visitor) const;
+ virtual ID id() const;
+
+ /**
+ * @returns always CreatesFocusForLast.
+ */
+ virtual Properties properties() const;
+
+ virtual QString description() const;
+
+ protected:
+
+ /**
+ * Creates a GenericPredicate which filters the items from the @p sourceExpression
+ * through @p predicate.
+ *
+ * This constructor is protected. The proper way to create predicates is via the static
+ * create() function.
+ */
+ GenericPredicate(const Expression::Ptr &sourceExpression,
+ const Expression::Ptr &predicate);
+
+ /**
+ * @returns the ItemType of the first operand's staticType().
+ */
+ virtual ItemType::Ptr newFocusType() const;
+
+ private:
+ typedef QExplicitlySharedDataPointer<const GenericPredicate> ConstPtr;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/expr/qifthenclause.cpp b/src/xmlpatterns/expr/qifthenclause.cpp
new file mode 100644
index 0000000..cd9cbc3
--- /dev/null
+++ b/src/xmlpatterns/expr/qifthenclause.cpp
@@ -0,0 +1,152 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qcommonsequencetypes_p.h"
+#include "qgenericsequencetype_p.h"
+#include "qoptimizationpasses_p.h"
+
+#include "qifthenclause_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+IfThenClause::IfThenClause(const Expression::Ptr &test,
+ const Expression::Ptr &then,
+ const Expression::Ptr &el) : TripleContainer(test, then, el)
+{
+}
+
+Item::Iterator::Ptr IfThenClause::evaluateSequence(const DynamicContext::Ptr &context) const
+{
+ return m_operand1->evaluateEBV(context)
+ ? m_operand2->evaluateSequence(context)
+ : m_operand3->evaluateSequence(context);
+}
+
+Item IfThenClause::evaluateSingleton(const DynamicContext::Ptr &context) const
+{
+ return m_operand1->evaluateEBV(context)
+ ? m_operand2->evaluateSingleton(context)
+ : m_operand3->evaluateSingleton(context);
+}
+
+bool IfThenClause::evaluateEBV(const DynamicContext::Ptr &context) const
+{
+ return m_operand1->evaluateEBV(context)
+ ? m_operand2->evaluateEBV(context)
+ : m_operand3->evaluateEBV(context);
+}
+
+void IfThenClause::evaluateToSequenceReceiver(const DynamicContext::Ptr &context) const
+{
+ if(m_operand1->evaluateEBV(context))
+ m_operand2->evaluateToSequenceReceiver(context);
+ else
+ m_operand3->evaluateToSequenceReceiver(context);
+}
+
+Expression::Ptr IfThenClause::compress(const StaticContext::Ptr &context)
+{
+ const Expression::Ptr me(TripleContainer::compress(context));
+
+ if(me != this)
+ return me;
+
+ /* All operands mustn't be evaluated in order for const folding to
+ * be possible. Let's see how far we get. */
+
+ if(m_operand1->isEvaluated())
+ {
+ if(m_operand1->evaluateEBV(context->dynamicContext()))
+ return m_operand2;
+ else
+ return m_operand3;
+ }
+ else
+ return me;
+}
+
+QList<QExplicitlySharedDataPointer<OptimizationPass> > IfThenClause::optimizationPasses() const
+{
+ return OptimizationPasses::ifThenPasses;
+}
+
+SequenceType::List IfThenClause::expectedOperandTypes() const
+{
+ SequenceType::List result;
+ result.append(CommonSequenceTypes::EBV);
+ result.append(CommonSequenceTypes::ZeroOrMoreItems);
+ result.append(CommonSequenceTypes::ZeroOrMoreItems);
+ return result;
+}
+
+SequenceType::Ptr IfThenClause::staticType() const
+{
+ const SequenceType::Ptr t1(m_operand2->staticType());
+ const SequenceType::Ptr t2(m_operand3->staticType());
+
+ return makeGenericSequenceType(t1->itemType() | t2->itemType(),
+ t1->cardinality() | t2->cardinality());
+}
+
+ExpressionVisitorResult::Ptr IfThenClause::accept(const ExpressionVisitor::Ptr &visitor) const
+{
+ return visitor->visit(this);
+}
+
+Expression::ID IfThenClause::id() const
+{
+ return IDIfThenClause;
+}
+
+/*
+Expression::Properties IfThenClause::properties() const
+{
+ return m_operand1->properties()
+ | m_operand2->properties()
+ | m_operand3->properties()
+ & ( Expression::RequiresFocus
+ | Expression::IsEvaluated
+ | Expression::DisableElimination);
+}
+*/
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/expr/qifthenclause_p.h b/src/xmlpatterns/expr/qifthenclause_p.h
new file mode 100644
index 0000000..e24d5d0
--- /dev/null
+++ b/src/xmlpatterns/expr/qifthenclause_p.h
@@ -0,0 +1,101 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_IfThenClause_H
+#define Patternist_IfThenClause_H
+
+#include "qtriplecontainer_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Implements XPath 2.0's conditional expression <tt>if([expr]) then [expr] else [expr]</tt>.
+ *
+ * @see <a href="http://www.w3.org/TR/xpath20/#id-conditionals">XML Path Language (XPath) 2.0,
+ * 3.8 Conditional Expressions</a>
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_expressions
+ */
+ class IfThenClause : public TripleContainer
+ {
+ public:
+ IfThenClause(const Expression::Ptr &test,
+ const Expression::Ptr &then,
+ const Expression::Ptr &el);
+
+ virtual bool evaluateEBV(const DynamicContext::Ptr &context) const;
+ virtual Item::Iterator::Ptr evaluateSequence(const DynamicContext::Ptr &context) const;
+ virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const;
+ virtual void evaluateToSequenceReceiver(const DynamicContext::Ptr &context) const;
+
+ virtual SequenceType::List expectedOperandTypes() const;
+ virtual Expression::Ptr compress(const StaticContext::Ptr &context);
+
+ virtual SequenceType::Ptr staticType() const;
+ virtual ExpressionVisitorResult::Ptr accept(const ExpressionVisitor::Ptr &visitor) const;
+ /**
+ * @returns IDIfThenClause
+ */
+ virtual ID id() const;
+ virtual QList<QExplicitlySharedDataPointer<OptimizationPass> > optimizationPasses() const;
+ //virtual Properties properties() const;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/expr/qinstanceof.cpp b/src/xmlpatterns/expr/qinstanceof.cpp
new file mode 100644
index 0000000..8e6e5ce
--- /dev/null
+++ b/src/xmlpatterns/expr/qinstanceof.cpp
@@ -0,0 +1,129 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qboolean_p.h"
+#include "qcommonsequencetypes_p.h"
+#include "qcommonvalues_p.h"
+#include "qliteral_p.h"
+
+#include "qinstanceof_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+InstanceOf::InstanceOf(const Expression::Ptr &operand,
+ const SequenceType::Ptr &tType) : SingleContainer(operand)
+ , m_targetType(tType)
+{
+ Q_ASSERT(m_targetType);
+}
+
+bool InstanceOf::evaluateEBV(const DynamicContext::Ptr &context) const
+{
+ const Item::Iterator::Ptr it(m_operand->evaluateSequence(context));
+ Item item(it->next());
+ unsigned int count = 1;
+
+ if(!item)
+ return m_targetType->cardinality().allowsEmpty();
+
+ do
+ {
+ if(!m_targetType->itemType()->itemMatches(item))
+ return false;
+
+ if(count == 2 && !m_targetType->cardinality().allowsMany())
+ return false;
+
+ item = it->next();
+ ++count;
+ } while(item);
+
+ return true;
+}
+
+Expression::Ptr InstanceOf::compress(const StaticContext::Ptr &context)
+{
+ const Expression::Ptr me(SingleContainer::compress(context));
+
+ if(me != this || m_operand->has(DisableTypingDeduction))
+ return me;
+
+ const SequenceType::Ptr opType(m_operand->staticType());
+ const ItemType::Ptr targetType(m_targetType->itemType());
+ const ItemType::Ptr operandType(opType->itemType());
+
+ if(m_targetType->cardinality().isMatch(opType->cardinality()))
+ {
+ if(*operandType == *CommonSequenceTypes::Empty || targetType->xdtTypeMatches(operandType))
+ return wrapLiteral(CommonValues::BooleanTrue, context, this);
+ else if(!operandType->xdtTypeMatches(targetType))
+ return wrapLiteral(CommonValues::BooleanFalse, context, this);
+ }
+ /* Optimization: rule out the case where instance of will always fail. */
+
+ return me;
+}
+
+SequenceType::Ptr InstanceOf::targetType() const
+{
+ return m_targetType;
+}
+
+SequenceType::Ptr InstanceOf::staticType() const
+{
+ return CommonSequenceTypes::ExactlyOneBoolean;
+}
+
+SequenceType::List InstanceOf::expectedOperandTypes() const
+{
+ SequenceType::List result;
+ result.append(CommonSequenceTypes::ZeroOrMoreItems);
+ return result;
+}
+
+ExpressionVisitorResult::Ptr InstanceOf::accept(const ExpressionVisitor::Ptr &visitor) const
+{
+ return visitor->visit(this);
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/expr/qinstanceof_p.h b/src/xmlpatterns/expr/qinstanceof_p.h
new file mode 100644
index 0000000..d3da026
--- /dev/null
+++ b/src/xmlpatterns/expr/qinstanceof_p.h
@@ -0,0 +1,101 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_InstanceOf_H
+#define Patternist_InstanceOf_H
+
+#include "qsinglecontainer_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+
+ /**
+ * @short Implements XPath 2.0's <tt>instance of</tt> expression.
+ *
+ * @see <a href="http://www.w3.org/TR/xpath20/#id-instance-of">XML Path Language (XPath) 2.0,
+ * 3.10.1 Instance Of</a>
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_expressions
+ */
+ class Q_AUTOTEST_EXPORT InstanceOf : public SingleContainer
+ {
+ public:
+
+ InstanceOf(const Expression::Ptr &operand,
+ const SequenceType::Ptr &targetType);
+
+ virtual bool evaluateEBV(const DynamicContext::Ptr &) const;
+
+ virtual SequenceType::List expectedOperandTypes() const;
+ virtual SequenceType::Ptr staticType() const;
+ virtual Expression::Ptr compress(const StaticContext::Ptr &context);
+ virtual ExpressionVisitorResult::Ptr accept(const ExpressionVisitor::Ptr &visitor) const;
+
+ /**
+ * @returns the SequenceType that this <tt>instance of</tt> Expression
+ * is testing its operand against.
+ */
+ SequenceType::Ptr targetType() const;
+
+ private:
+ const SequenceType::Ptr m_targetType;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/expr/qletclause.cpp b/src/xmlpatterns/expr/qletclause.cpp
new file mode 100644
index 0000000..d3e939b
--- /dev/null
+++ b/src/xmlpatterns/expr/qletclause.cpp
@@ -0,0 +1,142 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qboolean_p.h"
+#include "qcommonsequencetypes_p.h"
+#include "qdynamiccontextstore_p.h"
+#include "qliteral_p.h"
+
+#include "qletclause_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+LetClause::LetClause(const Expression::Ptr &operand1,
+ const Expression::Ptr &operand2,
+ const VariableDeclaration::Ptr &decl) : PairContainer(operand1, operand2)
+ , m_varDecl(decl)
+{
+ Q_ASSERT(m_varDecl);
+}
+
+DynamicContext::Ptr LetClause::bindVariable(const DynamicContext::Ptr &context) const
+{
+ context->setExpressionVariable(m_varDecl->slot, Expression::Ptr(new DynamicContextStore(m_operand1, context)));
+ return context;
+}
+
+Item::Iterator::Ptr LetClause::evaluateSequence(const DynamicContext::Ptr &context) const
+{
+ return m_operand2->evaluateSequence(bindVariable(context));
+}
+
+Item LetClause::evaluateSingleton(const DynamicContext::Ptr &context) const
+{
+ return m_operand2->evaluateSingleton(bindVariable(context));
+}
+
+bool LetClause::evaluateEBV(const DynamicContext::Ptr &context) const
+{
+ return m_operand2->evaluateEBV(bindVariable(context));
+}
+
+void LetClause::evaluateToSequenceReceiver(const DynamicContext::Ptr &context) const
+{
+ m_operand2->evaluateToSequenceReceiver(bindVariable(context));
+}
+
+Expression::Ptr LetClause::typeCheck(const StaticContext::Ptr &context,
+ const SequenceType::Ptr &reqType)
+{
+ /* Consider the following query:
+ *
+ * <tt>let $d := \<child type=""/>
+ * return $d//\*[let $i := @type
+ * return $d//\*[$i]]</tt>
+ *
+ * The node test <tt>@type</tt> is referenced from two different places,
+ * where each reference have a different focus. So, in the case of that the source
+ * uses the focus, we need to use a DynamicContextStore to ensure the variable
+ * is always evaluated with the correct focus, regardless of where it is referenced
+ * from.
+ *
+ * We miss out a lot of false positives. For instance, the case of where the focus
+ * is identical for everyone. One reason we cannot check this, is that Expression
+ * doesn't know about its parent.
+ */
+ m_varDecl->canSourceRewrite = !m_operand1->deepProperties().testFlag(RequiresFocus);
+
+ if(m_varDecl->canSourceRewrite)
+ return m_operand2->typeCheck(context, reqType);
+ else
+ return PairContainer::typeCheck(context, reqType);
+}
+
+Expression::Properties LetClause::properties() const
+{
+ return m_varDecl->expression()->properties() & (Expression::RequiresFocus | Expression::IsEvaluated | Expression::DisableElimination);
+}
+
+SequenceType::List LetClause::expectedOperandTypes() const
+{
+ SequenceType::List result;
+ result.append(CommonSequenceTypes::ZeroOrMoreItems);
+ result.append(CommonSequenceTypes::ZeroOrMoreItems);
+ return result;
+}
+
+SequenceType::Ptr LetClause::staticType() const
+{
+ return m_operand2->staticType();
+}
+
+ExpressionVisitorResult::Ptr LetClause::accept(const ExpressionVisitor::Ptr &visitor) const
+{
+ return visitor->visit(this);
+}
+
+Expression::ID LetClause::id() const
+{
+ return IDLetClause;
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/expr/qletclause_p.h b/src/xmlpatterns/expr/qletclause_p.h
new file mode 100644
index 0000000..24a7bb1
--- /dev/null
+++ b/src/xmlpatterns/expr/qletclause_p.h
@@ -0,0 +1,109 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_LetClause_H
+#define Patternist_LetClause_H
+
+#include "qpaircontainer_p.h"
+#include "qvariabledeclaration_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+
+ /**
+ * @short Represents a <tt>let</tt>-clause, but is only used at compile
+ * time.
+ *
+ * LetClause is inserted into the AST tree for the single purpose of
+ * ensuring that the focus is correct for the binding expression. Once
+ * that is done, LetClause sometimes rewrites itself to its
+ * <tt>return</tt> expression, and the ExpressionVariableReference will
+ * handle the evaluation of the variable.
+ *
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_expressions
+ */
+ class LetClause : public PairContainer
+ {
+ public:
+ LetClause(const Expression::Ptr &operand1,
+ const Expression::Ptr &operand2,
+ const VariableDeclaration::Ptr &decl);
+
+ virtual Item::Iterator::Ptr evaluateSequence(const DynamicContext::Ptr &context) const;
+ virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const;
+ virtual bool evaluateEBV(const DynamicContext::Ptr &context) const;
+ virtual void evaluateToSequenceReceiver(const DynamicContext::Ptr &context) const;
+
+ virtual SequenceType::List expectedOperandTypes() const;
+ virtual Expression::Ptr typeCheck(const StaticContext::Ptr &context,
+ const SequenceType::Ptr &reqType);
+ virtual SequenceType::Ptr staticType() const;
+ virtual Properties properties() const;
+ virtual ExpressionVisitorResult::Ptr accept(const ExpressionVisitor::Ptr &visitor) const;
+ virtual ID id() const;
+
+ private:
+ inline DynamicContext::Ptr bindVariable(const DynamicContext::Ptr &context) const;
+
+ const VariableDeclaration::Ptr m_varDecl;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/expr/qliteral.cpp b/src/xmlpatterns/expr/qliteral.cpp
new file mode 100644
index 0000000..ac68fe3
--- /dev/null
+++ b/src/xmlpatterns/expr/qliteral.cpp
@@ -0,0 +1,114 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qboolean_p.h"
+#include "qbuiltintypes_p.h"
+#include "qcommonsequencetypes_p.h"
+#include "qgenericsequencetype_p.h"
+
+#include "qliteral_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+Literal::Literal(const Item &i) : m_item(i)
+{
+ Q_ASSERT(m_item);
+ Q_ASSERT(m_item.isAtomicValue());
+}
+
+Item Literal::evaluateSingleton(const DynamicContext::Ptr &) const
+{
+ return m_item;
+}
+
+bool Literal::evaluateEBV(const DynamicContext::Ptr &context) const
+{
+ return Boolean::evaluateEBV(m_item, context);
+}
+
+void Literal::evaluateToSequenceReceiver(const DynamicContext::Ptr &context) const
+{
+ context->outputReceiver()->item(m_item);
+}
+
+SequenceType::Ptr Literal::staticType() const
+{
+ return makeGenericSequenceType(m_item.type(), Cardinality::exactlyOne());
+}
+
+ExpressionVisitorResult::Ptr Literal::accept(const ExpressionVisitor::Ptr &visitor) const
+{
+ return visitor->visit(this);
+}
+
+Expression::ID Literal::id() const
+{
+ Q_ASSERT(m_item);
+ Q_ASSERT(m_item.isAtomicValue());
+ const ItemType::Ptr t(m_item.type());
+
+ if(BuiltinTypes::xsBoolean->xdtTypeMatches(t))
+ return IDBooleanValue;
+ else if(BuiltinTypes::xsString->xdtTypeMatches(t) ||
+ BuiltinTypes::xsAnyURI->xdtTypeMatches(t) ||
+ BuiltinTypes::xsUntypedAtomic->xdtTypeMatches(t))
+ {
+ return IDStringValue;
+ }
+ else if(BuiltinTypes::xsInteger->xdtTypeMatches(t))
+ return IDIntegerValue;
+ else
+ return IDFloat;
+}
+
+Expression::Properties Literal::properties() const
+{
+ return IsEvaluated;
+}
+
+QString Literal::description() const
+{
+ return m_item.stringValue();
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/expr/qliteral_p.h b/src/xmlpatterns/expr/qliteral_p.h
new file mode 100644
index 0000000..aec7d53
--- /dev/null
+++ b/src/xmlpatterns/expr/qliteral_p.h
@@ -0,0 +1,148 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_Literal_H
+#define Patternist_Literal_H
+
+#include "qemptycontainer_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Houses an AtomicValue, making it available as an Expression.
+ *
+ * This is not only literals that can be created via the XQuery syntax(strings and numbers), but
+ * all other atomic values, such as <tt>xs:date</tt> or <tt>xs:time</tt>.
+ *
+ * @see <a href="http://www.w3.org/TR/xquery/#id-literals">XQuery 1.0: An XML Query Language,
+ * 3.1.1 Literals</a>
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_expressions
+ */
+ class Literal : public EmptyContainer
+ {
+ public:
+ /**
+ * Creates a Literal that represents @p item.
+ *
+ * @param item must be non-null and cannot be a QXmlNodeModelIndex.
+ */
+ Literal(const Item &item);
+
+ virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const;
+ virtual bool evaluateEBV(const DynamicContext::Ptr &context) const;
+ void evaluateToSequenceReceiver(const DynamicContext::Ptr &context) const;
+
+ virtual SequenceType::Ptr staticType() const;
+ virtual ExpressionVisitorResult::Ptr accept(const ExpressionVisitor::Ptr &visitor) const;
+ virtual ID id() const;
+ virtual QString description() const;
+
+ /**
+ * @returns Expression::DisableElimination and Expression::IsEvaluated
+ */
+ virtual Properties properties() const;
+
+ /**
+ * Declaring the return value of this function a const reference, leads
+ * to crashes in patternistview, for a to me unknown reason.
+ */
+ inline Item item() const
+ {
+ return m_item;
+ }
+
+ private:
+ const Item m_item;
+ };
+
+ /**
+ * @short Creates a Literal that wraps @p item, and returns it.
+ *
+ * This simplifies code. Instead of writing:
+ *
+ * @code
+ * Expression::Ptr(new Literal(item));
+ * @endcode
+ *
+ * One can write:
+ *
+ * @code
+ * wrapLiteral(item);
+ * @endcode
+ *
+ * This function is not declared static, because it breaks the build on
+ * at least aix-xlc-64.
+ *
+ * @relates Literal
+ */
+ inline Expression::Ptr wrapLiteral(const Item &item,
+ const StaticContext::Ptr &context,
+ const SourceLocationReflection *const r)
+ {
+ Q_ASSERT(item);
+
+ const Expression::Ptr retval(new Literal(item));
+ context->addLocation(retval.data(), context->locationFor(r));
+
+ return retval;
+ }
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/expr/qliteralsequence.cpp b/src/xmlpatterns/expr/qliteralsequence.cpp
new file mode 100644
index 0000000..dfd0fd6
--- /dev/null
+++ b/src/xmlpatterns/expr/qliteralsequence.cpp
@@ -0,0 +1,92 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qbuiltintypes_p.h"
+#include "qcommonsequencetypes_p.h"
+#include "qgenericsequencetype_p.h"
+
+#include "qliteralsequence_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+LiteralSequence::LiteralSequence(const Item::List &list) : m_list(list)
+{
+ Q_ASSERT(list.size() >= 2);
+}
+
+Item::Iterator::Ptr LiteralSequence::evaluateSequence(const DynamicContext::Ptr &) const
+{
+ return makeListIterator(m_list);
+}
+
+SequenceType::Ptr LiteralSequence::staticType() const
+{
+ const Item::List::const_iterator end(m_list.constEnd());
+ Item::List::const_iterator it(m_list.constBegin());
+
+ /* Load the first item. */
+ ItemType::Ptr t((*it).type());
+ ++it;
+
+ for(; end != it; ++it)
+ t |= (*it).type();
+
+ return makeGenericSequenceType(t, Cardinality::fromCount(m_list.size()));
+}
+
+ExpressionVisitorResult::Ptr LiteralSequence::accept(const ExpressionVisitor::Ptr &visitor) const
+{
+ return visitor->visit(this);
+}
+
+Expression::ID LiteralSequence::id() const
+{
+ return IDExpressionSequence;
+}
+
+Expression::Properties LiteralSequence::properties() const
+{
+ return IsEvaluated;
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/expr/qliteralsequence_p.h b/src/xmlpatterns/expr/qliteralsequence_p.h
new file mode 100644
index 0000000..6699ce0
--- /dev/null
+++ b/src/xmlpatterns/expr/qliteralsequence_p.h
@@ -0,0 +1,104 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_LiteralSequence_H
+#define Patternist_LiteralSequence_H
+
+#include "qemptycontainer_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Houses a sequence of atomic values, making it available as an Expression.
+ *
+ * This is not only literals that can be created via the XQuery syntax(strings and numbers), but
+ * all other atomic values, such as <tt>xs:date</tt> or <tt>xs:time</tt>. It is not guaranteed
+ * that consecutive atomic values are represented in a LiteralSequence.
+ *
+ * @see <a href="http://www.w3.org/TR/xquery/#id-literals">XQuery 1.0: An XML Query Language,
+ * 3.1.1 Literals</a>
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_expressions
+ */
+ class LiteralSequence : public EmptyContainer
+ {
+ public:
+ /**
+ * Creates a LiteralSequence that represents @p item.
+ *
+ * @param list the list of item. No entry may be @c null. The list
+ * must at least be two entries large.
+ */
+ LiteralSequence(const Item::List &list);
+
+ virtual Item::Iterator::Ptr evaluateSequence(const DynamicContext::Ptr &context) const;
+ virtual SequenceType::Ptr staticType() const;
+
+ virtual ExpressionVisitorResult::Ptr accept(const ExpressionVisitor::Ptr &visitor) const;
+
+ virtual ID id() const;
+
+ virtual Properties properties() const;
+
+ private:
+ const Item::List m_list;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/expr/qnamespaceconstructor.cpp b/src/xmlpatterns/expr/qnamespaceconstructor.cpp
new file mode 100644
index 0000000..c6838ee
--- /dev/null
+++ b/src/xmlpatterns/expr/qnamespaceconstructor.cpp
@@ -0,0 +1,87 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qcommonsequencetypes_p.h"
+
+#include "qnamespaceconstructor_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+NamespaceConstructor::NamespaceConstructor(const QXmlName nb) : m_binding(nb)
+{
+ Q_ASSERT(!m_binding.isNull());
+}
+
+void NamespaceConstructor::evaluateToSequenceReceiver(const DynamicContext::Ptr &context) const
+{
+ context->outputReceiver()->namespaceBinding(m_binding);
+}
+
+SequenceType::Ptr NamespaceConstructor::staticType() const
+{
+ return CommonSequenceTypes::ExactlyOneAttribute;
+}
+
+SequenceType::List NamespaceConstructor::expectedOperandTypes() const
+{
+ SequenceType::List result;
+ result.append(CommonSequenceTypes::ExactlyOneString);
+ return result;
+}
+
+Expression::Properties NamespaceConstructor::properties() const
+{
+ return DisableElimination | IsNodeConstructor;
+}
+
+ExpressionVisitorResult::Ptr NamespaceConstructor::accept(const ExpressionVisitor::Ptr &visitor) const
+{
+ return visitor->visit(this);
+}
+
+Expression::ID NamespaceConstructor::id() const
+{
+ return IDNamespaceConstructor;
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/expr/qnamespaceconstructor_p.h b/src/xmlpatterns/expr/qnamespaceconstructor_p.h
new file mode 100644
index 0000000..5b73d37
--- /dev/null
+++ b/src/xmlpatterns/expr/qnamespaceconstructor_p.h
@@ -0,0 +1,109 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_NamespaceConstructor_H
+#define Patternist_NamespaceConstructor_H
+
+#include "qemptycontainer_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Constructs a namespace on an element, and naturally only appears
+ * as a child of ElementConstructor.
+ *
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_expressions
+ */
+ class NamespaceConstructor : public EmptyContainer
+ {
+ public:
+ NamespaceConstructor(const QXmlName nb);
+
+ virtual void evaluateToSequenceReceiver(const DynamicContext::Ptr &context) const;
+
+ /**
+ * @returns a list containing one CommonSequenceTypes::ExactlyOneString instance.
+ */
+ virtual SequenceType::List expectedOperandTypes() const;
+
+ /**
+ * The static type is exactly one attribute node. It's unclear what
+ * affects the static type has, but specifying anything else could lead
+ * to complications wrt. node order, XQTY0024. Of course, it's not
+ * conceptually correct, since a namespace node isn't an attribute
+ * node.
+ */
+ virtual SequenceType::Ptr staticType() const;
+
+ virtual ExpressionVisitorResult::Ptr accept(const ExpressionVisitor::Ptr &visitor) const;
+ virtual Expression::Properties properties() const;
+
+ inline const QXmlName &namespaceBinding() const
+ {
+ return m_binding;
+ }
+
+ virtual ID id() const;
+ private:
+ const QXmlName m_binding;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/expr/qncnameconstructor.cpp b/src/xmlpatterns/expr/qncnameconstructor.cpp
new file mode 100644
index 0000000..b1d2739
--- /dev/null
+++ b/src/xmlpatterns/expr/qncnameconstructor.cpp
@@ -0,0 +1,96 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qbuiltintypes_p.h"
+#include "qcommonsequencetypes_p.h"
+#include "qatomicstring_p.h"
+
+#include "qncnameconstructor_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+NCNameConstructor::NCNameConstructor(const Expression::Ptr &source) : SingleContainer(source)
+{
+}
+
+Item NCNameConstructor::evaluateSingleton(const DynamicContext::Ptr &context) const
+{
+ Q_ASSERT(context);
+ /* Apply the whitespace facet for when casting to xs:NCName. */
+ const QString lexNCName(m_operand->evaluateSingleton(context).stringValue().trimmed());
+
+ validateTargetName<DynamicContext::Ptr,
+ ReportContext::XQDY0064,
+ ReportContext::XQDY0041>(lexNCName,
+ context,
+ this);
+ return AtomicString::fromValue(lexNCName);
+}
+
+Expression::Ptr NCNameConstructor::typeCheck(const StaticContext::Ptr &context,
+ const SequenceType::Ptr &reqType)
+{
+ if(BuiltinTypes::xsNCName->xdtTypeMatches(m_operand->staticType()->itemType()))
+ return m_operand->typeCheck(context, reqType);
+ else
+ return SingleContainer::typeCheck(context, reqType);
+}
+
+SequenceType::Ptr NCNameConstructor::staticType() const
+{
+ return CommonSequenceTypes::ExactlyOneString;
+}
+
+SequenceType::List NCNameConstructor::expectedOperandTypes() const
+{
+ SequenceType::List result;
+ result.append(CommonSequenceTypes::ExactlyOneString);
+ return result;
+}
+
+ExpressionVisitorResult::Ptr NCNameConstructor::accept(const ExpressionVisitor::Ptr &visitor) const
+{
+ return visitor->visit(this);
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/expr/qncnameconstructor_p.h b/src/xmlpatterns/expr/qncnameconstructor_p.h
new file mode 100644
index 0000000..02163c5
--- /dev/null
+++ b/src/xmlpatterns/expr/qncnameconstructor_p.h
@@ -0,0 +1,154 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_NCNameConstructor_H
+#define Patternist_NCNameConstructor_H
+
+#include "qsinglecontainer_p.h"
+#include "qpatternistlocale_p.h"
+#include "private/qxmlutils_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Ensures the lexical space of the string value of the Item returned
+ * from its child Expression is an NCName.
+ *
+ * @note It doesn't actually construct an @c xs:NCName. It only ensures the lexical
+ * space is an @c NCName. The atomic value can be of any string type, such as @c xs:untypedAtomic
+ * of @c xs:string.
+ *
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_expressions
+ */
+ class NCNameConstructor : public SingleContainer
+ {
+ public:
+
+ NCNameConstructor(const Expression::Ptr &source);
+
+ virtual Item evaluateSingleton(const DynamicContext::Ptr &) const;
+
+ virtual SequenceType::List expectedOperandTypes() const;
+
+ virtual Expression::Ptr typeCheck(const StaticContext::Ptr &context,
+ const SequenceType::Ptr &reqType);
+
+ virtual SequenceType::Ptr staticType() const;
+
+ virtual ExpressionVisitorResult::Ptr accept(const ExpressionVisitor::Ptr &visitor) const;
+
+ /**
+ * Validates @p lexicalNCName as a processing instruction's target
+ * name, and raise an error if it's not an @c NCName.
+ */
+ template<typename TReportContext,
+ const ReportContext::ErrorCode NameIsXML,
+ const ReportContext::ErrorCode LexicallyInvalid>
+ static inline
+ void validateTargetName(const QString &lexicalNCName,
+ const TReportContext &context,
+ const SourceLocationReflection *const r);
+ private:
+
+ /**
+ * This translation string is put here in order to avoid duplicate messages and
+ * hence reduce work for translators and increase consistency.
+ */
+ static
+ const QString nameIsXML(const QString &lexTarget)
+ {
+ return QtXmlPatterns::tr("The target name in a processing instruction "
+ "cannot be %1 in any combination of upper "
+ "and lower case. Therefore, %2 is invalid.")
+ .arg(formatKeyword("xml"), formatKeyword(lexTarget));
+ }
+ };
+
+ template<typename TReportContext,
+ const ReportContext::ErrorCode NameIsXML,
+ const ReportContext::ErrorCode LexicallyInvalid>
+ inline
+ void NCNameConstructor::validateTargetName(const QString &lexicalTarget,
+ const TReportContext &context,
+ const SourceLocationReflection *const r)
+ {
+ Q_ASSERT(context);
+
+ if(QXmlUtils::isNCName(lexicalTarget))
+ {
+ if(QString::compare(QLatin1String("xml"), lexicalTarget, Qt::CaseInsensitive) == 0)
+ context->error(nameIsXML(lexicalTarget), NameIsXML, r);
+ }
+ else
+ {
+ context->error(QtXmlPatterns::tr("%1 is not a valid target name in "
+ "a processing instruction. It "
+ "must be a %2 value, e.g. %3.")
+ .arg(formatKeyword(lexicalTarget))
+ .arg(formatType(context->namePool(),
+ BuiltinTypes::xsNCName))
+ .arg(formatKeyword("my-name.123")),
+ LexicallyInvalid,
+ r);
+ }
+ }
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/expr/qnodecomparison.cpp b/src/xmlpatterns/expr/qnodecomparison.cpp
new file mode 100644
index 0000000..ba262fd
--- /dev/null
+++ b/src/xmlpatterns/expr/qnodecomparison.cpp
@@ -0,0 +1,184 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qcommonsequencetypes_p.h"
+#include "qcommonvalues_p.h"
+#include "qemptysequence_p.h"
+#include "qinteger_p.h"
+#include "qschemanumeric_p.h"
+#include "qrangeiterator_p.h"
+
+#include "qnodecomparison_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+NodeComparison::NodeComparison(const Expression::Ptr &operand1,
+ const QXmlNodeModelIndex::DocumentOrder op,
+ const Expression::Ptr &operand2)
+ : PairContainer(operand1, operand2)
+ , m_op(op)
+{
+ Q_ASSERT(op == QXmlNodeModelIndex::Precedes ||
+ op == QXmlNodeModelIndex::Follows ||
+ op == QXmlNodeModelIndex::Is);
+}
+
+Item NodeComparison::evaluateSingleton(const DynamicContext::Ptr &context) const
+{
+ switch(evaluate(context))
+ {
+ case True:
+ return CommonValues::BooleanTrue;
+ case False:
+ return CommonValues::BooleanFalse;
+ default:
+ return Item();
+ }
+}
+
+bool NodeComparison::evaluateEBV(const DynamicContext::Ptr &context) const
+{
+ switch(evaluate(context))
+ {
+ case True:
+ return true;
+ default:
+ /* We include the empty sequence here. */
+ return false;
+ }
+}
+
+NodeComparison::Result NodeComparison::evaluate(const DynamicContext::Ptr &context) const
+{
+ const Item op1(m_operand1->evaluateSingleton(context));
+ if(!op1)
+ return Empty;
+
+ const Item op2(m_operand2->evaluateSingleton(context));
+ if(!op2)
+ return Empty;
+
+ /* We just returns an arbitrary value, since there's no order defined for nodes from different
+ * models, except for that the return value must be stable. */
+ if(op1.asNode().model() != op2.asNode().model())
+ return False;
+
+ switch(m_op)
+ {
+ case QXmlNodeModelIndex::Is:
+ return op1.asNode().is(op2.asNode()) ? True : False;
+ case QXmlNodeModelIndex::Precedes:
+ return op1.asNode().compareOrder(op2.asNode()) == QXmlNodeModelIndex::Precedes ? True : False;
+ default:
+ {
+ Q_ASSERT(m_op == QXmlNodeModelIndex::Follows);
+ return op1.asNode().compareOrder(op2.asNode()) == QXmlNodeModelIndex::Follows ? True : False;
+ }
+ }
+}
+
+
+SequenceType::List NodeComparison::expectedOperandTypes() const
+{
+ SequenceType::List result;
+ result.append(CommonSequenceTypes::ZeroOrOneNode);
+ result.append(CommonSequenceTypes::ZeroOrOneNode);
+ return result;
+}
+
+Expression::Ptr NodeComparison::compress(const StaticContext::Ptr &context)
+{
+ const Expression::Ptr me(PairContainer::compress(context));
+
+ if(me != this)
+ /* We're already rewritten. */
+ return me;
+
+ if(m_operand1->staticType()->cardinality().isEmpty() ||
+ m_operand2->staticType()->cardinality().isEmpty())
+ {
+ // TODO issue a warning in the @p context saying that one of the operands
+ // were empty, and that the expression always result in the empty sequence
+ // (which never is the intent, right?).
+ return EmptySequence::create(this, context);
+ }
+
+ return Expression::Ptr(this);
+}
+
+QString NodeComparison::displayName(const QXmlNodeModelIndex::DocumentOrder op)
+{
+ switch(op)
+ {
+ case QXmlNodeModelIndex::Is:
+ return QLatin1String("is");
+ case QXmlNodeModelIndex::Precedes:
+ return QLatin1String("<<");
+ default:
+ {
+ Q_ASSERT(op == QXmlNodeModelIndex::Follows);
+ return QLatin1String(">>");
+ }
+ }
+}
+
+SequenceType::Ptr NodeComparison::staticType() const
+{
+ if(m_operand1->staticType()->cardinality().allowsEmpty() ||
+ m_operand2->staticType()->cardinality().allowsEmpty())
+ return CommonSequenceTypes::ZeroOrOneBoolean;
+ else
+ return CommonSequenceTypes::ExactlyOneBoolean;
+}
+
+QXmlNodeModelIndex::DocumentOrder NodeComparison::operatorID() const
+{
+ return m_op;
+}
+
+ExpressionVisitorResult::Ptr NodeComparison::accept(const ExpressionVisitor::Ptr &visitor) const
+{
+ return visitor->visit(this);
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/expr/qnodecomparison_p.h b/src/xmlpatterns/expr/qnodecomparison_p.h
new file mode 100644
index 0000000..86af0f6
--- /dev/null
+++ b/src/xmlpatterns/expr/qnodecomparison_p.h
@@ -0,0 +1,127 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_NodeComparison_H
+#define Patternist_NodeComparison_H
+
+#include "qpaircontainer_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+
+ /**
+ * @short Implements the node comparison operators <tt>\>\></tt>, <tt>\<\<</tt>, and @c is.
+ *
+ * @see <a href="http://www.w3.org/TR/xpath20/#id-node-comparisons">XML Path Language
+ * (XPath) 2.0, 3.5.3 QXmlNodeModelIndex Comparisons</a>
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_expressions
+ */
+ class Q_AUTOTEST_EXPORT NodeComparison : public PairContainer
+ {
+ public:
+ NodeComparison(const Expression::Ptr &operand1,
+ const QXmlNodeModelIndex::DocumentOrder op,
+ const Expression::Ptr &operand2);
+
+ virtual Item evaluateSingleton(const DynamicContext::Ptr &) const;
+ virtual bool evaluateEBV(const DynamicContext::Ptr &) const;
+
+ virtual SequenceType::List expectedOperandTypes() const;
+
+ virtual QXmlNodeModelIndex::DocumentOrder operatorID() const;
+ /**
+ * If any operator is the empty sequence, the NodeComparison rewrites
+ * into that, since the empty sequence is always the result in that case.
+ */
+ virtual Expression::Ptr compress(const StaticContext::Ptr &context);
+
+ /**
+ * @returns either CommonSequenceTypes::ZeroOrOneBoolean or
+ * CommonSequenceTypes::ExactlyOneBoolean depending on the static
+ * cardinality of its operands.
+ */
+ virtual SequenceType::Ptr staticType() const;
+
+ /**
+ * Determines the string representation for a node comparison operator.
+ *
+ * @returns
+ * - "<<" if @p op is Precedes
+ * - ">>" if @p op is Follows
+ * - "is" if @p op is Is
+ */
+ static QString displayName(const QXmlNodeModelIndex::DocumentOrder op);
+
+ virtual ExpressionVisitorResult::Ptr accept(const ExpressionVisitor::Ptr &visitor) const;
+ private:
+ enum Result
+ {
+ Empty,
+ True,
+ False
+ };
+ inline Result evaluate(const DynamicContext::Ptr &context) const;
+
+ const QXmlNodeModelIndex::DocumentOrder m_op;
+
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/expr/qnodesort.cpp b/src/xmlpatterns/expr/qnodesort.cpp
new file mode 100644
index 0000000..171fbc0
--- /dev/null
+++ b/src/xmlpatterns/expr/qnodesort.cpp
@@ -0,0 +1,142 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qcommonsequencetypes_p.h"
+#include "qdeduplicateiterator_p.h"
+#include "qnodesort_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+NodeSortExpression::NodeSortExpression(const Expression::Ptr &op) : SingleContainer(op)
+{
+}
+
+bool NodeSortExpression::lessThanUsingNodeModel(const Item &n1,
+ const Item &n2)
+{
+ Q_ASSERT(n1.isNode());
+ Q_ASSERT(n2.isNode());
+
+ if(n1.asNode().model() == n2.asNode().model())
+ return n1.asNode().compareOrder(n2.asNode()) == QXmlNodeModelIndex::Precedes;
+ else
+ {
+ /* The two nodes are from different trees. The sort order is implementation
+ * defined, but it must be stable.
+ *
+ * We do this by looking at the pointer difference. The value means nothing,
+ * but it is stable, and that's what we're looking for. */
+ return n1.asNode().model() - n2.asNode().model() < 0;
+ }
+}
+
+Item::Iterator::Ptr NodeSortExpression::evaluateSequence(const DynamicContext::Ptr &context) const
+{
+ Q_ASSERT_X(m_operand->staticType()->cardinality().allowsMany(), Q_FUNC_INFO,
+ "It makes no sense to sort a single node.");
+
+ Item::List nodes(m_operand->evaluateSequence(context)->toList());
+
+ if(nodes.isEmpty())
+ return CommonValues::emptyIterator;
+ else if(nodes.first().isAtomicValue())
+ return makeListIterator(nodes);
+ else
+ {
+ qSort(nodes.begin(), nodes.end(), lessThanUsingNodeModel);
+
+ return Item::Iterator::Ptr(new DeduplicateIterator(nodes));
+ }
+}
+
+Expression::Ptr NodeSortExpression::wrapAround(const Expression::Ptr &operand,
+ const StaticContext::Ptr &context)
+{
+ Q_ASSERT(operand);
+ Q_ASSERT(context);
+
+ const Expression::Ptr sort(new NodeSortExpression(operand));
+ context->wrapExpressionWith(operand.data(), sort);
+ return sort;
+}
+
+Expression::Ptr NodeSortExpression::compress(const StaticContext::Ptr &context)
+{
+ const Expression::Ptr me(SingleContainer::compress(context));
+
+ /* It make no sense to sort & deduplicate a single node. */
+ if(m_operand->staticType()->cardinality().allowsMany())
+ return me;
+ else
+ return m_operand;
+}
+
+SequenceType::Ptr NodeSortExpression::staticType() const
+{
+ return m_operand->staticType();
+}
+
+SequenceType::List NodeSortExpression::expectedOperandTypes() const
+{
+ SequenceType::List result;
+ result.append(CommonSequenceTypes::ZeroOrMoreItems);
+ return result;
+}
+
+ExpressionVisitorResult::Ptr
+NodeSortExpression::accept(const ExpressionVisitor::Ptr &visitor) const
+{
+ return visitor->visit(this);
+}
+
+Expression::Properties NodeSortExpression::properties() const
+{
+ /* The reason we disable elimination is that the assert for sorting a
+ * single node in evaluateSequence() triggers unless our compress() routine
+ * has been run. Anyhow, it's not that we would manage to write away anyway,
+ * since the node source in most(all?) cases prevents it.
+ */
+ return AffectsOrderOnly | DisableElimination;
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/expr/qnodesort_p.h b/src/xmlpatterns/expr/qnodesort_p.h
new file mode 100644
index 0000000..850023b
--- /dev/null
+++ b/src/xmlpatterns/expr/qnodesort_p.h
@@ -0,0 +1,98 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_NodeSortExpression_H
+#define Patternist_NodeSortExpression_H
+
+#include "qsinglecontainer_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short De-duplicates and sorts in document order the content that its
+ * operand returns.
+ *
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_expressions
+ */
+ class NodeSortExpression : public SingleContainer
+ {
+ public:
+ NodeSortExpression(const Expression::Ptr &operand);
+
+ virtual Item::Iterator::Ptr evaluateSequence(const DynamicContext::Ptr &context) const;
+ virtual SequenceType::Ptr staticType() const;
+ virtual SequenceType::List expectedOperandTypes() const;
+ virtual Expression::Ptr compress(const StaticContext::Ptr &context);
+ virtual ExpressionVisitorResult::Ptr accept(const ExpressionVisitor::Ptr &visitor) const;
+ virtual Properties properties() const;
+
+ /**
+ * Ensures that result delivered from @p operand, is in document order.
+ */
+ static Expression::Ptr wrapAround(const Expression::Ptr &operand,
+ const StaticContext::Ptr &context);
+
+ private:
+ static inline bool lessThanUsingNodeModel(const Item &n1,
+ const Item &n2);
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/expr/qoperandsiterator_p.h b/src/xmlpatterns/expr/qoperandsiterator_p.h
new file mode 100644
index 0000000..9986ef2
--- /dev/null
+++ b/src/xmlpatterns/expr/qoperandsiterator_p.h
@@ -0,0 +1,193 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_OperandsIterator_H
+#define Patternist_OperandsIterator_H
+
+#include <QPair>
+#include <QStack>
+
+#include "qexpression_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short A helper class that iterates a tree of Expression instances. It
+ * is not a sub-class of QAbstractXmlForwardIterator.
+ *
+ * The OperandsIterator delivers all Expression instances that are children at any
+ * depth of the Expression passed in the constructor.
+ * The order is delivered in a defined way, from left to right and depth
+ * first.
+ *
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class OperandsIterator
+ {
+ /**
+ * The second value, the int, is the current position in the first.
+ */
+ typedef QPair<Expression::List, int> Level;
+
+ public:
+ enum TreatParent
+ {
+ ExcludeParent,
+ IncludeParent
+ };
+
+ /**
+ * if @p treatParent is @c IncludeParent, @p start is excluded.
+ *
+ * @p start must be a valid Expression.
+ */
+ inline OperandsIterator(const Expression::Ptr &start,
+ const TreatParent treatParent)
+ {
+ Q_ASSERT(start);
+ if(treatParent == IncludeParent)
+ {
+ Expression::List l;
+ l.append(start);
+ m_exprs.push(qMakePair(l, -1));
+ }
+
+ m_exprs.push(qMakePair(start->operands(), -1));
+ }
+
+ /**
+ * @short Returns the current Expression and advances the iterator.
+ *
+ * If the end has been reached, a default constructed pointer is
+ * returned.
+ *
+ * We intentionally return by reference.
+ */
+ inline Expression::Ptr next()
+ {
+ if(m_exprs.isEmpty())
+ return Expression::Ptr();
+
+ Level &lvl = m_exprs.top();
+ ++lvl.second;
+
+ if(lvl.second == lvl.first.size())
+ {
+ /* Resume iteration above us. */
+ m_exprs.pop();
+
+ if(m_exprs.isEmpty())
+ return Expression::Ptr();
+
+ while(true)
+ {
+ Level &previous = m_exprs.top();
+ ++previous.second;
+
+ if(previous.second < previous.first.count())
+ {
+ const Expression::Ptr &op = previous.first.at(previous.second);
+ m_exprs.push(qMakePair(op->operands(), -1));
+ return op;
+ }
+ else
+ {
+ // We have already reached the end of this level.
+ m_exprs.pop();
+ if(m_exprs.isEmpty())
+ return Expression::Ptr();
+ }
+ }
+ }
+ else
+ {
+ const Expression::Ptr &op = lvl.first.at(lvl.second);
+ m_exprs.push(qMakePair(op->operands(), -1));
+ return op;
+ }
+ }
+
+ /**
+ * Advances this iterator by the current expression and its operands.
+ */
+ Expression::Ptr skipOperands()
+ {
+ if(m_exprs.isEmpty())
+ return Expression::Ptr();
+
+ Level &lvl = m_exprs.top();
+ ++lvl.second;
+
+ if(lvl.second == lvl.first.size())
+ {
+ /* We've reached the end of this level, at least. */
+ m_exprs.pop();
+ }
+
+ return next();
+ }
+
+ private:
+ Q_DISABLE_COPY(OperandsIterator)
+
+ QStack<Level> m_exprs;
+ };
+}
+
+
+QT_END_NAMESPACE
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/expr/qoptimizationpasses.cpp b/src/xmlpatterns/expr/qoptimizationpasses.cpp
new file mode 100644
index 0000000..d970483
--- /dev/null
+++ b/src/xmlpatterns/expr/qoptimizationpasses.cpp
@@ -0,0 +1,182 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qcommonsequencetypes_p.h"
+#include "qoptimizerblocks_p.h"
+
+#include "qoptimizationpasses_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+OptimizationPass::List OptimizationPasses::comparisonPasses;
+OptimizationPass::List OptimizationPasses::forPasses;
+OptimizationPass::List OptimizationPasses::ifThenPasses;
+OptimizationPass::List OptimizationPasses::notFN;
+
+void OptimizationPasses::Coordinator::init()
+{
+ static bool isInitialized = false; // STATIC DATA
+
+ if(isInitialized)
+ return;
+
+ isInitialized = true;
+
+ /* Note, below is many of the building blocks re-used in several passes
+ * in order to reduce memory use. Thus, when changing one building block
+ * it potentially affects many passes. */
+
+ /* ****************************************************** */
+ /* Rewrite "count(<expr>) ge 1" into "exists(<expr>)" */
+ OptimizationPass::ExpressionMarker firstFirstChild;
+ firstFirstChild.append(0);
+ firstFirstChild.append(0);
+
+ ExpressionIdentifier::List geOpIDs;
+ const ExpressionIdentifier::Ptr countFN(new ByIDIdentifier(Expression::IDCountFN));
+ geOpIDs.append(countFN);
+ geOpIDs.append(ExpressionIdentifier::Ptr(new IntegerIdentifier(1)));
+
+ QVector<Expression::ID> geMatcher;
+ geMatcher.append(Expression::IDValueComparison);
+ geMatcher.append(Expression::IDGeneralComparison);
+
+ const ExpressionIdentifier::Ptr ge(new ComparisonIdentifier(geMatcher,
+ AtomicComparator::OperatorGreaterOrEqual));
+
+ const ExpressionCreator::Ptr existsFN(new ByIDCreator(Expression::IDExistsFN));
+ const OptimizationPass::Ptr geToExists(new OptimizationPass(ge, geOpIDs, firstFirstChild, existsFN));
+ comparisonPasses.append(geToExists);
+ /* ****************************************************** */
+
+ /* ****************************************************** */
+ /* Rewrite "count(<expr>) gt 0" into "exists(<expr>)" */
+ ExpressionIdentifier::List countAndIntZero;
+ countAndIntZero.append(countFN);
+ const ExpressionIdentifier::Ptr zeroInteger(new IntegerIdentifier(0));
+ countAndIntZero.append(zeroInteger);
+
+ const ExpressionIdentifier::Ptr gt(new ComparisonIdentifier(geMatcher,
+ AtomicComparator::OperatorGreaterThan));
+
+ const OptimizationPass::Ptr gtToExists(new OptimizationPass(gt, countAndIntZero,
+ firstFirstChild, existsFN));
+ comparisonPasses.append(gtToExists);
+ /* ****************************************************** */
+
+ /* ****************************************************** */
+ /* Rewrite "count(<expr>) ne 0" into "exists(<expr>)" */
+
+ const ExpressionIdentifier::Ptr ne(new ComparisonIdentifier(geMatcher,
+ AtomicComparator::OperatorNotEqual));
+ const OptimizationPass::Ptr neToExists(new OptimizationPass(ne, countAndIntZero, firstFirstChild,
+ existsFN,
+ OptimizationPass::AnyOrder));
+ comparisonPasses.append(neToExists);
+ /* ****************************************************** */
+
+ /* ****************************************************** */
+ /* Rewrite "count(<expr>) eq 0" into "empty(<expr>)" */
+ ExpressionIdentifier::List eqOpIDs;
+ eqOpIDs.append(countFN);
+ eqOpIDs.append(zeroInteger);
+ const ExpressionCreator::Ptr emptyFN(new ByIDCreator(Expression::IDEmptyFN));
+ const ExpressionIdentifier::Ptr eq(new ComparisonIdentifier(geMatcher,
+ AtomicComparator::OperatorEqual));
+ const OptimizationPass::Ptr eqToEmpty(new OptimizationPass(eq, eqOpIDs, firstFirstChild,
+ emptyFN,
+ OptimizationPass::AnyOrder));
+ comparisonPasses.append(eqToEmpty);
+
+ /* ****************************************************** */
+
+ /* ****************************************************** */
+ /* Rewrite "for $var in <expr> return $var" into "<expr>" */
+ ExpressionIdentifier::List forOps;
+ OptimizationPass::ExpressionMarker firstChild;
+ firstChild.append(0);
+
+ forOps.append(ExpressionIdentifier::Ptr());
+ forOps.append(ExpressionIdentifier::Ptr(new ByIDIdentifier(Expression::IDRangeVariableReference)));
+ const OptimizationPass::Ptr simplifyFor(new OptimizationPass(ExpressionIdentifier::Ptr(), forOps,
+ firstChild, ExpressionCreator::Ptr()));
+ forPasses.append(simplifyFor);
+ /* ****************************************************** */
+
+ /* ****************************************************** */
+ /* Rewrite "if(<expr>) then true() else false()" to "<expr>" */
+ OptimizationPass::ExpressionMarker marker;
+ marker.append(0);
+
+ ExpressionIdentifier::List opIDs;
+ opIDs.append(ExpressionIdentifier::Ptr(new BySequenceTypeIdentifier(
+ CommonSequenceTypes::ExactlyOneBoolean)));
+ opIDs.append(ExpressionIdentifier::Ptr(new BooleanIdentifier(true)));
+ opIDs.append(ExpressionIdentifier::Ptr(new BooleanIdentifier(false)));
+
+ const OptimizationPass::Ptr pass(new OptimizationPass(ExpressionIdentifier::Ptr(), opIDs, marker));
+ ifThenPasses.append(pass);
+ /* ****************************************************** */
+
+ /* ****************************************************** */
+ /* Rewrite "not(exists(X))" into "empty(X)" */
+ ExpressionIdentifier::List idExistsFN;
+ idExistsFN.append(ExpressionIdentifier::Ptr(new ByIDIdentifier(Expression::IDExistsFN)));
+
+ notFN.append(OptimizationPass::Ptr(new OptimizationPass(ExpressionIdentifier::Ptr(),
+ idExistsFN,
+ firstFirstChild,
+ emptyFN)));
+
+ /* Rewrite "not(empty(X))" into "exists(X)" */
+ ExpressionIdentifier::List idEmptyFN;
+ idEmptyFN.append(ExpressionIdentifier::Ptr(new ByIDIdentifier(Expression::IDEmptyFN)));
+
+ notFN.append(OptimizationPass::Ptr(new OptimizationPass(ExpressionIdentifier::Ptr(),
+ idEmptyFN,
+ firstFirstChild,
+ existsFN)));
+ /* ****************************************************** */
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/expr/qoptimizationpasses_p.h b/src/xmlpatterns/expr/qoptimizationpasses_p.h
new file mode 100644
index 0000000..6f10572
--- /dev/null
+++ b/src/xmlpatterns/expr/qoptimizationpasses_p.h
@@ -0,0 +1,143 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_OptimizationBlocks_H
+#define Patternist_OptimizationBlocks_H
+
+#include "qatomiccomparator_p.h"
+#include "qexpression_p.h"
+#include "qoptimizerframework_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Contains a set of common OptimizerPass instances.
+ *
+ * @author Frans englich <frans.englich@nokia.com>
+ * @ingroup Patternist_expressions
+ */
+ namespace OptimizationPasses
+ {
+ /**
+ * A list of OptimizerPass instances that performs the
+ * following rewrites:
+ *
+ * - <tt>count([expr]) ne 0</tt> into <tt>exists([expr])</tt>
+ * - <tt>count([expr]) != 0</tt> into <tt>exists([expr])</tt>
+ * - <tt>0 ne count([expr])</tt> into <tt>exists([expr])</tt>
+ * - <tt>0 != count([expr])</tt> into <tt>exists([expr])</tt>
+ * - <tt>count([expr]) eq 0</tt> into <tt>empty([expr])</tt>
+ * - <tt>count([expr]) = 0</tt> into <tt>empty([expr])</tt>
+ * - <tt>0 eq count([expr])</tt> into <tt>empty([expr])</tt>
+ * - <tt>0 = count([expr])</tt> into <tt>empty([expr])</tt>
+ * - <tt>count([expr]) ge 1</tt> into <tt>exists([expr])</tt>
+ * - <tt>count([expr]) >= 1</tt> into <tt>exists([expr])</tt>
+ */
+ extern OptimizationPass::List comparisonPasses;
+
+ /**
+ * A list of OptimizerPass instances that performs the
+ * following rewrites:
+ *
+ * - <tt>for $var in [expr] return $var</tt> into <tt>[expr]</tt>
+ */
+ extern OptimizationPass::List forPasses;
+
+ /**
+ * A list of OptimizerPass instances that performs the
+ * following rewrites:
+ *
+ * - <tt>if([expr of type xs:boolean]) then true() else false()</tt>
+ * into <tt>[expr of type xs:boolean]</tt>
+ */
+ extern OptimizationPass::List ifThenPasses;
+
+ /**
+ * A list of OptimizerPass instances that performs the
+ * following rewrites:
+ *
+ * - <tt>fn:not(fn:exists([expr]))</tt> into <tt>fn:empty([expr])</tt>
+ * - <tt>fn:not(fn:empty([expr]))</tt> into <tt>fn:exists([expr])</tt>
+ */
+ extern OptimizationPass::List notFN;
+
+ /**
+ * Initializes the data members in the OptimizationPasses namespace.
+ *
+ * This class is not supposed to be instantiated, but to be used via its init()
+ * function. In fact, this class cannot be instantiated.
+ *
+ * @author Frans englich <frans.englich@nokia.com>
+ */
+ class Coordinator
+ {
+ public:
+ /**
+ * Initializes the members in the OptimizationPasses namespace.
+ */
+ static void init();
+
+ private:
+ Q_DISABLE_COPY(Coordinator)
+ inline Coordinator();
+ };
+ }
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/expr/qoptimizerblocks.cpp b/src/xmlpatterns/expr/qoptimizerblocks.cpp
new file mode 100644
index 0000000..511faae
--- /dev/null
+++ b/src/xmlpatterns/expr/qoptimizerblocks.cpp
@@ -0,0 +1,179 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qcommonnamespaces_p.h"
+
+#include "qcommonsequencetypes_p.h"
+#include "qfunctionfactory_p.h"
+#include "qgeneralcomparison_p.h"
+#include "qliteral_p.h"
+#include "qschemanumeric_p.h"
+#include "qvaluecomparison_p.h"
+
+#include "qoptimizerblocks_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+ByIDIdentifier::ByIDIdentifier(const Expression::ID id) : m_id(id)
+{
+}
+
+bool ByIDIdentifier::matches(const Expression::Ptr &expr) const
+{
+ return expr->is(m_id);
+}
+
+ComparisonIdentifier::ComparisonIdentifier(const QVector<Expression::ID> hosts,
+ const AtomicComparator::Operator op) : m_hosts(hosts),
+ m_op(op)
+{
+}
+
+bool ComparisonIdentifier::matches(const Expression::Ptr &e) const
+{
+ const Expression::ID eID = e->id();
+
+ if(eID == Expression::IDGeneralComparison)
+ {
+ if(m_hosts.contains(Expression::IDGeneralComparison))
+ return e->as<GeneralComparison>()->operatorID() == m_op;
+ else
+ return false;
+ }
+ else if(eID == Expression::IDValueComparison)
+ {
+ if(m_hosts.contains(Expression::IDValueComparison))
+ return e->as<ValueComparison>()->operatorID() == m_op;
+ else
+ return false;
+ }
+ else
+ return false;
+}
+
+BySequenceTypeIdentifier::BySequenceTypeIdentifier(const SequenceType::Ptr &seqType) : m_seqType(seqType)
+{
+ Q_ASSERT(seqType);
+}
+
+bool BySequenceTypeIdentifier::matches(const Expression::Ptr &expr) const
+{
+ const SequenceType::Ptr t(expr->staticType());
+
+ return m_seqType->itemType()->xdtTypeMatches(t->itemType())
+ &&
+ m_seqType->cardinality().isMatch(t->cardinality());
+}
+
+IntegerIdentifier::IntegerIdentifier(const xsInteger num) : m_num(num)
+{
+}
+
+bool IntegerIdentifier::matches(const Expression::Ptr &expr) const
+{
+ return expr->is(Expression::IDIntegerValue) &&
+ expr->as<Literal>()->item().as<Numeric>()->toInteger() == m_num;
+}
+
+BooleanIdentifier::BooleanIdentifier(const bool value) : m_value(value)
+{
+}
+
+bool BooleanIdentifier::matches(const Expression::Ptr &expr) const
+{
+ return expr->is(Expression::IDBooleanValue) &&
+ expr->evaluateEBV(DynamicContext::Ptr()) == m_value;
+}
+
+ByIDCreator::ByIDCreator(const Expression::ID id) : m_id(id)
+{
+ Q_ASSERT(id != Expression::IDIgnorableExpression);
+}
+
+Expression::Ptr ByIDCreator::create(const Expression::List &operands,
+ const StaticContext::Ptr &context,
+ const SourceLocationReflection *const r) const
+{
+ return create(m_id, operands, context, r);
+}
+
+Expression::Ptr ByIDCreator::create(const Expression::ID id,
+ const Expression::List &operands,
+ const StaticContext::Ptr &context,
+ const SourceLocationReflection *const r)
+{
+ Q_ASSERT(context);
+
+ QXmlName::LocalNameCode fnName;
+
+ switch(id)
+ {
+ case Expression::IDExistsFN:
+ {
+ fnName = StandardLocalNames::exists;
+ break;
+ }
+ case Expression::IDEmptyFN:
+ {
+ fnName = StandardLocalNames::empty;
+ break;
+ }
+ default:
+ {
+ Q_ASSERT_X(false, Q_FUNC_INFO,
+ "Cannot create an expression of requested type; m_id is wrong.");
+ return Expression::Ptr();
+ }
+ }
+
+ /* The reason we don't simply do 'new ExistsFN()' ourselves, is that all FunctionCall
+ * instances needs their FunctionSignature in order to function, and the FunctionFactories
+ * sets that. */
+ const QXmlName qName(StandardNamespaces::fn, fnName);
+
+ const Expression::Ptr result(context->functionSignatures()->createFunctionCall(qName, operands, context, r));
+ context->wrapExpressionWith(r, result);
+ return result;
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/expr/qoptimizerblocks_p.h b/src/xmlpatterns/expr/qoptimizerblocks_p.h
new file mode 100644
index 0000000..575e07c
--- /dev/null
+++ b/src/xmlpatterns/expr/qoptimizerblocks_p.h
@@ -0,0 +1,226 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_OptimizerBlocks_H
+#define Patternist_OptimizerBlocks_H
+
+#include "qatomiccomparator_p.h"
+#include "qexpression_p.h"
+#include "qoptimizerframework_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Identifies Expression instances by their Expression::id().
+ *
+ * @author Frans englich <frans.englich@nokia.com>
+ * @ingroup Patternist_expressions
+ */
+ class ByIDIdentifier : public ExpressionIdentifier
+ {
+ public:
+ ByIDIdentifier(const Expression::ID id);
+ virtual bool matches(const Expression::Ptr &expr) const;
+ private:
+ const Expression::ID m_id;
+ };
+
+ /**
+ * @short Identifies Expression instances based on their static type.
+ *
+ * BySequenceTypeIdentifier identifies Expression instances
+ * if their Expression::staticType() matches the requested one,
+ * regardless of whether the Expression is a particular one, such
+ * as AndExpression.
+ *
+ * For example, constructing a BySequenceTypeIdentifier while
+ * passing CommonSequenceTypes::EBV in its constructor will create
+ * a ExpressionIdentifier that returns @c true for a static type with
+ * item type <tt>xs:string</tt>, but returns @c false for a static type involving
+ * <tt>xs:date</tt>.
+ *
+ * @author Frans englich <frans.englich@nokia.com>
+ * @ingroup Patternist_expressions
+ */
+ class BySequenceTypeIdentifier : public ExpressionIdentifier
+ {
+ public:
+ BySequenceTypeIdentifier(const SequenceType::Ptr &seqType);
+
+ /**
+ * @returns @c true, if the static type of @p expr is matches
+ * the SequenceType passed in the BySequenceTypeIdentifier()
+ * constructor, otherwise @c false.
+ */
+ virtual bool matches(const Expression::Ptr &expr) const;
+
+ private:
+ const SequenceType::Ptr m_seqType;
+ };
+
+ /**
+ * @short Determines whether an Expression is a value or general comparison or both,
+ * with a certain operator.
+ *
+ * @author Frans englich <frans.englich@nokia.com>
+ * @ingroup Patternist_expressions
+ */
+ class ComparisonIdentifier : public ExpressionIdentifier
+ {
+ public:
+
+ /**
+ * @param comparatorHosts the possible parent that may have
+ * the operator. This may be Expression::IDGeneralComparison or
+ * Expression::IDValueComparison. The two values may also be OR'd,
+ * meaning any of them will do.
+ *
+ * @param op the operator that the comparator host must have. For example,
+ * if @p op is AtomicComparator::OperatorGreatorOrEqual this ComparisonIdentifier
+ * will match operator >= in the case of IDGeneralComparison and 'ge' in the
+ * case of IDValueComparison.
+ */
+ ComparisonIdentifier(const QVector<Expression::ID> comparatorHosts,
+ const AtomicComparator::Operator op);
+
+ /**
+ * @returns @c true, if @p expr is a ValueComparison with the operator
+ * passed in ComparisonIdentifier().
+ */
+ virtual bool matches(const Expression::Ptr &expr) const;
+
+ private:
+ const QVector<Expression::ID> m_hosts;
+ const AtomicComparator::Operator m_op;
+ };
+
+ /**
+ * @short Matches numeric literals that are of type xs:integer and
+ * has a specific value.
+ *
+ * For example IntegerIdentifier(4) would match the former but
+ * not the latter operand in this expression: "4 + 5".
+ *
+ * @author Frans englich <frans.englich@nokia.com>
+ * @ingroup Patternist_expressions
+ */
+ class IntegerIdentifier : public ExpressionIdentifier
+ {
+ public:
+ IntegerIdentifier(const xsInteger num);
+ virtual bool matches(const Expression::Ptr &expr) const;
+
+ private:
+ const xsInteger m_num;
+ };
+
+ /**
+ * @short Matches boolean literals.
+ *
+ * For example BooleanIdentifier(true) would match the former but
+ * not the latter operand in this expression: "true() + false()".
+ *
+ * @author Frans englich <frans.englich@nokia.com>
+ * @ingroup Patternist_expressions
+ */
+ class BooleanIdentifier : public ExpressionIdentifier
+ {
+ public:
+ BooleanIdentifier(const bool value);
+ virtual bool matches(const Expression::Ptr &expr) const;
+
+ private:
+ const bool m_value;
+ };
+
+ /**
+ * @short Creates a particular Expression instance identified by an Expression::ID.
+ *
+ * For example, if ByIDCreator() is passed Expression::IDCountFN, create()
+ * will return CountFN instances.
+ *
+ * @author Frans englich <frans.englich@nokia.com>
+ * @ingroup Patternist_expressions
+ */
+ class ByIDCreator : public ExpressionCreator
+ {
+ public:
+ /**
+ * Creates a ByIDCreator that creates expressions
+ * of the type that @p id identifies.
+ */
+ ByIDCreator(const Expression::ID id);
+ virtual Expression::Ptr create(const Expression::List &operands,
+ const StaticContext::Ptr &context,
+ const SourceLocationReflection *const r) const;
+
+ /**
+ * Creates an expression by id @p id with the arguments @p operands.
+ */
+ static Expression::Ptr create(const Expression::ID id,
+ const Expression::List &operands,
+ const StaticContext::Ptr &context,
+ const SourceLocationReflection *const r);
+
+ private:
+ const Expression::ID m_id;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/expr/qoptimizerframework.cpp b/src/xmlpatterns/expr/qoptimizerframework.cpp
new file mode 100644
index 0000000..c9e1991
--- /dev/null
+++ b/src/xmlpatterns/expr/qoptimizerframework.cpp
@@ -0,0 +1,71 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qoptimizerblocks_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+ExpressionIdentifier::~ExpressionIdentifier()
+{
+}
+
+ExpressionCreator::~ExpressionCreator()
+{
+}
+
+OptimizationPass::OptimizationPass(const ExpressionIdentifier::Ptr &startID,
+ const ExpressionIdentifier::List &opIDs,
+ const ExpressionMarker &sourceExpr,
+ const ExpressionCreator::Ptr &resultCtor,
+ const OperandsMatchMethod mMethod) : startIdentifier(startID),
+ operandIdentifiers(opIDs),
+ sourceExpression(sourceExpr),
+ resultCreator(resultCtor),
+ operandsMatchMethod(mMethod)
+{
+ Q_ASSERT_X(resultCtor || !sourceExpr.isEmpty(), Q_FUNC_INFO,
+ "Either resultCreator or sourceExpression must be set, otherwise there's "
+ "nothing to rewrite to.");
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/expr/qoptimizerframework_p.h b/src/xmlpatterns/expr/qoptimizerframework_p.h
new file mode 100644
index 0000000..a2c9373
--- /dev/null
+++ b/src/xmlpatterns/expr/qoptimizerframework_p.h
@@ -0,0 +1,294 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_OptimizerFramework_H
+#define Patternist_OptimizerFramework_H
+
+#include <QSharedData>
+
+#include "qexpression_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short A factory for creating Expression instances.
+ *
+ * ExpressionIdentifier is one of the building block of Patternist's
+ * optimizer framework. An ExpressionIdentifier sub-class has
+ * the responsibility of creating the Expression that should be
+ * the result of the optimization.
+ *
+ * This class and sub-classes are never used on their own,
+ * but in cooperation with OptimizationPass.
+ *
+ * @author Frans englich <frans.englich@nokia.com>
+ * @ingroup Patternist_expressions
+ */
+ class ExpressionCreator : public QSharedData
+ {
+ public:
+ typedef QExplicitlySharedDataPointer<ExpressionCreator> Ptr;
+
+ /**
+ * For some reason this constructor cannot be synthesized.
+ */
+ inline ExpressionCreator()
+ {
+ }
+
+ virtual ~ExpressionCreator();
+ /**
+ * Creates an expression that has @p operands as operands.
+ *
+ * The Expression that is returned is guaranteed, by the caller,
+ * to get a treatment identical to if the expression was created
+ * in an ordinary compilation(via the parser, and so forth). That is,
+ * Expression::typeCheck() and Expression::compress() stages will be
+ * carried out on the returned expression.
+ *
+ * @returns an Expression::Ptr that never is non @c null, valid pointer
+ */
+ virtual Expression::Ptr create(const Expression::List &operands,
+ const StaticContext::Ptr &context,
+ const SourceLocationReflection *const) const = 0;
+
+ private:
+ Q_DISABLE_COPY(ExpressionCreator)
+ };
+
+ /**
+ * @short Abstract base class for all classes that identify Expressions
+ * based on some criteria.
+ *
+ * ExpressionIdentifier is one of the building block of Patternist's
+ * optimizer framework. An ExpressionIdentifier sub-class has
+ * the responsibility of determining whether a particular Expression
+ * is the one an OptimizationPass should apply for.
+ *
+ * This class and sub-classes are never used on their own,
+ * but in cooperation with OptimizationPass.
+ *
+ * @author Frans englich <frans.englich@nokia.com>
+ * @ingroup Patternist_expressions
+ */
+ class ExpressionIdentifier : public QSharedData
+ {
+ public:
+ typedef QExplicitlySharedDataPointer<ExpressionIdentifier> Ptr;
+ typedef QList<ExpressionIdentifier::Ptr> List;
+
+ /**
+ * For some reason this constructor cannot be synthesized.
+ */
+ inline ExpressionIdentifier()
+ {
+ }
+
+ virtual ~ExpressionIdentifier();
+ /**
+ * @param expr the Expression to be tested. This is guranteed
+ * to always be a non @c null, valid pointer.
+ *
+ * @returns @c true if @p expr matches as according to this ExpressionIdentifier,
+ * otherwise @c false.
+ */
+ virtual bool matches(const Expression::Ptr &expr) const = 0;
+
+ private:
+ Q_DISABLE_COPY(ExpressionIdentifier)
+ };
+
+ /**
+ * @short Describes how a particular optimization pass should be carried out.
+ *
+ * OptimizationPass is essentially a declaration, which describes
+ * how an optimization pass in the form of an AST rewrite should be done,
+ * by describing what that should be rewritten into what how.
+ *
+ * Each OptimizationPass is applied to a "start" Expression. The Expression
+ * that qualifies as a start Expression for the OptimizationPass in question is
+ * determined by startIdentifier; if its ExpressionIdentifier::matches() function
+ * returns @c true, the optimizer continues to apply this OptimizationPass.
+ *
+ * After a start Expression has been found, it is verified if the operands matches
+ * as well by applying the ExpressionIdentifiers in operandIdentifiers to the
+ * start Expression's operands. Similarly, if the operands matches what
+ * operandIdentifiers requires, the optimizer continues to apply this OptimizationPass.
+ *
+ * At this stage, it has been concluded that the OptimizationPass validly applies, and
+ * what now remains is to carry out the actual rewrite. The Expression rewritten
+ * to is the one returned by ExpressionCreator::create(), when invoked via the resultCreator
+ * variable.
+ *
+ * How these components, startIdentifier, operandIdentifiers, sourceExpression,
+ * and resultCreator interacts with one another is described in more detail
+ * in the member documentation as well as the classes they are instances of.
+ *
+ * @author Frans englich <frans.englich@nokia.com>
+ * @ingroup Patternist_expressions
+ */
+ class OptimizationPass : public QSharedData
+ {
+ public:
+ typedef QExplicitlySharedDataPointer<OptimizationPass> Ptr;
+ typedef QList<OptimizationPass::Ptr> List;
+
+ enum OperandsMatchMethod
+ {
+ /**
+ * All operands must match in the same order the ExpressionMarkers do.
+ */
+ Sequential = 1,
+
+ /**
+ * Matches if all operands are matched, regardless of their order. This is
+ * useful when an OptimizationPass is matching an Expression that has two operands
+ * and that both of them can appear on the left or right hand as long as it is those
+ * two.
+ *
+ * This comparison method only works when two operands
+ * needs to be matched.
+ */
+ AnyOrder
+ };
+
+ /**
+ * An ExpressionMarker identifies an operand Expression relatively
+ * the start Expression by that each integer identifies a step
+ * in a descending AST walk. For example an ExpressionMarker with
+ * only one entry that is 0(zero), identifies the first operand of the
+ * start Expression. An ExpressionMarker containing 1, 2 in that order
+ * identifies the third operand of the second operand of the start Expression.
+ */
+ typedef QList<qint8> ExpressionMarker;
+
+ /**
+ * Creates an OptimizationPass and sets its public variables
+ * to the corresponding values passed in this constructor.
+ */
+ OptimizationPass(const ExpressionIdentifier::Ptr &startID,
+ const ExpressionIdentifier::List &operandIDs,
+ const ExpressionMarker &sourceExpr,
+ const ExpressionCreator::Ptr &resultCtor = ExpressionCreator::Ptr(),
+ const OperandsMatchMethod matchMethod = Sequential);
+
+ /**
+ * The ExpressionIdentifier that must the Expression this OptimizationPass concerns.
+ *
+ * If this variable is @c null, it means that the start Expression does
+ * not have to match any particular ExpressionIdentifier, but is fine as is.
+ *
+ * One might wonder what the purpose of this startIdentifier is, considering
+ * that what start Expression an OptimizationPass can at all apply to is
+ * naturally determined by what Expression::optimizationPasses() re-implementation that
+ * returns this OptimizationPass. The reason is that in some cases an OptimizationPass
+ * nevertheless doesn't apply. For example, optimizations applying to a ValueComparison
+ * might depend on what operator that is in use.
+ *
+ * May be @c null or point to an ExpressionIdentifier.
+ */
+ const ExpressionIdentifier::Ptr startIdentifier;
+
+ /**
+ * In order for an OptimizationPass to apply, the start Expression's
+ * operands must be matched with this list of ExpressionIdentifier instances.
+ * The first ExpressionIdentifier is applied to the first operand, the second
+ * ExpressionIdentifier to the second operand, and so forth until all operands
+ * have been iterated.
+ *
+ * Entries in this list may be @c null, and those signals that the corresponding
+ * operand is not constrained. For example, if the third ExpressionIdentifier in
+ * the list is @c null, it signals that the third operand may be anykind of expression.
+ *
+ * May be empty or contain an arbitrary amount of objects or @c null pointers.
+ */
+ const ExpressionIdentifier::List operandIdentifiers;
+
+ /**
+ * Identifies the expression that should be part of the new expression
+ * that this OptimizationPass rewrites to. If this list is empty, it
+ * means that the result is not derived from the existing tree, and
+ * that resultCreator will exclusively be used for creating the result
+ * Expression.
+ *
+ * How the ExpressionMarker identifies an Expression is document in
+ * its documentation.
+ *
+ * May be empty.
+ */
+ const ExpressionMarker sourceExpression;
+
+ /**
+ * This is the ExpressionCreator that will be used to create the
+ * Expression which is the result. ExpressionCreator::create()
+ * will be passed as operands the Expression that sourceExpression
+ * specify, if any.
+ *
+ * If this variable is @c null, the result Expression will be the one
+ * sourceExpression identifies.
+ */
+ const ExpressionCreator::Ptr resultCreator;
+
+ const OperandsMatchMethod operandsMatchMethod;
+ private:
+ Q_DISABLE_COPY(OptimizationPass)
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/expr/qorderby.cpp b/src/xmlpatterns/expr/qorderby.cpp
new file mode 100644
index 0000000..b2fae5a
--- /dev/null
+++ b/src/xmlpatterns/expr/qorderby.cpp
@@ -0,0 +1,261 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtAlgorithms>
+
+#include "qcommonsequencetypes_p.h"
+#include "qnodebuilder_p.h"
+#include "qschemanumeric_p.h"
+#include "qpatternistlocale_p.h"
+#include "qreturnorderby_p.h"
+#include "qsorttuple_p.h"
+#include "qsequencemappingiterator_p.h"
+
+#include "qorderby_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+OrderBy::OrderBy(const Stability stability,
+ const OrderSpec::Vector &aOrderSpecs,
+ const Expression::Ptr &op,
+ ReturnOrderBy *const returnOrderBy) : SingleContainer(op)
+ , m_stability(stability)
+ , m_orderSpecs(aOrderSpecs)
+ , m_returnOrderBy(returnOrderBy)
+{
+ Q_ASSERT(m_returnOrderBy);
+}
+
+void OrderBy::OrderSpec::prepare(const Expression::Ptr &source,
+ const StaticContext::Ptr &context)
+{
+ m_expr = source;
+ const ItemType::Ptr t(source->staticType()->itemType());
+ prepareComparison(fetchComparator(t, t, context));
+}
+
+/**
+ * @short Functor used by Qt's qSort() and qStableSort(). Used for FLWOR's
+ * <tt>order by</tt> expression.
+ *
+ * This must be in the global namespace, since it is specializing qLess(), which
+ * is in the global namespace. Hence it can't be in QPatternist.
+ */
+template<>
+class qLess<Item::List>
+{
+private:
+
+ static inline bool isNaN(const Item &i)
+ {
+ return BuiltinTypes::xsDouble->xdtTypeMatches(i.type()) &&
+ i.as<Numeric>()->isNaN();
+ }
+
+public:
+ inline qLess(const OrderBy::OrderSpec::Vector &orderspecs,
+ const DynamicContext::Ptr &context) : m_orderSpecs(orderspecs)
+ , m_context(context)
+ {
+ Q_ASSERT(!m_orderSpecs.isEmpty());
+ Q_ASSERT(context);
+ }
+
+ inline bool operator()(const Item &item1, const Item &item2) const
+ {
+ const SortTuple *const s1 = item1.as<SortTuple>();
+ const SortTuple *const s2 = item2.as<SortTuple>();
+
+ const Item::Vector &sortKeys1 = s1->sortKeys();
+ const Item::Vector &sortKeys2 = s2->sortKeys();
+ const int len = sortKeys1.count();
+ Q_ASSERT(sortKeys1.count() == sortKeys2.count());
+
+ for(int i = 0; i < len; ++i)
+ {
+ const Item &i1 = sortKeys1.at(i);
+ const Item &i2 = sortKeys2.at(i);
+ const OrderBy::OrderSpec &orderSpec = m_orderSpecs.at(i);
+
+ if(!i1)
+ {
+ if(i2 && !isNaN(i2))
+ {
+ /* We got ((), item()). */
+ return orderSpec.orderingEmptySequence == StaticContext::Least ? orderSpec.direction == OrderBy::OrderSpec::Ascending
+ : orderSpec.direction != OrderBy::OrderSpec::Ascending;
+ }
+ else
+ return false;
+ }
+
+ if(!i2)
+ {
+ if(i1 && !isNaN(i1))
+ /* We got (item(), ()). */
+ return orderSpec.orderingEmptySequence == StaticContext::Greatest ? orderSpec.direction == OrderBy::OrderSpec::Ascending
+ : orderSpec.direction != OrderBy::OrderSpec::Ascending;
+ else
+ return false;
+ }
+
+ Q_ASSERT(orderSpec.direction == OrderBy::OrderSpec::Ascending ||
+ orderSpec.direction == OrderBy::OrderSpec::Descending);
+ const AtomicComparator::ComparisonResult result = orderSpec.detailedFlexibleCompare(i1, i2, m_context);
+
+ switch(result)
+ {
+ case AtomicComparator::LessThan:
+ return orderSpec.direction == OrderBy::OrderSpec::Ascending;
+ case AtomicComparator::GreaterThan:
+ return orderSpec.direction != OrderBy::OrderSpec::Ascending;
+ case AtomicComparator::Equal:
+ continue;
+ case AtomicComparator::Incomparable:
+ Q_ASSERT_X(false, Q_FUNC_INFO, "This code path assume values are always comparable.");
+ }
+ }
+
+ return false;
+ }
+
+private:
+ /* Yes, we store references here. */
+ const OrderBy::OrderSpec::Vector & m_orderSpecs;
+ const DynamicContext::Ptr & m_context;
+};
+
+Item::Iterator::Ptr OrderBy::mapToSequence(const Item &i,
+ const DynamicContext::Ptr &) const
+{
+ return i.as<SortTuple>()->value();
+}
+
+Item::Iterator::Ptr OrderBy::evaluateSequence(const DynamicContext::Ptr &context) const
+{
+ Item::List tuples(m_operand->evaluateSequence(context)->toList());
+
+ const qLess<Item::List> sorter(m_orderSpecs, context);
+
+ Q_ASSERT(m_stability == StableOrder || m_stability == UnstableOrder);
+
+ /* On one hand we could just disregard stability and always use qStableSort(), but maybe qSort()
+ * is a bit faster? */
+ if(m_stability == StableOrder)
+ qStableSort(tuples.begin(), tuples.end(), sorter);
+ else
+ {
+ Q_ASSERT(m_stability == UnstableOrder);
+ qSort(tuples.begin(), tuples.end(), sorter);
+ }
+
+ return makeSequenceMappingIterator<Item>(ConstPtr(this),
+ makeListIterator(tuples),
+ context);
+}
+
+Expression::Ptr OrderBy::typeCheck(const StaticContext::Ptr &context,
+ const SequenceType::Ptr &reqType)
+{
+ m_returnOrderBy->setStay(true);
+
+ /* It's important we do the typeCheck() before calling OrderSpec::prepare(), since
+ * atomizers must first be inserted. */
+ const Expression::Ptr me(SingleContainer::typeCheck(context, reqType));
+
+ const Expression::List ops(m_returnOrderBy->operands());
+ const int len = ops.count();
+ Q_ASSERT(ops.count() > 1);
+ Q_ASSERT(m_orderSpecs.count() == ops.count() - 1);
+
+ for(int i = 1; i < len; ++i)
+ m_orderSpecs[i - 1].prepare(ops.at(i), context);
+
+ return me;
+
+ /* It's not meaningful to sort a single item or less, so rewrite ourselves
+ * away if that is the case. This is an optimization. */
+ /* TODO: How do we remove ReturnOrderBy?
+ if(Cardinality::zeroOrOne().isMatch(m_operand->staticType()->cardinality()))
+ return m_operand->typeCheck(context, reqType);
+ else
+ return SingleContainer::typeCheck(context, reqType);
+ */
+}
+
+Expression::Properties OrderBy::properties() const
+{
+ return m_operand->properties() & DisableElimination;
+}
+
+Expression::Ptr OrderBy::compress(const StaticContext::Ptr &context)
+{
+ /* If we only will produce one item, there's no point in sorting. */
+ if(m_operand->staticType()->cardinality().allowsMany())
+ return SingleContainer::compress(context);
+ else
+ {
+ m_returnOrderBy->setStay(false);
+ return m_operand->compress(context);
+ }
+}
+
+SequenceType::Ptr OrderBy::staticType() const
+{
+ return m_operand->staticType();
+}
+
+SequenceType::List OrderBy::expectedOperandTypes() const
+{
+ SequenceType::List result;
+ result.append(CommonSequenceTypes::ZeroOrMoreItems);
+ return result;
+}
+
+ExpressionVisitorResult::Ptr
+OrderBy::accept(const ExpressionVisitor::Ptr &visitor) const
+{
+ return visitor->visit(this);
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/expr/qorderby_p.h b/src/xmlpatterns/expr/qorderby_p.h
new file mode 100644
index 0000000..332702b
--- /dev/null
+++ b/src/xmlpatterns/expr/qorderby_p.h
@@ -0,0 +1,183 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_OrderBy_H
+#define Patternist_OrderBy_H
+
+#include "qatomiccomparator_p.h"
+#include "qcomparisonplatform_p.h"
+#include "qsinglecontainer_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ class ReturnOrderBy;
+
+ /**
+ * @short Performs the sorting by being a parent to ForClause.
+ *
+ * The child of the ForClause is a ReturnOrderBy expression, which collects
+ * the sort keys and values.
+ *
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_expressions
+ */
+ class OrderBy : public SingleContainer
+ {
+ public:
+ enum Stability
+ {
+ StableOrder,
+ UnstableOrder
+ };
+
+ /**
+ * This class is value based.
+ */
+ class OrderSpec : public ComparisonPlatform<OrderBy::OrderSpec,
+ true, /* Yes, issue errors. */
+ AtomicComparator::AsValueComparison>
+ {
+ public:
+ /**
+ * We want this guy to be public.
+ */
+ using ComparisonPlatform<OrderBy::OrderSpec, true, AtomicComparator::AsValueComparison>::detailedFlexibleCompare;
+
+ typedef QVector<OrderSpec> Vector;
+
+ enum Direction
+ {
+ Ascending,
+ Descending
+ };
+
+ /**
+ * @short Default constructor, which is needed by QVector.
+ */
+ inline OrderSpec()
+ {
+ }
+
+ inline OrderSpec(const Direction dir,
+ const StaticContext::OrderingEmptySequence orderingEmpty) : direction(dir),
+ orderingEmptySequence(orderingEmpty)
+ {
+ }
+
+ void prepare(const Expression::Ptr &source,
+ const StaticContext::Ptr &context);
+
+ const SourceLocationReflection *actualReflection() const
+ {
+ return m_expr.data();
+ }
+
+ private:
+ Expression::Ptr m_expr;
+
+ public:
+ /**
+ * We place these afterwards, such that m_expr gets aligned at the
+ * start of the address.
+ */
+ Direction direction;
+
+ StaticContext::OrderingEmptySequence orderingEmptySequence;
+
+ inline AtomicComparator::Operator operatorID() const
+ {
+ return orderingEmptySequence == StaticContext::Least ? AtomicComparator::OperatorLessThanNaNLeast
+ : AtomicComparator::OperatorLessThanNaNGreatest;
+ }
+
+ };
+
+ OrderBy(const Stability stability,
+ const OrderSpec::Vector &orderSpecs,
+ const Expression::Ptr &operand,
+ ReturnOrderBy *const returnOrderBy);
+
+ virtual Item::Iterator::Ptr evaluateSequence(const DynamicContext::Ptr &context) const;
+ virtual SequenceType::Ptr staticType() const;
+ virtual Expression::Ptr typeCheck(const StaticContext::Ptr &context,
+ const SequenceType::Ptr &reqType);
+ virtual Expression::Ptr compress(const StaticContext::Ptr &context);
+ virtual SequenceType::List expectedOperandTypes() const;
+ virtual ExpressionVisitorResult::Ptr accept(const ExpressionVisitor::Ptr &visitor) const;
+
+ inline Item::Iterator::Ptr mapToSequence(const Item &i,
+ const DynamicContext::Ptr &context) const;
+ virtual Properties properties() const;
+
+ private:
+ /**
+ * Needed when calling makeSequenceMappingIterator().
+ */
+ typedef QExplicitlySharedDataPointer<const OrderBy> ConstPtr;
+
+ const Stability m_stability;
+ OrderSpec::Vector m_orderSpecs;
+ ReturnOrderBy *const m_returnOrderBy;
+ };
+
+ /* TODO Q_DECLARE_TYPEINFO(OrderBy::OrderSpec, Q_MOVABLE_TYPE); Breaks,
+ * probably because it's nested. */
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/expr/qorexpression.cpp b/src/xmlpatterns/expr/qorexpression.cpp
new file mode 100644
index 0000000..c2bbe3c
--- /dev/null
+++ b/src/xmlpatterns/expr/qorexpression.cpp
@@ -0,0 +1,83 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qboolean_p.h"
+#include "qcommonvalues_p.h"
+#include "qliteral_p.h"
+
+#include "qorexpression_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+OrExpression::OrExpression(const Expression::Ptr &operand1,
+ const Expression::Ptr &operand2) : AndExpression(operand1, operand2)
+{
+}
+
+bool OrExpression::evaluateEBV(const DynamicContext::Ptr &context) const
+{
+ return m_operand1->evaluateEBV(context) || m_operand2->evaluateEBV(context);
+}
+
+Expression::Ptr OrExpression::compress(const StaticContext::Ptr &context)
+{
+ const Expression::Ptr newMe(PairContainer::compress(context));
+
+ if(newMe != this)
+ return newMe;
+
+ /* Both operands mustn't be evaluated in order to be able to compress. */
+ if(m_operand1->isEvaluated() && m_operand1->evaluateEBV(context->dynamicContext()))
+ return wrapLiteral(CommonValues::BooleanTrue, context, this);
+ else if(m_operand2->isEvaluated() && m_operand2->evaluateEBV(context->dynamicContext()))
+ return wrapLiteral(CommonValues::BooleanTrue, context, this);
+ else
+ return Expression::Ptr(this);
+}
+
+ExpressionVisitorResult::Ptr OrExpression::accept(const ExpressionVisitor::Ptr &visitor) const
+{
+ return visitor->visit(this);
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/expr/qorexpression_p.h b/src/xmlpatterns/expr/qorexpression_p.h
new file mode 100644
index 0000000..c86f654
--- /dev/null
+++ b/src/xmlpatterns/expr/qorexpression_p.h
@@ -0,0 +1,88 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_OrExpression_H
+#define Patternist_OrExpression_H
+
+#include "qandexpression_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Implements XPath 2.0's logical expression @c or.
+ *
+ * @see <a href="http://www.w3.org/TR/xpath20/#id-logical-expressions">XML Path Language
+ * (XPath) 2.0, 3.6 Logical Expressions</a>
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_expressions
+ */
+ class OrExpression : public AndExpression
+ {
+ public:
+ OrExpression(const Expression::Ptr &operand1,
+ const Expression::Ptr &operand2);
+
+ virtual bool evaluateEBV(const DynamicContext::Ptr &context) const;
+
+ virtual Expression::Ptr compress(const StaticContext::Ptr &context);
+ virtual ExpressionVisitorResult::Ptr accept(const ExpressionVisitor::Ptr &visitor) const;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/expr/qpaircontainer.cpp b/src/xmlpatterns/expr/qpaircontainer.cpp
new file mode 100644
index 0000000..7ca7b53
--- /dev/null
+++ b/src/xmlpatterns/expr/qpaircontainer.cpp
@@ -0,0 +1,85 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qbuiltintypes_p.h"
+
+#include "qpaircontainer_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+PairContainer::PairContainer(const Expression::Ptr &operand1,
+ const Expression::Ptr &operand2) : m_operand1(operand1),
+ m_operand2(operand2)
+{
+ Q_ASSERT(m_operand1);
+ Q_ASSERT(m_operand2);
+}
+
+Expression::List PairContainer::operands() const
+{
+ Expression::List list;
+ list.append(m_operand1);
+ list.append(m_operand2);
+ return list;
+}
+
+void PairContainer::setOperands(const Expression::List &ops)
+{
+ Q_ASSERT(ops.count() == 2);
+ m_operand1 = ops.first();
+ m_operand2 = ops.last();
+ Q_ASSERT(m_operand1);
+ Q_ASSERT(m_operand2);
+}
+
+bool PairContainer::compressOperands(const StaticContext::Ptr &context)
+{
+ Q_ASSERT(m_operand1);
+ Q_ASSERT(m_operand2);
+ rewrite(m_operand1, m_operand1->compress(context), context);
+ rewrite(m_operand2, m_operand2->compress(context), context);
+
+ return m_operand1->isEvaluated() && m_operand2->isEvaluated();
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/expr/qpaircontainer_p.h b/src/xmlpatterns/expr/qpaircontainer_p.h
new file mode 100644
index 0000000..7acf7df
--- /dev/null
+++ b/src/xmlpatterns/expr/qpaircontainer_p.h
@@ -0,0 +1,89 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_PairContainer_H
+#define Patternist_PairContainer_H
+
+#include "qexpression_p.h"
+#include "qatomictype_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Base class for expressions that has exactly two operands.
+ *
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_expressions
+ */
+ class PairContainer : public Expression
+ {
+ public:
+ virtual Expression::List operands() const;
+ virtual void setOperands(const Expression::List &operands);
+ virtual bool compressOperands(const StaticContext::Ptr &);
+
+ protected:
+ PairContainer(const Expression::Ptr &operand1, const Expression::Ptr &operand2);
+
+ Expression::Ptr m_operand1;
+ Expression::Ptr m_operand2;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/expr/qparentnodeaxis.cpp b/src/xmlpatterns/expr/qparentnodeaxis.cpp
new file mode 100644
index 0000000..b715782
--- /dev/null
+++ b/src/xmlpatterns/expr/qparentnodeaxis.cpp
@@ -0,0 +1,77 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qbuiltintypes_p.h"
+#include "qcommonsequencetypes_p.h"
+
+#include "qparentnodeaxis_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+Item ParentNodeAxis::evaluateSingleton(const DynamicContext::Ptr &context) const
+{
+ return context->contextItem().asNode().iterate(QXmlNodeModelIndex::AxisParent)->next();
+}
+
+Expression::Properties ParentNodeAxis::properties() const
+{
+ return DisableElimination | RequiresContextItem;
+}
+
+ExpressionVisitorResult::Ptr ParentNodeAxis::accept(const ExpressionVisitor::Ptr &visitor) const
+{
+ return visitor->visit(this);
+}
+
+ItemType::Ptr ParentNodeAxis::expectedContextItemType() const
+{
+ return BuiltinTypes::node;
+}
+
+SequenceType::Ptr ParentNodeAxis::staticType() const
+{
+ // Parentless node exists.
+ return CommonSequenceTypes::ZeroOrOneNode;
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/expr/qparentnodeaxis_p.h b/src/xmlpatterns/expr/qparentnodeaxis_p.h
new file mode 100644
index 0000000..ee5529f
--- /dev/null
+++ b/src/xmlpatterns/expr/qparentnodeaxis_p.h
@@ -0,0 +1,103 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_ParentNodeAxis_H
+#define Patternist_ParentNodeAxis_H
+
+#include "qemptycontainer_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Corresponds to the expression <tt>parent::node()</tt>.
+ *
+ * This AST node is now useless, due to refactorings. Prevously we had
+ * Item QAbstractXmlNodeModel::parent(), which didn't have the overhead of
+ * allocating an iterator for a single node. However, in order to stream
+ * line the API it is now gone and hence the node performs exactly the same
+ * as AxisStep.
+ *
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_expressions
+ */
+ class ParentNodeAxis : public EmptyContainer
+ {
+ public:
+ virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const;
+
+ /**
+ * @returns always DisableElimination
+ */
+ virtual Expression::Properties properties() const;
+
+ virtual ExpressionVisitorResult::Ptr accept(const ExpressionVisitor::Ptr &visitor) const;
+
+ /**
+ * @returns always CommonSequenceTypes::ExactlyOneNode;
+ */
+ virtual SequenceType::Ptr staticType() const;
+
+ /**
+ * @returns always BuiltinTypes::node;
+ */
+ virtual ItemType::Ptr expectedContextItemType() const;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/expr/qpath.cpp b/src/xmlpatterns/expr/qpath.cpp
new file mode 100644
index 0000000..73cf0d9
--- /dev/null
+++ b/src/xmlpatterns/expr/qpath.cpp
@@ -0,0 +1,271 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qbuiltintypes_p.h"
+#include "qcommonsequencetypes_p.h"
+#include "qgenericsequencetype_p.h"
+#include "qnodesort_p.h"
+#include "qpatternistlocale_p.h"
+#include "qsequencemappingiterator_p.h"
+#include "qtypechecker_p.h"
+
+#include "qpath_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+Path::Path(const Expression::Ptr &operand1,
+ const Expression::Ptr &operand2,
+ const Kind kind) : PairContainer(operand1, operand2)
+ , m_hasCreatedSorter(kind != RegularPath)
+ , m_isLast(false)
+ , m_checkXPTY0018(kind == RegularPath)
+ , m_kind(kind)
+{
+}
+
+Item::Iterator::Ptr Path::mapToSequence(const Item &item,
+ const DynamicContext::Ptr &context) const
+{
+ /* item is the focus here. That is in <e/>/1, item is <e/>. However,
+ * we don't use it, since the context item is accessed through
+ * DynamicContext::focusIterator() and friends. */
+ Q_ASSERT(item);
+ Q_UNUSED(item); /* Needed when compiling in release mode. */
+ return m_operand2->evaluateSequence(context);
+}
+
+Item::Iterator::Ptr Path::evaluateSequence(const DynamicContext::Ptr &context) const
+{
+ /* Note, we use the old context for m_operand1. */
+ const Item::Iterator::Ptr source(m_operand1->evaluateSequence(context));
+
+ const DynamicContext::Ptr focus(context->createFocus());
+ focus->setFocusIterator(source);
+
+ const Item::Iterator::Ptr result(makeSequenceMappingIterator<Item>(ConstPtr(this), source, focus));
+
+ if(m_checkXPTY0018)
+ {
+ /* This is an expensive code path, but it should happen very rarely. */
+
+ enum FoundItem
+ {
+ FoundNone,
+ FoundNode,
+ FoundAtomicValue
+ } hasFound = FoundNone;
+
+ Item::List whenChecked;
+
+ Item next(result->next());
+
+ while(next)
+ {
+ const FoundItem found = next.isAtomicValue() ? FoundAtomicValue : FoundNode;
+
+ if(hasFound != FoundNone && hasFound != found)
+ {
+ /* It's an atomic value and we've already found a node. Mixed content. */
+ context->error(QtXmlPatterns::tr("The last step in a path must contain either nodes "
+ "or atomic values. It cannot be a mixture between the two."),
+ ReportContext::XPTY0018, this);
+ }
+ else
+ hasFound = found;
+
+ whenChecked.append(next);
+ next = result->next();
+ }
+
+ return makeListIterator(whenChecked);
+ }
+ else
+ return result;
+}
+
+Item Path::evaluateSingleton(const DynamicContext::Ptr &context) const
+{
+ /* This function is called if both operands' cardinality is exactly-one. Therefore
+ * we manually go forward in the focus by calling next().
+ *
+ * We don't check for XPTY0018, only in evaluateSequence(), since if we're guaranteed
+ * to evaluate to one item, we can only evaluate to one node or one atomic value.
+ */
+
+ /* Note, we use the old context for m_operand1. */
+ const Item::Iterator::Ptr source(m_operand1->evaluateSequence(context));
+
+ const DynamicContext::Ptr focus(context->createFocus());
+ focus->setFocusIterator(source);
+
+ /* This test is needed because if the focus is empty, we don't want to(nor can't) evaluate
+ * the next step. */
+ // TODO Why are we at all invoked then?
+ if(source->next())
+ return m_operand2->evaluateSingleton(focus);
+ else
+ return Item();
+}
+
+void Path::evaluateToSequenceReceiver(const DynamicContext::Ptr &context) const
+{
+ /* Note, we use the old context for m_operand1. */
+ const Item::Iterator::Ptr source(m_operand1->evaluateSequence(context));
+
+ const DynamicContext::Ptr focus(context->createFocus());
+ focus->setFocusIterator(source);
+
+ while(source->next())
+ m_operand2->evaluateToSequenceReceiver(focus);
+}
+
+Expression::Ptr Path::compress(const StaticContext::Ptr &context)
+{
+ const Expression::Ptr me(PairContainer::compress(context));
+
+ /* "./expr" is by now equal to "expr" since we've done
+ * focus/type checks, and a node sorter has been inserted. */
+ if(m_operand1->is(IDContextItem))
+ return m_operand2;
+
+ /* We do this as late as we can, such that we pick up the most recent type
+ * from the operand. */
+ if(m_isLast && m_kind != XSLTForEach && m_operand2->staticType()->itemType() == BuiltinTypes::item)
+ m_checkXPTY0018 = true;
+
+ return me;
+}
+
+Expression::Ptr Path::typeCheck(const StaticContext::Ptr &context,
+ const SequenceType::Ptr &reqType)
+{
+ m_operand2->announceFocusType(newFocusType());
+
+ /* Here we apply the function conversion first, and with the error code
+ * that we want -- XPTY0019 instead of XPTY0004. Unfortunately
+ * PairContainer::typeCheck() will do the type check again, which is
+ * redundant in the case of when we're not XSLTForEach.
+ *
+ * If we're XSLTForEach, it means we're a synthetic "map" expression for
+ * implementing various XSL-T expressions, and hence don't have the
+ * constraint of XPTY0019.
+ *
+ * It's important that typeCheck() is run for the operands(of course), and the call to
+ * PairContainer::typeCheck() ensures that below, in the case that we're XSL-T code.
+ *
+ * The type we expect, CommonSequenceTypes::ZeroOrMoreNodes() needs to be in sync with
+ * what we return in expectedOperandTypes(). */
+ if(m_kind != XSLTForEach)
+ {
+ m_operand1 = TypeChecker::applyFunctionConversion(m_operand1,
+ CommonSequenceTypes::ZeroOrMoreNodes,
+ context,
+ m_kind == ForApplyTemplate ? ReportContext::XTTE0520
+ : ReportContext::XPTY0019);
+ }
+
+ /* If our step ends with atomic values, we cannot sort.
+ *
+ * We must smack the NodeSortExpression ontop before calling typeCheck(), since the latter
+ * may insert an Atomizer, as possibly mandated by reqType. By doing it after, the Atomizer
+ * will be a parent to NodeSortExpression, as opposed to a child.
+ */
+ if(!m_hasCreatedSorter)
+ {
+ m_hasCreatedSorter = true;
+
+ return NodeSortExpression::wrapAround(Expression::Ptr(this), context)->typeCheck(context, reqType);
+ }
+ else
+ return PairContainer::typeCheck(context, reqType);
+}
+
+SequenceType::List Path::expectedOperandTypes() const
+{
+ SequenceType::List result;
+
+ /* This value needs to be in sync with what we pass to
+ * applyFunctionConversion() in typeCheck() above.
+ *
+ * We don't have the XPTY0019 restriction when we're synthetic XSL-T code.
+ */
+ if(m_kind == XSLTForEach)
+ result.append(CommonSequenceTypes::ZeroOrMoreItems);
+ else
+ result.append(CommonSequenceTypes::ZeroOrMoreNodes);
+
+ result.append(CommonSequenceTypes::ZeroOrMoreItems);
+ return result;
+}
+
+SequenceType::Ptr Path::staticType() const
+{
+ const SequenceType::Ptr opType(m_operand2->staticType());
+
+ /* For each parent step, we evaluate the child step. So multiply the two
+ * cardinalities. */
+ return makeGenericSequenceType(opType->itemType(),
+ m_operand1->staticType()->cardinality() * opType->cardinality());
+}
+
+ExpressionVisitorResult::Ptr Path::accept(const ExpressionVisitor::Ptr &visitor) const
+{
+ return visitor->visit(this);
+}
+
+Expression::Properties Path::properties() const
+{
+ return CreatesFocusForLast | ((m_operand1->properties() | m_operand2->properties()) & (RequiresCurrentItem | DisableElimination));
+}
+
+ItemType::Ptr Path::newFocusType() const
+{
+ return m_operand1->staticType()->itemType();
+}
+
+Expression::ID Path::id() const
+{
+ return IDPath;
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/expr/qpath_p.h b/src/xmlpatterns/expr/qpath_p.h
new file mode 100644
index 0000000..e4dc365
--- /dev/null
+++ b/src/xmlpatterns/expr/qpath_p.h
@@ -0,0 +1,176 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_Path_H
+#define Patternist_Path_H
+
+#include "qpaircontainer_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+
+ /**
+ * @short Implements the path expression, containing two steps, such as in <tt>html/body</tt>.
+ *
+ * @see <a href="http://www.w3.org/TR/xquery/#id-path-expressions">XQuery 1.0: An
+ * XML Query Language, 3.2 Path Expressions</a>
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_expressions
+ */
+ class Path : public PairContainer
+ {
+ public:
+ enum Kind
+ {
+ /**
+ * This Path is a plain old path expression as found in XPath.
+ * Sorting is performed, and atomics are disallowed as left
+ * operand.
+ */
+ RegularPath = 1,
+
+ /**
+ * This Path emulates an @c xsl:for-each instruction. This means no
+ * sorting of result, and atomics are allowed as left operand.
+ */
+ XSLTForEach,
+
+ /**
+ * This Path performs the iteration in an @c xsl:apply-templates
+ * instruction. This means sorting, and atomics are disallowed
+ * as left operand.
+ */
+ ForApplyTemplate
+ };
+
+ Path(const Expression::Ptr &operand1,
+ const Expression::Ptr &operand2,
+ const Kind kind = RegularPath);
+
+ virtual Item::Iterator::Ptr evaluateSequence(const DynamicContext::Ptr &context) const;
+ virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const;
+ virtual void evaluateToSequenceReceiver(const DynamicContext::Ptr &context) const;
+ inline Item::Iterator::Ptr mapToSequence(const Item &item,
+ const DynamicContext::Ptr &context) const;
+
+ virtual Expression::Ptr typeCheck(const StaticContext::Ptr &context,
+ const SequenceType::Ptr &reqType);
+
+ virtual SequenceType::List expectedOperandTypes() const;
+
+ /**
+ * @returns the static type of the last step where the cardinality is multiplied with
+ * the cardinality of the first step's cardinality.
+ */
+ virtual SequenceType::Ptr staticType() const;
+
+ virtual ExpressionVisitorResult::Ptr accept(const ExpressionVisitor::Ptr &visitor) const;
+
+ virtual Properties properties() const;
+
+ virtual Expression::Ptr compress(const StaticContext::Ptr &context);
+
+ /**
+ * @returns the item type of the last step's static type.
+ */
+ virtual ItemType::Ptr newFocusType() const;
+
+ virtual ID id() const;
+
+ inline void setLast();
+
+ inline Kind kind() const
+ {
+ return m_kind;
+ }
+
+ private:
+ typedef QExplicitlySharedDataPointer<const Path> ConstPtr;
+
+ /**
+ * One might think this block exists for preventing multiple
+ * NodeSortExpressions to be created. However, that is not an issue,
+ * since NodeSortExpression optimizes this away anyway.
+ *
+ * The real reason is to avoid infinite recursion. When our typeCheck()
+ * forwards on the type check to the just created
+ * NodeSortExpression, it in turn calls typeCheck() on its child, which
+ * is this Path. Rince and repeat.
+ *
+ * We only create node sorts when we're a regular path expression, and
+ * not when standing in as a generic map expression. */
+ bool m_hasCreatedSorter;
+
+ /**
+ * Whether this path is the step. For instance, in <tt>a/b/c</tt>, the
+ * last path has @c c as the right operand.
+ */
+ bool m_isLast;
+
+ bool m_checkXPTY0018;
+ const Kind m_kind;
+ };
+
+ void Path::setLast()
+ {
+ m_isLast = true;
+ }
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/expr/qpositionalvariablereference.cpp b/src/xmlpatterns/expr/qpositionalvariablereference.cpp
new file mode 100644
index 0000000..0b4f69b
--- /dev/null
+++ b/src/xmlpatterns/expr/qpositionalvariablereference.cpp
@@ -0,0 +1,84 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qcommonsequencetypes_p.h"
+#include "qinteger_p.h"
+
+#include "qpositionalvariablereference_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+PositionalVariableReference::PositionalVariableReference(const VariableSlotID s) : VariableReference(s)
+{
+}
+
+Item PositionalVariableReference::evaluateSingleton(const DynamicContext::Ptr &context) const
+{
+ Q_ASSERT(context);
+ Q_ASSERT(context->positionIterator(slot()));
+ return Integer::fromValue(context->positionIterator(slot())->position());
+}
+
+bool PositionalVariableReference::evaluateEBV(const DynamicContext::Ptr &) const
+{
+ return true;
+}
+
+SequenceType::Ptr PositionalVariableReference::staticType() const
+{
+ return CommonSequenceTypes::ExactlyOneInteger;
+}
+
+Expression::Properties PositionalVariableReference::properties() const
+{
+ return DependsOnLocalVariable;
+}
+
+ExpressionVisitorResult::Ptr
+
+PositionalVariableReference::accept(const ExpressionVisitor::Ptr &visitor) const
+{
+ return visitor->visit(this);
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/expr/qpositionalvariablereference_p.h b/src/xmlpatterns/expr/qpositionalvariablereference_p.h
new file mode 100644
index 0000000..9fe3cbd
--- /dev/null
+++ b/src/xmlpatterns/expr/qpositionalvariablereference_p.h
@@ -0,0 +1,100 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_PositionVariableReference_H
+#define Patternist_PositionVariableReference_H
+
+#include "qvariablereference_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short A reference to an @c at variable, declared with the
+ * <tt>for</tt>-part in XQuery's FLWOR expression.
+ *
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_expressions
+ */
+ class PositionalVariableReference : public VariableReference
+ {
+ public:
+ typedef QExplicitlySharedDataPointer<PositionalVariableReference> Ptr;
+ PositionalVariableReference(const VariableSlotID slot);
+
+ virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const;
+
+ /**
+ * Returns always @c true, since a positional variable is always one or more, and the
+ * Effective %Boolean Value for that range is always @c true.
+ *
+ * @returns always @c true
+ */
+ virtual bool evaluateEBV(const DynamicContext::Ptr &context) const;
+
+ /**
+ * @returns always CommonSequenceTypes::ExactlyOneInteger
+ */
+ virtual SequenceType::Ptr staticType() const;
+
+ virtual ExpressionVisitorResult::Ptr accept(const ExpressionVisitor::Ptr &visitor) const;
+ virtual Properties properties() const;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/expr/qprocessinginstructionconstructor.cpp b/src/xmlpatterns/expr/qprocessinginstructionconstructor.cpp
new file mode 100644
index 0000000..d933ee0
--- /dev/null
+++ b/src/xmlpatterns/expr/qprocessinginstructionconstructor.cpp
@@ -0,0 +1,144 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qcommonsequencetypes_p.h"
+#include "qpatternistlocale_p.h"
+#include "qnodebuilder_p.h"
+#include "qqnamevalue_p.h"
+
+#include "qprocessinginstructionconstructor_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+ProcessingInstructionConstructor::
+ProcessingInstructionConstructor(const Expression::Ptr &op1,
+ const Expression::Ptr &op2) : PairContainer(op1, op2)
+{
+}
+
+QString ProcessingInstructionConstructor::leftTrimmed(const QString &input)
+{
+ const int len = input.length();
+
+ for(int i = 0; i < len; ++i)
+ {
+ if(!input.at(i).isSpace())
+ return input.mid(i);
+ }
+
+ return QString(); /* input consists only of whitespace. All was trimmed. */
+}
+
+QString ProcessingInstructionConstructor::data(const DynamicContext::Ptr &context) const
+{
+ const Item name(m_operand1->evaluateSingleton(context));
+ const Item dataArg(m_operand2->evaluateSingleton(context));
+
+ if(dataArg)
+ {
+ /* Perform trimming before validation, to increase speed. */
+ const QString value(leftTrimmed(dataArg.stringValue()));
+
+ if(value.contains(QLatin1String("?>")))
+ {
+ context->error(QtXmlPatterns::tr("The data of a processing instruction cannot contain the string %1").arg(formatData("?>")),
+ ReportContext::XQDY0026, this);
+ return QString();
+ }
+ else
+ return value;
+ }
+ else
+ return QString();
+}
+
+QXmlName ProcessingInstructionConstructor::evaluateTardata(const DynamicContext::Ptr &context) const
+{
+ const Item name(m_operand1->evaluateSingleton(context));
+ return context->namePool()->allocateQName(QString(), name.stringValue());
+}
+
+Item ProcessingInstructionConstructor::evaluateSingleton(const DynamicContext::Ptr &context) const
+{
+ const NodeBuilder::Ptr nodeBuilder(context->nodeBuilder(QUrl()));
+
+ nodeBuilder->processingInstruction(evaluateTardata(context), data(context));
+
+ const QAbstractXmlNodeModel::Ptr nm(nodeBuilder->builtDocument());
+ context->addNodeModel(nm);
+
+ return nm->root(QXmlNodeModelIndex());
+}
+
+void ProcessingInstructionConstructor::evaluateToSequenceReceiver(const DynamicContext::Ptr &context) const
+{
+ QAbstractXmlReceiver *const receiver = context->outputReceiver();
+
+ receiver->processingInstruction(evaluateTardata(context), data(context));
+}
+
+SequenceType::Ptr ProcessingInstructionConstructor::staticType() const
+{
+ return CommonSequenceTypes::ExactlyOneProcessingInstruction;
+}
+
+SequenceType::List ProcessingInstructionConstructor::expectedOperandTypes() const
+{
+ SequenceType::List result;
+ result.append(CommonSequenceTypes::ExactlyOneString);
+ result.append(CommonSequenceTypes::ZeroOrOneString);
+ return result;
+}
+
+Expression::Properties ProcessingInstructionConstructor::properties() const
+{
+ return DisableElimination | IsNodeConstructor;
+}
+
+ExpressionVisitorResult::Ptr
+ProcessingInstructionConstructor::accept(const ExpressionVisitor::Ptr &visitor) const
+{
+ return visitor->visit(this);
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/expr/qprocessinginstructionconstructor_p.h b/src/xmlpatterns/expr/qprocessinginstructionconstructor_p.h
new file mode 100644
index 0000000..950ebc8
--- /dev/null
+++ b/src/xmlpatterns/expr/qprocessinginstructionconstructor_p.h
@@ -0,0 +1,109 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_ProcessingInstructionConstructor_H
+#define Patternist_ProcessingInstructionConstructor_H
+
+#include "qpaircontainer_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Constructs an element node. This covers both computed and directly constructed
+ * element nodes.
+ *
+ * @see <a href="http://www.w3.org/TR/xquery/#id-constructors">XQuery
+ * 1.0: An XML Query Language, 3.7 Constructors</a>
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_expressions
+ */
+ class ProcessingInstructionConstructor : public PairContainer
+ {
+ public:
+ ProcessingInstructionConstructor(const Expression::Ptr &operand1,
+ const Expression::Ptr &operand2);
+
+ virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const;
+ virtual void evaluateToSequenceReceiver(const DynamicContext::Ptr &context) const;
+
+ virtual SequenceType::Ptr staticType() const;
+
+ /**
+ * Both arguments must of type @c xs:string. It is assumes that the first argument's
+ * lexical space is @c xs:NCName.
+ */
+ virtual SequenceType::List expectedOperandTypes() const;
+
+ virtual ExpressionVisitorResult::Ptr accept(const ExpressionVisitor::Ptr &visitor) const;
+
+ virtual Properties properties() const;
+ private:
+ inline QXmlName evaluateTardata(const DynamicContext::Ptr &context) const;
+ /**
+ * Performs left-trimming only.
+ *
+ * @see QString::trimmed()
+ */
+ static inline QString leftTrimmed(const QString &input);
+
+ QString data(const DynamicContext::Ptr &context) const;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/expr/qqnameconstructor.cpp b/src/xmlpatterns/expr/qqnameconstructor.cpp
new file mode 100644
index 0000000..7925e2b
--- /dev/null
+++ b/src/xmlpatterns/expr/qqnameconstructor.cpp
@@ -0,0 +1,114 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qcommonsequencetypes_p.h"
+#include "qpatternistlocale_p.h"
+#include "qqnamevalue_p.h"
+
+#include "qqnameconstructor_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+QNameConstructor::QNameConstructor(const Expression::Ptr &source,
+ const NamespaceResolver::Ptr &nsResolver) : SingleContainer(source),
+ m_nsResolver(nsResolver)
+{
+ Q_ASSERT(m_nsResolver);
+}
+
+Item QNameConstructor::evaluateSingleton(const DynamicContext::Ptr &context) const
+{
+ Q_ASSERT(context);
+ const QString lexQName(m_operand->evaluateSingleton(context).stringValue());
+
+ const QXmlName expQName(expandQName<DynamicContext::Ptr,
+ ReportContext::XQDY0074,
+ ReportContext::XQDY0074>(lexQName,
+ context,
+ m_nsResolver,
+ this));
+ return toItem(QNameValue::fromValue(context->namePool(), expQName));
+}
+
+QXmlName::NamespaceCode QNameConstructor::namespaceForPrefix(const QXmlName::PrefixCode prefix,
+ const StaticContext::Ptr &context,
+ const SourceLocationReflection *const r)
+{
+ Q_ASSERT(context);
+ const QXmlName::NamespaceCode ns(context->namespaceBindings()->lookupNamespaceURI(prefix));
+
+ if(ns == NamespaceResolver::NoBinding)
+ {
+ context->error(QtXmlPatterns::tr("No namespace binding exists for the prefix %1")
+ .arg(formatKeyword(context->namePool()->stringForPrefix(prefix))),
+ ReportContext::XPST0081,
+ r);
+ return NamespaceResolver::NoBinding;
+ }
+ else
+ return ns;
+}
+
+SequenceType::Ptr QNameConstructor::staticType() const
+{
+ return CommonSequenceTypes::ExactlyOneQName;
+}
+
+SequenceType::List QNameConstructor::expectedOperandTypes() const
+{
+ SequenceType::List result;
+ result.append(CommonSequenceTypes::ExactlyOneString);
+ return result;
+}
+
+ExpressionVisitorResult::Ptr QNameConstructor::accept(const ExpressionVisitor::Ptr &visitor) const
+{
+ return visitor->visit(this);
+}
+
+const SourceLocationReflection *QNameConstructor::actualReflection() const
+{
+ return m_operand.data();
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/expr/qqnameconstructor_p.h b/src/xmlpatterns/expr/qqnameconstructor_p.h
new file mode 100644
index 0000000..4011870
--- /dev/null
+++ b/src/xmlpatterns/expr/qqnameconstructor_p.h
@@ -0,0 +1,182 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_QNameConstructor_H
+#define Patternist_QNameConstructor_H
+
+#include "qsinglecontainer_p.h"
+#include "qbuiltintypes_p.h"
+#include "qpatternistlocale_p.h"
+#include "qxpathhelper_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Creates an @c xs:QName value from a lexical QName using
+ * statically known namespace bindings.
+ *
+ * @see QQNameValue
+ * @see QXmlUtils
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_expressions
+ */
+ class QNameConstructor : public SingleContainer
+ {
+ public:
+
+ QNameConstructor(const Expression::Ptr &source,
+ const NamespaceResolver::Ptr &nsResolver);
+
+ virtual Item evaluateSingleton(const DynamicContext::Ptr &) const;
+
+ virtual SequenceType::List expectedOperandTypes() const;
+
+ virtual SequenceType::Ptr staticType() const;
+
+ virtual ExpressionVisitorResult::Ptr accept(const ExpressionVisitor::Ptr &visitor) const;
+
+ /**
+ * Expands @p lexicalQName, which is a lexical representation of a QName such as "x:body", into
+ * a QName using @p nsResolver to supply the namespace bindings.
+ *
+ * If @p lexicalQName is lexically invalid @p InvalidQName is raised via @p context, or if
+ * no namespace binding does not exists for a prefix(if any) in @p lexicalQName, @p NoBinding
+ * is raised via @p context.
+ *
+ * If @p asForAttribute is @c true, the name is considered to be for an
+ * attribute in some way, and @p lexicalQName will not pick up the
+ * default namespace if it doesn't have a prefix.
+ *
+ * @p nsResolver is parameterized meaning the function can be instantiated with either
+ * DynamicContext or StaticContext.
+ *
+ * @see QQNameValue
+ * @see QXmlUtils
+ */
+ template<typename TReportContext,
+ const ReportContext::ErrorCode InvalidQName,
+ const ReportContext::ErrorCode NoBinding>
+ static
+ QXmlName expandQName(const QString &lexicalQName,
+ const TReportContext &context,
+ const NamespaceResolver::Ptr &nsResolver,
+ const SourceLocationReflection *const r,
+ const bool asForAttribute = false);
+
+ /**
+ * Resolves the namespace prefix @p prefix to its namespace if it exists, or
+ * raised ReportContext::XPST0081 otherwise.
+ *
+ * @returns the namespace URI corresponding to @p prefix
+ */
+ static QXmlName::NamespaceCode namespaceForPrefix(const QXmlName::PrefixCode prefix,
+ const StaticContext::Ptr &context,
+ const SourceLocationReflection *const r);
+
+ virtual const SourceLocationReflection *actualReflection() const;
+
+ private:
+ const NamespaceResolver::Ptr m_nsResolver;
+ };
+
+ template<typename TReportContext,
+ const ReportContext::ErrorCode InvalidQName,
+ const ReportContext::ErrorCode NoBinding>
+ QXmlName QNameConstructor::expandQName(const QString &lexicalQName,
+ const TReportContext &context,
+ const NamespaceResolver::Ptr &nsResolver,
+ const SourceLocationReflection *const r,
+ const bool asForAttribute)
+ {
+ Q_ASSERT(nsResolver);
+ Q_ASSERT(context);
+
+ if(XPathHelper::isQName(lexicalQName))
+ {
+ QString prefix;
+ QString local;
+ XPathHelper::splitQName(lexicalQName, prefix, local);
+ const QXmlName::NamespaceCode nsCode = asForAttribute && prefix.isEmpty() ? QXmlName::NamespaceCode(StandardNamespaces::empty)
+ : (nsResolver->lookupNamespaceURI(context->namePool()->allocatePrefix(prefix)));
+
+ if(nsCode == NamespaceResolver::NoBinding)
+ {
+ context->error(QtXmlPatterns::tr("No namespace binding exists for "
+ "the prefix %1 in %2").arg(formatKeyword(prefix),
+ formatKeyword(lexicalQName)),
+ NoBinding,
+ r);
+ return QXmlName(); /* Silence compiler warning. */
+ }
+ else
+ return context->namePool()->allocateQName(context->namePool()->stringForNamespace(nsCode), local, prefix);
+ }
+ else
+ {
+ context->error(QtXmlPatterns::tr("%1 is an invalid %2")
+ .arg(formatData(lexicalQName))
+ .arg(formatType(context->namePool(), BuiltinTypes::xsQName)),
+ InvalidQName,
+ r);
+ return QXmlName(); /* Silence compiler warning. */
+ }
+ }
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/expr/qquantifiedexpression.cpp b/src/xmlpatterns/expr/qquantifiedexpression.cpp
new file mode 100644
index 0000000..a6c4d03
--- /dev/null
+++ b/src/xmlpatterns/expr/qquantifiedexpression.cpp
@@ -0,0 +1,140 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qcommonsequencetypes_p.h"
+#include "qgenericsequencetype_p.h"
+#include "qitemmappingiterator_p.h"
+
+#include "qquantifiedexpression_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+QuantifiedExpression::QuantifiedExpression(const VariableSlotID varSlot,
+ const Operator quantifier,
+ const Expression::Ptr &inClause,
+ const Expression::Ptr &testExpression)
+ : PairContainer(inClause, testExpression),
+ m_varSlot(varSlot),
+ m_quantifier(quantifier)
+{
+ Q_ASSERT(quantifier == Some || quantifier == Every);
+}
+
+Item QuantifiedExpression::mapToItem(const Item &item,
+ const DynamicContext::Ptr &context) const
+{
+ context->setRangeVariable(m_varSlot, item);
+ return item;
+}
+
+bool QuantifiedExpression::evaluateEBV(const DynamicContext::Ptr &context) const
+{
+ const Item::Iterator::Ptr it(makeItemMappingIterator<Item>(ConstPtr(this),
+ m_operand1->evaluateSequence(context),
+ context));
+
+ Item item(it->next());
+
+ if(m_quantifier == Some)
+ {
+ while(item)
+ {
+ if(m_operand2->evaluateEBV(context))
+ return true;
+ else
+ item = it->next();
+ };
+
+ return false;
+ }
+ else
+ {
+ Q_ASSERT(m_quantifier == Every);
+
+ while(item)
+ {
+ if(m_operand2->evaluateEBV(context))
+ item = it->next();
+ else
+ return false;
+ }
+
+ return true;
+ }
+}
+
+QString QuantifiedExpression::displayName(const Operator quantifier)
+{
+ if(quantifier == Some)
+ return QLatin1String("some");
+ else
+ {
+ Q_ASSERT(quantifier == Every);
+ return QLatin1String("every");
+ }
+}
+
+SequenceType::Ptr QuantifiedExpression::staticType() const
+{
+ return CommonSequenceTypes::ExactlyOneBoolean;
+}
+
+SequenceType::List QuantifiedExpression::expectedOperandTypes() const
+{
+ SequenceType::List result;
+ result.append(CommonSequenceTypes::ZeroOrMoreItems);
+ result.append(CommonSequenceTypes::EBV);
+ return result;
+}
+
+QuantifiedExpression::Operator QuantifiedExpression::operatorID() const
+{
+ return m_quantifier;
+}
+
+ExpressionVisitorResult::Ptr QuantifiedExpression::accept(const ExpressionVisitor::Ptr &visitor) const
+{
+ return visitor->visit(this);
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/expr/qquantifiedexpression_p.h b/src/xmlpatterns/expr/qquantifiedexpression_p.h
new file mode 100644
index 0000000..0c65782
--- /dev/null
+++ b/src/xmlpatterns/expr/qquantifiedexpression_p.h
@@ -0,0 +1,114 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_QuantifiedExpression_H
+#define Patternist_QuantifiedExpression_H
+
+#include "qpaircontainer_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Implements XPath 2.0's quantification expressions @c some and @c every.
+ *
+ * @see <a href="http://www.w3.org/TR/xpath20/#id-quantified-expressions">XML Path Language
+ * (XPath) 2.0, 3.9 Quantified Expressions</a>
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_expressions
+ */
+ class Q_AUTOTEST_EXPORT QuantifiedExpression : public PairContainer
+ {
+ public:
+ enum Operator
+ {
+ Some = 1,
+ Every
+ };
+
+ QuantifiedExpression(const VariableSlotID varSlot,
+ const Operator quantifier,
+ const Expression::Ptr &inClause,
+ const Expression::Ptr &testExpression);
+
+ virtual bool evaluateEBV(const DynamicContext::Ptr &context) const;
+ virtual SequenceType::Ptr staticType() const;
+ virtual SequenceType::List expectedOperandTypes() const;
+
+ Operator operatorID() const;
+
+ /**
+ * Determines the string representation for a quantification operator.
+ *
+ * @return "some" if @p quantifier is Some, or "every" if @p quantifier
+ * is Every
+ */
+ static QString displayName(const Operator quantifier);
+
+ virtual ExpressionVisitorResult::Ptr accept(const ExpressionVisitor::Ptr &visitor) const;
+
+ inline Item mapToItem(const Item &item, const DynamicContext::Ptr &context) const;
+
+ private:
+ typedef QExplicitlySharedDataPointer<const QuantifiedExpression> ConstPtr;
+ const VariableSlotID m_varSlot;
+ const Operator m_quantifier;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/expr/qrangeexpression.cpp b/src/xmlpatterns/expr/qrangeexpression.cpp
new file mode 100644
index 0000000..b4d7e91
--- /dev/null
+++ b/src/xmlpatterns/expr/qrangeexpression.cpp
@@ -0,0 +1,170 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qbuiltintypes_p.h"
+#include "qcommonsequencetypes_p.h"
+#include "qcommonvalues_p.h"
+#include "qgenericsequencetype_p.h"
+#include "qinteger_p.h"
+#include "qliteral_p.h"
+#include "qrangeiterator_p.h"
+
+#include "qrangeexpression_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+RangeExpression::RangeExpression(const Expression::Ptr &operand1,
+ const Expression::Ptr &operand2) : PairContainer(operand1, operand2)
+{
+}
+
+Item::Iterator::Ptr RangeExpression::evaluateSequence(const DynamicContext::Ptr &context) const
+{
+ const Item s(m_operand1->evaluateSingleton(context));
+
+ if(!s)
+ return CommonValues::emptyIterator;
+
+ const Item e(m_operand2->evaluateSingleton(context));
+ if(!e)
+ return CommonValues::emptyIterator;
+
+ const xsInteger start = s.as<Numeric>()->toInteger();
+ const xsInteger end = e.as<Numeric>()->toInteger();
+
+ if(start > end)
+ return CommonValues::emptyIterator;
+ else if(start == end)
+ return makeSingletonIterator(s);
+ else
+ return Item::Iterator::Ptr(new RangeIterator(start, RangeIterator::Forward, end));
+}
+
+Item RangeExpression::evaluateSingleton(const DynamicContext::Ptr &context) const
+{
+ return m_operand1->evaluateSingleton(context);
+}
+
+SequenceType::List RangeExpression::expectedOperandTypes() const
+{
+ SequenceType::List result;
+ result.append(CommonSequenceTypes::ZeroOrOneInteger);
+ result.append(CommonSequenceTypes::ZeroOrOneInteger);
+ return result;
+}
+
+SequenceType::Ptr RangeExpression::staticType() const
+{
+ /* This logic makes the Cardinality more specific. */
+ Cardinality::Count from;
+ bool hasFrom;
+
+ if(m_operand1->is(IDIntegerValue))
+ {
+ from = m_operand1->as<Literal>()->item().as<Integer>()->toInteger();
+ hasFrom = true;
+ }
+ else
+ {
+ hasFrom = false;
+ from = 0;
+ }
+
+ /* We can't check whether to is -1 since maybe the user wrote -1. Hence
+ * hasTo is required. */
+ bool hasTo;
+ Cardinality::Count to;
+
+ if(m_operand2->is(IDIntegerValue))
+ {
+ const xsInteger asInt = m_operand2->as<Literal>()->item().as<Integer>()->toInteger();
+ to = asInt;
+
+ if(to == asInt)
+ hasTo = true;
+ else
+ {
+ /* Cardinality::Count is not the same as type xsInteger. We had overflow. */
+ to = -1;
+ hasTo = false;
+ }
+ }
+ else
+ {
+ to = -1;
+ hasTo = false;
+ }
+
+ if(hasTo && hasFrom)
+ {
+ if(from > to)
+ {
+ /* The query is incorrectly written, we'll evaluate to the empty sequence.
+ * Just return what's correct. */
+ return CommonSequenceTypes::ZeroOrMoreIntegers;
+ }
+ else
+ {
+ Cardinality::Count count = (to - from) + 1; /* + 1, since it's inclusive. */
+ return makeGenericSequenceType(BuiltinTypes::xsInteger, Cardinality::fromExact(count));
+ }
+ }
+ else
+ {
+ /* We can't do fromExact(from, -1) since the latter can evaluate to a value that actually is
+ * lower than from, although that unfortunately is very unlikely. */
+ return CommonSequenceTypes::ZeroOrMoreIntegers;
+ }
+}
+
+Expression::Properties RangeExpression::properties() const
+{
+ return Expression::DisableElimination;
+}
+
+ExpressionVisitorResult::Ptr RangeExpression::accept(const ExpressionVisitor::Ptr &visitor) const
+{
+ return visitor->visit(this);
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/expr/qrangeexpression_p.h b/src/xmlpatterns/expr/qrangeexpression_p.h
new file mode 100644
index 0000000..94756d7
--- /dev/null
+++ b/src/xmlpatterns/expr/qrangeexpression_p.h
@@ -0,0 +1,112 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_RangeExpression_H
+#define Patternist_RangeExpression_H
+
+#include "qpaircontainer_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+
+ /**
+ * @short Implements XPath 2.0's @c to expression.
+ *
+ * Despite its name, RangeExpression is not related to RangeVariableDeclaration.
+ *
+ * @see <a href="http://www.w3.org/TR/xpath20/#construct_seq">XML Path Language
+ * (XPath) 2.0, 3.3.1 Constructing Sequences</a>
+ * @see RangeIterator
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_expressions
+ */
+ class RangeExpression : public PairContainer
+ {
+ public:
+ RangeExpression(const Expression::Ptr &operand1, const Expression::Ptr &operand2);
+
+ virtual Item::Iterator::Ptr evaluateSequence(const DynamicContext::Ptr &) const;
+ /**
+ * It's likely that this function gets called if staticType() inferred
+ * the cardinality to an exact number. In that case, we know that the
+ * first arguments is the same as the second argument.
+ */
+ virtual Item evaluateSingleton(const DynamicContext::Ptr &) const;
+
+ virtual SequenceType::List expectedOperandTypes() const;
+
+ /**
+ * @returns always CommonSequenceTypes::ZeroOrMoreIntegers
+ */
+ virtual SequenceType::Ptr staticType() const;
+
+ /**
+ * Disables compression for optimization reasons. For example, the
+ * expression "1 to 1000" would consume thousand allocated instances
+ * of Integer, and RangeIterator is well suited for dynamic evaluation.
+ *
+ * @returns Expression::DisableElimination
+ */
+ virtual Expression::Properties properties() const;
+
+ virtual ExpressionVisitorResult::Ptr accept(const ExpressionVisitor::Ptr &visitor) const;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/expr/qrangevariablereference.cpp b/src/xmlpatterns/expr/qrangevariablereference.cpp
new file mode 100644
index 0000000..e4d6c7e
--- /dev/null
+++ b/src/xmlpatterns/expr/qrangevariablereference.cpp
@@ -0,0 +1,92 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qboolean_p.h"
+#include "qgenericsequencetype_p.h"
+
+#include "qrangevariablereference_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+RangeVariableReference::RangeVariableReference(const Expression::Ptr &source,
+ const VariableSlotID slotP) : VariableReference(slotP),
+ m_sourceExpression(source)
+{
+ Q_ASSERT(source);
+}
+
+bool RangeVariableReference::evaluateEBV(const DynamicContext::Ptr &context) const
+{
+ Q_ASSERT_X(context->rangeVariable(slot()), Q_FUNC_INFO, "The range variable must be set.");
+ return Boolean::evaluateEBV(context->rangeVariable(slot()), context);
+}
+
+Item RangeVariableReference::evaluateSingleton(const DynamicContext::Ptr &context) const
+{
+ Q_ASSERT_X(context->rangeVariable(slot()), Q_FUNC_INFO, "The range variable must be set.");
+ return context->rangeVariable(slot());
+}
+
+SequenceType::Ptr RangeVariableReference::staticType() const
+{
+ return makeGenericSequenceType(m_sourceExpression->staticType()->itemType(),
+ Cardinality::exactlyOne());
+}
+
+Expression::ID RangeVariableReference::id() const
+{
+ return IDRangeVariableReference;
+}
+
+ExpressionVisitorResult::Ptr
+RangeVariableReference::accept(const ExpressionVisitor::Ptr &visitor) const
+{
+ return visitor->visit(this);
+}
+
+Expression::Properties RangeVariableReference::properties() const
+{
+ return DependsOnLocalVariable;
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/expr/qrangevariablereference_p.h b/src/xmlpatterns/expr/qrangevariablereference_p.h
new file mode 100644
index 0000000..1246937
--- /dev/null
+++ b/src/xmlpatterns/expr/qrangevariablereference_p.h
@@ -0,0 +1,100 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_RangeVariableReference_H
+#define Patternist_RangeVariableReference_H
+
+#include "qvariablereference_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short A reference to a variable declared with @c for or a quantification
+ * expression, but not for instance a @c let binding.
+ *
+ * A range variable always represents a single item, while an other
+ * expression provides the binding and iteration. A @c for expression is
+ * a good example.
+ *
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_expressions
+ */
+ class RangeVariableReference : public VariableReference
+ {
+ public:
+ RangeVariableReference(const Expression::Ptr &sourceExpression,
+ const VariableSlotID slot);
+
+ virtual bool evaluateEBV(const DynamicContext::Ptr &context) const;
+ virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const;
+ virtual SequenceType::Ptr staticType() const;
+
+ /**
+ * @returns IDRangeVariableReference
+ */
+ virtual ID id() const;
+
+ virtual ExpressionVisitorResult::Ptr accept(const ExpressionVisitor::Ptr &visitor) const;
+ virtual Properties properties() const;
+ private:
+ const Expression::Ptr m_sourceExpression;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/expr/qreturnorderby.cpp b/src/xmlpatterns/expr/qreturnorderby.cpp
new file mode 100644
index 0000000..c530971
--- /dev/null
+++ b/src/xmlpatterns/expr/qreturnorderby.cpp
@@ -0,0 +1,133 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qcommonsequencetypes_p.h"
+#include "qexpressionsequence_p.h"
+#include "qsorttuple_p.h"
+
+#include "qreturnorderby_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+ReturnOrderBy::ReturnOrderBy(const OrderBy::Stability aStability,
+ const OrderBy::OrderSpec::Vector &oSpecs,
+ const Expression::List &ops) : UnlimitedContainer(ops)
+ , m_stability(aStability)
+ , m_orderSpecs(oSpecs)
+ , m_flyAway(true)
+{
+ Q_ASSERT_X(m_operands.size() >= 2, Q_FUNC_INFO,
+ "ReturnOrderBy must have the return expression, and at least one sort key.");
+ Q_ASSERT(m_orderSpecs.size() == ops.size() - 1);
+}
+
+Item ReturnOrderBy::evaluateSingleton(const DynamicContext::Ptr &context) const
+{
+ Q_ASSERT(m_operands.size() > 1);
+ const Item::Iterator::Ptr value(makeListIterator(m_operands.first()->evaluateSequence(context)->toList()));
+ Item::Vector sortKeys;
+
+ /* We're skipping the first operand. */
+ const int len = m_operands.size() - 1;
+ sortKeys.resize(len);
+
+ for(int i = 1; i <= len; ++i)
+ sortKeys[i - 1] = m_operands.at(i)->evaluateSingleton(context);
+
+ return Item(new SortTuple(value, sortKeys));
+}
+
+bool ReturnOrderBy::evaluateEBV(const DynamicContext::Ptr &context) const
+{
+ // TODO This is temporary code.
+ return m_operands.first()->evaluateEBV(context);
+}
+
+Expression::Ptr ReturnOrderBy::compress(const StaticContext::Ptr &context)
+{
+ /* We first did this in typeCheck(), but that broke due to that type checks were
+ * missed, which other pieces relied on. */
+ if(m_flyAway)
+ {
+ /* We only want the return expression, not the sort keys. */
+ return m_operands.first()->compress(context);
+ }
+ else
+ {
+ /* We don't need the members, so don't keep a reference to them. */
+ m_orderSpecs.clear();
+
+ return UnlimitedContainer::compress(context);
+ }
+}
+
+Expression::Properties ReturnOrderBy::properties() const
+{
+ /* For some unknown reason this is necessary for XQTS test case orderBy18. */
+ return DisableElimination;
+}
+
+ExpressionVisitorResult::Ptr ReturnOrderBy::accept(const ExpressionVisitor::Ptr &visitor) const
+{
+ return visitor->visit(this);
+}
+
+SequenceType::Ptr ReturnOrderBy::staticType() const
+{
+ return m_operands.first()->staticType();
+}
+
+SequenceType::List ReturnOrderBy::expectedOperandTypes() const
+{
+ SequenceType::List result;
+ result.append(CommonSequenceTypes::ZeroOrMoreItems);
+ result.append(CommonSequenceTypes::ZeroOrOneAtomicType);
+ return result;
+}
+
+Expression::ID ReturnOrderBy::id() const
+{
+ return IDReturnOrderBy;
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/expr/qreturnorderby_p.h b/src/xmlpatterns/expr/qreturnorderby_p.h
new file mode 100644
index 0000000..6a51717
--- /dev/null
+++ b/src/xmlpatterns/expr/qreturnorderby_p.h
@@ -0,0 +1,136 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_ReturnOrderBy_H
+#define Patternist_ReturnOrderBy_H
+
+#include "qorderby_p.h"
+#include "qunlimitedcontainer_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Together with OrderBy, it implements XQuery 1.0's <tt>order by</tt> expression.
+ *
+ * ReturnOrderBy evaluates the sort keys and values, and hands it over to
+ * OrderBy, which is an AST ancestor, using SortTuples.
+ *
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_expressions
+ */
+ class ReturnOrderBy : public UnlimitedContainer
+ {
+ public:
+ /**
+ * In @p operands the first item is the return expression, and the
+ * rest, which is at least one, are the sort keys.
+ */
+ ReturnOrderBy(const OrderBy::Stability stability,
+ const OrderBy::OrderSpec::Vector &oSpecs,
+ const Expression::List &operands);
+
+ virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const;
+ virtual bool evaluateEBV(const DynamicContext::Ptr &context) const;
+ virtual SequenceType::Ptr staticType() const;
+ virtual SequenceType::List expectedOperandTypes() const;
+ virtual Expression::Ptr compress(const StaticContext::Ptr &context);
+ virtual ExpressionVisitorResult::Ptr accept(const ExpressionVisitor::Ptr &visitor) const;
+ virtual ID id() const;
+
+ inline OrderBy::OrderSpec::Vector orderSpecs() const
+ {
+ return m_orderSpecs;
+ }
+
+ inline OrderBy::Stability stability() const
+ {
+ return m_stability;
+ }
+
+ /**
+ * In the case of that we don't have a for-expression beloning us, but
+ * only a let clause, this ReturnOrderBy breaks if it stays in the AST.
+ * So, by default we assume that we should write ourselves away, unless
+ * this function is called. The associated ForClause will call it
+ * during typeCheck(), if it exists.
+ */
+ inline void setStay(const bool a)
+ {
+ m_flyAway = !a;
+ }
+
+ virtual Properties properties() const;
+ private:
+ /**
+ * This variable is unfortunately only used at compile time. However,
+ * it's tricky to get rid of it due to how QueryTransformParser would
+ * have to be adapted.
+ */
+ const OrderBy::Stability m_stability;
+
+ OrderBy::OrderSpec::Vector m_orderSpecs;
+
+ /**
+ * @see stay()
+ */
+ bool m_flyAway;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/expr/qsimplecontentconstructor.cpp b/src/xmlpatterns/expr/qsimplecontentconstructor.cpp
new file mode 100644
index 0000000..e98d988
--- /dev/null
+++ b/src/xmlpatterns/expr/qsimplecontentconstructor.cpp
@@ -0,0 +1,114 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qcommonsequencetypes_p.h"
+#include "qatomicstring_p.h"
+
+#include "qsimplecontentconstructor_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+SimpleContentConstructor::SimpleContentConstructor(const Expression::Ptr &operand) : SingleContainer(operand)
+{
+}
+
+Item SimpleContentConstructor::evaluateSingleton(const DynamicContext::Ptr &context) const
+{
+ const Item::Iterator::Ptr it(m_operand->evaluateSequence(context));
+ Item next(it->next());
+ QString result;
+
+ if(next)
+ {
+ result = next.stringValue();
+ next = it->next();
+ }
+ else
+ return Item();
+
+ while(next)
+ {
+ result += QLatin1Char(' ');
+ result += next.stringValue();
+ next = it->next();
+ }
+
+ return AtomicString::fromValue(result);
+}
+
+Expression::Ptr SimpleContentConstructor::compress(const StaticContext::Ptr &context)
+{
+ const Expression::Ptr me(SingleContainer::compress(context));
+
+ if(me.data() == this)
+ {
+ /* Optimization: if we will evaluate to a single string, we're not
+ * necessary. */
+ if(CommonSequenceTypes::ExactlyOneString->matches(m_operand->staticType()))
+ return m_operand;
+ }
+
+ return me;
+}
+
+SequenceType::List SimpleContentConstructor::expectedOperandTypes() const
+{
+ SequenceType::List result;
+ result.append(CommonSequenceTypes::ZeroOrMoreAtomicTypes);
+ return result;
+}
+
+SequenceType::Ptr SimpleContentConstructor::staticType() const
+{
+ if(m_operand->staticType()->cardinality().allowsEmpty())
+ return CommonSequenceTypes::ZeroOrOneString;
+ else
+ return CommonSequenceTypes::ExactlyOneString;
+}
+
+ExpressionVisitorResult::Ptr SimpleContentConstructor::accept(const ExpressionVisitor::Ptr &visitor) const
+{
+ return visitor->visit(this);
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/expr/qsimplecontentconstructor_p.h b/src/xmlpatterns/expr/qsimplecontentconstructor_p.h
new file mode 100644
index 0000000..bb80b4a
--- /dev/null
+++ b/src/xmlpatterns/expr/qsimplecontentconstructor_p.h
@@ -0,0 +1,96 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_SimpleContentConstructor_H
+#define Patternist_SimpleContentConstructor_H
+
+#include "qsinglecontainer_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+
+ /**
+ * @short Constructs simple content as specified for attributes in direct
+ * element constructors in XQuery.
+ *
+ * @note Sometimes you want XSLTSimpleContentConstructor.
+ *
+ * @see XSLTSimpleContentConstructor
+ * @see <a href="http://www.w3.org/TR/xquery/#id-attributes">XQuery 1.0:
+ * An XML Query Language, 3.7.1.1 Attributes</a>
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_expressions
+ */
+ class SimpleContentConstructor : public SingleContainer
+ {
+ public:
+ SimpleContentConstructor(const Expression::Ptr &operand);
+
+ virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const;
+
+ virtual Expression::Ptr compress(const StaticContext::Ptr &context);
+
+ virtual SequenceType::List expectedOperandTypes() const;
+ virtual SequenceType::Ptr staticType() const;
+
+ virtual ExpressionVisitorResult::Ptr accept(const ExpressionVisitor::Ptr &visitor) const;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/expr/qsinglecontainer.cpp b/src/xmlpatterns/expr/qsinglecontainer.cpp
new file mode 100644
index 0000000..cd280f3
--- /dev/null
+++ b/src/xmlpatterns/expr/qsinglecontainer.cpp
@@ -0,0 +1,76 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QList>
+
+
+#include "qsinglecontainer_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+SingleContainer::SingleContainer(const Expression::Ptr &operand) : m_operand(operand)
+{
+ Q_ASSERT(operand);
+}
+
+Expression::List SingleContainer::operands() const
+{
+ Expression::List list;
+ list.append(m_operand);
+ return list;
+}
+
+void SingleContainer::setOperands(const Expression::List &ops)
+{
+ Q_ASSERT(ops.count() == 1);
+ m_operand = ops.first();
+}
+
+bool SingleContainer::compressOperands(const StaticContext::Ptr &context)
+{
+ rewrite(m_operand, m_operand->compress(context), context);
+
+ return m_operand->isEvaluated();
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/expr/qsinglecontainer_p.h b/src/xmlpatterns/expr/qsinglecontainer_p.h
new file mode 100644
index 0000000..a55e891
--- /dev/null
+++ b/src/xmlpatterns/expr/qsinglecontainer_p.h
@@ -0,0 +1,88 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_SingleContainer_H
+#define Patternist_SingleContainer_H
+
+#include "qexpression_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Base class for expressions that has exactly one operand.
+ *
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_expressions
+ */
+ class SingleContainer : public Expression
+ {
+ public:
+ virtual Expression::List operands() const;
+
+ virtual void setOperands(const Expression::List &operands);
+ virtual bool compressOperands(const StaticContext::Ptr &);
+
+ protected:
+ SingleContainer(const Expression::Ptr &operand);
+
+ Expression::Ptr m_operand;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/expr/qsourcelocationreflection.cpp b/src/xmlpatterns/expr/qsourcelocationreflection.cpp
new file mode 100644
index 0000000..d24b030
--- /dev/null
+++ b/src/xmlpatterns/expr/qsourcelocationreflection.cpp
@@ -0,0 +1,65 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qsourcelocation.h"
+
+#include "qsourcelocationreflection_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+QSourceLocation SourceLocationReflection::sourceLocation() const
+{
+ return QSourceLocation();
+}
+
+const SourceLocationReflection *DelegatingSourceLocationReflection::actualReflection() const
+{
+ return m_r->actualReflection();
+}
+
+QString DelegatingSourceLocationReflection::description() const
+{
+ return m_r->description();
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/expr/qsourcelocationreflection_p.h b/src/xmlpatterns/expr/qsourcelocationreflection_p.h
new file mode 100644
index 0000000..d85c10c
--- /dev/null
+++ b/src/xmlpatterns/expr/qsourcelocationreflection_p.h
@@ -0,0 +1,131 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_SourceLocationReflection_H
+#define Patternist_SourceLocationReflection_H
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+class QString;
+
+namespace QPatternist
+{
+ /**
+ * @short Base class for all instances that represents something
+ * at a certain location.
+ *
+ * SourceLocationReflection does not provide the source location itself,
+ * the address to an instance is the mark for it, that in turn can be used
+ * for looking up the source location where that mapping is provided.
+ *
+ * However, this SourceLocationReflection is not itself the mark. The real
+ * mark is retrieved by calling actualReflection(). This mechanism
+ * allows a SourceLocationReflection sub-class to delegate, or be an alias,
+ * for another source location mark.
+ *
+ * If sourceLocation() returns a non-null object, it will be used instead
+ * of looking up via actualReflection().
+ *
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_expressions
+ */
+ class Q_AUTOTEST_EXPORT SourceLocationReflection
+ {
+ public:
+ inline SourceLocationReflection()
+ {
+ }
+
+ virtual ~SourceLocationReflection()
+ {
+ }
+
+ virtual const SourceLocationReflection *actualReflection() const = 0;
+
+ /**
+ * A description of what represents the source code location, for
+ * human consumption. Must be translated, as appropriate.
+ */
+ virtual QString description() const
+ {
+ return QString();
+ }
+
+ virtual QSourceLocation sourceLocation() const;
+
+ private:
+ Q_DISABLE_COPY(SourceLocationReflection)
+ };
+
+ class DelegatingSourceLocationReflection : public SourceLocationReflection
+ {
+ public:
+ inline DelegatingSourceLocationReflection(const SourceLocationReflection *const r) : m_r(r)
+ {
+ Q_ASSERT(r);
+ }
+
+ virtual const SourceLocationReflection *actualReflection() const;
+ virtual QString description() const;
+
+ private:
+ const SourceLocationReflection *const m_r;
+ };
+
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/expr/qstaticbaseuristore.cpp b/src/xmlpatterns/expr/qstaticbaseuristore.cpp
new file mode 100644
index 0000000..41b2d02
--- /dev/null
+++ b/src/xmlpatterns/expr/qstaticbaseuristore.cpp
@@ -0,0 +1,82 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qcommonsequencetypes_p.h"
+#include "qstaticbaseuricontext_p.h"
+
+#include "qstaticbaseuristore_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+StaticBaseURIStore::StaticBaseURIStore(const QUrl &baseURI,
+ const Expression::Ptr &operand) : SingleContainer(operand)
+ , m_baseURI(baseURI)
+{
+}
+
+Expression::Ptr StaticBaseURIStore::typeCheck(const StaticContext::Ptr &context,
+ const SequenceType::Ptr &reqType)
+{
+ const StaticContext::Ptr newContext(new StaticBaseURIContext(context->baseURI().resolved(m_baseURI),
+ context));
+ return m_operand->typeCheck(newContext, reqType);
+}
+
+SequenceType::Ptr StaticBaseURIStore::staticType() const
+{
+ return m_operand->staticType();
+}
+
+SequenceType::List StaticBaseURIStore::expectedOperandTypes() const
+{
+ SequenceType::List ops;
+ ops.append(CommonSequenceTypes::ZeroOrMoreItems);
+ return ops;
+}
+
+ExpressionVisitorResult::Ptr StaticBaseURIStore::accept(const ExpressionVisitor::Ptr &visitor) const
+{
+ return visitor->visit(this);
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/expr/qstaticbaseuristore_p.h b/src/xmlpatterns/expr/qstaticbaseuristore_p.h
new file mode 100644
index 0000000..1347eab
--- /dev/null
+++ b/src/xmlpatterns/expr/qstaticbaseuristore_p.h
@@ -0,0 +1,96 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_StaticBaseURIStore_H
+#define Patternist_StaticBaseURIStore_H
+
+#include "qsinglecontainer_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short A compile time only AST node that changes the static base URI,
+ * used when @c xml:base attributes appears.
+ *
+ * @see StaticBaseURIContext
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_expressions
+ * @since 4.5
+ */
+ class StaticBaseURIStore : public SingleContainer
+ {
+ public:
+ /**
+ * @p baseURI must be valid, not empty, and either relative or
+ * absolute.
+ */
+ StaticBaseURIStore(const QUrl &baseURI,
+ const Expression::Ptr &operand);
+ virtual Expression::Ptr typeCheck(const StaticContext::Ptr &context,
+ const SequenceType::Ptr &reqType);
+ virtual SequenceType::Ptr staticType() const;
+ virtual SequenceType::List expectedOperandTypes() const;
+ virtual ExpressionVisitorResult::Ptr accept(const ExpressionVisitor::Ptr &visitor) const;
+
+ private:
+ const QUrl m_baseURI;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/expr/qstaticcompatibilitystore.cpp b/src/xmlpatterns/expr/qstaticcompatibilitystore.cpp
new file mode 100644
index 0000000..1131955
--- /dev/null
+++ b/src/xmlpatterns/expr/qstaticcompatibilitystore.cpp
@@ -0,0 +1,79 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qcommonsequencetypes_p.h"
+#include "qstaticcompatibilitycontext_p.h"
+
+#include "qstaticcompatibilitystore_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+StaticCompatibilityStore::StaticCompatibilityStore(const Expression::Ptr &operand) : SingleContainer(operand)
+{
+}
+
+Expression::Ptr StaticCompatibilityStore::typeCheck(const StaticContext::Ptr &context,
+ const SequenceType::Ptr &reqType)
+{
+ const StaticContext::Ptr newContext(new StaticCompatibilityContext(context));
+ return m_operand->typeCheck(newContext, reqType);
+}
+
+SequenceType::Ptr StaticCompatibilityStore::staticType() const
+{
+ return m_operand->staticType();
+}
+
+SequenceType::List StaticCompatibilityStore::expectedOperandTypes() const
+{
+ SequenceType::List ops;
+ ops.append(CommonSequenceTypes::ZeroOrMoreItems);
+ return ops;
+}
+
+ExpressionVisitorResult::Ptr StaticCompatibilityStore::accept(const ExpressionVisitor::Ptr &visitor) const
+{
+ return visitor->visit(this);
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/expr/qstaticcompatibilitystore_p.h b/src/xmlpatterns/expr/qstaticcompatibilitystore_p.h
new file mode 100644
index 0000000..981a177
--- /dev/null
+++ b/src/xmlpatterns/expr/qstaticcompatibilitystore_p.h
@@ -0,0 +1,92 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_StaticCompatibilityStore_H
+#define Patternist_StaticCompatibilityStore_H
+
+#include "qsinglecontainer_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short A compile time only AST node that changes the backwareds compatibility mode.
+ * Used for XSL-T 2.0's backwards compatibility mode.
+ *
+ * @see StaticCompatibilityContext
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_expressions
+ * @since 4.5
+ */
+ class StaticCompatibilityStore : public SingleContainer
+ {
+ public:
+ /**
+ * @p baseURI must be valid, not empty, and either relative or
+ * absolute.
+ */
+ StaticCompatibilityStore(const Expression::Ptr &operand);
+ virtual Expression::Ptr typeCheck(const StaticContext::Ptr &context,
+ const SequenceType::Ptr &reqType);
+ virtual SequenceType::Ptr staticType() const;
+ virtual SequenceType::List expectedOperandTypes() const;
+ virtual ExpressionVisitorResult::Ptr accept(const ExpressionVisitor::Ptr &visitor) const;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/expr/qtemplate.cpp b/src/xmlpatterns/expr/qtemplate.cpp
new file mode 100644
index 0000000..79afab6
--- /dev/null
+++ b/src/xmlpatterns/expr/qtemplate.cpp
@@ -0,0 +1,232 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qdynamiccontextstore_p.h"
+#include "qpatternistlocale_p.h"
+
+#include "qtemplate_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+const SourceLocationReflection* Template::actualReflection() const
+{
+ return this;
+}
+
+DynamicContext::TemplateParameterHash Template::parametersAsHash() const
+{
+ DynamicContext::TemplateParameterHash retval;
+ const int len = templateParameters.count();
+
+ for(int i = 0; i < len; ++i)
+ {
+ const VariableDeclaration::Ptr &at = templateParameters.at(i);
+ retval.insert(at->name, at->expression());
+ }
+
+ return retval;
+}
+
+void Template::raiseXTSE0680(const ReportContext::Ptr &context,
+ const QXmlName &name,
+ const SourceLocationReflection *const reflection)
+{
+ context->error(QtXmlPatterns::tr("The parameter %1 is passed, but no corresponding %2 exists.")
+ .arg(formatKeyword(context->namePool(), name),
+ formatKeyword(QLatin1String("xsl:param"))),
+ ReportContext::XTSE0680,
+ reflection);
+}
+
+DynamicContext::Ptr Template::createContext(const TemplateInvoker *const invoker,
+ const DynamicContext::Ptr &context,
+ const bool isCallTemplate) const
+{
+ Q_ASSERT(invoker);
+ Q_ASSERT(context);
+
+ /* We have:
+ * - xsl:params in the target template (if any) which may provide
+ * default values.
+ * - xsl:with-params in the caller (if any) which provides values.
+ *
+ * We need to, for each parameter:
+ * - If the called template provides no default value and the caller
+ * has no value, it's an error
+ * - If the called template has a default value and the caller provides
+ * none, it should be used
+ * - In any case the caller provides a value, it needs to be used.
+ *
+ * Problems to look out for:
+ *
+ * - Each xsl:param is in scope for the subsequent xsl:params. Hence,
+ * the evaluation of one xsl:param can depend on another xsl:param,
+ * and so on
+ * - The focus for xsl:params is different from the focus for
+ * the xsl:with-params
+ * - The xsl:with-params are not in scope for the xsl:params.
+ */
+
+ WithParam::Hash withParams(invoker->withParams());
+
+ /**
+ * Parameters or not, we must in any case create a new stack frame
+ * for the template invocation since otherwise we will trash our existing
+ * variables. Hence it's as with calling user functions.
+ *
+ * This is especially reproducible with recursive functions.
+ */
+ DynamicContext::Ptr newStack(context->createStack());
+
+ /* We have no parameters, and we have no further error checking to
+ * do in the case of not being xsl:apply-templates, so we need to do nothing. */
+ if(templateParameters.isEmpty() && (!isCallTemplate || withParams.isEmpty()))
+ return newStack;
+
+ const DynamicContext::TemplateParameterHash hashedParams(parametersAsHash());
+ DynamicContext::TemplateParameterHash sewnTogether(hashedParams);
+
+ const DynamicContext::TemplateParameterHash::iterator end(sewnTogether.end());
+
+ for(DynamicContext::TemplateParameterHash::iterator it(sewnTogether.begin());
+ it != end;
+ ++it)
+ {
+ Expression::Ptr &param = it.value();
+
+ WithParam::Ptr &withParam = withParams[it.key()];
+
+ if(withParam)
+ param = Expression::Ptr(new DynamicContextStore(withParam->sourceExpression(), context));
+ else if(!param)
+ {
+ /* Ops, no xsl:with-param and no default value to cover up for it.
+ */
+ context->error(QtXmlPatterns::tr("The parameter %1 is required, but no corresponding %2 is supplied.")
+ .arg(formatKeyword(context->namePool(), it.key()),
+ formatKeyword(QLatin1String("xsl:with-param"))),
+ ReportContext::XTSE0690,
+ this);
+ }
+ }
+
+ if(isCallTemplate)
+ {
+ /* Find xsl:with-param that has no corresponding xsl:param. */
+ /* Optimization: candidate for threading? */
+
+ const WithParam::Hash::const_iterator end(withParams.constEnd());
+
+ for(WithParam::Hash::const_iterator it(withParams.constBegin()); it != end; ++it)
+ {
+ if(!hashedParams.contains(it.key()))
+ raiseXTSE0680(context, it.key(), this);
+ }
+
+ }
+
+ newStack->templateParameterStore() = sewnTogether;
+ return newStack;
+}
+
+void Template::compileParameters(const StaticContext::Ptr &context)
+{
+ Q_ASSERT(context);
+
+ const int len = templateParameters.count();
+
+ for(int i = 0; i < len; ++i)
+ {
+ const VariableDeclaration::Ptr &at = templateParameters.at(i);
+
+ /* If our value is required, we don't have a default value. */
+ if(at->expression())
+ {
+ // TODO why do we pass in its own type here?
+ at->setExpression(at->expression()->typeCheck(context, at->expression()->staticType()));
+
+ at->setExpression(at->expression()->compress(context));
+ }
+ }
+}
+
+Expression::Properties Template::properties() const
+{
+ return Expression::DisableElimination; /* We're having issues with recursion detection, so this path currently loops infintely. */
+
+ Expression::Properties collect(body->properties());
+
+ VariableDeclaration::List::const_iterator end(templateParameters.constEnd());
+
+ for(VariableDeclaration::List::const_iterator it(templateParameters.constBegin());
+ it != end;
+ ++it)
+ {
+ if((*it)->expression())
+ collect |= (*it)->expression()->properties();
+ }
+
+ // TODO simplify.
+ return collect & (Expression::RequiresFocus | Expression::IsEvaluated | Expression::DisableElimination);
+}
+
+Expression::Properties Template::dependencies() const
+{
+ return Expression::DisableElimination; /* We're having issues with recursion detection, so this path currently loops infintely. */
+
+ Expression::Properties collect(body->dependencies());
+
+ VariableDeclaration::List::const_iterator end(templateParameters.constEnd());
+
+ for(VariableDeclaration::List::const_iterator it(templateParameters.constBegin());
+ it != end;
+ ++it)
+ {
+ if((*it)->expression())
+ collect |= (*it)->expression()->dependencies();
+ }
+
+ return collect & (Expression::RequiresFocus | Expression::IsEvaluated | Expression::DisableElimination);
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/expr/qtemplate_p.h b/src/xmlpatterns/expr/qtemplate_p.h
new file mode 100644
index 0000000..cf00850
--- /dev/null
+++ b/src/xmlpatterns/expr/qtemplate_p.h
@@ -0,0 +1,146 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_Template_H
+#define Patternist_Template_H
+
+#include <QSharedData>
+#include <QVector>
+
+#include "qdynamiccontext_p.h"
+#include "qexpression_p.h"
+#include "qsourcelocationreflection_p.h"
+#include "qtemplateinvoker_p.h"
+#include "qvariabledeclaration_p.h"
+
+QT_BEGIN_HEADER
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Contains data related to a template.
+ *
+ * A Template is associated with a mode, by being housed
+ * inside a TemplateMode instance.
+ *
+ * Template has role very similar to UserFunction.
+ *
+ * @see TemplateMode
+ * @see TemplatePattern
+ * @see UserFunction
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_expressions
+ * @since 4.5
+ */
+ class Template : public QSharedData
+ , public SourceLocationReflection
+
+ {
+ public:
+ typedef QExplicitlySharedDataPointer<Template> Ptr;
+ typedef QVector<Template::Ptr> Vector;
+
+ inline Template(const ImportPrecedence ip,
+ const SequenceType::Ptr &reqType) : importPrecedence(ip)
+ , m_reqType(reqType)
+ {
+ }
+
+ Expression::Ptr body;
+
+ /**
+ * Returns @c this.
+ */
+ virtual const SourceLocationReflection* actualReflection() const;
+
+ const ImportPrecedence importPrecedence;
+
+ VariableDeclaration::List templateParameters;
+
+ /**
+ * If @p isCallTemplate, the caller is @c xsl:call-template, as opposed
+ * to for instance @c xsl:apply-templates. This affects error
+ * reporting.
+ */
+ DynamicContext::Ptr createContext(const TemplateInvoker *const invoker,
+ const DynamicContext::Ptr &context,
+ const bool isCallTemplate) const;
+
+ /**
+ * Since we have our template parameters in templateParameters, we need
+ * this separate step to do the regular phases:
+ * Expression::typeCheck(), and Expression::compress().
+ */
+ void compileParameters(const StaticContext::Ptr &context);
+
+ /**
+ * A value which takes into account the body and its template
+ * parameters.
+ */
+ Expression::Properties properties() const;
+
+ Expression::Properties dependencies() const;
+
+ static void raiseXTSE0680(const ReportContext::Ptr &context,
+ const QXmlName &name,
+ const SourceLocationReflection *const reflection);
+
+ private:
+ DynamicContext::TemplateParameterHash parametersAsHash() const;
+ const SequenceType::Ptr m_reqType;
+ };
+}
+
+QT_END_NAMESPACE
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/expr/qtemplateinvoker.cpp b/src/xmlpatterns/expr/qtemplateinvoker.cpp
new file mode 100644
index 0000000..7de8e01
--- /dev/null
+++ b/src/xmlpatterns/expr/qtemplateinvoker.cpp
@@ -0,0 +1,106 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qtemplateinvoker_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+TemplateInvoker::TemplateInvoker(const WithParam::Hash &withParams,
+ const QXmlName &name) : CallSite(name)
+ , m_withParams(withParams)
+{
+ const WithParam::Hash::const_iterator end(m_withParams.constEnd());
+
+ for(WithParam::Hash::const_iterator it(m_withParams.constBegin()); it != end; ++it)
+ {
+ /* In the case of for instance:
+ * <xsl:with-param name="empty_seq" as="item()"/>
+ *
+ * we have no default expression. */
+ Q_ASSERT(it.value()->sourceExpression());
+ m_operands.append(it.value()->sourceExpression());
+ }
+}
+
+Expression::Ptr TemplateInvoker::compress(const StaticContext::Ptr &context)
+{
+ /* CallSite::compress() may have changed our children, so update
+ * our m_withParams. */
+ const Expression::Ptr me(CallSite::compress(context));
+ const WithParam::Hash::const_iterator end(m_withParams.constEnd());
+ int exprIndex = -1;
+
+ for(WithParam::Hash::const_iterator it(m_withParams.constBegin()); it != end; ++it)
+ {
+ if(it.value()->sourceExpression())
+ {
+ ++exprIndex;
+ it.value()->setSourceExpression(m_operands.at(exprIndex));
+ }
+ }
+
+ return me;
+}
+
+SequenceType::List TemplateInvoker::expectedOperandTypes() const
+{
+ SequenceType::List result;
+
+ /* We don't return the type of the m_template->templateParameters(), we
+ * return the type of the @c xsl:with-param first. @em After that, we
+ * manually apply the parameter types in typeCheck(). */
+ const WithParam::Hash::const_iterator end(m_withParams.constEnd());
+
+ for(WithParam::Hash::const_iterator it(m_withParams.constBegin()); it != end; ++it)
+ {
+ /* We're not guaranteed to have a with-param, we may be using the
+ * default value of the xsl:param. Tunnel parameters may also play
+ * in. */
+ result.append(it.value()->type());
+ }
+
+ return result;
+}
+
+QT_END_NAMESPACE
+
diff --git a/src/xmlpatterns/expr/qtemplateinvoker_p.h b/src/xmlpatterns/expr/qtemplateinvoker_p.h
new file mode 100644
index 0000000..caf0253
--- /dev/null
+++ b/src/xmlpatterns/expr/qtemplateinvoker_p.h
@@ -0,0 +1,119 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_TemplateInvoker_H
+#define Patternist_TemplateInvoker_H
+
+#include "qcallsite_p.h"
+#include "qwithparam_p.h"
+
+QT_BEGIN_HEADER
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Base class for classes that invokes @em templates, such as
+ * CallTemplate and ApplyTemplate.
+ *
+ * TemplateInvoker has the member m_withParams, which is the @c
+ * xsl:with-param instructions of the caller. The definite source for the
+ * expressions is m_withParams, not Expression::operands(). However, the
+ * order of operands() is defined, while m_withParams is not since it's a
+ * hash. Therefore operands() is definite on order.
+ *
+ * TemplateInvoker is intended to be sub-classed.
+ *
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_expressions
+ * @since 4.5
+ */
+ class TemplateInvoker : public CallSite
+ {
+ public:
+ virtual Expression::Ptr compress(const StaticContext::Ptr &context);
+
+ inline const WithParam::Hash &withParams() const;
+ WithParam::Hash m_withParams;
+
+ /**
+ * This is a bit complicated by that we have two required types, one
+ * specified by @c xsl:param in the template declaration, and one on @c
+ * xsl:with-param.
+ *
+ * @see UserFunctionCallsite::expectedOperandTypes()
+ * @see <a href="http://www.w3.org/TR/xslt20/#with-param">XSL
+ * Transformations (XSLT) Version 2.0, 10.1.1 Passing Parameters to Templates</a>
+ */
+ virtual SequenceType::List expectedOperandTypes() const;
+ protected:
+ /**
+ * @p withParams may be empty.
+ */
+ TemplateInvoker(const WithParam::Hash &withParams,
+ const QXmlName &name = QXmlName());
+
+ private:
+ Q_DISABLE_COPY(TemplateInvoker)
+ };
+
+ const WithParam::Hash &TemplateInvoker::withParams() const
+ {
+ return m_withParams;
+ }
+
+}
+
+QT_END_NAMESPACE
+QT_END_HEADER
+
+#endif
+
diff --git a/src/xmlpatterns/expr/qtemplatemode.cpp b/src/xmlpatterns/expr/qtemplatemode.cpp
new file mode 100644
index 0000000..976cefd
--- /dev/null
+++ b/src/xmlpatterns/expr/qtemplatemode.cpp
@@ -0,0 +1,61 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qtemplatemode_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+bool TemplateMode::lessThanByPriority(const TemplatePattern::Ptr &t1,
+ const TemplatePattern::Ptr &t2)
+{
+ return t1->priority() > t2->priority();
+}
+
+void TemplateMode::finalize()
+{
+ qSort(templatePatterns.begin(), templatePatterns.end(), lessThanByPriority);
+
+ /* Now we have a list of patterns sorted by priority. */
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/expr/qtemplatemode_p.h b/src/xmlpatterns/expr/qtemplatemode_p.h
new file mode 100644
index 0000000..044b405
--- /dev/null
+++ b/src/xmlpatterns/expr/qtemplatemode_p.h
@@ -0,0 +1,128 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_TemplateMode_H
+#define Patternist_TemplateMode_H
+
+#include <QtCore/QSharedData>
+#include <QXmlName>
+
+#include "qtemplatepattern_p.h"
+
+QT_BEGIN_HEADER
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Houses the data specific to the templates for a certain mode.
+ *
+ * @see Template
+ * @see TemplatePattern
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_expressions
+ * @since 4.5
+ */
+ class Q_AUTOTEST_EXPORT TemplateMode : public QSharedData
+ {
+ public:
+ typedef QExplicitlySharedDataPointer<TemplateMode> Ptr;
+
+ inline TemplateMode(const QXmlName &modeName) : m_modeName(modeName)
+ {
+ }
+
+ TemplatePattern::Vector templatePatterns;
+
+ /**
+ * Adds the templates in @p mode to this TemplateMode.
+ *
+ * The existing name remains.
+ */
+ inline void addMode(const TemplateMode::Ptr &mode);
+
+ inline const QXmlName &name() const;
+
+ /**
+ * Orders its templates by priority such that the first lookup always
+ * returns the template with highest priority, and removes templates
+ * shadowed by import precedence.
+ */
+ void finalize();
+
+ private:
+ const QXmlName m_modeName;
+ Q_DISABLE_COPY(TemplateMode)
+
+ /**
+ * Operator for qSort().
+ */
+ static inline bool lessThanByPriority(const TemplatePattern::Ptr &t1,
+ const TemplatePattern::Ptr &t2);
+ };
+
+ const QXmlName &TemplateMode::name() const
+ {
+ return m_modeName;
+ }
+
+ void TemplateMode::addMode(const TemplateMode::Ptr &mode)
+ {
+ templatePatterns += mode->templatePatterns;
+ }
+
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/expr/qtemplateparameterreference.cpp b/src/xmlpatterns/expr/qtemplateparameterreference.cpp
new file mode 100644
index 0000000..550e39f
--- /dev/null
+++ b/src/xmlpatterns/expr/qtemplateparameterreference.cpp
@@ -0,0 +1,91 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qcommonsequencetypes_p.h"
+
+#include "qtemplateparameterreference_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+TemplateParameterReference::TemplateParameterReference(const VariableDeclaration::Ptr &varDecl) : m_varDecl(varDecl)
+{
+}
+
+bool TemplateParameterReference::evaluateEBV(const DynamicContext::Ptr &context) const
+{
+ return context->templateParameterStore()[m_varDecl->name]->evaluateEBV(context);
+}
+
+Item TemplateParameterReference::evaluateSingleton(const DynamicContext::Ptr &context) const
+{
+ return context->templateParameterStore()[m_varDecl->name]->evaluateSingleton(context);
+}
+
+Item::Iterator::Ptr TemplateParameterReference::evaluateSequence(const DynamicContext::Ptr &context) const
+{
+ Q_ASSERT(!m_varDecl->name.isNull());
+ Q_ASSERT(context->templateParameterStore()[m_varDecl->name]);
+ return context->templateParameterStore()[m_varDecl->name]->evaluateSequence(context);
+}
+
+ExpressionVisitorResult::Ptr TemplateParameterReference::accept(const ExpressionVisitor::Ptr &visitor) const
+{
+ return visitor->visit(this);
+}
+
+Expression::Properties TemplateParameterReference::properties() const
+{
+ return DisableElimination;
+}
+
+SequenceType::Ptr TemplateParameterReference::staticType() const
+{
+ /* We can't use m_varDecl->expression()'s static type here, because
+ * it's the default argument. */
+ if(!m_varDecl->sequenceType)
+ return CommonSequenceTypes::ZeroOrMoreItems;
+ else
+ return m_varDecl->sequenceType;
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/expr/qtemplateparameterreference_p.h b/src/xmlpatterns/expr/qtemplateparameterreference_p.h
new file mode 100644
index 0000000..7eb9562
--- /dev/null
+++ b/src/xmlpatterns/expr/qtemplateparameterreference_p.h
@@ -0,0 +1,105 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_TemplateParameterReference_H
+#define Patternist_TemplateParameterReference_H
+
+#include "qvariabledeclaration_p.h"
+#include "qemptycontainer_p.h"
+
+QT_BEGIN_HEADER
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short A reference to a template parameter declared with @c xsl:param.
+ *
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_expressions
+ * @since 4.5
+ */
+ class TemplateParameterReference : public EmptyContainer
+ {
+ public:
+ TemplateParameterReference(const VariableDeclaration::Ptr &varDecl);
+
+ virtual bool evaluateEBV(const DynamicContext::Ptr &context) const;
+ virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const;
+ virtual Item::Iterator::Ptr evaluateSequence(const DynamicContext::Ptr &context) const;
+
+ virtual SequenceType::Ptr staticType() const;
+ virtual ExpressionVisitorResult::Ptr accept(const ExpressionVisitor::Ptr &visitor) const;
+ virtual Properties properties() const;
+
+ inline const Expression::Ptr &sourceExpression() const;
+ inline const VariableDeclaration::Ptr &variableDeclaration() const;
+
+ private:
+ const VariableDeclaration::Ptr m_varDecl;
+ };
+
+ inline const Expression::Ptr &TemplateParameterReference::sourceExpression() const
+ {
+ return m_varDecl->expression();
+ }
+
+ inline const VariableDeclaration::Ptr &TemplateParameterReference::variableDeclaration() const
+ {
+ return m_varDecl;
+ }
+
+}
+
+QT_END_NAMESPACE
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/expr/qtemplatepattern_p.h b/src/xmlpatterns/expr/qtemplatepattern_p.h
new file mode 100644
index 0000000..1ac1c56
--- /dev/null
+++ b/src/xmlpatterns/expr/qtemplatepattern_p.h
@@ -0,0 +1,161 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_TemplatePattern_H
+#define Patternist_TemplatePattern_H
+
+#include "qtemplate_p.h"
+
+QT_BEGIN_HEADER
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Houses the data necessary for a template pattern.
+ *
+ * A template pattern is the match pattern, but have had each operand to @c
+ * | separated out into a separate TemplatePattern. For instance, the
+ * pattern <tt>a | b | c</tt>, becomes three separate TemplatePattern
+ * instances.
+ *
+ * @see TemplateMode
+ * @see Template
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_expressions
+ * @since 4.5
+ */
+ class TemplatePattern : public QSharedData
+ {
+ public:
+ typedef QExplicitlySharedDataPointer<TemplatePattern> Ptr;
+ typedef QVector<Ptr> Vector;
+ typedef int ID;
+
+ inline TemplatePattern(const Expression::Ptr &matchPattern,
+ const PatternPriority pri,
+ const ID id,
+ const Template::Ptr templ);
+
+ inline PatternPriority priority() const;
+ inline const Expression::Ptr &matchPattern() const;
+ inline void setMatchPattern(const Expression::Ptr &pattern);
+ inline const Template::Ptr &templateTarget() const;
+ inline ID id() const;
+
+ /**
+ * This ID is used to ensure that, as 6.4 Conflict Resolution for
+ * Template Rules reads:
+ *
+ * "If the pattern contains multiple alternatives separated by |, then
+ * the template rule is treated equivalently to a set of template
+ * rules, one for each alternative. However, it is not an error if a
+ * node matches more than one of the alternatives."
+ *
+ * For patterns separated by @c |, we have one Template instance for
+ * each alternative, but they all have the same ID, hence if several
+ * alternatives match, we don't flag it as an error if they have the
+ * same ID.
+ */
+ private:
+ Expression::Ptr m_matchPattern;
+ PatternPriority m_priority;
+ ID m_id;
+ Template::Ptr m_templateTarget;
+ Q_DISABLE_COPY(TemplatePattern)
+ };
+
+ TemplatePattern::TemplatePattern(const Expression::Ptr &matchPattern,
+ const PatternPriority pri,
+ const ID id,
+ const Template::Ptr templ) : m_matchPattern(matchPattern)
+ , m_priority(pri)
+ , m_id(id)
+ , m_templateTarget(templ)
+
+ {
+ Q_ASSERT(m_matchPattern);
+ Q_ASSERT(m_templateTarget);
+ }
+
+ const Expression::Ptr &TemplatePattern::matchPattern() const
+ {
+ return m_matchPattern;
+ }
+
+ void TemplatePattern::setMatchPattern(const Expression::Ptr &pattern)
+ {
+ m_matchPattern = pattern;
+ }
+
+ PatternPriority TemplatePattern::priority() const
+ {
+ return m_priority;
+ }
+
+ TemplatePattern::ID TemplatePattern::id() const
+ {
+ return m_id;
+ }
+
+ const Template::Ptr &TemplatePattern::templateTarget() const
+ {
+ return m_templateTarget;
+ }
+
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
+
diff --git a/src/xmlpatterns/expr/qtextnodeconstructor.cpp b/src/xmlpatterns/expr/qtextnodeconstructor.cpp
new file mode 100644
index 0000000..bb74079
--- /dev/null
+++ b/src/xmlpatterns/expr/qtextnodeconstructor.cpp
@@ -0,0 +1,115 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QUrl>
+
+#include "qcommonsequencetypes_p.h"
+#include "qnodebuilder_p.h"
+
+#include "qtextnodeconstructor_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+TextNodeConstructor::TextNodeConstructor(const Expression::Ptr &op) : SingleContainer(op)
+{
+}
+
+Item TextNodeConstructor::evaluateSingleton(const DynamicContext::Ptr &context) const
+{
+ const Item chars(m_operand->evaluateSingleton(context));
+
+ if(!chars)
+ return Item();
+
+ const NodeBuilder::Ptr nodeBuilder(context->nodeBuilder(QUrl()));
+ const QString &v = chars.stringValue();
+ nodeBuilder->characters(QStringRef(&v));
+
+ const QAbstractXmlNodeModel::Ptr nm(nodeBuilder->builtDocument());
+ context->addNodeModel(nm);
+
+ return nm->root(QXmlNodeModelIndex());
+}
+
+void TextNodeConstructor::evaluateToSequenceReceiver(const DynamicContext::Ptr &context) const
+{
+ const Item item(m_operand->evaluateSingleton(context));
+
+ QAbstractXmlReceiver *const receiver = context->outputReceiver();
+
+ if(item)
+ {
+ const QString &v = item.stringValue();
+ receiver->characters(QStringRef(&v));
+ }
+ else
+ receiver->characters(QStringRef());
+}
+
+SequenceType::Ptr TextNodeConstructor::staticType() const
+{
+ if(m_operand->staticType()->cardinality().allowsEmpty())
+ return CommonSequenceTypes::ZeroOrOneTextNode;
+ else
+ return CommonSequenceTypes::ExactlyOneTextNode;
+}
+
+SequenceType::List TextNodeConstructor::expectedOperandTypes() const
+{
+ SequenceType::List result;
+ result.append(CommonSequenceTypes::ZeroOrOneString);
+ return result;
+}
+
+Expression::Properties TextNodeConstructor::properties() const
+{
+ return DisableElimination | IsNodeConstructor;
+}
+
+ExpressionVisitorResult::Ptr
+TextNodeConstructor::accept(const ExpressionVisitor::Ptr &visitor) const
+{
+ return visitor->visit(this);
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/expr/qtextnodeconstructor_p.h b/src/xmlpatterns/expr/qtextnodeconstructor_p.h
new file mode 100644
index 0000000..ac20cc7
--- /dev/null
+++ b/src/xmlpatterns/expr/qtextnodeconstructor_p.h
@@ -0,0 +1,97 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_TextNodeConstructor_H
+#define Patternist_TextNodeConstructor_H
+
+#include "qsinglecontainer_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Constructs a text node. This covers both computed and directly constructed
+ * text nodes.
+ *
+ * @see <a href="http://www.w3.org/TR/xquery/#id-constructors">XQuery
+ * 1.0: An XML Query Language, 3.7 Constructors</a>
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_expressions
+ */
+ class TextNodeConstructor : public SingleContainer
+ {
+ public:
+ TextNodeConstructor(const Expression::Ptr &operand);
+
+ virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const;
+ virtual void evaluateToSequenceReceiver(const DynamicContext::Ptr &context) const;
+
+ virtual SequenceType::Ptr staticType() const;
+
+ /**
+ * The first operand must be exactly one @c xs:string.
+ */
+ virtual SequenceType::List expectedOperandTypes() const;
+
+ virtual ExpressionVisitorResult::Ptr accept(const ExpressionVisitor::Ptr &visitor) const;
+
+ virtual Properties properties() const;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/expr/qtreatas.cpp b/src/xmlpatterns/expr/qtreatas.cpp
new file mode 100644
index 0000000..8ccfb12
--- /dev/null
+++ b/src/xmlpatterns/expr/qtreatas.cpp
@@ -0,0 +1,92 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qcommonsequencetypes_p.h"
+#include "qtypechecker_p.h"
+
+#include "qtreatas_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+TreatAs::TreatAs(const Expression::Ptr &operand,
+ const SequenceType::Ptr &reqType) : SingleContainer(operand),
+ m_reqType(reqType)
+{
+ Q_ASSERT(reqType);
+}
+
+Expression::Ptr TreatAs::typeCheck(const StaticContext::Ptr &context,
+ const SequenceType::Ptr &reqType)
+{
+ Q_ASSERT(context);
+ Q_ASSERT(reqType);
+
+ /* Apply function conversion with the special error code XPDY0050. After that, we
+ * let the regular typeCheck() function be invoked on the operand before we rewrite
+ * to it. Hence is applyFunctionConversion() called twice, which doesn't break anything,
+ * but indeed is redundant. */
+ const Expression::Ptr treated(TypeChecker::applyFunctionConversion(m_operand,
+ m_reqType,
+ context,
+ ReportContext::XPDY0050));
+ return treated->typeCheck(context, reqType);
+}
+
+ExpressionVisitorResult::Ptr TreatAs::accept(const ExpressionVisitor::Ptr &visitor) const
+{
+ return visitor->visit(this);
+}
+
+SequenceType::Ptr TreatAs::staticType() const
+{
+ return m_reqType;
+}
+
+SequenceType::List TreatAs::expectedOperandTypes() const
+{
+ SequenceType::List result;
+ result.append(CommonSequenceTypes::ZeroOrMoreItems);
+ return result;
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/expr/qtreatas_p.h b/src/xmlpatterns/expr/qtreatas_p.h
new file mode 100644
index 0000000..cf8599c
--- /dev/null
+++ b/src/xmlpatterns/expr/qtreatas_p.h
@@ -0,0 +1,122 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_TreatAs_H
+#define Patternist_TreatAs_H
+
+#include "qsinglecontainer_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Implements XPath 2.0's <tt>treat as</tt> expression.
+ *
+ * TreatAs is always a compile-time class only, and is always deallocated
+ * by re-writing to CardinalityVerifier or ItemVerifier or both, by calling
+ * TypeChecker::applyFunctionConversion().
+ *
+ *
+ * One approach could be to skip instantiating TreatAs and simply let the
+ * return value of TypeChecker::applyFunctionConversion() be inserted into
+ * the AST, but that wouldn't handle type checking the context item
+ * properly, which depends on that the StaticContext have been set by the
+ * parent Expression.
+ *
+ * @see <a href="http://www.w3.org/TR/xpath20/#id-treat">XML Path Language
+ * (XPath) 2.0, 3.10.5 Treat</a>
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_expressions
+ */
+ class TreatAs : public SingleContainer
+ {
+ public:
+ /**
+ * Creats a TreatAs where it is checked that the expression @p operand conforms
+ * to the type @p reqType.
+ */
+ TreatAs(const Expression::Ptr &operand,
+ const SequenceType::Ptr &reqType);
+
+ /**
+ * This function rewrites always. First the type that this TreatAs expression tests for
+ * is verified. Then, the type the <tt>treat as</tt> expression itself must match, @p reqType,
+ * is verified.
+ */
+ virtual Expression::Ptr typeCheck(const StaticContext::Ptr &context,
+ const SequenceType::Ptr &reqType);
+
+ /**
+ * @returns always the SequenceType passed in the constructor to this class. That is, the
+ * SequenceType that the operand must conform to.
+ */
+ virtual SequenceType::Ptr staticType() const;
+
+ /**
+ * @returns a list containing one CommonSequenceTypes::ZeroOrMoreItems
+ */
+ virtual SequenceType::List expectedOperandTypes() const;
+
+ virtual ExpressionVisitorResult::Ptr accept(const ExpressionVisitor::Ptr &visitor) const;
+
+ private:
+ const SequenceType::Ptr m_reqType;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/expr/qtriplecontainer.cpp b/src/xmlpatterns/expr/qtriplecontainer.cpp
new file mode 100644
index 0000000..8ffff85
--- /dev/null
+++ b/src/xmlpatterns/expr/qtriplecontainer.cpp
@@ -0,0 +1,87 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QList>
+
+#include "qtriplecontainer_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+TripleContainer::TripleContainer(const Expression::Ptr &operand1,
+ const Expression::Ptr &operand2,
+ const Expression::Ptr &operand3) : m_operand1(operand1),
+ m_operand2(operand2),
+ m_operand3(operand3)
+{
+ Q_ASSERT(operand1);
+ Q_ASSERT(operand2);
+ Q_ASSERT(operand3);
+}
+
+Expression::List TripleContainer::operands() const
+{
+ Expression::List result;
+ result.append(m_operand1);
+ result.append(m_operand2);
+ result.append(m_operand3);
+ return result;
+}
+
+void TripleContainer::setOperands(const Expression::List &ops)
+{
+ Q_ASSERT(ops.count() == 3);
+ m_operand1 = ops.first();
+ m_operand2 = ops.at(1);
+ m_operand3 = ops.at(2);
+}
+
+bool TripleContainer::compressOperands(const StaticContext::Ptr &context)
+{
+ rewrite(m_operand1, m_operand1->compress(context), context);
+ rewrite(m_operand2, m_operand2->compress(context), context);
+ rewrite(m_operand3, m_operand3->compress(context), context);
+
+ return m_operand1->isEvaluated() && m_operand2->isEvaluated() && m_operand3->isEvaluated();
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/expr/qtriplecontainer_p.h b/src/xmlpatterns/expr/qtriplecontainer_p.h
new file mode 100644
index 0000000..e9cd249
--- /dev/null
+++ b/src/xmlpatterns/expr/qtriplecontainer_p.h
@@ -0,0 +1,92 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_TripleContainer_H
+#define Patternist_TripleContainer_H
+
+#include "qexpression_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Base class for expressions that has exactly three operands.
+ *
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_expressions
+ */
+ class TripleContainer : public Expression
+ {
+ public:
+ virtual Expression::List operands() const;
+ virtual void setOperands(const Expression::List &operands);
+
+ virtual bool compressOperands(const StaticContext::Ptr &);
+
+ protected:
+ TripleContainer(const Expression::Ptr &operand1,
+ const Expression::Ptr &operand2,
+ const Expression::Ptr &operand3);
+
+ Expression::Ptr m_operand1;
+ Expression::Ptr m_operand2;
+ Expression::Ptr m_operand3;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/expr/qtruthpredicate.cpp b/src/xmlpatterns/expr/qtruthpredicate.cpp
new file mode 100644
index 0000000..0c967d2
--- /dev/null
+++ b/src/xmlpatterns/expr/qtruthpredicate.cpp
@@ -0,0 +1,71 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qcommonsequencetypes_p.h"
+#include "qcommonvalues_p.h"
+#include "qgenericsequencetype_p.h"
+
+#include "qtruthpredicate_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+TruthPredicate::TruthPredicate(const Expression::Ptr &sourceExpression,
+ const Expression::Ptr &predicate) : GenericPredicate(sourceExpression,
+ predicate)
+{
+}
+
+SequenceType::List TruthPredicate::expectedOperandTypes() const
+{
+ SequenceType::List result;
+ result.append(CommonSequenceTypes::ZeroOrMoreItems);
+ result.append(CommonSequenceTypes::EBV);
+ return result;
+}
+
+ExpressionVisitorResult::Ptr TruthPredicate::accept(const ExpressionVisitor::Ptr &visitor) const
+{
+ return visitor->visit(this);
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/expr/qtruthpredicate_p.h b/src/xmlpatterns/expr/qtruthpredicate_p.h
new file mode 100644
index 0000000..1a395bd
--- /dev/null
+++ b/src/xmlpatterns/expr/qtruthpredicate_p.h
@@ -0,0 +1,112 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_TruthPredicate_H
+#define Patternist_TruthPredicate_H
+
+#include "qgenericpredicate_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short A predicate which is optimized for filter expressions that
+ * are of type @c xs:boolean.
+ *
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_expressions
+ */
+ class TruthPredicate : public GenericPredicate
+ {
+ public:
+ /**
+ * Creates a TruthPredicate which filters the items from the @p sourceExpression
+ * through @p predicate.
+ *
+ * This constructor is protected. The proper way to create predicates is via the static
+ * create() function.
+ */
+ TruthPredicate(const Expression::Ptr &sourceExpression,
+ const Expression::Ptr &predicate);
+
+ inline Item mapToItem(const Item &item, const DynamicContext::Ptr &context) const
+ {
+ Q_ASSERT_X(false, Q_FUNC_INFO, "This is practically dead code because it never gets called in GenericPredicate, "
+ "which binds to its own mapToItem for completely legitime reasons.");
+ if(m_operand2->evaluateEBV(context))
+ return item;
+ else
+ return Item();
+ }
+
+ inline Item::Iterator::Ptr map(const Item &item,
+ const DynamicContext::Ptr &context) const
+ {
+ Q_ASSERT_X(false, Q_FUNC_INFO, "I don't expect this function to be called, for the same reasons as above.");
+ if(m_operand2->evaluateEBV(context))
+ return makeSingletonIterator(item);
+ else
+ return CommonValues::emptyIterator;
+ }
+
+ virtual SequenceType::List expectedOperandTypes() const;
+ virtual ExpressionVisitorResult::Ptr accept(const ExpressionVisitor::Ptr &visitor) const;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/expr/qunaryexpression.cpp b/src/xmlpatterns/expr/qunaryexpression.cpp
new file mode 100644
index 0000000..88419ce
--- /dev/null
+++ b/src/xmlpatterns/expr/qunaryexpression.cpp
@@ -0,0 +1,79 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qarithmeticexpression_p.h"
+#include "qcommonvalues_p.h"
+#include "qliteral_p.h"
+#include "qschemanumeric_p.h"
+
+#include "qunaryexpression_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+UnaryExpression::UnaryExpression(const AtomicMathematician::Operator op,
+ const Expression::Ptr &operand,
+ const StaticContext::Ptr &context) : ArithmeticExpression(wrapLiteral(CommonValues::IntegerZero, context, operand.data()),
+ op,
+ operand)
+{
+ Q_ASSERT(op == AtomicMathematician::Substract ||
+ op == AtomicMathematician::Add);
+ Q_ASSERT(context);
+}
+
+Item UnaryExpression::evaluateSingleton(const DynamicContext::Ptr &context) const
+{
+ if(operatorID() == AtomicMathematician::Substract)
+ {
+ const Item item(m_operand2->evaluateSingleton(context));
+
+ if(item)
+ return item.as<Numeric>()->toNegated();
+ else
+ return Item();
+ }
+ else
+ return m_operand2->evaluateSingleton(context);
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/expr/qunaryexpression_p.h b/src/xmlpatterns/expr/qunaryexpression_p.h
new file mode 100644
index 0000000..abc17cb
--- /dev/null
+++ b/src/xmlpatterns/expr/qunaryexpression_p.h
@@ -0,0 +1,114 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_UnaryExpression_H
+#define Patternist_UnaryExpression_H
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+#include "qarithmeticexpression_p.h"
+
+namespace QPatternist
+{
+ /**
+ * @short Implements XPath 2.0 unary expression, <tt>(-|+)ValueExpr</tt>.
+ *
+ * UnaryExpression is implemented by rewriting the expression <tt>operator [expr]</tt>
+ * to the ArithmeticExpression <tt>0 operator [expr]</tt>. For example, the expression
+ * <tt>+3</tt> becomes <tt>0 + 3</tt>, and <tt>-nodetest</tt> becomes <tt>0 - nodetest</tt>.
+ *
+ * On top of that expression ArithmeticExpression does the usual type
+ * checking conversion. The only thing this class do, is to overide
+ * evaluateSingleton() and calls Numeric::toNegated(). The reason this
+ * UnaryExpression is needed at all and that <tt>0 - [expr]</tt> is
+ * insufficent is that <tt>0 - xs:double(0)</tt> needs to return -0,
+ * instead of 0. I know no other difference.
+ *
+ * In most cases the constant propagation optimization rewrites UnaryExpression into
+ * a value, an instance of a sub-class of the Numeric class, wrapped with
+ * Literal.
+ *
+ * Beyond the mathematical implication the unary expression have, it also
+ * have the significant effect that it may invoke type promotion or that an expression
+ * may contain a type error. For example, the expression "+'a string'" contains a type error, since
+ * no unary operator is defined for @c xs:string. This is the reason why the '+' unary
+ * operator isn't ignored.
+ *
+ * @see <a href="http://www.w3.org/TR/xpath20/#id-arithmetic">XML Path Language
+ * (XPath) 2.0, 3.4 Arithmetic Expressions</a>
+ * @see <a href="http://www.w3.org/TR/xpath-functions/#func-numeric-unary-plus">XQuery 1.0 and XPath
+ * 2.0 Functions and Operators, 6.2.7 op:numeric-unary-plus</a>
+ * @see <a href="http://www.w3.org/TR/xpath-functions/#func-numeric-unary-minus">XQuery 1.0 and XPath
+ * 2.0 Functions and Operators, 6.2.8 op:numeric-unary-minus</a>
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_expressions
+ */
+ class UnaryExpression : public ArithmeticExpression
+ {
+ public:
+ UnaryExpression(const AtomicMathematician::Operator op,
+ const Expression::Ptr &operand,
+ const StaticContext::Ptr &context);
+
+ virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const;
+
+ private:
+ Q_DISABLE_COPY(UnaryExpression)
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/expr/qunlimitedcontainer.cpp b/src/xmlpatterns/expr/qunlimitedcontainer.cpp
new file mode 100644
index 0000000..d1f4638
--- /dev/null
+++ b/src/xmlpatterns/expr/qunlimitedcontainer.cpp
@@ -0,0 +1,79 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qunlimitedcontainer_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+UnlimitedContainer::UnlimitedContainer(const Expression::List &ops) : m_operands(ops)
+{
+}
+
+void UnlimitedContainer::setOperands(const Expression::List &list)
+{
+ m_operands = list;
+}
+
+Expression::List UnlimitedContainer::operands() const
+{
+ return m_operands;
+}
+
+bool UnlimitedContainer::compressOperands(const StaticContext::Ptr &context)
+{
+ const Expression::List::iterator end(m_operands.end());
+ Expression::List::iterator it(m_operands.begin());
+ int evaled = 0;
+
+ for(; it != end; ++it)
+ {
+ Q_ASSERT((*it));
+ rewrite((*it), (*it)->compress(context), context);
+ if((*it)->isEvaluated())
+ ++evaled;
+ }
+
+ return evaled == m_operands.count();
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/expr/qunlimitedcontainer_p.h b/src/xmlpatterns/expr/qunlimitedcontainer_p.h
new file mode 100644
index 0000000..1c032f0
--- /dev/null
+++ b/src/xmlpatterns/expr/qunlimitedcontainer_p.h
@@ -0,0 +1,149 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_UnlimitedContainer_H
+#define Patternist_UnlimitedContainer_H
+
+#include <QList>
+#include "qexpression_p.h"
+#include "qgenericsequencetype_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Base class for expressions that has any amount of operands.
+ *
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_expressions
+ */
+ class UnlimitedContainer : public Expression
+ {
+ public:
+ /**
+ * Creates an UnlimitedContainer containing the operands @p operands. @p operands
+ * may be empty.
+ */
+ UnlimitedContainer(const Expression::List &operands = Expression::List());
+
+ virtual void setOperands(const Expression::List &list);
+
+ virtual Expression::List operands() const;
+
+ /**
+ * @note This function cannot be called before setOperands is called.
+ */
+ virtual bool compressOperands(const StaticContext::Ptr &);
+
+ /**
+ * Tells how operandsUnionType() should compute the cardinality of
+ * its children.
+ *
+ * This type is public because of a bug in the HP-UX aCC compiler.
+ */
+ enum CardinalityComputation
+ {
+ ProductOfCardinality,
+ UnionOfCardinality
+ };
+
+ protected:
+ /**
+ * Computes and returns the union type of all the Expression instances
+ * in this Expression's operands.
+ *
+ * This implementation is placed inside because CardinalityComputation
+ * can't be referenced from the outside(in conforming compilers).
+ */
+ template<CardinalityComputation suppliedCard>
+ inline
+ SequenceType::Ptr operandsUnionType() const
+ {
+ Q_ASSERT(suppliedCard == ProductOfCardinality || suppliedCard == UnionOfCardinality);
+ const Expression::List::const_iterator end(m_operands.constEnd());
+ Expression::List::const_iterator it(m_operands.constBegin());
+
+ /* Load the first one, and jump over it in the loop. */
+ SequenceType::Ptr t(m_operands.first()->staticType());
+ ItemType::Ptr type(t->itemType());
+ Cardinality card(t->cardinality());
+ ++it;
+
+ for(; it != end; ++it)
+ {
+ t = (*it)->staticType();
+ type |= t->itemType();
+
+ /* Since this function is a template function, it doesn't
+ * hurt performance that this test is inside the loop. */
+ if(suppliedCard == ProductOfCardinality)
+ card += t->cardinality();
+ else
+ card |= t->cardinality();
+ }
+
+ return makeGenericSequenceType(type, card);
+ }
+
+ Expression::List m_operands;
+ };
+
+
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/expr/qunresolvedvariablereference.cpp b/src/xmlpatterns/expr/qunresolvedvariablereference.cpp
new file mode 100644
index 0000000..68c974e
--- /dev/null
+++ b/src/xmlpatterns/expr/qunresolvedvariablereference.cpp
@@ -0,0 +1,91 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qcommonsequencetypes_p.h"
+
+#include "qunresolvedvariablereference_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+UnresolvedVariableReference::UnresolvedVariableReference(const QXmlName &name) : m_name(name)
+{
+ Q_ASSERT(!m_name.isNull());
+}
+
+Expression::Ptr UnresolvedVariableReference::typeCheck(const StaticContext::Ptr &context,
+ const SequenceType::Ptr &reqType)
+{
+ /* We may be called before m_replacement is called, when we're part of a
+ * function body whose type checking is performed for. See
+ * UserFunctionCallsite::typeCheck(). */
+ if(m_replacement)
+ return m_replacement->typeCheck(context, reqType);
+ else
+ return EmptyContainer::typeCheck(context, reqType);
+}
+
+SequenceType::Ptr UnresolvedVariableReference::staticType() const
+{
+ /* We may be called by xmlpatternsview before the typeCheck() stage. */
+ if(m_replacement)
+ return m_replacement->staticType();
+ else
+ return CommonSequenceTypes::ZeroOrMoreItems;
+}
+
+SequenceType::List UnresolvedVariableReference::expectedOperandTypes() const
+{
+ return SequenceType::List();
+}
+
+ExpressionVisitorResult::Ptr UnresolvedVariableReference::accept(const ExpressionVisitor::Ptr &visitor) const
+{
+ return visitor->visit(this);
+}
+
+Expression::ID UnresolvedVariableReference::id() const
+{
+ return IDUnresolvedVariableReference;
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/expr/qunresolvedvariablereference_p.h b/src/xmlpatterns/expr/qunresolvedvariablereference_p.h
new file mode 100644
index 0000000..d32fb0a
--- /dev/null
+++ b/src/xmlpatterns/expr/qunresolvedvariablereference_p.h
@@ -0,0 +1,111 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_UnresolvedVariableReference_H
+#define Patternist_UnresolvedVariableReference_H
+
+#include "qemptycontainer_p.h"
+
+QT_BEGIN_HEADER
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+
+ /**
+ * @short Compile time only AST-node which is a marker for variable
+ * references whose declaration has not yet appeared in the source code.
+ *
+ * This can not appear in XQuery, but can in XSL-T.
+ *
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_expressions
+ * @since 4.5
+ */
+ class Q_AUTOTEST_EXPORT UnresolvedVariableReference : public EmptyContainer
+ {
+ public:
+ UnresolvedVariableReference(const QXmlName &name);
+
+ virtual Expression::Ptr typeCheck(const StaticContext::Ptr &context,
+ const SequenceType::Ptr &reqType);
+ virtual SequenceType::List expectedOperandTypes() const;
+ virtual SequenceType::Ptr staticType() const;
+ virtual ExpressionVisitorResult::Ptr accept(const ExpressionVisitor::Ptr &visitor) const;
+ virtual ID id() const;
+
+ inline void bindTo(const Expression::Ptr &body);
+
+ inline Expression::Ptr replacement() const;
+
+ private:
+ const QXmlName m_name;
+ Expression::Ptr m_replacement;
+ };
+
+ void UnresolvedVariableReference::bindTo(const Expression::Ptr &body)
+ {
+ Q_ASSERT(body);
+ m_replacement = body;
+ }
+
+ Expression::Ptr UnresolvedVariableReference::replacement() const
+ {
+ Q_ASSERT(m_replacement);
+ return m_replacement;
+ }
+
+}
+
+QT_END_NAMESPACE
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/expr/quserfunction.cpp b/src/xmlpatterns/expr/quserfunction.cpp
new file mode 100644
index 0000000..f440b61
--- /dev/null
+++ b/src/xmlpatterns/expr/quserfunction.cpp
@@ -0,0 +1,62 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#include "quserfunction_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+UserFunction::UserFunction(const FunctionSignature::Ptr &sign,
+ const Expression::Ptr &b,
+ const VariableSlotID slotOffset,
+ const VariableDeclaration::List &varDecls) : m_signature(sign),
+ m_body(b),
+ m_slotOffset(slotOffset),
+ m_argumentDeclarations(varDecls)
+{
+ Q_ASSERT(m_signature);
+ Q_ASSERT(m_body);
+ Q_ASSERT(m_slotOffset > -2);
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/expr/quserfunction_p.h b/src/xmlpatterns/expr/quserfunction_p.h
new file mode 100644
index 0000000..938a1d9
--- /dev/null
+++ b/src/xmlpatterns/expr/quserfunction_p.h
@@ -0,0 +1,135 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_UserFunction_H
+#define Patternist_UserFunction_H
+
+template<typename T> class QList;
+
+#include <QSharedData>
+
+#include "qexpression_p.h"
+#include "qfunctionsignature_p.h"
+#include "qvariabledeclaration_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short A function created with XQuery's <tt>declare function</tt> declaration.
+ *
+ * @see UserFunctionCall
+ * @see ArgumentReference
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_expressions
+ */
+ class UserFunction : public QSharedData
+ {
+ public:
+ typedef QExplicitlySharedDataPointer<UserFunction> Ptr;
+ typedef QList<UserFunction::Ptr> List;
+
+ /**
+ * If @p slotOffset is -1, it means this function has no arguments.
+ */
+ UserFunction(const FunctionSignature::Ptr &signature,
+ const Expression::Ptr &body,
+ const VariableSlotID slotOffset,
+ const VariableDeclaration::List &varDecls);
+
+ inline const Expression::Ptr &body() const;
+ inline void setBody(const Expression::Ptr &newBody);
+ inline FunctionSignature::Ptr signature() const;
+ inline VariableSlotID expressionSlotOffset() const;
+ inline VariableDeclaration::List argumentDeclarations() const;
+
+ private:
+ const FunctionSignature::Ptr m_signature;
+ Expression::Ptr m_body;
+ const VariableSlotID m_slotOffset;
+ const VariableDeclaration::List m_argumentDeclarations;
+ };
+
+ inline const Expression::Ptr &UserFunction::body() const
+ {
+ return m_body;
+ }
+
+ inline FunctionSignature::Ptr UserFunction::signature() const
+ {
+ return m_signature;
+ }
+
+ inline VariableSlotID UserFunction::expressionSlotOffset() const
+ {
+ return m_slotOffset;
+ }
+
+ inline VariableDeclaration::List UserFunction::argumentDeclarations() const
+ {
+ return m_argumentDeclarations;
+ }
+
+ void UserFunction::setBody(const Expression::Ptr &newBody)
+ {
+ m_body = newBody;
+ }
+
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/expr/quserfunctioncallsite.cpp b/src/xmlpatterns/expr/quserfunctioncallsite.cpp
new file mode 100644
index 0000000..4e81484
--- /dev/null
+++ b/src/xmlpatterns/expr/quserfunctioncallsite.cpp
@@ -0,0 +1,245 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qcommonsequencetypes_p.h"
+#include "qdynamiccontextstore_p.h"
+#include "qevaluationcache_p.h"
+
+#include "quserfunctioncallsite_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+UserFunctionCallsite::UserFunctionCallsite(const QXmlName nameP,
+ const FunctionSignature::Arity ar) : CallSite(nameP)
+ , m_arity(ar)
+ , m_expressionSlotOffset(-2)
+
+{
+}
+
+Item::Iterator::Ptr UserFunctionCallsite::evaluateSequence(const DynamicContext::Ptr &context) const
+{
+ return m_body->evaluateSequence(bindVariables(context));
+}
+
+Item UserFunctionCallsite::evaluateSingleton(const DynamicContext::Ptr &context) const
+{
+ return m_body->evaluateSingleton(bindVariables(context));
+}
+
+bool UserFunctionCallsite::evaluateEBV(const DynamicContext::Ptr &context) const
+{
+ return m_body->evaluateEBV(bindVariables(context));
+}
+
+void UserFunctionCallsite::evaluateToSequenceReceiver(const DynamicContext::Ptr &context) const
+{
+ m_body->evaluateToSequenceReceiver(bindVariables(context));
+}
+
+DynamicContext::Ptr UserFunctionCallsite::bindVariables(const DynamicContext::Ptr &context) const
+{
+ const DynamicContext::Ptr stackContext(context->createStack());
+ Q_ASSERT(stackContext);
+
+ const Expression::List::const_iterator end(m_operands.constEnd());
+ Expression::List::const_iterator it(m_operands.constBegin());
+
+ VariableSlotID slot = m_expressionSlotOffset;
+
+ for(; it != end; ++it)
+ {
+ stackContext->setExpressionVariable(slot,
+ Expression::Ptr(new DynamicContextStore(*it, context)));
+ ++slot;
+ }
+
+ return stackContext;
+}
+
+SequenceType::List UserFunctionCallsite::expectedOperandTypes() const
+{
+ SequenceType::List result;
+
+ if(m_functionDeclaration)
+ {
+ const FunctionArgument::List args(m_functionDeclaration->signature()->arguments());
+ const FunctionArgument::List::const_iterator end(args.constEnd());
+ FunctionArgument::List::const_iterator it(args.constBegin());
+
+ for(; it != end; ++it)
+ result.append((*it)->type());
+ }
+ else
+ result.append(CommonSequenceTypes::ZeroOrMoreItems);
+
+ return result;
+}
+
+Expression::Ptr UserFunctionCallsite::typeCheck(const StaticContext::Ptr &context,
+ const SequenceType::Ptr &reqType)
+{
+ /* The parser calls TypeChecker::applyFunctionConversion() on user function
+ * bodies, possibly indirectly, before all function call sites have been
+ * resolved. Hence it's possible that we're called before before the usual
+ * typeCheck() pass, and hence before we have been resolved/checked and
+ * subsequently m_functionDeclaration set. Therefore, encounter for that below.
+ *
+ * UnresolvedVariableReference::typeCheck() has the same dilemma.
+ */
+
+ /* Ensure that the return value of the function is properly
+ * converted/does match from where it is called(which is here). */
+ if(isRecursive() || !m_functionDeclaration)
+ return CallSite::typeCheck(context, reqType);
+ else
+ {
+ /* Update, such that we use a recent version of the body that has typeCheck()
+ * and compress() rewrites included. */
+ m_body = m_functionDeclaration->body();
+
+ /* Note, we can't assign to m_functionDeclaration->body() because UserFunction can apply
+ * to several different callsites. Hence we need our own version. */
+ m_body = m_body->typeCheck(context, reqType);
+
+ /* We just act as a pipe for m_body, so we don't have to typecheck ourselves. However,
+ * the arguments must match the function declaration. */
+ typeCheckOperands(context);
+ return Expression::Ptr(this);
+ }
+}
+
+Expression::Ptr UserFunctionCallsite::compress(const StaticContext::Ptr &context)
+{
+ if(!isRecursive())
+ rewrite(m_body, m_body->compress(context), context);
+
+ return CallSite::compress(context);
+}
+
+Expression::Properties UserFunctionCallsite::properties() const
+{
+ return DisableElimination;
+}
+
+SequenceType::Ptr UserFunctionCallsite::staticType() const
+{
+ /* Our return type, is the static type of the function body. We could have also used
+ * m_functionDeclaration->signature()->returnType(), but it doesn't get updated
+ * when function conversion is applied.
+ * We can't use m_body's type if we're recursive, because m_body computes its type
+ * from its children, and we're at least one of the children. Hence, we would
+ * recurse infinitely if we did.
+ *
+ * m_body can be null here if we're called before setSource().
+ */
+ if(isRecursive() || !m_body)
+ return CommonSequenceTypes::ZeroOrMoreItems; // TODO use the declaration, it can have a type explicitly.
+ else
+ return m_body->staticType();
+}
+
+ExpressionVisitorResult::Ptr UserFunctionCallsite::accept(const ExpressionVisitor::Ptr &visitor) const
+{
+ return visitor->visit(this);
+}
+
+Expression::ID UserFunctionCallsite::id() const
+{
+ return IDUserFunctionCallsite;
+}
+
+bool UserFunctionCallsite::isSignatureValid(const FunctionSignature::Ptr &sign) const
+{
+ Q_ASSERT(sign);
+
+ return sign->name() == name()
+ &&
+ sign->isArityValid(m_arity);
+}
+
+bool UserFunctionCallsite::configureRecursion(const CallTargetDescription::Ptr &sign)
+{
+ Q_ASSERT(sign);
+
+ setIsRecursive(isSignatureValid(sign));
+ return isRecursive();
+}
+
+void UserFunctionCallsite::setSource(const UserFunction::Ptr &userFunction,
+ const VariableSlotID cacheSlotOffset)
+{
+ m_functionDeclaration = userFunction;
+ m_body = userFunction->body();
+ m_expressionSlotOffset = userFunction->expressionSlotOffset();
+
+ const int len = m_operands.size();
+
+ const VariableDeclaration::List varDecls(userFunction->argumentDeclarations());
+
+ for(int i = 0; i < len; ++i)
+ {
+ /* We don't want evaluation caches for range variables, it's not necessary since
+ * the item is already cached in DynamicContext::rangeVariable(). */
+ if(m_operands.at(i)->is(IDRangeVariableReference))
+ continue;
+
+ /* Note that we pass in cacheSlotOffset + i here instead of varDecls.at(i)->slot since
+ * we want independent caches for each callsite. */
+ m_operands[i] = Expression::Ptr(new EvaluationCache<false>(m_operands.at(i),
+ varDecls.at(i),
+ cacheSlotOffset + i));
+ }
+}
+
+FunctionSignature::Arity UserFunctionCallsite::arity() const
+{
+ return m_arity;
+}
+
+CallTargetDescription::Ptr UserFunctionCallsite::callTargetDescription() const
+{
+ return m_functionDeclaration->signature();
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/expr/quserfunctioncallsite_p.h b/src/xmlpatterns/expr/quserfunctioncallsite_p.h
new file mode 100644
index 0000000..db6a661
--- /dev/null
+++ b/src/xmlpatterns/expr/quserfunctioncallsite_p.h
@@ -0,0 +1,182 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_UserFunctionCallsite_H
+#define Patternist_UserFunctionCallsite_H
+
+#include "qcallsite_p.h"
+#include "qfunctionsignature_p.h"
+#include "qunlimitedcontainer_p.h"
+#include "quserfunction_p.h"
+#include "qvariabledeclaration_p.h"
+
+QT_BEGIN_HEADER
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Performs a call to a UserFunction.
+ *
+ * UserFunctionCallsite is the call site to a function that has been
+ * declared in the query using <tt>declare function</tt>. That is, it is
+ * never used for builtin functions such as <tt>fn:count()</tt>.
+ *
+ * @see UserFunction
+ * @see ArgumentReference
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_expressions
+ */
+ class UserFunctionCallsite : public CallSite
+ {
+ public:
+ typedef QExplicitlySharedDataPointer<UserFunctionCallsite> Ptr;
+ typedef QList<UserFunctionCallsite::Ptr> List;
+
+ UserFunctionCallsite(const QXmlName name,
+ const FunctionSignature::Arity arity);
+
+ virtual bool evaluateEBV(const DynamicContext::Ptr &context) const;
+ virtual Item::Iterator::Ptr evaluateSequence(const DynamicContext::Ptr &context) const;
+ virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const;
+ virtual void evaluateToSequenceReceiver(const DynamicContext::Ptr &context) const;
+
+ virtual Expression::Ptr typeCheck(const StaticContext::Ptr &context,
+ const SequenceType::Ptr &reqType);
+
+ /**
+ * We call compress on our body.
+ */
+ virtual Expression::Ptr compress(const StaticContext::Ptr &context);
+
+ virtual Expression::Properties properties() const;
+
+ /**
+ * @short Returns the types declared in the function declaration.
+ *
+ * @see CallTemplate::expectedOperandTypes()
+ */
+ virtual SequenceType::List expectedOperandTypes() const;
+
+ virtual SequenceType::Ptr staticType() const;
+ virtual ExpressionVisitorResult::Ptr accept(const ExpressionVisitor::Ptr &visitor) const;
+
+ /**
+ * @returns always IDUserFunctionCallsite.
+ */
+ virtual ID id() const;
+
+ /**
+ * If @p slotOffset is -1, it means this function has no arguments.
+ */
+ void setSource(const UserFunction::Ptr &userFunction,
+ const VariableSlotID cacheSlotOffset);
+
+ /**
+ * @returns @c true, if a function definition with signature @p sign
+ * would be valid to call from this callsite, otherwise @c false.
+ */
+ bool isSignatureValid(const FunctionSignature::Ptr &sign) const;
+
+ FunctionSignature::Arity arity() const;
+
+ inline Expression::Ptr body() const
+ {
+ return m_body;
+ }
+
+ virtual bool configureRecursion(const CallTargetDescription::Ptr &sign);
+ virtual CallTargetDescription::Ptr callTargetDescription() const;
+
+ private:
+ /**
+ * Creates a new context sets the arguments, and returns it.
+ */
+ DynamicContext::Ptr bindVariables(const DynamicContext::Ptr &context) const;
+
+ const FunctionSignature::Arity m_arity;
+ /**
+ * The reason this variable, as well as others, aren't const, is that
+ * the binding to the actual function, is resolved after this
+ * UserFunctionCallsite has been created.
+ */
+ VariableSlotID m_expressionSlotOffset;
+
+ /**
+ * @note This may be different from m_functionDeclaration->body(). It
+ * may differ on a per-callsite basis.
+ */
+ Expression::Ptr m_body;
+ UserFunction::Ptr m_functionDeclaration;
+ };
+
+ /**
+ * @short Formats UserFunctionCallsite.
+ *
+ * @relates UserFunctionCallsite
+ */
+ static inline QString formatFunction(const UserFunctionCallsite::Ptr &func)
+ {
+ Q_UNUSED(func);
+ // TODO TODO TODO
+ // TODO Make UserFunctionCallsite always use a FunctionSignature
+ return QLatin1String("<span class='XQuery-function'>") +
+ QString() +
+ //escape(func->name()->toString()) +
+ QLatin1String("</span>");
+ }
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/expr/qvalidate.cpp b/src/xmlpatterns/expr/qvalidate.cpp
new file mode 100644
index 0000000..8071b32
--- /dev/null
+++ b/src/xmlpatterns/expr/qvalidate.cpp
@@ -0,0 +1,77 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qbuiltintypes_p.h"
+#include "qgenericsequencetype_p.h"
+#include "qmultiitemtype_p.h"
+#include "qtypechecker_p.h"
+
+#include "qvalidate_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+Expression::Ptr Validate::create(const Expression::Ptr &operandNode,
+ const Mode validationMode,
+ const StaticContext::Ptr &context)
+{
+ Q_ASSERT(operandNode);
+ Q_ASSERT(validationMode == Lax || validationMode == Strict);
+ Q_ASSERT(context);
+ Q_UNUSED(validationMode);
+ Q_UNUSED(context);
+
+ ItemType::List tList;
+ tList.append(BuiltinTypes::element);
+ tList.append(BuiltinTypes::document);
+
+ const SequenceType::Ptr elementOrDocument(makeGenericSequenceType(ItemType::Ptr(new MultiItemType(tList)),
+ Cardinality::exactlyOne()));
+
+
+ return TypeChecker::applyFunctionConversion(operandNode,
+ elementOrDocument,
+ context,
+ ReportContext::XQTY0030);
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/expr/qvalidate_p.h b/src/xmlpatterns/expr/qvalidate_p.h
new file mode 100644
index 0000000..10910cd
--- /dev/null
+++ b/src/xmlpatterns/expr/qvalidate_p.h
@@ -0,0 +1,106 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_Validate_H
+#define Patternist_Validate_H
+
+#include "qexpression_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Handles XQuery 1.0's <tt>validate</tt> expression.
+ *
+ * This class is currently not used. The Schema Validation Feature is not supported.
+ *
+ * @see <a href="http://www.w3.org/TR/xquery/#id-validate">XQuery 1.0: An XML
+ * Query Language, 3.13 Validate Expressions</a>
+ * @see <a href="http://www.w3.org/TR/xquery/#id-schema-validation-feature">XQuery 1.0: An
+ * XML Query Language, 5.2.2 Schema Validation Feature</a>
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_expressions
+ */
+ class Validate
+ {
+ public:
+
+ /**
+ * Represents the validation mode.
+ */
+ enum Mode
+ {
+ Lax = 1,
+ Strict
+ };
+
+ /**
+ * Creates the necessary Expression instances
+ * that validates the operand node @p operandNode in mode @p validationMode,
+ * and returns it.
+ */
+ static Expression::Ptr create(const Expression::Ptr &operandNode,
+ const Mode validationMode,
+ const StaticContext::Ptr &context);
+ private:
+ Validate();
+ Q_DISABLE_COPY(Validate)
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/expr/qvaluecomparison.cpp b/src/xmlpatterns/expr/qvaluecomparison.cpp
new file mode 100644
index 0000000..fd0e51b
--- /dev/null
+++ b/src/xmlpatterns/expr/qvaluecomparison.cpp
@@ -0,0 +1,163 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qitem_p.h"
+#include "qboolean_p.h"
+#include "qbuiltintypes_p.h"
+#include "qcommonsequencetypes_p.h"
+#include "qemptysequence_p.h"
+#include "qoptimizationpasses_p.h"
+
+#include "qvaluecomparison_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+ValueComparison::ValueComparison(const Expression::Ptr &op1,
+ const AtomicComparator::Operator op,
+ const Expression::Ptr &op2) : PairContainer(op1, op2),
+ m_operator(op)
+{
+}
+
+Item ValueComparison::evaluateSingleton(const DynamicContext::Ptr &context) const
+{
+ const Item it1(m_operand1->evaluateSingleton(context));
+ if(!it1)
+ return Item();
+
+ const Item it2(m_operand2->evaluateSingleton(context));
+ if(!it2)
+ return Item();
+
+ return Boolean::fromValue(flexibleCompare(it1, it2, context));
+}
+
+Expression::Ptr ValueComparison::typeCheck(const StaticContext::Ptr &context,
+ const SequenceType::Ptr &reqType)
+{
+ const Expression::Ptr me(PairContainer::typeCheck(context, reqType));
+ const ItemType::Ptr t1(m_operand1->staticType()->itemType());
+ const ItemType::Ptr t2(m_operand2->staticType()->itemType());
+ Q_ASSERT(t1);
+ Q_ASSERT(t2);
+
+ if(*CommonSequenceTypes::Empty == *t1 ||
+ *CommonSequenceTypes::Empty == *t2)
+ {
+ return EmptySequence::create(this, context);
+ }
+ else
+ {
+ prepareComparison(fetchComparator(t1, t2, context));
+
+ return me;
+ }
+}
+
+Expression::Ptr ValueComparison::compress(const StaticContext::Ptr &context)
+{
+ const Expression::Ptr me(PairContainer::compress(context));
+
+ if(me != this)
+ return me;
+
+ if(isCaseInsensitiveCompare(m_operand1, m_operand2))
+ useCaseInsensitiveComparator();
+
+ return me;
+}
+
+bool ValueComparison::isCaseInsensitiveCompare(Expression::Ptr &op1, Expression::Ptr &op2)
+{
+ Q_ASSERT(op1);
+ Q_ASSERT(op2);
+
+ const ID iD = op1->id();
+
+ if((iD == IDLowerCaseFN || iD == IDUpperCaseFN) && iD == op2->id())
+ {
+ /* Both are either fn:lower-case() or fn:upper-case(). */
+
+ /* Replace the calls to the functions with its operands. */
+ op1 = op1->operands().first();
+ op2 = op2->operands().first();
+
+ return true;
+ }
+ else
+ return false;
+}
+
+OptimizationPass::List ValueComparison::optimizationPasses() const
+{
+ return OptimizationPasses::comparisonPasses;
+}
+
+SequenceType::List ValueComparison::expectedOperandTypes() const
+{
+ SequenceType::List result;
+ result.append(CommonSequenceTypes::ZeroOrOneAtomicType);
+ result.append(CommonSequenceTypes::ZeroOrOneAtomicType);
+ return result;
+}
+
+SequenceType::Ptr ValueComparison::staticType() const
+{
+ if(m_operand1->staticType()->cardinality().allowsEmpty() ||
+ m_operand2->staticType()->cardinality().allowsEmpty())
+ return CommonSequenceTypes::ZeroOrOneBoolean;
+ else
+ return CommonSequenceTypes::ExactlyOneBoolean;
+}
+
+ExpressionVisitorResult::Ptr ValueComparison::accept(const ExpressionVisitor::Ptr &visitor) const
+{
+ return visitor->visit(this);
+}
+
+Expression::ID ValueComparison::id() const
+{
+ return IDValueComparison;
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/expr/qvaluecomparison_p.h b/src/xmlpatterns/expr/qvaluecomparison_p.h
new file mode 100644
index 0000000..3aa9f5f
--- /dev/null
+++ b/src/xmlpatterns/expr/qvaluecomparison_p.h
@@ -0,0 +1,138 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_ValueComparison_H
+#define Patternist_ValueComparison_H
+
+#include "qatomiccomparator_p.h"
+#include "qpaircontainer_p.h"
+#include "qcomparisonplatform_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+
+ /**
+ * @short Implements XPath 2.0 value comparions, such as the <tt>eq</tt> operator.
+ *
+ * ComparisonPlatform is inherited with @c protected scope because ComparisonPlatform
+ * must access members of ValueComparison.
+ *
+ * @see <a href="http://www.w3.org/TR/xpath20/#id-value-comparisons">XML Path Language
+ * (XPath) 2.0, 3.5.1 Value Comparisons</a>
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_expressions
+ */
+ class ValueComparison : public PairContainer,
+ public ComparisonPlatform<ValueComparison, true>
+ {
+ public:
+ ValueComparison(const Expression::Ptr &op1,
+ const AtomicComparator::Operator op,
+ const Expression::Ptr &op2);
+
+ virtual Item evaluateSingleton(const DynamicContext::Ptr &) const;
+
+ virtual Expression::Ptr typeCheck(const StaticContext::Ptr &context,
+ const SequenceType::Ptr &reqType);
+
+ /**
+ * @returns always CommonSequenceTypes::ExactlyOneBoolean
+ */
+ virtual SequenceType::Ptr staticType() const;
+
+ virtual SequenceType::List expectedOperandTypes() const;
+
+ /**
+ * @returns IDValueComparison
+ */
+ virtual ID id() const;
+
+ virtual ExpressionVisitorResult::Ptr accept(const ExpressionVisitor::Ptr &visitor) const;
+ virtual QList<QExplicitlySharedDataPointer<OptimizationPass> > optimizationPasses() const;
+
+ /**
+ * Overridden to optimize case-insensitive compares.
+ */
+ virtual Expression::Ptr compress(const StaticContext::Ptr &context);
+
+ /**
+ * @returns the operator that this ValueComparison is using.
+ */
+ inline AtomicComparator::Operator operatorID() const
+ {
+ return m_operator;
+ }
+
+ /**
+ * It is considered that the string value from @p op1 will be compared against @p op2. This
+ * function determines whether the user intends the comparison to be case insensitive. If
+ * that is the case @c true is returned, and the operands are re-written appropriately.
+ *
+ * This is a helper function for Expression classes that compares strings.
+ *
+ * @see ComparisonPlatform::useCaseInsensitiveComparator()
+ */
+ static bool isCaseInsensitiveCompare(Expression::Ptr &op1, Expression::Ptr &op2);
+
+ private:
+ const AtomicComparator::Operator m_operator;
+ };
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/expr/qvariabledeclaration.cpp b/src/xmlpatterns/expr/qvariabledeclaration.cpp
new file mode 100644
index 0000000..2f5a72e
--- /dev/null
+++ b/src/xmlpatterns/expr/qvariabledeclaration.cpp
@@ -0,0 +1,63 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qvariabledeclaration_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+bool VariableDeclaration::contains(const VariableDeclaration::List &list,
+ const QXmlName &lookup)
+{
+ VariableDeclaration::List::const_iterator it(list.constBegin());
+ const VariableDeclaration::List::const_iterator end(list.constEnd());
+
+ for(; it != end; ++it)
+ {
+ if((*it)->name == lookup)
+ return true;
+ }
+
+ return false;
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/expr/qvariabledeclaration_p.h b/src/xmlpatterns/expr/qvariabledeclaration_p.h
new file mode 100644
index 0000000..a2430a8
--- /dev/null
+++ b/src/xmlpatterns/expr/qvariabledeclaration_p.h
@@ -0,0 +1,203 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_VariableDeclaration_H
+#define Patternist_VariableDeclaration_H
+
+#include <QSharedData>
+
+#include "qexpression_p.h"
+#include "qpatternistlocale_p.h"
+#include "qvariablereference_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+template<typename T> class QStack;
+
+namespace QPatternist
+{
+ /**
+ * @short Represents a declared variable. Only used at
+ * the compilation stage.
+ *
+ * @see FunctionArgument
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_expressions
+ */
+ class VariableDeclaration : public QSharedData
+ {
+ public:
+ typedef QExplicitlySharedDataPointer<VariableDeclaration> Ptr;
+ typedef QStack<VariableDeclaration::Ptr> Stack;
+ typedef QList<VariableDeclaration::Ptr> List;
+
+ /**
+ * @short The key is the variable name.
+ */
+ typedef QHash<QXmlName, VariableDeclaration::Ptr> Hash;
+
+ enum Type
+ {
+ RangeVariable,
+ ExpressionVariable,
+ FunctionArgument,
+ PositionalVariable,
+ TemplateParameter,
+
+ /**
+ * A global variable is always an external variable, but it is
+ * cached differently.
+ *
+ * @see DynamicContext::globalItemCacheCell()
+ */
+ GlobalVariable,
+
+ /**
+ * External variables doesn't use slots, that's a big difference
+ * compared to the other types.
+ */
+ ExternalVariable
+ };
+
+ /**
+ * Creates a VariableDeclaration.
+ *
+ * @p sourceExpr and @p seqType may be @c null.
+ */
+ VariableDeclaration(const QXmlName n,
+ const VariableSlotID varSlot,
+ const Type t,
+ const SequenceType::Ptr &seqType) : name(n)
+ , slot(varSlot)
+ , type(t)
+ , sequenceType(seqType)
+ , canSourceRewrite(true)
+ {
+ Q_ASSERT(!name.isNull());
+ Q_ASSERT(t == ExternalVariable || t == TemplateParameter || varSlot > -1);
+ }
+
+ inline bool isUsed() const
+ {
+ return !references.isEmpty();
+ }
+
+ inline const Expression::Ptr &expression() const
+ {
+ return m_expression;
+ }
+
+ inline void setExpression(const Expression::Ptr &expr)
+ {
+ m_expression = expr;
+ }
+
+ /**
+ * @short Returns how many times this variable is used.
+ */
+ inline bool usedByMany() const
+ {
+ return references.count() > 1;
+ }
+
+ /**
+ * @short Returns @c true if @p list contains @p lookup.
+ */
+ static bool contains(const VariableDeclaration::List &list,
+ const QXmlName &lookup);
+
+ const QXmlName name;
+ const VariableSlotID slot;
+ const Type type;
+
+ /**
+ * The declared type of the variable. What the value might be, depends
+ * on the context which VariableDeclaration is used in. Note that
+ * sequenceType is hence not in anyway obligated to the type of
+ * expression().
+ */
+ const SequenceType::Ptr sequenceType;
+ VariableReference::List references;
+
+ /**
+ * @short Whether a reference can rewrite itself to expression().
+ *
+ * The default value is @c true.
+ */
+ bool canSourceRewrite;
+
+ private:
+ Expression::Ptr m_expression;
+ Q_DISABLE_COPY(VariableDeclaration)
+ };
+
+ /**
+ * @short Formats @p var appropriately for display.
+ *
+ * @relates VariableDeclaration
+ */
+ static inline QString formatKeyword(const VariableDeclaration::Ptr &var,
+ const NamePool::Ptr &np)
+ {
+ Q_ASSERT(var);
+ Q_ASSERT(np);
+ return formatKeyword(np->displayName(var->name));
+ }
+
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/expr/qvariablereference.cpp b/src/xmlpatterns/expr/qvariablereference.cpp
new file mode 100644
index 0000000..5281820
--- /dev/null
+++ b/src/xmlpatterns/expr/qvariablereference.cpp
@@ -0,0 +1,58 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qvariablereference_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+VariableReference::VariableReference(const VariableSlotID slotP) : m_varSlot(slotP)
+{
+ Q_ASSERT(m_varSlot > -1);
+}
+
+Expression::Properties VariableReference::properties() const
+{
+ return DisableElimination;
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/expr/qvariablereference_p.h b/src/xmlpatterns/expr/qvariablereference_p.h
new file mode 100644
index 0000000..fca6fdd
--- /dev/null
+++ b/src/xmlpatterns/expr/qvariablereference_p.h
@@ -0,0 +1,121 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_VariableReference_H
+#define Patternist_VariableReference_H
+
+#include "qemptycontainer_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+template<typename T> class QList;
+
+namespace QPatternist
+{
+ /**
+ * @short Baseclass for classes being references to variables.
+ *
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_expressions
+ */
+ class VariableReference : public EmptyContainer
+ {
+ public:
+ typedef QExplicitlySharedDataPointer<VariableReference> Ptr;
+ typedef QList<VariableReference::Ptr> List;
+
+ /**
+ * Creates a VariableReference.
+ *
+ * @param slot must be a valid slot. That is, zero or larger.
+ */
+ VariableReference(const VariableSlotID slot);
+
+ /**
+ * @returns the slot that this reference communicates through.
+ *
+ * This is a slot in the DynamicContext. Which one, depends on the
+ * type, which this VariableReference does not have information about.
+ * For instance, it could DynamicContext::expressionVariable() or
+ * DynamicContext::rangeVariable().
+ */
+ inline VariableSlotID slot() const;
+
+ /**
+ * @returns DisableElimination
+ */
+ virtual Properties properties() const;
+
+ private:
+ /**
+ * The slot. Same as returned by slot().
+ *
+ * This variable is not called m_slot, because that creates a weird
+ * compiler error on hpuxi-acc. See the preprocessor output. EvaluationCache::m_varSlot
+ * is a similar workaround.
+ */
+ const VariableSlotID m_varSlot;
+ };
+
+ inline VariableSlotID VariableReference::slot() const
+ {
+ return m_varSlot;
+ }
+
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/expr/qwithparam_p.h b/src/xmlpatterns/expr/qwithparam_p.h
new file mode 100644
index 0000000..7f8b542
--- /dev/null
+++ b/src/xmlpatterns/expr/qwithparam_p.h
@@ -0,0 +1,123 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_TemplateParam_H
+#define Patternist_TemplateParam_H
+
+#include "qfunctionargument_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Carries meta data for @c xsl:with-param as encountered in
+ * template callsites such as @c xsl:call-template and @c
+ * xsl:apply-templates.
+ *
+ * WithParam is similar to FunctionArgument, but has in addition a default
+ * value in the form of an Expression.
+ *
+ * @since 4.5
+ * @ingroup Patternist_expressions
+ * @author Frans Englich <frans.englich@nokia.com>
+ */
+ class WithParam : public FunctionArgument
+ {
+ public:
+ typedef QExplicitlySharedDataPointer<WithParam> Ptr;
+ typedef QHash<QXmlName, Ptr> Hash;
+
+ /**
+ * @p sourceExpression can not be @c null.
+ */
+ inline WithParam(const QXmlName name,
+ const SequenceType::Ptr &type,
+ const Expression::Ptr &sourceExpression);
+
+ inline void setSourceExpression(const Expression::Ptr &expr)
+ {
+ Q_ASSERT(expr);
+ m_sourceExpression = expr;
+ }
+
+ /**
+ * @short Returns the expression which is the source the value for this
+ * parameter.
+ *
+ * Guaranteed to never be @c null.
+ */
+ inline Expression::Ptr sourceExpression() const
+ {
+ return m_sourceExpression;
+ }
+
+ private:
+ Expression::Ptr m_sourceExpression;
+ };
+
+ WithParam::WithParam(const QXmlName name,
+ const SequenceType::Ptr &type,
+ const Expression::Ptr &sourceExpression) : FunctionArgument(name, type)
+ , m_sourceExpression(sourceExpression)
+ {
+ Q_ASSERT(m_sourceExpression);
+ }
+
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/xmlpatterns/expr/qxsltsimplecontentconstructor.cpp b/src/xmlpatterns/expr/qxsltsimplecontentconstructor.cpp
new file mode 100644
index 0000000..e69dc5d
--- /dev/null
+++ b/src/xmlpatterns/expr/qxsltsimplecontentconstructor.cpp
@@ -0,0 +1,158 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qatomicstring_p.h"
+#include "qcommonsequencetypes_p.h"
+
+#include "qxsltsimplecontentconstructor_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace QPatternist;
+
+XSLTSimpleContentConstructor::XSLTSimpleContentConstructor(const Expression::Ptr &source) : SimpleContentConstructor(source)
+{
+}
+
+QString XSLTSimpleContentConstructor::processItem(const Item &item,
+ bool &discard,
+ bool &isText)
+{
+ if(item.isNode())
+ {
+ isText = (item.asNode().kind() == QXmlNodeModelIndex::Text);
+
+ if(isText)
+ {
+ const QString value(item.stringValue());
+
+ /* "1. Zero-length text nodes in the sequence are discarded." */
+ discard = value.isEmpty();
+ return value;
+ }
+ else
+ {
+ Item::Iterator::Ptr it(item.sequencedTypedValue()); /* Atomic values. */
+ Item next(it->next());
+ QString result;
+
+ if(next)
+ result = next.stringValue();
+
+ next = it->next();
+
+ while(next)
+ {
+ result += next.stringValue();
+ result += QLatin1Char(' ');
+ next = it->next();
+ }
+
+ return result;
+ }
+ }
+ else
+ {
+ discard = false;
+ isText = false;
+ return item.stringValue();
+ }
+}
+
+Item XSLTSimpleContentConstructor::evaluateSingleton(const DynamicContext::Ptr &context) const
+{
+ const Item::Iterator::Ptr it(m_operand->evaluateSequence(context));
+
+ Item next(it->next());
+ QString result;
+
+ bool previousIsText = false;
+ bool discard = false;
+
+ if(next)
+ {
+ const QString unit(processItem(next, discard, previousIsText));
+
+ if(!discard)
+ result = unit;
+
+ next = it->next();
+ }
+ else
+ return Item();
+
+ while(next)
+ {
+ bool currentIsText = false;
+ const QString unit(processItem(next, discard, currentIsText));
+
+ if(!discard)
+ {
+ /* "Adjacent text nodes in the sequence are merged into a single text
+ * node." */
+ if(previousIsText && currentIsText)
+ ;
+ else
+ result += QLatin1Char(' ');
+
+ result += unit;
+ }
+
+ next = it->next();
+ previousIsText = currentIsText;
+ }
+
+ return AtomicString::fromValue(result);
+}
+
+SequenceType::List XSLTSimpleContentConstructor::expectedOperandTypes() const
+{
+ SequenceType::List result;
+ result.append(CommonSequenceTypes::ZeroOrMoreItems);
+ return result;
+}
+
+SequenceType::Ptr XSLTSimpleContentConstructor::staticType() const
+{
+ return CommonSequenceTypes::ZeroOrOneString;
+}
+
+QT_END_NAMESPACE
diff --git a/src/xmlpatterns/expr/qxsltsimplecontentconstructor_p.h b/src/xmlpatterns/expr/qxsltsimplecontentconstructor_p.h
new file mode 100644
index 0000000..853a38b
--- /dev/null
+++ b/src/xmlpatterns/expr/qxsltsimplecontentconstructor_p.h
@@ -0,0 +1,89 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtXmlPatterns module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Patternist_XSLTSimpleContentConstructor_H
+#define Patternist_XSLTSimpleContentConstructor_H
+
+#include "qsimplecontentconstructor_p.h"
+
+QT_BEGIN_HEADER
+QT_BEGIN_NAMESPACE
+
+namespace QPatternist
+{
+ /**
+ * @short Implements XSL-T's construction of simple content, which is
+ * different from XQuery's approach.
+ *
+ * @see <a href="http://www.w3.org/TR/xslt20/#constructing-simple-content">XSL
+ * Transformations (XSLT) Version 2.0, 5.7.2 Constructing Simple Content</a>
+ * @author Frans Englich <frans.englich@nokia.com>
+ * @ingroup Patternist_expressions
+ */
+ class XSLTSimpleContentConstructor : public SimpleContentConstructor
+ {
+ public:
+ XSLTSimpleContentConstructor(const Expression::Ptr &source);
+ virtual Item evaluateSingleton(const DynamicContext::Ptr &context) const;
+
+ virtual SequenceType::List expectedOperandTypes() const;
+ virtual SequenceType::Ptr staticType() const;
+ private:
+ static inline QString processItem(const Item &item,
+ bool &discard,
+ bool &isText);
+ };
+}
+
+QT_END_NAMESPACE
+QT_END_HEADER
+
+#endif