source: trunk/src/scripttools/debugging/qscriptxmlparser.cpp@ 561

Last change on this file since 561 was 561, checked in by Dmitry A. Kuminov, 15 years ago

trunk: Merged in qt 4.6.1 sources.

File size: 7.9 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
4** All rights reserved.
5** Contact: Nokia Corporation ([email protected])
6**
7** This file is part of the QtSCriptTools module of the Qt Toolkit.
8**
9** $QT_BEGIN_LICENSE:LGPL$
10** Commercial Usage
11** Licensees holding valid Qt Commercial licenses may use this file in
12** accordance with the Qt Commercial License Agreement provided with the
13** Software or, alternatively, in accordance with the terms contained in
14** a written agreement between you and Nokia.
15**
16** GNU Lesser General Public License Usage
17** Alternatively, this file may be used under the terms of the GNU Lesser
18** General Public License version 2.1 as published by the Free Software
19** Foundation and appearing in the file LICENSE.LGPL included in the
20** packaging of this file. Please review the following information to
21** ensure the GNU Lesser General Public License version 2.1 requirements
22** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
23**
24** In addition, as a special exception, Nokia gives you certain additional
25** rights. These rights are described in the Nokia Qt LGPL Exception
26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
27**
28** GNU General Public License Usage
29** Alternatively, this file may be used under the terms of the GNU
30** General Public License version 3.0 as published by the Free Software
31** Foundation and appearing in the file LICENSE.GPL included in the
32** packaging of this file. Please review the following information to
33** ensure the GNU General Public License version 3.0 requirements will be
34** met: http://www.gnu.org/copyleft/gpl.html.
35**
36** If you have questions regarding the use of this file, please contact
37** Nokia at [email protected].
38** $QT_END_LICENSE$
39**
40****************************************************************************/
41
42#include "qscriptxmlparser_p.h"
43
44#include <QtCore/qstringlist.h>
45#include <QtCore/qxmlstream.h>
46#include <QtCore/qdebug.h>
47
48QT_BEGIN_NAMESPACE
49
50static void tokenUntil(QXmlStreamReader &reader, QXmlStreamReader::TokenType target,
51 QList<int> &lineNumbers)
52{
53 int level = 0;
54 while (!reader.atEnd()) {
55 QXmlStreamReader::TokenType t = reader.readNext();
56 if ((t == target) && (level == 0))
57 return;
58 if (t == QXmlStreamReader::StartElement) {
59 ++level;
60 QString line = reader.attributes().value(QLatin1String("line")).toString();
61 if (!line.isEmpty())
62 lineNumbers.append(line.toInt());
63 } else if (t == QXmlStreamReader::EndElement) {
64 --level;
65 }
66 }
67// Q_ASSERT_X(false, "QScriptXmlParser", "premature end of file");
68}
69
70QScriptXmlParser::Result QScriptXmlParser::parse(const QString &xml)
71{
72 QMap<QString, int> functionsInfo;
73 QList<int> lineNumbers;
74 QXmlStreamReader reader(xml);
75 reader.readNext(); // StartDocument
76 reader.readNext(); // <program>
77 reader.readNext(); // <source-elements>
78 while (reader.readNext() == QXmlStreamReader::StartElement) {
79// qDebug() << reader.name().toString();
80 int line = reader.attributes().value(QLatin1String("line")).toString().toInt();
81 lineNumbers.append(line);
82 if (reader.name() == QLatin1String("function-declaration")) {
83 // extract the line number, name and formal parameters
84 reader.readNext(); // <name>
85 reader.readNext(); // Characters
86 QString name = reader.text().toString();
87 reader.readNext(); // </name>
88 reader.readNext(); // <formal-parameter-list>
89 QStringList formalParameters;
90 while (reader.readNext() == QXmlStreamReader::StartElement) {
91 reader.readNext(); // Characters
92 formalParameters.append(reader.text().toString());
93 reader.readNext(); // </identifier>
94 }
95 reader.readNext(); // <function-body>
96 tokenUntil(reader, QXmlStreamReader::EndElement, lineNumbers);
97
98 QString signature;
99 signature.append(name);
100 signature.append(QLatin1Char('('));
101 for (int i = 0; i < formalParameters.size(); ++i) {
102 if (i > 0)
103 signature.append(QLatin1String(", "));
104 signature.append(formalParameters.at(i));
105 }
106 signature.append(QLatin1Char(')'));
107 functionsInfo.insert(signature, line);
108 } else if (reader.name() == QLatin1String("expression-statement")) {
109 reader.readNext();
110 if ((reader.name() == QLatin1String("binary-expression"))
111 && reader.attributes().value(QLatin1String("op")) == QLatin1String("=")) {
112 // try to match a statement of the form Foo.prototype.bar = function() { ... }
113 // this can be generalized...
114 QString first, second, third;
115 reader.readNext(); // LHS
116 if (reader.name() == QLatin1String("field-member-expression")) {
117 reader.readNext();
118 if (reader.name() == QLatin1String("field-member-expression")) {
119 reader.readNext();
120 if (reader.name() == QLatin1String("identifier")) {
121 reader.readNext();
122 first = reader.text().toString();
123 }
124 tokenUntil(reader, QXmlStreamReader::EndElement, lineNumbers);
125 reader.readNext();
126 if (reader.name() == QLatin1String("identifier")) {
127 reader.readNext();
128 second = reader.text().toString();
129 }
130 tokenUntil(reader, QXmlStreamReader::EndElement, lineNumbers);
131 } else if (reader.name() == QLatin1String("identifier")) {
132 reader.readNext();
133 first = reader.text().toString();
134 }
135 tokenUntil(reader, QXmlStreamReader::EndElement, lineNumbers);
136 reader.readNext();
137 if (reader.name() == QLatin1String("identifier")) {
138 reader.readNext();
139 if (second.isEmpty())
140 second = reader.text().toString();
141 else
142 third = reader.text().toString();
143 }
144 tokenUntil(reader, QXmlStreamReader::EndElement, lineNumbers);
145 }
146 tokenUntil(reader, QXmlStreamReader::EndElement, lineNumbers);
147 reader.readNext(); // RHS
148 if (reader.name() == QLatin1String("function-expression")) {
149 if (!first.isEmpty()) {
150 QString signature = first;
151 if (!second.isEmpty()) {
152 signature.append(QLatin1Char('.'));
153 signature.append(second);
154 if (!third.isEmpty()) {
155 signature.append(QLatin1Char('.'));
156 signature.append(third);
157 }
158 }
159 signature.append(QLatin1String("()"));
160 functionsInfo.insert(signature, line);
161 }
162 }
163 tokenUntil(reader, QXmlStreamReader::EndElement, lineNumbers);
164 }
165 tokenUntil(reader, QXmlStreamReader::EndElement, lineNumbers);
166 }
167 tokenUntil(reader, QXmlStreamReader::EndElement, lineNumbers);
168 }
169 reader.readNext(); // </source-elements>
170 reader.readNext(); // </program>
171 reader.readNext(); // EndDocument
172 Q_ASSERT(reader.atEnd());
173 return Result(functionsInfo, lineNumbers.toSet());
174}
175
176QT_END_NAMESPACE
Note: See TracBrowser for help on using the repository browser.