1/****************************************************************************
2**
3** Copyright (C) 2016 The Qt Company Ltd.
4** Contact: https://www.qt.io/licensing/
5**
6** This file is part of the test suite of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:GPL-EXCEPT$
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 The Qt Company. For licensing terms
14** and conditions see https://www.qt.io/terms-conditions. For further
15** information use the contact form at https://www.qt.io/contact-us.
16**
17** GNU General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU
19** General Public License version 3 as published by the Free Software
20** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
21** included in the packaging of this file. Please review the following
22** information to ensure the GNU General Public License requirements will
23** be met: https://www.gnu.org/licenses/gpl-3.0.html.
24**
25** $QT_END_LICENSE$
26**
27****************************************************************************/
28
29#include <QStringList>
30#include <QVariant>
31#include <QtDebug>
32#include <QXmlNamePool>
33
34#include <private/qfunctionfactorycollection_p.h>
35
36#include "ASTItem.h"
37#include "ExpressionInfo.h"
38#include "ExpressionNamer.h"
39#include "Global.h"
40
41#include "DebugExpressionFactory.h"
42
43using namespace QPatternistSDK;
44using namespace QPatternist;
45
46static const QPatternist::ExpressionVisitor::Ptr namer(new ExpressionNamer());
47
48QStringList DebugExpressionFactory::availableFunctionSignatures()
49{
50 const QPatternist::FunctionFactory::Ptr factory(QPatternist::FunctionFactoryCollection::xpath20Factory(np: Global::namePool()));
51 const QPatternist::FunctionSignature::Hash signs(factory->functionSignatures());
52 const QPatternist::FunctionSignature::Hash::const_iterator end(signs.constEnd());
53 QPatternist::FunctionSignature::Hash::const_iterator it(signs.constBegin());
54 QStringList retval;
55
56 while(it != end)
57 {
58 retval << it.value()->displayName(np: Global::namePool());
59 ++it;
60 }
61
62 return retval;
63}
64
65ASTItem *DebugExpressionFactory::buildASTTree(const QPatternist::Expression::Ptr &expr,
66 ASTItem *parent,
67 const QPatternist::SequenceType::Ptr &reqType)
68{
69 Q_ASSERT(expr);
70 const QPatternist::ExpressionVisitorResult::Ptr exprInfo(expr->accept(visitor: namer));
71 Q_ASSERT(exprInfo);
72 const ExpressionInfo *const constExprInfo = static_cast<const ExpressionInfo *>(exprInfo.data());
73 const QString name(constExprInfo->name());
74 const QString details(constExprInfo->details());
75 const QString rType(reqType ? reqType->displayName(np: Global::namePool()) : QLatin1String("Not specified"));
76
77 /* ---------- Handle its staticType() -------- */
78 const QPatternist::SequenceType::Ptr type(expr->staticType());
79 QString seqType;
80
81 if(type)
82 seqType = type->displayName(np: Global::namePool());
83 else
84 seqType = QLatin1String("no type, null pointer returned");
85 /* ------------------------------------------- */
86
87 ASTItem *const node = new ASTItem(parent, name, details, seqType, rType);
88
89 /* ------------ Handle child nodes ----------- */
90 const QPatternist::Expression::List children(expr->operands());
91 QPatternist::Expression::List::const_iterator it(children.constBegin());
92 const QPatternist::Expression::List::const_iterator end(children.constEnd());
93
94 const QPatternist::SequenceType::List reqTypes(expr->expectedOperandTypes());
95 const QPatternist::SequenceType::List::const_iterator typeEnd(reqTypes.constEnd());
96 QPatternist::SequenceType::List::const_iterator typeIt(reqTypes.constBegin());
97 QPatternist::SequenceType::Ptr t;
98
99 for(; it != end; ++it)
100 {
101 if(typeIt != typeEnd)
102 {
103 t = *typeIt;
104 ++typeIt;
105 }
106
107 node->appendChild(item: buildASTTree(expr: *it, parent: node, reqType: t));
108 }
109 /* ------------------------------------------- */
110
111 return node;
112}
113
114QPatternist::Expression::Ptr
115DebugExpressionFactory::createExpression(QIODevice *const expr,
116 const QPatternist::StaticContext::Ptr &context,
117 const QXmlQuery::QueryLanguage lang,
118 const QPatternist::SequenceType::Ptr &requiredType,
119 const QUrl &baseURI,
120 const QXmlName &initialTemplateName)
121{
122 /* Create the root node. */
123 m_ast = new ASTItem(0, QString());
124
125 return ExpressionFactory::createExpression(device: expr, context, lang, requiredType, queryURI: baseURI, initialTemplateName);
126}
127
128void DebugExpressionFactory::processTreePass(const QPatternist::Expression::Ptr &expr,
129 const CompilationStage stage)
130{
131 ASTItem *newChild = 0;
132
133 switch(stage)
134 {
135 case QueryBodyInitial:
136 {
137 newChild = new ASTItem(m_ast, QLatin1String("Initial Build"));
138 break;
139 }
140 case QueryBodyTypeCheck:
141 {
142 newChild = new ASTItem(m_ast, QLatin1String("Type Check"));
143 break;
144 }
145 case QueryBodyCompression:
146 {
147 newChild = new ASTItem(m_ast, QLatin1String("Compression"));
148 break;
149 }
150 case UserFunctionTypeCheck:
151 {
152 newChild = new ASTItem(m_ast, QLatin1String("User Function Type Check"));
153 break;
154 }
155 case UserFunctionCompression:
156 {
157 newChild = new ASTItem(m_ast, QLatin1String("User Function Compression"));
158 break;
159 }
160 case GlobalVariableTypeCheck:
161 {
162 newChild = new ASTItem(m_ast, QLatin1String("Global Variable Type Check"));
163 break;
164 }
165 }
166
167 Q_ASSERT(newChild);
168 m_ast->appendChild(item: newChild);
169 newChild->appendChild(item: buildASTTree(expr, parent: newChild, reqType: QPatternist::SequenceType::Ptr()));
170}
171
172void DebugExpressionFactory::processTemplateRule(const Expression::Ptr &body,
173 const TemplatePattern::Ptr &pattern,
174 const QXmlName &mode,
175 const TemplateCompilationStage stage)
176{
177 QString title = QLatin1String("T-Rule ");
178
179 switch (stage) {
180 case TemplateInitial:
181 title += QLatin1String("Initial Build");
182 break;
183 case TemplateTypeCheck:
184 title += QLatin1String("Type Check");
185 break;
186 case TemplateCompress:
187 title += QLatin1String("Compression");
188 break;
189 }
190 title += QLatin1String(" mode: ")
191 + Global::namePool()->displayName(qName: mode)
192 + QLatin1String(" priority: ")
193 + QString::number(pattern->priority());
194
195 ASTItem *const newChild = new ASTItem(m_ast, title);
196 m_ast->appendChild(item: newChild);
197
198 newChild->appendChild(item: buildASTTree(expr: pattern->matchPattern(), parent: newChild, reqType: QPatternist::SequenceType::Ptr()));
199 newChild->appendChild(item: buildASTTree(expr: body, parent: newChild, reqType: QPatternist::SequenceType::Ptr()));
200}
201
202void DebugExpressionFactory::processNamedTemplate(const QXmlName &name,
203 const Expression::Ptr &body,
204 const TemplateCompilationStage stage)
205{
206 QString title;
207
208 switch (stage) {
209 case TemplateInitial:
210 title += QLatin1String("Named Template Initial Build");
211 break;
212 case TemplateTypeCheck:
213 title += QLatin1String("Named Template Type Check");
214 break;
215 case TemplateCompress:
216 title += QLatin1String("Named Template Compression");
217 break;
218 }
219
220 title += QLatin1String(": ") + Global::namePool()->displayName(qName: name);
221
222 ASTItem *const newChild = new ASTItem(m_ast, title);
223
224 m_ast->appendChild(item: newChild);
225 newChild->appendChild(item: buildASTTree(expr: body, parent: newChild, reqType: QPatternist::SequenceType::Ptr()));
226}
227
228ASTItem *DebugExpressionFactory::astTree() const
229{
230 return m_ast;
231}
232
233// vim: et:ts=4:sw=4:sts=4
234

source code of qtxmlpatterns/tests/auto/xmlpatternssdk/DebugExpressionFactory.cpp