Esempio n. 1
0
void tst_qqmlerror::copy()
{
    QQmlError error;
    error.setUrl(QUrl("http://www.qt-project.org/main.qml"));
    error.setDescription("An Error");
    error.setLine(92);
    error.setColumn(13);

    QQmlError error2(error);
    QQmlError 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);

}
QV4::ReturnedValue QQmlJavaScriptExpression::qmlBinding(QQmlContextData *ctxt, QObject *qmlScope,
                                                       const QString &code, const QString &filename, quint16 line,
                                                       QV4::PersistentValue *qmlscope)
{
    QQmlEngine *engine = ctxt->engine;
    QQmlEnginePrivate *ep = QQmlEnginePrivate::get(engine);

    QV4::ExecutionEngine *v4 = QV8Engine::getV4(ep->v8engine());
    QV4::ExecutionContext *ctx = v4->currentContext();
    QV4::Scope scope(v4);

    QV4::ScopedObject qmlScopeObject(scope, QV4::QmlContextWrapper::qmlScope(ep->v8engine(), ctxt, qmlScope));
    QV4::Script script(v4, qmlScopeObject, code, filename, line);
    QV4::ScopedValue result(scope);
    script.parse();
    if (!v4->hasException)
        result = script.qmlBinding();
    if (v4->hasException) {
        QQmlError error = QV4::ExecutionEngine::catchExceptionAsQmlError(ctx);
        if (error.description().isEmpty())
            error.setDescription(QLatin1String("Exception occurred during function evaluation"));
        if (error.line() == -1)
            error.setLine(line);
        if (error.url().isEmpty())
            error.setUrl(QUrl::fromLocalFile(filename));
        error.setObject(qmlScope);
        ep->warning(error);
        return QV4::Encode::undefined();
    }
    if (qmlscope)
        *qmlscope = qmlScopeObject;
    return result.asReturnedValue();
}
/*!
    Reports an error with the given \a description.

    An error is generated referring to the \a location in the source file.
*/
void QQmlCustomParser::error(const QV4::CompiledData::Location &location, const QString &description)
{
    QQmlError error;
    error.setLine(location.line);
    error.setColumn(location.column);
    error.setDescription(description);
    exceptions << error;
}
Esempio n. 4
0
void QmcTypeCompiler::recordError(const QV4::CompiledData::Location& location, const QString& description)
{
    QQmlError error;
    error.setLine(location.line);
    error.setColumn(location.column);
    error.setUrl(compiledData->url);
    error.setDescription(description);
    recordError(error);
}
Esempio n. 5
0
CompiledData::CompilationUnit *Script::precompile(ExecutionEngine *engine, const QUrl &url, const QString &source, QList<QQmlError> *reportedErrors)
{
    using namespace QQmlJS;
    using namespace QQmlJS::AST;

    QQmlJS::V4IR::Module module(engine->debugger != 0);

    QQmlJS::Engine ee;
    QQmlJS::Lexer lexer(&ee);
    lexer.setCode(source, /*line*/1, /*qml mode*/true);
    QQmlJS::Parser parser(&ee);

    parser.parseProgram();

    QList<QQmlError> errors;

    foreach (const QQmlJS::DiagnosticMessage &m, parser.diagnosticMessages()) {
        if (m.isWarning()) {
            qWarning("%s:%d : %s", qPrintable(url.toString()), m.loc.startLine, qPrintable(m.message));
            continue;
        }

        QQmlError error;
        error.setUrl(url);
        error.setDescription(m.message);
        error.setLine(m.loc.startLine);
        error.setColumn(m.loc.startColumn);
        errors << error;
    }

    if (!errors.isEmpty()) {
        if (reportedErrors)
            *reportedErrors << errors;
        return 0;
    }

    Program *program = AST::cast<Program *>(parser.rootNode());
    if (!program) {
        // if parsing was successful, and we have no program, then
        // we're done...:
        return 0;
    }

    QQmlJS::Codegen cg(/*strict mode*/false);
    cg.generateFromProgram(url.toString(), source, program, &module, QQmlJS::Codegen::EvalCode);
    errors = cg.errors();
    if (!errors.isEmpty()) {
        if (reportedErrors)
            *reportedErrors << cg.errors();
        return 0;
    }

    Compiler::JSUnitGenerator jsGenerator(&module);
    QScopedPointer<QQmlJS::EvalInstructionSelection> isel(engine->iselFactory->create(QQmlEnginePrivate::get(engine), engine->executableAllocator, &module, &jsGenerator));
    isel->setUseFastLookups(false);
    return isel->compile();
}
Esempio n. 6
0
void tst_qqmlerror::line()
{
    QQmlError error;

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

    error.setLine(102);

    QCOMPARE(error.line(), 102);

    QQmlError error2 = error;

    QCOMPARE(error2.line(), 102);

    error.setLine(4);

    QCOMPARE(error.line(), 4);
    QCOMPARE(error2.line(), 102);
}
Esempio n. 7
0
void tst_qqmlerror::debug()
{
    {
        QQmlError 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(dataDirectoryUrl().resolved(QUrl("test.txt")));
        QQmlError 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(dataDirectoryUrl().resolved(QUrl("foo.txt")));
        QQmlError 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;
    }
}
// Callee owns the persistent handle
v8::Persistent<v8::Function>
QQmlJavaScriptExpression::evalFunction(QQmlContextData *ctxt, QObject *scope,
                                       const char *code, int codeLength,
                                       const QString &filename, quint16 line,
                                       v8::Persistent<v8::Object> *qmlscope)
{
    QQmlEngine *engine = ctxt->engine;
    QQmlEnginePrivate *ep = QQmlEnginePrivate::get(engine);

    v8::HandleScope handle_scope;
    v8::Context::Scope ctxtscope(ep->v8engine()->context());

    v8::TryCatch tc;
    v8::Local<v8::Object> scopeobject = ep->v8engine()->qmlScope(ctxt, scope);
    v8::Local<v8::Script> script = ep->v8engine()->qmlModeCompile(code, codeLength, filename, line);
    if (tc.HasCaught()) {
        QQmlError error;
        error.setDescription(QLatin1String("Exception occurred during function compilation"));
        error.setLine(line);
        error.setUrl(QUrl::fromLocalFile(filename));
        v8::Local<v8::Message> message = tc.Message();
        if (!message.IsEmpty())
            QQmlExpressionPrivate::exceptionToError(message, error);
        ep->warning(error);
        return v8::Persistent<v8::Function>();
    }
    v8::Local<v8::Value> result = script->Run(scopeobject);
    if (tc.HasCaught()) {
        QQmlError error;
        error.setDescription(QLatin1String("Exception occurred during function evaluation"));
        error.setLine(line);
        error.setUrl(QUrl::fromLocalFile(filename));
        v8::Local<v8::Message> message = tc.Message();
        if (!message.IsEmpty())
            QQmlExpressionPrivate::exceptionToError(message, error);
        ep->warning(error);
        return v8::Persistent<v8::Function>();
    }
    if (qmlscope) *qmlscope = qPersistentNew<v8::Object>(scopeobject);
    return qPersistentNew<v8::Function>(v8::Local<v8::Function>::Cast(result));
}
Esempio n. 9
0
void tst_qqmlerror::toString()
{
    {
        QQmlError 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"));
    }

    {
        QQmlError 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"));
    }
}
Esempio n. 10
0
QList<QQmlError> QQmlDirParser::errors(const QString &uri) const
{
    QUrl url(uri);
    QList<QQmlError> errors;
    for (int i = 0; i < _errors.size(); ++i) {
        const QQmlJS::DiagnosticMessage &msg = _errors.at(i);
        QQmlError e;
        QString description = msg.message;
        description.replace(QLatin1String("$$URI$$"), uri);
        e.setDescription(description);
        e.setUrl(url);
        e.setLine(msg.loc.startLine);
        e.setColumn(msg.loc.startColumn);
        errors << e;
    }
    return errors;
}
void QQmlJavaScriptExpression::exceptionToError(v8::Handle<v8::Message> message, QQmlError &error)
{
    Q_ASSERT(!message.IsEmpty());

    v8::Handle<v8::Value> name = message->GetScriptResourceName();
    v8::Handle<v8::String> description = message->Get();
    int lineNumber = message->GetLineNumber();

    v8::Local<v8::String> file = name->IsString()?name->ToString():v8::Local<v8::String>();
    if (file.IsEmpty() || file->Length() == 0)
        error.setUrl(QUrl());
    else
        error.setUrl(QUrl(QV8Engine::toStringStatic(file)));

    error.setLine(lineNumber);
    error.setColumn(-1);

    QString qDescription = QV8Engine::toStringStatic(description);
    if (qDescription.startsWith(QLatin1String("Uncaught ")))
        qDescription = qDescription.mid(9 /* strlen("Uncaught ") */);

    error.setDescription(qDescription);
}
Esempio n. 12
0
bool QmcTypeCompiler::createTypeMap()
{
    // qqmltypecompiler.cpp:81
    const QHash<int, QmlCompilation::TypeReference> &resolvedTypes = compilation->typeReferences;
    for (QHash<int, QmlCompilation::TypeReference>::ConstIterator resolvedType = resolvedTypes.constBegin(), end = resolvedTypes.constEnd();
         resolvedType != end; ++resolvedType) {
        QScopedPointer<QQmlCompiledData::TypeReference> ref(new QQmlCompiledData::TypeReference);
        QQmlType *qmlType = resolvedType->type;
        if (resolvedType.value().composite) {
            // qqmltypecompiler.cpp:87
            if (resolvedType->needsCreation && qmlType->isCompositeSingleton()) {
                QQmlError error;
                QString reason = tr("Composite Singleton Type %1 is not creatable.").arg(qmlType->qmlTypeName());
                error.setDescription(reason);
                error.setColumn(resolvedType->location.column);
                error.setLine(resolvedType->location.line);
                recordError(error);
                return false;
            }
            // qqmltypecompiler.cpp:96
            Q_ASSERT(resolvedType->component);
            Q_ASSERT(resolvedType->component->compiledData);
            ref->component = resolvedType->component->compiledData;
            ref->component->addref();
        } else if (qmlType) {
            ref->type = qmlType;
            Q_ASSERT(ref->type);

            if (resolvedType->needsCreation && !ref->type->isCreatable()) {
                QQmlError error;
                QString reason = ref->type->noCreationReason();
                if (reason.isEmpty())
                    reason = tr("Element is not creatable.");
                error.setDescription(reason);
                error.setColumn(resolvedType->location.column);
                error.setLine(resolvedType->location.line);
                error.setUrl(compilation->url);
                recordError(error);
                return false;
            }

            if (ref->type->containsRevisionedAttributes()) {
                QQmlError cacheError;
                ref->typePropertyCache = QQmlEnginePrivate::get(compilation->engine)->cache(
                                                        ref->type,
                                                        resolvedType->minorVersion,
                                                        cacheError);
                if (!ref->typePropertyCache) {
                    cacheError.setColumn(resolvedType->location.column);
                    cacheError.setLine(resolvedType->location.line);
                    recordError(cacheError);
                    return false;
                }
                ref->typePropertyCache->addref();
            }
        }
        ref->majorVersion = resolvedType->majorVersion;
        ref->minorVersion = resolvedType->minorVersion;
        ref->doDynamicTypeCheck();
        compiledData->resolvedTypes.insert(resolvedType.key(), ref.take());
    }
    return true;
}
Esempio n. 13
0
QQmlInfo::~QQmlInfo()
{
    if (0 == --d->ref) {
        QList<QQmlError> errors = d->errors;

        QQmlEngine *engine = 0;

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

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

            if (object) {
                engine = qmlEngine(d->object);
                QString typeName;
                QQmlType *type = QQmlMetaType::qmlType(object->metaObject());
                if (type) {
                    typeName = 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);
                        typeName += QLatin1Char('*');
                        type = QQmlMetaType::qmlType(QMetaType::type(typeName.toLatin1()));
                        if (type) {
                            typeName = type->qmlTypeName();
                            int lastSlash = typeName.lastIndexOf(QLatin1Char('/'));
                            if (lastSlash != -1)
                                typeName = typeName.mid(lastSlash+1);
                        }
                    }
                }

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

                QQmlData *ddata = QQmlData::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);
        }

        QQmlEnginePrivate::warning(engine, errors);

        delete d;
    }
}
Esempio n. 14
0
bool Compiler::addImport(const QV4::CompiledData::Import *import, QList<QQmlError> *errors)
{
    Q_D(Compiler);
    const QString &importUri = stringAt(import->uriIndex);
    const QString &importQualifier = stringAt(import->qualifierIndex);

    if (import->type == QV4::CompiledData::Import::ImportScript) {
        // TBD: qqmltypeloader.cpp:1320
        QmlCompilation::ScriptReference scriptRef;
        scriptRef.location = import->location;
        scriptRef.qualifier = importQualifier;
        scriptRef.compilation = NULL;
        d->compilation->scripts.append(scriptRef);
    } else if (import->type == QV4::CompiledData::Import::ImportLibrary) {
        QString qmldirFilePath;
        QString qmldirUrl;
        if (QQmlMetaType::isLockedModule(importUri, import->majorVersion)) {
            //Locked modules are checked first, to save on filesystem checks
            if (!d->compilation->importCache->addLibraryImport(d->compilation->importDatabase, importUri, importQualifier, import->majorVersion,
                                          import->minorVersion, QString(), QString(), false, errors))
                return false;

        } else if (d->compilation->importCache->locateQmldir(d->compilation->importDatabase, importUri, import->majorVersion, import->minorVersion,
                                 &qmldirFilePath, &qmldirUrl)) {
            // This is a local library import
            if (!d->compilation->importCache->addLibraryImport(d->compilation->importDatabase, importUri, importQualifier, import->majorVersion,
                                          import->minorVersion, qmldirFilePath, qmldirUrl, false, errors))
                return false;

            if (!importQualifier.isEmpty()) {
                // Does this library contain any qualified scripts?
                QUrl libraryUrl(qmldirUrl);
                QQmlTypeLoader* typeLoader = &QQmlEnginePrivate::get(d->compilation->engine)->typeLoader;
                const QQmlTypeLoader::QmldirContent *qmldir = typeLoader->qmldirContent(qmldirFilePath, qmldirUrl);
                // File loading will import the dependency and takes care of
                // everything there. Adding a script reference here just seems
                // to add an unnecessary reference that might actually be a bug.
                // In case something is needed, see: qqmltypeloader.cpp:1343
            }
        } else {
            // Is this a module?
            qDebug() << "Importing local module" << importUri;
            if (QQmlMetaType::isAnyModule(importUri)) {
                if (!d->compilation->importCache->addLibraryImport(d->compilation->importDatabase, importUri, importQualifier, import->majorVersion,
                                              import->minorVersion, QString(), QString(), false, errors))
                    return false;
            } else {
                QQmlError error;
                error.setDescription("Unresolved import " + importUri);
                error.setLine(import->location.line);
                error.setColumn(import->location.column);
                error.setUrl(d->compilation->url);
                appendError(error);
                return false;
                // TBD: else add to unresolved imports qqmltypeloader.cpp:1356
            }
        }
    } else {
        // qqmltypeloader.cpp:1383
        Q_ASSERT(import->type == QV4::CompiledData::Import::ImportFile);

        QUrl qmldirUrl;
        if (importQualifier.isEmpty()) {
            qmldirUrl = compilation()->loadUrl.resolved(QUrl(importUri + QLatin1String("/qmldir")));
            if (!QQmlImports::isLocal(qmldirUrl)) {
                qDebug() << "File import from network not supported";
                QQmlError error;
                error.setDescription("File import from network not supported");
                errors->append(error);
                return false;
            }
        }

        if (!compilation()->importCache->addFileImport(compilation()->importDatabase, importUri, importQualifier, import->majorVersion,
                                   import->minorVersion, /*incomplete*/ false, errors))
            return false;
    }
    return true;
}