2010-01-21 15:54:19 +01:00
/**************************************************************************
* *
* * 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 "qmljsinterpreter.h"
2010-02-15 11:52:39 +01:00
# include "qmljsevaluate.h"
2010-02-04 10:19:37 +01:00
# include "qmljslink.h"
2010-02-03 14:31:03 +01:00
# include "parser/qmljsast_p.h"
2010-01-24 19:31:38 +01:00
# include <QtCore/QMetaObject>
# include <QtCore/QMetaProperty>
2010-01-21 15:54:19 +01:00
# include <QtCore/QDebug>
2010-01-24 13:29:46 +01:00
# ifndef NO_DECLARATIVE_BACKEND
2010-02-26 14:43:39 +01:00
# include <QtDeclarative / private / qdeclarativemetatype_p.h>
# include <QtDeclarative / private / qdeclarativeanchors_p.h> // ### remove me
# include <QtDeclarative / private / qdeclarativerectangle_p.h> // ### remove me
# include <QtDeclarative / private / qdeclarativevaluetype_p.h> // ### remove me
# include <QtDeclarative / private / qdeclarativeanimation_p.h> // ### remove me
2010-01-24 13:29:46 +01:00
# endif
2010-01-21 15:54:19 +01:00
using namespace QmlJS : : Interpreter ;
2010-02-03 14:31:03 +01:00
using namespace QmlJS : : AST ;
2010-01-21 15:54:19 +01:00
2010-02-01 13:54:44 +01:00
namespace {
class LookupMember : public MemberProcessor
{
QString _name ;
const Value * _value ;
bool process ( const QString & name , const Value * value )
{
if ( _value )
return false ;
if ( name = = _name ) {
_value = value ;
return false ;
}
return true ;
}
public :
LookupMember ( const QString & name )
: _name ( name ) , _value ( 0 ) { }
const Value * value ( ) const { return _value ; }
virtual bool processProperty ( const QString & name , const Value * value )
{
return process ( name , value ) ;
}
virtual bool processEnumerator ( const QString & name , const Value * value )
{
return process ( name , value ) ;
}
virtual bool processSignal ( const QString & name , const Value * value )
{
return process ( name , value ) ;
}
virtual bool processSlot ( const QString & name , const Value * value )
{
return process ( name , value ) ;
}
virtual bool processGeneratedSlot ( const QString & name , const Value * value )
{
return process ( name , value ) ;
}
} ;
} // end of anonymous namespace
2010-01-24 13:29:46 +01:00
# ifndef NO_DECLARATIVE_BACKEND
2010-02-01 13:54:44 +01:00
namespace {
2010-01-26 10:50:30 +01:00
class MetaFunction : public FunctionValue
{
QMetaMethod _method ;
public :
MetaFunction ( const QMetaMethod & method , Engine * engine )
: FunctionValue ( engine ) , _method ( method )
{
}
virtual const Value * returnValue ( ) const
{
return engine ( ) - > undefinedValue ( ) ;
}
virtual int argumentCount ( ) const
{
return _method . parameterNames ( ) . size ( ) ;
}
virtual const Value * argument ( int ) const
{
return engine ( ) - > undefinedValue ( ) ;
}
virtual QString argumentName ( int index ) const
{
if ( index < _method . parameterNames ( ) . size ( ) )
return _method . parameterNames ( ) . at ( index ) ;
return FunctionValue : : argumentName ( index ) ;
}
virtual bool isVariadic ( ) const
{
return false ;
}
virtual const Value * invoke ( const Activation * ) const
{
return engine ( ) - > undefinedValue ( ) ;
}
} ;
2010-02-01 13:54:44 +01:00
} // end of anonymous namespace
2010-01-28 15:50:58 +01:00
QmlObjectValue : : QmlObjectValue ( const QMetaObject * metaObject , const QString & qmlTypeName ,
int majorVersion , int minorVersion , Engine * engine )
: ObjectValue ( engine ) ,
_metaObject ( metaObject ) ,
_qmlTypeName ( qmlTypeName ) ,
_majorVersion ( majorVersion ) ,
_minorVersion ( minorVersion )
2010-01-27 12:40:02 +01:00
{
setClassName ( qmlTypeName ) ; // ### TODO: we probably need to do more than just this...
}
2010-01-24 13:29:46 +01:00
2010-01-26 14:50:52 +01:00
QmlObjectValue : : ~ QmlObjectValue ( ) { }
2010-01-24 13:29:46 +01:00
2010-02-03 15:39:57 +01:00
const Value * QmlObjectValue : : lookupMember ( const QString & name , Context * context ) const
2010-01-26 14:50:52 +01:00
{
2010-02-03 15:39:57 +01:00
return ObjectValue : : lookupMember ( name , context ) ;
2010-02-01 13:54:44 +01:00
}
2010-01-26 10:50:30 +01:00
2010-02-01 13:54:44 +01:00
const Value * QmlObjectValue : : findOrCreateSignature ( int index , const QMetaMethod & method , QString * methodName ) const
{
const QString signature = QString : : fromUtf8 ( method . signature ( ) ) ;
2010-01-26 10:50:30 +01:00
2010-02-01 13:54:44 +01:00
const int indexOfParen = signature . indexOf ( QLatin1Char ( ' ( ' ) ) ;
if ( indexOfParen = = - 1 )
return engine ( ) - > undefinedValue ( ) ; // skip it, invalid signature.
2010-01-26 10:50:30 +01:00
2010-02-01 13:54:44 +01:00
* methodName = signature . left ( indexOfParen ) ;
const Value * value = _metaSignature . value ( index ) ;
if ( ! value ) {
value = new MetaFunction ( method , engine ( ) ) ;
_metaSignature . insert ( index , value ) ;
2010-01-24 13:29:46 +01:00
}
2010-02-01 13:54:44 +01:00
return value ;
2010-01-26 14:50:52 +01:00
}
2010-01-24 13:29:46 +01:00
2010-01-26 14:50:52 +01:00
void QmlObjectValue : : processMembers ( MemberProcessor * processor ) const
{
2010-02-01 13:54:44 +01:00
// process the meta enums
2010-01-28 15:50:58 +01:00
for ( int index = _metaObject - > enumeratorOffset ( ) ; index < _metaObject - > propertyCount ( ) ; + + index ) {
QMetaEnum e = _metaObject - > enumerator ( index ) ;
for ( int i = 0 ; i < e . keyCount ( ) ; + + i ) {
processor - > processEnumerator ( QString : : fromUtf8 ( e . key ( i ) ) , engine ( ) - > numberValue ( ) ) ;
}
}
2010-02-01 13:54:44 +01:00
// process the meta properties
for ( int index = 0 ; index < _metaObject - > propertyCount ( ) ; + + index ) {
QMetaProperty prop = _metaObject - > property ( index ) ;
2010-01-25 14:48:44 +01:00
2010-02-01 13:54:44 +01:00
processor - > processProperty ( prop . name ( ) , propertyValue ( prop ) ) ;
}
2010-01-26 10:10:11 +01:00
2010-02-01 13:54:44 +01:00
// process the meta methods
for ( int index = 0 ; index < _metaObject - > methodCount ( ) ; + + index ) {
QMetaMethod method = _metaObject - > method ( index ) ;
QString methodName ;
const Value * signature = findOrCreateSignature ( index , method , & methodName ) ;
2010-01-26 10:19:42 +01:00
2010-01-26 14:50:52 +01:00
if ( method . methodType ( ) = = QMetaMethod : : Slot & & method . access ( ) = = QMetaMethod : : Public ) {
2010-02-01 13:54:44 +01:00
processor - > processSlot ( methodName , signature ) ;
2010-01-26 10:19:42 +01:00
2010-01-26 14:50:52 +01:00
} else if ( method . methodType ( ) = = QMetaMethod : : Signal & & method . access ( ) ! = QMetaMethod : : Private ) {
// process the signal
2010-02-01 13:54:44 +01:00
processor - > processSignal ( methodName , signature ) ;
2010-01-26 10:19:42 +01:00
2010-01-26 14:50:52 +01:00
QString slotName ;
slotName + = QLatin1String ( " on " ) ;
slotName + = methodName . at ( 0 ) . toUpper ( ) ;
slotName + = methodName . midRef ( 1 ) ;
2010-01-25 14:48:44 +01:00
2010-01-26 14:50:52 +01:00
// process the generated slot
2010-02-01 13:54:44 +01:00
processor - > processGeneratedSlot ( slotName , signature ) ;
2010-01-26 14:50:52 +01:00
}
2010-01-24 13:29:46 +01:00
}
2010-01-26 14:50:52 +01:00
ObjectValue : : processMembers ( processor ) ;
}
const Value * QmlObjectValue : : propertyValue ( const QMetaProperty & prop ) const
{
2010-02-26 14:43:39 +01:00
if ( QDeclarativeMetaType : : isQObject ( prop . userType ( ) ) ) {
QDeclarativeType * qmlPropertyType = QDeclarativeMetaType : : qmlType ( prop . userType ( ) ) ;
2010-01-24 13:29:46 +01:00
2010-01-26 14:50:52 +01:00
if ( qmlPropertyType & & ! qmlPropertyType - > qmlTypeName ( ) . isEmpty ( ) ) {
QString typeName = qmlPropertyType - > qmlTypeName ( ) ;
int slashIdx = typeName . lastIndexOf ( QLatin1Char ( ' / ' ) ) ;
QString package ;
if ( slashIdx ! = - 1 ) {
package = typeName . left ( slashIdx ) ;
typeName = typeName . mid ( slashIdx + 1 ) ;
}
if ( const ObjectValue * objectValue = engine ( ) - > newQmlObject ( typeName , package , qmlPropertyType - > majorVersion ( ) , qmlPropertyType - > minorVersion ( ) ) )
return objectValue ;
} else {
2010-01-24 13:29:46 +01:00
QString typeName = QString : : fromUtf8 ( prop . typeName ( ) ) ;
if ( typeName . endsWith ( QLatin1Char ( ' * ' ) ) )
typeName . truncate ( typeName . length ( ) - 1 ) ;
typeName . replace ( QLatin1Char ( ' . ' ) , QLatin1Char ( ' / ' ) ) ;
2010-02-26 14:43:39 +01:00
if ( const ObjectValue * objectValue = engine ( ) - > newQmlObject ( typeName , " " , - 1 , - 1 ) ) // ### we should extend this to lookup the property types in the QDeclarativeType object, instead of the QMetaProperty.
2010-01-24 13:29:46 +01:00
return objectValue ;
}
}
2010-01-26 14:50:52 +01:00
const Value * value = engine ( ) - > undefinedValue ( ) ;
switch ( prop . type ( ) ) {
case QMetaType : : QByteArray :
case QMetaType : : QString :
case QMetaType : : QUrl :
value = engine ( ) - > stringValue ( ) ;
break ;
case QMetaType : : Bool :
value = engine ( ) - > booleanValue ( ) ;
break ;
case QMetaType : : Int :
case QMetaType : : Float :
case QMetaType : : Double :
value = engine ( ) - > numberValue ( ) ;
break ;
case QMetaType : : QFont : {
// ### cache
ObjectValue * object = engine ( ) - > newObject ( /*prototype =*/ 0 ) ;
object - > setProperty ( " family " , engine ( ) - > stringValue ( ) ) ;
object - > setProperty ( " weight " , engine ( ) - > undefinedValue ( ) ) ; // ### make me an object
object - > setProperty ( " copitalization " , engine ( ) - > undefinedValue ( ) ) ; // ### make me an object
object - > setProperty ( " bold " , engine ( ) - > booleanValue ( ) ) ;
object - > setProperty ( " italic " , engine ( ) - > booleanValue ( ) ) ;
object - > setProperty ( " underline " , engine ( ) - > booleanValue ( ) ) ;
object - > setProperty ( " overline " , engine ( ) - > booleanValue ( ) ) ;
object - > setProperty ( " strikeout " , engine ( ) - > booleanValue ( ) ) ;
object - > setProperty ( " pointSize " , engine ( ) - > numberValue ( ) ) ;
object - > setProperty ( " pixelSize " , engine ( ) - > numberValue ( ) ) ;
object - > setProperty ( " letterSpacing " , engine ( ) - > numberValue ( ) ) ;
object - > setProperty ( " wordSpacing " , engine ( ) - > numberValue ( ) ) ;
value = object ;
} break ;
case QMetaType : : QPoint :
2010-02-18 14:53:44 +01:00
case QMetaType : : QPointF :
case QMetaType : : QVector2D : {
2010-01-26 14:50:52 +01:00
// ### cache
ObjectValue * object = engine ( ) - > newObject ( /*prototype =*/ 0 ) ;
object - > setProperty ( " x " , engine ( ) - > numberValue ( ) ) ;
object - > setProperty ( " y " , engine ( ) - > numberValue ( ) ) ;
value = object ;
} break ;
case QMetaType : : QRect :
case QMetaType : : QRectF : {
// ### cache
ObjectValue * object = engine ( ) - > newObject ( /*prototype =*/ 0 ) ;
object - > setProperty ( " x " , engine ( ) - > numberValue ( ) ) ;
object - > setProperty ( " y " , engine ( ) - > numberValue ( ) ) ;
object - > setProperty ( " width " , engine ( ) - > numberValue ( ) ) ;
object - > setProperty ( " height " , engine ( ) - > numberValue ( ) ) ;
value = object ;
} break ;
2010-02-18 14:53:44 +01:00
case QMetaType : : QVector3D : {
// ### cache
ObjectValue * object = engine ( ) - > newObject ( /*prototype =*/ 0 ) ;
object - > setProperty ( " x " , engine ( ) - > numberValue ( ) ) ;
object - > setProperty ( " y " , engine ( ) - > numberValue ( ) ) ;
object - > setProperty ( " z " , engine ( ) - > numberValue ( ) ) ;
value = object ;
} break ;
2010-02-23 14:36:38 +01:00
case QMetaType : : QColor : {
value = engine ( ) - > colorValue ( ) ;
} break ;
2010-01-26 14:50:52 +01:00
default :
break ;
} // end of switch
2010-02-19 15:10:39 +01:00
const QString typeName = prop . typeName ( ) ;
2010-02-26 14:43:39 +01:00
if ( typeName = = QLatin1String ( " QDeclarativeAnchorLine " ) ) {
2010-02-23 17:02:50 +01:00
value = engine ( ) - > anchorLineValue ( ) ;
2010-02-19 15:10:39 +01:00
}
if ( value - > asStringValue ( ) & & prop . name ( ) = = QLatin1String ( " easing " )
2010-02-26 14:43:39 +01:00
& & isDerivedFrom ( & QDeclarativePropertyAnimation : : staticMetaObject ) ) {
2010-02-19 15:10:39 +01:00
value = engine ( ) - > easingCurveNameValue ( ) ;
}
2010-01-26 14:50:52 +01:00
return value ;
}
2010-02-19 15:10:39 +01:00
bool QmlObjectValue : : isDerivedFrom ( const QMetaObject * base ) const
{
for ( const QMetaObject * iter = _metaObject ; iter ; iter = iter - > superClass ( ) ) {
if ( iter = = base )
return true ;
}
return false ;
}
2010-01-24 13:29:46 +01:00
# endif
2010-01-26 14:50:52 +01:00
namespace {
2010-01-24 11:10:01 +01:00
////////////////////////////////////////////////////////////////////////////////
// constructors
////////////////////////////////////////////////////////////////////////////////
class ObjectCtor : public Function
{
public :
ObjectCtor ( Engine * engine ) ;
2010-01-24 11:35:11 +01:00
virtual const Value * invoke ( const Activation * activation ) const ;
2010-01-24 11:10:01 +01:00
} ;
class FunctionCtor : public Function
{
public :
FunctionCtor ( Engine * engine ) ;
2010-01-24 11:35:11 +01:00
virtual const Value * invoke ( const Activation * activation ) const ;
2010-01-24 11:10:01 +01:00
} ;
class ArrayCtor : public Function
{
public :
ArrayCtor ( Engine * engine ) ;
2010-01-24 11:35:11 +01:00
virtual const Value * invoke ( const Activation * activation ) const ;
2010-01-24 11:10:01 +01:00
} ;
class StringCtor : public Function
{
public :
StringCtor ( Engine * engine ) ;
2010-01-24 11:35:11 +01:00
virtual const Value * invoke ( const Activation * activation ) const ;
2010-01-24 11:10:01 +01:00
} ;
class BooleanCtor : public Function
{
public :
BooleanCtor ( Engine * engine ) ;
2010-01-24 11:35:11 +01:00
virtual const Value * invoke ( const Activation * activation ) const ;
2010-01-24 11:10:01 +01:00
} ;
class NumberCtor : public Function
{
public :
NumberCtor ( Engine * engine ) ;
2010-01-24 11:35:11 +01:00
virtual const Value * invoke ( const Activation * activation ) const ;
2010-01-24 11:10:01 +01:00
} ;
class DateCtor : public Function
{
public :
DateCtor ( Engine * engine ) ;
2010-01-24 11:35:11 +01:00
virtual const Value * invoke ( const Activation * activation ) const ;
2010-01-24 11:10:01 +01:00
} ;
class RegExpCtor : public Function
{
public :
RegExpCtor ( Engine * engine ) ;
2010-01-24 11:35:11 +01:00
virtual const Value * invoke ( const Activation * activation ) const ;
2010-01-24 11:10:01 +01:00
} ;
ObjectCtor : : ObjectCtor ( Engine * engine )
: Function ( engine )
{
}
FunctionCtor : : FunctionCtor ( Engine * engine )
: Function ( engine )
{
}
ArrayCtor : : ArrayCtor ( Engine * engine )
: Function ( engine )
{
}
StringCtor : : StringCtor ( Engine * engine )
: Function ( engine )
{
}
BooleanCtor : : BooleanCtor ( Engine * engine )
: Function ( engine )
{
}
NumberCtor : : NumberCtor ( Engine * engine )
: Function ( engine )
{
}
DateCtor : : DateCtor ( Engine * engine )
: Function ( engine )
{
}
RegExpCtor : : RegExpCtor ( Engine * engine )
: Function ( engine )
{
}
2010-01-24 11:35:11 +01:00
const Value * ObjectCtor : : invoke ( const Activation * activation ) const
2010-01-24 11:10:01 +01:00
{
2010-01-24 11:35:11 +01:00
ObjectValue * thisObject = activation - > thisObject ( ) ;
if ( activation - > calledAsFunction ( ) )
thisObject = engine ( ) - > newObject ( ) ;
thisObject - > setClassName ( " Object " ) ;
thisObject - > setPrototype ( engine ( ) - > objectPrototype ( ) ) ;
thisObject - > setProperty ( " length " , engine ( ) - > numberValue ( ) ) ;
return thisObject ;
2010-01-24 11:10:01 +01:00
}
2010-01-24 11:35:11 +01:00
const Value * FunctionCtor : : invoke ( const Activation * activation ) const
2010-01-24 11:10:01 +01:00
{
2010-01-24 11:35:11 +01:00
ObjectValue * thisObject = activation - > thisObject ( ) ;
if ( activation - > calledAsFunction ( ) )
thisObject = engine ( ) - > newObject ( ) ;
thisObject - > setClassName ( " Function " ) ;
thisObject - > setPrototype ( engine ( ) - > functionPrototype ( ) ) ;
thisObject - > setProperty ( " length " , engine ( ) - > numberValue ( ) ) ;
return thisObject ;
2010-01-24 11:10:01 +01:00
}
2010-01-24 11:35:11 +01:00
const Value * ArrayCtor : : invoke ( const Activation * activation ) const
2010-01-24 11:10:01 +01:00
{
2010-01-24 11:35:11 +01:00
ObjectValue * thisObject = activation - > thisObject ( ) ;
if ( activation - > calledAsFunction ( ) )
thisObject = engine ( ) - > newObject ( ) ;
2010-01-24 11:10:01 +01:00
2010-01-24 11:35:11 +01:00
thisObject - > setClassName ( " Array " ) ;
thisObject - > setPrototype ( engine ( ) - > arrayPrototype ( ) ) ;
thisObject - > setProperty ( " length " , engine ( ) - > numberValue ( ) ) ;
return thisObject ;
2010-01-24 11:10:01 +01:00
}
2010-01-24 11:35:11 +01:00
const Value * StringCtor : : invoke ( const Activation * activation ) const
2010-01-24 11:10:01 +01:00
{
2010-01-24 11:35:11 +01:00
if ( activation - > calledAsFunction ( ) )
return engine ( ) - > convertToString ( activation - > thisObject ( ) ) ;
2010-01-24 11:10:01 +01:00
2010-01-24 11:35:11 +01:00
ObjectValue * thisObject = activation - > thisObject ( ) ;
thisObject - > setClassName ( " String " ) ;
thisObject - > setPrototype ( engine ( ) - > stringPrototype ( ) ) ;
thisObject - > setProperty ( " length " , engine ( ) - > numberValue ( ) ) ;
return thisObject ;
2010-01-24 11:10:01 +01:00
}
2010-01-24 11:35:11 +01:00
const Value * BooleanCtor : : invoke ( const Activation * activation ) const
2010-01-24 11:10:01 +01:00
{
2010-01-24 11:35:11 +01:00
if ( activation - > calledAsFunction ( ) )
return engine ( ) - > convertToBoolean ( activation - > thisObject ( ) ) ;
ObjectValue * thisObject = activation - > thisObject ( ) ;
thisObject - > setClassName ( " Boolean " ) ;
thisObject - > setPrototype ( engine ( ) - > booleanPrototype ( ) ) ;
return thisObject ;
2010-01-24 11:10:01 +01:00
}
2010-01-24 11:35:11 +01:00
const Value * NumberCtor : : invoke ( const Activation * activation ) const
2010-01-24 11:10:01 +01:00
{
2010-01-24 11:35:11 +01:00
if ( activation - > calledAsFunction ( ) )
return engine ( ) - > convertToNumber ( activation - > thisObject ( ) ) ;
ObjectValue * thisObject = activation - > thisObject ( ) ;
thisObject - > setClassName ( " Number " ) ;
thisObject - > setPrototype ( engine ( ) - > numberPrototype ( ) ) ;
return thisObject ;
2010-01-24 11:10:01 +01:00
}
2010-01-24 11:35:11 +01:00
const Value * DateCtor : : invoke ( const Activation * activation ) const
2010-01-24 11:10:01 +01:00
{
2010-01-24 11:35:11 +01:00
if ( activation - > calledAsFunction ( ) )
return engine ( ) - > stringValue ( ) ;
ObjectValue * thisObject = activation - > thisObject ( ) ;
thisObject - > setClassName ( " Date " ) ;
thisObject - > setPrototype ( engine ( ) - > datePrototype ( ) ) ;
return thisObject ;
2010-01-24 11:10:01 +01:00
}
2010-01-24 11:35:11 +01:00
const Value * RegExpCtor : : invoke ( const Activation * activation ) const
2010-01-24 11:10:01 +01:00
{
2010-01-24 11:35:11 +01:00
ObjectValue * thisObject = activation - > thisObject ( ) ;
if ( activation - > calledAsFunction ( ) )
thisObject = engine ( ) - > newObject ( ) ;
thisObject - > setClassName ( " RegExp " ) ;
thisObject - > setPrototype ( engine ( ) - > regexpPrototype ( ) ) ;
thisObject - > setProperty ( " source " , engine ( ) - > stringValue ( ) ) ;
thisObject - > setProperty ( " global " , engine ( ) - > booleanValue ( ) ) ;
thisObject - > setProperty ( " ignoreCase " , engine ( ) - > booleanValue ( ) ) ;
thisObject - > setProperty ( " multiline " , engine ( ) - > booleanValue ( ) ) ;
thisObject - > setProperty ( " lastIndex " , engine ( ) - > numberValue ( ) ) ;
return thisObject ;
2010-01-24 11:10:01 +01:00
}
} // end of anonymous namespace
2010-01-21 15:54:19 +01:00
////////////////////////////////////////////////////////////////////////////////
// ValueVisitor
////////////////////////////////////////////////////////////////////////////////
2010-01-24 11:10:01 +01:00
ValueVisitor : : ValueVisitor ( )
{
}
ValueVisitor : : ~ ValueVisitor ( )
{
}
void ValueVisitor : : visit ( const NullValue * )
{
}
void ValueVisitor : : visit ( const UndefinedValue * )
{
}
void ValueVisitor : : visit ( const NumberValue * )
{
}
void ValueVisitor : : visit ( const BooleanValue * )
{
}
void ValueVisitor : : visit ( const StringValue * )
{
}
void ValueVisitor : : visit ( const ObjectValue * )
{
}
void ValueVisitor : : visit ( const FunctionValue * )
{
}
2010-01-21 15:54:19 +01:00
2010-02-03 10:24:25 +01:00
void ValueVisitor : : visit ( const Reference * )
{
}
2010-01-21 15:54:19 +01:00
2010-02-19 15:10:39 +01:00
void ValueVisitor : : visit ( const EasingCurveNameValue * )
{
}
2010-02-23 14:36:38 +01:00
void ValueVisitor : : visit ( const ColorValue * )
{
}
2010-02-23 17:02:50 +01:00
void ValueVisitor : : visit ( const AnchorLineValue * )
{
}
2010-01-21 15:54:19 +01:00
////////////////////////////////////////////////////////////////////////////////
// Value
////////////////////////////////////////////////////////////////////////////////
2010-01-24 11:10:01 +01:00
Value : : Value ( )
{
}
Value : : ~ Value ( )
{
}
2010-02-08 12:50:10 +01:00
bool Value : : getSourceLocation ( QString * , int * , int * ) const
{
return false ;
}
2010-01-24 11:10:01 +01:00
const NullValue * Value : : asNullValue ( ) const
{
return 0 ;
}
const UndefinedValue * Value : : asUndefinedValue ( ) const
{
return 0 ;
}
const NumberValue * Value : : asNumberValue ( ) const
{
return 0 ;
}
const BooleanValue * Value : : asBooleanValue ( ) const
{
return 0 ;
}
const StringValue * Value : : asStringValue ( ) const
{
return 0 ;
}
const ObjectValue * Value : : asObjectValue ( ) const
{
return 0 ;
}
const FunctionValue * Value : : asFunctionValue ( ) const
{
return 0 ;
}
2010-01-21 15:54:19 +01:00
2010-02-03 10:24:25 +01:00
const Reference * Value : : asReference ( ) const
{
return 0 ;
}
2010-02-19 15:10:39 +01:00
const EasingCurveNameValue * Value : : asEasingCurveNameValue ( ) const
{
return 0 ;
}
2010-02-23 14:36:38 +01:00
const ColorValue * Value : : asColorValue ( ) const
{
return 0 ;
}
2010-02-23 17:02:50 +01:00
const AnchorLineValue * Value : : asAnchorLineValue ( ) const
{
return 0 ;
}
2010-01-21 15:54:19 +01:00
////////////////////////////////////////////////////////////////////////////////
// Values
////////////////////////////////////////////////////////////////////////////////
2010-01-24 11:10:01 +01:00
const NullValue * NullValue : : asNullValue ( ) const
{
return this ;
}
void NullValue : : accept ( ValueVisitor * visitor ) const
{
visitor - > visit ( this ) ;
}
const UndefinedValue * UndefinedValue : : asUndefinedValue ( ) const
{
return this ;
}
void UndefinedValue : : accept ( ValueVisitor * visitor ) const
{
visitor - > visit ( this ) ;
}
2010-01-21 15:54:19 +01:00
2010-01-24 11:10:01 +01:00
const NumberValue * NumberValue : : asNumberValue ( ) const
{
return this ;
}
void NumberValue : : accept ( ValueVisitor * visitor ) const
{
visitor - > visit ( this ) ;
}
const BooleanValue * BooleanValue : : asBooleanValue ( ) const
{
return this ;
}
void BooleanValue : : accept ( ValueVisitor * visitor ) const
{
visitor - > visit ( this ) ;
}
const StringValue * StringValue : : asStringValue ( ) const
{
return this ;
}
void StringValue : : accept ( ValueVisitor * visitor ) const
{
visitor - > visit ( this ) ;
}
2010-02-03 10:24:25 +01:00
2010-02-19 10:14:34 +01:00
ScopeChain : : ScopeChain ( )
: globalScope ( 0 )
, qmlTypes ( 0 )
{
}
2010-02-22 11:21:03 +01:00
ScopeChain : : QmlComponentChain : : QmlComponentChain ( )
: rootObject ( 0 ) , ids ( 0 )
{
}
ScopeChain : : QmlComponentChain : : ~ QmlComponentChain ( )
{
qDeleteAll ( instantiatingComponents ) ;
}
void ScopeChain : : QmlComponentChain : : clear ( )
{
qDeleteAll ( instantiatingComponents ) ;
instantiatingComponents . clear ( ) ;
rootObject = 0 ;
functionScopes . clear ( ) ;
ids = 0 ;
}
2010-02-19 10:14:34 +01:00
void ScopeChain : : QmlComponentChain : : add ( QList < const ObjectValue * > * list ) const
{
foreach ( QmlComponentChain * parent , instantiatingComponents )
parent - > add ( list ) ;
if ( rootObject )
list - > append ( rootObject ) ;
list - > append ( functionScopes ) ;
if ( ids )
list - > append ( ids ) ;
}
void ScopeChain : : update ( )
{
2010-02-22 10:21:07 +01:00
_all . clear ( ) ;
2010-02-19 10:14:34 +01:00
2010-02-22 10:21:07 +01:00
_all + = globalScope ;
2010-02-19 10:14:34 +01:00
foreach ( QmlComponentChain * parent , qmlComponentScope . instantiatingComponents )
2010-02-22 10:21:07 +01:00
parent - > add ( & _all ) ;
2010-02-19 10:14:34 +01:00
2010-02-23 12:34:52 +01:00
if ( qmlComponentScope . rootObject & & ! qmlScopeObjects . contains ( qmlComponentScope . rootObject ) )
2010-02-22 10:21:07 +01:00
_all + = qmlComponentScope . rootObject ;
_all + = qmlScopeObjects ;
_all + = qmlComponentScope . functionScopes ;
2010-02-19 10:14:34 +01:00
if ( qmlComponentScope . ids )
2010-02-22 10:21:07 +01:00
_all + = qmlComponentScope . ids ;
2010-02-19 10:14:34 +01:00
if ( qmlTypes )
2010-02-22 10:21:07 +01:00
_all + = qmlTypes ;
_all + = jsScopes ;
}
QList < const ObjectValue * > ScopeChain : : all ( ) const
{
return _all ;
2010-02-19 10:14:34 +01:00
}
2010-02-03 10:24:25 +01:00
Context : : Context ( Engine * engine )
2010-02-03 14:31:03 +01:00
: _engine ( engine ) ,
2010-02-16 10:36:09 +01:00
_lookupMode ( JSLookup ) ,
_qmlScopeObjectIndex ( - 1 ) ,
_qmlScopeObjectSet ( false )
2010-02-03 10:24:25 +01:00
{
}
Context : : ~ Context ( )
{
}
2010-02-22 11:57:32 +01:00
void Context : : build ( const QList < Node * > & astPath , QmlJS : : Document : : Ptr doc , const QmlJS : : Snapshot & snapshot )
2010-02-04 10:19:37 +01:00
{
Link link ( this , doc , snapshot ) ;
2010-02-19 12:25:26 +01:00
link . scopeChainAt ( doc , astPath ) ;
2010-02-04 10:19:37 +01:00
}
2010-02-03 10:24:25 +01:00
Engine * Context : : engine ( ) const
{
return _engine ;
}
2010-02-19 10:14:34 +01:00
const ScopeChain & Context : : scopeChain ( ) const
{
return _scopeChain ;
}
ScopeChain & Context : : scopeChain ( )
2010-02-03 14:31:03 +01:00
{
return _scopeChain ;
}
Context : : LookupMode Context : : lookupMode ( ) const
{
return _lookupMode ;
}
void Context : : setLookupMode ( LookupMode lookupMode )
{
_lookupMode = lookupMode ;
}
2010-02-04 11:08:57 +01:00
const ObjectValue * Context : : typeEnvironment ( const QmlJS : : Document * doc ) const
2010-02-03 15:39:57 +01:00
{
2010-02-04 09:44:43 +01:00
return _typeEnvironments . value ( doc , 0 ) ;
2010-02-03 15:39:57 +01:00
}
2010-02-04 11:08:57 +01:00
void Context : : setTypeEnvironment ( const QmlJS : : Document * doc , const ObjectValue * typeEnvironment )
2010-02-03 15:39:57 +01:00
{
2010-02-04 09:44:43 +01:00
_typeEnvironments [ doc ] = typeEnvironment ;
2010-02-03 15:39:57 +01:00
}
const Value * Context : : lookup ( const QString & name )
2010-02-03 14:31:03 +01:00
{
2010-02-22 10:21:07 +01:00
QList < const ObjectValue * > scopes = _scopeChain . all ( ) ;
2010-02-19 10:14:34 +01:00
for ( int index = scopes . size ( ) - 1 ; index ! = - 1 ; - - index ) {
const ObjectValue * scope = scopes . at ( index ) ;
2010-02-03 14:31:03 +01:00
2010-02-03 15:39:57 +01:00
if ( const Value * member = scope - > lookupMember ( name , this ) ) {
2010-02-03 14:31:03 +01:00
if ( _lookupMode = = JSLookup | | ! dynamic_cast < const ASTVariableReference * > ( member ) ) {
return member ;
}
}
}
return _engine - > undefinedValue ( ) ;
}
2010-02-04 11:08:57 +01:00
const ObjectValue * Context : : lookupType ( const QmlJS : : Document * doc , UiQualifiedId * qmlTypeName )
2010-02-03 15:39:57 +01:00
{
2010-02-04 09:44:43 +01:00
const ObjectValue * objectValue = typeEnvironment ( doc ) ;
2010-02-03 15:39:57 +01:00
for ( UiQualifiedId * iter = qmlTypeName ; objectValue & & iter ; iter = iter - > next ) {
if ( ! iter - > name )
return 0 ;
const Value * value = objectValue - > property ( iter - > name - > asString ( ) , this ) ;
if ( ! value )
return 0 ;
objectValue = value - > asObjectValue ( ) ;
}
return objectValue ;
}
2010-02-03 10:24:25 +01:00
const Value * Context : : property ( const ObjectValue * object , const QString & name ) const
{
const Properties properties = _properties . value ( object ) ;
return properties . value ( name , engine ( ) - > undefinedValue ( ) ) ;
}
void Context : : setProperty ( const ObjectValue * object , const QString & name , const Value * value )
{
_properties [ object ] . insert ( name , value ) ;
}
2010-02-03 14:31:03 +01:00
Reference : : Reference ( Engine * engine )
: _engine ( engine )
2010-02-03 10:24:25 +01:00
{
2010-02-03 14:31:03 +01:00
_engine - > registerValue ( this ) ;
2010-02-03 10:24:25 +01:00
}
Reference : : ~ Reference ( )
{
}
2010-02-03 14:31:03 +01:00
Engine * Reference : : engine ( ) const
{
return _engine ;
}
2010-02-03 10:24:25 +01:00
const Reference * Reference : : asReference ( ) const
{
return this ;
}
void Reference : : accept ( ValueVisitor * visitor ) const
{
visitor - > visit ( this ) ;
}
2010-02-03 14:31:03 +01:00
const Value * Reference : : value ( Context * ) const
{
return _engine - > undefinedValue ( ) ;
}
2010-02-03 10:24:25 +01:00
2010-02-19 15:10:39 +01:00
void EasingCurveNameValue : : accept ( ValueVisitor * visitor ) const
{
visitor - > visit ( this ) ;
}
QSet < QString > EasingCurveNameValue : : _curveNames ;
QSet < QString > EasingCurveNameValue : : curveNames ( )
{
if ( _curveNames . isEmpty ( ) ) {
_curveNames = QSet < QString > ( )
< < " easeLinear "
< < " easeInQuad "
< < " easeOutQuad "
< < " easeInOutQuad "
< < " easeOutInQuad "
< < " easeInCubic "
< < " easeOutCubic "
< < " easeInOutCubic "
< < " easeOutInCubic "
< < " easeInQuart "
< < " easeOutQuart "
< < " easeInOutQuart "
< < " easeOutInQuart "
< < " easeInQuint "
< < " easeOutQuint "
< < " easeInOutQuint "
< < " easeOutInQuint "
< < " easeInSine "
< < " easeOutSine "
< < " easeInOutSine "
< < " easeOutInSine "
< < " easeInExpo "
< < " easeOutExpo "
< < " easeInOutExpo "
< < " easeOutInExpo "
< < " easeInCirc "
< < " easeOutCirc "
< < " easeInOutCirc "
< < " easeOutInCirc "
< < " easeInElastic "
< < " easeOutElastic "
< < " easeInOutElastic "
< < " easeOutInElastic "
< < " easeInBack "
< < " easeOutBack "
< < " easeInOutBack "
< < " easeOutInBack "
< < " easeInBounce "
< < " easeOutBounce "
< < " easeInOutBounce "
< < " easeOutInBounce " ;
}
return _curveNames ;
}
const EasingCurveNameValue * EasingCurveNameValue : : asEasingCurveNameValue ( ) const
{
return this ;
}
2010-02-23 14:36:38 +01:00
void ColorValue : : accept ( ValueVisitor * visitor ) const
{
visitor - > visit ( this ) ;
}
const ColorValue * ColorValue : : asColorValue ( ) const
{
return this ;
}
2010-02-23 17:02:50 +01:00
void AnchorLineValue : : accept ( ValueVisitor * visitor ) const
{
visitor - > visit ( this ) ;
}
const AnchorLineValue * AnchorLineValue : : asAnchorLineValue ( ) const
{
return this ;
}
2010-01-26 10:10:11 +01:00
MemberProcessor : : MemberProcessor ( )
{
}
MemberProcessor : : ~ MemberProcessor ( )
{
}
bool MemberProcessor : : processProperty ( const QString & , const Value * )
{
return true ;
}
2010-01-28 15:50:58 +01:00
bool MemberProcessor : : processEnumerator ( const QString & , const Value * )
{
return true ;
}
2010-01-26 10:10:11 +01:00
bool MemberProcessor : : processSignal ( const QString & , const Value * )
{
return true ;
}
bool MemberProcessor : : processSlot ( const QString & , const Value * )
{
return true ;
}
2010-01-26 10:19:42 +01:00
bool MemberProcessor : : processGeneratedSlot ( const QString & , const Value * )
{
return true ;
}
2010-01-24 11:10:01 +01:00
ObjectValue : : ObjectValue ( Engine * engine )
2010-01-28 14:11:56 +01:00
: _engine ( engine ) ,
2010-02-03 10:59:52 +01:00
_prototype ( 0 )
2010-01-24 11:10:01 +01:00
{
2010-02-03 14:31:03 +01:00
engine - > registerValue ( this ) ;
2010-01-24 11:10:01 +01:00
}
ObjectValue : : ~ ObjectValue ( )
{
}
Engine * ObjectValue : : engine ( ) const
{
return _engine ;
}
QString ObjectValue : : className ( ) const
{
return _className ;
}
void ObjectValue : : setClassName ( const QString & className )
{
_className = className ;
}
2010-02-03 15:39:57 +01:00
const ObjectValue * ObjectValue : : prototype ( Context * context ) const
2010-01-24 11:10:01 +01:00
{
2010-02-03 15:39:57 +01:00
const ObjectValue * prototypeObject = value_cast < const ObjectValue * > ( _prototype ) ;
if ( ! prototypeObject ) {
if ( const Reference * prototypeReference = value_cast < const Reference * > ( _prototype ) ) {
prototypeObject = value_cast < const ObjectValue * > ( prototypeReference - > value ( context ) ) ;
}
}
return prototypeObject ;
}
void ObjectValue : : setPrototype ( const Value * prototype )
{
// ### FIXME: Check for cycles.
_prototype = prototype ;
2010-01-24 11:10:01 +01:00
}
void ObjectValue : : setProperty ( const QString & name , const Value * value )
{
_members [ name ] = value ;
}
void ObjectValue : : removeProperty ( const QString & name )
{
_members . remove ( name ) ;
}
const ObjectValue * ObjectValue : : asObjectValue ( ) const
{
return this ;
}
void ObjectValue : : accept ( ValueVisitor * visitor ) const
{
visitor - > visit ( this ) ;
}
2010-02-03 15:39:57 +01:00
const Value * ObjectValue : : property ( const QString & name , Context * context ) const
2010-01-24 11:10:01 +01:00
{
2010-02-03 15:39:57 +01:00
return lookupMember ( name , context ) ;
2010-01-21 15:54:19 +01:00
}
2010-02-03 15:39:57 +01:00
bool ObjectValue : : checkPrototype ( const ObjectValue * , QSet < const ObjectValue * > * ) const
2010-01-21 15:54:19 +01:00
{
2010-02-03 15:39:57 +01:00
#if 0
2010-01-21 15:54:19 +01:00
const int previousSize = processed - > size ( ) ;
processed - > insert ( this ) ;
if ( previousSize ! = processed - > size ( ) ) {
if ( this = = proto )
return false ;
2010-01-24 11:10:01 +01:00
if ( prototype ( ) & & ! prototype ( ) - > checkPrototype ( proto , processed ) )
2010-01-21 15:54:19 +01:00
return false ;
return true ;
}
2010-02-03 15:39:57 +01:00
# endif
2010-01-21 15:54:19 +01:00
return false ;
}
2010-01-24 11:10:01 +01:00
void ObjectValue : : processMembers ( MemberProcessor * processor ) const
{
QHashIterator < QString , const Value * > it ( _members ) ;
while ( it . hasNext ( ) ) {
it . next ( ) ;
2010-01-26 10:10:11 +01:00
if ( ! processor - > processProperty ( it . key ( ) , it . value ( ) ) )
2010-01-24 11:10:01 +01:00
break ;
}
}
2010-02-03 15:39:57 +01:00
const Value * ObjectValue : : lookupMember ( const QString & name , Context * context ) const
2010-01-24 11:10:01 +01:00
{
2010-01-24 13:29:46 +01:00
if ( const Value * m = _members . value ( name ) )
2010-01-24 11:10:01 +01:00
return m ;
2010-02-01 13:54:44 +01:00
else {
LookupMember slowLookup ( name ) ;
processMembers ( & slowLookup ) ;
if ( slowLookup . value ( ) )
return slowLookup . value ( ) ;
}
2010-01-24 11:10:01 +01:00
2010-02-03 15:39:57 +01:00
const ObjectValue * prototypeObject = prototype ( context ) ;
if ( prototypeObject ) {
if ( const Value * m = prototypeObject - > lookupMember ( name , context ) )
2010-01-24 11:10:01 +01:00
return m ;
}
return 0 ;
}
2010-02-03 15:39:57 +01:00
Activation : : Activation ( Context * parentContext )
2010-01-28 14:11:56 +01:00
: _thisObject ( 0 ) ,
2010-02-03 15:39:57 +01:00
_calledAsFunction ( true ) ,
_parentContext ( parentContext )
2010-01-24 11:35:11 +01:00
{
}
Activation : : ~ Activation ( )
{
}
2010-02-03 15:39:57 +01:00
Context * Activation : : parentContext ( ) const
{
return _parentContext ;
}
Context * Activation : : context ( ) const
{
// ### FIXME: Real context for activations.
return 0 ;
}
2010-01-24 11:35:11 +01:00
bool Activation : : calledAsConstructor ( ) const
{
return ! _calledAsFunction ;
}
void Activation : : setCalledAsConstructor ( bool calledAsConstructor )
{
_calledAsFunction = ! calledAsConstructor ;
}
bool Activation : : calledAsFunction ( ) const
{
return _calledAsFunction ;
}
void Activation : : setCalledAsFunction ( bool calledAsFunction )
{
_calledAsFunction = calledAsFunction ;
}
ObjectValue * Activation : : thisObject ( ) const
{
return _thisObject ;
}
void Activation : : setThisObject ( ObjectValue * thisObject )
{
_thisObject = thisObject ;
}
ValueList Activation : : arguments ( ) const
{
return _arguments ;
}
void Activation : : setArguments ( const ValueList & arguments )
{
_arguments = arguments ;
}
2010-01-24 11:10:01 +01:00
FunctionValue : : FunctionValue ( Engine * engine )
: ObjectValue ( engine )
{
}
FunctionValue : : ~ FunctionValue ( )
{
}
const Value * FunctionValue : : construct ( const ValueList & actuals ) const
{
2010-01-28 14:11:56 +01:00
Activation activation ;
2010-01-24 11:35:11 +01:00
activation . setCalledAsConstructor ( true ) ;
activation . setThisObject ( engine ( ) - > newObject ( ) ) ;
activation . setArguments ( actuals ) ;
return invoke ( & activation ) ;
2010-01-24 11:10:01 +01:00
}
const Value * FunctionValue : : call ( const ValueList & actuals ) const
{
2010-01-28 14:11:56 +01:00
Activation activation ;
2010-01-24 11:35:11 +01:00
activation . setCalledAsFunction ( true ) ;
activation . setThisObject ( engine ( ) - > globalObject ( ) ) ; // ### FIXME: it should be `null'
activation . setArguments ( actuals ) ;
return invoke ( & activation ) ;
2010-01-24 11:10:01 +01:00
}
const Value * FunctionValue : : call ( const ObjectValue * thisObject , const ValueList & actuals ) const
{
2010-01-28 14:11:56 +01:00
Activation activation ;
2010-01-24 11:35:11 +01:00
activation . setCalledAsFunction ( true ) ;
activation . setThisObject ( const_cast < ObjectValue * > ( thisObject ) ) ; // ### FIXME: remove the const_cast
activation . setArguments ( actuals ) ;
return invoke ( & activation ) ;
2010-01-24 11:10:01 +01:00
}
2010-01-26 10:50:30 +01:00
const Value * FunctionValue : : returnValue ( ) const
{
return engine ( ) - > undefinedValue ( ) ;
}
2010-01-24 11:10:01 +01:00
int FunctionValue : : argumentCount ( ) const
{
return 0 ;
}
2010-01-26 10:50:30 +01:00
const Value * FunctionValue : : argument ( int ) const
{
return engine ( ) - > undefinedValue ( ) ;
}
QString FunctionValue : : argumentName ( int index ) const
{
2010-02-01 12:43:36 +01:00
return QString : : fromLatin1 ( " arg%1 " ) . arg ( index + 1 ) ;
2010-01-26 10:50:30 +01:00
}
bool FunctionValue : : isVariadic ( ) const
{
return true ;
}
const Value * FunctionValue : : invoke ( const Activation * activation ) const
{
return activation - > thisObject ( ) ; // ### FIXME: it should return undefined
}
2010-01-24 11:10:01 +01:00
const FunctionValue * FunctionValue : : asFunctionValue ( ) const
{
return this ;
}
void FunctionValue : : accept ( ValueVisitor * visitor ) const
{
visitor - > visit ( this ) ;
}
Function : : Function ( Engine * engine )
: FunctionValue ( engine ) , _returnValue ( 0 )
2010-01-21 15:54:19 +01:00
{
2010-01-24 11:10:01 +01:00
setClassName ( " Function " ) ;
2010-01-21 15:54:19 +01:00
}
2010-01-24 11:35:11 +01:00
Function : : ~ Function ( )
{
}
2010-01-24 11:10:01 +01:00
void Function : : addArgument ( const Value * argument )
2010-01-21 15:54:19 +01:00
{
2010-01-24 11:10:01 +01:00
_arguments . push_back ( argument ) ;
2010-01-21 15:54:19 +01:00
}
2010-01-24 11:10:01 +01:00
const Value * Function : : returnValue ( ) const
2010-01-21 15:54:19 +01:00
{
2010-01-24 11:10:01 +01:00
return _returnValue ;
2010-01-21 15:54:19 +01:00
}
2010-01-24 11:10:01 +01:00
void Function : : setReturnValue ( const Value * returnValue )
{
_returnValue = returnValue ;
}
2010-01-21 15:54:19 +01:00
2010-01-24 11:10:01 +01:00
int Function : : argumentCount ( ) const
{
return _arguments . size ( ) ;
}
2010-01-21 15:54:19 +01:00
2010-01-24 11:10:01 +01:00
const Value * Function : : argument ( int index ) const
{
return _arguments . at ( index ) ;
}
2010-01-21 15:54:19 +01:00
2010-02-03 15:39:57 +01:00
const Value * Function : : property ( const QString & name , Context * context ) const
2010-01-21 15:54:19 +01:00
{
if ( name = = " length " )
return engine ( ) - > numberValue ( ) ;
2010-02-03 15:39:57 +01:00
return FunctionValue : : property ( name , context ) ;
2010-01-21 15:54:19 +01:00
}
2010-01-24 11:35:11 +01:00
const Value * Function : : invoke ( const Activation * activation ) const
2010-01-21 15:54:19 +01:00
{
2010-01-24 11:35:11 +01:00
return activation - > thisObject ( ) ; // ### FIXME it should return undefined
2010-01-21 15:54:19 +01:00
}
////////////////////////////////////////////////////////////////////////////////
// typing environment
////////////////////////////////////////////////////////////////////////////////
2010-01-24 11:10:01 +01:00
ConvertToNumber : : ConvertToNumber ( Engine * engine )
: _engine ( engine ) , _result ( 0 )
{
}
2010-01-21 15:54:19 +01:00
2010-01-24 11:10:01 +01:00
const Value * ConvertToNumber : : operator ( ) ( const Value * value )
{
2010-01-21 15:54:19 +01:00
const Value * previousValue = switchResult ( 0 ) ;
if ( value )
value - > accept ( this ) ;
return switchResult ( previousValue ) ;
}
2010-01-24 11:10:01 +01:00
const Value * ConvertToNumber : : switchResult ( const Value * value )
{
2010-01-21 15:54:19 +01:00
const Value * previousResult = _result ;
_result = value ;
return previousResult ;
}
2010-01-26 15:12:47 +01:00
void ConvertToNumber : : visit ( const NullValue * )
{
_result = _engine - > numberValue ( ) ;
}
void ConvertToNumber : : visit ( const UndefinedValue * )
{
_result = _engine - > numberValue ( ) ;
}
void ConvertToNumber : : visit ( const NumberValue * value )
{
_result = value ;
}
void ConvertToNumber : : visit ( const BooleanValue * )
{
_result = _engine - > numberValue ( ) ;
}
void ConvertToNumber : : visit ( const StringValue * )
{
_result = _engine - > numberValue ( ) ;
}
void ConvertToNumber : : visit ( const ObjectValue * object )
{
2010-02-03 15:39:57 +01:00
if ( const FunctionValue * valueOfMember = value_cast < const FunctionValue * > ( object - > lookupMember ( " valueOf " , 0 ) ) ) {
2010-01-26 15:12:47 +01:00
_result = value_cast < const NumberValue * > ( valueOfMember - > call ( object ) ) ; // ### invoke convert-to-number?
}
}
void ConvertToNumber : : visit ( const FunctionValue * object )
{
2010-02-03 15:39:57 +01:00
if ( const FunctionValue * valueOfMember = value_cast < const FunctionValue * > ( object - > lookupMember ( " valueOf " , 0 ) ) ) {
2010-01-26 15:12:47 +01:00
_result = value_cast < const NumberValue * > ( valueOfMember - > call ( object ) ) ; // ### invoke convert-to-number?
}
}
2010-01-24 11:10:01 +01:00
ConvertToString : : ConvertToString ( Engine * engine )
: _engine ( engine ) , _result ( 0 )
{
}
2010-01-21 15:54:19 +01:00
2010-01-24 11:10:01 +01:00
const Value * ConvertToString : : operator ( ) ( const Value * value )
{
2010-01-21 15:54:19 +01:00
const Value * previousValue = switchResult ( 0 ) ;
if ( value )
value - > accept ( this ) ;
return switchResult ( previousValue ) ;
}
2010-01-24 11:10:01 +01:00
const Value * ConvertToString : : switchResult ( const Value * value )
{
2010-01-21 15:54:19 +01:00
const Value * previousResult = _result ;
_result = value ;
return previousResult ;
}
2010-01-26 15:12:47 +01:00
void ConvertToString : : visit ( const NullValue * )
{
_result = _engine - > stringValue ( ) ;
}
void ConvertToString : : visit ( const UndefinedValue * )
{
_result = _engine - > stringValue ( ) ;
}
void ConvertToString : : visit ( const NumberValue * )
{
_result = _engine - > stringValue ( ) ;
}
void ConvertToString : : visit ( const BooleanValue * )
{
_result = _engine - > stringValue ( ) ;
}
void ConvertToString : : visit ( const StringValue * value )
{
_result = value ;
}
void ConvertToString : : visit ( const ObjectValue * object )
{
2010-02-03 15:39:57 +01:00
if ( const FunctionValue * toStringMember = value_cast < const FunctionValue * > ( object - > lookupMember ( " toString " , 0 ) ) ) {
2010-01-26 15:12:47 +01:00
_result = value_cast < const StringValue * > ( toStringMember - > call ( object ) ) ; // ### invoke convert-to-string?
}
}
void ConvertToString : : visit ( const FunctionValue * object )
{
2010-02-03 15:39:57 +01:00
if ( const FunctionValue * toStringMember = value_cast < const FunctionValue * > ( object - > lookupMember ( " toString " , 0 ) ) ) {
2010-01-26 15:12:47 +01:00
_result = value_cast < const StringValue * > ( toStringMember - > call ( object ) ) ; // ### invoke convert-to-string?
}
}
2010-01-22 14:42:15 +01:00
ConvertToObject : : ConvertToObject ( Engine * engine )
: _engine ( engine ) , _result ( 0 )
{
}
2010-01-21 15:54:19 +01:00
2010-01-24 11:10:01 +01:00
const Value * ConvertToObject : : operator ( ) ( const Value * value )
{
2010-01-21 15:54:19 +01:00
const Value * previousValue = switchResult ( 0 ) ;
if ( value )
value - > accept ( this ) ;
return switchResult ( previousValue ) ;
}
2010-01-24 11:10:01 +01:00
const Value * ConvertToObject : : switchResult ( const Value * value )
{
2010-01-21 15:54:19 +01:00
const Value * previousResult = _result ;
_result = value ;
return previousResult ;
}
2010-01-22 14:42:15 +01:00
void ConvertToObject : : visit ( const NullValue * value )
{
_result = value ;
}
void ConvertToObject : : visit ( const UndefinedValue * )
{
_result = _engine - > nullValue ( ) ;
}
2010-01-24 11:10:01 +01:00
void ConvertToObject : : visit ( const NumberValue * value )
2010-01-22 14:42:15 +01:00
{
2010-01-24 11:10:01 +01:00
ValueList actuals ;
actuals . append ( value ) ;
_result = _engine - > numberCtor ( ) - > construct ( actuals ) ;
2010-01-22 14:42:15 +01:00
}
2010-01-24 11:10:01 +01:00
void ConvertToObject : : visit ( const BooleanValue * value )
2010-01-22 14:42:15 +01:00
{
2010-01-24 11:10:01 +01:00
ValueList actuals ;
actuals . append ( value ) ;
_result = _engine - > booleanCtor ( ) - > construct ( actuals ) ;
2010-01-22 14:42:15 +01:00
}
2010-01-24 11:10:01 +01:00
void ConvertToObject : : visit ( const StringValue * value )
2010-01-22 14:42:15 +01:00
{
2010-01-24 11:10:01 +01:00
ValueList actuals ;
actuals . append ( value ) ;
_result = _engine - > stringCtor ( ) - > construct ( actuals ) ;
2010-01-22 14:42:15 +01:00
}
void ConvertToObject : : visit ( const ObjectValue * object )
{
_result = object ;
}
void ConvertToObject : : visit ( const FunctionValue * object )
{
_result = object ;
}
2010-01-21 15:54:19 +01:00
QString TypeId : : operator ( ) ( const Value * value )
{
_result = QLatin1String ( " unknown " ) ;
if ( value )
value - > accept ( this ) ;
return _result ;
}
2010-01-24 11:10:01 +01:00
void TypeId : : visit ( const NullValue * )
2010-01-21 15:54:19 +01:00
{
2010-01-24 11:10:01 +01:00
_result = QLatin1String ( " null " ) ;
}
2010-01-21 15:54:19 +01:00
2010-01-24 11:10:01 +01:00
void TypeId : : visit ( const UndefinedValue * )
2010-01-21 15:54:19 +01:00
{
2010-01-24 11:10:01 +01:00
_result = QLatin1String ( " undefined " ) ;
}
2010-01-21 15:54:19 +01:00
2010-01-24 11:10:01 +01:00
void TypeId : : visit ( const NumberValue * )
2010-01-21 15:54:19 +01:00
{
2010-01-24 11:10:01 +01:00
_result = QLatin1String ( " number " ) ;
}
2010-01-21 15:54:19 +01:00
2010-01-24 11:10:01 +01:00
void TypeId : : visit ( const BooleanValue * )
2010-01-21 15:54:19 +01:00
{
2010-01-24 11:10:01 +01:00
_result = QLatin1String ( " boolean " ) ;
}
2010-01-21 15:54:19 +01:00
2010-01-24 11:10:01 +01:00
void TypeId : : visit ( const StringValue * )
2010-01-21 15:54:19 +01:00
{
2010-01-24 11:10:01 +01:00
_result = QLatin1String ( " string " ) ;
}
2010-01-21 15:54:19 +01:00
2010-01-24 11:10:01 +01:00
void TypeId : : visit ( const ObjectValue * object )
2010-01-21 15:54:19 +01:00
{
2010-01-24 11:10:01 +01:00
_result = object - > className ( ) ;
2010-01-21 15:54:19 +01:00
2010-01-24 11:10:01 +01:00
if ( _result . isEmpty ( ) )
_result = QLatin1String ( " object " ) ;
}
2010-01-21 15:54:19 +01:00
2010-01-24 11:10:01 +01:00
void TypeId : : visit ( const FunctionValue * object )
2010-01-21 15:54:19 +01:00
{
2010-01-24 11:10:01 +01:00
_result = object - > className ( ) ;
2010-01-21 15:54:19 +01:00
2010-01-24 11:10:01 +01:00
if ( _result . isEmpty ( ) )
_result = QLatin1String ( " Function " ) ;
}
2010-01-21 15:54:19 +01:00
2010-02-23 17:02:50 +01:00
void TypeId : : visit ( const EasingCurveNameValue * )
{
_result = QLatin1String ( " string " ) ;
}
void TypeId : : visit ( const ColorValue * )
{
_result = QLatin1String ( " string " ) ;
}
void TypeId : : visit ( const AnchorLineValue * )
{
_result = QLatin1String ( " AnchorLine " ) ;
}
2010-01-21 15:54:19 +01:00
Engine : : Engine ( )
: _objectPrototype ( 0 ) ,
_functionPrototype ( 0 ) ,
_numberPrototype ( 0 ) ,
_booleanPrototype ( 0 ) ,
_stringPrototype ( 0 ) ,
_arrayPrototype ( 0 ) ,
_datePrototype ( 0 ) ,
_regexpPrototype ( 0 ) ,
_objectCtor ( 0 ) ,
_functionCtor ( 0 ) ,
_arrayCtor ( 0 ) ,
_stringCtor ( 0 ) ,
_booleanCtor ( 0 ) ,
_numberCtor ( 0 ) ,
_dateCtor ( 0 ) ,
_regexpCtor ( 0 ) ,
_globalObject ( 0 ) ,
_mathObject ( 0 ) ,
2010-02-10 15:51:21 +01:00
_qtObject ( 0 ) ,
2010-01-26 12:06:44 +01:00
# ifndef NO_DECLARATIVE_BACKEND
2010-01-26 11:06:28 +01:00
_qmlKeysObject ( 0 ) ,
2010-01-26 12:06:44 +01:00
# endif
2010-01-21 15:54:19 +01:00
_convertToNumber ( this ) ,
_convertToString ( this ) ,
_convertToObject ( this )
{
initializePrototypes ( ) ;
2010-01-26 14:50:52 +01:00
_metaTypeSystem . reload ( this ) ;
2010-01-21 15:54:19 +01:00
}
2010-01-24 11:10:01 +01:00
Engine : : ~ Engine ( )
{
2010-02-03 14:31:03 +01:00
qDeleteAll ( _registeredValues ) ;
2010-01-21 15:54:19 +01:00
}
2010-01-24 11:10:01 +01:00
const NullValue * Engine : : nullValue ( ) const
{
return & _nullValue ;
}
const UndefinedValue * Engine : : undefinedValue ( ) const
{
return & _undefinedValue ;
}
const NumberValue * Engine : : numberValue ( ) const
{
return & _numberValue ;
}
const BooleanValue * Engine : : booleanValue ( ) const
{
return & _booleanValue ;
}
const StringValue * Engine : : stringValue ( ) const
{
return & _stringValue ;
}
2010-01-21 15:54:19 +01:00
2010-02-19 15:10:39 +01:00
const EasingCurveNameValue * Engine : : easingCurveNameValue ( ) const
{
return & _easingCurveNameValue ;
}
2010-02-23 14:36:38 +01:00
const ColorValue * Engine : : colorValue ( ) const
{
return & _colorValue ;
}
2010-02-23 17:02:50 +01:00
const AnchorLineValue * Engine : : anchorLineValue ( ) const
{
return & _anchorLineValue ;
}
2010-01-24 11:10:01 +01:00
const Value * Engine : : newArray ( )
{
return arrayCtor ( ) - > construct ( ) ;
}
2010-01-21 15:54:19 +01:00
ObjectValue * Engine : : newObject ( )
{
return newObject ( _objectPrototype ) ;
}
ObjectValue * Engine : : newObject ( const ObjectValue * prototype )
{
ObjectValue * object = new ObjectValue ( this ) ;
object - > setPrototype ( prototype ) ;
return object ;
}
2010-01-28 14:11:56 +01:00
Function * Engine : : newFunction ( )
{
2010-01-21 15:54:19 +01:00
Function * function = new Function ( this ) ;
function - > setPrototype ( functionPrototype ( ) ) ;
return function ;
}
2010-01-24 11:10:01 +01:00
ObjectValue * Engine : : globalObject ( ) const
{
return _globalObject ;
}
ObjectValue * Engine : : objectPrototype ( ) const
{
return _objectPrototype ;
}
ObjectValue * Engine : : functionPrototype ( ) const
{
return _functionPrototype ;
}
ObjectValue * Engine : : numberPrototype ( ) const
{
return _numberPrototype ;
}
ObjectValue * Engine : : booleanPrototype ( ) const
{
return _booleanPrototype ;
}
ObjectValue * Engine : : stringPrototype ( ) const
{
return _stringPrototype ;
}
ObjectValue * Engine : : arrayPrototype ( ) const
{
return _arrayPrototype ;
}
ObjectValue * Engine : : datePrototype ( ) const
{
return _datePrototype ;
}
ObjectValue * Engine : : regexpPrototype ( ) const
{
return _regexpPrototype ;
}
const FunctionValue * Engine : : objectCtor ( ) const
{
return _objectCtor ;
}
const FunctionValue * Engine : : functionCtor ( ) const
{
return _functionCtor ;
}
const FunctionValue * Engine : : arrayCtor ( ) const
{
return _arrayCtor ;
}
const FunctionValue * Engine : : stringCtor ( ) const
{
return _stringCtor ;
}
const FunctionValue * Engine : : booleanCtor ( ) const
{
return _booleanCtor ;
}
const FunctionValue * Engine : : numberCtor ( ) const
{
return _numberCtor ;
}
const FunctionValue * Engine : : dateCtor ( ) const
{
return _dateCtor ;
}
const FunctionValue * Engine : : regexpCtor ( ) const
{
return _regexpCtor ;
}
const ObjectValue * Engine : : mathObject ( ) const
{
return _mathObject ;
}
2010-02-10 15:51:21 +01:00
const ObjectValue * Engine : : qtObject ( ) const
{
return _qtObject ;
}
2010-02-03 14:31:03 +01:00
void Engine : : registerValue ( Value * value )
2010-01-26 10:50:30 +01:00
{
2010-02-03 14:31:03 +01:00
_registeredValues . append ( value ) ;
2010-01-26 10:50:30 +01:00
}
2010-01-24 11:35:11 +01:00
const Value * Engine : : convertToBoolean ( const Value * value )
2010-01-24 11:10:01 +01:00
{
return _convertToNumber ( value ) ; // ### implement convert to bool
}
const Value * Engine : : convertToNumber ( const Value * value )
{
return _convertToNumber ( value ) ;
}
const Value * Engine : : convertToString ( const Value * value )
{
return _convertToString ( value ) ;
}
2010-01-21 15:54:19 +01:00
2010-01-24 11:10:01 +01:00
const Value * Engine : : convertToObject ( const Value * value )
2010-01-21 15:54:19 +01:00
{
2010-01-24 11:10:01 +01:00
return _convertToObject ( value ) ;
2010-01-21 15:54:19 +01:00
}
2010-01-24 11:10:01 +01:00
QString Engine : : typeId ( const Value * value )
2010-01-21 15:54:19 +01:00
{
2010-01-24 11:10:01 +01:00
return _typeId ( value ) ;
2010-01-21 15:54:19 +01:00
}
void Engine : : addFunction ( ObjectValue * object , const QString & name , const Value * result , int argumentCount )
{
Function * function = newFunction ( ) ;
function - > setReturnValue ( result ) ;
for ( int i = 0 ; i < argumentCount ; + + i )
function - > addArgument ( undefinedValue ( ) ) ; // ### introduce unknownValue
object - > setProperty ( name , function ) ;
}
void Engine : : addFunction ( ObjectValue * object , const QString & name , int argumentCount )
{
Function * function = newFunction ( ) ;
for ( int i = 0 ; i < argumentCount ; + + i )
function - > addArgument ( undefinedValue ( ) ) ; // ### introduce unknownValue
object - > setProperty ( name , function ) ;
}
void Engine : : initializePrototypes ( )
{
_objectPrototype = newObject ( /*prototype = */ 0 ) ;
_functionPrototype = newObject ( _objectPrototype ) ;
_numberPrototype = newObject ( _objectPrototype ) ;
_booleanPrototype = newObject ( _objectPrototype ) ;
_stringPrototype = newObject ( _objectPrototype ) ;
_arrayPrototype = newObject ( _objectPrototype ) ;
_datePrototype = newObject ( _objectPrototype ) ;
_regexpPrototype = newObject ( _objectPrototype ) ;
// set up the Global object
_globalObject = newObject ( ) ;
_globalObject - > setClassName ( " Global " ) ;
// set up the default Object prototype
_objectCtor = new ObjectCtor ( this ) ;
_objectCtor - > setPrototype ( _functionPrototype ) ;
_objectCtor - > setProperty ( " prototype " , _objectPrototype ) ;
_functionCtor = new FunctionCtor ( this ) ;
_functionCtor - > setPrototype ( _functionPrototype ) ;
_functionCtor - > setProperty ( " prototype " , _functionPrototype ) ;
_arrayCtor = new ArrayCtor ( this ) ;
_arrayCtor - > setPrototype ( _functionPrototype ) ;
_arrayCtor - > setProperty ( " prototype " , _arrayPrototype ) ;
_stringCtor = new StringCtor ( this ) ;
_stringCtor - > setPrototype ( _functionPrototype ) ;
_stringCtor - > setProperty ( " prototype " , _stringPrototype ) ;
_booleanCtor = new BooleanCtor ( this ) ;
_booleanCtor - > setPrototype ( _functionPrototype ) ;
_booleanCtor - > setProperty ( " prototype " , _booleanPrototype ) ;
_numberCtor = new NumberCtor ( this ) ;
_numberCtor - > setPrototype ( _functionPrototype ) ;
_numberCtor - > setProperty ( " prototype " , _numberPrototype ) ;
_dateCtor = new DateCtor ( this ) ;
_dateCtor - > setPrototype ( _functionPrototype ) ;
_dateCtor - > setProperty ( " prototype " , _datePrototype ) ;
_regexpCtor = new RegExpCtor ( this ) ;
_regexpCtor - > setPrototype ( _functionPrototype ) ;
_regexpCtor - > setProperty ( " prototype " , _regexpPrototype ) ;
addFunction ( _objectCtor , " getPrototypeOf " , 1 ) ;
addFunction ( _objectCtor , " getOwnPropertyDescriptor " , 2 ) ;
2010-01-24 11:10:01 +01:00
addFunction ( _objectCtor , " getOwnPropertyNames " , newArray ( ) , 1 ) ;
2010-01-21 15:54:19 +01:00
addFunction ( _objectCtor , " create " , 1 ) ;
addFunction ( _objectCtor , " defineProperty " , 3 ) ;
addFunction ( _objectCtor , " defineProperties " , 2 ) ;
addFunction ( _objectCtor , " seal " , 1 ) ;
addFunction ( _objectCtor , " freeze " , 1 ) ;
addFunction ( _objectCtor , " preventExtensions " , 1 ) ;
addFunction ( _objectCtor , " isSealed " , booleanValue ( ) , 1 ) ;
addFunction ( _objectCtor , " isFrozen " , booleanValue ( ) , 1 ) ;
addFunction ( _objectCtor , " isExtensible " , booleanValue ( ) , 1 ) ;
2010-01-24 11:10:01 +01:00
addFunction ( _objectCtor , " keys " , newArray ( ) , 1 ) ;
2010-01-21 15:54:19 +01:00
addFunction ( _objectPrototype , " toString " , stringValue ( ) , 0 ) ;
addFunction ( _objectPrototype , " toLocaleString " , stringValue ( ) , 0 ) ;
2010-01-24 11:10:01 +01:00
addFunction ( _objectPrototype , " valueOf " , 0 ) ; // ### FIXME it should return thisObject
2010-01-21 15:54:19 +01:00
addFunction ( _objectPrototype , " hasOwnProperty " , booleanValue ( ) , 1 ) ;
addFunction ( _objectPrototype , " isPrototypeOf " , booleanValue ( ) , 1 ) ;
addFunction ( _objectPrototype , " propertyIsEnumerable " , booleanValue ( ) , 1 ) ;
// set up the default Function prototype
_functionPrototype - > setProperty ( " constructor " , _functionCtor ) ;
addFunction ( _functionPrototype , " toString " , stringValue ( ) , 0 ) ;
addFunction ( _functionPrototype , " apply " , 2 ) ;
addFunction ( _functionPrototype , " call " , 1 ) ;
addFunction ( _functionPrototype , " bind " , 1 ) ;
// set up the default Array prototype
addFunction ( _arrayCtor , " isArray " , booleanValue ( ) , 1 ) ;
_arrayPrototype - > setProperty ( " constructor " , _arrayCtor ) ;
addFunction ( _arrayPrototype , " toString " , stringValue ( ) , 0 ) ;
addFunction ( _arrayPrototype , " toLocalString " , stringValue ( ) , 0 ) ;
addFunction ( _arrayPrototype , " concat " , 0 ) ;
addFunction ( _arrayPrototype , " join " , 1 ) ;
addFunction ( _arrayPrototype , " pop " , 0 ) ;
addFunction ( _arrayPrototype , " push " , 0 ) ;
addFunction ( _arrayPrototype , " reverse " , 0 ) ;
addFunction ( _arrayPrototype , " shift " , 0 ) ;
addFunction ( _arrayPrototype , " slice " , 2 ) ;
addFunction ( _arrayPrototype , " sort " , 1 ) ;
addFunction ( _arrayPrototype , " splice " , 2 ) ;
addFunction ( _arrayPrototype , " unshift " , 0 ) ;
addFunction ( _arrayPrototype , " indexOf " , numberValue ( ) , 1 ) ;
addFunction ( _arrayPrototype , " lastIndexOf " , numberValue ( ) , 1 ) ;
addFunction ( _arrayPrototype , " every " , 1 ) ;
addFunction ( _arrayPrototype , " some " , 1 ) ;
addFunction ( _arrayPrototype , " forEach " , 1 ) ;
addFunction ( _arrayPrototype , " map " , 1 ) ;
addFunction ( _arrayPrototype , " filter " , 1 ) ;
addFunction ( _arrayPrototype , " reduce " , 1 ) ;
addFunction ( _arrayPrototype , " reduceRight " , 1 ) ;
// set up the default String prototype
addFunction ( _stringCtor , " fromCharCode " , stringValue ( ) , 0 ) ;
_stringPrototype - > setProperty ( " constructor " , _stringCtor ) ;
addFunction ( _stringPrototype , " toString " , stringValue ( ) , 0 ) ;
addFunction ( _stringPrototype , " valueOf " , stringValue ( ) , 0 ) ;
addFunction ( _stringPrototype , " charAt " , stringValue ( ) , 1 ) ;
addFunction ( _stringPrototype , " charCodeAt " , stringValue ( ) , 1 ) ;
addFunction ( _stringPrototype , " concat " , stringValue ( ) , 0 ) ;
addFunction ( _stringPrototype , " indexOf " , numberValue ( ) , 2 ) ;
addFunction ( _stringPrototype , " lastIndexOf " , numberValue ( ) , 2 ) ;
addFunction ( _stringPrototype , " localeCompare " , booleanValue ( ) , 1 ) ;
2010-01-24 11:10:01 +01:00
addFunction ( _stringPrototype , " match " , newArray ( ) , 1 ) ;
2010-01-21 15:54:19 +01:00
addFunction ( _stringPrototype , " replace " , stringValue ( ) , 2 ) ;
addFunction ( _stringPrototype , " search " , numberValue ( ) , 1 ) ;
addFunction ( _stringPrototype , " slice " , stringValue ( ) , 2 ) ;
2010-01-26 12:38:52 +01:00
addFunction ( _stringPrototype , " split " , newArray ( ) , 1 ) ;
2010-01-21 15:54:19 +01:00
addFunction ( _stringPrototype , " substring " , stringValue ( ) , 2 ) ;
addFunction ( _stringPrototype , " toLowerCase " , stringValue ( ) , 0 ) ;
addFunction ( _stringPrototype , " toLocaleLowerCase " , stringValue ( ) , 0 ) ;
addFunction ( _stringPrototype , " toUpperCase " , stringValue ( ) , 0 ) ;
addFunction ( _stringPrototype , " toLocaleUpperCase " , stringValue ( ) , 0 ) ;
addFunction ( _stringPrototype , " trim " , stringValue ( ) , 0 ) ;
// set up the default Boolean prototype
addFunction ( _booleanCtor , " fromCharCode " , 0 ) ;
_booleanPrototype - > setProperty ( " constructor " , _booleanCtor ) ;
addFunction ( _booleanPrototype , " toString " , stringValue ( ) , 0 ) ;
addFunction ( _booleanPrototype , " valueOf " , booleanValue ( ) , 0 ) ;
// set up the default Number prototype
_numberCtor - > setProperty ( " MAX_VALUE " , numberValue ( ) ) ;
_numberCtor - > setProperty ( " MIN_VALUE " , numberValue ( ) ) ;
_numberCtor - > setProperty ( " NaN " , numberValue ( ) ) ;
_numberCtor - > setProperty ( " NEGATIVE_INFINITY " , numberValue ( ) ) ;
_numberCtor - > setProperty ( " POSITIVE_INFINITY " , numberValue ( ) ) ;
addFunction ( _numberCtor , " fromCharCode " , 0 ) ;
_numberPrototype - > setProperty ( " constructor " , _numberCtor ) ;
addFunction ( _numberPrototype , " toString " , stringValue ( ) , 0 ) ;
addFunction ( _numberPrototype , " toLocaleString " , stringValue ( ) , 0 ) ;
addFunction ( _numberPrototype , " valueOf " , numberValue ( ) , 0 ) ;
addFunction ( _numberPrototype , " toFixed " , numberValue ( ) , 1 ) ;
addFunction ( _numberPrototype , " toExponential " , numberValue ( ) , 1 ) ;
addFunction ( _numberPrototype , " toPrecision " , numberValue ( ) , 1 ) ;
// set up the Math object
_mathObject = newObject ( ) ;
_mathObject - > setProperty ( " E " , numberValue ( ) ) ;
_mathObject - > setProperty ( " LN10 " , numberValue ( ) ) ;
_mathObject - > setProperty ( " LN2 " , numberValue ( ) ) ;
_mathObject - > setProperty ( " LOG2E " , numberValue ( ) ) ;
_mathObject - > setProperty ( " LOG10E " , numberValue ( ) ) ;
_mathObject - > setProperty ( " PI " , numberValue ( ) ) ;
_mathObject - > setProperty ( " SQRT1_2 " , numberValue ( ) ) ;
_mathObject - > setProperty ( " SQRT2 " , numberValue ( ) ) ;
addFunction ( _mathObject , " abs " , numberValue ( ) , 1 ) ;
addFunction ( _mathObject , " acos " , numberValue ( ) , 1 ) ;
addFunction ( _mathObject , " asin " , numberValue ( ) , 1 ) ;
addFunction ( _mathObject , " atan " , numberValue ( ) , 1 ) ;
addFunction ( _mathObject , " atan2 " , numberValue ( ) , 2 ) ;
addFunction ( _mathObject , " ceil " , numberValue ( ) , 1 ) ;
addFunction ( _mathObject , " cos " , numberValue ( ) , 1 ) ;
addFunction ( _mathObject , " exp " , numberValue ( ) , 1 ) ;
addFunction ( _mathObject , " floor " , numberValue ( ) , 1 ) ;
addFunction ( _mathObject , " log " , numberValue ( ) , 1 ) ;
2010-01-26 10:50:30 +01:00
addFunction ( _mathObject , " max " , numberValue ( ) , 0 ) ;
addFunction ( _mathObject , " min " , numberValue ( ) , 0 ) ;
2010-01-21 15:54:19 +01:00
addFunction ( _mathObject , " pow " , numberValue ( ) , 2 ) ;
addFunction ( _mathObject , " random " , numberValue ( ) , 1 ) ;
addFunction ( _mathObject , " round " , numberValue ( ) , 1 ) ;
addFunction ( _mathObject , " sin " , numberValue ( ) , 1 ) ;
addFunction ( _mathObject , " sqrt " , numberValue ( ) , 1 ) ;
addFunction ( _mathObject , " tan " , numberValue ( ) , 1 ) ;
// set up the default Boolean prototype
addFunction ( _dateCtor , " parse " , numberValue ( ) , 1 ) ;
addFunction ( _dateCtor , " now " , numberValue ( ) , 0 ) ;
_datePrototype - > setProperty ( " constructor " , _dateCtor ) ;
addFunction ( _datePrototype , " toString " , stringValue ( ) , 0 ) ;
addFunction ( _datePrototype , " toDateString " , stringValue ( ) , 0 ) ;
addFunction ( _datePrototype , " toTimeString " , stringValue ( ) , 0 ) ;
addFunction ( _datePrototype , " toLocaleString " , stringValue ( ) , 0 ) ;
addFunction ( _datePrototype , " toLocaleDateString " , stringValue ( ) , 0 ) ;
addFunction ( _datePrototype , " toLocaleTimeString " , stringValue ( ) , 0 ) ;
addFunction ( _datePrototype , " valueOf " , numberValue ( ) , 0 ) ;
addFunction ( _datePrototype , " getTime " , numberValue ( ) , 0 ) ;
addFunction ( _datePrototype , " getFullYear " , numberValue ( ) , 0 ) ;
addFunction ( _datePrototype , " getUTCFullYear " , numberValue ( ) , 0 ) ;
addFunction ( _datePrototype , " getMonth " , numberValue ( ) , 0 ) ;
addFunction ( _datePrototype , " getUTCMonth " , numberValue ( ) , 0 ) ;
addFunction ( _datePrototype , " getDate " , numberValue ( ) , 0 ) ;
addFunction ( _datePrototype , " getUTCDate " , numberValue ( ) , 0 ) ;
addFunction ( _datePrototype , " getHours " , numberValue ( ) , 0 ) ;
addFunction ( _datePrototype , " getUTCHours " , numberValue ( ) , 0 ) ;
addFunction ( _datePrototype , " getMinutes " , numberValue ( ) , 0 ) ;
addFunction ( _datePrototype , " getUTCMinutes " , numberValue ( ) , 0 ) ;
addFunction ( _datePrototype , " getSeconds " , numberValue ( ) , 0 ) ;
addFunction ( _datePrototype , " getUTCSeconds " , numberValue ( ) , 0 ) ;
addFunction ( _datePrototype , " getMilliseconds " , numberValue ( ) , 0 ) ;
addFunction ( _datePrototype , " getUTCMilliseconds " , numberValue ( ) , 0 ) ;
addFunction ( _datePrototype , " getTimezoneOffset " , numberValue ( ) , 0 ) ;
addFunction ( _datePrototype , " setTime " , 1 ) ;
addFunction ( _datePrototype , " setMilliseconds " , 1 ) ;
addFunction ( _datePrototype , " setUTCMilliseconds " , 1 ) ;
addFunction ( _datePrototype , " setSeconds " , 1 ) ;
addFunction ( _datePrototype , " setUTCSeconds " , 1 ) ;
addFunction ( _datePrototype , " setMinutes " , 1 ) ;
addFunction ( _datePrototype , " setUTCMinutes " , 1 ) ;
addFunction ( _datePrototype , " setHours " , 1 ) ;
addFunction ( _datePrototype , " setUTCHours " , 1 ) ;
addFunction ( _datePrototype , " setDate " , 1 ) ;
addFunction ( _datePrototype , " setUTCDate " , 1 ) ;
addFunction ( _datePrototype , " setMonth " , 1 ) ;
addFunction ( _datePrototype , " setUTCMonth " , 1 ) ;
addFunction ( _datePrototype , " setFullYear " , 1 ) ;
addFunction ( _datePrototype , " setUTCFullYear " , 1 ) ;
addFunction ( _datePrototype , " toUTCString " , stringValue ( ) , 0 ) ;
addFunction ( _datePrototype , " toISOString " , stringValue ( ) , 0 ) ;
addFunction ( _datePrototype , " toJSON " , stringValue ( ) , 1 ) ;
// set up the default Boolean prototype
_regexpPrototype - > setProperty ( " constructor " , _regexpCtor ) ;
2010-01-24 11:10:01 +01:00
addFunction ( _regexpPrototype , " exec " , newArray ( ) , 1 ) ;
2010-01-21 15:54:19 +01:00
addFunction ( _regexpPrototype , " test " , booleanValue ( ) , 1 ) ;
addFunction ( _regexpPrototype , " toString " , stringValue ( ) , 0 ) ;
// fill the Global object
_globalObject - > setProperty ( " Math " , _mathObject ) ;
_globalObject - > setProperty ( " Object " , objectCtor ( ) ) ;
_globalObject - > setProperty ( " Function " , functionCtor ( ) ) ;
_globalObject - > setProperty ( " Array " , arrayCtor ( ) ) ;
_globalObject - > setProperty ( " String " , stringCtor ( ) ) ;
_globalObject - > setProperty ( " Boolean " , booleanCtor ( ) ) ;
_globalObject - > setProperty ( " Number " , numberCtor ( ) ) ;
_globalObject - > setProperty ( " Date " , dateCtor ( ) ) ;
_globalObject - > setProperty ( " RegExp " , regexpCtor ( ) ) ;
2010-02-10 15:51:21 +01:00
//types
_qtObject = newObject ( /*prototype */ 0 ) ;
addFunction ( _qtObject , QLatin1String ( " rgba " ) , 4 ) ;
addFunction ( _qtObject , QLatin1String ( " hsla " ) , 4 ) ;
addFunction ( _qtObject , QLatin1String ( " rect " ) , 4 ) ;
addFunction ( _qtObject , QLatin1String ( " point " ) , 2 ) ;
addFunction ( _qtObject , QLatin1String ( " size " ) , 2 ) ;
addFunction ( _qtObject , QLatin1String ( " vector3d " ) , 3 ) ;
//color helpers
addFunction ( _qtObject , QLatin1String ( " lighter " ) , 1 ) ;
addFunction ( _qtObject , QLatin1String ( " darker " ) , 1 ) ;
addFunction ( _qtObject , QLatin1String ( " tint " ) , 2 ) ;
//misc methods
addFunction ( _qtObject , QLatin1String ( " closestAngle " ) , 2 ) ;
addFunction ( _qtObject , QLatin1String ( " playSound " ) , 1 ) ;
addFunction ( _qtObject , QLatin1String ( " openUrlExternally " ) , 1 ) ;
addFunction ( _qtObject , QLatin1String ( " md5 " ) , 1 ) ;
addFunction ( _qtObject , QLatin1String ( " btoa " ) , 1 ) ;
addFunction ( _qtObject , QLatin1String ( " atob " ) , 1 ) ;
addFunction ( _qtObject , QLatin1String ( " quit " ) , 0 ) ;
addFunction ( _qtObject , QLatin1String ( " resolvedUrl " ) , 1 ) ;
//firebug/webkit compat
ObjectValue * consoleObject = newObject ( /*prototype */ 0 ) ;
addFunction ( consoleObject , QLatin1String ( " log " ) , 1 ) ;
addFunction ( consoleObject , QLatin1String ( " debug " ) , 1 ) ;
_globalObject - > setProperty ( QLatin1String ( " console " ) , consoleObject ) ;
_globalObject - > setProperty ( QLatin1String ( " Qt " ) , _qtObject ) ;
2010-01-26 11:06:28 +01:00
}
const ObjectValue * Engine : : qmlKeysObject ( )
{
2010-01-26 12:06:44 +01:00
# ifndef NO_DECLARATIVE_BACKEND
2010-01-26 11:06:28 +01:00
return _qmlKeysObject ;
2010-01-26 12:06:44 +01:00
# else
return 0 ;
# endif
2010-01-21 15:54:19 +01:00
}
2010-01-26 11:15:21 +01:00
const Value * Engine : : defaultValueForBuiltinType ( const QString & typeName ) const
{
if ( typeName = = QLatin1String ( " string " ) | | typeName = = QLatin1String ( " url " ) )
return stringValue ( ) ;
else if ( typeName = = QLatin1String ( " bool " ) )
return booleanValue ( ) ;
else if ( typeName = = QLatin1String ( " int " ) | | typeName = = QLatin1String ( " real " ) )
return numberValue ( ) ;
// ### more types...
return undefinedValue ( ) ;
}
2010-01-24 13:29:46 +01:00
# ifndef NO_DECLARATIVE_BACKEND
2010-01-26 14:50:52 +01:00
QmlObjectValue * Engine : : newQmlObject ( const QString & name , const QString & prefix , int majorVersion , int minorVersion )
{
2010-02-26 14:43:39 +01:00
if ( name = = QLatin1String ( " QDeclarativeAnchors " ) ) {
QmlObjectValue * object = new QmlObjectValue ( & QDeclarativeAnchors : : staticMetaObject , QLatin1String ( " Anchors " ) , - 1 , - 1 , this ) ;
2010-01-24 13:29:46 +01:00
return object ;
2010-02-26 14:43:39 +01:00
} else if ( name = = QLatin1String ( " QDeclarativePen " ) ) {
QmlObjectValue * object = new QmlObjectValue ( & QDeclarativePen : : staticMetaObject , QLatin1String ( " Pen " ) , - 1 , - 1 , this ) ;
2010-01-24 19:31:38 +01:00
return object ;
2010-02-26 14:43:39 +01:00
} else if ( name = = QLatin1String ( " QDeclarativeScaleGrid " ) ) {
2010-01-26 14:50:52 +01:00
QmlObjectValue * object = new QmlObjectValue ( & QObject : : staticMetaObject , QLatin1String ( " ScaleGrid " ) , - 1 , - 1 , this ) ;
2010-01-25 15:05:23 +01:00
object - > setProperty ( " left " , numberValue ( ) ) ;
object - > setProperty ( " top " , numberValue ( ) ) ;
object - > setProperty ( " right " , numberValue ( ) ) ;
object - > setProperty ( " bottom " , numberValue ( ) ) ;
return object ;
2010-01-24 13:29:46 +01:00
}
// ### TODO: add support for QML packages
2010-01-26 14:50:52 +01:00
const QString componentName = prefix + QLatin1Char ( ' / ' ) + name ;
2010-01-24 13:29:46 +01:00
2010-02-26 14:43:39 +01:00
if ( QDeclarativeType * qmlType = QDeclarativeMetaType : : qmlType ( componentName . toUtf8 ( ) , majorVersion , minorVersion ) ) {
2010-01-26 14:50:52 +01:00
const QString typeName = qmlType - > qmlTypeName ( ) ;
const QString strippedTypeName = typeName . mid ( typeName . lastIndexOf ( ' / ' ) + 1 ) ;
QmlObjectValue * object = new QmlObjectValue ( qmlType - > metaObject ( ) , strippedTypeName , majorVersion , minorVersion , this ) ;
2010-01-24 13:29:46 +01:00
return object ;
}
return 0 ;
}
2010-01-26 14:50:52 +01:00
# endif
2010-01-24 13:29:46 +01:00
2010-02-03 14:31:03 +01:00
2010-02-08 12:50:10 +01:00
ASTObjectValue : : ASTObjectValue ( UiQualifiedId * typeName ,
UiObjectInitializer * initializer ,
2010-02-09 12:27:52 +01:00
const QmlJS : : Document * doc ,
2010-02-08 12:50:10 +01:00
Engine * engine )
: ObjectValue ( engine ) , _typeName ( typeName ) , _initializer ( initializer ) , _doc ( doc )
2010-02-03 14:31:03 +01:00
{
if ( _initializer ) {
for ( UiObjectMemberList * it = _initializer - > members ; it ; it = it - > next ) {
UiObjectMember * member = it - > member ;
if ( UiPublicMember * def = cast < UiPublicMember * > ( member ) ) {
2010-02-17 08:44:17 +01:00
if ( def - > type = = UiPublicMember : : Property & & def - > name & & def - > memberType ) {
2010-02-08 12:50:10 +01:00
ASTPropertyReference * ref = new ASTPropertyReference ( def , _doc , engine ) ;
_properties . append ( ref ) ;
2010-02-17 08:44:17 +01:00
} else if ( def - > type = = UiPublicMember : : Signal & & def - > name ) {
ASTSignalReference * ref = new ASTSignalReference ( def , _doc , engine ) ;
_signals . append ( ref ) ;
2010-02-03 14:31:03 +01:00
}
}
}
}
2010-02-08 12:50:10 +01:00
}
ASTObjectValue : : ~ ASTObjectValue ( )
{
}
bool ASTObjectValue : : getSourceLocation ( QString * fileName , int * line , int * column ) const
{
* fileName = _doc - > fileName ( ) ;
* line = _typeName - > identifierToken . startLine ;
* column = _typeName - > identifierToken . startColumn ;
return true ;
}
void ASTObjectValue : : processMembers ( MemberProcessor * processor ) const
{
2010-02-17 09:16:28 +01:00
foreach ( ASTPropertyReference * ref , _properties ) {
2010-02-08 12:50:10 +01:00
processor - > processProperty ( ref - > ast ( ) - > name - > asString ( ) , ref ) ;
2010-02-17 09:16:28 +01:00
// ### Should get a different value?
processor - > processGeneratedSlot ( ref - > onChangedSlotName ( ) , ref ) ;
}
2010-02-17 08:44:17 +01:00
foreach ( ASTSignalReference * ref , _signals ) {
processor - > processSignal ( ref - > ast ( ) - > name - > asString ( ) , ref ) ;
2010-02-17 09:16:28 +01:00
// ### Should get a different value?
2010-02-17 08:44:17 +01:00
processor - > processGeneratedSlot ( ref - > slotName ( ) , ref ) ;
}
2010-02-08 12:50:10 +01:00
2010-02-03 14:31:03 +01:00
ObjectValue : : processMembers ( processor ) ;
}
ASTVariableReference : : ASTVariableReference ( VariableDeclaration * ast , Engine * engine )
: Reference ( engine ) , _ast ( ast )
{
}
ASTVariableReference : : ~ ASTVariableReference ( )
{
}
const Value * ASTVariableReference : : value ( Context * context ) const
{
2010-02-15 11:52:39 +01:00
Evaluate check ( context ) ;
2010-02-03 14:31:03 +01:00
return check ( _ast - > expression ) ;
}
ASTFunctionValue : : ASTFunctionValue ( FunctionDeclaration * ast , Engine * engine )
: FunctionValue ( engine ) , _ast ( ast )
{
setPrototype ( engine - > functionPrototype ( ) ) ;
for ( FormalParameterList * it = ast - > formals ; it ; it = it - > next )
_argumentNames . append ( it - > name ) ;
}
ASTFunctionValue : : ~ ASTFunctionValue ( )
{
}
FunctionDeclaration * ASTFunctionValue : : ast ( ) const
{
return _ast ;
}
const Value * ASTFunctionValue : : returnValue ( ) const
{
return engine ( ) - > undefinedValue ( ) ;
}
int ASTFunctionValue : : argumentCount ( ) const
{
return _argumentNames . size ( ) ;
}
const Value * ASTFunctionValue : : argument ( int ) const
{
return engine ( ) - > undefinedValue ( ) ;
}
QString ASTFunctionValue : : argumentName ( int index ) const
{
if ( index < _argumentNames . size ( ) ) {
if ( NameId * nameId = _argumentNames . at ( index ) )
return nameId - > asString ( ) ;
}
return FunctionValue : : argumentName ( index ) ;
}
bool ASTFunctionValue : : isVariadic ( ) const
{
return true ;
}
2010-02-03 15:39:57 +01:00
2010-02-04 11:08:57 +01:00
QmlPrototypeReference : : QmlPrototypeReference ( UiQualifiedId * qmlTypeName , const QmlJS : : Document * doc ,
2010-02-04 09:44:43 +01:00
Engine * engine )
2010-02-03 15:39:57 +01:00
: Reference ( engine ) ,
2010-02-04 09:44:43 +01:00
_qmlTypeName ( qmlTypeName ) ,
_doc ( doc )
2010-02-03 15:39:57 +01:00
{
}
QmlPrototypeReference : : ~ QmlPrototypeReference ( )
{
}
UiQualifiedId * QmlPrototypeReference : : qmlTypeName ( ) const
{
return _qmlTypeName ;
}
const Value * QmlPrototypeReference : : value ( Context * context ) const
{
2010-02-04 09:44:43 +01:00
return context - > lookupType ( _doc , _qmlTypeName ) ;
2010-02-03 15:39:57 +01:00
}
2010-02-09 12:27:52 +01:00
ASTPropertyReference : : ASTPropertyReference ( UiPublicMember * ast , const QmlJS : : Document * doc , Engine * engine )
2010-02-08 12:50:10 +01:00
: Reference ( engine ) , _ast ( ast ) , _doc ( doc )
{
2010-02-17 09:16:28 +01:00
const QString propertyName = ast - > name - > asString ( ) ;
_onChangedSlotName = QLatin1String ( " on " ) ;
_onChangedSlotName + = propertyName . at ( 0 ) . toUpper ( ) ;
_onChangedSlotName + = propertyName . midRef ( 1 ) ;
_onChangedSlotName + = QLatin1String ( " Changed " ) ;
2010-02-08 12:50:10 +01:00
}
ASTPropertyReference : : ~ ASTPropertyReference ( )
{
}
bool ASTPropertyReference : : getSourceLocation ( QString * fileName , int * line , int * column ) const
{
* fileName = _doc - > fileName ( ) ;
* line = _ast - > identifierToken . startLine ;
* column = _ast - > identifierToken . startColumn ;
return true ;
}
const Value * ASTPropertyReference : : value ( Context * context ) const
{
if ( _ast - > expression ) {
2010-02-15 11:52:39 +01:00
Evaluate check ( context ) ;
2010-02-08 12:50:10 +01:00
return check ( _ast - > expression ) ;
}
if ( _ast - > memberType )
return engine ( ) - > defaultValueForBuiltinType ( _ast - > memberType - > asString ( ) ) ;
return engine ( ) - > undefinedValue ( ) ;
}
2010-02-17 08:44:17 +01:00
ASTSignalReference : : ASTSignalReference ( UiPublicMember * ast , const QmlJS : : Document * doc , Engine * engine )
: Reference ( engine ) , _ast ( ast ) , _doc ( doc )
{
const QString signalName = ast - > name - > asString ( ) ;
_slotName = QLatin1String ( " on " ) ;
_slotName + = signalName . at ( 0 ) . toUpper ( ) ;
_slotName + = signalName . midRef ( 1 ) ;
}
ASTSignalReference : : ~ ASTSignalReference ( )
{
}
bool ASTSignalReference : : getSourceLocation ( QString * fileName , int * line , int * column ) const
{
* fileName = _doc - > fileName ( ) ;
* line = _ast - > identifierToken . startLine ;
* column = _ast - > identifierToken . startColumn ;
return true ;
}
2010-02-17 08:58:33 +01:00
const Value * ASTSignalReference : : value ( Context * ) const
2010-02-17 08:44:17 +01:00
{
return engine ( ) - > undefinedValue ( ) ;
}