diff --git a/src/libs/qmljs/qmljsinterpreter.cpp b/src/libs/qmljs/qmljsinterpreter.cpp index c9e0c15f539ebad2dddc470f790f2d823f64fafc..ca317b6801f2bf8d014c0d982ca57e0f51801738 100644 --- a/src/libs/qmljs/qmljsinterpreter.cpp +++ b/src/libs/qmljs/qmljsinterpreter.cpp @@ -29,6 +29,7 @@ #include "qmljsinterpreter.h" #include "qmljscheck.h" +#include "qmljslink.h" #include "parser/qmljsast_p.h" #include <QtCore/QMetaObject> #include <QtCore/QMetaProperty> @@ -688,6 +689,12 @@ Context::~Context() { } +void Context::build(AST::Node *node, Document::Ptr doc, const Snapshot &snapshot) +{ + Link link(this, doc, snapshot); + link.scopeChainAt(doc, node); +} + Engine *Context::engine() const { return _engine; diff --git a/src/libs/qmljs/qmljsinterpreter.h b/src/libs/qmljs/qmljsinterpreter.h index feaf95e33f0f3a8b4c6bb5b15414075292e9ec41..88a958a64fa88679f30139f97c2d59df9af06d71 100644 --- a/src/libs/qmljs/qmljsinterpreter.h +++ b/src/libs/qmljs/qmljsinterpreter.h @@ -30,6 +30,7 @@ #ifndef QMLJS_INTERPRETER_H #define QMLJS_INTERPRETER_H +#include <qmljs/qmljsdocument.h> #include <qmljs/qmljs_global.h> #include <qmljs/qmljsmetatypesystem.h> #include <qmljs/parser/qmljsastfwd_p.h> @@ -224,6 +225,8 @@ public: Context(Engine *engine); ~Context(); + void build(AST::Node *node, Document::Ptr doc, const Snapshot &snapshot); + Engine *engine() const; ScopeChain scopeChain() const; diff --git a/src/libs/qmljs/qmljslink.cpp b/src/libs/qmljs/qmljslink.cpp index 50cfc515432bb8795cc2df92e9077301821600f9..f39b91c04e3ce2d2ab2fbd773672033bf5bedcd7 100644 --- a/src/libs/qmljs/qmljslink.cpp +++ b/src/libs/qmljs/qmljslink.cpp @@ -12,12 +12,11 @@ using namespace QmlJS; using namespace QmlJS::Interpreter; using namespace QmlJS::AST; -Link::Link(Document::Ptr currentDoc, const Snapshot &snapshot, Interpreter::Engine *interp) +Link::Link(Context *context, Document::Ptr currentDoc, const Snapshot &snapshot) : _snapshot(snapshot) - , _context(interp) + , _context(context) { _docs = reachableDocuments(currentDoc, snapshot); - linkImports(); } @@ -25,25 +24,20 @@ Link::~Link() { } -Context *Link::context() -{ - return &_context; -} - Interpreter::Engine *Link::engine() { - return _context.engine(); + return _context->engine(); } void Link::scopeChainAt(Document::Ptr doc, Node *currentObject) { - _context.pushScope(engine()->globalObject()); + _context->pushScope(engine()->globalObject()); if (! doc) return; if (doc->qmlProgram() != 0) - _context.setLookupMode(Context::QmlLookup); + _context->setLookupMode(Context::QmlLookup); Bind *bind = doc->bind(); @@ -52,7 +46,7 @@ void Link::scopeChainAt(Document::Ptr doc, Node *currentObject) // ### FIXME: May want to link to instantiating components from here. if (bind->_rootObjectValue) - _context.pushScope(bind->_rootObjectValue); + _context->pushScope(bind->_rootObjectValue); ObjectValue *scopeObject = 0; if (UiObjectDefinition *definition = cast<UiObjectDefinition *>(currentObject)) @@ -61,7 +55,7 @@ void Link::scopeChainAt(Document::Ptr doc, Node *currentObject) scopeObject = bind->_qmlObjects.value(binding); if (scopeObject && scopeObject != bind->_rootObjectValue) - _context.pushScope(scopeObject); + _context->pushScope(scopeObject); const QStringList &includedScripts = bind->includedScripts(); for (int index = includedScripts.size() - 1; index != -1; --index) { @@ -69,19 +63,19 @@ void Link::scopeChainAt(Document::Ptr doc, Node *currentObject) if (Document::Ptr scriptDoc = _snapshot.document(scriptFile)) { if (scriptDoc->jsProgram()) { - _context.pushScope(scriptDoc->bind()->_rootObjectValue); + _context->pushScope(scriptDoc->bind()->_rootObjectValue); } } } if (bind->_functionEnvironment) - _context.pushScope(bind->_functionEnvironment); + _context->pushScope(bind->_functionEnvironment); if (bind->_idEnvironment) - _context.pushScope(bind->_idEnvironment); + _context->pushScope(bind->_idEnvironment); - if (const ObjectValue *typeEnvironment = _context.typeEnvironment(doc.data())) - _context.pushScope(typeEnvironment); + if (const ObjectValue *typeEnvironment = _context->typeEnvironment(doc.data())) + _context->pushScope(typeEnvironment); } void Link::linkImports() @@ -92,7 +86,7 @@ void Link::linkImports() // Populate the _typeEnvironment with imports. populateImportedTypes(typeEnv, doc); - _context.setTypeEnvironment(doc.data(), typeEnv); + _context->setTypeEnvironment(doc.data(), typeEnv); } } diff --git a/src/libs/qmljs/qmljslink.h b/src/libs/qmljs/qmljslink.h index fd92fd06149d7aaf5c8135c6a45ec6c46f2ffa85..c6329fef324c0f24c78cb8dfe81cd429aacbd2df 100644 --- a/src/libs/qmljs/qmljslink.h +++ b/src/libs/qmljs/qmljslink.h @@ -2,34 +2,32 @@ #define QMLJSLINK_H #include <qmljs/qmljsdocument.h> -#include <qmljs/qmljsbind.h> #include <qmljs/qmljsinterpreter.h> #include <qmljs/parser/qmljsastfwd_p.h> -#include <qmljs/parser/qmljsengine_p.h> #include <QtCore/QList> #include <QtCore/QHash> namespace QmlJS { +class NameId; + /* - Temporarily links a set of bound documents together to allow resolving cross-document - dependencies. The link is undone when this object is destoyed. + Helper for building a context. */ -class QMLJS_EXPORT Link +class Link { public: // Link all documents in snapshot reachable from doc. - Link(Document::Ptr doc, const Snapshot &snapshot, Interpreter::Engine *interp); + Link(Interpreter::Context *context, Document::Ptr doc, const Snapshot &snapshot); ~Link(); - Interpreter::Context *context(); - Interpreter::Engine *engine(); - // Get the scope chain for the currentObject inside doc. void scopeChainAt(Document::Ptr doc, AST::Node *currentObject); private: + Interpreter::Engine *engine(); + static QList<Document::Ptr> reachableDocuments(Document::Ptr startDoc, const Snapshot &snapshot); static AST::UiQualifiedId *qualifiedTypeNameId(AST::Node *node); @@ -44,7 +42,7 @@ private: private: Snapshot _snapshot; - Interpreter::Context _context; + Interpreter::Context *_context; QList<Document::Ptr> _docs; }; diff --git a/src/plugins/qmljseditor/qmlcodecompletion.cpp b/src/plugins/qmljseditor/qmlcodecompletion.cpp index d76b6eebace3bbaeb858ba907641f81b537a2b97..92a29f42093b26dbd23f4b7f9475ba5eb3342c8b 100644 --- a/src/plugins/qmljseditor/qmlcodecompletion.cpp +++ b/src/plugins/qmljseditor/qmlcodecompletion.cpp @@ -653,12 +653,11 @@ int QmlCodeCompletion::startCompletion(TextEditor::ITextEditable *editor) const QIcon symbolIcon = iconForColor(Qt::darkCyan); Interpreter::Engine interp; + Interpreter::Context context(&interp); // Set up the current scope chain. - Link link(document, snapshot, &interp); - AST::Node *declaringMember = semanticInfo.declaringMember(editor->position()); - link.scopeChainAt(document, declaringMember); + context.build(declaringMember, document, snapshot); // Search for the operator that triggered the completion. QChar completionOperator; @@ -668,7 +667,7 @@ int QmlCodeCompletion::startCompletion(TextEditor::ITextEditable *editor) if (completionOperator.isSpace() || completionOperator.isNull() || isDelimiter(completionOperator) || (completionOperator == QLatin1Char('(') && m_startPosition != editor->position())) { // It's a global completion. - EnumerateProperties enumerateProperties(link.context()); + EnumerateProperties enumerateProperties(&context); enumerateProperties.setGlobalCompletion(true); QHashIterator<QString, const Interpreter::Value *> it(enumerateProperties()); while (it.hasNext()) { @@ -691,14 +690,14 @@ int QmlCodeCompletion::startCompletion(TextEditor::ITextEditable *editor) //qDebug() << "expression:" << expression; if (expression != 0) { - Check evaluate(link.context()); + Check evaluate(&context); // Evaluate the expression under cursor. const Interpreter::Value *value = interp.convertToObject(evaluate(expression)); //qDebug() << "type:" << interp.typeId(value); if (value && completionOperator == QLatin1Char('.')) { // member completion - EnumerateProperties enumerateProperties(link.context()); + EnumerateProperties enumerateProperties(&context); QHashIterator<QString, const Interpreter::Value *> it(enumerateProperties(value)); while (it.hasNext()) { it.next(); diff --git a/src/plugins/qmljseditor/qmlhoverhandler.cpp b/src/plugins/qmljseditor/qmlhoverhandler.cpp index 5885be5383b4373e788912b45756bc5455147f8a..666b7ae92f0b35afd24841c7e4951af33fb0cc56 100644 --- a/src/plugins/qmljseditor/qmlhoverhandler.cpp +++ b/src/plugins/qmljseditor/qmlhoverhandler.cpp @@ -172,14 +172,14 @@ void QmlHoverHandler::updateHelpIdAndTooltip(TextEditor::ITextEditor *editor, in AST::Node *declaringMember = semanticInfo.declaringMember(pos); Interpreter::Engine interp; - Link link(qmlDocument, snapshot, &interp); - link.scopeChainAt(qmlDocument, declaringMember); + Interpreter::Context context(&interp); + context.build(declaringMember, qmlDocument, snapshot); - Check check(link.context()); + Check check(&context); const Interpreter::Value *value = check(node); QStringList baseClasses; - m_toolTip = prettyPrint(value, link.context(), &baseClasses); + m_toolTip = prettyPrint(value, &context, &baseClasses); foreach (const QString &baseClass, baseClasses) { QString helpId = QLatin1String("QML.");