OSDN Git Service

It's 2011 now.
[qt-creator-jp/qt-creator-jp.git] / src / libs / qmljs / parser / qmlerror.cpp
1 /****************************************************************************
2 **
3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: Nokia Corporation (qt-info@nokia.com)
6 **
7 ** This file is part of the QtDeclarative module of the Qt Toolkit.
8 **
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** No Commercial Usage
11 ** This file contains pre-release code and may not be distributed.
12 ** You may use this file in accordance with the terms and conditions
13 ** contained in the Technology Preview License Agreement accompanying
14 ** this package.
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 ** If you have questions regarding the use of this file, please contact
29 ** Nokia at qt-info@nokia.com.
30 **
31 **
32 **
33 **
34 **
35 **
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41
42 #include "qmlerror.h"
43
44 #include <QtCore/qdebug.h>
45 #include <QtCore/qfile.h>
46 #include <QtCore/qstringlist.h>
47
48 QT_BEGIN_NAMESPACE
49
50 /*!
51     \class QmlError
52     \since 4.7
53     \brief The QmlError class encapsulates a QML error.
54
55     QmlError includes a textual description of the error, as well
56     as location information (the file, line, and column). The toString()
57     method creates a single-line, human-readable string containing all of
58     this information, for example:
59     \code
60     file:///home/user/test.qml:7:8: Invalid property assignment: double expected
61     \endcode
62
63     You can use qDebug() or qWarning() to output errors to the console. This method
64     will attempt to open the file indicated by the error
65     and include additional contextual information.
66     \code
67     file:///home/user/test.qml:7:8: Invalid property assignment: double expected
68             y: "hello"
69                ^
70     \endcode
71
72     \sa QmlView::errors(), QmlComponent::errors()
73 */
74 class QmlErrorPrivate
75 {
76 public:
77     QmlErrorPrivate();
78
79     QUrl url;
80     QString description;
81     int line;
82     int column;
83 };
84
85 QmlErrorPrivate::QmlErrorPrivate()
86 : line(-1), column(-1)
87 {
88 }
89
90 /*!
91     Creates an empty error object.
92 */
93 QmlError::QmlError()
94 : d(0)
95 {
96 }
97
98 /*!
99     Creates a copy of \a other.
100 */
101 QmlError::QmlError(const QmlError &other)
102 : d(0)
103 {
104     *this = other;
105 }
106
107 /*!
108     Assigns \a other to this error object.
109 */
110 QmlError &QmlError::operator=(const QmlError &other)
111 {
112     if (!other.d) {
113         delete d;
114         d = 0;
115     } else {
116         if (!d) d = new QmlErrorPrivate;
117         d->url = other.d->url;
118         d->description = other.d->description;
119         d->line = other.d->line;
120         d->column = other.d->column;
121     }
122     return *this;
123 }
124
125 /*!
126     \internal 
127 */
128 QmlError::~QmlError()
129 {
130     delete d; d = 0;
131 }
132
133 /*!
134     Returns true if this error is valid, otherwise false.
135 */
136 bool QmlError::isValid() const
137 {
138     return d != 0;
139 }
140
141 /*!
142     Returns the url for the file that caused this error.
143 */
144 QUrl QmlError::url() const
145 {
146     if (d) return d->url;
147     else return QUrl();
148 }
149
150 /*!
151     Sets the \a url for the file that caused this error.
152 */
153 void QmlError::setUrl(const QUrl &url)
154 {
155     if (!d) d = new QmlErrorPrivate;
156     d->url = url;
157 }
158
159 /*!
160     Returns the error description.
161 */
162 QString QmlError::description() const
163 {
164     if (d) return d->description;
165     else return QString();
166 }
167
168 /*!
169     Sets the error \a description.
170 */
171 void QmlError::setDescription(const QString &description)
172 {
173     if (!d) d = new QmlErrorPrivate;
174     d->description = description;
175 }
176
177 /*!
178     Returns the error line number.
179 */
180 int QmlError::line() const
181 {
182     if (d) return d->line;
183     else return -1;
184 }
185
186 /*!
187     Sets the error \a line number.
188 */
189 void QmlError::setLine(int line)
190 {
191     if (!d) d = new QmlErrorPrivate;
192     d->line = line;
193 }
194
195 /*!
196     Returns the error column number.
197 */
198 int QmlError::column() const
199 {
200     if (d) return d->column;
201     else return -1;
202 }
203
204 /*!
205     Sets the error \a column number.
206 */
207 void QmlError::setColumn(int column)
208 {
209     if (!d) d = new QmlErrorPrivate;
210     d->column = column;
211 }
212
213 /*!
214     Returns the error as a human readable string.
215 */
216 QString QmlError::toString() const
217 {
218     QString rv;
219     if (url().isEmpty()) {
220         rv = QLatin1String("<Unknown File>");
221     } else if (line() != -1) {
222         rv = url().toString() + QLatin1Char(':') + QString::number(line());
223         if(column() != -1) 
224             rv += QLatin1Char(':') + QString::number(column());
225     } else {
226         rv = url().toString();
227     }
228
229     rv += QLatin1String(": ") + description();
230
231     return rv;
232 }
233
234 /*!
235     \relates QmlError
236     \fn QDebug operator<<(QDebug debug, const QmlError &error)
237
238     Outputs a human readable version of \a error to \a debug.
239 */
240
241 QDebug operator<<(QDebug debug, const QmlError &error)
242 {
243     debug << qPrintable(error.toString());
244
245     QUrl url = error.url();
246
247     if (error.line() > 0 && url.scheme() == QLatin1String("file")) {
248         QString file = url.toLocalFile();
249         QFile f(file);
250         if (f.open(QIODevice::ReadOnly)) {
251             QByteArray data = f.readAll();
252             QTextStream stream(data, QIODevice::ReadOnly);
253 #ifndef QT_NO_TEXTCODEC
254             stream.setCodec("UTF-8");
255 #endif
256             const QString code = stream.readAll();
257             const QStringList lines = code.split(QLatin1Char('\n'));
258
259             if (lines.count() >= error.line()) {
260                 const QString &line = lines.at(error.line() - 1);
261                 debug << "\n    " << qPrintable(line);
262
263                 if(error.column() > 0) {
264                     int column = qMax(0, error.column() - 1);
265                     column = qMin(column, line.length()); 
266
267                     QByteArray ind;
268                     ind.reserve(column);
269                     for (int i = 0; i < column; ++i) {
270                         const QChar ch = line.at(i);
271                         if (ch.isSpace())
272                             ind.append(ch.unicode());
273                         else
274                             ind.append(' ');
275                     }
276                     ind.append('^');
277                     debug << "\n    " << ind.constData();
278                 }
279             }
280         }
281     }
282     return debug;
283 }
284
285 QT_END_NAMESPACE