forked from qt-creator/qt-creator
		
	
		
			
				
	
	
		
			732 lines
		
	
	
		
			15 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			732 lines
		
	
	
		
			15 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
/**************************************************************************
 | 
						|
**
 | 
						|
** This file is part of Qt Creator
 | 
						|
**
 | 
						|
** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
 | 
						|
**
 | 
						|
** Contact: Nokia Corporation (qt-info@nokia.com)
 | 
						|
**
 | 
						|
** Commercial Usage
 | 
						|
**
 | 
						|
** Licensees holding valid Qt Commercial licenses may use this file in
 | 
						|
** accordance with the Qt Commercial License Agreement provided with the
 | 
						|
** Software or, alternatively, in accordance with the terms contained in
 | 
						|
** a written agreement between you and Nokia.
 | 
						|
**
 | 
						|
** GNU Lesser General Public License Usage
 | 
						|
**
 | 
						|
** Alternatively, this file may be used under the terms of the GNU Lesser
 | 
						|
** General Public License version 2.1 as published by the Free Software
 | 
						|
** Foundation and appearing in the file LICENSE.LGPL included in the
 | 
						|
** packaging of this file.  Please review the following information to
 | 
						|
** ensure the GNU Lesser General Public License version 2.1 requirements
 | 
						|
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
 | 
						|
**
 | 
						|
** If you are unsure which license is appropriate for your use, please
 | 
						|
** contact the sales department at http://qt.nokia.com/contact.
 | 
						|
**
 | 
						|
**************************************************************************/
 | 
						|
 | 
						|
#include "parser/qmljsast_p.h"
 | 
						|
#include "qmljsbind.h"
 | 
						|
#include "qmljsmetatypesystem.h"
 | 
						|
#include <QtCore/QDebug>
 | 
						|
 | 
						|
using namespace QmlJS;
 | 
						|
using namespace QmlJS::AST;
 | 
						|
using namespace QmlJS::Interpreter;
 | 
						|
 | 
						|
Bind::Bind(Document::Ptr doc, const Snapshot &snapshot, Interpreter::Engine *interp)
 | 
						|
    : _doc(doc),
 | 
						|
      _snapshot(snapshot),
 | 
						|
      _interp(interp),
 | 
						|
      _interestingMember(0),
 | 
						|
      _currentObjectValue(0),
 | 
						|
      _typeEnvironment(0),
 | 
						|
      _idEnvironment(0),
 | 
						|
      _functionEnvironment(0),
 | 
						|
      _interestingObjectValue(0),
 | 
						|
      _rootObjectValue(0)
 | 
						|
{
 | 
						|
}
 | 
						|
 | 
						|
Bind::~Bind()
 | 
						|
{
 | 
						|
}
 | 
						|
 | 
						|
Interpreter::ObjectValue *Bind::operator()(UiObjectMember *member)
 | 
						|
{
 | 
						|
    UiProgram *program = _doc->qmlProgram();
 | 
						|
    if (!program)
 | 
						|
        return 0;
 | 
						|
 | 
						|
    _interestingMember = 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) {
 | 
						|
        _functionEnvironment->setScope(_interestingObjectValue);
 | 
						|
 | 
						|
        if (_interestingObjectValue != _rootObjectValue)
 | 
						|
            _interestingObjectValue->setScope(_rootObjectValue);
 | 
						|
    } else {
 | 
						|
        _functionEnvironment->setScope(_rootObjectValue);
 | 
						|
    }
 | 
						|
    _idEnvironment->setScope(_functionEnvironment);
 | 
						|
    _typeEnvironment->setScope(_idEnvironment);
 | 
						|
 | 
						|
    return _typeEnvironment;
 | 
						|
}
 | 
						|
 | 
						|
void Bind::accept(Node *node)
 | 
						|
{
 | 
						|
    Node::accept(node, this);
 | 
						|
}
 | 
						|
 | 
						|
bool Bind::visit(UiProgram *)
 | 
						|
{
 | 
						|
    return true;
 | 
						|
}
 | 
						|
 | 
						|
bool Bind::visit(UiImportList *)
 | 
						|
{
 | 
						|
    return true;
 | 
						|
}
 | 
						|
 | 
						|
static QString serialize(UiQualifiedId *qualifiedId, QChar delimiter)
 | 
						|
{
 | 
						|
    QString result;
 | 
						|
 | 
						|
    for (UiQualifiedId *iter = qualifiedId; iter; iter = iter->next) {
 | 
						|
        if (iter != qualifiedId)
 | 
						|
            result += delimiter;
 | 
						|
 | 
						|
        if (iter->name)
 | 
						|
            result += iter->name->asString();
 | 
						|
    }
 | 
						|
 | 
						|
    return result;
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
  import Qt 4.6
 | 
						|
  import Qt 4.6 as Xxx
 | 
						|
  (import com.nokia.qt is the same as the ones above)
 | 
						|
 | 
						|
  import "content"
 | 
						|
  import "content" as Xxx
 | 
						|
  import "content" 4.6
 | 
						|
  import "content" 4.6 as Xxx
 | 
						|
 | 
						|
  import "http://www.ovi.com/" as Ovi
 | 
						|
 */
 | 
						|
bool Bind::visit(UiImport *ast)
 | 
						|
{
 | 
						|
    if (! (ast->importUri || ast->fileName))
 | 
						|
        return false; // nothing to do.
 | 
						|
 | 
						|
    ObjectValue *namespaceObject = 0;
 | 
						|
 | 
						|
    if (ast->asToken.isValid()) { // with namespace we insert an object in the type env. to hold the imported types
 | 
						|
        if (!ast->importId)
 | 
						|
            return false; // this should never happen, but better be safe than sorry
 | 
						|
 | 
						|
        namespaceObject = _interp->newObject(/*prototype */ 0);
 | 
						|
 | 
						|
        _typeEnvironment->setProperty(ast->importId->asString(), namespaceObject);
 | 
						|
 | 
						|
    } else { // without namespace we insert all types directly into the type env.
 | 
						|
        namespaceObject = _typeEnvironment;
 | 
						|
    }
 | 
						|
 | 
						|
    // look at files first
 | 
						|
 | 
						|
    // else try the metaobject system
 | 
						|
    if (ast->importUri) {
 | 
						|
        const QString package = serialize(ast->importUri, '/');
 | 
						|
        int majorVersion = -1; // ### TODO: Check these magic version numbers
 | 
						|
        int minorVersion = -1; // ### TODO: Check these magic version numbers
 | 
						|
 | 
						|
        if (ast->versionToken.isValid()) {
 | 
						|
            const QString versionString = _doc->source().mid(ast->versionToken.offset, ast->versionToken.length);
 | 
						|
            const int dotIdx = versionString.indexOf(QLatin1Char('.'));
 | 
						|
            if (dotIdx == -1) {
 | 
						|
                // only major (which is probably invalid, but let's handle it anyway)
 | 
						|
                majorVersion = versionString.toInt();
 | 
						|
                minorVersion = 0; // ### TODO: Check with magic version numbers above
 | 
						|
            } else {
 | 
						|
                majorVersion = versionString.left(dotIdx).toInt();
 | 
						|
                minorVersion = versionString.mid(dotIdx + 1).toInt();
 | 
						|
            }
 | 
						|
        }
 | 
						|
#ifndef NO_DECLARATIVE_BACKEND
 | 
						|
        foreach (QmlObjectValue *object, _interp->metaTypeSystem().staticTypesForImport(package, majorVersion, minorVersion)) {
 | 
						|
            namespaceObject->setProperty(object->qmlTypeName(), object);
 | 
						|
        }
 | 
						|
#endif // NO_DECLARATIVE_BACKEND
 | 
						|
    } else if (ast->fileName) {
 | 
						|
        // got an import "contents"
 | 
						|
        const QString relativePath = ast->fileName->asString();
 | 
						|
        const QList<Document::Ptr> userComponents = _snapshot.importedDocuments(_doc, relativePath);
 | 
						|
        foreach (Document::Ptr userComponent, userComponents) {
 | 
						|
            if (UiProgram *program = userComponent->qmlProgram()) {
 | 
						|
                if (UiObjectMemberList *members = program->members) {
 | 
						|
                    if (UiObjectDefinition *def = cast<UiObjectDefinition *>(members->member)) {
 | 
						|
                        const ObjectValue *prototype = lookupType(def->qualifiedTypeNameId);
 | 
						|
                        ObjectValue *objectValue = _interp->newObject(prototype);
 | 
						|
                        if (def->initializer) {
 | 
						|
                            for (AST::UiObjectMemberList *it = def->initializer->members; it; it = it->next) {
 | 
						|
                                if (AST::UiPublicMember *prop = AST::cast<AST::UiPublicMember *>(it->member)) {
 | 
						|
                                    if (prop->name && prop->memberType) {
 | 
						|
                                        const QString propName = prop->name->asString();
 | 
						|
                                        const QString propType = prop->memberType->asString();
 | 
						|
                                        objectValue->setProperty(propName, _interp->defaultValueForBuiltinType(propType));
 | 
						|
                                    }
 | 
						|
                                }
 | 
						|
                            }
 | 
						|
                        }
 | 
						|
 | 
						|
                        const QString componentName = userComponent->componentName();
 | 
						|
 | 
						|
                        if (! componentName.isEmpty()) {
 | 
						|
                            objectValue->setClassName(componentName);
 | 
						|
                            namespaceObject->setProperty(componentName, objectValue);
 | 
						|
                        }
 | 
						|
                    }
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    return false;
 | 
						|
}
 | 
						|
 | 
						|
bool Bind::visit(UiPublicMember *ast)
 | 
						|
{
 | 
						|
    if (_currentObjectValue && ast->name && ast->memberType) {
 | 
						|
        const QString propName = ast->name->asString();
 | 
						|
        const QString propType = ast->memberType->asString();
 | 
						|
 | 
						|
        _currentObjectValue->setProperty(propName, _interp->defaultValueForBuiltinType(propType));
 | 
						|
    }
 | 
						|
 | 
						|
    return false;
 | 
						|
}
 | 
						|
 | 
						|
bool Bind::visit(UiSourceElement *)
 | 
						|
{
 | 
						|
    return true;
 | 
						|
}
 | 
						|
 | 
						|
const ObjectValue *Bind::lookupType(UiQualifiedId *qualifiedTypeNameId)
 | 
						|
{
 | 
						|
    const ObjectValue *objectValue = _typeEnvironment;
 | 
						|
 | 
						|
    for (UiQualifiedId *iter = qualifiedTypeNameId; objectValue && iter; iter = iter->next) {
 | 
						|
        if (! iter->name)
 | 
						|
            return 0;
 | 
						|
 | 
						|
        const Value *value = objectValue->property(iter->name->asString());
 | 
						|
        if (!value)
 | 
						|
            return 0;
 | 
						|
 | 
						|
        objectValue = value->asObjectValue();
 | 
						|
    }
 | 
						|
 | 
						|
    return objectValue;
 | 
						|
}
 | 
						|
 | 
						|
ObjectValue *Bind::bindObject(UiQualifiedId *qualifiedTypeNameId, UiObjectInitializer *initializer)
 | 
						|
{
 | 
						|
    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(parentObjectValue);
 | 
						|
}
 | 
						|
 | 
						|
bool Bind::visit(UiObjectDefinition *ast)
 | 
						|
{
 | 
						|
    ObjectValue *value = bindObject(ast->qualifiedTypeNameId, ast->initializer);
 | 
						|
 | 
						|
    if (_interestingMember == ast)
 | 
						|
        _interestingObjectValue = value;
 | 
						|
    return false;
 | 
						|
}
 | 
						|
 | 
						|
bool Bind::visit(UiObjectBinding *ast)
 | 
						|
{
 | 
						|
//    const QString name = serialize(ast->qualifiedId);
 | 
						|
    ObjectValue *value = bindObject(ast->qualifiedTypeNameId, ast->initializer);
 | 
						|
    // ### FIXME: we don't handle dot-properties correctly (i.e. font.size)
 | 
						|
//    _currentObjectValue->setProperty(name, value);
 | 
						|
 | 
						|
    if (_interestingMember == ast)
 | 
						|
        _interestingObjectValue = value;
 | 
						|
    return false;
 | 
						|
}
 | 
						|
 | 
						|
bool Bind::visit(UiObjectInitializer *)
 | 
						|
{
 | 
						|
    return true;
 | 
						|
}
 | 
						|
 | 
						|
bool Bind::visit(UiScriptBinding *ast)
 | 
						|
{
 | 
						|
    if (!(ast->qualifiedId->next) && ast->qualifiedId->name->asString() == "id")
 | 
						|
        if (ExpressionStatement *e = cast<ExpressionStatement*>(ast->statement))
 | 
						|
            if (IdentifierExpression *i = cast<IdentifierExpression*>(e->expression))
 | 
						|
                if (i->name)
 | 
						|
                    _idEnvironment->setProperty(i->name->asString(), _currentObjectValue);
 | 
						|
 | 
						|
    return false;
 | 
						|
}
 | 
						|
 | 
						|
bool Bind::visit(UiArrayBinding *)
 | 
						|
{
 | 
						|
    // ### FIXME: do we need to store the members into the property? Or, maybe the property type is an JS Array?
 | 
						|
 | 
						|
    return true;
 | 
						|
}
 | 
						|
 | 
						|
bool Bind::visit(UiObjectMemberList *)
 | 
						|
{
 | 
						|
    return true;
 | 
						|
}
 | 
						|
 | 
						|
bool Bind::visit(UiArrayMemberList *)
 | 
						|
{
 | 
						|
    return true;
 | 
						|
}
 | 
						|
 | 
						|
bool Bind::visit(UiQualifiedId *)
 | 
						|
{
 | 
						|
    return true;
 | 
						|
}
 | 
						|
 | 
						|
bool Bind::visit(UiSignature *)
 | 
						|
{
 | 
						|
    return true;
 | 
						|
}
 | 
						|
 | 
						|
bool Bind::visit(UiFormalList *)
 | 
						|
{
 | 
						|
    return true;
 | 
						|
}
 | 
						|
 | 
						|
bool Bind::visit(UiFormal *)
 | 
						|
{
 | 
						|
    return true;
 | 
						|
}
 | 
						|
 | 
						|
bool Bind::visit(ThisExpression *)
 | 
						|
{
 | 
						|
    return true;
 | 
						|
}
 | 
						|
 | 
						|
bool Bind::visit(IdentifierExpression *)
 | 
						|
{
 | 
						|
    return true;
 | 
						|
}
 | 
						|
 | 
						|
bool Bind::visit(NullExpression *)
 | 
						|
{
 | 
						|
    return true;
 | 
						|
}
 | 
						|
 | 
						|
bool Bind::visit(TrueLiteral *)
 | 
						|
{
 | 
						|
    return true;
 | 
						|
}
 | 
						|
 | 
						|
bool Bind::visit(FalseLiteral *)
 | 
						|
{
 | 
						|
    return true;
 | 
						|
}
 | 
						|
 | 
						|
bool Bind::visit(StringLiteral *)
 | 
						|
{
 | 
						|
    return true;
 | 
						|
}
 | 
						|
 | 
						|
bool Bind::visit(NumericLiteral *)
 | 
						|
{
 | 
						|
    return true;
 | 
						|
}
 | 
						|
 | 
						|
bool Bind::visit(RegExpLiteral *)
 | 
						|
{
 | 
						|
    return true;
 | 
						|
}
 | 
						|
 | 
						|
bool Bind::visit(ArrayLiteral *)
 | 
						|
{
 | 
						|
    return true;
 | 
						|
}
 | 
						|
 | 
						|
bool Bind::visit(ObjectLiteral *)
 | 
						|
{
 | 
						|
    return true;
 | 
						|
}
 | 
						|
 | 
						|
bool Bind::visit(ElementList *)
 | 
						|
{
 | 
						|
    return true;
 | 
						|
}
 | 
						|
 | 
						|
bool Bind::visit(Elision *)
 | 
						|
{
 | 
						|
    return true;
 | 
						|
}
 | 
						|
 | 
						|
bool Bind::visit(PropertyNameAndValueList *)
 | 
						|
{
 | 
						|
    return true;
 | 
						|
}
 | 
						|
 | 
						|
bool Bind::visit(NestedExpression *)
 | 
						|
{
 | 
						|
    return true;
 | 
						|
}
 | 
						|
 | 
						|
bool Bind::visit(IdentifierPropertyName *)
 | 
						|
{
 | 
						|
    return true;
 | 
						|
}
 | 
						|
 | 
						|
bool Bind::visit(StringLiteralPropertyName *)
 | 
						|
{
 | 
						|
    return true;
 | 
						|
}
 | 
						|
 | 
						|
bool Bind::visit(NumericLiteralPropertyName *)
 | 
						|
{
 | 
						|
    return true;
 | 
						|
}
 | 
						|
 | 
						|
bool Bind::visit(ArrayMemberExpression *)
 | 
						|
{
 | 
						|
    return true;
 | 
						|
}
 | 
						|
 | 
						|
bool Bind::visit(FieldMemberExpression *)
 | 
						|
{
 | 
						|
    return true;
 | 
						|
}
 | 
						|
 | 
						|
bool Bind::visit(NewMemberExpression *)
 | 
						|
{
 | 
						|
    return true;
 | 
						|
}
 | 
						|
 | 
						|
bool Bind::visit(NewExpression *)
 | 
						|
{
 | 
						|
    return true;
 | 
						|
}
 | 
						|
 | 
						|
bool Bind::visit(CallExpression *)
 | 
						|
{
 | 
						|
    return true;
 | 
						|
}
 | 
						|
 | 
						|
bool Bind::visit(ArgumentList *)
 | 
						|
{
 | 
						|
    return true;
 | 
						|
}
 | 
						|
 | 
						|
bool Bind::visit(PostIncrementExpression *)
 | 
						|
{
 | 
						|
    return true;
 | 
						|
}
 | 
						|
 | 
						|
bool Bind::visit(PostDecrementExpression *)
 | 
						|
{
 | 
						|
    return true;
 | 
						|
}
 | 
						|
 | 
						|
bool Bind::visit(DeleteExpression *)
 | 
						|
{
 | 
						|
    return true;
 | 
						|
}
 | 
						|
 | 
						|
bool Bind::visit(VoidExpression *)
 | 
						|
{
 | 
						|
    return true;
 | 
						|
}
 | 
						|
 | 
						|
bool Bind::visit(TypeOfExpression *)
 | 
						|
{
 | 
						|
    return true;
 | 
						|
}
 | 
						|
 | 
						|
bool Bind::visit(PreIncrementExpression *)
 | 
						|
{
 | 
						|
    return true;
 | 
						|
}
 | 
						|
 | 
						|
bool Bind::visit(PreDecrementExpression *)
 | 
						|
{
 | 
						|
    return true;
 | 
						|
}
 | 
						|
 | 
						|
bool Bind::visit(UnaryPlusExpression *)
 | 
						|
{
 | 
						|
    return true;
 | 
						|
}
 | 
						|
 | 
						|
bool Bind::visit(UnaryMinusExpression *)
 | 
						|
{
 | 
						|
    return true;
 | 
						|
}
 | 
						|
 | 
						|
bool Bind::visit(TildeExpression *)
 | 
						|
{
 | 
						|
    return true;
 | 
						|
}
 | 
						|
 | 
						|
bool Bind::visit(NotExpression *)
 | 
						|
{
 | 
						|
    return true;
 | 
						|
}
 | 
						|
 | 
						|
bool Bind::visit(BinaryExpression *)
 | 
						|
{
 | 
						|
    return true;
 | 
						|
}
 | 
						|
 | 
						|
bool Bind::visit(ConditionalExpression *)
 | 
						|
{
 | 
						|
    return true;
 | 
						|
}
 | 
						|
 | 
						|
bool Bind::visit(Expression *)
 | 
						|
{
 | 
						|
    return true;
 | 
						|
}
 | 
						|
 | 
						|
bool Bind::visit(Block *)
 | 
						|
{
 | 
						|
    return true;
 | 
						|
}
 | 
						|
 | 
						|
bool Bind::visit(StatementList *)
 | 
						|
{
 | 
						|
    return true;
 | 
						|
}
 | 
						|
 | 
						|
bool Bind::visit(VariableStatement *)
 | 
						|
{
 | 
						|
    return true;
 | 
						|
}
 | 
						|
 | 
						|
bool Bind::visit(VariableDeclarationList *)
 | 
						|
{
 | 
						|
    return true;
 | 
						|
}
 | 
						|
 | 
						|
bool Bind::visit(VariableDeclaration *)
 | 
						|
{
 | 
						|
    return true;
 | 
						|
}
 | 
						|
 | 
						|
bool Bind::visit(EmptyStatement *)
 | 
						|
{
 | 
						|
    return true;
 | 
						|
}
 | 
						|
 | 
						|
bool Bind::visit(ExpressionStatement *)
 | 
						|
{
 | 
						|
    return true;
 | 
						|
}
 | 
						|
 | 
						|
bool Bind::visit(IfStatement *)
 | 
						|
{
 | 
						|
    return true;
 | 
						|
}
 | 
						|
 | 
						|
bool Bind::visit(DoWhileStatement *)
 | 
						|
{
 | 
						|
    return true;
 | 
						|
}
 | 
						|
 | 
						|
bool Bind::visit(WhileStatement *)
 | 
						|
{
 | 
						|
    return true;
 | 
						|
}
 | 
						|
 | 
						|
bool Bind::visit(ForStatement *)
 | 
						|
{
 | 
						|
    return true;
 | 
						|
}
 | 
						|
 | 
						|
bool Bind::visit(LocalForStatement *)
 | 
						|
{
 | 
						|
    return true;
 | 
						|
}
 | 
						|
 | 
						|
bool Bind::visit(ForEachStatement *)
 | 
						|
{
 | 
						|
    return true;
 | 
						|
}
 | 
						|
 | 
						|
bool Bind::visit(LocalForEachStatement *)
 | 
						|
{
 | 
						|
    return true;
 | 
						|
}
 | 
						|
 | 
						|
bool Bind::visit(ContinueStatement *)
 | 
						|
{
 | 
						|
    return true;
 | 
						|
}
 | 
						|
 | 
						|
bool Bind::visit(BreakStatement *)
 | 
						|
{
 | 
						|
    return true;
 | 
						|
}
 | 
						|
 | 
						|
bool Bind::visit(ReturnStatement *)
 | 
						|
{
 | 
						|
    return true;
 | 
						|
}
 | 
						|
 | 
						|
bool Bind::visit(WithStatement *)
 | 
						|
{
 | 
						|
    return true;
 | 
						|
}
 | 
						|
 | 
						|
bool Bind::visit(SwitchStatement *)
 | 
						|
{
 | 
						|
    return true;
 | 
						|
}
 | 
						|
 | 
						|
bool Bind::visit(CaseBlock *)
 | 
						|
{
 | 
						|
    return true;
 | 
						|
}
 | 
						|
 | 
						|
bool Bind::visit(CaseClauses *)
 | 
						|
{
 | 
						|
    return true;
 | 
						|
}
 | 
						|
 | 
						|
bool Bind::visit(CaseClause *)
 | 
						|
{
 | 
						|
    return true;
 | 
						|
}
 | 
						|
 | 
						|
bool Bind::visit(DefaultClause *)
 | 
						|
{
 | 
						|
    return true;
 | 
						|
}
 | 
						|
 | 
						|
bool Bind::visit(LabelledStatement *)
 | 
						|
{
 | 
						|
    return true;
 | 
						|
}
 | 
						|
 | 
						|
bool Bind::visit(ThrowStatement *)
 | 
						|
{
 | 
						|
    return true;
 | 
						|
}
 | 
						|
 | 
						|
bool Bind::visit(TryStatement *)
 | 
						|
{
 | 
						|
    return true;
 | 
						|
}
 | 
						|
 | 
						|
bool Bind::visit(Catch *)
 | 
						|
{
 | 
						|
    return true;
 | 
						|
}
 | 
						|
 | 
						|
bool Bind::visit(Finally *)
 | 
						|
{
 | 
						|
    return true;
 | 
						|
}
 | 
						|
 | 
						|
bool Bind::visit(FunctionDeclaration *ast)
 | 
						|
{
 | 
						|
    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 *)
 | 
						|
{
 | 
						|
    return true;
 | 
						|
}
 | 
						|
 | 
						|
bool Bind::visit(FormalParameterList *)
 | 
						|
{
 | 
						|
    return true;
 | 
						|
}
 | 
						|
 | 
						|
bool Bind::visit(FunctionBody *)
 | 
						|
{
 | 
						|
    return true;
 | 
						|
}
 | 
						|
 | 
						|
bool Bind::visit(Program *)
 | 
						|
{
 | 
						|
    return true;
 | 
						|
}
 | 
						|
 | 
						|
bool Bind::visit(SourceElements *)
 | 
						|
{
 | 
						|
    return true;
 | 
						|
}
 | 
						|
 | 
						|
bool Bind::visit(FunctionSourceElement *)
 | 
						|
{
 | 
						|
    return true;
 | 
						|
}
 | 
						|
 | 
						|
bool Bind::visit(StatementSourceElement *)
 | 
						|
{
 | 
						|
    return true;
 | 
						|
}
 | 
						|
 | 
						|
bool Bind::visit(DebuggerStatement *)
 | 
						|
{
 | 
						|
    return true;
 | 
						|
}
 | 
						|
 | 
						|
ObjectValue *Bind::switchObjectValue(ObjectValue *newObjectValue)
 | 
						|
{
 | 
						|
    ObjectValue *oldObjectValue = _currentObjectValue;
 | 
						|
    _currentObjectValue = newObjectValue;
 | 
						|
    return oldObjectValue;
 | 
						|
}
 |