forked from qt-creator/qt-creator
QmlJS: Output qmltypes parse warnings to General messages pane.
Change-Id: I8ca100ef141082c7606bb98f8a2f81502b14e1af Reviewed-on: http://codereview.qt.nokia.com/204 Reviewed-by: Kai Koehne <kai.koehne@nokia.com>
This commit is contained in:
committed by
Kai Koehne
parent
ec97fc95a0
commit
f0a4e7e225
@@ -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);
|
||||
}
|
||||
|
||||
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,12 +190,12 @@ void PluginDumper::qmlPluginTypeDumpDone(int exitCode)
|
||||
|
||||
const QByteArray output = process->readAllStandardOutput();
|
||||
QString error;
|
||||
QList<FakeMetaObject::ConstPtr> objectsList = parseHelper(output, &error);
|
||||
if (exitCode == 0 && !error.isEmpty()) {
|
||||
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));
|
||||
}
|
||||
|
||||
if (exitCode == 0 && error.isEmpty()) {
|
||||
} else {
|
||||
libraryInfo.setMetaObjects(objectsList);
|
||||
// ### disabled code path for running qmldump to get Qt's builtins
|
||||
// if (libraryPath.isEmpty())
|
||||
@@ -192,6 +203,10 @@ void PluginDumper::qmlPluginTypeDumpDone(int exitCode)
|
||||
libraryInfo.setPluginTypeInfoStatus(LibraryInfo::DumpDone);
|
||||
}
|
||||
|
||||
if (!warning.isEmpty())
|
||||
printParseWarnings(libraryPath, warning);
|
||||
}
|
||||
|
||||
if (!libraryPath.isEmpty())
|
||||
m_modelManager->updateLibraryInfo(libraryPath, libraryInfo);
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
Reference in New Issue
Block a user