Implement strict mode for qmldir modules
[profile/ivi/qtdeclarative.git] / src / qml / qml / qqmlscript_p.h
1 /****************************************************************************
2 **
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/
5 **
6 ** This file is part of the QtQml module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** GNU Lesser General Public License Usage
10 ** This file may be used under the terms of the GNU Lesser General Public
11 ** License version 2.1 as published by the Free Software Foundation and
12 ** appearing in the file LICENSE.LGPL included in the packaging of this
13 ** file. Please review the following information to ensure the GNU Lesser
14 ** General Public License version 2.1 requirements will be met:
15 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
16 **
17 ** In addition, as a special exception, Nokia gives you certain additional
18 ** rights. These rights are described in the Nokia Qt LGPL Exception
19 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
20 **
21 ** GNU General Public License Usage
22 ** Alternatively, this file may be used under the terms of the GNU General
23 ** Public License version 3.0 as published by the Free Software Foundation
24 ** and appearing in the file LICENSE.GPL included in the packaging of this
25 ** file. Please review the following information to ensure the GNU General
26 ** Public License version 3.0 requirements will be met:
27 ** http://www.gnu.org/copyleft/gpl.html.
28 **
29 ** Other Usage
30 ** Alternatively, this file may be used in accordance with the terms and
31 ** conditions contained in a signed written agreement between you and Nokia.
32 **
33 **
34 **
35 **
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41 #ifndef QQMLSCRIPT_P_H
42 #define QQMLSCRIPT_P_H
43
44 //
45 //  W A R N I N G
46 //  -------------
47 //
48 // This file is not part of the Qt API.  It exists purely as an
49 // implementation detail.  This header file may change from version to
50 // version without notice, or even be removed.
51 //
52 // We mean it.
53 //
54
55 #include <QtQml/qqmlerror.h>
56
57 #include <private/qfieldlist_p.h>
58 #include <private/qhashfield_p.h>
59 #include <private/qqmlpool_p.h>
60 #include <private/qqmlpropertycache_p.h>
61
62 #include <QtCore/QList>
63 #include <QtCore/QUrl>
64
65 QT_BEGIN_HEADER
66
67 QT_BEGIN_NAMESPACE
68
69
70 class QByteArray;
71 class QQmlPropertyCache;
72 namespace QQmlJS { namespace AST { class Node; class StringLiteral; } }
73 namespace QQmlCompilerTypes { struct BindingReference; struct ComponentCompileState; }
74
75 namespace QQmlScript {
76
77 struct Location 
78 {
79     Location() : line(-1), column(-1) {}
80     int line;
81     int column;
82
83     inline bool operator<(const Location &other) {
84         return line < other.line || 
85                (line == other.line && column < other.column);
86     }
87 };
88
89 struct LocationRange
90 {
91     LocationRange() : offset(0), length(0) {}
92     quint32 offset;
93     quint32 length;
94 };
95
96 struct LocationSpan
97 {
98     Location start;
99     Location end;
100     LocationRange range;
101
102     bool operator<(LocationSpan &o) const {
103         return (start.line < o.start.line) ||
104                (start.line == o.start.line && start.column < o.start.column);
105     }
106 };
107
108 class Import
109 {
110 public:
111     Import() : type(Library), majorVersion(-1), minorVersion(-1) {}
112
113     enum Type { Library, File, Script };
114     Type type;
115
116     QString uri;
117     QString qualifier;
118
119     int majorVersion;
120     int minorVersion;
121
122     QQmlScript::LocationSpan location;
123 };
124
125 class Object;
126 class TypeReference : public QQmlPool::Class
127 {
128 public:
129     // type as it has been referenced in Qml
130     QString name;
131     // The first use of this type in the parse tree.  Useful for error locations.
132     QQmlScript::Object *firstUse;
133 };
134
135 class Object;
136 class Property;
137
138 class Q_QML_PRIVATE_EXPORT Variant
139 {
140 public:
141     enum Type {
142         Invalid,
143         Boolean,
144         Number,
145         String,
146         Script
147     };
148
149     Variant();
150     Variant(const Variant &);
151     explicit Variant(bool);
152     explicit Variant(double, const QStringRef &asWritten = QStringRef());
153     explicit Variant(QQmlJS::AST::StringLiteral *);
154     explicit Variant(const QStringRef &asWritten, QQmlJS::AST::Node *);
155     Variant &operator=(const Variant &);
156
157     Type type() const;
158
159     bool isBoolean() const { return type() == Boolean; }
160     bool isNumber() const { return type() == Number; }
161     bool isString() const { return type() == String; }
162     bool isScript() const { return type() == Script; }
163     bool isStringList() const;
164
165     bool asBoolean() const;
166     QString asString() const;
167     double asNumber() const;
168     QString asScript() const;
169     QQmlJS::AST::Node *asAST() const;
170     QStringList asStringList() const;
171
172 private:
173     Type t;
174     union {
175         bool b;
176         double d;
177         QQmlJS::AST::StringLiteral *l;
178         QQmlJS::AST::Node *n;
179     };
180     QStringRef asWritten;
181 };
182
183 class Value : public QQmlPool::POD
184 {
185 public:
186     Value();
187
188     enum Type {
189         // The type of this value assignment is not yet known
190         Unknown,
191         // This is used as a literal property assignment
192         Literal,
193         // This is used as a property binding assignment
194         PropertyBinding,
195         // This is used as a QQmlPropertyValueSource assignment
196         ValueSource,
197         // This is used as a QQmlPropertyValueInterceptor assignment
198         ValueInterceptor,
199         // This is used as a property QObject assignment
200         CreatedObject,
201         // This is used as a signal object assignment
202         SignalObject,
203         // This is used as a signal expression assignment
204         SignalExpression,
205         // This is used as an id assignment only
206         Id
207     };
208     Type type;
209
210     // ### Temporary (for id only)
211     QString primitive() const { return value.isString() ? value.asString() : value.asScript(); }
212
213     // Primitive value
214     Variant value;
215     // Object value
216     Object *object;
217
218     LocationSpan location;
219
220     // Used by compiler
221     union {
222         QQmlCompilerTypes::BindingReference *bindingReference;
223         int signalExpressionContextStack;
224     };
225
226     // Used in Property::ValueList lists
227     Value *nextValue;
228 };
229
230 class Property : public QQmlPool::POD
231 {
232 public:
233     Property();
234
235     // The Object to which this property is attached
236     Object *parent;
237
238     Object *getValue(const LocationSpan &);
239     void addValue(Value *v);
240     void addOnValue(Value *v);
241
242     // The QVariant::Type of the property, or 0 (QVariant::Invalid) if 
243     // unknown.
244     int type;
245     // The metaobject index of this property, or -1 if unknown.
246     int index;
247     // The core data in the case of a regular property.  
248     // XXX This has to be a value now as the synthCache may change during
249     // compilation which invalidates pointers.  We should fix this.
250     QQmlPropertyData core;
251
252     // Returns true if this is an empty property - both value and values
253     // are unset.
254     bool isEmpty() const;
255
256     typedef QFieldList<Value, &Value::nextValue> ValueList;
257     // The list of values assigned to this property.  Content in values
258     // and value are mutually exclusive
259     ValueList values;
260     // The list of values assigned to this property using the "on" syntax
261     ValueList onValues;
262     // The accessed property.  This is used to represent dot properties.
263     // Content in value and values are mutually exclusive.
264     Object *value;
265     // The property name
266     const QHashedStringRef &name() const { return _name; }
267     void setName(const QString &n) { _name = QHashedStringRef(pool()->NewString(n)); }
268     void setName(const QHashedStringRef &n) { _name = n; }
269     // True if this property was accessed as the default property.  
270     bool isDefault;
271     // True if the setting of this property will be deferred.  Set by the
272     // QQmlCompiler
273     bool isDeferred;
274     // True if this property is a value-type pseudo-property
275     bool isValueTypeSubProperty;
276     // True if this property is a property alias.  Set by the 
277     // QQmlCompiler
278     bool isAlias;
279     // True if this is a readonly property declaration
280     bool isReadOnlyDeclaration;
281
282     // Used for scriptStringProperties
283     int scriptStringScope;
284
285     LocationSpan location;
286     LocationRange listValueRange;
287
288     // Used in Object::MainPropertyList
289     Property *nextMainProperty;
290
291     // Used in Object::PropertyList lists
292     Property *nextProperty;
293
294 private:
295     friend class Object;
296     QHashedStringRef _name;
297 };
298
299 class Object : public QQmlPool::Class
300 {
301 public:
302     Object();
303     virtual ~Object(); 
304
305     // Type of the object.  The integer is an index into the 
306     // QQmlCompiledData::types array, or -1 if the object is a property
307     // group.
308     int type;
309     // A back pointer to the QQmlScript::TypeReference for this type, if any.
310     // Set by the parser.
311     TypeReference *typeReference;
312
313     // The id assigned to the object (if any).  Set by the QQmlCompiler
314     QString id;
315     // The id index assigned to the object (if any).  Set by the QQmlCompiler
316     int idIndex;
317     // Custom parsed data
318     QByteArray custom;
319     // Bit mask of the properties assigned bindings
320     QByteArray bindingBitmask; 
321     void setBindingBit(int);
322
323     QQmlPropertyCache *metatype;
324
325     // The synthesized metaobject, if QML added signals or properties to
326     // this type.  Otherwise null
327     QByteArray synthdata;  // Generated by compiler
328     QQmlPropertyCache *synthCache; // Generated by compiler
329
330     Property *getDefaultProperty();
331     // name ptr must be guarenteed to remain valid
332     Property *getProperty(const QHashedStringRef &name, bool create=true);
333     Property *getProperty(const QStringRef &name, bool create=true);
334     Property *getProperty(const QString &name, bool create=true);
335
336     Property *defaultProperty;
337
338     typedef QFieldList<Property, &Property::nextMainProperty> MainPropertyList;
339     MainPropertyList properties;
340     QHashField propertiesHashField;
341
342     // Output of the compilation phase (these properties continue to exist
343     // in either the defaultProperty or properties members too)
344     void addValueProperty(Property *);
345     void addSignalProperty(Property *);
346     void addAttachedProperty(Property *);
347     void addGroupedProperty(Property *);
348     void addValueTypeProperty(Property *);
349     void addScriptStringProperty(Property *);
350
351     typedef QFieldList<Property, &Property::nextProperty> PropertyList;
352     PropertyList valueProperties;
353     PropertyList signalProperties;
354     PropertyList attachedProperties;
355     PropertyList groupedProperties;
356     PropertyList valueTypeProperties;
357     PropertyList scriptStringProperties;
358
359     // Script blocks that were nested under this object
360     struct ScriptBlock {
361         enum Pragma { 
362             None   = 0x00000000,
363             Shared = 0x00000001
364         };
365         Q_DECLARE_FLAGS(Pragmas, Pragma)
366
367         QString code;
368         QString file;
369         Pragmas pragmas;
370     };
371
372     // The bytes to cast instances by to get to the QQmlParserStatus 
373     // interface.  -1 indicates the type doesn't support this interface.
374     // Set by the QQmlCompiler.
375     int parserStatusCast;
376
377     LocationSpan location;
378
379     struct DynamicProperty : public QQmlPool::POD 
380     {
381         DynamicProperty();
382
383         enum Type { Var, Variant, Int, Bool, Real, String, Url, Color,
384                     Font, Time, Date, DateTime, Rect, Point, Size,
385                     Vector2D, Vector3D, Vector4D, Matrix4x4, Quaternion,
386                     Alias, Custom, CustomList };
387
388         quint32 isDefaultProperty:1;
389         quint32 isReadOnly:1;
390
391         Type type;
392
393         QHashedStringRef customType;
394         QHashedStringRef name;
395         QQmlScript::Property *defaultValue;
396         LocationSpan location;
397         Location nameLocation;
398
399         // Used by Object::DynamicPropertyList
400         DynamicProperty *nextProperty;
401
402         // Used by the compiler
403         int nameIndex; // Points at the name and name + "Changed()" strings
404     };
405
406     struct DynamicSignal : public QQmlPool::POD
407     {
408         DynamicSignal();
409
410         QHashedStringRef name;
411         QQmlPool::List<DynamicProperty::Type> parameterTypes;
412         QQmlPool::List<QHashedStringRef> parameterNames;
413
414         // Used by Object::DynamicSignalList
415         DynamicSignal *nextSignal;
416
417         // Used by the compiler
418         int nameIndex;
419         LocationSpan location;
420     };
421
422     struct DynamicSlot : public QQmlPool::Class
423     {
424         DynamicSlot();
425
426         QHashedStringRef name;
427         QString body;
428         QList<QByteArray> parameterNames;
429         LocationSpan location;
430
431         int parameterNamesLength() const;
432
433         // Used by Object::DynamicSlotList
434         DynamicSlot *nextSlot;
435
436         // Used by the compiler
437         int nameIndex;
438     };
439
440     // The list of dynamic properties
441     typedef QFieldList<DynamicProperty, &DynamicProperty::nextProperty> DynamicPropertyList;
442     DynamicPropertyList dynamicProperties;
443     // The list of dynamic signals
444     typedef QFieldList<DynamicSignal, &DynamicSignal::nextSignal> DynamicSignalList;
445     DynamicSignalList dynamicSignals;
446     // The list of dynamic slots
447     typedef QFieldList<DynamicSlot, &DynamicSlot::nextSlot> DynamicSlotList;
448     DynamicSlotList dynamicSlots;
449
450     int aggregateDynamicSignalParameterCount() const;
451     int aggregateDynamicSlotParameterCount() const;
452
453     // Used by compiler
454     QQmlCompilerTypes::ComponentCompileState *componentCompileState;
455
456     // Used by ComponentCompileState::AliasingObjectsList
457     Object *nextAliasingObject;
458     // Used by ComponentComppileState::IdList
459     Object *nextIdObject;
460 };
461
462 class ParserJsASTData;
463 class Q_QML_PRIVATE_EXPORT Parser
464 {
465 public:
466     Parser();
467     ~Parser();
468
469     bool parse(const QString &data, const QByteArray &preparseData,
470                const QUrl &url = QUrl(), const QString &urlString = QString());
471
472     QByteArray preparseData() const;
473
474     QList<TypeReference*> referencedTypes() const;
475
476     QQmlScript::Object *tree() const;
477     QList<Import> imports() const;
478
479     void clear();
480
481     QList<QQmlError> errors() const;
482
483     class JavaScriptMetaData {
484     public:
485         JavaScriptMetaData() 
486         : pragmas(QQmlScript::Object::ScriptBlock::None) {}
487
488         QQmlScript::Object::ScriptBlock::Pragmas pragmas;
489         QList<Import> imports;
490     };
491
492     static QQmlScript::Object::ScriptBlock::Pragmas extractPragmas(QString &);
493     static JavaScriptMetaData extractMetaData(QString &, QQmlError *error);
494
495
496 // ### private:
497     int findOrCreateTypeId(const QString &name, Object *);
498     void setTree(QQmlScript::Object *tree);
499
500     void setScriptFile(const QString &filename) {_scriptFile = filename; }
501     QString scriptFile() const { return _scriptFile; }
502
503 // ### private:
504     QList<QQmlError> _errors;
505
506     QQmlPool _pool;
507     QQmlScript::Object *root;
508     QList<Import> _imports;
509     QList<TypeReference*> _refTypes;
510     QString _scriptFile;
511     ParserJsASTData *data;
512 };
513
514 }
515
516 Q_DECLARE_OPERATORS_FOR_FLAGS(QQmlScript::Object::ScriptBlock::Pragmas);
517
518 QT_END_NAMESPACE
519
520 Q_DECLARE_METATYPE(QQmlScript::Variant)
521
522 QT_END_HEADER
523
524 #endif // QQMLSCRIPT_P_H