qmljsinterpreter.h 24.1 KB
Newer Older
1 2 3 4
/**************************************************************************
**
** This file is part of Qt Creator
**
hjk's avatar
hjk committed
5
** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
**
** 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.
**
**************************************************************************/

#ifndef QMLJS_INTERPRETER_H
#define QMLJS_INTERPRETER_H

33
#include <qmljs/qmljsdocument.h>
34
#include <qmljs/qmljs_global.h>
35
#include <qmljs/qmljscomponentversion.h>
36
#include <qmljs/parser/qmljsastfwd_p.h>
37

38
#include <QtCore/QFileInfoList>
39 40 41 42 43 44
#include <QtCore/QList>
#include <QtCore/QString>
#include <QtCore/QHash>
#include <QtCore/QSet>

namespace QmlJS {
45 46

class NameId;
47
class Document;
48

49 50 51 52 53 54 55 56 57 58 59 60 61 62
namespace Interpreter {

////////////////////////////////////////////////////////////////////////////////
// Forward declarations
////////////////////////////////////////////////////////////////////////////////
class Engine;
class Value;
class NullValue;
class UndefinedValue;
class NumberValue;
class BooleanValue;
class StringValue;
class ObjectValue;
class FunctionValue;
Roberto Raggi's avatar
Roberto Raggi committed
63
class Reference;
64
class ColorValue;
65
class AnchorLineValue;
66

Roberto Raggi's avatar
Cleanup  
Roberto Raggi committed
67 68
typedef QList<const Value *> ValueList;

69 70 71
class FakeMetaObject;
class FakeMetaMethod;
class FakeMetaProperty;
Christian Kamm's avatar
Christian Kamm committed
72
class FakeMetaEnum;
73

74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89
////////////////////////////////////////////////////////////////////////////////
// Value visitor
////////////////////////////////////////////////////////////////////////////////
class QMLJS_EXPORT ValueVisitor
{
public:
    ValueVisitor();
    virtual ~ValueVisitor();

    virtual void visit(const NullValue *);
    virtual void visit(const UndefinedValue *);
    virtual void visit(const NumberValue *);
    virtual void visit(const BooleanValue *);
    virtual void visit(const StringValue *);
    virtual void visit(const ObjectValue *);
    virtual void visit(const FunctionValue *);
Roberto Raggi's avatar
Roberto Raggi committed
90
    virtual void visit(const Reference *);
91
    virtual void visit(const ColorValue *);
92
    virtual void visit(const AnchorLineValue *);
93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113
};

////////////////////////////////////////////////////////////////////////////////
// QML/JS value
////////////////////////////////////////////////////////////////////////////////
class QMLJS_EXPORT Value
{
    Value(const Value &other);
    void operator = (const Value &other);

public:
    Value();
    virtual ~Value();

    virtual const NullValue *asNullValue() const;
    virtual const UndefinedValue *asUndefinedValue() const;
    virtual const NumberValue *asNumberValue() const;
    virtual const BooleanValue *asBooleanValue() const;
    virtual const StringValue *asStringValue() const;
    virtual const ObjectValue *asObjectValue() const;
    virtual const FunctionValue *asFunctionValue() const;
Roberto Raggi's avatar
Roberto Raggi committed
114
    virtual const Reference *asReference() const;
115
    virtual const ColorValue *asColorValue() const;
116
    virtual const AnchorLineValue *asAnchorLineValue() const;
117 118

    virtual void accept(ValueVisitor *) const = 0;
119 120

    virtual bool getSourceLocation(QString *fileName, int *line, int *column) const;
121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166
};

template <typename _RetTy> _RetTy value_cast(const Value *v);

template <> Q_INLINE_TEMPLATE const NullValue *value_cast(const Value *v)
{
    if (v) return v->asNullValue();
    else   return 0;
}

template <> Q_INLINE_TEMPLATE const UndefinedValue *value_cast(const Value *v)
{
    if (v) return v->asUndefinedValue();
    else   return 0;
}

template <> Q_INLINE_TEMPLATE const NumberValue *value_cast(const Value *v)
{
    if (v) return v->asNumberValue();
    else   return 0;
}

template <> Q_INLINE_TEMPLATE const BooleanValue *value_cast(const Value *v)
{
    if (v) return v->asBooleanValue();
    else   return 0;
}

template <> Q_INLINE_TEMPLATE const StringValue *value_cast(const Value *v)
{
    if (v) return v->asStringValue();
    else   return 0;
}

template <> Q_INLINE_TEMPLATE const ObjectValue *value_cast(const Value *v)
{
    if (v) return v->asObjectValue();
    else   return 0;
}

template <> Q_INLINE_TEMPLATE const FunctionValue *value_cast(const Value *v)
{
    if (v) return v->asFunctionValue();
    else   return 0;
}

Roberto Raggi's avatar
Roberto Raggi committed
167 168 169 170 171 172
template <> Q_INLINE_TEMPLATE const Reference *value_cast(const Value *v)
{
    if (v) return v->asReference();
    else   return 0;
}

173 174 175 176 177 178
template <> Q_INLINE_TEMPLATE const ColorValue *value_cast(const Value *v)
{
    if (v) return v->asColorValue();
    else   return 0;
}

179 180 181 182 183 184
template <> Q_INLINE_TEMPLATE const AnchorLineValue *value_cast(const Value *v)
{
    if (v) return v->asAnchorLineValue();
    else   return 0;
}

185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222
////////////////////////////////////////////////////////////////////////////////
// Value nodes
////////////////////////////////////////////////////////////////////////////////
class QMLJS_EXPORT NullValue: public Value
{
public:
    virtual const NullValue *asNullValue() const;
    virtual void accept(ValueVisitor *visitor) const;
};

class QMLJS_EXPORT UndefinedValue: public Value
{
public:
    virtual const UndefinedValue *asUndefinedValue() const;
    virtual void accept(ValueVisitor *visitor) const;
};

class QMLJS_EXPORT NumberValue: public Value
{
public:
    virtual const NumberValue *asNumberValue() const;
    virtual void accept(ValueVisitor *visitor) const;
};

class QMLJS_EXPORT BooleanValue: public Value
{
public:
    virtual const BooleanValue *asBooleanValue() const;
    virtual void accept(ValueVisitor *visitor) const;
};

class QMLJS_EXPORT StringValue: public Value
{
public:
    virtual const StringValue *asStringValue() const;
    virtual void accept(ValueVisitor *visitor) const;
};

Roberto Raggi's avatar
Cleanup  
Roberto Raggi committed
223 224 225 226 227 228
class QMLJS_EXPORT MemberProcessor
{
    MemberProcessor(const MemberProcessor &other);
    void operator = (const MemberProcessor &other);

public:
229 230
    MemberProcessor();
    virtual ~MemberProcessor();
Roberto Raggi's avatar
Cleanup  
Roberto Raggi committed
231 232

    // Returns false to stop the processor.
233
    virtual bool processProperty(const QString &name, const Value *value);
234
    virtual bool processEnumerator(const QString &name, const Value *value);
235 236
    virtual bool processSignal(const QString &name, const Value *value);
    virtual bool processSlot(const QString &name, const Value *value);
237
    virtual bool processGeneratedSlot(const QString &name, const Value *value);
Roberto Raggi's avatar
Cleanup  
Roberto Raggi committed
238 239
};

240
class QMLJS_EXPORT ScopeChain
Roberto Raggi's avatar
Roberto Raggi committed
241
{
242
public:
243 244 245 246
    ScopeChain();

    struct QmlComponentChain
    {
247 248
        QmlComponentChain();
        ~QmlComponentChain();
249

250
        QList<QmlComponentChain *> instantiatingComponents;
251
        Document::Ptr document;
252 253

        void add(QList<const ObjectValue *> *list) const;
254
        void clear();
255 256 257 258 259 260 261 262 263 264
    };

    const ObjectValue *globalScope;
    QmlComponentChain qmlComponentScope;
    QList<const ObjectValue *> qmlScopeObjects;
    const ObjectValue *qmlTypes;
    QList<const ObjectValue *> jsScopes;

    // rebuilds the flat list of all scopes
    void update();
265 266 267 268
    QList<const ObjectValue *> all() const;

private:
    QList<const ObjectValue *> _all;
269 270 271 272
};

class QMLJS_EXPORT Context
{
Roberto Raggi's avatar
Roberto Raggi committed
273 274
public:
    Context(Engine *engine);
275
    ~Context();
Roberto Raggi's avatar
Roberto Raggi committed
276 277

    Engine *engine() const;
278 279
    const ScopeChain &scopeChain() const;
    ScopeChain &scopeChain();
280

281 282
    const ObjectValue *typeEnvironment(const Document *doc) const;
    void setTypeEnvironment(const Document *doc, const ObjectValue *typeEnvironment);
283 284

    const Value *lookup(const QString &name);
285
    const ObjectValue *lookupType(const Document *doc, AST::UiQualifiedId *qmlTypeName);
286
    const ObjectValue *lookupType(const Document *doc, const QStringList &qmlTypeName);
287
    const Value *lookupReference(const Reference *reference);
Roberto Raggi's avatar
Roberto Raggi committed
288 289 290 291

    const Value *property(const ObjectValue *object, const QString &name) const;
    void setProperty(const ObjectValue *object, const QString &name, const Value *value);

292 293
    QString defaultPropertyName(const ObjectValue *object);

294 295 296
    bool documentImportsPlugins(const Document *doc) const;
    void setDocumentImportsPlugins(const Document *doc);

Roberto Raggi's avatar
Roberto Raggi committed
297 298 299 300 301
private:
    typedef QHash<QString, const Value *> Properties;

    Engine *_engine;
    QHash<const ObjectValue *, Properties> _properties;
302
    QHash<QString, const ObjectValue *> _typeEnvironments;
303
    QSet<QString> _documentsImportingPlugins;
Christian Kamm's avatar
Christian Kamm committed
304 305 306
    ScopeChain _scopeChain;
    int _qmlScopeObjectIndex;
    bool _qmlScopeObjectSet;
307
    QList<const Reference *> _referenceStack;
Roberto Raggi's avatar
Roberto Raggi committed
308 309 310 311 312
};

class QMLJS_EXPORT Reference: public Value
{
public:
313
    Reference(Engine *engine);
Roberto Raggi's avatar
Roberto Raggi committed
314 315
    virtual ~Reference();

316
    Engine *engine() const;
Roberto Raggi's avatar
Roberto Raggi committed
317 318 319 320

    // Value interface
    virtual const Reference *asReference() const;
    virtual void accept(ValueVisitor *) const;
321 322

private:
323 324
    virtual const Value *value(Context *context) const;

325
    Engine *_engine;
326
    friend class Context;
Roberto Raggi's avatar
Roberto Raggi committed
327 328
};

329 330 331 332 333 334 335 336
class QMLJS_EXPORT ColorValue: public Value
{
public:
    // Value interface
    virtual const ColorValue *asColorValue() const;
    virtual void accept(ValueVisitor *) const;
};

337 338 339 340 341 342 343 344
class QMLJS_EXPORT AnchorLineValue: public Value
{
public:
    // Value interface
    virtual const AnchorLineValue *asAnchorLineValue() const;
    virtual void accept(ValueVisitor *) const;
};

345
class QMLJS_EXPORT ObjectValue: public Value
346 347 348
{
public:
    ObjectValue(Engine *engine);
Roberto Raggi's avatar
Cleanup  
Roberto Raggi committed
349
    virtual ~ObjectValue();
350 351 352 353 354 355

    Engine *engine() const;

    QString className() const;
    void setClassName(const QString &className);

356 357
    const ObjectValue *prototype(Context *context) const;
    void setPrototype(const Value *prototype);
358

Roberto Raggi's avatar
Cleanup  
Roberto Raggi committed
359
    virtual void processMembers(MemberProcessor *processor) const;
360

361
    virtual const Value *property(const QString &name, Context *context) const;
362 363 364
    virtual void setProperty(const QString &name, const Value *value);
    virtual void removeProperty(const QString &name);

365
    virtual const Value *lookupMember(const QString &name, Context *context, bool examinePrototypes = true) const;
366 367 368 369 370 371

    // Value interface
    virtual const ObjectValue *asObjectValue() const;
    virtual void accept(ValueVisitor *visitor) const;

private:
Roberto Raggi's avatar
Cleanup  
Roberto Raggi committed
372
    bool checkPrototype(const ObjectValue *prototype, QSet<const ObjectValue *> *processed) const;
373 374 375

private:
    Engine *_engine;
376
    const Value *_prototype;
377 378 379 380
    QHash<QString, const Value *> _members;
    QString _className;
};

381
class QMLJS_EXPORT QmlObjectValue: public ObjectValue
382
{
383 384
public:
    QmlObjectValue(const FakeMetaObject *metaObject, Engine *engine);
385 386 387
    virtual ~QmlObjectValue();

    virtual void processMembers(MemberProcessor *processor) const;
388
    const Value *propertyValue(const FakeMetaProperty &prop) const;
389

390
    QString packageName() const;
391
    ComponentVersion version() const;
392
    QString defaultPropertyName() const;
393
    QString propertyType(const QString &propertyName) const;
394
    bool isListProperty(const QString &name) const;
395
    bool isEnum(const QString &typeName) const;
396
    bool enumContainsKey(const QString &enumName, const QString &enumKeyName) const;
397
    bool hasChildInPackage() const;
398

Roberto Raggi's avatar
Roberto Raggi committed
399
protected:
400 401
    const Value *findOrCreateSignature(int index, const FakeMetaMethod &method, QString *methodName) const;
    bool isDerivedFrom(const FakeMetaObject *base) const;
Roberto Raggi's avatar
Roberto Raggi committed
402

403
private:
404
    const FakeMetaObject *_metaObject;
Roberto Raggi's avatar
Roberto Raggi committed
405
    mutable QHash<int, const Value *> _metaSignature;
406 407
};

Christian Kamm's avatar
Christian Kamm committed
408 409 410 411 412 413 414 415 416 417 418 419 420
class QMLJS_EXPORT QmlEnumValue: public NumberValue
{
public:
    QmlEnumValue(const FakeMetaEnum &metaEnum, Engine *engine);
    virtual ~QmlEnumValue();

    QString name() const;
    QStringList keys() const;

private:
    FakeMetaEnum *_metaEnum;
};

421
class QMLJS_EXPORT Activation
Roberto Raggi's avatar
Roberto Raggi committed
422 423
{
public:
424
    explicit Activation(Context *parentContext = 0);
Roberto Raggi's avatar
Roberto Raggi committed
425 426
    virtual ~Activation();

427 428 429
    Context *context() const;
    Context *parentContext() const;

Roberto Raggi's avatar
Roberto Raggi committed
430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445
    bool calledAsConstructor() const;
    void setCalledAsConstructor(bool calledAsConstructor);

    bool calledAsFunction() const;
    void setCalledAsFunction(bool calledAsFunction);

    ObjectValue *thisObject() const;
    void setThisObject(ObjectValue *thisObject);

    ValueList arguments() const;
    void setArguments(const ValueList &arguments);

private:
    ObjectValue *_thisObject;
    ValueList _arguments;
    bool _calledAsFunction;
446
    Context *_parentContext;
Roberto Raggi's avatar
Roberto Raggi committed
447 448 449
};


450 451 452 453
class QMLJS_EXPORT FunctionValue: public ObjectValue
{
public:
    FunctionValue(Engine *engine);
Roberto Raggi's avatar
Cleanup  
Roberto Raggi committed
454 455 456 457 458 459 460 461 462 463 464
    virtual ~FunctionValue();

    // [[construct]]
    const Value *construct(const ValueList &actuals = ValueList()) const;

    // [[call]]
    const Value *call(const ValueList &actuals = ValueList()) const;

    const Value *call(const ObjectValue *thisObject,
                      const ValueList &actuals = ValueList()) const;

465 466 467 468

    virtual const Value *returnValue() const;

    virtual int argumentCount() const;
Roberto Raggi's avatar
Cleanup  
Roberto Raggi committed
469
    virtual const Value *argument(int index) const;
470 471
    virtual QString argumentName(int index) const;
    virtual bool isVariadic() const;
472

Roberto Raggi's avatar
Roberto Raggi committed
473
    virtual const Value *invoke(const Activation *activation) const;
474 475 476 477 478 479 480 481 482 483

    // Value interface
    virtual const FunctionValue *asFunctionValue() const;
    virtual void accept(ValueVisitor *visitor) const;
};

class QMLJS_EXPORT Function: public FunctionValue
{
public:
    Function(Engine *engine);
Roberto Raggi's avatar
Roberto Raggi committed
484
    virtual ~Function();
485

486
    void addArgument(const Value *argument);
487 488 489
    void setReturnValue(const Value *returnValue);

    // ObjectValue interface
490
    virtual const Value *property(const QString &name, Context *context) const;
491 492 493 494 495

    // FunctionValue interface
    virtual const Value *returnValue() const;
    virtual int argumentCount() const;
    virtual const Value *argument(int index) const;
Roberto Raggi's avatar
Roberto Raggi committed
496
    virtual const Value *invoke(const Activation *activation) const;
497 498

private:
Roberto Raggi's avatar
Cleanup  
Roberto Raggi committed
499
    ValueList _arguments;
500 501 502 503 504 505 506 507
    const Value *_returnValue;
};


////////////////////////////////////////////////////////////////////////////////
// typing environment
////////////////////////////////////////////////////////////////////////////////

508
class QMLJS_EXPORT CppQmlTypesLoader
509 510 511
{
public:
    /** \return an empty list when successful, error messages otherwise. */
512
    static QStringList load(const QFileInfoList &xmlFiles);
513
    static QList<const FakeMetaObject *> builtinObjects;
514

515 516
    // parses the xml string and fills the newObjects map
    static QString parseQmlTypeXml(const QByteArray &xml, QMap<QString, FakeMetaObject *> *newObjects);
517
private:
518
    static void setSuperClasses(QMap<QString, FakeMetaObject *> *newObjects);
519 520 521 522 523
};

class QMLJS_EXPORT CppQmlTypes
{
public:
524
    void load(Interpreter::Engine *interpreter, const QList<const FakeMetaObject *> &objects);
525

526
    QList<Interpreter::QmlObjectValue *> typesForImport(const QString &prefix, ComponentVersion version) const;
527
    Interpreter::QmlObjectValue *typeForImport(const QString &qualifiedName) const;
528

529 530
    bool hasPackage(const QString &package) const;

531 532 533
    QHash<QString, QmlObjectValue *> types() const
    { return _typesByFullyQualifiedName; }

534
private:
535 536
    QHash<QString, QList<QmlObjectValue *> > _typesByPackage;
    QHash<QString, QmlObjectValue *> _typesByFullyQualifiedName;
537 538
};

539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622
class ConvertToNumber: protected ValueVisitor // ECMAScript ToInt()
{
public:
    ConvertToNumber(Engine *engine);

    const Value *operator()(const Value *value);

protected:
    const Value *switchResult(const Value *value);

    virtual void visit(const NullValue *);
    virtual void visit(const UndefinedValue *);
    virtual void visit(const NumberValue *);
    virtual void visit(const BooleanValue *);
    virtual void visit(const StringValue *);
    virtual void visit(const ObjectValue *);
    virtual void visit(const FunctionValue *);

private:
    Engine *_engine;
    const Value *_result;
};

class ConvertToString: protected ValueVisitor // ECMAScript ToString
{
public:
    ConvertToString(Engine *engine);

    const Value *operator()(const Value *value);

protected:
    const Value *switchResult(const Value *value);

    virtual void visit(const NullValue *);
    virtual void visit(const UndefinedValue *);
    virtual void visit(const NumberValue *);
    virtual void visit(const BooleanValue *);
    virtual void visit(const StringValue *);
    virtual void visit(const ObjectValue *);
    virtual void visit(const FunctionValue *);

private:
    Engine *_engine;
    const Value *_result;
};

class ConvertToObject: protected ValueVisitor // ECMAScript ToObject
{
public:
    ConvertToObject(Engine *engine);

    const Value *operator()(const Value *value);

protected:
    const Value *switchResult(const Value *value);

    virtual void visit(const NullValue *);
    virtual void visit(const UndefinedValue *);
    virtual void visit(const NumberValue *);
    virtual void visit(const BooleanValue *);
    virtual void visit(const StringValue *);
    virtual void visit(const ObjectValue *);
    virtual void visit(const FunctionValue *);

private:
    Engine *_engine;
    const Value *_result;
};

class TypeId: protected ValueVisitor
{
    QString _result;

public:
    QString operator()(const Value *value);

protected:
    virtual void visit(const NullValue *);
    virtual void visit(const UndefinedValue *);
    virtual void visit(const NumberValue *);
    virtual void visit(const BooleanValue *);
    virtual void visit(const StringValue *);
    virtual void visit(const ObjectValue *object);
    virtual void visit(const FunctionValue *object);
623 624
    virtual void visit(const ColorValue *);
    virtual void visit(const AnchorLineValue *);
625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640
};

class QMLJS_EXPORT Engine
{
    Engine(const Engine &other);
    void operator = (const Engine &other);

public:
    Engine();
    ~Engine();

    const NullValue *nullValue() const;
    const UndefinedValue *undefinedValue() const;
    const NumberValue *numberValue() const;
    const BooleanValue *booleanValue() const;
    const StringValue *stringValue() const;
641
    const ColorValue *colorValue() const;
642
    const AnchorLineValue *anchorLineValue() const;
643

Roberto Raggi's avatar
Roberto Raggi committed
644
    ObjectValue *newObject(const ObjectValue *prototype);
645 646
    ObjectValue *newObject();
    Function *newFunction();
Roberto Raggi's avatar
Roberto Raggi committed
647
    const Value *newArray(); // ### remove me
648

Roberto Raggi's avatar
Roberto Raggi committed
649
    // QML objects
650
    const ObjectValue *qmlKeysObject();
651
    const Value *defaultValueForBuiltinType(const QString &typeName) const;
Roberto Raggi's avatar
Roberto Raggi committed
652

653 654 655
    // global object
    ObjectValue *globalObject() const;
    const ObjectValue *mathObject() const;
656
    const ObjectValue *qtObject() const;
657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678

    // prototypes
    ObjectValue *objectPrototype() const;
    ObjectValue *functionPrototype() const;
    ObjectValue *numberPrototype() const;
    ObjectValue *booleanPrototype() const;
    ObjectValue *stringPrototype() const;
    ObjectValue *arrayPrototype() const;
    ObjectValue *datePrototype() const;
    ObjectValue *regexpPrototype() const;

    // ctors
    const FunctionValue *objectCtor() const;
    const FunctionValue *functionCtor() const;
    const FunctionValue *arrayCtor() const;
    const FunctionValue *stringCtor() const;
    const FunctionValue *booleanCtor() const;
    const FunctionValue *numberCtor() const;
    const FunctionValue *dateCtor() const;
    const FunctionValue *regexpCtor() const;

    // operators
Roberto Raggi's avatar
Roberto Raggi committed
679
    const Value *convertToBoolean(const Value *value);
680 681 682 683 684
    const Value *convertToNumber(const Value *value);
    const Value *convertToString(const Value *value);
    const Value *convertToObject(const Value *value);
    QString typeId(const Value *value);

685
    // typing:
686 687
    CppQmlTypes &cppQmlTypes()
    { return _cppQmlTypes; }
688 689
    const CppQmlTypes &cppQmlTypes() const
    { return _cppQmlTypes; }
690

691 692
    void registerValue(Value *value); // internal

693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719
private:
    void initializePrototypes();

    void addFunction(ObjectValue *object, const QString &name, const Value *result, int argumentCount);
    void addFunction(ObjectValue *object, const QString &name, int argumentCount);

private:
    ObjectValue *_objectPrototype;
    ObjectValue *_functionPrototype;
    ObjectValue *_numberPrototype;
    ObjectValue *_booleanPrototype;
    ObjectValue *_stringPrototype;
    ObjectValue *_arrayPrototype;
    ObjectValue *_datePrototype;
    ObjectValue *_regexpPrototype;

    Function *_objectCtor;
    Function *_functionCtor;
    Function *_arrayCtor;
    Function *_stringCtor;
    Function *_booleanCtor;
    Function *_numberCtor;
    Function *_dateCtor;
    Function *_regexpCtor;

    ObjectValue *_globalObject;
    ObjectValue *_mathObject;
720
    ObjectValue *_qtObject;
721
    ObjectValue *_qmlKeysObject;
722 723 724 725 726 727

    NullValue _nullValue;
    UndefinedValue _undefinedValue;
    NumberValue _numberValue;
    BooleanValue _booleanValue;
    StringValue _stringValue;
728
    ColorValue _colorValue;
729
    AnchorLineValue _anchorLineValue;
730
    QList<Value *> _registeredValues;
731 732 733 734 735

    ConvertToNumber _convertToNumber;
    ConvertToString _convertToString;
    ConvertToObject _convertToObject;
    TypeId _typeId;
736

737
    CppQmlTypes _cppQmlTypes;
738 739
};

740 741

// internal
742 743 744
class QMLJS_EXPORT QmlPrototypeReference: public Reference
{
public:
745
    QmlPrototypeReference(AST::UiQualifiedId *qmlTypeName, const Document *doc, Engine *engine);
746 747 748 749
    virtual ~QmlPrototypeReference();

    AST::UiQualifiedId *qmlTypeName() const;

750
private:    
751 752 753
    virtual const Value *value(Context *context) const;

    AST::UiQualifiedId *_qmlTypeName;
754
    const Document *_doc;
755 756
};

757 758 759 760 761 762 763 764
class QMLJS_EXPORT ASTVariableReference: public Reference
{
    AST::VariableDeclaration *_ast;

public:
    ASTVariableReference(AST::VariableDeclaration *ast, Engine *engine);
    virtual ~ASTVariableReference();

765
private:
766 767 768 769 770 771
    virtual const Value *value(Context *context) const;
};

class QMLJS_EXPORT ASTFunctionValue: public FunctionValue
{
    AST::FunctionDeclaration *_ast;
772
    const Document *_doc;
773 774 775
    QList<NameId *> _argumentNames;

public:
776
    ASTFunctionValue(AST::FunctionDeclaration *ast, const Document *doc, Engine *engine);
777 778 779 780 781 782 783 784 785
    virtual ~ASTFunctionValue();

    AST::FunctionDeclaration *ast() const;

    virtual const Value *returnValue() const;
    virtual int argumentCount() const;
    virtual const Value *argument(int) const;
    virtual QString argumentName(int index) const;
    virtual bool isVariadic() const;
786 787

    virtual bool getSourceLocation(QString *fileName, int *line, int *column) const;
788 789
};

790 791 792 793
class QMLJS_EXPORT ASTPropertyReference: public Reference
{
    AST::UiPublicMember *_ast;
    const Document *_doc;
794
    QString _onChangedSlotName;
795 796 797 798

public:
    ASTPropertyReference(AST::UiPublicMember *ast, const Document *doc, Engine *engine);
    virtual ~ASTPropertyReference();
799

800
    AST::UiPublicMember *ast() const { return _ast; }
801
    QString onChangedSlotName() const { return _onChangedSlotName; }
802 803

    virtual bool getSourceLocation(QString *fileName, int *line, int *column) const;
804 805

private:
806 807 808
    virtual const Value *value(Context *context) const;
};

809 810 811 812 813 814 815 816 817 818 819 820 821 822
class QMLJS_EXPORT ASTSignalReference: public Reference
{
    AST::UiPublicMember *_ast;
    const Document *_doc;
    QString _slotName;

public:
    ASTSignalReference(AST::UiPublicMember *ast, const Document *doc, Engine *engine);
    virtual ~ASTSignalReference();

    AST::UiPublicMember *ast() const { return _ast; }
    QString slotName() const { return _slotName; }

    virtual bool getSourceLocation(QString *fileName, int *line, int *column) const;
823 824

private:
825 826 827
    virtual const Value *value(Context *context) const;
};

828 829 830 831 832 833
class QMLJS_EXPORT ASTObjectValue: public ObjectValue
{
    AST::UiQualifiedId *_typeName;
    AST::UiObjectInitializer *_initializer;
    const Document *_doc;
    QList<ASTPropertyReference *> _properties;
834
    QList<ASTSignalReference *> _signals;
835
    ASTPropertyReference *_defaultPropertyRef;
836 837 838 839 840 841 842 843 844 845

public:
    ASTObjectValue(AST::UiQualifiedId *typeName,
                   AST::UiObjectInitializer *initializer,
                   const Document *doc,
                   Engine *engine);
    virtual ~ASTObjectValue();

    bool getSourceLocation(QString *fileName, int *line, int *column) const;
    virtual void processMembers(MemberProcessor *processor) const;
846 847

    QString defaultPropertyName() const;
848
};
849

850 851 852
} } // end of namespace QmlJS::Interpreter

#endif // QMLJS_INTERPRETER_H