Commit f0a4e7e2 authored by Christian Kamm's avatar Christian Kamm Committed by Kai Koehne
Browse files

QmlJS: Output qmltypes parse warnings to General messages pane.

Change-Id: I8ca100ef141082c7606bb98f8a2f81502b14e1af
Reviewed-on: http://codereview.qt.nokia.com/204

Reviewed-by: default avatarKai Koehne <kai.koehne@nokia.com>
parent ec97fc95
......@@ -40,6 +40,7 @@
#include "parser/qmljsast_p.h"
#include <languageutils/fakemetaobject.h>
#include <coreplugin/messagemanager.h>
#include <QtCore/QFile>
#include <QtCore/QDir>
......@@ -1580,31 +1581,38 @@ const Value *Function::invoke(const Activation *activation) const
QHash<QString, FakeMetaObject::ConstPtr> CppQmlTypesLoader::builtinObjects;
QHash<QString, QList<LanguageUtils::ComponentVersion> > CppQmlTypesLoader::builtinPackages;
QStringList CppQmlTypesLoader::loadQmlTypes(const QFileInfoList &qmlTypeFiles)
void CppQmlTypesLoader::loadQmlTypes(const QFileInfoList &qmlTypeFiles)
{
QHash<QString, FakeMetaObject::ConstPtr> newObjects;
QStringList errorMsgs;
Core::MessageManager *messageManager = Core::MessageManager::instance();
foreach (const QFileInfo &qmlTypeFile, qmlTypeFiles) {
QString error, warning;
QFile file(qmlTypeFile.absoluteFilePath());
if (file.open(QIODevice::ReadOnly)) {
QString contents = QString::fromUtf8(file.readAll());
file.close();
QmlJS::TypeDescriptionReader reader(contents);
if (!reader(&newObjects)) {
errorMsgs.append(reader.errorMessage());
}
if (!reader(&newObjects))
error = reader.errorMessage();
warning = reader.warningMessage();
} else {
errorMsgs.append(QmlJS::TypeDescriptionReader::tr("%1: %2")
.arg(qmlTypeFile.absoluteFilePath(),
file.errorString()));
error = file.errorString();
}
if (!error.isEmpty()) {
messageManager->printToOutputPane(
TypeDescriptionReader::tr("Errors while loading qmltypes from %1:\n%2").arg(
qmlTypeFile.absoluteFilePath(), error));
}
if (!warning.isEmpty()) {
messageManager->printToOutputPane(
TypeDescriptionReader::tr("Warnings while loading qmltypes from %1:\n%2").arg(
qmlTypeFile.absoluteFilePath(), warning));
}
}
if (errorMsgs.isEmpty()) {
builtinObjects.unite(newObjects);
}
builtinObjects.unite(newObjects);
QHash<QString, LanguageUtils::FakeMetaObject::ConstPtr>::const_iterator iter
= builtinObjects.constBegin();
......@@ -1617,18 +1625,24 @@ QStringList CppQmlTypesLoader::loadQmlTypes(const QFileInfoList &qmlTypeFiles)
}
}
}
return errorMsgs;
}
QString CppQmlTypesLoader::parseQmlTypeDescriptions(const QByteArray &xml, QHash<QString, FakeMetaObject::ConstPtr> *newObjects)
void CppQmlTypesLoader::parseQmlTypeDescriptions(const QByteArray &xml,
QHash<QString, FakeMetaObject::ConstPtr> *newObjects,
QString *errorMessage,
QString *warningMessage)
{
errorMessage->clear();
warningMessage->clear();
QmlJS::TypeDescriptionReader reader(QString::fromUtf8(xml));
if (!reader(newObjects)) {
if (reader.errorMessage().isEmpty())
return QLatin1String("unknown error");
return reader.errorMessage();
if (reader.errorMessage().isEmpty()) {
*errorMessage = QLatin1String("unknown error");
} else {
*errorMessage = reader.errorMessage();
}
}
return QString();
*warningMessage = reader.warningMessage();
}
const QLatin1String CppQmlTypes::defaultPackage("<default>");
......
......@@ -614,15 +614,19 @@ private:
class QMLJS_EXPORT CppQmlTypesLoader
{
public:
/** \return an empty list when successful, error messages otherwise. */
static QStringList loadQmlTypes(const QFileInfoList &xmlFiles);
/** Loads a set of qmltypes files into the builtin objects list
and prints any errors to the General Messages pane
*/
static void loadQmlTypes(const QFileInfoList &qmltypesFiles);
static QHash<QString, LanguageUtils::FakeMetaObject::ConstPtr> builtinObjects;
static QHash<QString, QList<LanguageUtils::ComponentVersion> > builtinPackages;
// parses the xml string and fills the newObjects map
static QString parseQmlTypeDescriptions(const QByteArray &xml,
QHash<QString, LanguageUtils::FakeMetaObject::ConstPtr> *newObjects);
// parses the contents of a qmltypes file and fills the newObjects map
static void parseQmlTypeDescriptions(
const QByteArray &qmlTypes,
QHash<QString, LanguageUtils::FakeMetaObject::ConstPtr> *newObjects,
QString *errorMessage, QString *warningMessage);
};
class QMLJS_EXPORT CppQmlTypes
......
......@@ -89,6 +89,11 @@ QString TypeDescriptionReader::errorMessage() const
return _errorMessage;
}
QString TypeDescriptionReader::warningMessage() const
{
return _warningMessage;
}
void TypeDescriptionReader::readDocument(UiProgram *ast)
{
if (!ast) {
......@@ -144,7 +149,7 @@ void TypeDescriptionReader::readModule(UiObjectDefinition *ast)
UiObjectMember *member = it->member;
UiObjectDefinition *component = dynamic_cast<UiObjectDefinition *>(member);
if (!component || Bind::toString(component->qualifiedTypeNameId) != "Component") {
//addError(member->firstSourceLocation(), "Expected only 'Component' object definitions");
addWarning(member->firstSourceLocation(), "Expected only 'Component' object definitions");
continue;
}
......@@ -160,6 +165,14 @@ void TypeDescriptionReader::addError(const SourceLocation &loc, const QString &m
message);
}
void TypeDescriptionReader::addWarning(const SourceLocation &loc, const QString &message)
{
_warningMessage += QString("%1:%2: %3\n").arg(
QString::number(loc.startLine),
QString::number(loc.startColumn),
message);
}
void TypeDescriptionReader::readComponent(UiObjectDefinition *ast)
{
FakeMetaObject::Ptr fmo(new FakeMetaObject);
......@@ -177,7 +190,7 @@ void TypeDescriptionReader::readComponent(UiObjectDefinition *ast)
} else if (name == "Enum") {
readEnum(component, fmo);
} else {
//addError(component->firstSourceLocation(), "Expected only Property, Method, Signal and Enum object definitions");
addWarning(component->firstSourceLocation(), "Expected only Property, Method, Signal and Enum object definitions");
}
} else if (script) {
QString name = Bind::toString(script->qualifiedId);
......@@ -192,10 +205,10 @@ void TypeDescriptionReader::readComponent(UiObjectDefinition *ast)
} else if (name == "attachedType") {
fmo->setAttachedTypeName(readStringBinding(script));
} else {
//addError(script->firstSourceLocation(), "Expected only name, prototype, defaultProperty, attachedType and exports script bindings");
addWarning(script->firstSourceLocation(), "Expected only name, prototype, defaultProperty, attachedType and exports script bindings");
}
} else {
//addError(member->firstSourceLocation(), "Expected only script bindings and object definitions");
addWarning(member->firstSourceLocation(), "Expected only script bindings and object definitions");
}
}
......@@ -227,7 +240,7 @@ void TypeDescriptionReader::readSignalOrMethod(UiObjectDefinition *ast, bool isM
if (name == "Parameter") {
readParameter(component, &fmm);
} else {
//addError(component->firstSourceLocation(), "Expected only Parameter object definitions");
addWarning(component->firstSourceLocation(), "Expected only Parameter object definitions");
}
} else if (script) {
QString name = Bind::toString(script->qualifiedId);
......@@ -238,11 +251,11 @@ void TypeDescriptionReader::readSignalOrMethod(UiObjectDefinition *ast, bool isM
} else if (name == "revision") {
fmm.setRevision(readIntBinding(script));
} else {
//addError(script->firstSourceLocation(), "Expected only name and type script bindings");
addWarning(script->firstSourceLocation(), "Expected only name and type script bindings");
}
} else {
//addError(member->firstSourceLocation(), "Expected only script bindings and object definitions");
addWarning(member->firstSourceLocation(), "Expected only script bindings and object definitions");
}
}
......@@ -267,7 +280,7 @@ void TypeDescriptionReader::readProperty(UiObjectDefinition *ast, FakeMetaObject
UiObjectMember *member = it->member;
UiScriptBinding *script = dynamic_cast<UiScriptBinding *>(member);
if (!script) {
//addError(member->firstSourceLocation(), "Expected script binding");
addWarning(member->firstSourceLocation(), "Expected script binding");
continue;
}
......@@ -285,7 +298,7 @@ void TypeDescriptionReader::readProperty(UiObjectDefinition *ast, FakeMetaObject
} else if (id == "revision") {
revision = readIntBinding(script);
} else {
//addError(script->firstSourceLocation(), "Expected only type, name, revision, isPointer, isReadonly and isList script bindings");
addWarning(script->firstSourceLocation(), "Expected only type, name, revision, isPointer, isReadonly and isList script bindings");
}
}
......@@ -305,7 +318,7 @@ void TypeDescriptionReader::readEnum(UiObjectDefinition *ast, FakeMetaObject::Pt
UiObjectMember *member = it->member;
UiScriptBinding *script = dynamic_cast<UiScriptBinding *>(member);
if (!script) {
//addError(member->firstSourceLocation(), "Expected script binding");
addWarning(member->firstSourceLocation(), "Expected script binding");
continue;
}
......@@ -315,7 +328,7 @@ void TypeDescriptionReader::readEnum(UiObjectDefinition *ast, FakeMetaObject::Pt
} else if (name == "values") {
readEnumValues(script, &fme);
} else {
//addError(script->firstSourceLocation(), "Expected only name and values script bindings");
addWarning(script->firstSourceLocation(), "Expected only name and values script bindings");
}
}
......@@ -331,7 +344,7 @@ void TypeDescriptionReader::readParameter(UiObjectDefinition *ast, FakeMetaMetho
UiObjectMember *member = it->member;
UiScriptBinding *script = dynamic_cast<UiScriptBinding *>(member);
if (!script) {
//addError(member->firstSourceLocation(), "Expected script binding");
addWarning(member->firstSourceLocation(), "Expected script binding");
continue;
}
......@@ -347,7 +360,7 @@ void TypeDescriptionReader::readParameter(UiObjectDefinition *ast, FakeMetaMetho
} else if (id == "isList") {
// ### unhandled
} else {
//addError(script->firstSourceLocation(), "Expected only name and type script bindings");
addWarning(script->firstSourceLocation(), "Expected only name and type script bindings");
}
}
......
......@@ -64,6 +64,7 @@ public:
bool operator()(QHash<QString, LanguageUtils::FakeMetaObject::ConstPtr> *objects);
QString errorMessage() const;
QString warningMessage() const;
private:
void readDocument(AST::UiProgram *ast);
......@@ -80,10 +81,13 @@ private:
int readIntBinding(AST::UiScriptBinding *ast);
void readExports(AST::UiScriptBinding *ast, LanguageUtils::FakeMetaObject::Ptr fmo);
void readEnumValues(AST::UiScriptBinding *ast, LanguageUtils::FakeMetaEnum *fme);
void addError(const AST::SourceLocation &loc, const QString &message);
void addWarning(const AST::SourceLocation &loc, const QString &message);
QString _source;
QString _errorMessage;
QString _warningMessage;
QHash<QString, LanguageUtils::FakeMetaObject::ConstPtr> *_objects;
};
......
......@@ -118,9 +118,7 @@ void ModelManager::loadQmlTypeDescriptions(const QString &resourcePath)
QDir::Files,
QDir::Name);
const QStringList errors = Interpreter::CppQmlTypesLoader::loadQmlTypes(qmlTypesFiles);
foreach (const QString &error, errors)
qWarning() << qPrintable(error);
Interpreter::CppQmlTypesLoader::loadQmlTypes(qmlTypesFiles);
// disabled for now: Prefer the xml file until the type dumping functionality
// has been moved into Qt.
......
......@@ -147,11 +147,22 @@ static QString qmldumpFailedMessage(const QString &error)
).arg(firstLines);
}
static QList<FakeMetaObject::ConstPtr> parseHelper(const QByteArray &qmlTypeDescriptions, QString *error)
static void printParseWarnings(const QString &libraryPath, const QString &warning)
{
Core::MessageManager *messageManager = Core::MessageManager::instance();
messageManager->printToOutputPane(
PluginDumper::tr("Warnings while parsing qmltypes information of %1:\n"
"%2").arg(libraryPath, warning));
}
static QList<FakeMetaObject::ConstPtr> parseHelper(const QByteArray &qmlTypeDescriptions,
QString *error,
QString *warning)
{
QList<FakeMetaObject::ConstPtr> ret;
QHash<QString, FakeMetaObject::ConstPtr> newObjects;
*error = Interpreter::CppQmlTypesLoader::parseQmlTypeDescriptions(qmlTypeDescriptions, &newObjects);
Interpreter::CppQmlTypesLoader::parseQmlTypeDescriptions(qmlTypeDescriptions, &newObjects,
error, warning);
if (error->isEmpty()) {
ret = newObjects.values();
......@@ -179,17 +190,21 @@ void PluginDumper::qmlPluginTypeDumpDone(int exitCode)
const QByteArray output = process->readAllStandardOutput();
QString error;
QList<FakeMetaObject::ConstPtr> objectsList = parseHelper(output, &error);
if (exitCode == 0 && !error.isEmpty()) {
libraryInfo.setPluginTypeInfoStatus(LibraryInfo::DumpError, tr("Type dump of C++ plugin failed. Parse error:\n'%1'").arg(error));
}
QString warning;
QList<FakeMetaObject::ConstPtr> objectsList = parseHelper(output, &error, &warning);
if (exitCode == 0) {
if (!error.isEmpty()) {
libraryInfo.setPluginTypeInfoStatus(LibraryInfo::DumpError, tr("Type dump of C++ plugin failed. Parse error:\n'%1'").arg(error));
} else {
libraryInfo.setMetaObjects(objectsList);
// ### disabled code path for running qmldump to get Qt's builtins
// if (libraryPath.isEmpty())
// Interpreter::CppQmlTypesLoader::builtinObjects.append(objectsList);
libraryInfo.setPluginTypeInfoStatus(LibraryInfo::DumpDone);
}
if (exitCode == 0 && error.isEmpty()) {
libraryInfo.setMetaObjects(objectsList);
// ### disabled code path for running qmldump to get Qt's builtins
// if (libraryPath.isEmpty())
// Interpreter::CppQmlTypesLoader::builtinObjects.append(objectsList);
libraryInfo.setPluginTypeInfoStatus(LibraryInfo::DumpDone);
if (!warning.isEmpty())
printParseWarnings(libraryPath, warning);
}
if (!libraryPath.isEmpty())
......@@ -244,7 +259,8 @@ void PluginDumper::dump(const Plugin &plugin)
}
QString error;
const QList<FakeMetaObject::ConstPtr> objectsList = parseHelper(reader.data(), &error);
QString warning;
const QList<FakeMetaObject::ConstPtr> objectsList = parseHelper(reader.data(), &error, &warning);
if (error.isEmpty()) {
libraryInfo.setMetaObjects(objectsList);
......@@ -253,6 +269,9 @@ void PluginDumper::dump(const Plugin &plugin)
libraryInfo.setPluginTypeInfoStatus(LibraryInfo::TypeInfoFileError,
tr("Failed to parse '%1'.\nError: %2").arg(path, error));
}
if (!warning.isEmpty())
printParseWarnings(plugin.qmldirPath, warning);
m_modelManager->updateLibraryInfo(plugin.qmldirPath, libraryInfo);
return;
}
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment