diff --git a/src/libs/qmljs/qmljsbind.cpp b/src/libs/qmljs/qmljsbind.cpp index 8c453d0c2cb97e7e6c4d24b1c9c53cf2b0b32573..7935452be576cdc01e2e69c0e43be90beaf71caf 100644 --- a/src/libs/qmljs/qmljsbind.cpp +++ b/src/libs/qmljs/qmljsbind.cpp @@ -120,6 +120,42 @@ public: } }; +class ProcessSourceElements: protected AST::Visitor +{ + Interpreter::Engine *_interp; + +public: + ProcessSourceElements(Interpreter::Engine *interp) + : _interp(interp) + { + } + + void operator()(AST::Node *node) + { + if (node) + node->accept(this); + } + +protected: + using AST::Visitor::visit; + + virtual bool visit(FunctionDeclaration *ast) + { + if (ast->name) + _interp->globalObject()->setProperty(ast->name->asString(), new ASTFunctionValue(ast, _interp)); + + return false; + } + + virtual bool visit(VariableDeclaration *ast) + { + if (ast->name) + _interp->globalObject()->setProperty(ast->name->asString(), _interp->undefinedValue()); + + return false; + } +}; + } // end of anonymous namespace Bind::Bind(Document::Ptr doc, const Snapshot &snapshot, Interpreter::Engine *interp) @@ -152,6 +188,11 @@ Bind::~Bind() { } +QStringList Bind::includedScripts() const +{ + return _includedScripts; +} + ObjectValue *Bind::switchObjectValue(ObjectValue *newObjectValue) { ObjectValue *oldObjectValue = _currentObjectValue; @@ -177,10 +218,30 @@ ObjectValue *Bind::scopeChainAt(Document::Ptr currentDocument, const Snapshot &s LinkImports linkImports; Link link; + // link the import directives linkImports(binds); + + // link the scripts + QStringList includedScriptFiles; + foreach (Bind *bind, binds) + includedScriptFiles += bind->includedScripts(); + + includedScriptFiles.removeDuplicates(); + + ProcessSourceElements processSourceElements(interp); + + foreach (const QString &scriptFile, includedScriptFiles) { + if (Document::Ptr scriptDoc = snapshot.document(scriptFile)) { + if (AST::Program *program = scriptDoc->jsProgram()) { + processSourceElements(program); + } + } + } + ObjectValue *scope = interp->globalObject(); if (currentBind) scope = link(binds, currentBind, currentObject); + qDeleteAll(binds); return scope; @@ -222,8 +283,8 @@ void Bind::processScript(AST::UiQualifiedId *qualifiedId, AST::UiObjectInitializ if (bindingName == QLatin1String("source")) { if (StringLiteral *literal = cast<StringLiteral *>(expression(binding))) { QFileInfo fileInfo(QDir(_doc->path()), literal->value->asString()); - Document::Ptr script = _snapshot.document(fileInfo.absoluteFilePath()); - // ### process the script + const QString scriptPath = fileInfo.absoluteFilePath(); + _includedScripts.append(scriptPath); } } } else if (UiSourceElement *binding = cast<UiSourceElement *>(it->member)) { diff --git a/src/libs/qmljs/qmljsbind.h b/src/libs/qmljs/qmljsbind.h index a0196640e260181327fc13a008092e32ea2e804a..ec6f1c38f8f85f074be7cbf6d7b20b8bc111e371 100644 --- a/src/libs/qmljs/qmljsbind.h +++ b/src/libs/qmljs/qmljsbind.h @@ -35,6 +35,7 @@ #include <qmljs/qmljsinterpreter.h> #include <QtCore/QHash> +#include <QtCore/QStringList> namespace QmlJS { @@ -49,6 +50,8 @@ protected: public: virtual ~Bind(); + QStringList includedScripts() const; + // ### TODO: This methods should go. Bind each document after parsing, link later. static Interpreter::ObjectValue *scopeChainAt(Document::Ptr currentDocument, const Snapshot &snapshot, @@ -91,6 +94,7 @@ private: QHash<AST::UiObjectDefinition *, Interpreter::ObjectValue *> _qmlObjectDefinitions; QHash<AST::UiObjectBinding *, Interpreter::ObjectValue *> _qmlObjectBindings; + QStringList _includedScripts; friend class LinkImports; friend class Link; diff --git a/src/libs/qmljs/qmljslink.cpp b/src/libs/qmljs/qmljslink.cpp index 197faaf2db06f846e52596077b7972fa3b4c1b69..e86db8799a32dfce854679bea932d0bf1675cbf5 100644 --- a/src/libs/qmljs/qmljslink.cpp +++ b/src/libs/qmljs/qmljslink.cpp @@ -148,7 +148,6 @@ void LinkImports::operator()(const QList<Bind *> &binds) ObjectValue *Link::operator()(const QList<Bind *> &binds, Bind *currentBind, UiObjectMember *currentObject) { Q_UNUSED(binds); - ObjectValue *scopeObject; if (UiObjectDefinition *definition = cast<UiObjectDefinition *>(currentObject)) scopeObject = currentBind->_qmlObjectDefinitions.value(definition);