QmlJS: Add semantic errors to task window.

Task-number: QTCREATORBUG-4103
Reviewed-by: Leandro Melo
This commit is contained in:
Christian Kamm
2011-04-21 11:09:29 +02:00
parent e21311132b
commit c504d28eb5
11 changed files with 203 additions and 51 deletions

View File

@@ -86,14 +86,16 @@ bool operator==(const ImportCacheKey &i1, const ImportCacheKey &i2)
class QmlJS::LinkPrivate
{
public:
Document::Ptr doc;
Snapshot snapshot;
Interpreter::Context *context;
QStringList importPaths;
QHash<ImportCacheKey, Interpreter::ObjectValue *> importCache;
QList<DiagnosticMessage> diagnosticMessages;
Document::Ptr doc;
QList<DiagnosticMessage> *diagnosticMessages;
QHash<QString, QList<DiagnosticMessage> > *allDiagnosticMessages;
};
/*!
@@ -109,16 +111,42 @@ public:
\l{Context} with \l{Link}.
*/
Link::Link(Context *context, const Document::Ptr &doc, const Snapshot &snapshot,
const QStringList &importPaths)
Link::Link(Context *context, const Snapshot &snapshot, const QStringList &importPaths,
QHash<QString, QList<DiagnosticMessage> > *messages)
: d_ptr(new LinkPrivate)
{
Q_D(Link);
d->context = context;
d->doc = doc;
d->snapshot = snapshot;
d->importPaths = importPaths;
d->diagnosticMessages = 0;
d->allDiagnosticMessages = messages;
// populate engine with types from C++
ModelManagerInterface *modelManager = ModelManagerInterface::instance();
if (modelManager) {
foreach (const QList<FakeMetaObject::ConstPtr> &cppTypes, modelManager->cppQmlTypes()) {
engine()->cppQmlTypes().load(engine(), cppTypes);
}
}
linkImports();
}
Link::Link(Context *context, const Snapshot &snapshot, const QStringList &importPaths,
const Document::Ptr &doc, QList<DiagnosticMessage> *messages)
: d_ptr(new LinkPrivate)
{
Q_D(Link);
d->context = context;
d->snapshot = snapshot;
d->importPaths = importPaths;
d->doc = doc;
d->diagnosticMessages = messages;
d->allDiagnosticMessages = 0;
// populate engine with types from C++
ModelManagerInterface *modelManager = ModelManagerInterface::instance();
if (modelManager) {
@@ -140,20 +168,16 @@ Interpreter::Engine *Link::engine()
return d->context->engine();
}
QList<DiagnosticMessage> Link::diagnosticMessages() const
{
Q_D(const Link);
return d->diagnosticMessages;
}
void Link::linkImports()
{
Q_D(Link);
// do it on d->doc first, to make sure import errors are shown
TypeEnvironment *typeEnv = new TypeEnvironment(engine());
populateImportedTypes(typeEnv, d->doc);
d->context->setTypeEnvironment(d->doc.data(), typeEnv);
if (d->doc) {
// do it on d->doc first, to make sure import errors are shown
TypeEnvironment *typeEnv = new TypeEnvironment(engine());
populateImportedTypes(typeEnv, d->doc);
d->context->setTypeEnvironment(d->doc.data(), typeEnv);
}
foreach (Document::Ptr doc, d->snapshot) {
if (doc == d->doc)
@@ -364,18 +388,22 @@ UiQualifiedId *Link::qualifiedTypeNameId(Node *node)
void Link::error(const Document::Ptr &doc, const AST::SourceLocation &loc, const QString &message)
{
Q_D(Link);
if (doc->fileName() == d->doc->fileName())
d->diagnosticMessages.append(DiagnosticMessage(DiagnosticMessage::Error, loc, message));
appendDiagnostic(doc, DiagnosticMessage(DiagnosticMessage::Error, loc, message));
}
void Link::warning(const Document::Ptr &doc, const AST::SourceLocation &loc, const QString &message)
{
appendDiagnostic(doc, DiagnosticMessage(DiagnosticMessage::Warning, loc, message));
}
void Link::appendDiagnostic(const Document::Ptr &doc, const DiagnosticMessage &message)
{
Q_D(Link);
if (doc->fileName() == d->doc->fileName())
d->diagnosticMessages.append(DiagnosticMessage(DiagnosticMessage::Warning, loc, message));
if (d->diagnosticMessages && doc->fileName() == d->doc->fileName())
d->diagnosticMessages->append(message);
if (d->allDiagnosticMessages)
(*d->allDiagnosticMessages)[doc->fileName()].append(message);
}
void Link::loadQmldirComponents(Interpreter::ObjectValue *import, ComponentVersion version,

View File

@@ -54,12 +54,16 @@ class QMLJS_EXPORT Link
Q_DECLARE_TR_FUNCTIONS(QmlJS::Link)
public:
// Link all documents in snapshot
Link(Interpreter::Context *context, const Document::Ptr &doc, const Snapshot &snapshot,
const QStringList &importPaths);
~Link();
// Link all documents in snapshot, collecting all diagnostic messages
Link(Interpreter::Context *context, const Snapshot &snapshot,
const QStringList &importPaths, QHash<QString, QList<DiagnosticMessage> > *messages = 0);
QList<DiagnosticMessage> diagnosticMessages() const;
// Link all documents in snapshot, appending the diagnostic messages
// for 'doc' in 'messages'
Link(Interpreter::Context *context, const Snapshot &snapshot,
const QStringList &importPaths, const Document::Ptr &doc, QList<DiagnosticMessage> *messages);
~Link();
private:
Interpreter::Engine *engine();
@@ -87,6 +91,7 @@ private:
void error(const Document::Ptr &doc, const AST::SourceLocation &loc, const QString &message);
void warning(const Document::Ptr &doc, const AST::SourceLocation &loc, const QString &message);
void appendDiagnostic(const Document::Ptr &doc, const DiagnosticMessage &message);
private:
QScopedPointer<LinkPrivate> d_ptr;

View File

@@ -47,7 +47,7 @@ public:
snapshot(snapshot)
{
// since we keep the document and snapshot around, we don't need to keep the Link instance
Link link(&context, doc, snapshot, ModelManagerInterface::instance()->importPaths());
Link link(&context, snapshot, ModelManagerInterface::instance()->importPaths());
ScopeBuilder scopeBuilder(&context, doc, snapshot);
scopeBuilder.push(path);

View File

@@ -142,6 +142,7 @@ signals:
void documentChangedOnDisk(QmlJS::Document::Ptr doc);
void aboutToRemoveFiles(const QStringList &files);
void libraryInfoUpdated(const QString &path, const QmlJS::LibraryInfo &info);
void projectInfoUpdated(const ProjectInfo &pinfo);
};
} // namespace QmlJS