summaryrefslogtreecommitdiff
path: root/src/xmlpatterns/expr
diff options
context:
space:
mode:
authorQt by Nokia <qt-info@nokia.com>2011-04-27 12:05:43 +0200
committeraxis <qt-info@nokia.com>2011-04-27 12:05:43 +0200
commite1b2c9deb5943faae2b29be6a5c006f75bb73f06 (patch)
treefc79e45367c0a8fc71185e9afc33f7503a58653c /src/xmlpatterns/expr
downloadqtxmlpatterns-e1b2c9deb5943faae2b29be6a5c006f75bb73f06.tar.gz
Initial import from the monolithic Qt.
This is the beginning of revision history for this module. If you want to look at revision history older than this, please refer to the Qt Git wiki for how to use Git history grafting. At the time of writing, this wiki is located here: http://qt.gitorious.org/qt/pages/GitIntroductionWithQt If you have already performed the grafting and you don't see any history beyond this commit, try running "git log" with the "--follow" argument. Branched from the monolithic repo, Qt master branch, at commit 896db169ea224deb96c59ce8af800d019de63f12
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