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-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
# include <QtDeclarative / QmlType>
# include <QtDeclarative / QmlMetaType>
# include <QtDeclarative / private / qmlgraphicsanchors_p.h> // ### remove me
2010-01-24 19:31:38 +01:00
# include <QtDeclarative / private / qmlgraphicsrectangle_p.h> // ### remove me
# include <QtDeclarative / private / qmlvaluetype_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-01-24 13:29:46 +01:00
# ifndef NO_DECLARATIVE_BACKEND
2010-01-26 11:06:28 +01:00
class QmlAttachedKeys : public ObjectValue
{
static const char * * builtinPropertyNames ( )
{
static const char * properties [ ] = {
" enabledChanged " ,
" pressed " ,
" released " ,
" digit0Pressed " ,
" digit1Pressed " ,
" digit2Pressed " ,
" digit3Pressed " ,
" digit4Pressed " ,
" digit5Pressed " ,
" digit6Pressed " ,
" digit7Pressed " ,
" digit8Pressed " ,
" digit9Pressed " ,
" leftPressed " ,
" rightPressed " ,
" upPressed " ,
" downPressed " ,
" asteriskPressed " ,
" numberSignPressed " ,
" escapePressed " ,
" returnPressed " ,
" enterPressed " ,
" deletePressed " ,
" spacePressed " ,
" backPressed " ,
" cancelPressed " ,
" selectPressed " ,
" yesPressed " ,
" noPressed " ,
" context1Pressed " ,
" context2Pressed " ,
" context3Pressed " ,
" context4Pressed " ,
" callPressed " ,
" hangupPressed " ,
" flipPressed " ,
" menuPressed " ,
" volumeUpPressed " ,
" volumeDownPressed " ,
0
} ;
return properties ;
}
QSet < QString > _generatedSlots ;
public :
QmlAttachedKeys ( Engine * engine )
: ObjectValue ( engine )
{
for ( const char * * it = builtinPropertyNames ( ) ; * it ; + + it ) {
QString signalName = QLatin1String ( * it ) ;
QString generatedSlot = QLatin1String ( " on " ) ;
generatedSlot + = signalName . at ( 0 ) . toUpper ( ) ;
generatedSlot + = signalName . midRef ( 1 ) ;
_generatedSlots . insert ( generatedSlot ) ;
}
}
virtual void processMembers ( MemberProcessor * processor ) const
{
foreach ( const QString & generatedSlot , _generatedSlots )
processor - > processSlot ( generatedSlot , engine ( ) - > undefinedValue ( ) ) ;
ObjectValue : : processMembers ( processor ) ;
}
} ;
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 )
{
engine - > registerObject ( this ) ;
}
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-01-26 14:50:52 +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-01-26 14:50:52 +01:00
const Value * QmlObjectValue : : lookupMember ( const QString & name ) const
{
for ( int index = 0 ; index < _metaObject - > propertyCount ( ) ; + + index ) {
QMetaProperty prop = _metaObject - > property ( index ) ;
2010-01-24 13:29:46 +01:00
2010-01-26 14:50:52 +01:00
if ( name = = QString : : fromUtf8 ( prop . name ( ) ) )
return propertyValue ( prop ) ;
}
2010-01-24 13:29:46 +01:00
2010-01-26 14:50:52 +01:00
for ( int index = 0 ; index < _metaObject - > methodCount ( ) ; + + index ) {
QMetaMethod method = _metaObject - > method ( index ) ;
2010-01-26 10:50:30 +01:00
2010-01-26 14:50:52 +01:00
const QString signature = QString : : fromUtf8 ( method . signature ( ) ) ;
2010-01-26 10:50:30 +01:00
2010-01-26 14:50:52 +01:00
const int indexOfParen = signature . indexOf ( QLatin1Char ( ' ( ' ) ) ;
if ( indexOfParen = = - 1 )
continue ; // skip it, invalid signature.
2010-01-26 10:50:30 +01:00
2010-01-26 14:50:52 +01:00
const QString methodName = signature . left ( indexOfParen ) ;
2010-01-26 10:50:30 +01:00
2010-01-26 14:50:52 +01:00
if ( methodName ! = name ) {
continue ;
2010-01-26 10:50:30 +01:00
2010-01-26 14:50:52 +01:00
} else if ( method . methodType ( ) = = QMetaMethod : : Slot & & method . access ( ) = = QMetaMethod : : Public ) {
return new MetaFunction ( method , engine ( ) ) ;
2010-01-26 10:50:30 +01:00
2010-01-26 14:50:52 +01:00
} else if ( method . methodType ( ) = = QMetaMethod : : Signal & & method . access ( ) ! = QMetaMethod : : Private ) {
return new MetaFunction ( method , engine ( ) ) ;
2010-01-26 10:50:30 +01:00
}
2010-01-24 13:29:46 +01:00
}
2010-01-26 14:50:52 +01:00
return ObjectValue : : lookupMember ( name ) ;
}
2010-01-24 13:29:46 +01:00
2010-01-26 14:50:52 +01:00
void QmlObjectValue : : processMembers ( MemberProcessor * processor ) const
{
for ( int index = 0 ; index < _metaObject - > propertyCount ( ) ; + + index ) {
QMetaProperty prop = _metaObject - > property ( index ) ;
2010-01-25 14:48:44 +01:00
2010-01-26 14:50:52 +01:00
processor - > processProperty ( prop . name ( ) , propertyValue ( prop ) ) ;
}
2010-01-26 10:10:11 +01:00
2010-01-26 14:50:52 +01:00
for ( int index = 0 ; index < _metaObject - > methodCount ( ) ; + + index ) {
QMetaMethod method = _metaObject - > method ( index ) ;
2010-01-25 14:48:44 +01:00
2010-01-26 14:50:52 +01:00
const QString signature = QString : : fromUtf8 ( method . signature ( ) ) ;
2010-01-25 14:48:44 +01:00
2010-01-26 14:50:52 +01:00
const int indexOfParen = signature . indexOf ( QLatin1Char ( ' ( ' ) ) ;
if ( indexOfParen = = - 1 )
continue ; // skip it, invalid signature.
2010-01-26 10:10:11 +01:00
2010-01-26 14:50:52 +01:00
const QString methodName = signature . left ( indexOfParen ) ;
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 ) {
processor - > processSlot ( methodName , engine ( ) - > undefinedValue ( ) ) ;
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
processor - > processSignal ( methodName , engine ( ) - > undefinedValue ( ) ) ;
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
processor - > processGeneratedSlot ( slotName , engine ( ) - > undefinedValue ( ) ) ;
}
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
{
if ( QmlMetaType : : isObject ( prop . userType ( ) ) ) {
QmlType * qmlPropertyType = QmlMetaType : : qmlType ( QmlMetaType : : metaObjectForType ( 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-01-26 14:50:52 +01:00
if ( const ObjectValue * objectValue = engine ( ) - > newQmlObject ( typeName , " " , - 1 , - 1 ) ) // ### we should extend this to lookup the property types in the QmlType 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 :
case QMetaType : : QPointF : {
// ### 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 ;
default :
break ;
} // end of switch
return value ;
}
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
////////////////////////////////////////////////////////////////////////////////
// Value
////////////////////////////////////////////////////////////////////////////////
2010-01-24 11:10:01 +01:00
Value : : Value ( )
{
}
Value : : ~ Value ( )
{
}
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
////////////////////////////////////////////////////////////////////////////////
// Environment
////////////////////////////////////////////////////////////////////////////////
2010-01-24 11:10:01 +01:00
Environment : : Environment ( )
{
}
Environment : : ~ Environment ( )
{
}
const Environment * Environment : : parent ( ) const
{
return 0 ;
}
2010-01-21 15:54:19 +01:00
const Value * Environment : : lookup ( const QString & name ) const
{
if ( const Value * member = lookupMember ( name ) )
return member ;
else if ( const Environment * p = parent ( ) )
return p - > lookup ( name ) ;
else
return 0 ;
}
const Value * Environment : : lookupMember ( const QString & name ) const {
Q_UNUSED ( name ) ;
return 0 ;
}
////////////////////////////////////////////////////////////////////////////////
// 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-01-26 10:10:11 +01:00
MemberProcessor : : MemberProcessor ( )
{
}
MemberProcessor : : ~ MemberProcessor ( )
{
}
bool MemberProcessor : : processProperty ( const QString & , const Value * )
{
return true ;
}
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 )
: _engine ( engine ) , _prototype ( 0 ) , _scope ( 0 )
{
}
ObjectValue : : ~ ObjectValue ( )
{
}
Engine * ObjectValue : : engine ( ) const
{
return _engine ;
}
QString ObjectValue : : className ( ) const
{
return _className ;
}
void ObjectValue : : setClassName ( const QString & className )
{
_className = className ;
}
const ObjectValue * ObjectValue : : prototype ( ) const
{
return _prototype ;
}
const ObjectValue * ObjectValue : : scope ( ) const
{
return _scope ;
}
void ObjectValue : : setScope ( const ObjectValue * scope )
{
_scope = scope ;
}
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 ) ;
}
const Value * ObjectValue : : property ( const QString & name ) const
{
2010-01-21 15:54:19 +01:00
return lookupMember ( name ) ;
}
void ObjectValue : : setPrototype ( const ObjectValue * prototype )
{
QSet < const ObjectValue * > processed ;
2010-01-24 11:10:01 +01:00
if ( ! prototype | | checkPrototype ( prototype , & processed ) )
2010-01-21 15:54:19 +01:00
_prototype = prototype ;
else
qWarning ( ) < < " **** invalid prototype: " ;
}
2010-01-24 11:10:01 +01:00
bool ObjectValue : : checkPrototype ( const ObjectValue * proto , QSet < const ObjectValue * > * processed ) const
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 ;
}
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 ;
}
}
const Environment * ObjectValue : : parent ( ) const
{
return _scope ;
}
const Value * ObjectValue : : lookupMember ( const QString & name ) const
{
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 ;
if ( _prototype ) {
if ( const Value * m = _prototype - > lookup ( name ) )
return m ;
}
return 0 ;
}
2010-01-24 11:35:11 +01:00
Activation : : Activation ( Engine * engine )
: ObjectValue ( engine ) ,
_thisObject ( 0 ) ,
_calledAsFunction ( true )
{
}
Activation : : ~ Activation ( )
{
}
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-24 11:35:11 +01:00
Activation activation ( engine ( ) ) ; // ### FIXME: create on the heap
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-24 11:35:11 +01:00
Activation activation ( engine ( ) ) ; // ### FIXME: create on the heap
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-24 11:35:11 +01:00
Activation activation ( engine ( ) ) ; // ### FIXME: create on the heap
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
{
return QString : : fromLatin1 ( " arg%1 " ) . arg ( index ) ;
}
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
const Value * Function : : property ( const QString & name ) const
{
if ( name = = " length " )
return engine ( ) - > numberValue ( ) ;
return FunctionValue : : property ( name ) ;
}
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 )
{
if ( const FunctionValue * valueOfMember = value_cast < const FunctionValue * > ( object - > lookup ( " valueOf " ) ) ) {
_result = value_cast < const NumberValue * > ( valueOfMember - > call ( object ) ) ; // ### invoke convert-to-number?
}
}
void ConvertToNumber : : visit ( const FunctionValue * object )
{
if ( const FunctionValue * valueOfMember = value_cast < const FunctionValue * > ( object - > lookup ( " valueOf " ) ) ) {
_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 )
{
if ( const FunctionValue * toStringMember = value_cast < const FunctionValue * > ( object - > lookup ( " toString " ) ) ) {
_result = value_cast < const StringValue * > ( toStringMember - > call ( object ) ) ; // ### invoke convert-to-string?
}
}
void ConvertToString : : visit ( const FunctionValue * object )
{
if ( const FunctionValue * toStringMember = value_cast < const FunctionValue * > ( object - > lookup ( " toString " ) ) ) {
_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
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-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-01-21 15:54:19 +01:00
QList < ObjectValue * > : : iterator it = _objects . begin ( ) ;
for ( ; it ! = _objects . end ( ) ; + + it )
delete * it ;
}
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-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 ) ;
_objects . push_back ( object ) ;
return object ;
}
Function * Engine : : newFunction ( ) {
Function * function = new Function ( this ) ;
function - > setPrototype ( functionPrototype ( ) ) ;
_objects . push_back ( function ) ;
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-01-26 10:50:30 +01:00
void Engine : : registerObject ( ObjectValue * object )
{
_objects . append ( object ) ;
}
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 ) ;
_objects . push_back ( _objectCtor ) ;
_objectCtor - > setProperty ( " prototype " , _objectPrototype ) ;
_functionCtor = new FunctionCtor ( this ) ;
_functionCtor - > setPrototype ( _functionPrototype ) ;
_objects . push_back ( _functionCtor ) ;
_functionCtor - > setProperty ( " prototype " , _functionPrototype ) ;
_arrayCtor = new ArrayCtor ( this ) ;
_arrayCtor - > setPrototype ( _functionPrototype ) ;
_objects . push_back ( _arrayCtor ) ;
_arrayCtor - > setProperty ( " prototype " , _arrayPrototype ) ;
_stringCtor = new StringCtor ( this ) ;
_stringCtor - > setPrototype ( _functionPrototype ) ;
_objects . push_back ( _stringCtor ) ;
_stringCtor - > setProperty ( " prototype " , _stringPrototype ) ;
_booleanCtor = new BooleanCtor ( this ) ;
_booleanCtor - > setPrototype ( _functionPrototype ) ;
_objects . push_back ( _booleanCtor ) ;
_booleanCtor - > setProperty ( " prototype " , _booleanPrototype ) ;
_numberCtor = new NumberCtor ( this ) ;
_numberCtor - > setPrototype ( _functionPrototype ) ;
_objects . push_back ( _numberCtor ) ;
_numberCtor - > setProperty ( " prototype " , _numberPrototype ) ;
_dateCtor = new DateCtor ( this ) ;
_dateCtor - > setPrototype ( _functionPrototype ) ;
_objects . push_back ( _dateCtor ) ;
_dateCtor - > setProperty ( " prototype " , _datePrototype ) ;
_regexpCtor = new RegExpCtor ( this ) ;
_regexpCtor - > setPrototype ( _functionPrototype ) ;
_objects . push_back ( _regexpCtor ) ;
_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-01-26 11:06:28 +01:00
2010-01-26 12:06:44 +01:00
# ifndef NO_DECLARATIVE_BACKEND
2010-01-26 11:06:28 +01:00
_qmlKeysObject = new QmlAttachedKeys ( this ) ;
_globalObject - > setProperty ( " Keys " , _qmlKeysObject ) ; // ### attach it to the current scope, and not to the global object
registerObject ( _qmlKeysObject ) ;
2010-01-26 12:06:44 +01:00
# endif
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-01-24 13:29:46 +01:00
if ( name = = QLatin1String ( " QmlGraphicsAnchors " ) ) {
2010-01-26 14:50:52 +01:00
QmlObjectValue * object = new QmlObjectValue ( & QmlGraphicsAnchors : : staticMetaObject , QLatin1String ( " Anchors " ) , - 1 , - 1 , this ) ;
2010-01-24 13:29:46 +01:00
_objects . append ( object ) ;
return object ;
2010-01-24 19:31:38 +01:00
} else if ( name = = QLatin1String ( " QmlGraphicsPen " ) ) {
2010-01-26 14:50:52 +01:00
QmlObjectValue * object = new QmlObjectValue ( & QmlGraphicsPen : : staticMetaObject , QLatin1String ( " Pen " ) , - 1 , - 1 , this ) ;
2010-01-24 19:31:38 +01:00
_objects . append ( object ) ;
return object ;
2010-01-25 15:05:23 +01:00
} else if ( name = = QLatin1String ( " QmlGraphicsScaleGrid " ) ) {
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-01-26 14:50:52 +01:00
if ( QmlType * qmlType = QmlMetaType : : qmlType ( componentName . toUtf8 ( ) , majorVersion , minorVersion ) ) {
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
_objects . append ( object ) ;
return object ;
}
return 0 ;
}
2010-01-26 14:50:52 +01:00
# endif
2010-01-24 13:29:46 +01:00