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 | |
43 | using namespace QPatternistSDK; |
44 | using namespace QPatternist; |
45 | |
46 | static const QPatternist::ExpressionVisitor::Ptr namer(new ExpressionNamer()); |
47 | |
48 | QStringList 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 | |
65 | ASTItem *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 | |
114 | QPatternist::Expression::Ptr |
115 | DebugExpressionFactory::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 | |
128 | void 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 | |
172 | void 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 | |
202 | void 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 | |
228 | ASTItem *DebugExpressionFactory::astTree() const |
229 | { |
230 | return m_ast; |
231 | } |
232 | |
233 | // vim: et:ts=4:sw=4:sts=4 |
234 | |