Commit d05992d0 authored by Christian Kamm's avatar Christian Kamm

QmlJS: Stop doing significant work in constructors.

To avoid order-of-initialization problems.

Reviewed-by: Thomas Hartmann
parent 6ea355ad
......@@ -43,7 +43,6 @@
namespace QmlJS {
class Link;
class Document;
class QMLJS_EXPORT Bind: protected AST::Visitor
......
......@@ -375,6 +375,7 @@ Check::Check(Document::Ptr doc, const Context *linkedContextNoScope)
| WarnCaseWithoutFlowControlEnd | ErrCheckTypeErrors)
, _lastValue(0)
{
_scopeBuilder.initializeRootScope();
}
Check::~Check()
......
......@@ -3286,6 +3286,7 @@ const Value *ASTPropertyReference::value(const Context *context) const
QmlJS::Document::Ptr doc = _doc->ptr();
Context localContext(*context);
QmlJS::ScopeBuilder builder(&localContext, doc);
builder.initializeRootScope();
int offset = _ast->expression->firstSourceLocation().begin();
builder.push(ScopeAstPath(doc)(offset));
......
......@@ -110,8 +110,7 @@ public:
\l{Context} with \l{Link}.
*/
Link::Link(Context *context, const Snapshot &snapshot, const QStringList &importPaths,
QHash<QString, QList<DiagnosticMessage> > *messages)
Link::Link(Context *context, const Snapshot &snapshot, const QStringList &importPaths)
: d_ptr(new LinkPrivate)
{
Q_D(Link);
......@@ -120,7 +119,7 @@ Link::Link(Context *context, const Snapshot &snapshot, const QStringList &import
d->importPaths = importPaths;
d->diagnosticMessages = 0;
d->allDiagnosticMessages = messages;
d->allDiagnosticMessages = 0;
// populate engine with types from C++
ModelManagerInterface *modelManager = ModelManagerInterface::instance();
......@@ -129,31 +128,20 @@ Link::Link(Context *context, const Snapshot &snapshot, const QStringList &import
engine()->cppQmlTypes().load(engine(), cppTypes);
}
}
}
void Link::operator()(QHash<QString, QList<DiagnosticMessage> > *messages)
{
Q_D(Link);
d->allDiagnosticMessages = messages;
linkImports();
}
Link::Link(Context *context, const Snapshot &snapshot, const QStringList &importPaths,
const Document::Ptr &doc, QList<DiagnosticMessage> *messages)
: d_ptr(new LinkPrivate)
void Link::operator()(const Document::Ptr &doc, QList<DiagnosticMessage> *messages)
{
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) {
foreach (const QList<FakeMetaObject::ConstPtr> &cppTypes, modelManager->cppQmlTypes()) {
engine()->cppQmlTypes().load(engine(), cppTypes);
}
}
linkImports();
}
......
......@@ -54,14 +54,15 @@ class QMLJS_EXPORT Link
Q_DECLARE_TR_FUNCTIONS(QmlJS::Link)
public:
// 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);
const QStringList &importPaths);
// Link all documents in snapshot, collecting all diagnostic messages (if messages != 0)
void operator()(QHash<QString, QList<DiagnosticMessage> > *messages = 0);
// 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);
void operator()(const Document::Ptr &doc, QList<DiagnosticMessage> *messages);
~Link();
......
......@@ -48,18 +48,21 @@ public:
{
// 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();
ScopeBuilder scopeBuilder(&context, doc);
scopeBuilder.initializeRootScope();
scopeBuilder.push(path);
}
LookupContextData(Document::Ptr doc, const Snapshot &snapshot,
LookupContextData(Document::Ptr doc,
const Interpreter::Context &linkedContextWithoutScope,
const QList<AST::Node *> &path)
: context(linkedContextWithoutScope),
doc(doc)
{
ScopeBuilder scopeBuilder(&context, doc);
scopeBuilder.initializeRootScope();
scopeBuilder.push(path);
}
......@@ -73,10 +76,10 @@ LookupContext::LookupContext(Document::Ptr doc, const Snapshot &snapshot, const
{
}
LookupContext::LookupContext(const Document::Ptr doc, const Snapshot &snapshot,
LookupContext::LookupContext(const Document::Ptr doc,
const Interpreter::Context &linkedContextWithoutScope,
const QList<AST::Node *> &path)
: d(new LookupContextData(doc, snapshot, linkedContextWithoutScope, path))
: d(new LookupContextData(doc, linkedContextWithoutScope, path))
{
}
......@@ -90,11 +93,11 @@ LookupContext::Ptr LookupContext::create(Document::Ptr doc, const Snapshot &snap
return ptr;
}
LookupContext::Ptr LookupContext::create(const Document::Ptr doc, const Snapshot &snapshot,
LookupContext::Ptr LookupContext::create(const Document::Ptr doc,
const Interpreter::Context &linkedContextWithoutScope,
const QList<AST::Node *> &path)
{
Ptr ptr(new LookupContext(doc, snapshot, linkedContextWithoutScope, path));
Ptr ptr(new LookupContext(doc, linkedContextWithoutScope, path));
return ptr;
}
......
......@@ -54,7 +54,7 @@ class QMLJS_EXPORT LookupContext
Q_DISABLE_COPY(LookupContext)
LookupContext(const Document::Ptr doc, const Snapshot &snapshot, const QList<AST::Node *> &path);
LookupContext(const Document::Ptr doc, const Snapshot &snapshot,
LookupContext(const Document::Ptr doc,
const Interpreter::Context &linkedContextWithoutScope,
const QList<AST::Node *> &path);
......@@ -66,7 +66,7 @@ public:
// consider using SemanticInfo::lookupContext instead, it's faster
static Ptr create(const Document::Ptr doc, const Snapshot &snapshot,
const QList<AST::Node *> &path);
static Ptr create(const Document::Ptr doc, const Snapshot &snapshot,
static Ptr create(const Document::Ptr doc,
const Interpreter::Context &linkedContextWithoutScope,
const QList<AST::Node *> &path);
......
......@@ -45,7 +45,6 @@ ScopeBuilder::ScopeBuilder(Context *context, Document::Ptr doc)
: _doc(doc)
, _context(context)
{
initializeScopeChain();
}
ScopeBuilder::~ScopeBuilder()
......@@ -98,7 +97,7 @@ void ScopeBuilder::pop()
_context->scopeChain().update();
}
void ScopeBuilder::initializeScopeChain()
void ScopeBuilder::initializeRootScope()
{
ScopeChain &scopeChain = _context->scopeChain();
if (scopeChain.qmlComponentScope
......
......@@ -50,6 +50,8 @@ public:
ScopeBuilder(Interpreter::Context *context, Document::Ptr doc);
~ScopeBuilder();
void initializeRootScope();
void push(AST::Node *node);
void push(const QList<AST::Node *> &nodes);
void pop();
......@@ -57,7 +59,6 @@ public:
static const Interpreter::ObjectValue *isPropertyChangesObject(const Interpreter::Context *context, const Interpreter::ObjectValue *object);
private:
void initializeScopeChain();
void makeComponentChain(Document::Ptr doc, const Snapshot &snapshot,
Interpreter::ScopeChain::QmlComponentChain *target,
QHash<Document *, Interpreter::ScopeChain::QmlComponentChain *> *components);
......
......@@ -298,10 +298,12 @@ public:
: m_snapshot(snapshot)
, m_doc(doc)
, m_context(new Interpreter::Context(snapshot))
, m_link(m_context, snapshot, importPaths, doc, &m_diagnosticLinkMessages)
, m_lookupContext(LookupContext::create(doc, snapshot, *m_context, QList<AST::Node*>()))
, m_link(m_context, snapshot, importPaths)
, m_scopeBuilder(m_context, doc)
{
m_lookupContext = LookupContext::create(doc, *m_context, QList<AST::Node*>());
// cheaper than calling m_scopeBuilder.initializeRootScope()
*m_context = *m_lookupContext->context();
}
~ReadingContext()
......
......@@ -540,7 +540,7 @@ LookupContext::Ptr SemanticInfo::lookupContext(const QList<QmlJS::AST::Node *> &
if (m_context.isNull())
return LookupContext::create(document, snapshot, path);
return LookupContext::create(document, snapshot, *m_context, path);
return LookupContext::create(document, *m_context, path);
}
static bool importContainsCursor(UiImport *importAst, unsigned cursorPosition)
......
......@@ -83,6 +83,7 @@ public:
, _context(context)
, _builder(context, doc)
{
_builder.initializeRootScope();
}
Result operator()(const QString &name, const ObjectValue *scope)
......@@ -555,7 +556,10 @@ static void find_helper(QFutureInterface<FindReferences::Usage> &future,
return;
Link link(&context, snapshot, ModelManagerInterface::instance()->importPaths());
link();
ScopeBuilder builder(&context, doc);
builder.initializeRootScope();
ScopeAstPath astPath(doc);
builder.push(astPath(offset));
......
......@@ -133,7 +133,8 @@ SemanticInfo SemanticHighlighter::semanticInfo(const SemanticHighlighterSource &
semanticInfo.document = doc;
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());
link(doc, &semanticInfo.semanticMessages);
semanticInfo.m_context = QSharedPointer<const QmlJS::Interpreter::Context>(ctx);
QmlJS::Check checker(doc, ctx);
......
......@@ -74,7 +74,8 @@ void QmlTaskManager::collectMessages(QFutureInterface<FileErrorMessages> &future
{
Interpreter::Context ctx(snapshot);
QHash<QString, QList<DiagnosticMessage> > linkMessages;
Link link(&ctx, snapshot, importPaths, &linkMessages);
Link link(&ctx, snapshot, importPaths);
link(&linkMessages);
foreach (const QString &fileName, files) {
Document::Ptr document = snapshot.document(fileName);
......
Markdown is supported
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