QDeclarativeInfo::~QDeclarativeInfo()
{
    if (0 == --d->ref) {
        QList<QDeclarativeError> errors = d->errors;

        QDeclarativeEngine *engine = 0;

        if (!d->buffer.isEmpty()) {
            QDeclarativeError error;

            QObject *object = const_cast<QObject *>(d->object);

            if (object) {
                engine = qmlEngine(d->object);
                QString typeName;
                QDeclarativeType *type = QDeclarativeMetaType::qmlType(object->metaObject());
                if (type) {
                    typeName = QLatin1String(type->qmlTypeName());
                    int lastSlash = typeName.lastIndexOf(QLatin1Char('/'));
                    if (lastSlash != -1)
                        typeName = typeName.mid(lastSlash+1);
                } else {
                    typeName = QString::fromUtf8(object->metaObject()->className());
                    int marker = typeName.indexOf(QLatin1String("_QMLTYPE_"));
                    if (marker != -1)
                        typeName = typeName.left(marker);

                    marker = typeName.indexOf(QLatin1String("_QML_"));
                    if (marker != -1) {
                        typeName = typeName.left(marker) + "*";
                        type = QDeclarativeMetaType::qmlType(QMetaType::type(typeName.toLatin1()));
                        if (type) {
                            typeName = QLatin1String(type->qmlTypeName());
                            int lastSlash = typeName.lastIndexOf(QLatin1Char('/'));
                            if (lastSlash != -1)
                                typeName = typeName.mid(lastSlash+1);
                        }
                    }
                }

                d->buffer.prepend(QLatin1String("QML ") + typeName + QLatin1String(": "));

                QDeclarativeData *ddata = QDeclarativeData::get(object, false);
                if (ddata && ddata->outerContext && !ddata->outerContext->url.isEmpty()) {
                    error.setUrl(ddata->outerContext->url);
                    error.setLine(ddata->lineNumber);
                    error.setColumn(ddata->columnNumber);
                }
            }

            error.setDescription(d->buffer);

            errors.prepend(error);
        }

        QDeclarativeEnginePrivate::warning(engine, errors);

        delete d;
    }
}
示例#2
0
/*!
    Load the QDeclarativeComponent from the provided \a url.

    Ensure that the URL provided is full and correct, in particular, use
    \l QUrl::fromLocalFile() when loading a file from the local filesystem.
*/
void QDeclarativeComponent::loadUrl(const QUrl &url)
{
    Q_D(QDeclarativeComponent);

    d->clear();

    if (url.isRelative() && !url.isEmpty())
        d->url = d->engine->baseUrl().resolved(url);
    else
        d->url = url;

    if (url.isEmpty()) {
        QDeclarativeError error;
        error.setDescription(tr("Invalid empty URL"));
        d->state.errors << error;
        return;
    }

    QDeclarativeCompositeTypeData *data =
        QDeclarativeEnginePrivate::get(d->engine)->typeManager.get(d->url);

    if (data->status == QDeclarativeCompositeTypeData::Waiting
            || data->status == QDeclarativeCompositeTypeData::WaitingResources)
    {
        d->typeData = data;
        d->typeData->addWaiter(d);
        d->progress = data->progress;
    } else {
        d->fromTypeData(data);
        d->progress = 1.0;
    }

    emit statusChanged(status());
    emit progressChanged(d->progress);
}
示例#3
0
/*!
    Load the QDeclarativeComponent from the provided \a url.

    Ensure that the URL provided is full and correct, in particular, use
    \l QUrl::fromLocalFile() when loading a file from the local filesystem.
*/
void QDeclarativeComponent::loadUrl(const QUrl &url)
{
    Q_D(QDeclarativeComponent);

    d->clear();

    if ((url.isRelative() && !url.isEmpty())
    || url.scheme() == QLatin1String("file")) // Workaround QTBUG-11929
        d->url = d->engine->baseUrl().resolved(url);
    else
        d->url = url;

    if (url.isEmpty()) {
        QDeclarativeError error;
        error.setDescription(tr("Invalid empty URL"));
        d->state.errors << error;
        return;
    }

    QDeclarativeTypeData *data = QDeclarativeEnginePrivate::get(d->engine)->typeLoader.get(d->url);

    if (data->isCompleteOrError()) {
        d->fromTypeData(data);
        d->progress = 1.0;
    } else {
        d->typeData = data;
        d->typeData->registerCallback(d);
        d->progress = data->progress();
    }

    emit statusChanged(status());
    emit progressChanged(d->progress);
}
示例#4
0
void QDeclarativeExpressionPrivate::exceptionToError(QScriptEngine *scriptEngine, 
                                            QDeclarativeError &error)
{
    if (scriptEngine->hasUncaughtException() && 
        scriptEngine->uncaughtException().isError()) {

        QString fileName;
        int lineNumber = scriptEngine->uncaughtExceptionLineNumber();

        QScriptValue exception = scriptEngine->uncaughtException();
        QLatin1String fileNameProp("fileName");

        if (!exception.property(fileNameProp).toString().isEmpty()){
            fileName = exception.property(fileNameProp).toString();
        } else {
            fileName = QLatin1String("<Unknown File>");
        }

        error.setUrl(QUrl(fileName));
        error.setLine(lineNumber);
        error.setColumn(-1);
        error.setDescription(exception.toString());
    } else {
        error = QDeclarativeError();
    }
}
示例#5
0
/*!
    Reports an error in parsing \a prop, with the given \a description.

    An error is generated referring to the position of \a node in the source file.
*/
void QDeclarativeCustomParser::error(const QDeclarativeCustomParserProperty& prop, const QString& description)
{
    QDeclarativeError error;
    QString exceptionDescription;
    error.setLine(prop.location().line);
    error.setColumn(prop.location().column);
    error.setDescription(description);
    exceptions << error;
}
示例#6
0
/*!
    Reports an error in parsing \a node, with the given \a description.

    An error is generated referring to the position of \a node in the source file.
*/
void QDeclarativeCustomParser::error(const QDeclarativeCustomParserNode& node, const QString& description)
{
    QDeclarativeError error;
    QString exceptionDescription;
    error.setLine(node.location().line);
    error.setColumn(node.location().column);
    error.setDescription(description);
    exceptions << error;
}
示例#7
0
void QDeclarativeDirParser::reportError(int line, int column, const QString &description)
{
    QDeclarativeError error;
    error.setUrl(_url);
    error.setLine(line);
    error.setColumn(column);
    error.setDescription(description);
    _errors.append(error);
}
示例#8
0
/*!
    Reports an error with the given \a description.

    This can only be used during the compile() step. For errors during setCustomData(), use qmlInfo().

    An error is generated referring to the position of the element in the source file.
*/
void QDeclarativeCustomParser::error(const QString& description)
{
    Q_ASSERT(object);
    QDeclarativeError error;
    QString exceptionDescription;
    error.setLine(object->location.start.line);
    error.setColumn(object->location.start.column);
    error.setDescription(description);
    exceptions << error;
}
示例#9
0
/*!
    Loads a QDeclarativeDomDocument from \a data.  \a data should be valid QML
    data.  On success, true is returned.  If the \a data is malformed, false
    is returned and QDeclarativeDomDocument::errors() contains an error description.

    \sa QDeclarativeDomDocument::loadError()
*/
bool QDeclarativeDomDocument::load(QDeclarativeEngine *engine, const QByteArray &data, const QUrl &url)
{
    d->errors.clear();
    d->imports.clear();

    QDeclarativeCompiledData *component = new QDeclarativeCompiledData(engine);
    QDeclarativeCompiler compiler;

    QDeclarativeCompositeTypeData *td = ((QDeclarativeEnginePrivate *)QDeclarativeEnginePrivate::get(engine))->typeManager.getImmediate(data, url);

    if(td->status == QDeclarativeCompositeTypeData::Error) {
        d->errors = td->errors;
        td->release();
        component->release();
        return false;
    } else if(td->status == QDeclarativeCompositeTypeData::Waiting ||
              td->status == QDeclarativeCompositeTypeData::WaitingResources) {
        QDeclarativeError error;
        error.setDescription(QLatin1String("QDeclarativeDomDocument supports local types only"));
        d->errors << error;
        td->release();
        component->release();
        return false;
    }

    compiler.compile(engine, td, component);

    if (compiler.isError()) {
        d->errors = compiler.errors();
        td->release();
        component->release();
        return false;
    }

    for (int i = 0; i < td->data.imports().size(); ++i) {
        QDeclarativeScriptParser::Import parserImport = td->data.imports().at(i);
        QDeclarativeDomImport domImport;
        domImport.d->type = static_cast<QDeclarativeDomImportPrivate::Type>(parserImport.type);
        domImport.d->uri = parserImport.uri;
        domImport.d->qualifier = parserImport.qualifier;
        domImport.d->version = parserImport.version;
        d->imports += domImport;
    }

    if (td->data.tree()) {
        d->root = td->data.tree();
        d->root->addref();
    }

    component->release();
    return true;
}
示例#10
0
/*!
    Loads a QDeclarativeDomDocument from \a data.  \a data should be valid QML
    data.  On success, true is returned.  If the \a data is malformed, false
    is returned and QDeclarativeDomDocument::errors() contains an error description.

    \sa QDeclarativeDomDocument::loadError()
*/
bool QDeclarativeDomDocument::load(QDeclarativeEngine *engine, const QByteArray &data, const QUrl &url)
{
    d->errors.clear();
    d->imports.clear();

    QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(engine);
    QDeclarativeTypeData *td = ep->typeLoader.get(data, url, QDeclarativeTypeLoader::PreserveParser);

    if(td->isError()) {
        d->errors = td->errors();
        td->release();
        return false;
    } else if(!td->isCompleteOrError()) {
        QDeclarativeError error;
        error.setDescription(QLatin1String("QDeclarativeDomDocument supports local types only"));
        d->errors << error;
        td->release();
        return false;
    }

    for (int i = 0; i < td->parser().imports().size(); ++i) {
        QDeclarativeScriptParser::Import parserImport = td->parser().imports().at(i);
        QDeclarativeDomImport domImport;
        domImport.d->type = static_cast<QDeclarativeDomImportPrivate::Type>(parserImport.type);
        domImport.d->uri = parserImport.uri;
        domImport.d->qualifier = parserImport.qualifier;
        domImport.d->version = parserImport.version;
        d->imports += domImport;
    }

    if (td->parser().tree()) {
        d->root = td->parser().tree();
        d->root->addref();
    }

    td->release();
    return true;
}
示例#11
0
bool QDeclarativeScriptParser::parse(const QByteArray &qmldata, const QUrl &url)
{
    clear();

    const QString fileName = url.toString();
    _scriptFile = fileName;

    QTextStream stream(qmldata, QIODevice::ReadOnly);
#ifndef QT_NO_TEXTCODEC
    stream.setCodec("UTF-8");
#endif
    const QString code = stream.readAll();

    data = new QDeclarativeScriptParserJsASTData(fileName);

    Lexer lexer(&data->engine);
    lexer.setCode(code, /*line = */ 1);

    Parser parser(&data->engine);

    if (! parser.parse() || !_errors.isEmpty()) {

        // Extract errors from the parser
        foreach (const DiagnosticMessage &m, parser.diagnosticMessages()) {

            if (m.isWarning())
                continue;

            QDeclarativeError error;
            error.setUrl(url);
            error.setDescription(m.message);
            error.setLine(m.loc.startLine);
            error.setColumn(m.loc.startColumn);
            _errors << error;

        }
    }
QDebug operator<<(QDebug debug, const QDeclarativeError &error)
{
    debug << error.toString().toUtf8().constData();

    QUrl url = error.url();

    if (error.line() > 0 && url.scheme() == QLatin1String("file")) {
        QString file = url.toLocalFile();
        QFile f(file);
        if (f.open(QIODevice::ReadOnly)) {
            QByteArray data = f.readAll();
            QTextStream stream(data, QIODevice::ReadOnly);
#ifndef QT_NO_TEXTCODEC
            stream.setCodec("UTF-8");
#endif
            const QString code = stream.readAll();
            const QStringList lines = code.split(QLatin1Char('\n'));

            if (lines.count() >= error.line()) {
                const QString &line = lines.at(error.line() - 1);
                debug << "\n    " << qPrintable(line);

                if(error.column() > 0) {
                    int column = qMax(0, error.column() - 1);
                    column = qMin(column, line.length());

                    QByteArray ind;
                    ind.reserve(column);
                    for (int i = 0; i < column; ++i) {
                        const QChar ch = line.at(i);
                        if (ch.isSpace())
                            ind.append(ch.unicode());
                        else
                            ind.append(' ');
                    }
                    ind.append('^');
                    debug << "\n    " << ind.constData();
                }
            }
        }
    }
    return debug;
}
void tst_qdeclarativeerror::url()
{
    QDeclarativeError error;

    QCOMPARE(error.url(), QUrl());

    error.setUrl(QUrl("http://www.nokia.com/main.qml"));

    QCOMPARE(error.url(), QUrl("http://www.nokia.com/main.qml"));

    QDeclarativeError error2 = error;

    QCOMPARE(error2.url(), QUrl("http://www.nokia.com/main.qml"));

    error.setUrl(QUrl("http://qt.nokia.com/main.qml"));

    QCOMPARE(error.url(), QUrl("http://qt.nokia.com/main.qml"));
    QCOMPARE(error2.url(), QUrl("http://www.nokia.com/main.qml"));
}
示例#14
0
void tst_qdeclarativeerror::line()
{
    QDeclarativeError error;

    QCOMPARE(error.line(), -1);

    error.setLine(102);

    QCOMPARE(error.line(), 102);

    QDeclarativeError error2 = error;

    QCOMPARE(error2.line(), 102);

    error.setLine(4);

    QCOMPARE(error.line(), 4);
    QCOMPARE(error2.line(), 102);
}
示例#15
0
void tst_qdeclarativeerror::description()
{
    QDeclarativeError error;

    QCOMPARE(error.description(), QString());

    error.setDescription("An Error");

    QCOMPARE(error.description(), QString("An Error"));

    QDeclarativeError error2 = error;

    QCOMPARE(error2.description(), QString("An Error"));

    error.setDescription("Another Error");

    QCOMPARE(error.description(), QString("Another Error"));
    QCOMPARE(error2.description(), QString("An Error"));
}
示例#16
0
void tst_qdeclarativeerror::url()
{
    QDeclarativeError error;

    QCOMPARE(error.url(), QUrl());

    error.setUrl(QUrl("http://www.qt-project.org/main.qml"));

    QCOMPARE(error.url(), QUrl("http://www.qt-project.org/main.qml"));

    QDeclarativeError error2 = error;

    QCOMPARE(error2.url(), QUrl("http://www.qt-project.org/main.qml"));

    error.setUrl(QUrl("http://www.qt-project.org/main.qml"));

    QCOMPARE(error.url(), QUrl("http://www.qt-project.org/main.qml"));
    QCOMPARE(error2.url(), QUrl("http://www.qt-project.org/main.qml"));
}
示例#17
0
void tst_qdeclarativeerror::column()
{
    QDeclarativeError error;

    QCOMPARE(error.column(), -1);

    error.setColumn(16);

    QCOMPARE(error.column(), 16);

    QDeclarativeError error2 = error;

    QCOMPARE(error2.column(), 16);

    error.setColumn(3);

    QCOMPARE(error.column(), 3);
    QCOMPARE(error2.column(), 16);
}
示例#18
0
void tst_qdeclarativeerror::debug()
{
    {
        QDeclarativeError error;
        error.setUrl(QUrl("http://www.qt-project.org/main.qml"));
        error.setDescription("An Error");
        error.setLine(92);
        error.setColumn(13);

        QTest::ignoreMessage(QtWarningMsg, "http://www.qt-project.org/main.qml:92:13: An Error ");
        qWarning() << error;
    }

    {
        QUrl url(QUrl::fromLocalFile(QString(SRCDIR) + "/").resolved(QUrl("test.txt")));
        QDeclarativeError error;
        error.setUrl(url);
        error.setDescription("An Error");
        error.setLine(2);
        error.setColumn(5);

        QString out = url.toString() + ":2:5: An Error \n     Line2 Content \n         ^ ";
        QTest::ignoreMessage(QtWarningMsg, qPrintable(out));

        qWarning() << error;
    }

    {
        QUrl url(QUrl::fromLocalFile(QString(SRCDIR) + "/").resolved(QUrl("foo.txt")));
        QDeclarativeError error;
        error.setUrl(url);
        error.setDescription("An Error");
        error.setLine(2);
        error.setColumn(5);

        QString out = url.toString() + ":2:5: An Error ";
        QTest::ignoreMessage(QtWarningMsg, qPrintable(out));

        qWarning() << error;
    }
}
示例#19
0
void tst_qdeclarativeerror::copy()
{
    QDeclarativeError error;
    error.setUrl(QUrl("http://www.qt-project.org/main.qml"));
    error.setDescription("An Error");
    error.setLine(92);
    error.setColumn(13);

    QDeclarativeError error2(error);
    QDeclarativeError error3;
    error3 = error;

    error.setUrl(QUrl("http://www.qt-project.org/main.qml"));
    error.setDescription("Another Error");
    error.setLine(2);
    error.setColumn(33);

    QCOMPARE(error.url(), QUrl("http://www.qt-project.org/main.qml"));
    QCOMPARE(error.description(), QString("Another Error"));
    QCOMPARE(error.line(), 2);
    QCOMPARE(error.column(), 33);

    QCOMPARE(error2.url(), QUrl("http://www.qt-project.org/main.qml"));
    QCOMPARE(error2.description(), QString("An Error"));
    QCOMPARE(error2.line(), 92);
    QCOMPARE(error2.column(), 13);

    QCOMPARE(error3.url(), QUrl("http://www.qt-project.org/main.qml"));
    QCOMPARE(error3.description(), QString("An Error"));
    QCOMPARE(error3.line(), 92);
    QCOMPARE(error3.column(), 13);

}
示例#20
0
void tst_qdeclarativeerror::toString()
{
    {
        QDeclarativeError error;
        error.setUrl(QUrl("http://www.qt-project.org/main.qml"));
        error.setDescription("An Error");
        error.setLine(92);
        error.setColumn(13);

        QCOMPARE(error.toString(), QString("http://www.qt-project.org/main.qml:92:13: An Error"));
    }

    {
        QDeclarativeError error;
        error.setUrl(QUrl("http://www.qt-project.org/main.qml"));
        error.setDescription("An Error");
        error.setLine(92);

        QCOMPARE(error.toString(), QString("http://www.qt-project.org/main.qml:92: An Error"));
    }
}
bool QDeclarativeImportsPrivate::importExtension(const QString &absoluteFilePath, const QString &uri, 
                                                 QDeclarativeImportDatabase *database, 
                                                 QDeclarativeDirComponents* components, QList<QDeclarativeError> *errors)
{
    QFile file(absoluteFilePath);
    QString filecontent;
    if (!QDeclarative_isFileCaseCorrect(absoluteFilePath)) {
        if (errors) {
            QDeclarativeError error;
            error.setDescription(QDeclarativeImportDatabase::tr("cannot load module \"%1\": File name case mismatch for \"%2\"").arg(uri).arg(absoluteFilePath));
            errors->prepend(error);
        }
        return false;
    } else if (file.open(QFile::ReadOnly)) {
        filecontent = QString::fromUtf8(file.readAll());
        if (qmlImportTrace())
            qDebug().nospace() << "QDeclarativeImports(" << qPrintable(base.toString()) << "::importExtension: "
                               << "loaded " << absoluteFilePath;
    } else {
        if (errors) {
            QDeclarativeError error;
            error.setDescription(QDeclarativeImportDatabase::tr("module \"%1\" definition \"%2\" not readable").arg(uri).arg(absoluteFilePath));
            errors->prepend(error);
        }
        return false;
    }
    QDir dir = QFileInfo(file).dir();
    QUrl url = QUrl::fromLocalFile(absoluteFilePath);

    QDeclarativeDirParser qmldirParser;
    qmldirParser.setSource(filecontent);
    qmldirParser.setUrl(url);

    // propagate any errors reported by the parser back up to the typeloader.
    if (qmldirParser.parse()) {
        if (errors) {
            for (int i = 0; i < qmldirParser.errors().size(); ++i) {
                errors->prepend(qmldirParser.errors().at(i));
            }
        }
        return false;
    }

    if (! qmlDirFilesForWhichPluginsHaveBeenLoaded.contains(absoluteFilePath)) {
        qmlDirFilesForWhichPluginsHaveBeenLoaded.insert(absoluteFilePath);


        foreach (const QDeclarativeDirParser::Plugin &plugin, qmldirParser.plugins()) {

            QString resolvedFilePath = database->resolvePlugin(dir, plugin.path, plugin.name);
#if defined(QT_LIBINFIX) && defined(Q_OS_SYMBIAN)
            if (resolvedFilePath.isEmpty()) {
                // In case of libinfixed build, attempt to load libinfixed version, too.
                QString infixedPluginName = plugin.name + QLatin1String(QT_LIBINFIX);
                resolvedFilePath = database->resolvePlugin(dir, plugin.path, infixedPluginName);
            }
#endif
            if (!resolvedFilePath.isEmpty()) {
                if (!database->importPlugin(resolvedFilePath, uri, errors)) {
                    if (errors) {
                        // XXX TODO: should we leave the import plugin error alone?
                        // Here, we pop it off the top and coalesce it into this error's message.
                        // The reason is that the lower level may add url and line/column numbering information.
                        QDeclarativeError poppedError = errors->takeFirst();
                        QDeclarativeError error;
                        error.setDescription(QDeclarativeImportDatabase::tr("plugin cannot be loaded for module \"%1\": %2").arg(uri).arg(poppedError.description()));
                        error.setUrl(url);
                        errors->prepend(error);
                    }
                    return false;
                }
            } else {
                if (errors) {
                    QDeclarativeError error;
                    error.setDescription(QDeclarativeImportDatabase::tr("module \"%1\" plugin \"%2\" not found").arg(uri).arg(plugin.name));
                    error.setUrl(url);
                    errors->prepend(error);
                }
                return false;
            }
        }
    }
bool QDeclarativeDirParser::parse()
{
    if (_isParsed)
        return true;

    _isParsed = true;
    _errors.clear();
    _plugins.clear();
    _components.clear();

    if (_source.isEmpty() && !_filePathSouce.isEmpty()) {
        QFile file(_filePathSouce);
        if (!QDeclarative_isFileCaseCorrect(_filePathSouce)) {
            QDeclarativeError error;
            error.setDescription(QString::fromUtf8("cannot load module \"$$URI$$\": File name case mismatch for \"%1\"").arg(_filePathSouce));
            _errors.prepend(error);
            return false;
        } else if (file.open(QFile::ReadOnly)) {
            _source = QString::fromUtf8(file.readAll());
        } else {
            QDeclarativeError error;
            error.setDescription(QString::fromUtf8("module \"$$URI$$\" definition \"%1\" not readable").arg(_filePathSouce));
            _errors.prepend(error);
            return false;
        }
    }

    QTextStream stream(&_source);
    int lineNumber = 0;

    forever {
        ++lineNumber;

        const QString line = stream.readLine();
        if (line.isNull())
            break;

        QString sections[3];
        int sectionCount = 0;

        int index = 0;
        const int length = line.length();

        while (index != length) {
            const QChar ch = line.at(index);

            if (ch.isSpace()) {
                do { ++index; }
                while (index != length && line.at(index).isSpace());

            } else if (ch == QLatin1Char('#')) {
                // recognized a comment
                break;

            } else {
                const int start = index;

                do { ++index; }
                while (index != length && !line.at(index).isSpace());

                const QString lexeme = line.mid(start, index - start);

                if (sectionCount >= 3) {
                    reportError(lineNumber, start, QLatin1String("unexpected token"));

                } else {
                    sections[sectionCount++] = lexeme;
                }
            }
        }

        if (sectionCount == 0) {
            continue; // no sections, no party.

        } else if (sections[0] == QLatin1String("plugin")) {
            if (sectionCount < 2) {
                reportError(lineNumber, -1,
                            QString::fromUtf8("plugin directive requires 2 arguments, but %1 were provided").arg(sectionCount + 1));

                continue;
            }

            const Plugin entry(sections[1], sections[2]);

            _plugins.append(entry);

        } else if (sections[0] == QLatin1String("internal")) {
            if (sectionCount != 3) {
                reportError(lineNumber, -1,
                            QString::fromUtf8("internal types require 2 arguments, but %1 were provided").arg(sectionCount + 1));
                continue;
            }
            Component entry(sections[1], sections[2], -1, -1);
            entry.internal = true;
            _components.append(entry);
        } else if (sections[0] == QLatin1String("typeinfo")) {
            if (sectionCount != 2) {
                reportError(lineNumber, -1,
                            QString::fromUtf8("typeinfo requires 1 argument, but %1 were provided").arg(sectionCount - 1));
                continue;
            }
#ifdef QT_CREATOR
            TypeInfo typeInfo(sections[1]);
            _typeInfos.append(typeInfo);
#endif

        } else if (sectionCount == 2) {
            // No version specified (should only be used for relative qmldir files)
            const Component entry(sections[0], sections[1], -1, -1);
            _components.append(entry);
        } else if (sectionCount == 3) {
            const QString &version = sections[1];
            const int dotIndex = version.indexOf(QLatin1Char('.'));

            if (dotIndex == -1) {
                reportError(lineNumber, -1, QLatin1String("expected '.'"));
            } else if (version.indexOf(QLatin1Char('.'), dotIndex + 1) != -1) {
                reportError(lineNumber, -1, QLatin1String("unexpected '.'"));
            } else {
                bool validVersionNumber = false;
                const int majorVersion = version.left(dotIndex).toInt(&validVersionNumber);

                if (validVersionNumber) {
                    const int minorVersion = version.mid(dotIndex + 1).toInt(&validVersionNumber);

                    if (validVersionNumber) {
                        const Component entry(sections[0], sections[2], majorVersion, minorVersion);

                        _components.append(entry);
                    }
                }
            }
        } else {
            reportError(lineNumber, -1,
                        QString::fromUtf8("a component declaration requires 3 arguments, but %1 were provided").arg(sectionCount + 1));
        }
    }

    return hasError();
}