diff --git a/src/libs/qmljs/qmljsbind.cpp b/src/libs/qmljs/qmljsbind.cpp index 2a4713eda9cdac84dd5da7c454fac1c4dfe264e5..0ea48d737584f49f78752d578bbda82e25d4e164 100644 --- a/src/libs/qmljs/qmljsbind.cpp +++ b/src/libs/qmljs/qmljsbind.cpp @@ -44,6 +44,7 @@ Bind::Bind(Document::Ptr doc, const Snapshot &snapshot, Interpreter::Engine *int _currentObjectValue(0), _typeEnvironment(0), _idEnvironment(0), + _functionEnvironment(0), _interestingObjectValue(0), _rootObjectValue(0) { @@ -64,19 +65,21 @@ Interpreter::ObjectValue *Bind::operator()(UiObjectMember *member) _currentObjectValue = 0; _typeEnvironment = _interp->newObject(/*prototype =*/ 0); _idEnvironment = _interp->newObject(/*prototype =*/ 0); + _functionEnvironment = _interp->newObject(/*prototype =*/ 0); _interestingObjectValue = 0; _rootObjectValue = 0; accept(program); if (_interestingObjectValue) { - _idEnvironment->setScope(_interestingObjectValue); + _functionEnvironment->setScope(_interestingObjectValue); if (_interestingObjectValue != _rootObjectValue) _interestingObjectValue->setScope(_rootObjectValue); } else { - _idEnvironment->setScope(_rootObjectValue); + _functionEnvironment->setScope(_rootObjectValue); } + _idEnvironment->setScope(_functionEnvironment); _typeEnvironment->setScope(_idEnvironment); return _typeEnvironment; @@ -244,17 +247,26 @@ const ObjectValue *Bind::lookupType(UiQualifiedId *qualifiedTypeNameId) ObjectValue *Bind::bindObject(UiQualifiedId *qualifiedTypeNameId, UiObjectInitializer *initializer) { - const ObjectValue *prototype = lookupType(qualifiedTypeNameId); - ObjectValue *objectValue = _interp->newObject(prototype); - ObjectValue *oldObjectValue = switchObjectValue(objectValue); - if (oldObjectValue) - objectValue->setProperty("parent", oldObjectValue); - else - _rootObjectValue = objectValue; + ObjectValue *parentObjectValue; + + if (qualifiedTypeNameId && !qualifiedTypeNameId->next + && qualifiedTypeNameId->name->asString() == QLatin1String("Script") + ) { + // Script blocks all contribute to the same scope + parentObjectValue = switchObjectValue(_functionEnvironment); + } else { // normal component instance + const ObjectValue *prototype = lookupType(qualifiedTypeNameId); + ObjectValue *objectValue = _interp->newObject(prototype); + parentObjectValue = switchObjectValue(objectValue); + if (parentObjectValue) + objectValue->setProperty("parent", parentObjectValue); + else + _rootObjectValue = objectValue; + } accept(initializer); - return switchObjectValue(oldObjectValue); + return switchObjectValue(parentObjectValue); } bool Bind::visit(UiObjectDefinition *ast) @@ -656,9 +668,21 @@ bool Bind::visit(Finally *) return true; } -bool Bind::visit(FunctionDeclaration *) +bool Bind::visit(FunctionDeclaration *ast) { - return true; + if (!ast->name) + return false; + // the first declaration counts + if (_currentObjectValue->property(ast->name->asString())) + return false; + + Function *function = _interp->newFunction(); + for (FormalParameterList *iter = ast->formals; iter; iter = iter->next) { + function->addArgument(_interp->undefinedValue()); // ### introduce unknownValue + // ### store argument names + } + _currentObjectValue->setProperty(ast->name->asString(), function); + return false; // ### eventually want to visit function bodies } bool Bind::visit(FunctionExpression *) diff --git a/src/libs/qmljs/qmljsbind.h b/src/libs/qmljs/qmljsbind.h index 2eb017126811e7d48b37d527d4a1f7b7e34cd8a0..258e02d4622a4a17917c13ba34b3d01894fd1186 100644 --- a/src/libs/qmljs/qmljsbind.h +++ b/src/libs/qmljs/qmljsbind.h @@ -156,6 +156,7 @@ private: Interpreter::ObjectValue *_typeEnvironment; Interpreter::ObjectValue *_idEnvironment; + Interpreter::ObjectValue *_functionEnvironment; Interpreter::ObjectValue *_interestingObjectValue; Interpreter::ObjectValue *_rootObjectValue; };