Qt 4.8
qtemplate.cpp
Go to the documentation of this file.
1 /****************************************************************************
2 **
3 ** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/legal
5 **
6 ** This file is part of the QtXmlPatterns module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia. For licensing terms and
14 ** conditions see http://qt.digia.com/licensing. For further information
15 ** use the contact form at http://qt.digia.com/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 2.1 requirements
23 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24 **
25 ** In addition, as a special exception, Digia gives you certain additional
26 ** rights. These rights are described in the Digia Qt LGPL Exception
27 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28 **
29 ** GNU General Public License Usage
30 ** Alternatively, this file may be used under the terms of the GNU
31 ** General Public License version 3.0 as published by the Free Software
32 ** Foundation and appearing in the file LICENSE.GPL included in the
33 ** packaging of this file. Please review the following information to
34 ** ensure the GNU General Public License version 3.0 requirements will be
35 ** met: http://www.gnu.org/copyleft/gpl.html.
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41 
42 #include "qdynamiccontextstore_p.h"
43 #include "qpatternistlocale_p.h"
44 
45 #include "qtemplate_p.h"
46 
48 
49 using namespace QPatternist;
50 
52 {
53  return this;
54 }
55 
57 {
59  const int len = templateParameters.count();
60 
61  for(int i = 0; i < len; ++i)
62  {
64  retval.insert(at->name, at->expression());
65  }
66 
67  return retval;
68 }
69 
71  const QXmlName &name,
72  const SourceLocationReflection *const reflection)
73 {
74  context->error(QtXmlPatterns::tr("The parameter %1 is passed, but no corresponding %2 exists.")
75  .arg(formatKeyword(context->namePool(), name),
76  formatKeyword(QLatin1String("xsl:param"))),
78  reflection);
79 }
80 
82  const DynamicContext::Ptr &context,
83  const bool isCallTemplate) const
84 {
85  Q_ASSERT(invoker);
86  Q_ASSERT(context);
87 
88  /* We have:
89  * - xsl:params in the target template (if any) which may provide
90  * default values.
91  * - xsl:with-params in the caller (if any) which provides values.
92  *
93  * We need to, for each parameter:
94  * - If the called template provides no default value and the caller
95  * has no value, it's an error
96  * - If the called template has a default value and the caller provides
97  * none, it should be used
98  * - In any case the caller provides a value, it needs to be used.
99  *
100  * Problems to look out for:
101  *
102  * - Each xsl:param is in scope for the subsequent xsl:params. Hence,
103  * the evaluation of one xsl:param can depend on another xsl:param,
104  * and so on
105  * - The focus for xsl:params is different from the focus for
106  * the xsl:with-params
107  * - The xsl:with-params are not in scope for the xsl:params.
108  */
109 
110  WithParam::Hash withParams(invoker->withParams());
111 
119  DynamicContext::Ptr newStack(context->createStack());
120 
121  /* We have no parameters, and we have no further error checking to
122  * do in the case of not being xsl:apply-templates, so we need to do nothing. */
123  if(templateParameters.isEmpty() && (!isCallTemplate || withParams.isEmpty()))
124  return newStack;
125 
127  DynamicContext::TemplateParameterHash sewnTogether(hashedParams);
128 
130 
132  it != end;
133  ++it)
134  {
135  Expression::Ptr &param = it.value();
136 
137  WithParam::Ptr &withParam = withParams[it.key()];
138 
139  if(withParam)
140  param = Expression::Ptr(new DynamicContextStore(withParam->sourceExpression(), context));
141  else if(!param)
142  {
143  /* Ops, no xsl:with-param and no default value to cover up for it.
144  */
145  context->error(QtXmlPatterns::tr("The parameter %1 is required, but no corresponding %2 is supplied.")
146  .arg(formatKeyword(context->namePool(), it.key()),
147  formatKeyword(QLatin1String("xsl:with-param"))),
149  this);
150  }
151  }
152 
153  if(isCallTemplate)
154  {
155  /* Find xsl:with-param that has no corresponding xsl:param. */
156  /* Optimization: candidate for threading? */
157 
158  const WithParam::Hash::const_iterator end(withParams.constEnd());
159 
160  for(WithParam::Hash::const_iterator it(withParams.constBegin()); it != end; ++it)
161  {
162  if(!hashedParams.contains(it.key()))
163  raiseXTSE0680(context, it.key(), this);
164  }
165 
166  }
167 
168  newStack->templateParameterStore() = sewnTogether;
169  return newStack;
170 }
171 
173 {
174  Q_ASSERT(context);
175 
176  const int len = templateParameters.count();
177 
178  for(int i = 0; i < len; ++i)
179  {
181 
182  /* If our value is required, we don't have a default value. */
183  if(at->expression())
184  {
185  // TODO why do we pass in its own type here?
186  at->setExpression(at->expression()->typeCheck(context, at->expression()->staticType()));
187 
188  at->setExpression(at->expression()->compress(context));
189  }
190  }
191 }
192 
194 {
195  return Expression::DisableElimination; /* We're having issues with recursion detection, so this path currently loops infintely. */
196 
198 
200 
202  it != end;
203  ++it)
204  {
205  if((*it)->expression())
206  collect |= (*it)->expression()->properties();
207  }
208 
209  // TODO simplify.
211 }
212 
214 {
215  return Expression::DisableElimination; /* We're having issues with recursion detection, so this path currently loops infintely. */
216 
218 
220 
222  it != end;
223  ++it)
224  {
225  if((*it)->expression())
226  collect |= (*it)->expression()->dependencies();
227  }
228 
230 }
231 
virtual NamePool::Ptr namePool() const =0
#define QT_END_NAMESPACE
This macro expands to.
Definition: qglobal.h:90
Expression::Properties properties() const
Definition: qtemplate.cpp:193
QString formatKeyword(const QString &keyword)
#define it(className, varName)
DynamicContext::TemplateParameterHash parametersAsHash() const
Definition: qtemplate.cpp:56
static void raiseXTSE0680(const ReportContext::Ptr &context, const QXmlName &name, const SourceLocationReflection *const reflection)
Definition: qtemplate.cpp:70
#define at(className, varName)
The QExplicitlySharedDataPointer class represents a pointer to an explicitly shared object...
Definition: qshareddata.h:136
const_iterator constBegin() const
Returns a const STL-style iterator pointing to the first item in the list.
Definition: qlist.h:269
DynamicContext::Ptr createStack()
QLatin1String(DBUS_INTERFACE_DBUS))) Q_GLOBAL_STATIC_WITH_ARGS(QString
int count(const T &t) const
Returns the number of occurrences of value in the list.
Definition: qlist.h:891
Base class for classes that invokes templates, such as CallTemplate and ApplyTemplate.
#define Q_ASSERT(cond)
Definition: qglobal.h:1823
bool contains(const Key &key) const
Returns true if the hash contains an item with the key; otherwise returns false.
Definition: qhash.h:872
bool isEmpty() const
Returns true if the list contains no items; otherwise returns false.
Definition: qlist.h:152
iterator insert(const Key &key, const T &value)
Inserts a new item with the key and a value of value.
Definition: qhash.h:753
Expression::Properties dependencies() const
Definition: qtemplate.cpp:213
Expression::Ptr body
Definition: qtemplate_p.h:98
virtual const SourceLocationReflection * actualReflection() const
Definition: qtemplate.cpp:51
#define QT_BEGIN_NAMESPACE
This macro expands to.
Definition: qglobal.h:89
void error(const QString &message, const ReportContext::ErrorCode errorCode, const QSourceLocation &sourceLocation)
const char * name
const T & at(int i) const
Returns the item at index position i in the list.
Definition: qlist.h:468
The namespace for the internal API of QtXmlPatterns.
VariableDeclaration::List templateParameters
Definition: qtemplate_p.h:107
QExplicitlySharedDataPointer< Expression > Ptr
A smart pointer wrapping mutable Expression instances.
The QXmlName class represents the name of an XML node, in an efficient, namespace-aware way...
Definition: qxmlname.h:58
Contains functions used for formatting arguments, such as keywords and paths, in translated strings...
iterator end()
Returns an STL-style iterator pointing to the imaginary item after the last item in the hash...
Definition: qhash.h:467
const WithParam::Hash & withParams() const
virtual Properties properties() const
iterator begin()
Returns an STL-style iterator pointing to the first item in the hash.
Definition: qhash.h:464
DynamicContext::Ptr createContext(const TemplateInvoker *const invoker, const DynamicContext::Ptr &context, const bool isCallTemplate) const
Definition: qtemplate.cpp:81
Evaluates its operand with an assigned DynamicContext, not the one passed to one of the evaluation fu...
The QFlags class provides a type-safe way of storing OR-combinations of enum values.
Definition: qglobal.h:2313
static const KeyPair *const end
friend class const_iterator
Definition: qhash.h:461
Base class for all instances that represents something at a certain location.
virtual Properties dependencies() const
const_iterator constEnd() const
Returns a const STL-style iterator pointing to the imaginary item after the last item in the list...
Definition: qlist.h:272
void compileParameters(const StaticContext::Ptr &context)
Definition: qtemplate.cpp:172