Qt 4.8
qdeclarativecompiler.cpp
Go to the documentation of this file.
1 /****************************************************************************
2 **
3 ** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/legal
5 **
6 ** This file is part of the QtDeclarative module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia. For licensing terms and
14 ** conditions see http://qt.digia.com/licensing. For further information
15 ** use the contact form at http://qt.digia.com/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 2.1 requirements
23 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24 **
25 ** In addition, as a special exception, Digia gives you certain additional
26 ** rights. These rights are described in the Digia Qt LGPL Exception
27 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28 **
29 ** GNU General Public License Usage
30 ** Alternatively, this file may be used under the terms of the GNU
31 ** General Public License version 3.0 as published by the Free Software
32 ** Foundation and appearing in the file LICENSE.GPL included in the
33 ** packaging of this file. Please review the following information to
34 ** ensure the GNU General Public License version 3.0 requirements will be
35 ** met: http://www.gnu.org/copyleft/gpl.html.
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41 
42 #include "private/qdeclarativecompiler_p.h"
43 
44 #include "private/qdeclarativeparser_p.h"
45 #include "private/qdeclarativescriptparser_p.h"
47 #include "qdeclarativecomponent.h"
48 #include "private/qmetaobjectbuilder_p.h"
49 #include "private/qdeclarativestringconverters_p.h"
50 #include "private/qdeclarativeengine_p.h"
51 #include "qdeclarativeengine.h"
52 #include "qdeclarativecontext.h"
53 #include "private/qdeclarativemetatype_p.h"
54 #include "private/qdeclarativecustomparser_p_p.h"
55 #include "private/qdeclarativecontext_p.h"
56 #include "private/qdeclarativecomponent_p.h"
58 #include "private/qdeclarativevmemetaobject_p.h"
59 #include "private/qdeclarativeexpression_p.h"
60 #include "private/qdeclarativeproperty_p.h"
61 #include "private/qdeclarativerewrite_p.h"
63 #include "private/qdeclarativeglobal_p.h"
64 #include "private/qdeclarativescriptparser_p.h"
65 #include "private/qdeclarativebinding_p.h"
66 #include "private/qdeclarativecompiledbindings_p.h"
67 #include "private/qdeclarativeglobalscriptclass_p.h"
68 
69 #include <QColor>
70 #include <QDebug>
71 #include <QPointF>
72 #include <QSizeF>
73 #include <QRectF>
74 #include <QAtomicInt>
75 #include <QtCore/qdebug.h>
76 #include <QtCore/qdatetime.h>
77 
79 
80 DEFINE_BOOL_CONFIG_OPTION(compilerDump, QML_COMPILER_DUMP);
81 DEFINE_BOOL_CONFIG_OPTION(compilerStatDump, QML_COMPILER_STATS);
82 DEFINE_BOOL_CONFIG_OPTION(bindingsDump, QML_BINDINGS_DUMP);
83 
84 using namespace QDeclarativeParser;
85 
90 : output(0), engine(0), unitRoot(0), unit(0)
91 {
92 }
93 
100 {
101  return !exceptions.isEmpty();
102 }
103 
109 {
110  return exceptions;
111 }
112 
119 {
120  return !name.isEmpty() && name.at(0) >= 'A' && name.at(0) <= 'Z';
121 }
122 
130 {
131  return name.length() >= 3 && name.startsWith("on") &&
132  'A' <= name.at(2) && 'Z' >= name.at(2);
133 }
134 
153 #define COMPILE_EXCEPTION(token, desc) \
154  { \
155  QString exceptionDescription; \
156  QDeclarativeError error; \
157  error.setUrl(output->url); \
158  error.setLine((token)->location.start.line); \
159  error.setColumn((token)->location.start.column); \
160  error.setDescription(desc.trimmed()); \
161  exceptions << error; \
162  return false; \
163  }
164 
173 #define COMPILE_CHECK(a) \
174  { \
175  if (!a) return false; \
176  }
177 
187 {
188  QString string = v->value.asString();
189 
190  if (!prop.isWritable())
191  COMPILE_EXCEPTION(v, tr("Invalid property assignment: \"%1\" is a read-only property").arg(QString::fromUtf8(prop.name())));
192 
193  if (prop.isEnumType()) {
194  int value;
195  if (prop.isFlagType()) {
196  value = prop.enumerator().keysToValue(string.toUtf8().constData());
197  } else
198  value = prop.enumerator().keyToValue(string.toUtf8().constData());
199  if (value == -1)
200  COMPILE_EXCEPTION(v, tr("Invalid property assignment: unknown enumeration"));
201  return true;
202  }
203  int type = prop.userType();
204  switch(type) {
205  case -1:
206  break;
207  case QVariant::String:
208  if (!v->value.isString()) COMPILE_EXCEPTION(v, tr("Invalid property assignment: string expected"));
209  break;
210  case QVariant::Url:
211  if (!v->value.isString()) COMPILE_EXCEPTION(v, tr("Invalid property assignment: url expected"));
212  break;
213  case QVariant::UInt:
214  {
215  bool ok = v->value.isNumber();
216  if (ok) {
217  double n = v->value.asNumber();
218  if (double(uint(n)) != n)
219  ok = false;
220  }
221  if (!ok) COMPILE_EXCEPTION(v, tr("Invalid property assignment: unsigned int expected"));
222  }
223  break;
224  case QVariant::Int:
225  {
226  bool ok = v->value.isNumber();
227  if (ok) {
228  double n = v->value.asNumber();
229  if (double(int(n)) != n)
230  ok = false;
231  }
232  if (!ok) COMPILE_EXCEPTION(v, tr("Invalid property assignment: int expected"));
233  }
234  break;
235  case QMetaType::Float:
236  if (!v->value.isNumber()) COMPILE_EXCEPTION(v, tr("Invalid property assignment: number expected"));
237  break;
238  case QVariant::Double:
239  if (!v->value.isNumber()) COMPILE_EXCEPTION(v, tr("Invalid property assignment: number expected"));
240  break;
241  case QVariant::Color:
242  {
243  bool ok;
245  if (!ok) COMPILE_EXCEPTION(v, tr("Invalid property assignment: color expected"));
246  }
247  break;
248 #ifndef QT_NO_DATESTRING
249  case QVariant::Date:
250  {
251  bool ok;
253  if (!ok) COMPILE_EXCEPTION(v, tr("Invalid property assignment: date expected"));
254  }
255  break;
256  case QVariant::Time:
257  {
258  bool ok;
260  if (!ok) COMPILE_EXCEPTION(v, tr("Invalid property assignment: time expected"));
261  }
262  break;
263  case QVariant::DateTime:
264  {
265  bool ok;
267  if (!ok) COMPILE_EXCEPTION(v, tr("Invalid property assignment: datetime expected"));
268  }
269  break;
270 #endif // QT_NO_DATESTRING
271  case QVariant::Point:
272  case QVariant::PointF:
273  {
274  bool ok;
276  if (!ok) COMPILE_EXCEPTION(v, tr("Invalid property assignment: point expected"));
277  }
278  break;
279  case QVariant::Size:
280  case QVariant::SizeF:
281  {
282  bool ok;
284  if (!ok) COMPILE_EXCEPTION(v, tr("Invalid property assignment: size expected"));
285  }
286  break;
287  case QVariant::Rect:
288  case QVariant::RectF:
289  {
290  bool ok;
292  if (!ok) COMPILE_EXCEPTION(v, tr("Invalid property assignment: rect expected"));
293  }
294  break;
295  case QVariant::Bool:
296  {
297  if (!v->value.isBoolean()) COMPILE_EXCEPTION(v, tr("Invalid property assignment: boolean expected"));
298  }
299  break;
300  case QVariant::Vector3D:
301  {
302  bool ok;
304  if (!ok) COMPILE_EXCEPTION(v, tr("Invalid property assignment: 3D vector expected"));
305  }
306  break;
307  default:
308  {
309  int t = prop.userType();
312  if (!converter)
313  COMPILE_EXCEPTION(v, tr("Invalid property assignment: unsupported type \"%1\"").arg(QString::fromLatin1(QVariant::typeToName(prop.type()))));
314  }
315  break;
316  }
317  return true;
318 }
319 
328 {
329  QString string = v->value.asString();
330 
332  instr.line = v->location.start.line;
333  if (prop.isEnumType()) {
334  int value;
335  if (v->value.isNumber()) { //Number saved from earlier check - not valid in testLiteralAssignment
336  value = v->value.asNumber();
337  } else {
338  if (prop.isFlagType())
339  value = prop.enumerator().keysToValue(string.toUtf8().constData());
340  else
341  value = prop.enumerator().keyToValue(string.toUtf8().constData());
342  }
343 
346  instr.storeInteger.value = value;
347  output->bytecode << instr;
348  return;
349  }
350 
351  int type = prop.userType();
352  switch(type) {
353  case -1:
354  {
355  if (v->value.isNumber()) {
356  double n = v->value.asNumber();
357  if (double(int(n)) == n) {
360  instr.storeInteger.value = int(n);
361  } else {
363  instr.storeDouble.propertyIndex = prop.propertyIndex();
364  instr.storeDouble.value = n;
365  }
366  } else if(v->value.isBoolean()) {
368  instr.storeBool.propertyIndex = prop.propertyIndex();
369  instr.storeBool.value = v->value.asBoolean();
370  } else {
372  instr.storeString.propertyIndex = prop.propertyIndex();
373  instr.storeString.value = output->indexForString(string);
374  }
375  }
376  break;
377  case QVariant::String:
378  {
380  instr.storeString.propertyIndex = prop.propertyIndex();
381  instr.storeString.value = output->indexForString(string);
382  }
383  break;
384  case QVariant::Url:
385  {
387  QUrl u = string.isEmpty() ? QUrl() : output->url.resolved(QUrl(string));
388  instr.storeUrl.propertyIndex = prop.propertyIndex();
389  instr.storeUrl.value = output->indexForUrl(u);
390  }
391  break;
392  case QVariant::UInt:
393  {
396  instr.storeInteger.value = uint(v->value.asNumber());
397  }
398  break;
399  case QVariant::Int:
400  {
403  instr.storeInteger.value = int(v->value.asNumber());
404  }
405  break;
406  case QMetaType::Float:
407  {
409  instr.storeFloat.propertyIndex = prop.propertyIndex();
410  instr.storeFloat.value = float(v->value.asNumber());
411  }
412  break;
413  case QVariant::Double:
414  {
416  instr.storeDouble.propertyIndex = prop.propertyIndex();
417  instr.storeDouble.value = v->value.asNumber();
418  }
419  break;
420  case QVariant::Color:
421  {
424  instr.storeColor.propertyIndex = prop.propertyIndex();
425  instr.storeColor.value = c.rgba();
426  }
427  break;
428 #ifndef QT_NO_DATESTRING
429  case QVariant::Date:
430  {
433  instr.storeDate.propertyIndex = prop.propertyIndex();
434  instr.storeDate.value = d.toJulianDay();
435  }
436  break;
437  case QVariant::Time:
438  {
440  int data[] = { time.hour(), time.minute(),
441  time.second(), time.msec() };
442  int index = output->indexForInt(data, 4);
444  instr.storeTime.propertyIndex = prop.propertyIndex();
445  instr.storeTime.valueIndex = index;
446  }
447  break;
448  case QVariant::DateTime:
449  {
451  int data[] = { dateTime.date().toJulianDay(),
452  dateTime.time().hour(),
453  dateTime.time().minute(),
454  dateTime.time().second(),
455  dateTime.time().msec() };
456  int index = output->indexForInt(data, 5);
460  }
461  break;
462 #endif // QT_NO_DATESTRING
463  case QVariant::Point:
464  case QVariant::PointF:
465  {
466  bool ok;
467  QPointF point =
469  float data[] = { float(point.x()), float(point.y()) };
470  int index = output->indexForFloat(data, 2);
471  if (type == QVariant::PointF)
473  else
477  }
478  break;
479  case QVariant::Size:
480  case QVariant::SizeF:
481  {
482  bool ok;
484  float data[] = { float(size.width()), float(size.height()) };
485  int index = output->indexForFloat(data, 2);
486  if (type == QVariant::SizeF)
488  else
492  }
493  break;
494  case QVariant::Rect:
495  case QVariant::RectF:
496  {
497  bool ok;
499  float data[] = { float(rect.x()), float(rect.y()),
500  float(rect.width()), float(rect.height()) };
501  int index = output->indexForFloat(data, 4);
502  if (type == QVariant::RectF)
504  else
506  instr.storeRect.propertyIndex = prop.propertyIndex();
507  instr.storeRect.valueIndex = index;
508  }
509  break;
510  case QVariant::Bool:
511  {
512  bool b = v->value.asBoolean();
514  instr.storeBool.propertyIndex = prop.propertyIndex();
515  instr.storeBool.value = b;
516  }
517  break;
518  case QVariant::Vector3D:
519  {
520  bool ok;
521  QVector3D vector =
523  float data[] = { float(vector.x()), float(vector.y()), float(vector.z()) };
524  int index = output->indexForFloat(data, 3);
528  }
529  break;
530  default:
531  {
532  int t = prop.userType();
533  int index = output->customTypeData.count();
537 
539  data.index = output->indexForString(string);
540  data.type = t;
542  }
543  break;
544  }
545  output->bytecode << instr;
546 }
547 
552 {
553  data->types.clear();
554  data->primitives.clear();
555  data->floatData.clear();
556  data->intData.clear();
557  data->customTypeData.clear();
558  data->datas.clear();
559  data->bytecode.clear();
560 }
561 
576 {
577  exceptions.clear();
578 
579  Q_ASSERT(out);
580  reset(out);
581 
582  output = out;
583 
584  // Compile types
585  const QList<QDeclarativeTypeData::TypeReference> &resolvedTypes = unit->resolvedTypes();
587 
588  for (int ii = 0; ii < resolvedTypes.count(); ++ii) {
590 
591  const QDeclarativeTypeData::TypeReference &tref = resolvedTypes.at(ii);
592  QDeclarativeScriptParser::TypeReference *parserRef = referencedTypes.at(ii);
593 
594  if (tref.type) {
595  ref.type = tref.type;
596  if (!ref.type->isCreatable()) {
597  QString err = ref.type->noCreationReason();
598  if (err.isEmpty())
599  err = tr( "Element is not creatable.");
600  COMPILE_EXCEPTION(parserRef->refObjects.first(), err);
601  }
602 
603  if (ref.type->containsRevisionedAttributes()) {
604  QDeclarativeError cacheError;
605  ref.typePropertyCache =
606  QDeclarativeEnginePrivate::get(engine)->cache(ref.type, resolvedTypes.at(ii).minorVersion, cacheError);
607 
608  if (!ref.typePropertyCache) {
609  COMPILE_EXCEPTION(parserRef->refObjects.first(), cacheError.description());
610  }
611  ref.typePropertyCache->addref();
612  }
613 
614  } else if (tref.typeData) {
615  ref.component = tref.typeData->compiledData();
616  }
617  ref.className = parserRef->name.toUtf8();
618  out->types << ref;
619  }
620 
621  QDeclarativeParser::Object *root = unit->parser().tree();
622  Q_ASSERT(root);
623 
624  this->engine = engine;
626  this->unit = unit;
627  this->unitRoot = root;
628  compileTree(root);
629 
630  if (!isError()) {
631  if (compilerDump())
632  out->dumpInstructions();
633  if (compilerStatDump())
634  dumpStats();
636  } else {
637  reset(out);
638  }
639 
641  savedCompileStates.clear();
642  output = 0;
643  this->engine = 0;
644  this->enginePrivate = 0;
645  this->unit = 0;
646  this->unitRoot = 0;
647 
648  return !isError();
649 }
650 
652 {
653  compileState.root = tree;
655 
657  return;
658 
661  init.line = 0;
662  init.init.bindingsSize = compileState.bindings.count();
666  init.init.compiledBinding = -1;
667  else
669  output->bytecode << init;
670 
671  // Build global import scripts
672  QHash<QString, Object::ScriptBlock> importedScripts;
673  QStringList importedScriptIndexes;
674 
676  QString scriptCode = script.script->scriptSource();
677  Object::ScriptBlock::Pragmas pragmas = script.script->pragmas();
678 
679  Q_ASSERT(!importedScripts.contains(script.qualifier));
680 
681  if (!scriptCode.isEmpty()) {
682  Object::ScriptBlock &scriptBlock = importedScripts[script.qualifier];
683 
684  scriptBlock.code = scriptCode;
685  scriptBlock.file = script.script->finalUrl().toString();
686  scriptBlock.pragmas = pragmas;
687  }
688  }
689 
690  for (QHash<QString, Object::ScriptBlock>::Iterator iter = importedScripts.begin();
691  iter != importedScripts.end(); ++iter) {
692 
693  importedScriptIndexes.append(iter.key());
694 
697  import.line = 0;
698  import.storeScript.value = output->scripts.count();
699  output->scripts << *iter;
700  output->bytecode << import;
701  }
702 
703  genObject(tree);
704 
706  init.line = 0;
708  output->bytecode << def;
709 
711 
712  for (int ii = 0; ii < importedScriptIndexes.count(); ++ii)
713  output->importCache->add(importedScriptIndexes.at(ii), ii);
714 
716 
717  Q_ASSERT(tree->metatype);
718 
719  if (tree->metadata.isEmpty()) {
720  output->root = tree->metatype;
721  } else {
722  static_cast<QMetaObject &>(output->rootData) = *tree->metaObject();
723  output->root = &output->rootData;
724  }
725  if (!tree->metadata.isEmpty())
727 }
728 
730 {
731  return t1->location.start.line < t2->location.start.line ||
732  (t1->location.start.line == t2->location.start.line &&
734 }
735 
737 {
739 
740  Q_ASSERT (obj->type != -1);
742  output->types.at(obj->type);
743  obj->metatype = tr.metaObject();
744 
745  if (tr.component)
746  obj->url = tr.component->url;
747  if (tr.type)
748  obj->typeName = tr.type->qmlTypeName();
749  obj->className = tr.className;
750 
751  // This object is a "Component" element
753  COMPILE_CHECK(buildComponent(obj, ctxt));
754  return true;
755  }
756 
757  // Object instantiations reset the binding context
758  BindingContext objCtxt(obj);
759 
760  // Create the synthesized meta object, ignoring aliases
764 
765  // Find the native type and check for the QDeclarativeParserStatus interface
767  Q_ASSERT(type);
768  obj->parserStatusCast = type->parserStatusCast();
769  if (obj->parserStatusCast != -1)
771 
772  // Check if this is a custom parser type. Custom parser types allow
773  // assignments to non-existent properties. These assignments are then
774  // compiled by the type.
775  bool isCustomParser = output->types.at(obj->type).type &&
776  output->types.at(obj->type).type->customParser() != 0;
778 
779  // Fetch the list of deferred properties
780  QStringList deferredList = deferredProperties(obj);
781 
782  // Must do id property first. This is to ensure that the id given to any
783  // id reference created matches the order in which the objects are
784  // instantiated
785  foreach(Property *prop, obj->properties) {
786  if (prop->name == "id") {
787  COMPILE_CHECK(buildProperty(prop, obj, objCtxt));
788  break;
789  }
790  }
791 
792  // Merge
793  Property *defaultProperty = 0;
794  Property *skipProperty = 0;
795  if (obj->defaultProperty) {
796  const QMetaObject *metaObject = obj->metaObject();
797  Q_ASSERT(metaObject);
799  if (p.name()) {
800  Property *explicitProperty = obj->getProperty(p.name(), false);
801  if (explicitProperty && !explicitProperty->value) {
802  skipProperty = explicitProperty;
803 
804  defaultProperty = new Property;
805  defaultProperty->parent = obj;
806  defaultProperty->isDefault = true;
807  defaultProperty->location = obj->defaultProperty->location;
808  defaultProperty->listValueRange = obj->defaultProperty->listValueRange;
809  defaultProperty->listCommaPositions = obj->defaultProperty->listCommaPositions;
810 
811  defaultProperty->values = obj->defaultProperty->values;
812  defaultProperty->values += explicitProperty->values;
813  foreach(QDeclarativeParser::Value *value, defaultProperty->values)
814  value->addref();
815  qSort(defaultProperty->values.begin(), defaultProperty->values.end(), ValuePtrLessThan);
816 
817  } else {
818  defaultProperty = obj->defaultProperty;
819  defaultProperty->addref();
820  }
821  } else {
822  defaultProperty = obj->defaultProperty;
823  defaultProperty->addref();
824  }
825  }
826 
827  QDeclarativeCustomParser *cp = 0;
828  if (isCustomParser)
829  cp = output->types.at(obj->type).type->customParser();
830 
831  // Build all explicit properties specified
832  foreach(Property *prop, obj->properties) {
833 
834  if (prop == skipProperty)
835  continue;
836  if (prop->name == "id")
837  continue;
838 
839  bool canDefer = false;
840  if (isCustomParser) {
841  if (doesPropertyExist(prop, obj) &&
843  !isAttachedPropertyName(prop->name))) {
844  int ids = compileState.ids.count();
845  COMPILE_CHECK(buildProperty(prop, obj, objCtxt));
846  canDefer = ids == compileState.ids.count();
847  } else {
849  }
850  } else {
851  if (isSignalPropertyName(prop->name)) {
852  COMPILE_CHECK(buildSignal(prop,obj,objCtxt));
853  } else {
854  int ids = compileState.ids.count();
855  COMPILE_CHECK(buildProperty(prop, obj, objCtxt));
856  canDefer = ids == compileState.ids.count();
857  }
858  }
859 
860  if (canDefer && !deferredList.isEmpty() &&
861  deferredList.contains(QString::fromUtf8(prop->name)))
862  prop->isDeferred = true;
863 
864  }
865 
866  // Build the default property
867  if (defaultProperty) {
868  Property *prop = defaultProperty;
869 
870  bool canDefer = false;
871  if (isCustomParser) {
872  if (doesPropertyExist(prop, obj)) {
873  int ids = compileState.ids.count();
874  COMPILE_CHECK(buildProperty(prop, obj, objCtxt));
875  canDefer = ids == compileState.ids.count();
876  } else {
878  }
879  } else {
880  int ids = compileState.ids.count();
881  COMPILE_CHECK(buildProperty(prop, obj, objCtxt));
882  canDefer = ids == compileState.ids.count();
883  }
884 
885  if (canDefer && !deferredList.isEmpty() &&
886  deferredList.contains(QString::fromUtf8(prop->name)))
887  prop->isDeferred = true;
888  }
889 
890  if (defaultProperty)
891  defaultProperty->release();
892 
893  // Compile custom parser parts
894  if (isCustomParser && !customProps.isEmpty()) {
895  cp->clearErrors();
896  cp->compiler = this;
897  cp->object = obj;
898  obj->custom = cp->compile(customProps);
899  cp->compiler = 0;
900  cp->object = 0;
901  foreach (QDeclarativeError err, cp->errors()) {
902  err.setUrl(output->url);
903  exceptions << err;
904  }
905  }
906 
907  return true;
908 }
909 
911 {
914  genComponent(obj);
915  return;
916  }
917 
918  // Create the object
919  if (obj->custom.isEmpty() && output->types.at(obj->type).type &&
920  !output->types.at(obj->type).type->isExtendedType() && obj != compileState.root) {
921 
924  create.line = obj->location.start.line;
925  create.createSimple.create = output->types.at(obj->type).type->createFunction();
926  create.createSimple.typeSize = output->types.at(obj->type).type->createSize();
927  create.createSimple.type = obj->type;
928  create.createSimple.column = obj->location.start.column;
929  output->bytecode << create;
930 
931  } else {
932 
935  create.line = obj->location.start.line;
936  create.create.column = obj->location.start.column;
937  create.create.data = -1;
938  if (!obj->custom.isEmpty())
939  create.create.data = output->indexForByteArray(obj->custom);
940  create.create.type = obj->type;
941  if (!output->types.at(create.create.type).type &&
942  !obj->bindingBitmask.isEmpty()) {
943  Q_ASSERT(obj->bindingBitmask.size() % 4 == 0);
944  create.create.bindingBits =
946  } else {
947  create.create.bindingBits = -1;
948  }
949  output->bytecode << create;
950 
951  }
952 
953  // Setup the synthesized meta object if necessary
954  if (!obj->metadata.isEmpty()) {
957  meta.line = 0;
961 
962  QDeclarativePropertyCache *propertyCache = obj->synthCache;
963  Q_ASSERT(propertyCache);
964  propertyCache->addref();
965 
966  // Add flag for alias properties
967  if (!obj->synthdata.isEmpty()) {
968  const QDeclarativeVMEMetaData *vmeMetaData =
969  reinterpret_cast<const QDeclarativeVMEMetaData *>(obj->synthdata.constData());
970  for (int ii = 0; ii < vmeMetaData->aliasCount; ++ii) {
971  int index = obj->metaObject()->propertyOffset() + vmeMetaData->propertyCount + ii;
972  propertyCache->property(index)->flags |= QDeclarativePropertyCache::Data::IsAlias;
973  }
974  }
975 
976  if (obj == unitRoot) {
977  propertyCache->addref();
978  output->rootPropertyCache = propertyCache;
979  }
980 
981  output->propertyCaches << propertyCache;
982  output->bytecode << meta;
983  } else if (obj == unitRoot) {
986  }
987 
988  // Set the object id
989  if (!obj->id.isEmpty()) {
992  id.line = 0;
993  id.setId.value = output->indexForString(obj->id);
994  id.setId.index = obj->idIndex;
995  output->bytecode << id;
996  }
997 
998  // Begin the class
999  if (tr.type && obj->parserStatusCast != -1) {
1002  begin.begin.castValue = obj->parserStatusCast;
1003  begin.line = obj->location.start.line;
1004  output->bytecode << begin;
1005  }
1006 
1007  genObjectBody(obj);
1008 }
1009 
1011 {
1012  typedef QPair<Property *, int> PropPair;
1013  foreach(const PropPair &prop, obj->scriptStringProperties) {
1016  ss.storeScriptString.propertyIndex = prop.first->index;
1017  ss.storeScriptString.value =
1018  output->indexForString(prop.first->values.at(0)->value.asScript());
1019  ss.storeScriptString.scope = prop.second;
1020  output->bytecode << ss;
1021  }
1022 
1023  bool seenDefer = false;
1024  foreach(Property *prop, obj->valueProperties) {
1025  if (prop->isDeferred) {
1026  seenDefer = true;
1027  continue;
1028  }
1029  if (!prop->isAlias)
1030  genValueProperty(prop, obj);
1031  }
1032  if (seenDefer) {
1035  defer.line = 0;
1036  defer.defer.deferCount = 0;
1037  int deferIdx = output->bytecode.count();
1038  output->bytecode << defer;
1039 
1042  init.init.bindingsSize = compileState.bindings.count(); // XXX - bigger than necessary
1043  init.init.parserStatusSize = compileState.parserStatusCount; // XXX - bigger than necessary
1044  init.init.contextCache = -1;
1045  init.init.compiledBinding = -1;
1046  output->bytecode << init;
1047 
1048  foreach(Property *prop, obj->valueProperties) {
1049  if (!prop->isDeferred)
1050  continue;
1051  genValueProperty(prop, obj);
1052  }
1053 
1054  output->bytecode[deferIdx].defer.deferCount =
1055  output->bytecode.count() - deferIdx - 1;
1056  }
1057 
1058  foreach(Property *prop, obj->signalProperties) {
1059 
1060  QDeclarativeParser::Value *v = prop->values.at(0);
1061 
1062  if (v->type == Value::SignalObject) {
1063 
1064  genObject(v->object);
1065 
1066  QDeclarativeInstruction assign;
1068  assign.line = v->location.start.line;
1069  assign.assignSignalObject.signal =
1070  output->indexForByteArray(prop->name);
1071  output->bytecode << assign;
1072 
1073  } else if (v->type == Value::SignalExpression) {
1074 
1076 
1079  store.line = v->location.start.line;
1080  store.storeSignal.signalIndex = prop->index;
1081  store.storeSignal.value =
1083  store.storeSignal.context = ctxt.stack;
1084  store.storeSignal.name = output->indexForByteArray(prop->name);
1085  output->bytecode << store;
1086 
1087  }
1088 
1089  }
1090 
1091  foreach(Property *prop, obj->attachedProperties) {
1094  fetch.line = prop->location.start.line;
1095  fetch.fetchAttached.id = prop->index;
1096  output->bytecode << fetch;
1097 
1098  genObjectBody(prop->value);
1099 
1102  pop.line = prop->location.start.line;
1103  output->bytecode << pop;
1104  }
1105 
1106  foreach(Property *prop, obj->groupedProperties) {
1109  fetch.fetch.property = prop->index;
1110  fetch.line = prop->location.start.line;
1111  output->bytecode << fetch;
1112 
1113  if (!prop->value->metadata.isEmpty()) {
1116  meta.line = 0;
1119  meta.storeMeta.propertyCache = -1;
1120  output->bytecode << meta;
1121  }
1122 
1123  genObjectBody(prop->value);
1124 
1127  pop.line = prop->location.start.line;
1128  output->bytecode << pop;
1129  }
1130 
1131  foreach(Property *prop, obj->valueTypeProperties) {
1132  if (!prop->isAlias)
1133  genValueTypeProperty(obj, prop);
1134  }
1135 
1136  foreach(Property *prop, obj->valueProperties) {
1137  if (prop->isDeferred)
1138  continue;
1139  if (prop->isAlias)
1140  genValueProperty(prop, obj);
1141  }
1142 
1143  foreach(Property *prop, obj->valueTypeProperties) {
1144  if (prop->isAlias)
1145  genValueTypeProperty(obj, prop);
1146  }
1147 }
1148 
1150 {
1153  fetch.fetchValue.property = prop->index;
1154  fetch.fetchValue.type = prop->type;
1155  fetch.fetchValue.bindingSkipList = 0;
1156  fetch.line = prop->location.start.line;
1157 
1158  if (obj->type == -1 || output->types.at(obj->type).component) {
1159  // We only have to do this if this is a composite type. If it is a builtin
1160  // type it can't possibly already have bindings that need to be cleared.
1161  foreach(Property *vprop, prop->value->valueProperties) {
1162  if (!vprop->values.isEmpty()) {
1163  Q_ASSERT(vprop->index >= 0 && vprop->index < 32);
1164  fetch.fetchValue.bindingSkipList |= (1 << vprop->index);
1165  }
1166  }
1167  }
1168 
1169  output->bytecode << fetch;
1170 
1171  foreach(Property *vprop, prop->value->valueProperties) {
1172  genPropertyAssignment(vprop, prop->value, prop);
1173  }
1174 
1177  pop.fetchValue.property = prop->index;
1178  pop.fetchValue.type = prop->type;
1179  pop.fetchValue.bindingSkipList = 0;
1180  pop.line = prop->location.start.line;
1181  output->bytecode << pop;
1182 }
1183 
1185 {
1186  QDeclarativeParser::Object *root = obj->defaultProperty->values.at(0)->object;
1187  Q_ASSERT(root);
1188 
1191  create.line = root->location.start.line;
1192  create.createComponent.column = root->location.start.column;
1193  create.createComponent.endLine = root->location.end.line;
1194  output->bytecode << create;
1195  int count = output->bytecode.count();
1196 
1197  ComponentCompileState oldCompileState = compileState;
1198  compileState = componentState(root);
1199 
1202  init.init.bindingsSize = compileState.bindings.count();
1206  init.init.compiledBinding = -1;
1207  else
1209  init.line = obj->location.start.line;
1210  output->bytecode << init;
1211 
1212  genObject(root);
1213 
1215  init.line = 0;
1217  output->bytecode << def;
1218 
1219  output->bytecode[count - 1].createComponent.count =
1220  output->bytecode.count() - count;
1221 
1222  compileState = oldCompileState;
1223 
1224  if (!obj->id.isEmpty()) {
1227  id.line = 0;
1228  id.setId.value = output->indexForString(obj->id);
1229  id.setId.index = obj->idIndex;
1230  output->bytecode << id;
1231  }
1232 
1233  if (obj == unitRoot) {
1234  output->rootPropertyCache = output->types[obj->type].createPropertyCache(engine);
1236  }
1237 }
1238 
1240  const BindingContext &ctxt)
1241 {
1242  // The special "Component" element can only have the id property and a
1243  // default property, that actually defines the component's tree
1244 
1245  // Find, check and set the "id" property (if any)
1246  Property *idProp = 0;
1247  if (obj->properties.count() > 1 ||
1248  (obj->properties.count() == 1 && obj->properties.begin().key() != "id"))
1249  COMPILE_EXCEPTION(*obj->properties.begin(), tr("Component elements may not contain properties other than id"));
1250 
1251  if (obj->properties.count())
1252  idProp = *obj->properties.begin();
1253 
1254  if (idProp) {
1255  if (idProp->value || idProp->values.count() > 1 || idProp->values.at(0)->object)
1256  COMPILE_EXCEPTION(idProp, tr("Invalid component id specification"));
1257  COMPILE_CHECK(checkValidId(idProp->values.first(), idProp->values.first()->primitive()))
1258 
1259  QString idVal = idProp->values.first()->primitive();
1260 
1261  if (compileState.ids.contains(idVal))
1262  COMPILE_EXCEPTION(idProp, tr("id is not unique"));
1263 
1264  obj->id = idVal;
1265  addId(idVal, obj);
1266  }
1267 
1268  // Check the Component tree is well formed
1269  if (obj->defaultProperty &&
1270  (obj->defaultProperty->value || obj->defaultProperty->values.count() > 1 ||
1271  (obj->defaultProperty->values.count() == 1 && !obj->defaultProperty->values.first()->object)))
1272  COMPILE_EXCEPTION(obj, tr("Invalid component body specification"));
1273 
1274  if (!obj->dynamicProperties.isEmpty())
1275  COMPILE_EXCEPTION(obj, tr("Component objects cannot declare new properties."));
1276  if (!obj->dynamicSignals.isEmpty())
1277  COMPILE_EXCEPTION(obj, tr("Component objects cannot declare new signals."));
1278  if (!obj->dynamicSlots.isEmpty())
1279  COMPILE_EXCEPTION(obj, tr("Component objects cannot declare new functions."));
1280 
1281  QDeclarativeParser::Object *root = 0;
1282  if (obj->defaultProperty && obj->defaultProperty->values.count())
1283  root = obj->defaultProperty->values.first()->object;
1284 
1285  if (!root)
1286  COMPILE_EXCEPTION(obj, tr("Cannot create empty component specification"));
1287 
1288  // Build the component tree
1290 
1291  return true;
1292 }
1293 
1295  const BindingContext &ctxt)
1296 {
1297  ComponentCompileState oldComponentCompileState = compileState;
1298  ComponentStat oldComponentStat = componentStat;
1299 
1301  compileState.root = obj;
1302 
1305 
1306  if (obj)
1307  COMPILE_CHECK(buildObject(obj, ctxt));
1308 
1310 
1311  compileState = oldComponentCompileState;
1312  componentStat = oldComponentStat;
1313 
1314  return true;
1315 }
1316 
1317 
1318 // Build a sub-object. A sub-object is one that was not created directly by
1319 // QML - such as a grouped property object, or an attached object. Sub-object's
1320 // can't have an id, involve a custom parser, have attached properties etc.
1322 {
1323  Q_ASSERT(obj->metatype);
1324  Q_ASSERT(!obj->defaultProperty);
1325  Q_ASSERT(ctxt.isSubContext()); // sub-objects must always be in a binding
1326  // sub-context
1327 
1328  foreach(Property *prop, obj->properties) {
1329  if (isSignalPropertyName(prop->name)) {
1330  COMPILE_CHECK(buildSignal(prop, obj, ctxt));
1331  } else {
1332  COMPILE_CHECK(buildProperty(prop, obj, ctxt));
1333  }
1334  }
1335 
1336  return true;
1337 }
1338 
1340 {
1341  QDeclarativeType *t = QDeclarativeMetaType::qmlType("QtQuick/Component",1,0);
1342  for (int ii = output->types.count() - 1; ii >= 0; --ii) {
1343  if (output->types.at(ii).type == t)
1344  return ii;
1345  }
1347  ref.className = "Component";
1348  ref.type = t;
1349  output->types << ref;
1350  return output->types.count() - 1;
1351 }
1352 
1354  const BindingContext &ctxt)
1355 {
1356  Q_ASSERT(obj->metaObject());
1357 
1358  QByteArray name = prop->name;
1359  Q_ASSERT(name.startsWith("on"));
1360  name = name.mid(2);
1361  if(name[0] >= 'A' && name[0] <= 'Z')
1362  name[0] = name[0] - 'A' + 'a';
1363 
1364  bool notInRevision = false;
1365  int sigIdx = indexOfSignal(obj, name, &notInRevision);
1366 
1367  if (sigIdx == -1) {
1368 
1369  if (notInRevision && -1 == indexOfProperty(obj, prop->name, 0)) {
1370  Q_ASSERT(obj->type != -1);
1372  const QDeclarativeTypeData::TypeReference &type = resolvedTypes.at(obj->type);
1373  if (type.type) {
1374  COMPILE_EXCEPTION(prop, tr("\"%1.%2\" is not available in %3 %4.%5.").arg(QString::fromUtf8(obj->className)).arg(QString::fromUtf8(prop->name)).arg(QString::fromUtf8(type.type->module())).arg(type.majorVersion).arg(type.minorVersion));
1375  } else {
1376  COMPILE_EXCEPTION(prop, tr("\"%1.%2\" is not available due to component versioning.").arg(QString::fromUtf8(obj->className)).arg(QString::fromUtf8(prop->name)));
1377  }
1378  }
1379 
1380  // If the "on<Signal>" name doesn't resolve into a signal, try it as a
1381  // property.
1382  COMPILE_CHECK(buildProperty(prop, obj, ctxt));
1383 
1384  } else {
1385 
1386  if (prop->value || prop->values.count() != 1)
1387  COMPILE_EXCEPTION(prop, tr("Incorrectly specified signal assignment"));
1388 
1389  prop->index = sigIdx;
1390  obj->addSignalProperty(prop);
1391 
1392  if (prop->values.at(0)->object) {
1393  COMPILE_CHECK(buildObject(prop->values.at(0)->object, ctxt));
1394  prop->values.at(0)->type = Value::SignalObject;
1395  } else {
1396  prop->values.at(0)->type = Value::SignalExpression;
1397 
1398  if (!prop->values.at(0)->value.isScript())
1399  COMPILE_EXCEPTION(prop, tr("Cannot assign a value to a signal (expecting a script to be run)"));
1400 
1401  QString script = prop->values.at(0)->value.asScript().trimmed();
1402  if (script.isEmpty())
1403  COMPILE_EXCEPTION(prop, tr("Empty signal assignment"));
1404 
1405  compileState.signalExpressions.insert(prop->values.at(0), ctxt);
1406  }
1407  }
1408 
1409  return true;
1410 }
1411 
1412 
1418 {
1419  if(isAttachedPropertyName(prop->name) || prop->name == "id")
1420  return true;
1421 
1422  const QMetaObject *mo = obj->metaObject();
1423  if (mo) {
1424  if (prop->isDefault) {
1426  return p.name() != 0;
1427  } else {
1428  int idx = indexOfProperty(obj, prop->name);
1429  return idx != -1 && mo->property(idx).isScriptable();
1430  }
1431  }
1432 
1433  return false;
1434 }
1435 
1438  const BindingContext &ctxt)
1439 {
1440  if (prop->isEmpty())
1441  COMPILE_EXCEPTION(prop, tr("Empty property assignment"));
1442 
1443  const QMetaObject *metaObject = obj->metaObject();
1444  Q_ASSERT(metaObject);
1445 
1446  if (isAttachedPropertyName(prop->name)) {
1447  // Setup attached property data
1448 
1449  if (ctxt.isSubContext()) {
1450  // Attached properties cannot be used on sub-objects. Sub-objects
1451  // always exist in a binding sub-context, which is what we test
1452  // for here.
1453  COMPILE_EXCEPTION(prop, tr("Attached properties cannot be used here"));
1454  }
1455 
1456  QDeclarativeType *type = 0;
1457  QDeclarativeImportedNamespace *typeNamespace = 0;
1458  unit->imports().resolveType(prop->name, &type, 0, 0, 0, &typeNamespace);
1459 
1460  if (typeNamespace) {
1461  // ### We might need to indicate that this property is a namespace
1462  // for the DOM API
1463  COMPILE_CHECK(buildPropertyInNamespace(typeNamespace, prop, obj,
1464  ctxt));
1465  return true;
1466  } else if (!type || !type->attachedPropertiesType()) {
1467  COMPILE_EXCEPTION(prop, tr("Non-existent attached object"));
1468  }
1469 
1470  if (!prop->value)
1471  COMPILE_EXCEPTION(prop, tr("Invalid attached object assignment"));
1472 
1474  prop->index = type->attachedPropertiesId();
1475  prop->value->metatype = type->attachedPropertiesType();
1476  } else {
1477  // Setup regular property data
1478  QMetaProperty p;
1479 
1480  if (prop->isDefault) {
1481  p = QDeclarativeMetaType::defaultProperty(metaObject);
1482 
1483  if (p.name()) {
1484  prop->index = p.propertyIndex();
1485  prop->name = p.name();
1486  }
1487 
1488  } else {
1489  bool notInRevision = false;
1490  prop->index = indexOfProperty(obj, prop->name, &notInRevision);
1491  if (prop->index == -1 && notInRevision) {
1493  const QDeclarativeTypeData::TypeReference &type = resolvedTypes.at(obj->type);
1494  if (type.type) {
1495  COMPILE_EXCEPTION(prop, tr("\"%1.%2\" is not available in %3 %4.%5.").arg(QString::fromUtf8(obj->className)).arg(QString::fromUtf8(prop->name)).arg(QString::fromUtf8(type.type->module())).arg(type.majorVersion).arg(type.minorVersion));
1496  } else {
1497  COMPILE_EXCEPTION(prop, tr("\"%1.%2\" is not available due to component versioning.").arg(QString::fromUtf8(obj->className)).arg(QString::fromUtf8(prop->name)));
1498  }
1499  }
1500 
1501  if (prop->index != -1) {
1502  p = metaObject->property(prop->index);
1503  Q_ASSERT(p.name());
1504 
1505  if (!p.isScriptable()) {
1506  prop->index = -1;
1507  p = QMetaProperty();
1508  }
1509  }
1510  }
1511 
1512  // We can't error here as the "id" property does not require a
1513  // successful index resolution
1514  if (p.name())
1515  prop->type = p.userType();
1516 
1517  // Check if this is an alias
1518  if (prop->index != -1 &&
1519  prop->parent &&
1520  prop->parent->type != -1 &&
1521  output->types.at(prop->parent->type).component) {
1522 
1523  QDeclarativePropertyCache *cache = output->types.at(prop->parent->type).component->rootPropertyCache;
1524  if (cache && cache->property(prop->index) &&
1526  prop->isAlias = true;
1527  }
1528 
1529  if (prop->index != -1 && !prop->values.isEmpty())
1530  prop->parent->setBindingBit(prop->index);
1531  }
1532 
1533  if (!prop->isDefault && prop->name == "id" && !ctxt.isSubContext()) {
1534 
1535  // The magic "id" behavior doesn't apply when "id" is resolved as a
1536  // default property or to sub-objects (which are always in binding
1537  // sub-contexts)
1538  COMPILE_CHECK(buildIdProperty(prop, obj));
1539  if (prop->type == QVariant::String &&
1540  prop->values.at(0)->value.isString())
1541  COMPILE_CHECK(buildPropertyAssignment(prop, obj, ctxt));
1542 
1543  } else if (isAttachedPropertyName(prop->name)) {
1544 
1545  COMPILE_CHECK(buildAttachedProperty(prop, obj, ctxt));
1546 
1547  } else if (prop->index == -1) {
1548 
1549  if (prop->isDefault) {
1550  COMPILE_EXCEPTION(prop->values.first(), tr("Cannot assign to non-existent default property"));
1551  } else {
1552  COMPILE_EXCEPTION(prop, tr("Cannot assign to non-existent property \"%1\"").arg(QString::fromUtf8(prop->name)));
1553  }
1554 
1555  } else if (prop->value) {
1556 
1557  COMPILE_CHECK(buildGroupedProperty(prop, obj, ctxt));
1558 
1559  } else if (enginePrivate->isList(prop->type)) {
1560 
1561  COMPILE_CHECK(buildListProperty(prop, obj, ctxt));
1562 
1563  } else if (prop->type == qMetaTypeId<QDeclarativeScriptString>()) {
1564 
1565  COMPILE_CHECK(buildScriptStringProperty(prop, obj, ctxt));
1566 
1567  } else {
1568 
1569  COMPILE_CHECK(buildPropertyAssignment(prop, obj, ctxt));
1570 
1571  }
1572 
1573  return true;
1574 }
1575 
1579  const BindingContext &ctxt)
1580 {
1581  if (!nsProp->value)
1582  COMPILE_EXCEPTION(nsProp, tr("Invalid use of namespace"));
1583 
1584  foreach (Property *prop, nsProp->value->properties) {
1585 
1586  if (!isAttachedPropertyName(prop->name))
1587  COMPILE_EXCEPTION(prop, tr("Not an attached property name"));
1588 
1589  // Setup attached property data
1590 
1591  QDeclarativeType *type = 0;
1592  unit->imports().resolveType(ns, prop->name, &type, 0, 0, 0);
1593 
1594  if (!type || !type->attachedPropertiesType())
1595  COMPILE_EXCEPTION(prop, tr("Non-existent attached object"));
1596 
1597  if (!prop->value)
1598  COMPILE_EXCEPTION(prop, tr("Invalid attached object assignment"));
1599 
1601  prop->index = type->index();
1602  prop->value->metatype = type->attachedPropertiesType();
1603 
1604  COMPILE_CHECK(buildAttachedProperty(prop, obj, ctxt));
1605  }
1606 
1607  return true;
1608 }
1609 
1612 {
1613  if (enginePrivate->isList(prop->type)) {
1614  genListProperty(prop, obj);
1615  } else {
1616  genPropertyAssignment(prop, obj);
1617  }
1618 }
1619 
1622 {
1623  int listType = enginePrivate->listType(prop->type);
1624 
1627  fetch.line = prop->location.start.line;
1628  fetch.fetchQmlList.property = prop->index;
1629  bool listTypeIsInterface = QDeclarativeMetaType::isInterface(listType);
1630  fetch.fetchQmlList.type = listType;
1631  output->bytecode << fetch;
1632 
1633  for (int ii = 0; ii < prop->values.count(); ++ii) {
1634  QDeclarativeParser::Value *v = prop->values.at(ii);
1635 
1636  if (v->type == Value::CreatedObject) {
1637 
1638  genObject(v->object);
1639  if (listTypeIsInterface) {
1640  QDeclarativeInstruction assign;
1642  assign.line = prop->location.start.line;
1643  output->bytecode << assign;
1644  } else {
1647  store.line = prop->location.start.line;
1648  output->bytecode << store;
1649  }
1650 
1651  } else if (v->type == Value::PropertyBinding) {
1652 
1653  genBindingAssignment(v, prop, obj);
1654 
1655  }
1656 
1657  }
1658 
1661  pop.line = prop->location.start.line;
1662  output->bytecode << pop;
1663 }
1664 
1667  QDeclarativeParser::Property *valueTypeProperty)
1668 {
1669  for (int ii = 0; ii < prop->values.count(); ++ii) {
1670  QDeclarativeParser::Value *v = prop->values.at(ii);
1671 
1672  Q_ASSERT(v->type == Value::CreatedObject ||
1673  v->type == Value::PropertyBinding ||
1674  v->type == Value::Literal);
1675 
1676  if (v->type == Value::CreatedObject) {
1677 
1678  genObject(v->object);
1679 
1681 
1684  store.line = v->object->location.start.line;
1685  store.storeObject.propertyIndex = prop->index;
1686  output->bytecode << store;
1687 
1688  } else if (prop->type == -1) {
1689 
1692  store.line = v->object->location.start.line;
1693  store.storeObject.propertyIndex = prop->index;
1694  output->bytecode << store;
1695 
1696  } else {
1697 
1700  store.line = v->object->location.start.line;
1701  store.storeObject.propertyIndex = prop->index;
1702  output->bytecode << store;
1703 
1704  }
1705  } else if (v->type == Value::PropertyBinding) {
1706 
1707  genBindingAssignment(v, prop, obj, valueTypeProperty);
1708 
1709  } else if (v->type == Value::Literal) {
1710 
1711  QMetaProperty mp = obj->metaObject()->property(prop->index);
1712  genLiteralAssignment(mp, v);
1713 
1714  }
1715 
1716  }
1717 
1718  for (int ii = 0; ii < prop->onValues.count(); ++ii) {
1719 
1720  QDeclarativeParser::Value *v = prop->onValues.at(ii);
1721 
1722  Q_ASSERT(v->type == Value::ValueSource ||
1723  v->type == Value::ValueInterceptor);
1724 
1725  if (v->type == Value::ValueSource) {
1726  genObject(v->object);
1727 
1730  store.line = v->object->location.start.line;
1731  if (valueTypeProperty) {
1732  store.assignValueSource.property = genValueTypeData(prop, valueTypeProperty);
1733  store.assignValueSource.owner = 1;
1734  } else {
1736  store.assignValueSource.owner = 0;
1737  }
1738  QDeclarativeType *valueType = toQmlType(v->object);
1740  output->bytecode << store;
1741 
1742  } else if (v->type == Value::ValueInterceptor) {
1743  genObject(v->object);
1744 
1747  store.line = v->object->location.start.line;
1748  if (valueTypeProperty) {
1749  store.assignValueInterceptor.property = genValueTypeData(prop, valueTypeProperty);
1750  store.assignValueInterceptor.owner = 1;
1751  } else {
1753  store.assignValueInterceptor.owner = 0;
1754  }
1755  QDeclarativeType *valueType = toQmlType(v->object);
1757  output->bytecode << store;
1758  }
1759 
1760  }
1761 }
1762 
1765 {
1766  if (prop->value ||
1767  prop->values.count() > 1 ||
1768  prop->values.at(0)->object)
1769  COMPILE_EXCEPTION(prop, tr("Invalid use of id property"));
1770 
1771  QDeclarativeParser::Value *idValue = prop->values.at(0);
1772  QString val = idValue->primitive();
1773 
1774  COMPILE_CHECK(checkValidId(idValue, val));
1775 
1776  if (compileState.ids.contains(val))
1777  COMPILE_EXCEPTION(prop, tr("id is not unique"));
1778 
1779  prop->values.at(0)->type = Value::Id;
1780 
1781  obj->id = val;
1782  addId(val, obj);
1783 
1784  return true;
1785 }
1786 
1788 {
1790  Q_ASSERT(obj->id == id);
1791  obj->idIndex = compileState.ids.count();
1792  compileState.ids.insert(id, obj);
1793  compileState.idIndexes.insert(obj->idIndex, obj);
1794 }
1795 
1797 {
1798  Q_ASSERT(ref.value && !compileState.bindings.contains(ref.value));
1799  compileState.bindings.insert(ref.value, ref);
1800 }
1801 
1803 {
1806 
1809 }
1810 
1813 {
1814  Q_ASSERT(savedCompileStates.contains(obj));
1815  return savedCompileStates.value(obj);
1816 }
1817 
1818 // Build attached property object. In this example,
1819 // Text {
1820 // GridView.row: 10
1821 // }
1822 // GridView is an attached property object.
1825  const BindingContext &ctxt)
1826 {
1827  Q_ASSERT(prop->value);
1828  Q_ASSERT(prop->index != -1); // This is set in buildProperty()
1829 
1830  obj->addAttachedProperty(prop);
1831 
1832  COMPILE_CHECK(buildSubObject(prop->value, ctxt.incr()));
1833 
1834  return true;
1835 }
1836 
1837 
1838 // Build "grouped" properties. In this example:
1839 // Text {
1840 // font.pointSize: 12
1841 // font.family: "Helvetica"
1842 // }
1843 // font is a nested property. pointSize and family are not.
1846  const BindingContext &ctxt)
1847 {
1848  Q_ASSERT(prop->type != 0);
1849  Q_ASSERT(prop->index != -1);
1850 
1852  if (prop->type >= 0 /* QVariant == -1 */ && enginePrivate->valueTypes[prop->type]) {
1853 
1854  if (prop->values.count()) {
1855  if (prop->values.at(0)->location < prop->value->location) {
1856  COMPILE_EXCEPTION(prop->value, tr( "Property has already been assigned a value"));
1857  } else {
1858  COMPILE_EXCEPTION(prop->values.at(0), tr( "Property has already been assigned a value"));
1859  }
1860  }
1861 
1862  if (!obj->metaObject()->property(prop->index).isWritable()) {
1863  COMPILE_EXCEPTION(prop, tr( "Invalid property assignment: \"%1\" is a read-only property").arg(QString::fromUtf8(prop->name)));
1864  }
1865 
1866 
1867  if (prop->isAlias) {
1868  foreach (Property *vtProp, prop->value->properties)
1869  vtProp->isAlias = true;
1870  }
1871 
1873  prop->value, obj, ctxt.incr()));
1874  obj->addValueTypeProperty(prop);
1875  } else {
1876  COMPILE_EXCEPTION(prop, tr("Invalid grouped property access"));
1877  }
1878 
1879  } else {
1880  // Load the nested property's meta type
1882  if (!prop->value->metatype)
1883  COMPILE_EXCEPTION(prop, tr("Invalid grouped property access"));
1884 
1885  if (prop->values.count())
1886  COMPILE_EXCEPTION(prop->values.at(0), tr( "Cannot assign a value directly to a grouped property"));
1887 
1888  obj->addGroupedProperty(prop);
1889 
1890  COMPILE_CHECK(buildSubObject(prop->value, ctxt.incr()));
1891  }
1892 
1893  return true;
1894 }
1895 
1898  QDeclarativeParser::Object *baseObj,
1899  const BindingContext &ctxt)
1900 {
1901  if (obj->defaultProperty)
1902  COMPILE_EXCEPTION(obj, tr("Invalid property use"));
1903  obj->metatype = type->metaObject();
1904 
1905  foreach (Property *prop, obj->properties) {
1906  int idx = type->metaObject()->indexOfProperty(prop->name.constData());
1907  if (idx == -1)
1908  COMPILE_EXCEPTION(prop, tr("Cannot assign to non-existent property \"%1\"").arg(QString::fromUtf8(prop->name)));
1909  QMetaProperty p = type->metaObject()->property(idx);
1910  if (!p.isScriptable())
1911  COMPILE_EXCEPTION(prop, tr("Cannot assign to non-existent property \"%1\"").arg(QString::fromUtf8(prop->name)));
1912  prop->index = idx;
1913  prop->type = p.userType();
1914  prop->isValueTypeSubProperty = true;
1915 
1916  if (prop->value)
1917  COMPILE_EXCEPTION(prop, tr("Property assignment expected"));
1918 
1919  if (prop->values.count() > 1) {
1920  COMPILE_EXCEPTION(prop, tr("Single property assignment expected"));
1921  } else if (prop->values.count()) {
1922  QDeclarativeParser::Value *value = prop->values.at(0);
1923 
1924  if (value->object) {
1925  COMPILE_EXCEPTION(prop, tr("Unexpected object assignment"));
1926  } else if (value->value.isScript()) {
1927  // ### Check for writability
1928 
1929  //optimization for <Type>.<EnumValue> enum assignments
1930  bool isEnumAssignment = false;
1931  COMPILE_CHECK(testQualifiedEnumAssignment(p, obj, value, &isEnumAssignment));
1932  if (isEnumAssignment) {
1933  value->type = Value::Literal;
1934  } else {
1935  BindingReference reference;
1936  reference.expression = value->value;
1937  reference.property = prop;
1938  reference.value = value;
1939  reference.bindingContext = ctxt;
1940  reference.bindingContext.owner++;
1941  addBindingReference(reference);
1942  value->type = Value::PropertyBinding;
1943  }
1944  } else {
1946  value->type = Value::Literal;
1947  }
1948  }
1949 
1950  for (int ii = 0; ii < prop->onValues.count(); ++ii) {
1951  QDeclarativeParser::Value *v = prop->onValues.at(ii);
1952  Q_ASSERT(v->object);
1953 
1954  COMPILE_CHECK(buildPropertyOnAssignment(prop, obj, baseObj, v, ctxt));
1955  }
1956 
1957  obj->addValueProperty(prop);
1958  }
1959 
1960  return true;
1961 }
1962 
1963 // Build assignments to QML lists. QML lists are properties of type
1964 // QDeclarativeListProperty<T>. List properties can accept a list of
1965 // objects, or a single binding.
1968  const BindingContext &ctxt)
1969 {
1970  Q_ASSERT(enginePrivate->isList(prop->type));
1971 
1972  int t = prop->type;
1973 
1974  obj->addValueProperty(prop);
1975 
1976  int listType = enginePrivate->listType(t);
1977  bool listTypeIsInterface = QDeclarativeMetaType::isInterface(listType);
1978 
1979  bool assignedBinding = false;
1980  for (int ii = 0; ii < prop->values.count(); ++ii) {
1981  QDeclarativeParser::Value *v = prop->values.at(ii);
1982  if (v->object) {
1983  v->type = Value::CreatedObject;
1984  COMPILE_CHECK(buildObject(v->object, ctxt));
1985 
1986  // We check object coercian here. We check interface assignment
1987  // at runtime.
1988  if (!listTypeIsInterface) {
1989  if (!canCoerce(listType, v->object)) {
1990  COMPILE_EXCEPTION(v, tr("Cannot assign object to list"));
1991  }
1992  }
1993 
1994  } else if (v->value.isScript()) {
1995  if (assignedBinding)
1996  COMPILE_EXCEPTION(v, tr("Can only assign one binding to lists"));
1997 
1998  assignedBinding = true;
1999  COMPILE_CHECK(buildBinding(v, prop, ctxt));
2000  v->type = Value::PropertyBinding;
2001  } else {
2002  COMPILE_EXCEPTION(v, tr("Cannot assign primitives to lists"));
2003  }
2004  }
2005 
2006  return true;
2007 }
2008 
2009 // Compiles an assignment to a QDeclarativeScriptString property
2012  const BindingContext &ctxt)
2013 {
2014  if (prop->values.count() > 1)
2015  COMPILE_EXCEPTION(prop->values.at(1), tr( "Cannot assign multiple values to a script property"));
2016 
2017  if (prop->values.at(0)->object)
2018  COMPILE_EXCEPTION(prop->values.at(0), tr( "Invalid property assignment: script expected"));
2019 
2020  obj->addScriptStringProperty(prop, ctxt.stack);
2021 
2022  return true;
2023 }
2024 
2025 // Compile regular property assignments of the form "property: <value>"
2028  const BindingContext &ctxt)
2029 {
2030  obj->addValueProperty(prop);
2031 
2032  if (prop->values.count() > 1)
2033  COMPILE_EXCEPTION(prop->values.at(0), tr( "Cannot assign multiple values to a singular property") );
2034 
2035  for (int ii = 0; ii < prop->values.count(); ++ii) {
2036  QDeclarativeParser::Value *v = prop->values.at(ii);
2037  if (v->object) {
2038 
2039  COMPILE_CHECK(buildPropertyObjectAssignment(prop, obj, v, ctxt));
2040 
2041  } else {
2042 
2043  COMPILE_CHECK(buildPropertyLiteralAssignment(prop, obj, v, ctxt));
2044 
2045  }
2046  }
2047 
2048  for (int ii = 0; ii < prop->onValues.count(); ++ii) {
2049  QDeclarativeParser::Value *v = prop->onValues.at(ii);
2050 
2051  Q_ASSERT(v->object);
2052  COMPILE_CHECK(buildPropertyOnAssignment(prop, obj, obj, v, ctxt));
2053  }
2054 
2055  return true;
2056 }
2057 
2058 // Compile assigning a single object instance to a regular property
2062  const BindingContext &ctxt)
2063 {
2064  Q_ASSERT(prop->index != -1);
2065  Q_ASSERT(v->object->type != -1);
2066 
2067  if (!obj->metaObject()->property(prop->index).isWritable())
2068  COMPILE_EXCEPTION(v, tr("Invalid property assignment: \"%1\" is a read-only property").arg(QString::fromUtf8(prop->name)));
2069 
2071 
2072  // Assigning an object to an interface ptr property
2073  COMPILE_CHECK(buildObject(v->object, ctxt));
2074 
2075  v->type = Value::CreatedObject;
2076 
2077  } else if (prop->type == -1) {
2078 
2079  // Assigning an object to a QVariant
2080  COMPILE_CHECK(buildObject(v->object, ctxt));
2081 
2082  v->type = Value::CreatedObject;
2083  } else {
2084  // Normally buildObject() will set this up, but we need the static
2085  // meta object earlier to test for assignability. It doesn't matter
2086  // that there may still be outstanding synthesized meta object changes
2087  // on this type, as they are not relevant for assignability testing
2088  v->object->metatype = output->types.at(v->object->type).metaObject();
2089  Q_ASSERT(v->object->metaObject());
2090 
2091  // We want to raw metaObject here as the raw metaobject is the
2092  // actual property type before we applied any extensions that might
2093  // effect the properties on the type, but don't effect assignability
2094  const QMetaObject *propertyMetaObject = enginePrivate->rawMetaObjectForType(prop->type);
2095 
2096  // Will be true if the assgned type inherits propertyMetaObject
2097  bool isAssignable = false;
2098  // Determine isAssignable value
2099  if (propertyMetaObject) {
2100  const QMetaObject *c = v->object->metatype;
2101  while(c) {
2102  isAssignable |= (QDeclarativePropertyPrivate::equal(c, propertyMetaObject));
2103  c = c->superClass();
2104  }
2105  }
2106 
2107  if (isAssignable) {
2108  // Simple assignment
2109  COMPILE_CHECK(buildObject(v->object, ctxt));
2110 
2111  v->type = Value::CreatedObject;
2112  } else if (propertyMetaObject == &QDeclarativeComponent::staticMetaObject) {
2113  // Automatic "Component" insertion
2116  component->type = componentTypeRef();
2117  component->typeName = "Qt/Component";
2119  component->location = root->location;
2121  componentValue->object = root;
2122  component->getDefaultProperty()->addValue(componentValue);
2123  v->object = component;
2124  COMPILE_CHECK(buildPropertyObjectAssignment(prop, obj, v, ctxt));
2125  } else {
2126  COMPILE_EXCEPTION(v->object, tr("Cannot assign object to property"));
2127  }
2128  }
2129 
2130  return true;
2131 }
2132 
2133 // Compile assigning a single object instance to a regular property using the "on" syntax.
2134 //
2135 // For example:
2136 // Item {
2137 // NumberAnimation on x { }
2138 // }
2141  QDeclarativeParser::Object *baseObj,
2143  const BindingContext &ctxt)
2144 {
2145  Q_ASSERT(prop->index != -1);
2146  Q_ASSERT(v->object->type != -1);
2147 
2148  if (!obj->metaObject()->property(prop->index).isWritable())
2149  COMPILE_EXCEPTION(v, tr("Invalid property assignment: \"%1\" is a read-only property").arg(QString::fromUtf8(prop->name)));
2150 
2151 
2152  // Normally buildObject() will set this up, but we need the static
2153  // meta object earlier to test for assignability. It doesn't matter
2154  // that there may still be outstanding synthesized meta object changes
2155  // on this type, as they are not relevant for assignability testing
2156  v->object->metatype = output->types.at(v->object->type).metaObject();
2157  Q_ASSERT(v->object->metaObject());
2158 
2159  // Will be true if the assigned type inherits QDeclarativePropertyValueSource
2160  bool isPropertyValue = false;
2161  // Will be true if the assigned type inherits QDeclarativePropertyValueInterceptor
2162  bool isPropertyInterceptor = false;
2163  if (QDeclarativeType *valueType = toQmlType(v->object)) {
2164  isPropertyValue = valueType->propertyValueSourceCast() != -1;
2165  isPropertyInterceptor = valueType->propertyValueInterceptorCast() != -1;
2166  }
2167 
2168  if (isPropertyValue || isPropertyInterceptor) {
2169  // Assign as a property value source
2170  COMPILE_CHECK(buildObject(v->object, ctxt));
2171 
2172  if (isPropertyInterceptor && prop->parent->synthdata.isEmpty())
2173  buildDynamicMeta(baseObj, ForceCreation);
2174  v->type = isPropertyValue ? Value::ValueSource : Value::ValueInterceptor;
2175  } else {
2176  COMPILE_EXCEPTION(v, tr("\"%1\" cannot operate on \"%2\"").arg(QString::fromUtf8(v->object->typeName)).arg(QString::fromUtf8(prop->name.constData())));
2177  }
2178 
2179  return true;
2180 }
2181 
2182 // Compile assigning a literal or binding to a regular property
2186  const BindingContext &ctxt)
2187 {
2188  Q_ASSERT(prop->index != -1);
2189 
2190  if (v->value.isScript()) {
2191 
2192  //optimization for <Type>.<EnumValue> enum assignments
2193  bool isEnumAssignment = false;
2194  COMPILE_CHECK(testQualifiedEnumAssignment(obj->metaObject()->property(prop->index), obj, v, &isEnumAssignment));
2195  if (isEnumAssignment) {
2196  v->type = Value::Literal;
2197  return true;
2198  }
2199 
2200  COMPILE_CHECK(buildBinding(v, prop, ctxt));
2201 
2202  v->type = Value::PropertyBinding;
2203 
2204  } else {
2205 
2207 
2208  v->type = Value::Literal;
2209  }
2210 
2211  return true;
2212 }
2213 
2215 {
2216  static const QMetaObject *get()
2217  { return &static_cast<StaticQtMetaObject*> (0)->staticQtMetaObject; }
2218 };
2219 
2223  bool *isAssignment)
2224 {
2225  *isAssignment = false;
2226  if (!prop.isEnumType())
2227  return true;
2228 
2229  if (!prop.isWritable())
2230  COMPILE_EXCEPTION(v, tr("Invalid property assignment: \"%1\" is a read-only property").arg(QString::fromUtf8(prop.name())));
2231 
2232  QString string = v->value.asString();
2233  if (!string.at(0).isUpper())
2234  return true;
2235 
2236  QStringList parts = string.split(QLatin1Char('.'));
2237  if (parts.count() != 2)
2238  return true;
2239 
2240  QString typeName = parts.at(0);
2241  QDeclarativeType *type = 0;
2242  unit->imports().resolveType(typeName.toUtf8(), &type, 0, 0, 0, 0);
2243 
2244  //handle enums on value types (where obj->typeName is empty)
2245  QByteArray objTypeName = obj->typeName;
2246  if (objTypeName.isEmpty()) {
2247  QDeclarativeType *objType = toQmlType(obj);
2248  if (objType)
2249  objTypeName = objType->qmlTypeName();
2250  }
2251 
2252  if (!type && typeName != QLatin1String("Qt"))
2253  return true;
2254 
2255  QString enumValue = parts.at(1);
2256  int value = -1;
2257 
2258  if (type && objTypeName == type->qmlTypeName()) {
2259  if (prop.isFlagType()) {
2260  value = prop.enumerator().keysToValue(enumValue.toUtf8().constData());
2261  } else {
2262  value = prop.enumerator().keyToValue(enumValue.toUtf8().constData());
2263  }
2264  } else {
2265  QByteArray enumName = enumValue.toUtf8();
2266  //Special case for Qt object
2267  const QMetaObject *metaObject = type ? type->metaObject() : StaticQtMetaObject::get();
2268  for (int ii = metaObject->enumeratorCount() - 1; value == -1 && ii >= 0; --ii) {
2269  QMetaEnum e = metaObject->enumerator(ii);
2270  value = e.keyToValue(enumName.constData());
2271  }
2272  }
2273  if (value == -1)
2274  return true;
2275 
2276  v->type = Value::Literal;
2277  v->value = QDeclarativeParser::Variant((double)value);
2278  *isAssignment = true;
2279 
2280  return true;
2281 }
2282 
2283 // Similar logic to above, but not knowing target property.
2285 {
2286  int dot = script.indexOf('.');
2287  if (dot > 0) {
2288  QDeclarativeType *type = 0;
2289  unit->imports().resolveType(script.left(dot), &type, 0, 0, 0, 0);
2290  if (!type)
2291  return -1;
2292  const QMetaObject *mo = type->metaObject();
2293  const char *key = script.constData() + dot+1;
2294  int i = mo->enumeratorCount();
2295  while (i--) {
2296  int v = mo->enumerator(i).keyToValue(key);
2297  if (v >= 0)
2298  return v;
2299  }
2300  }
2301  return -1;
2302 }
2303 
2305 {
2306  QDeclarativeType *qmltype = 0;
2307  if (!unit->imports().resolveType(name, &qmltype, 0, 0, 0, 0))
2308  return 0;
2309  if (!qmltype)
2310  return 0;
2311  return qmltype->metaObject();
2312 }
2313 
2314 // similar to logic of completeComponentBuild, but also sticks data
2315 // into datas at the end
2317 {
2319  rewriteBinding.setName('$' + name.mid(name.lastIndexOf('.') + 1));
2320  bool isSharable = false;
2321  QString rewrite = rewriteBinding(expression, 0, &isSharable);
2322 
2323  quint32 length = rewrite.length();
2324  quint32 pc;
2325 
2326  if (isSharable) {
2327  pc = output->cachedClosures.count();
2328  pc |= 0x80000000;
2330  } else {
2331  pc = output->cachedPrograms.length();
2333  }
2334 
2335  QByteArray compiledData =
2336  QByteArray((const char *)&pc, sizeof(quint32)) +
2337  QByteArray((const char *)&length, sizeof(quint32)) +
2338  QByteArray((const char *)rewrite.constData(),
2339  rewrite.length() * sizeof(QChar));
2340 
2341  return output->indexForByteArray(compiledData);
2342 }
2343 
2344 // Ensures that the dynamic meta specification on obj is valid
2346 {
2347  QSet<QByteArray> propNames;
2348  QSet<QByteArray> methodNames;
2349  bool seenDefaultProperty = false;
2350 
2351  // Check properties
2352  for (int ii = 0; ii < obj->dynamicProperties.count(); ++ii) {
2354  obj->dynamicProperties.at(ii);
2355 
2356  if (prop.isDefaultProperty) {
2357  if (seenDefaultProperty)
2358  COMPILE_EXCEPTION(&prop, tr("Duplicate default property"));
2359  seenDefaultProperty = true;
2360  }
2361 
2362  if (propNames.contains(prop.name))
2363  COMPILE_EXCEPTION(&prop, tr("Duplicate property name"));
2364 
2365  QString propName = QString::fromUtf8(prop.name);
2366  if (propName.at(0).isUpper())
2367  COMPILE_EXCEPTION(&prop, tr("Property names cannot begin with an upper case letter"));
2368 
2369  if (enginePrivate->globalClass->illegalNames().contains(propName))
2370  COMPILE_EXCEPTION(&prop, tr("Illegal property name"));
2371 
2372  propNames.insert(prop.name);
2373  }
2374 
2375  for (int ii = 0; ii < obj->dynamicSignals.count(); ++ii) {
2376  QByteArray name = obj->dynamicSignals.at(ii).name;
2377  if (methodNames.contains(name))
2378  COMPILE_EXCEPTION(obj, tr("Duplicate signal name"));
2379  QString nameStr = QString::fromUtf8(name);
2380  if (nameStr.at(0).isUpper())
2381  COMPILE_EXCEPTION(obj, tr("Signal names cannot begin with an upper case letter"));
2383  COMPILE_EXCEPTION(obj, tr("Illegal signal name"));
2384  methodNames.insert(name);
2385  }
2386  for (int ii = 0; ii < obj->dynamicSlots.count(); ++ii) {
2387  QByteArray name = obj->dynamicSlots.at(ii).name;
2388  if (methodNames.contains(name))
2389  COMPILE_EXCEPTION(obj, tr("Duplicate method name"));
2390  QString nameStr = QString::fromUtf8(name);
2391  if (nameStr.at(0).isUpper())
2392  COMPILE_EXCEPTION(obj, tr("Method names cannot begin with an upper case letter"));
2394  COMPILE_EXCEPTION(obj, tr("Illegal method name"));
2395  methodNames.insert(name);
2396  }
2397 
2398  return true;
2399 }
2400 
2402 {
2403  for (int ii = 0; ii < obj->dynamicProperties.count(); ++ii) {
2404  const Object::DynamicProperty &p = obj->dynamicProperties.at(ii);
2405 
2406  if (!p.defaultValue || p.type == Object::DynamicProperty::Alias)
2407  continue;
2408 
2409  Property *property = 0;
2410  if (p.isDefaultProperty) {
2411  property = obj->getDefaultProperty();
2412  } else {
2413  property = obj->getProperty(p.name);
2414  if (!property->values.isEmpty())
2415  COMPILE_EXCEPTION(property, tr("Property value set multiple times"));
2416  }
2417 
2418  if (property->value)
2419  COMPILE_EXCEPTION(property, tr("Invalid property nesting"));
2420 
2421  for (int ii = 0; ii < p.defaultValue->values.count(); ++ii) {
2423  v->addref();
2424  property->values.append(v);
2425  }
2426  }
2427  return true;
2428 }
2429 
2430 Q_GLOBAL_STATIC(QAtomicInt, classIndexCounter)
2431 
2433 {
2434  Q_ASSERT(obj);
2435  Q_ASSERT(obj->metatype);
2436 
2437  if (mode != ForceCreation &&
2438  obj->dynamicProperties.isEmpty() &&
2439  obj->dynamicSignals.isEmpty() &&
2440  obj->dynamicSlots.isEmpty())
2441  return true;
2442 
2443  QByteArray dynamicData(sizeof(QDeclarativeVMEMetaData), (char)0);
2444 
2445  QByteArray newClassName = obj->metatype->className();
2446  newClassName.append("_QML_");
2447  int idx = classIndexCounter()->fetchAndAddRelaxed(1);
2448  newClassName.append(QByteArray::number(idx));
2449  if (compileState.root == obj) {
2450  QString path = output->url.path();
2451  int lastSlash = path.lastIndexOf(QLatin1Char('/'));
2452  if (lastSlash > -1) {
2453  QString nameBase = path.mid(lastSlash + 1, path.length()-lastSlash-5);
2454  if (!nameBase.isEmpty() && nameBase.at(0).isUpper())
2455  newClassName = nameBase.toUtf8() + "_QMLTYPE_" + QByteArray::number(idx);
2456  }
2457  }
2458 
2459  QMetaObjectBuilder builder;
2460  builder.setClassName(newClassName);
2462 
2463  bool hasAlias = false;
2464  for (int ii = 0; ii < obj->dynamicProperties.count(); ++ii) {
2465  const Object::DynamicProperty &p = obj->dynamicProperties.at(ii);
2466 
2467  int propIdx = obj->metaObject()->indexOfProperty(p.name.constData());
2468  if (-1 != propIdx) {
2469  QMetaProperty prop = obj->metaObject()->property(propIdx);
2470  if (prop.isFinal())
2471  COMPILE_EXCEPTION(&p, tr("Cannot override FINAL property"));
2472  }
2473 
2474  if (p.isDefaultProperty &&
2475  (p.type != Object::DynamicProperty::Alias ||
2476  mode == ResolveAliases))
2477  builder.addClassInfo("DefaultProperty", p.name);
2478 
2479  QByteArray type;
2480  int propertyType = 0;
2481  bool readonly = false;
2482  switch(p.type) {
2483  case Object::DynamicProperty::Alias:
2484  hasAlias = true;
2485  continue;
2486  break;
2487  case Object::DynamicProperty::CustomList:
2488  case Object::DynamicProperty::Custom:
2489  {
2490  QByteArray customTypeName;
2491  QDeclarativeType *qmltype = 0;
2492  QUrl url;
2493  if (!unit->imports().resolveType(p.customType, &qmltype, &url, 0, 0, 0))
2494  COMPILE_EXCEPTION(&p, tr("Invalid property type"));
2495 
2496  if (!qmltype) {
2498  Q_ASSERT(tdata);
2499  Q_ASSERT(tdata->isComplete());
2500 
2502  customTypeName = data->root->className();
2503  data->release();
2504  tdata->release();
2505  } else {
2506  customTypeName = qmltype->typeName();
2507  }
2508 
2509  if (p.type == Object::DynamicProperty::Custom) {
2510  type = customTypeName + '*';
2511  propertyType = QMetaType::QObjectStar;
2512  } else {
2513  readonly = true;
2514  type = "QDeclarativeListProperty<";
2515  type.append(customTypeName);
2516  type.append(">");
2517  propertyType = qMetaTypeId<QDeclarativeListProperty<QObject> >();
2518  }
2519  }
2520  break;
2521  case Object::DynamicProperty::Variant:
2522  propertyType = -1;
2523  type = "QVariant";
2524  break;
2525  case Object::DynamicProperty::Int:
2526  propertyType = QVariant::Int;
2527  type = "int";
2528  break;
2529  case Object::DynamicProperty::Bool:
2530  propertyType = QVariant::Bool;
2531  type = "bool";
2532  break;
2533  case Object::DynamicProperty::Real:
2534  propertyType = QVariant::Double;
2535  type = "double";
2536  break;
2538  propertyType = QVariant::String;
2539  type = "QString";
2540  break;
2541  case Object::DynamicProperty::Url:
2542  propertyType = QVariant::Url;
2543  type = "QUrl";
2544  break;
2546  propertyType = QVariant::Color;
2547  type = "QColor";
2548  break;
2549  case Object::DynamicProperty::Time:
2550  propertyType = QVariant::Time;
2551  type = "QTime";
2552  break;
2553  case Object::DynamicProperty::Date:
2554  propertyType = QVariant::Date;
2555  type = "QDate";
2556  break;
2557  case Object::DynamicProperty::DateTime:
2558  propertyType = QVariant::DateTime;
2559  type = "QDateTime";
2560  break;
2561  }
2562 
2563  ((QDeclarativeVMEMetaData *)dynamicData.data())->propertyCount++;
2564  QDeclarativeVMEMetaData::PropertyData propertyData = { propertyType };
2565  dynamicData.append((char *)&propertyData, sizeof(propertyData));
2566 
2567  builder.addSignal(p.name + "Changed()");
2568  QMetaPropertyBuilder propBuilder =
2569  builder.addProperty(p.name, type, builder.methodCount() - 1);
2570  propBuilder.setWritable(!readonly);
2571  }
2572 
2573  for (int ii = 0; ii < obj->dynamicProperties.count(); ++ii) {
2574  const Object::DynamicProperty &p = obj->dynamicProperties.at(ii);
2575 
2576  if (p.type == Object::DynamicProperty::Alias) {
2577  if (mode == ResolveAliases) {
2578  ((QDeclarativeVMEMetaData *)dynamicData.data())->aliasCount++;
2579  COMPILE_CHECK(compileAlias(builder, dynamicData, obj, p));
2580  } else {
2581  // Need a fake signal so that the metaobject remains consistent across
2582  // the resolve and non-resolve alias runs
2583  builder.addSignal(p.name + "Changed()");
2584  }
2585  }
2586  }
2587 
2588  for (int ii = 0; ii < obj->dynamicSignals.count(); ++ii) {
2589  const Object::DynamicSignal &s = obj->dynamicSignals.at(ii);
2590  QByteArray sig(s.name + '(');
2591  for (int jj = 0; jj < s.parameterTypes.count(); ++jj) {
2592  if (jj) sig.append(',');
2593  sig.append(s.parameterTypes.at(jj));
2594  }
2595  sig.append(')');
2596  QMetaMethodBuilder b = builder.addSignal(sig);
2598  ((QDeclarativeVMEMetaData *)dynamicData.data())->signalCount++;
2599  }
2600 
2601  QStringList funcScripts;
2602 
2603  for (int ii = 0; ii < obj->dynamicSlots.count(); ++ii) {
2604  Object::DynamicSlot &s = obj->dynamicSlots[ii];
2605  QByteArray sig(s.name + '(');
2606  QString funcScript(QLatin1String("(function ") + s.name + QLatin1Char('('));
2607 
2608  for (int jj = 0; jj < s.parameterNames.count(); ++jj) {
2609  if (jj) {
2610  sig.append(',');
2611  funcScript.append(QLatin1Char(','));
2612  }
2613  funcScript.append(QLatin1String(s.parameterNames.at(jj)));
2614  sig.append("QVariant");
2615  }
2616  sig.append(')');
2617  funcScript.append(QLatin1Char(')'));
2618  funcScript.append(s.body);
2619  funcScript.append(QLatin1Char(')'));
2620  funcScripts << funcScript;
2621 
2622  QMetaMethodBuilder b = builder.addSlot(sig);
2623  b.setReturnType("QVariant");
2625 
2626  ((QDeclarativeVMEMetaData *)dynamicData.data())->methodCount++;
2628  { s.parameterNames.count(), 0, funcScript.length(), s.location.start.line };
2629 
2630  dynamicData.append((char *)&methodData, sizeof(methodData));
2631  }
2632 
2633  for (int ii = 0; ii < obj->dynamicSlots.count(); ++ii) {
2634  const QString &funcScript = funcScripts.at(ii);
2636  ((QDeclarativeVMEMetaData *)dynamicData.data())->methodData() + ii;
2637 
2638  data->bodyOffset = dynamicData.size();
2639 
2640  dynamicData.append((const char *)funcScript.constData(),
2641  (funcScript.length() * sizeof(QChar)));
2642  }
2643 
2644  obj->metadata = builder.toRelocatableData();
2645  builder.fromRelocatableData(&obj->extObject, obj->metatype, obj->metadata);
2646 
2647  if (mode == IgnoreAliases && hasAlias)
2649 
2650  obj->synthdata = dynamicData;
2651 
2652  if (obj->synthCache) {
2653  obj->synthCache->release();
2654  obj->synthCache = 0;
2655  }
2656 
2657  if (obj->type != -1) {
2658  QDeclarativePropertyCache *cache = output->types[obj->type].createPropertyCache(engine)->copy();
2659  cache->append(engine, &obj->extObject, QDeclarativePropertyCache::Data::NoFlags,
2662  obj->synthCache = cache;
2663  }
2664 
2665  return true;
2666 }
2667 
2669 {
2670  if (val.isEmpty())
2671  COMPILE_EXCEPTION(v, tr( "Invalid empty ID"));
2672 
2673  if (val.at(0).isLetter() && !val.at(0).isLower())
2674  COMPILE_EXCEPTION(v, tr( "IDs cannot start with an uppercase letter"));
2675 
2676  QChar u(QLatin1Char('_'));
2677  for (int ii = 0; ii < val.count(); ++ii) {
2678 
2679  if (ii == 0 && !val.at(ii).isLetter() && val.at(ii) != u) {
2680  COMPILE_EXCEPTION(v, tr( "IDs must start with a letter or underscore"));
2681  } else if (ii != 0 && !val.at(ii).isLetterOrNumber() && val.at(ii) != u) {
2682  COMPILE_EXCEPTION(v, tr( "IDs must contain only letters, numbers, and underscores"));
2683  }
2684 
2685  }
2686 
2688  COMPILE_EXCEPTION(v, tr( "ID illegally masks global JavaScript property"));
2689 
2690  return true;
2691 }
2692 
2693 #include <qdeclarativejsparser_p.h>
2694 
2696 {
2698  QString name =
2699  static_cast<QDeclarativeJS::AST::IdentifierExpression *>(node)->name->asString();
2700  return QStringList() << name;
2703 
2704  QStringList rv = astNodeToStringList(expr->base);
2705  if (rv.isEmpty())
2706  return rv;
2707  rv.append(expr->name->asString());
2708  return rv;
2709  }
2710  return QStringList();
2711 }
2712 
2714  QByteArray &data,
2716  const Object::DynamicProperty &prop)
2717 {
2718  if (!prop.defaultValue)
2719  COMPILE_EXCEPTION(obj, tr("No property alias location"));
2720 
2721  if (prop.defaultValue->values.count() != 1 ||
2722  prop.defaultValue->values.at(0)->object ||
2723  !prop.defaultValue->values.at(0)->value.isScript())
2724  COMPILE_EXCEPTION(prop.defaultValue, tr("Invalid alias location"));
2725 
2726  QDeclarativeJS::AST::Node *node = prop.defaultValue->values.at(0)->value.asAST();
2727  if (!node)
2728  COMPILE_EXCEPTION(obj, tr("No property alias location")); // ### Can this happen?
2729 
2730  QStringList alias = astNodeToStringList(node);
2731 
2732  if (alias.count() < 1 || alias.count() > 3)
2733  COMPILE_EXCEPTION(prop.defaultValue, tr("Invalid alias reference. An alias reference must be specified as <id>, <id>.<property> or <id>.<value property>.<property>"));
2734 
2735  if (!compileState.ids.contains(alias.at(0)))
2736  COMPILE_EXCEPTION(prop.defaultValue, tr("Invalid alias reference. Unable to find id \"%1\"").arg(alias.at(0)));
2737 
2738  QDeclarativeParser::Object *idObject = compileState.ids[alias.at(0)];
2739 
2741 
2742  int propIdx = -1;
2743  int flags = 0;
2744  bool writable = false;
2745  if (alias.count() == 2 || alias.count() == 3) {
2746  propIdx = indexOfProperty(idObject, alias.at(1).toUtf8());
2747 
2748  if (-1 == propIdx) {
2749  COMPILE_EXCEPTION(prop.defaultValue, tr("Invalid alias location"));
2750  } else if (propIdx > 0xFFFF) {
2751  COMPILE_EXCEPTION(prop.defaultValue, tr("Alias property exceeds alias bounds"));
2752  }
2753 
2754  QMetaProperty aliasProperty = idObject->metaObject()->property(propIdx);
2755  if (!aliasProperty.isScriptable())
2756  COMPILE_EXCEPTION(prop.defaultValue, tr("Invalid alias location"));
2757 
2758  writable = aliasProperty.isWritable();
2759 
2760  if (alias.count() == 3) {
2761  QDeclarativeValueType *valueType = enginePrivate->valueTypes[aliasProperty.type()];
2762  if (!valueType)
2763  COMPILE_EXCEPTION(prop.defaultValue, tr("Invalid alias location"));
2764 
2765  propIdx |= ((unsigned int)aliasProperty.type()) << 24;
2766 
2767  int valueTypeIndex = valueType->metaObject()->indexOfProperty(alias.at(2).toUtf8().constData());
2768  if (valueTypeIndex == -1)
2769  COMPILE_EXCEPTION(prop.defaultValue, tr("Invalid alias location"));
2770  Q_ASSERT(valueTypeIndex <= 0xFF);
2771 
2772  aliasProperty = valueType->metaObject()->property(valueTypeIndex);
2773  propIdx |= (valueTypeIndex << 16);
2774  }
2775 
2776  if (aliasProperty.isEnumType())
2777  typeName = "int"; // Avoid introducing a dependency on the aliased metaobject
2778  else
2779  typeName = aliasProperty.typeName();
2780  } else {
2781  typeName = idObject->metaObject()->className();
2782 
2783  //use the base type since it has been registered with metatype system
2784  int index = typeName.indexOf("_QML_");
2785  if (index != -1) {
2786  typeName = typeName.left(index);
2787  } else {
2788  index = typeName.indexOf("_QMLTYPE_");
2789  const QMetaObject *mo = idObject->metaObject();
2790  while (index != -1 && mo) {
2791  typeName = mo->superClass()->className();
2792  index = typeName.indexOf("_QMLTYPE_");
2793  mo = mo->superClass();
2794  }
2795  }
2796 
2797  typeName += '*';
2798  }
2799 
2800  if (typeName.endsWith('*'))
2801  flags |= QML_ALIAS_FLAG_PTR;
2802 
2803  data.append((const char *)&idObject->idIndex, sizeof(idObject->idIndex));
2804  data.append((const char *)&propIdx, sizeof(propIdx));
2805  data.append((const char *)&flags, sizeof(flags));
2806 
2807  builder.addSignal(prop.name + "Changed()");
2808  QMetaPropertyBuilder propBuilder =
2809  builder.addProperty(prop.name, typeName.constData(), builder.methodCount() - 1);
2810  propBuilder.setWritable(writable);
2811  return true;
2812 }
2813 
2816  const BindingContext &ctxt)
2817 {
2818  Q_ASSERT(prop->index != -1);
2819  Q_ASSERT(prop->parent);
2820  Q_ASSERT(prop->parent->metaObject());
2821 
2822  QMetaProperty mp = prop->parent->metaObject()->property(prop->index);
2823  if (!mp.isWritable() && !QDeclarativeMetaType::isList(prop->type))
2824  COMPILE_EXCEPTION(prop, tr("Invalid property assignment: \"%1\" is a read-only property").arg(QString::fromUtf8(prop->name)));
2825 
2826  BindingReference reference;
2827  reference.expression = value->value;
2828  reference.property = prop;
2829  reference.value = value;
2830  reference.bindingContext = ctxt;
2831  addBindingReference(reference);
2832 
2833  return true;
2834 }
2835 
2839  QDeclarativeParser::Property *valueTypeProperty)
2840 {
2841  Q_UNUSED(obj);
2842  Q_ASSERT(compileState.bindings.contains(binding));
2843 
2844  const BindingReference &ref = compileState.bindings.value(binding);
2845  if (ref.dataType == BindingReference::Experimental) {
2848  store.assignBinding.value = ref.compiledIndex;
2849  store.assignBinding.context = ref.bindingContext.stack;
2850  store.assignBinding.owner = ref.bindingContext.owner;
2851  if (valueTypeProperty)
2852  store.assignBinding.property = (valueTypeProperty->index & 0xFFFF) |
2853  ((valueTypeProperty->type & 0xFF)) << 16 |
2854  ((prop->index & 0xFF) << 24);
2855  else
2856  store.assignBinding.property = prop->index;
2857  store.line = binding->location.start.line;
2858  output->bytecode << store;
2859  return;
2860  }
2861 
2863  if (!prop->isAlias)
2865  else
2867  store.assignBinding.value = output->indexForByteArray(ref.compiledData);
2868  store.assignBinding.context = ref.bindingContext.stack;
2869  store.assignBinding.owner = ref.bindingContext.owner;
2870  store.line = binding->location.start.line;
2871 
2872  Q_ASSERT(ref.bindingContext.owner == 0 ||
2873  (ref.bindingContext.owner != 0 && valueTypeProperty));
2874  if (ref.bindingContext.owner) {
2875  store.assignBinding.property = genValueTypeData(prop, valueTypeProperty);
2876  } else {
2877  store.assignBinding.property = genPropertyData(prop);
2878  }
2879 
2880  output->bytecode << store;
2881 }
2882 
2884 {
2885  if (compileState.ids.count() == 0)
2886  return -1;
2887 
2889 
2891  iter != compileState.ids.end();
2892  ++iter)
2893  cache->add(iter.key(), (*iter)->idIndex);
2894 
2895  output->contextCaches.append(cache);
2896  return output->contextCaches.count() - 1;
2897 }
2898 
2901 {
2902  QByteArray data =
2904  enginePrivate->valueTypes[prop->type]->metaObject(),
2905  valueTypeProp->index);
2906 // valueTypeProp->index, valueTypeProp->type);
2907 
2908  return output->indexForByteArray(data);
2909 }
2910 
2912 {
2914 }
2915 
2917 {
2919 
2920  for (int ii = 0; ii < compileState.aliasingObjects.count(); ++ii) {
2923  }
2924 
2926  expr.component = compileState.root;
2927  expr.ids = compileState.ids;
2928 
2929  QDeclarativeBindingCompiler bindingCompiler;
2930 
2932  iter != compileState.bindings.end(); ++iter) {
2933 
2934  BindingReference &binding = *iter;
2935 
2936  expr.context = binding.bindingContext.object;
2937  expr.property = binding.property;
2938  expr.expression = binding.expression;
2939  expr.imports = unit->imports();
2940 
2941  // ### We don't currently optimize for bindings on alias's - because
2942  // of the solution to QTBUG-13719
2943  if (!binding.property->isAlias) {
2944  int index = bindingCompiler.compile(expr, enginePrivate);
2945  if (index != -1) {
2947  binding.compiledIndex = index;
2948  componentStat.optimizedBindings.append(iter.key()->location);
2949  continue;
2950  }
2951  }
2952 
2954 
2955  // Pre-rewrite the expression
2956  QString expression = binding.expression.asScript();
2957 
2959  rewriteBinding.setName('$'+binding.property->name);
2960  bool isSharable = false;
2961  expression = rewriteBinding(binding.expression.asAST(), expression, &isSharable);
2962 
2963  quint32 length = expression.length();
2964  quint32 pc;
2965 
2966  if (isSharable) {
2967  pc = output->cachedClosures.count();
2968  pc |= 0x80000000;
2970  } else {
2971  pc = output->cachedPrograms.length();
2973  }
2974 
2975  binding.compiledData =
2976  QByteArray((const char *)&pc, sizeof(quint32)) +
2977  QByteArray((const char *)&length, sizeof(quint32)) +
2978  QByteArray((const char *)expression.constData(),
2979  expression.length() * sizeof(QChar));
2980 
2981  componentStat.scriptBindings.append(iter.key()->location);
2982  }
2983 
2984  if (bindingCompiler.isValid()) {
2985  compileState.compiledBindingData = bindingCompiler.program();
2986  if (bindingsDump())
2988  }
2989 
2991 
2992  return true;
2993 }
2994 
2996 {
2997  qWarning().nospace() << "QML Document: " << output->url.toString();
2998  for (int ii = 0; ii < savedComponentStats.count(); ++ii) {
2999  const ComponentStat &stat = savedComponentStats.at(ii);
3000  qWarning().nospace() << " Component Line " << stat.lineNumber;
3001  qWarning().nospace() << " Total Objects: " << stat.objects;
3002  qWarning().nospace() << " IDs Used: " << stat.ids;
3003  qWarning().nospace() << " Optimized Bindings: " << stat.optimizedBindings.count();
3004 
3005  {
3007  for (int ii = 0; ii < stat.optimizedBindings.count(); ++ii) {
3008  if (0 == (ii % 10)) {
3009  if (ii) output.append("\n");
3010  output.append(" ");
3011  }
3012 
3013  output.append("(");
3015  output.append(":");
3017  output.append(") ");
3018  }
3019  if (!output.isEmpty())
3020  qWarning().nospace() << output.constData();
3021  }
3022 
3023  qWarning().nospace() << " QScript Bindings: " << stat.scriptBindings.count();
3024  {
3026  for (int ii = 0; ii < stat.scriptBindings.count(); ++ii) {
3027  if (0 == (ii % 10)) {
3028  if (ii) output.append("\n");
3029  output.append(" ");
3030  }
3031 
3032  output.append("(");
3034  output.append(":");
3036  output.append(") ");
3037  }
3038  if (!output.isEmpty())
3039  qWarning().nospace() << output.constData();
3040  }
3041  }
3042 }
3043 
3049 {
3050  const QMetaObject *toMo =
3052  const QMetaObject *fromMo = from->metaObject();
3053 
3054  while (fromMo) {
3055  if (QDeclarativePropertyPrivate::equal(fromMo, toMo))
3056  return true;
3057  fromMo = fromMo->superClass();
3058  }
3059  return false;
3060 }
3061 
3063 {
3064  // ### Optimize
3065  const QMetaObject *mo = from->metatype;
3066  QDeclarativeType *type = 0;
3067  while (!type && mo) {
3068  type = QDeclarativeMetaType::qmlType(mo);
3069  mo = mo->superClass();
3070  }
3071  return type;
3072 }
3073 
3075 {
3076  const QMetaObject *mo = obj->metatype;
3077 
3078  int idx = mo->indexOfClassInfo("DeferredPropertyNames");
3079  if (idx == -1)
3080  return QStringList();
3081 
3082  QMetaClassInfo classInfo = mo->classInfo(idx);
3083  QStringList rv = QString::fromUtf8(classInfo.value()).split(QLatin1Char(','));
3084  return rv;
3085 }
3086 
3087 // This code must match the semantics of QDeclarativePropertyPrivate::findSignalByName
3089  bool *notInRevision)
3090 {
3091  if (notInRevision) *notInRevision = false;
3092 
3093  if (object->synthCache || (object->type != -1 && output->types.at(object->type).propertyCache())) {
3094  // XXX fromUtf8
3095  QString strName(QString::fromUtf8(name));
3096  QDeclarativePropertyCache *cache =
3097  object->synthCache?object->synthCache:output->types.at(object->type).propertyCache();
3098 
3099  QDeclarativePropertyCache::Data *d = cache->property(strName);
3100  if (notInRevision) *notInRevision = false;
3101 
3103  d = cache->overrideData(d);
3104 
3105  if (d && !cache->isAllowedInRevision(d)) {
3106  if (notInRevision) *notInRevision = true;
3107  return -1;
3108  } else if (d) {
3109  return d->coreIndex;
3110  }
3111 
3112  if (name.endsWith("Changed")) {
3113  QByteArray propName = name.mid(0, name.length() - 7);
3114 
3115  int propIndex = indexOfProperty(object, propName, notInRevision);
3116  if (propIndex != -1) {
3117  d = cache->property(propIndex);
3118  return d->notifyIndex;
3119  }
3120  }
3121 
3122  return -1;
3123  } else {
3124  return QDeclarativePropertyPrivate::findSignalByName(object->metaObject(), name).methodIndex();
3125  }
3126 
3127 }
3128 
3130  bool *notInRevision)
3131 {
3132  if (notInRevision) *notInRevision = false;
3133 
3134  if (object->synthCache || (object->type != -1 && output->types.at(object->type).propertyCache())) {
3135  // XXX fromUtf8
3136  QString strName(QString::fromUtf8(name));
3137  QDeclarativePropertyCache *cache =
3138  object->synthCache?object->synthCache:output->types.at(object->type).propertyCache();
3139 
3140  QDeclarativePropertyCache::Data *d = cache->property(strName);
3141  // Find the first property
3143  d = cache->overrideData(d);
3144 
3145  if (d && !cache->isAllowedInRevision(d)) {
3146  if (notInRevision) *notInRevision = true;
3147  return -1;
3148  } else {
3149  return d?d->coreIndex:-1;
3150  }
3151  } else {
3152  const QMetaObject *mo = object->metaObject();
3153  return mo->indexOfProperty(name.constData());
3154  }
3155 }
3156 
const QDeclarativeImports & imports() const
The QColor class provides colors based on RGB, HSV or CMYK values.
Definition: qcolor.h:67
double d
Definition: qnumeric_p.h:62
static void dump(const QByteArray &)
QHash< QDeclarativeParser::Value *, BindingContext > signalExpressions
The QMetaObject class contains meta-information about Qt objects.
Definition: qobjectdefs.h:304
static QStringList astNodeToStringList(QDeclarativeJS::AST::Node *node)
const QString asString() const
void genObjectBody(QDeclarativeParser::Object *obj)
DEFINE_BOOL_CONFIG_OPTION(compilerDump, QML_COMPILER_DUMP)
bool isFinal() const
qreal y() const
Returns the y-coordinate of the rectangle&#39;s top edge.
Definition: qrect.h:667
The QVector3D class represents a vector or vertex in 3D space.
Definition: qvector3d.h:60
The QHash::const_iterator class provides an STL-style const iterator for QHash and QMultiHash...
Definition: qhash.h:395
QColor Q_DECLARATIVE_PRIVATE_EXPORT colorFromString(const QString &, bool *ok=0)
int type
Definition: qmetatype.cpp:239
QByteArray module() const
bool buildSubObject(QDeclarativeParser::Object *obj, const BindingContext &)
bool isLetter() const
Returns true if the character is a letter (Letter_* categories); otherwise returns false...
Definition: qchar.cpp:653
bool isScriptable(const QObject *obj=0) const
Returns true if the property is scriptable for the given object; otherwise returns false...
bool isWritable() const
Returns true if this property is writable; otherwise returns false.
const QMetaObject * resolveType(const QByteArray &name) const
unsigned char c[8]
Definition: qnumeric_p.h:62
The QMetaEnum class provides meta-data about an enumerator.
Definition: qmetaobject.h:147
void setName(const QByteArray &name)
QList< Property * > attachedProperties
QList< QDeclarativeError > exceptions
#define QT_END_NAMESPACE
This macro expands to.
Definition: qglobal.h:90
int propertyValueInterceptorCast() const
int keysToValue(const char *keys) const
Returns the value derived from combining together the values of the keys using the OR operator...
void addScriptStringProperty(Property *, int=0)
static void fromRelocatableData(QMetaObject *, const QMetaObject *, const QByteArray &)
QMetaMethodBuilder addSlot(const QByteArray &signature)
Adds a new public slot to this class with the specified signature.
char * data()
Returns a pointer to the data stored in the byte array.
Definition: qbytearray.h:429
static bool ValuePtrLessThan(const QDeclarativeParser::Value *t1, const QDeclarativeParser::Value *t2)
const QChar at(int i) const
Returns the character at the given index position in the string.
Definition: qstring.h:698
bool buildPropertyObjectAssignment(QDeclarativeParser::Property *prop, QDeclarativeParser::Object *obj, QDeclarativeParser::Value *value, const BindingContext &ctxt)
QUrl finalUrl() const
Returns the final url of the data.
QString toString(FormattingOptions options=None) const
Returns the human-displayable string representation of the URL.
Definition: qurl.cpp:5896
int indexForByteArray(const QByteArray &)
The QAtomicInt class provides platform-independent atomic operations on integers. ...
Definition: qatomic.h:55
void genComponent(QDeclarativeParser::Object *obj)
static void reset(QDeclarativeCompiledData *)
Resets data by clearing the lists that the QDeclarativeCompiler modifies.
QByteArray & append(char c)
Appends the character ch to this byte array.
The QMetaPropertyBuilder class enables modifications to a property definition on a meta object builde...
QByteArray toUtf8() const Q_REQUIRED_RESULT
Returns a UTF-8 representation of the string as a QByteArray.
Definition: qstring.cpp:4074
QList< TypeReference * > referencedTypes() const
qreal width() const
Returns the width.
Definition: qsize.h:284
QMetaClassInfo classInfo(int index) const
Returns the meta-data for the item of class information with the given index.
#define at(className, varName)
The QByteArray class provides an array of bytes.
Definition: qbytearray.h:135
void setClassName(const QByteArray &name)
Sets the name of the class being constructed by this meta object builder.
static Expression::Ptr create(Expression *const expr, const YYLTYPE &sourceLocator, const ParserContext *const parseInfo)
int length() const
Returns the number of characters in this string.
Definition: qstring.h:696
FetchAttachedInstruction fetchAttached
static QMetaMethod findSignalByName(const QMetaObject *mo, const QByteArray &)
Return the signal corresponding to name.
void genLiteralAssignment(const QMetaProperty &prop, QDeclarativeParser::Value *value)
Generate a store instruction for assigning literal v to property prop.
QDeclarativePropertyCache * cache(QObject *obj)
Returns a QDeclarativePropertyCache for obj if one is available.
QDeclarativeCompiledData * compiledData() const
bool canCoerce(int to, QDeclarativeParser::Object *from)
Returns true if from can be assigned to a (QObject) property of type to.
QDeclarativePropertyCache * typePropertyCache
The QPointF class defines a point in the plane using floating point precision.
Definition: qpoint.h:214
qreal height() const
Returns the height.
Definition: qsize.h:287
QVector3D Q_DECLARATIVE_PRIVATE_EXPORT vector3DFromString(const QString &, bool *ok=0)
static const QMetaObject * get()
QDeclarativeGlobalScriptClass * globalClass
void add(const QString &, int)
QList< Property * > valueProperties
static const QMetaObject staticMetaObject
This variable stores the meta-object for the class.
Definition: qobject.h:128
static QDeclarativeType * qmlType(const QByteArray &, int, int)
Returns the type (if any) of URI-qualified named name in version specified by version_major and versi...
QList< QDeclarativeParser::Object::ScriptBlock > scripts
int genValueTypeData(QDeclarativeParser::Property *prop, QDeclarativeParser::Property *valueTypeProp)
const QMetaObject * metaObject() const
bool doesPropertyExist(QDeclarativeParser::Property *prop, QDeclarativeParser::Object *obj)
Returns true if (value) property prop exists on obj, false otherwise.
The QDate class provides date functions.
Definition: qdatetime.h:55
QLatin1String(DBUS_INTERFACE_DBUS))) Q_GLOBAL_STATIC_WITH_ARGS(QString
int msec() const
Returns the millisecond part (0 to 999) of the time.
Definition: qdatetime.cpp:1611
bool resolveType(const QByteArray &type, QDeclarativeType **type_return, QUrl *url_return, int *version_major, int *version_minor, QDeclarativeImportedNamespace **ns_return, QString *errorString=0) const
The given (namespace qualified) type is resolved to either.
quint16 u
int count(const T &t) const
Returns the number of occurrences of value in the list.
Definition: qlist.h:891
int attachedPropertiesId() const
void genValueTypeProperty(QDeclarativeParser::Object *obj, QDeclarativeParser::Property *)
qreal x() const
Returns the x coordinate of this point.
Definition: qvector3d.h:161
bool testQualifiedEnumAssignment(const QMetaProperty &prop, QDeclarativeParser::Object *obj, QDeclarativeParser::Value *value, bool *isAssignment)
int genPropertyData(QDeclarativeParser::Property *prop)
The QUrl class provides a convenient interface for working with URLs.
Definition: qurl.h:61
QDeclarativeTypeLoader typeLoader
The QString class provides a Unicode character string.
Definition: qstring.h:83
bool checkDynamicMeta(QDeclarativeParser::Object *obj)
The QHash class is a template class that provides a hash-table-based dictionary.
Definition: qdatastream.h:66
static QDeclarativeType * toQmlType(QDeclarativeParser::Object *from)
#define COMPILE_EXCEPTION(token, desc)
Inserts an error into the QDeclarativeCompiler error list, and returns false (failure).
static const char * typeToName(Type type)
Converts the enum representation of the storage type, typ, to its string representation.
Definition: qvariant.cpp:2008
#define Q_ASSERT(cond)
Definition: qglobal.h:1823
The QObject class is the base class of all Qt objects.
Definition: qobject.h:111
const char * value() const
Returns the value of this item.
bool startsWith(const QByteArray &a) const
Returns true if this byte array starts with byte array ba; otherwise returns false.
void genPropertyAssignment(QDeclarativeParser::Property *prop, QDeclarativeParser::Object *obj, QDeclarativeParser::Property *valueTypeProperty=0)
The QMetaMethodBuilder class enables modifications to a method definition on a meta object builder...
QDateTime Q_DECLARATIVE_PRIVATE_EXPORT dateTimeFromString(const QString &, bool *ok=0)
static QDeclarativeEnginePrivate * get(QDeclarativeEngine *e)
int indexOfProperty(const char *name) const
Finds property name and returns its index; otherwise returns -1.
bool contains(const Key &key) const
Returns true if the hash contains an item with the key; otherwise returns false.
Definition: qhash.h:872
int propertyIndex() const
Returns this property&#39;s index.
The QSizeF class defines the size of a two-dimensional object using floating point precision...
Definition: qsize.h:202
bool checkValidId(QDeclarativeParser::Value *, const QString &)
The QChar class provides a 16-bit Unicode character.
Definition: qchar.h:72
bool buildSignal(QDeclarativeParser::Property *prop, QDeclarativeParser::Object *obj, const BindingContext &)
bool containsRevisionedAttributes() const
QDeclarativeParser::Property * property
ComponentCompileState componentState(QDeclarativeParser::Object *)
QList< QDeclarativeParser::LocationSpan > optimizedBindings
QDeclarativeEngine * engine
QRectF Q_DECLARATIVE_PRIVATE_EXPORT rectFFromString(const QString &, bool *ok=0)
QDeclarativePropertyCache * synthCache
AssignSignalObjectInstruction assignSignalObject
QString path() const
Returns the path of the URL.
Definition: qurl.cpp:4977
bool isEmpty() const
Returns true if the list contains no items; otherwise returns false.
Definition: qlist.h:152
bool isLower() const
Returns true if the character is a lowercase letter, i.
Definition: qchar.h:272
qreal x() const
Returns the x-coordinate of this point.
Definition: qpoint.h:282
iterator insert(const Key &key, const T &value)
Inserts a new item with the key and a value of value.
Definition: qhash.h:753
const QList< TypeReference > & resolvedTypes() const
QDeclarativePropertyCache * createPropertyCache(QDeclarativeEngine *)
Returns the property cache, creating one if it doesn&#39;t already exist.
int indexOfProperty(QDeclarativeParser::Object *, const QByteArray &, bool *notInRevision=0)
void append(const T &t)
Inserts value at the end of the list.
Definition: qlist.h:507
bool isError() const
Returns true if the last call to compile() caused errors.
ComponentCompileState compileState
void genBindingAssignment(QDeclarativeParser::Value *binding, QDeclarativeParser::Property *prop, QDeclarativeParser::Object *obj, QDeclarativeParser::Property *valueTypeProperty=0)
FetchValueInstruction fetchValue
The QTime class provides clock time functions.
Definition: qdatetime.h:148
#define QT_BEGIN_NAMESPACE
This macro expands to.
Definition: qglobal.h:89
QList< DynamicSlot > dynamicSlots
The QRectF class defines a rectangle in the plane using floating point precision. ...
Definition: qrect.h:511
QHash< QString, QDeclarativeParser::Object * > ids
QByteArray toRelocatableData(bool *=0) const
bool isEnumType() const
Returns true if the property&#39;s type is an enumeration value; otherwise returns false.
int lastIndexOf(char c, int from=-1) const
Returns the index position of the last occurrence of character ch in the byte array, searching backward from index position from.
int methodCount() const
Returns the number of methods in this class, excluding the number of methods in the base class...
bool buildObject(QDeclarativeParser::Object *obj, const BindingContext &)
QByteArray typeName() const
QList< ComponentStat > savedComponentStats
int userType() const
Returns this property&#39;s user type.
QPointF Q_DECLARATIVE_PRIVATE_EXPORT pointFFromString(const QString &, bool *ok=0)
bool isFlagType() const
Returns true if the property&#39;s type is an enumeration value that is used as a flag; otherwise returns...
const char * typeName
Definition: qmetatype.cpp:239
bool contains(const T &value) const
Definition: qset.h:91
QString trimmed() const Q_REQUIRED_RESULT
Returns a string that has whitespace removed from the start and the end.
Definition: qstring.cpp:4506
bool isEmpty() const
Returns true if the string has no characters; otherwise returns false.
Definition: qstring.h:704
QList< QDeclarativeParser::Object * > refObjects
QList< DynamicProperty > dynamicProperties
QMetaPropertyBuilder addProperty(const QByteArray &name, const QByteArray &type, int notifierId=-1)
Adds a new readable/writable property to this class with the specified name and type.
static bool init
StoreRealPairInstruction storeRealPair
bool buildPropertyOnAssignment(QDeclarativeParser::Property *prop, QDeclarativeParser::Object *obj, QDeclarativeParser::Object *baseObj, QDeclarativeParser::Value *value, const BindingContext &ctxt)
qreal height() const
Returns the height of the rectangle.
Definition: qrect.h:710
bool buildIdProperty(QDeclarativeParser::Property *prop, QDeclarativeParser::Object *obj)
const char * name
static bool isAttachedPropertyName(const QByteArray &)
Returns true if name refers to an attached property, false otherwise.
bool buildComponent(QDeclarativeParser::Object *obj, const BindingContext &)
#define Q_GLOBAL_STATIC(TYPE, NAME)
Declares a global static variable with the given type and name.
Definition: qglobal.h:1968
const T & at(int i) const
Returns the item at index position i in the list.
Definition: qlist.h:468
QList< QPair< Property *, int > > scriptStringProperties
QString description() const
Returns the error description.
The QStringList class provides a list of strings.
Definition: qstringlist.h:66
bool testLiteralAssignment(const QMetaProperty &prop, QDeclarativeParser::Value *value)
Returns true if literal v can be assigned to property prop, otherwise false.
StoreColorInstruction storeColor
bool buildGroupedProperty(QDeclarativeParser::Property *prop, QDeclarativeParser::Object *obj, const BindingContext &ctxt)
Data * property(const QScriptDeclarativeClass::Identifier &id) const
int propertyValueSourceCast() const
QList< QDeclarativeError > errors() const
QDeclarativeAttachedPropertiesFunc attachedPropertiesFunction() const
static QString fromUtf8(const char *, int size=-1)
Returns a QString initialized with the first size bytes of the UTF-8 string str.
Definition: qstring.cpp:4302
Q_CORE_EXPORT void qWarning(const char *,...)
QList< DynamicSignal > dynamicSignals
int second() const
Returns the second part (0 to 59) of the time.
Definition: qdatetime.cpp:1600
const_iterator insert(const T &value)
Definition: qset.h:179
QDeclarativeCompiledData * output
static const char * data(const QByteArray &arr)
unsigned int uint
Definition: qglobal.h:996
StoreDateTimeInstruction storeDateTime
QList< QScriptProgram * > cachedPrograms
QDeclarativeParser::Object * unitRoot
qreal width() const
Returns the width of the rectangle.
Definition: qrect.h:707
QByteArray qmlTypeName() const
QBool contains(const QString &str, Qt::CaseSensitivity cs=Qt::CaseSensitive) const
Returns true if the list contains the string str; otherwise returns false.
Definition: qstringlist.h:172
StoreFloatInstruction storeFloat
int enumeratorCount() const
Returns the number of enumerators in this class.
static void split(QT_FT_Vector *b)
The QDeclarativeError class encapsulates a QML error.
QList< QDeclarativeParser::LocationSpan > scriptBindings
QString noCreationReason() const
void setFlags(MetaObjectFlags)
Sets the flags of the class being constructed by this meta object builder.
void clear()
Removes all items from the list.
Definition: qlist.h:764
QList< QDeclarativePropertyCache * > propertyCaches
int compile(const Expression &, QDeclarativeEnginePrivate *)
QByteArray left(int len) const
Returns a byte array that contains the leftmost len bytes of this byte array.
int minute() const
Returns the minute part (0 to 59) of the time.
Definition: qdatetime.cpp:1589
static qreal component(const QPointF &point, unsigned int i)
#define COMPILE_CHECK(a)
Returns false if is false, otherwise does nothing.
const QMetaObject * superClass() const
Returns the meta-object of the superclass, or 0 if there is no such object.
Definition: qobjectdefs.h:494
qreal z() const
Returns the z coordinate of this point.
Definition: qvector3d.h:163
The QDeclarativeCustomParser class allows you to add new arbitrary types to QML.
QByteArray mid(int index, int len=-1) const
Returns a byte array containing len bytes from this byte array, starting at position pos...
int indexOf(char c, int from=0) const
Returns the index position of the first occurrence of the character ch in the byte array...
StoreObjectInstruction storeObject
QList< Property * > signalProperties
void qSort(RandomAccessIterator start, RandomAccessIterator end)
Definition: qalgorithms.h:177
int count() const
Definition: qstring.h:103
Q_CORE_EXPORT int QT_FASTCALL script(uint ucs4)
QList< QScriptValue * > cachedClosures
bool buildValueTypeProperty(QObject *type, QDeclarativeParser::Object *obj, QDeclarativeParser::Object *baseObj, const BindingContext &ctxt)
bool buildPropertyInNamespace(QDeclarativeImportedNamespace *ns, QDeclarativeParser::Property *prop, QDeclarativeParser::Object *obj, const BindingContext &)
QList< QDeclarativeIntegerCache * > contextCaches
static QByteArray saveValueType(const QMetaObject *, int, const QMetaObject *, int)
bool isUpper() const
Returns true if the character is an uppercase letter, i.
Definition: qchar.h:273
int rewriteBinding(const QString &expression, const QByteArray &name)
int length() const
Same as size().
Definition: qbytearray.h:356
void addId(const QString &, QDeclarativeParser::Object *)
T & first()
Returns a reference to the first item in the list.
Definition: qlist.h:282
const char * constData() const
Returns a pointer to the data stored in the byte array.
Definition: qbytearray.h:433
QDate date() const
Returns the date part of the datetime.
Definition: qdatetime.cpp:2357
int toJulianDay() const
Converts the date to a Julian day.
Definition: qdatetime.h:134
QDeclarativeTypeData * unit
QDeclarativeParser::Object::ScriptBlock::Pragmas pragmas() const
QString mid(int position, int n=-1) const Q_REQUIRED_RESULT
Returns a string that contains n characters of this string, starting at the specified position index...
Definition: qstring.cpp:3706
QSizeF Q_DECLARATIVE_PRIVATE_EXPORT sizeFFromString(const QString &, bool *ok=0)
static QDeclarativeCustomParserProperty fromProperty(QDeclarativeParser::Property *)
QDeclarativePropertyCache * rootPropertyCache
const QMetaObject * metaObject() const
void populateCache(QDeclarativeTypeNameCache *cache, QDeclarativeEngine *) const
QStringList deferredProperties(QDeclarativeParser::Object *)
bool mergeDynamicMetaProperties(QDeclarativeParser::Object *obj)
void compileTree(QDeclarativeParser::Object *tree)
QDeclarativeJS::AST::Node * asAST() const
QList< Property * > groupedProperties
void append(QDeclarativeEngine *, const QMetaObject *, Data::Flag propertyFlags=Data::NoFlags, Data::Flag methodFlags=Data::NoFlags, Data::Flag signalFlags=Data::NoFlags)
QString & append(QChar c)
Definition: qstring.cpp:1777
void genValueProperty(QDeclarativeParser::Property *prop, QDeclarativeParser::Object *obj)
The QDateTime class provides date and time functions.
Definition: qdatetime.h:216
void setReturnType(const QByteArray &value)
Sets the return type for this method to value.
const QMetaObject * attachedPropertiesType() const
bool isComplete() const
Returns true if the status is Complete.
bool buildAttachedProperty(QDeclarativeParser::Property *prop, QDeclarativeParser::Object *obj, const BindingContext &ctxt)
iterator end()
Returns an STL-style iterator pointing to the imaginary item after the last item in the hash...
Definition: qhash.h:467
QList< Property * > valueTypeProperties
void setUrl(const QUrl &)
Sets the url for the file that caused this error.
const char * name() const
Returns this property&#39;s name.
The QDeclarativeEngine class provides an environment for instantiating QML components.
CreateComponentInstruction createComponent
The QMetaClassInfo class provides additional information about a class.
Definition: qmetaobject.h:224
qreal x() const
Returns the x-coordinate of the rectangle&#39;s left edge.
Definition: qrect.h:664
QDeclarativeCompiler()
Instantiate a new QDeclarativeCompiler.
#define store(x)
QDeclarativeValueTypeFactory valueTypes
QHash< QString, QDeclarativeParser::Object * > ids
int lastIndexOf(QChar c, int from=-1, Qt::CaseSensitivity cs=Qt::CaseSensitive) const
Definition: qstring.cpp:3000
static QString fromLatin1(const char *, int size=-1)
Returns a QString initialized with the first size characters of the Latin-1 string str...
Definition: qstring.cpp:4188
const QSet< QString > & illegalNames() const
const QMetaObject * metaObjectForType(int) const
AssignBindingInstruction assignBinding
int length() const
This function is identical to count().
Definition: qlist.h:281
int key
StoreDoubleInstruction storeDouble
QList< QDeclarativeError > errors() const
Return the list of errors from the last call to compile(), or an empty list if there were no errors...
The QHash::iterator class provides an STL-style non-const iterator for QHash and QMultiHash.
Definition: qhash.h:330
unsigned int quint32
Definition: qglobal.h:938
QList< QDeclarativeParser::Object * > aliasingObjects
StoreSignalInstruction storeSignal
qreal y() const
Returns the y coordinate of this point.
Definition: qvector3d.h:162
const char * className() const
Returns the class name.
Definition: qobjectdefs.h:491
CreateSimpleInstruction createSimple
const char * property
Definition: qwizard.cpp:138
bool buildListProperty(QDeclarativeParser::Property *prop, QDeclarativeParser::Object *obj, const BindingContext &ctxt)
bool buildComponentFromRoot(QDeclarativeParser::Object *obj, const BindingContext &)
int evaluateEnum(const QByteArray &script) const
void genListProperty(QDeclarativeParser::Property *prop, QDeclarativeParser::Object *obj)
iterator begin()
Returns an STL-style iterator pointing to the first item in the hash.
Definition: qhash.h:464
static StringConverter customStringConverter(int)
Return the custom string converter for type, previously installed through registerCustomStringConvert...
bool buildDynamicMeta(QDeclarativeParser::Object *obj, DynamicMetaMode mode)
void add(const QString &, int)
QAbstractDynamicMetaObject rootData
QMetaEnum enumerator(int index) const
Returns the meta-data for the enumerator with the given index.
int keyToValue(const char *key) const
Returns the integer value of the given enumeration key, or -1 if key is not defined.
int size() const
Returns the number of bytes in this byte array.
Definition: qbytearray.h:402
QList< CustomTypeData > customTypeData
QMetaEnum enumerator() const
Returns the enumerator if this property&#39;s type is an enumerator type; otherwise the returned value is...
void addBindingReference(const BindingReference &)
qreal y() const
Returns the y-coordinate of this point.
Definition: qpoint.h:287
QHash< QDeclarativeParser::Value *, BindingReference > bindings
quint16 index
FetchQmlListInstruction fetchQmlList
int indexOfSignal(QDeclarativeParser::Object *, const QByteArray &, bool *notInRevision=0)
QDeclarativeTypeData * get(const QUrl &url)
Returns a QDeclarativeTypeData for the specified url.
#define QML_ALIAS_FLAG_PTR
QHash< int, QDeclarativeParser::Object * > idIndexes
int count(const Key &key) const
Returns the number of items associated with the key.
Definition: qhash.h:719
QDeclarativeTypeNameCache * importCache
The QMetaProperty class provides meta-data about a property.
Definition: qmetaobject.h:176
int addClassInfo(const QByteArray &name, const QByteArray &value)
Adds name and value as an item of class information to this class.
bool isEmpty() const
Returns true if the byte array has size 0; otherwise returns false.
Definition: qbytearray.h:421
bool compile(QDeclarativeEngine *, QDeclarativeTypeData *, QDeclarativeCompiledData *)
Compile unit, and store the output in out.
Property * getProperty(const QByteArray &name, bool create=true)
QTime time() const
Returns the time part of the datetime.
Definition: qdatetime.cpp:2368
const QList< ScriptReference > & resolvedScripts() const
int propertyOffset() const
Returns the property offset for this class; i.e.
bool buildPropertyLiteralAssignment(QDeclarativeParser::Property *prop, QDeclarativeParser::Object *obj, QDeclarativeParser::Value *value, const BindingContext &ctxt)
QRgb rgba() const
Returns the RGB value of the color, including its alpha.
Definition: qcolor.cpp:1019
AssignValueInterceptorInstruction assignValueInterceptor
void setWritable(bool value)
Sets this property to writable if value is true.
const QDeclarativeScriptParser & parser() const
QDeclarativeEnginePrivate * enginePrivate
char at(int i) const
Returns the character at index position i in the byte array.
Definition: qbytearray.h:413
QUrl resolved(const QUrl &relative) const
Returns the result of the merge of this URL with relative.
Definition: qurl.cpp:5819
void registerCompositeType(QDeclarativeCompiledData *)
virtual QByteArray compile(const QList< QDeclarativeCustomParserProperty > &)=0
bool buildScriptStringProperty(QDeclarativeParser::Property *prop, QDeclarativeParser::Object *obj, const BindingContext &ctxt)
QMetaMethodBuilder addSignal(const QByteArray &signature)
Adds a new signal to this class with the specified signature.
void setParameterNames(const QList< QByteArray > &value)
Sets the list of parameter names for this method to value.
int indexOfClassInfo(const char *name) const
Finds class information item name and returns its index; otherwise returns -1.
static qreal dot(const QPointF &a, const QPointF &b)
bool buildProperty(QDeclarativeParser::Property *prop, QDeclarativeParser::Object *obj, const BindingContext &)
#define Q_UNUSED(x)
Indicates to the compiler that the parameter with the specified name is not used in the body of a fun...
Definition: qglobal.h:1729
const QMetaObject * rawMetaObjectForType(int) const
StoreIntegerInstruction storeInteger
QTime Q_DECLARATIVE_PRIVATE_EXPORT timeFromString(const QString &, bool *ok=0)
static QByteArray number(int, int base=10)
Returns a byte array containing the string equivalent of the number n to base base (10 by default)...
bool compileAlias(QMetaObjectBuilder &, QByteArray &data, QDeclarativeParser::Object *obj, const QDeclarativeParser::Object::DynamicProperty &)
QDeclarativeParser::Object * object
const char * typeName() const
Returns the name of this property&#39;s type.
The QLatin1Char class provides an 8-bit ASCII/Latin-1 character.
Definition: qchar.h:55
QList< TypeReference > types
AssignValueSourceInstruction assignValueSource
const QChar * constData() const
Returns a pointer to the data stored in the QString.
Definition: qstring.h:712
QDeclarativeParser::Object * tree() const
virtual const QMetaObject * metaObject() const
Returns a pointer to the meta-object of this object.
bool buildBinding(QDeclarativeParser::Value *, QDeclarativeParser::Property *prop, const BindingContext &ctxt)
static QByteArray saveProperty(const QMetaObject *, int)
QList< QDeclarativeInstruction > bytecode
QMetaProperty property(int index) const
Returns the meta-data for the property with the given index.
QDate Q_DECLARATIVE_PRIVATE_EXPORT dateFromString(const QString &, bool *ok=0)
StoreStringInstruction storeString
AssignCustomTypeInstruction assignCustomType
int hour() const
Returns the hour part (0 to 23) of the time.
Definition: qdatetime.cpp:1578
bool isLetterOrNumber() const
Returns true if the character is a letter or number (Letter_* or Number_* categories); otherwise retu...
Definition: qchar.cpp:681
static bool equal(const QMetaObject *, const QMetaObject *)
Returns true if lhs and rhs refer to the same metaobject data.
bool endsWith(const QByteArray &a) const
Returns true if this byte array ends with byte array ba; otherwise returns false. ...
QVariant(* StringConverter)(const QString &)
bool buildPropertyAssignment(QDeclarativeParser::Property *prop, QDeclarativeParser::Object *obj, const BindingContext &ctxt)
QHash< QByteArray, Property * > properties
static QMetaProperty defaultProperty(const QMetaObject *)
StoreScriptStringInstruction storeScriptString
QVariant::Type type() const
Returns this property&#39;s type.
QHash< QDeclarativeParser::Object *, ComponentCompileState > savedCompileStates
void genObject(QDeclarativeParser::Object *obj)
static bool isSignalPropertyName(const QByteArray &)
Returns true if name refers to a signal property, false otherwise.