/**************************************************************************** ** ** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal ** ** This file is part of the QtQml module of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** Commercial License Usage ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the ** Software or, alternatively, in accordance with the terms contained in ** a written agreement between you and Digia. For licensing terms and ** conditions see http://qt.digia.com/licensing. For further information ** use the contact form at http://qt.digia.com/contact-us. ** ** 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. ** ** In addition, as a special exception, Digia gives you certain additional ** rights. These rights are described in the Digia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** GNU General Public License Usage ** Alternatively, this file may be used under the terms of the GNU ** General Public License version 3.0 as published by the Free Software ** Foundation and appearing in the file LICENSE.GPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU General Public License version 3.0 requirements will be ** met: http://www.gnu.org/copyleft/gpl.html. ** ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #ifndef QQMLSCRIPT_P_H #define QQMLSCRIPT_P_H // // W A R N I N G // ------------- // // This file is not part of the Qt API. It exists purely as an // implementation detail. This header file may change from version to // version without notice, or even be removed. // // We mean it. // #include #include #include #include #include #include #include QT_BEGIN_NAMESPACE class QByteArray; class QQmlPropertyCache; namespace QQmlJS { namespace AST { class Node; class StringLiteral; } } namespace QQmlCompilerTypes { struct BindingReference; struct ComponentCompileState; } namespace QQmlScript { struct Location { Location() : line(0), column(0) {} quint16 line; quint16 column; inline bool operator<(const Location &other) { return line < other.line || (line == other.line && column < other.column); } }; struct LocationRange { LocationRange() : offset(0), length(0) {} quint32 offset; quint32 length; }; struct LocationSpan { Location start; Location end; LocationRange range; bool operator<(LocationSpan &o) const { return (start.line < o.start.line) || (start.line == o.start.line && start.column < o.start.column); } }; class Import { public: Import() : type(Library), majorVersion(-1), minorVersion(-1) {} enum Type { Library, File, Script }; Type type; QString uri; QString qualifier; int majorVersion; int minorVersion; QQmlScript::LocationSpan location; }; class Object; class TypeReference : public QQmlPool::Class { public: // type as it has been referenced in Qml QString name; // The first use of this type in the parse tree. Useful for error locations. QQmlScript::Object *firstUse; }; class Object; class Property; class Q_QML_PRIVATE_EXPORT Variant { public: enum Type { Invalid, Boolean, Number, String, Script }; Variant(); Variant(const Variant &); explicit Variant(bool); explicit Variant(double, const QStringRef &asWritten = QStringRef()); explicit Variant(QQmlJS::AST::StringLiteral *); explicit Variant(const QStringRef &asWritten, QQmlJS::AST::Node *); Variant &operator=(const Variant &); Type type() const; bool isBoolean() const { return type() == Boolean; } bool isNumber() const { return type() == Number; } bool isString() const { return type() == String; } bool isScript() const { return type() == Script; } bool isStringList() const; bool asBoolean() const; QString asString() const; double asNumber() const; QString asScript() const; QQmlJS::AST::Node *asAST() const; QStringList asStringList() const; private: Type t; union { bool b; double d; QQmlJS::AST::StringLiteral *l; QQmlJS::AST::Node *n; }; QStringRef asWritten; }; class Value : public QQmlPool::POD { public: Value(); enum Type { // The type of this value assignment is not yet known Unknown, // This is used as a literal property assignment Literal, // This is used as a property binding assignment PropertyBinding, // This is used as a QQmlPropertyValueSource assignment ValueSource, // This is used as a QQmlPropertyValueInterceptor assignment ValueInterceptor, // This is used as a property QObject assignment CreatedObject, // This is used as a signal object assignment SignalObject, // This is used as a signal expression assignment SignalExpression, // This is used as an id assignment only Id }; Type type; // ### Temporary (for id only) QString primitive() const { return value.isString() ? value.asString() : value.asScript(); } // Primitive value Variant value; // Object value Object *object; LocationSpan location; // Used by compiler union { QQmlCompilerTypes::BindingReference *bindingReference; int signalExpressionContextStack; }; // Used in Property::ValueList lists Value *nextValue; }; class Property : public QQmlPool::POD { public: Property(); // The Object to which this property is attached Object *parent; Object *getValue(const LocationSpan &); void addValue(Value *v); void addOnValue(Value *v); // The QVariant::Type of the property, or 0 (QVariant::Invalid) if // unknown. int type; // The metaobject index of this property, or -1 if unknown. int index; // The core data in the case of a regular property. // XXX This has to be a value now as the synthCache may change during // compilation which invalidates pointers. We should fix this. QQmlPropertyData core; // Returns true if this is an empty property - both value and values // are unset. bool isEmpty() const; typedef QFieldList ValueList; // The list of values assigned to this property. Content in values // and value are mutually exclusive ValueList values; // The list of values assigned to this property using the "on" syntax ValueList onValues; // The accessed property. This is used to represent dot properties. // Content in value and values are mutually exclusive. Object *value; // The property name const QHashedStringRef &name() const { return _name; } void setName(const QString &n) { _name = QHashedStringRef(pool()->NewString(n)); } void setName(const QHashedStringRef &n) { _name = n; } // True if this property was accessed as the default property. bool isDefault; // True if the setting of this property will be deferred. Set by the // QQmlCompiler bool isDeferred; // True if this property is a value-type pseudo-property bool isValueTypeSubProperty; // True if this property is a property alias. Set by the // QQmlCompiler bool isAlias; // True if this is a readonly property declaration bool isReadOnlyDeclaration; // Used for scriptStringProperties int scriptStringScope; LocationSpan location; LocationRange listValueRange; // Used in Object::MainPropertyList Property *nextMainProperty; // Used in Object::PropertyList lists Property *nextProperty; private: friend class Object; QHashedStringRef _name; }; class Object : public QQmlPool::Class { public: Object(); virtual ~Object(); // Type of the object. The integer is an index into the // QQmlCompiledData::types array, or -1 if the object is a property // group. int type; // A back pointer to the QQmlScript::TypeReference for this type, if any. // Set by the parser. TypeReference *typeReference; // The id assigned to the object (if any). Set by the QQmlCompiler QString id; // The id index assigned to the object (if any). Set by the QQmlCompiler int idIndex; // Custom parsed data QByteArray custom; // Bit mask of the properties assigned bindings QByteArray bindingBitmask; void setBindingBit(int); QQmlPropertyCache *metatype; // The synthesized metaobject, if QML added signals or properties to // this type. Otherwise null QByteArray synthdata; // Generated by compiler QQmlPropertyCache *synthCache; // Generated by compiler Property *getDefaultProperty(); // name ptr must be guaranteed to remain valid Property *getProperty(const QHashedStringRef &name, bool create=true); Property *getProperty(const QStringRef &name, bool create=true); Property *getProperty(const QString &name, bool create=true); Property *defaultProperty; typedef QFieldList MainPropertyList; MainPropertyList properties; QHashField propertiesHashField; // Output of the compilation phase (these properties continue to exist // in either the defaultProperty or properties members too) void addValueProperty(Property *); void addSignalProperty(Property *); void addAttachedProperty(Property *); void addGroupedProperty(Property *); void addValueTypeProperty(Property *); void addScriptStringProperty(Property *); typedef QFieldList PropertyList; PropertyList valueProperties; PropertyList signalProperties; PropertyList attachedProperties; PropertyList groupedProperties; PropertyList valueTypeProperties; PropertyList scriptStringProperties; // Script blocks that were nested under this object struct ScriptBlock { enum Pragma { None = 0x00000000, Shared = 0x00000001 }; Q_DECLARE_FLAGS(Pragmas, Pragma) QString code; QString file; Pragmas pragmas; }; // The bytes to cast instances by to get to the QQmlParserStatus // interface. -1 indicates the type doesn't support this interface. // Set by the QQmlCompiler. int parserStatusCast; LocationSpan location; struct DynamicProperty : public QQmlPool::POD { DynamicProperty(); enum Type { Var, Variant, Int, Bool, Real, String, Url, Color, Font, Time, Date, DateTime, Rect, Point, Size, Vector2D, Vector3D, Vector4D, Matrix4x4, Quaternion, Alias, Custom, CustomList }; quint32 isDefaultProperty:1; quint32 isReadOnly:1; Type type; QHashedStringRef customType; QHashedStringRef name; QQmlScript::Property *defaultValue; LocationSpan location; Location nameLocation; // Used by Object::DynamicPropertyList DynamicProperty *nextProperty; // Used by the compiler int nameIndex; // Points at the name and name + "Changed()" strings }; struct DynamicSignal : public QQmlPool::POD { DynamicSignal(); QHashedStringRef name; QQmlPool::List parameterTypes; QQmlPool::List parameterTypeNames; QQmlPool::List parameterNames; // Used by Object::DynamicSignalList DynamicSignal *nextSignal; // Used by the compiler int nameIndex; LocationSpan location; }; struct DynamicSlot : public QQmlPool::Class { DynamicSlot(); QHashedStringRef name; QString body; QList parameterNames; LocationSpan location; int parameterNamesLength() const; // Used by Object::DynamicSlotList DynamicSlot *nextSlot; // Used by the compiler int nameIndex; }; // The list of dynamic properties typedef QFieldList DynamicPropertyList; DynamicPropertyList dynamicProperties; // The list of dynamic signals typedef QFieldList DynamicSignalList; DynamicSignalList dynamicSignals; // The list of dynamic slots typedef QFieldList DynamicSlotList; DynamicSlotList dynamicSlots; int aggregateDynamicSignalParameterCount() const; int aggregateDynamicSlotParameterCount() const; // Used by compiler QQmlCompilerTypes::ComponentCompileState *componentCompileState; // Used by ComponentCompileState::AliasingObjectsList Object *nextAliasingObject; // Used by ComponentComppileState::IdList Object *nextIdObject; }; class ParserJsASTData; class Q_QML_PRIVATE_EXPORT Parser { public: Parser(); ~Parser(); bool parse(const QString &data, const QByteArray &preparseData, const QUrl &url = QUrl(), const QString &urlString = QString()); QByteArray preparseData() const; QList referencedTypes() const; QQmlScript::Object *tree() const; QList imports() const; void clear(); QList errors() const; class JavaScriptMetaData { public: JavaScriptMetaData() : pragmas(QQmlScript::Object::ScriptBlock::None) {} QQmlScript::Object::ScriptBlock::Pragmas pragmas; QList imports; }; static QQmlScript::Object::ScriptBlock::Pragmas extractPragmas(QString &); static JavaScriptMetaData extractMetaData(QString &, QQmlError *error); // ### private: int findOrCreateTypeId(const QString &name, Object *); void setTree(QQmlScript::Object *tree); void setScriptFile(const QString &filename) {_scriptFile = filename; } QString scriptFile() const { return _scriptFile; } // ### private: QList _errors; QQmlPool _pool; QQmlScript::Object *root; QList _imports; QList _refTypes; QString _scriptFile; ParserJsASTData *data; }; } Q_DECLARE_OPERATORS_FOR_FLAGS(QQmlScript::Object::ScriptBlock::Pragmas); QT_END_NAMESPACE Q_DECLARE_METATYPE(QQmlScript::Variant) #endif // QQMLSCRIPT_P_H