QmlJS: Fix type detection for alias properties.

Task-number: QTCREATORBUG-2306
This commit is contained in:
Christian Kamm
2011-05-04 11:12:45 +02:00
parent 6bb08f1bf9
commit 02b7eacf4b
17 changed files with 84 additions and 115 deletions

View File

@@ -27,7 +27,8 @@ HEADERS += \
$$PWD/qmljsrewriter.h \ $$PWD/qmljsrewriter.h \
$$PWD/qmljsicons.h \ $$PWD/qmljsicons.h \
$$PWD/qmljsdelta.h \ $$PWD/qmljsdelta.h \
$$PWD/qmljstypedescriptionreader.h $$PWD/qmljstypedescriptionreader.h \
$$PWD/qmljsscopeastpath.h
SOURCES += \ SOURCES += \
$$PWD/qmljsbind.cpp \ $$PWD/qmljsbind.cpp \
@@ -46,7 +47,8 @@ SOURCES += \
$$PWD/qmljsrewriter.cpp \ $$PWD/qmljsrewriter.cpp \
$$PWD/qmljsicons.cpp \ $$PWD/qmljsicons.cpp \
$$PWD/qmljsdelta.cpp \ $$PWD/qmljsdelta.cpp \
$$PWD/qmljstypedescriptionreader.cpp $$PWD/qmljstypedescriptionreader.cpp \
$$PWD/qmljsscopeastpath.cpp
RESOURCES += \ RESOURCES += \
$$PWD/qmljs.qrc $$PWD/qmljs.qrc

View File

@@ -365,11 +365,10 @@ private:
} // end of anonymous namespace } // end of anonymous namespace
Check::Check(Document::Ptr doc, const Snapshot &snapshot, const Context *linkedContextNoScope) Check::Check(Document::Ptr doc, const Context *linkedContextNoScope)
: _doc(doc) : _doc(doc)
, _snapshot(snapshot)
, _context(*linkedContextNoScope) , _context(*linkedContextNoScope)
, _scopeBuilder(&_context, doc, snapshot) , _scopeBuilder(&_context, doc)
, _options(WarnDangerousNonStrictEqualityChecks | WarnBlocks | WarnWith , _options(WarnDangerousNonStrictEqualityChecks | WarnBlocks | WarnWith
| WarnVoid | WarnCommaExpression | WarnExpressionStatement | WarnVoid | WarnCommaExpression | WarnExpressionStatement
| WarnAssignInCondition | WarnUseBeforeDeclaration | WarnDuplicateDeclaration | WarnAssignInCondition | WarnUseBeforeDeclaration | WarnDuplicateDeclaration
@@ -844,12 +843,17 @@ const Value *Check::checkScopeObjectMember(const UiQualifiedId *id)
if (!value) { if (!value) {
error(id->identifierToken, error(id->identifierToken,
Check::tr("'%1' is not a valid property name").arg(propertyName)); Check::tr("'%1' is not a valid property name").arg(propertyName));
return 0;
} }
// can't look up members for attached properties // can't look up members for attached properties
if (isAttachedProperty) if (isAttachedProperty)
return 0; return 0;
// resolve references
if (const Reference *ref = value->asReference())
value = _context.lookupReference(ref);
// member lookup // member lookup
const UiQualifiedId *idPart = id; const UiQualifiedId *idPart = id;
while (idPart->next) { while (idPart->next) {

View File

@@ -52,7 +52,7 @@ class QMLJS_EXPORT Check: protected AST::Visitor
typedef QSet<QString> StringSet; typedef QSet<QString> StringSet;
public: public:
Check(Document::Ptr doc, const Snapshot &snapshot, const Interpreter::Context *linkedContextNoScope); Check(Document::Ptr doc, const Interpreter::Context *linkedContextNoScope);
virtual ~Check(); virtual ~Check();
QList<DiagnosticMessage> operator()(); QList<DiagnosticMessage> operator()();
@@ -125,7 +125,6 @@ private:
AST::Node *parent(int distance = 0); AST::Node *parent(int distance = 0);
Document::Ptr _doc; Document::Ptr _doc;
Snapshot _snapshot;
Interpreter::Context _context; Interpreter::Context _context;
ScopeBuilder _scopeBuilder; ScopeBuilder _scopeBuilder;

View File

@@ -126,9 +126,15 @@ Document::~Document()
Document::Ptr Document::create(const QString &fileName) Document::Ptr Document::create(const QString &fileName)
{ {
Document::Ptr doc(new Document(fileName)); Document::Ptr doc(new Document(fileName));
doc->_ptr = doc;
return doc; return doc;
} }
Document::Ptr Document::ptr() const
{
return _ptr.toStrongRef();
}
bool Document::isQmlDocument() const bool Document::isQmlDocument() const
{ {
return _isQmlDocument; return _isQmlDocument;

View File

@@ -64,6 +64,8 @@ public:
static Document::Ptr create(const QString &fileName); static Document::Ptr create(const QString &fileName);
Document::Ptr ptr() const;
bool isQmlDocument() const; bool isQmlDocument() const;
bool isJSDocument() const; bool isJSDocument() const;
@@ -113,6 +115,7 @@ private:
QString _path; QString _path;
QString _componentName; QString _componentName;
QString _source; QString _source;
QWeakPointer<Document> _ptr;
// for documentFromSource // for documentFromSource
friend class Snapshot; friend class Snapshot;

View File

@@ -32,7 +32,6 @@
#include "qmljsevaluate.h" #include "qmljsevaluate.h"
#include "qmljsinterpreter.h" #include "qmljsinterpreter.h"
#include "parser/qmljsparser_p.h"
#include "parser/qmljsast_p.h" #include "parser/qmljsast_p.h"
#include <QtCore/QDebug> #include <QtCore/QDebug>

View File

@@ -52,7 +52,10 @@ public:
Evaluate(const Interpreter::Context *context); Evaluate(const Interpreter::Context *context);
virtual ~Evaluate(); virtual ~Evaluate();
// evaluate ast in the given context
const Interpreter::Value *operator()(AST::Node *ast); const Interpreter::Value *operator()(AST::Node *ast);
// evaluate, but stop when encountering a Reference
const Interpreter::Value *reference(AST::Node *ast); const Interpreter::Value *reference(AST::Node *ast);
protected: protected:

View File

@@ -36,6 +36,7 @@
#include "qmljsbind.h" #include "qmljsbind.h"
#include "qmljsscopebuilder.h" #include "qmljsscopebuilder.h"
#include "qmljstypedescriptionreader.h" #include "qmljstypedescriptionreader.h"
#include "qmljsscopeastpath.h"
#include "parser/qmljsast_p.h" #include "parser/qmljsast_p.h"
#include <languageutils/fakemetaobject.h> #include <languageutils/fakemetaobject.h>
@@ -1378,8 +1379,9 @@ QList<const ObjectValue *> ScopeChain::all() const
} }
Context::Context() Context::Context(const Snapshot &snapshot)
: _engine(new Engine), : _snapshot(snapshot),
_engine(new Engine),
_qmlScopeObjectIndex(-1), _qmlScopeObjectIndex(-1),
_qmlScopeObjectSet(false) _qmlScopeObjectSet(false)
{ {
@@ -1395,6 +1397,11 @@ Engine *Context::engine() const
return _engine.data(); return _engine.data();
} }
QmlJS::Snapshot Context::snapshot() const
{
return _snapshot;
}
const ScopeChain &Context::scopeChain() const const ScopeChain &Context::scopeChain() const
{ {
return _scopeChain; return _scopeChain;
@@ -3270,8 +3277,20 @@ bool ASTPropertyReference::getSourceLocation(QString *fileName, int *line, int *
const Value *ASTPropertyReference::value(const Context *context) const const Value *ASTPropertyReference::value(const Context *context) const
{ {
if (_ast->expression if (_ast->expression
&& (!_ast->memberType || _ast->memberType->asString() == QLatin1String("variant"))) { && (!_ast->memberType || _ast->memberType->asString() == QLatin1String("variant")
Evaluate check(context); || _ast->memberType->asString() == QLatin1String("alias"))) {
// Adjust the context for the current location - expensive!
// ### Improve efficiency by caching the 'use chain' constructed in ScopeBuilder.
QmlJS::Document::Ptr doc = _doc->ptr();
Context localContext(*context);
QmlJS::ScopeBuilder builder(&localContext, doc);
int offset = _ast->expression->firstSourceLocation().begin();
builder.push(ScopeAstPath(doc)(offset));
Evaluate check(&localContext);
return check(_ast->expression); return check(_ast->expression);
} }

View File

@@ -317,10 +317,12 @@ private:
class QMLJS_EXPORT Context class QMLJS_EXPORT Context
{ {
public: public:
Context(); Context(const Snapshot &snapshot);
~Context(); ~Context();
Engine *engine() const; Engine *engine() const;
Snapshot snapshot() const;
const ScopeChain &scopeChain() const; const ScopeChain &scopeChain() const;
ScopeChain &scopeChain(); ScopeChain &scopeChain();
@@ -340,6 +342,7 @@ public:
private: private:
typedef QHash<QString, const Value *> Properties; typedef QHash<QString, const Value *> Properties;
Snapshot _snapshot;
QSharedPointer<Engine> _engine; QSharedPointer<Engine> _engine;
QHash<const ObjectValue *, Properties> _properties; QHash<const ObjectValue *, Properties> _properties;
QHash<const Document *, const TypeEnvironment *> _typeEnvironments; QHash<const Document *, const TypeEnvironment *> _typeEnvironments;

View File

@@ -36,7 +36,6 @@
#include "qmljsdocument.h" #include "qmljsdocument.h"
#include "qmljsbind.h" #include "qmljsbind.h"
#include "qmljscheck.h" #include "qmljscheck.h"
#include "qmljsscopebuilder.h"
#include "qmljsmodelmanagerinterface.h" #include "qmljsmodelmanagerinterface.h"
#include <QtCore/QFileInfo> #include <QtCore/QFileInfo>

View File

@@ -43,13 +43,13 @@ class QmlJS::LookupContextData
{ {
public: public:
LookupContextData(Document::Ptr doc, const Snapshot &snapshot, const QList<AST::Node *> &path) LookupContextData(Document::Ptr doc, const Snapshot &snapshot, const QList<AST::Node *> &path)
: doc(doc), : context(snapshot),
snapshot(snapshot) doc(doc)
{ {
// since we keep the document and snapshot around, we don't need to keep the Link instance // since we keep the document and snapshot around, we don't need to keep the Link instance
Link link(&context, snapshot, ModelManagerInterface::instance()->importPaths()); Link link(&context, snapshot, ModelManagerInterface::instance()->importPaths());
ScopeBuilder scopeBuilder(&context, doc, snapshot); ScopeBuilder scopeBuilder(&context, doc);
scopeBuilder.push(path); scopeBuilder.push(path);
} }
@@ -57,16 +57,15 @@ public:
const Interpreter::Context &linkedContextWithoutScope, const Interpreter::Context &linkedContextWithoutScope,
const QList<AST::Node *> &path) const QList<AST::Node *> &path)
: context(linkedContextWithoutScope), : context(linkedContextWithoutScope),
doc(doc), doc(doc)
snapshot(snapshot)
{ {
ScopeBuilder scopeBuilder(&context, doc, snapshot); ScopeBuilder scopeBuilder(&context, doc);
scopeBuilder.push(path); scopeBuilder.push(path);
} }
Interpreter::Context context; Interpreter::Context context;
Document::Ptr doc; Document::Ptr doc;
Snapshot snapshot; // snapshot is in context
}; };
LookupContext::LookupContext(Document::Ptr doc, const Snapshot &snapshot, const QList<AST::Node *> &path) LookupContext::LookupContext(Document::Ptr doc, const Snapshot &snapshot, const QList<AST::Node *> &path)
@@ -112,7 +111,7 @@ Document::Ptr LookupContext::document() const
Snapshot LookupContext::snapshot() const Snapshot LookupContext::snapshot() const
{ {
return d->snapshot; return d->context.snapshot();
} }
// the engine is only guaranteed to live as long as the LookupContext // the engine is only guaranteed to live as long as the LookupContext

View File

@@ -41,9 +41,8 @@ using namespace QmlJS;
using namespace QmlJS::Interpreter; using namespace QmlJS::Interpreter;
using namespace QmlJS::AST; using namespace QmlJS::AST;
ScopeBuilder::ScopeBuilder(Context *context, Document::Ptr doc, const Snapshot &snapshot) ScopeBuilder::ScopeBuilder(Context *context, Document::Ptr doc)
: _doc(doc) : _doc(doc)
, _snapshot(snapshot)
, _context(context) , _context(context)
{ {
initializeScopeChain(); initializeScopeChain();
@@ -121,25 +120,26 @@ void ScopeBuilder::initializeScopeChain()
Bind *bind = _doc->bind(); Bind *bind = _doc->bind();
QHash<Document *, ScopeChain::QmlComponentChain *> componentScopes; QHash<Document *, ScopeChain::QmlComponentChain *> componentScopes;
const Snapshot &snapshot = _context->snapshot();
ScopeChain::QmlComponentChain *chain = new ScopeChain::QmlComponentChain; ScopeChain::QmlComponentChain *chain = new ScopeChain::QmlComponentChain;
scopeChain.qmlComponentScope = QSharedPointer<const ScopeChain::QmlComponentChain>(chain); scopeChain.qmlComponentScope = QSharedPointer<const ScopeChain::QmlComponentChain>(chain);
if (_doc->qmlProgram()) { if (_doc->qmlProgram()) {
componentScopes.insert(_doc.data(), chain); componentScopes.insert(_doc.data(), chain);
makeComponentChain(_doc, chain, &componentScopes); makeComponentChain(_doc, snapshot, chain, &componentScopes);
if (const TypeEnvironment *typeEnvironment = _context->typeEnvironment(_doc.data())) { if (const TypeEnvironment *typeEnvironment = _context->typeEnvironment(_doc.data())) {
scopeChain.qmlTypes = typeEnvironment; scopeChain.qmlTypes = typeEnvironment;
} }
} else { } else {
// add scope chains for all components that import this file // add scope chains for all components that import this file
foreach (Document::Ptr otherDoc, _snapshot) { foreach (Document::Ptr otherDoc, snapshot) {
foreach (const ImportInfo &import, otherDoc->bind()->imports()) { foreach (const ImportInfo &import, otherDoc->bind()->imports()) {
if (import.type() == ImportInfo::FileImport && _doc->fileName() == import.name()) { if (import.type() == ImportInfo::FileImport && _doc->fileName() == import.name()) {
ScopeChain::QmlComponentChain *component = new ScopeChain::QmlComponentChain; ScopeChain::QmlComponentChain *component = new ScopeChain::QmlComponentChain;
componentScopes.insert(otherDoc.data(), component); componentScopes.insert(otherDoc.data(), component);
chain->instantiatingComponents += component; chain->instantiatingComponents += component;
makeComponentChain(otherDoc, component, &componentScopes); makeComponentChain(otherDoc, snapshot, component, &componentScopes);
} }
} }
} }
@@ -155,6 +155,7 @@ void ScopeBuilder::initializeScopeChain()
void ScopeBuilder::makeComponentChain( void ScopeBuilder::makeComponentChain(
Document::Ptr doc, Document::Ptr doc,
const Snapshot &snapshot,
ScopeChain::QmlComponentChain *target, ScopeChain::QmlComponentChain *target,
QHash<Document *, ScopeChain::QmlComponentChain *> *components) QHash<Document *, ScopeChain::QmlComponentChain *> *components)
{ {
@@ -164,7 +165,7 @@ void ScopeBuilder::makeComponentChain(
Bind *bind = doc->bind(); Bind *bind = doc->bind();
// add scopes for all components instantiating this one // add scopes for all components instantiating this one
foreach (Document::Ptr otherDoc, _snapshot) { foreach (Document::Ptr otherDoc, snapshot) {
if (otherDoc == doc) if (otherDoc == doc)
continue; continue;
if (otherDoc->bind()->usesQmlPrototype(bind->rootObjectValue(), _context)) { if (otherDoc->bind()->usesQmlPrototype(bind->rootObjectValue(), _context)) {
@@ -175,7 +176,7 @@ void ScopeBuilder::makeComponentChain(
components->insert(otherDoc.data(), component); components->insert(otherDoc.data(), component);
target->instantiatingComponents += component; target->instantiatingComponents += component;
makeComponentChain(otherDoc, component, components); makeComponentChain(otherDoc, snapshot, component, components);
} }
} }
} }

View File

@@ -47,7 +47,7 @@ namespace AST {
class QMLJS_EXPORT ScopeBuilder class QMLJS_EXPORT ScopeBuilder
{ {
public: public:
ScopeBuilder(Interpreter::Context *context, Document::Ptr doc, const Snapshot &snapshot); ScopeBuilder(Interpreter::Context *context, Document::Ptr doc);
~ScopeBuilder(); ~ScopeBuilder();
void push(AST::Node *node); void push(AST::Node *node);
@@ -58,14 +58,14 @@ public:
private: private:
void initializeScopeChain(); void initializeScopeChain();
void makeComponentChain(Document::Ptr doc, Interpreter::ScopeChain::QmlComponentChain *target, void makeComponentChain(Document::Ptr doc, const Snapshot &snapshot,
Interpreter::ScopeChain::QmlComponentChain *target,
QHash<Document *, Interpreter::ScopeChain::QmlComponentChain *> *components); QHash<Document *, Interpreter::ScopeChain::QmlComponentChain *> *components);
void setQmlScopeObject(AST::Node *node); void setQmlScopeObject(AST::Node *node);
const Interpreter::Value *scopeObjectLookup(AST::UiQualifiedId *id); const Interpreter::Value *scopeObjectLookup(AST::UiQualifiedId *id);
Document::Ptr _doc; Document::Ptr _doc;
Snapshot _snapshot;
Interpreter::Context *_context; Interpreter::Context *_context;
QList<AST::Node *> _nodes; QList<AST::Node *> _nodes;
}; };

View File

@@ -282,10 +282,10 @@ public:
const QStringList importPaths) const QStringList importPaths)
: m_snapshot(snapshot) : m_snapshot(snapshot)
, m_doc(doc) , m_doc(doc)
, m_context(new Interpreter::Context) , m_context(new Interpreter::Context(snapshot))
, m_link(m_context, snapshot, importPaths, doc, &m_diagnosticLinkMessages) , m_link(m_context, snapshot, importPaths, doc, &m_diagnosticLinkMessages)
, m_lookupContext(LookupContext::create(doc, snapshot, *m_context, QList<AST::Node*>())) , m_lookupContext(LookupContext::create(doc, snapshot, *m_context, QList<AST::Node*>()))
, m_scopeBuilder(m_context, doc, snapshot) , m_scopeBuilder(m_context, doc)
{ {
} }
@@ -381,6 +381,10 @@ public:
if (isAttachedProperty) if (isAttachedProperty)
return false; return false;
// resolve references
if (const Interpreter::Reference *ref = value->asReference())
value = m_context->lookupReference(ref);
// member lookup // member lookup
const UiQualifiedId *idPart = id; const UiQualifiedId *idPart = id;
if (prefix.isEmpty()) if (prefix.isEmpty())
@@ -664,7 +668,7 @@ bool TextToModelMerger::load(const QString &data, DifferenceHandler &differenceH
} }
if (view()->checkSemanticErrors()) { if (view()->checkSemanticErrors()) {
Check check(doc, snapshot, m_lookupContext->context()); Check check(doc, m_lookupContext->context());
check.setOptions(check.options() & ~Check::ErrCheckTypeErrors); check.setOptions(check.options() & ~Check::ErrCheckTypeErrors);
foreach (const QmlJS::DiagnosticMessage &diagnosticMessage, check()) foreach (const QmlJS::DiagnosticMessage &diagnosticMessage, check())
if (diagnosticMessage.isError()) if (diagnosticMessage.isError())

View File

@@ -47,6 +47,7 @@
#include <qmljs/qmljslink.h> #include <qmljs/qmljslink.h>
#include <qmljs/qmljsevaluate.h> #include <qmljs/qmljsevaluate.h>
#include <qmljs/qmljsscopebuilder.h> #include <qmljs/qmljsscopebuilder.h>
#include <qmljs/qmljsscopeastpath.h>
#include <qmljs/parser/qmljsastvisitor_p.h> #include <qmljs/parser/qmljsastvisitor_p.h>
#include <qmljs/parser/qmljsast_p.h> #include <qmljs/parser/qmljsast_p.h>
@@ -80,7 +81,7 @@ public:
: _doc(doc) : _doc(doc)
, _snapshot(snapshot) , _snapshot(snapshot)
, _context(context) , _context(context)
, _builder(context, doc, snapshot) , _builder(context, doc)
{ {
} }
@@ -286,79 +287,6 @@ private:
const ObjectValue *_scope; const ObjectValue *_scope;
}; };
class ScopeAstPath: protected Visitor
{
public:
ScopeAstPath(Document::Ptr doc)
: _doc(doc)
{
}
QList<Node *> operator()(quint32 offset)
{
_result.clear();
_offset = offset;
if (_doc)
Node::accept(_doc->ast(), this);
return _result;
}
protected:
void accept(AST::Node *node)
{ AST::Node::acceptChild(node, this); }
using Visitor::visit;
virtual bool preVisit(Node *node)
{
if (Statement *stmt = node->statementCast()) {
return containsOffset(stmt->firstSourceLocation(), stmt->lastSourceLocation());
} else if (ExpressionNode *exp = node->expressionCast()) {
return containsOffset(exp->firstSourceLocation(), exp->lastSourceLocation());
} else if (UiObjectMember *ui = node->uiObjectMemberCast()) {
return containsOffset(ui->firstSourceLocation(), ui->lastSourceLocation());
}
return true;
}
virtual bool visit(AST::UiObjectDefinition *node)
{
_result.append(node);
Node::accept(node->initializer, this);
return false;
}
virtual bool visit(AST::UiObjectBinding *node)
{
_result.append(node);
Node::accept(node->initializer, this);
return false;
}
virtual bool visit(AST::FunctionDeclaration *node)
{
return visit(static_cast<FunctionExpression *>(node));
}
virtual bool visit(AST::FunctionExpression *node)
{
Node::accept(node->formals, this);
_result.append(node);
Node::accept(node->body, this);
return false;
}
private:
bool containsOffset(SourceLocation start, SourceLocation end)
{
return _offset >= start.begin() && _offset <= end.end();
}
QList<Node *> _result;
Document::Ptr _doc;
quint32 _offset;
};
class FindTargetExpression: protected Visitor class FindTargetExpression: protected Visitor
{ {
public: public:
@@ -621,13 +549,13 @@ static void find_helper(QFutureInterface<FindReferences::Usage> &future,
} }
// find the scope for the name we're searching // find the scope for the name we're searching
Context context; Context context(snapshot);
Document::Ptr doc = snapshot.document(fileName); Document::Ptr doc = snapshot.document(fileName);
if (!doc) if (!doc)
return; return;
Link link(&context, snapshot, ModelManagerInterface::instance()->importPaths()); Link link(&context, snapshot, ModelManagerInterface::instance()->importPaths());
ScopeBuilder builder(&context, doc, snapshot); ScopeBuilder builder(&context, doc);
ScopeAstPath astPath(doc); ScopeAstPath astPath(doc);
builder.push(astPath(offset)); builder.push(astPath(offset));

View File

@@ -132,11 +132,11 @@ SemanticInfo SemanticHighlighter::semanticInfo(const SemanticHighlighterSource &
semanticInfo.snapshot = snapshot; semanticInfo.snapshot = snapshot;
semanticInfo.document = doc; semanticInfo.document = doc;
QmlJS::Interpreter::Context *ctx = new QmlJS::Interpreter::Context; QmlJS::Interpreter::Context *ctx = new QmlJS::Interpreter::Context(snapshot);
QmlJS::Link link(ctx, snapshot, QmlJS::ModelManagerInterface::instance()->importPaths(), doc, &semanticInfo.semanticMessages); QmlJS::Link link(ctx, snapshot, QmlJS::ModelManagerInterface::instance()->importPaths(), doc, &semanticInfo.semanticMessages);
semanticInfo.m_context = QSharedPointer<const QmlJS::Interpreter::Context>(ctx); semanticInfo.m_context = QSharedPointer<const QmlJS::Interpreter::Context>(ctx);
QmlJS::Check checker(doc, snapshot, ctx); QmlJS::Check checker(doc, ctx);
semanticInfo.semanticMessages.append(checker()); semanticInfo.semanticMessages.append(checker());
return semanticInfo; return semanticInfo;

View File

@@ -72,7 +72,7 @@ QmlTaskManager::QmlTaskManager(QObject *parent) :
void QmlTaskManager::collectMessages(QFutureInterface<FileErrorMessages> &future, void QmlTaskManager::collectMessages(QFutureInterface<FileErrorMessages> &future,
Snapshot snapshot, QStringList files, QStringList importPaths) Snapshot snapshot, QStringList files, QStringList importPaths)
{ {
Interpreter::Context ctx; Interpreter::Context ctx(snapshot);
QHash<QString, QList<DiagnosticMessage> > linkMessages; QHash<QString, QList<DiagnosticMessage> > linkMessages;
Link link(&ctx, snapshot, importPaths, &linkMessages); Link link(&ctx, snapshot, importPaths, &linkMessages);
@@ -86,7 +86,7 @@ void QmlTaskManager::collectMessages(QFutureInterface<FileErrorMessages> &future
result.messages = document->diagnosticMessages(); result.messages = document->diagnosticMessages();
result.messages += linkMessages.value(fileName); result.messages += linkMessages.value(fileName);
Check checker(document, snapshot, &ctx); Check checker(document, &ctx);
result.messages.append(checker()); result.messages.append(checker());
future.reportResult(result); future.reportResult(result);