src/declarative/qml/qdeclarativecompiler.cpp
changeset 37 758a864f9613
parent 33 3e2da88830cd
equal deleted inserted replaced
36:ef0373b55136 37:758a864f9613
    39 **
    39 **
    40 ****************************************************************************/
    40 ****************************************************************************/
    41 
    41 
    42 #include "private/qdeclarativecompiler_p.h"
    42 #include "private/qdeclarativecompiler_p.h"
    43 
    43 
    44 #include "private/qdeclarativecompositetypedata_p.h"
       
    45 #include "private/qdeclarativeparser_p.h"
    44 #include "private/qdeclarativeparser_p.h"
    46 #include "private/qdeclarativescriptparser_p.h"
    45 #include "private/qdeclarativescriptparser_p.h"
    47 #include "qdeclarativepropertyvaluesource.h"
    46 #include "qdeclarativepropertyvaluesource.h"
    48 #include "qdeclarativecomponent.h"
    47 #include "qdeclarativecomponent.h"
    49 #include "private/qmetaobjectbuilder_p.h"
    48 #include "private/qmetaobjectbuilder_p.h"
   238             bool ok;
   237             bool ok;
   239             QDeclarativeStringConverters::colorFromString(string, &ok);
   238             QDeclarativeStringConverters::colorFromString(string, &ok);
   240             if (!ok) COMPILE_EXCEPTION(v, tr("Invalid property assignment: color expected"));
   239             if (!ok) COMPILE_EXCEPTION(v, tr("Invalid property assignment: color expected"));
   241             }
   240             }
   242             break;
   241             break;
   243 #ifndef QT_NO_TEXTDATE
   242 #ifndef QT_NO_DATESTRING
   244         case QVariant::Date:
   243         case QVariant::Date:
   245             {
   244             {
   246             bool ok;
   245             bool ok;
   247             QDeclarativeStringConverters::dateFromString(string, &ok);
   246             QDeclarativeStringConverters::dateFromString(string, &ok);
   248             if (!ok) COMPILE_EXCEPTION(v, tr("Invalid property assignment: date expected"));
   247             if (!ok) COMPILE_EXCEPTION(v, tr("Invalid property assignment: date expected"));
   260             bool ok;
   259             bool ok;
   261             QDeclarativeStringConverters::dateTimeFromString(string, &ok);
   260             QDeclarativeStringConverters::dateTimeFromString(string, &ok);
   262             if (!ok) COMPILE_EXCEPTION(v, tr("Invalid property assignment: datetime expected"));
   261             if (!ok) COMPILE_EXCEPTION(v, tr("Invalid property assignment: datetime expected"));
   263             }
   262             }
   264             break;
   263             break;
   265 #endif // QT_NO_TEXTDATE
   264 #endif // QT_NO_DATESTRING
   266         case QVariant::Point:
   265         case QVariant::Point:
   267         case QVariant::PointF:
   266         case QVariant::PointF:
   268             {
   267             {
   269             bool ok;
   268             bool ok;
   270             QPointF point = QDeclarativeStringConverters::pointFFromString(string, &ok);
   269             QPointF point = QDeclarativeStringConverters::pointFFromString(string, &ok);
   414             instr.type = QDeclarativeInstruction::StoreColor;
   413             instr.type = QDeclarativeInstruction::StoreColor;
   415             instr.storeColor.propertyIndex = prop.propertyIndex();
   414             instr.storeColor.propertyIndex = prop.propertyIndex();
   416             instr.storeColor.value = c.rgba();
   415             instr.storeColor.value = c.rgba();
   417             }
   416             }
   418             break;
   417             break;
   419 #ifndef QT_NO_TEXTDATE
   418 #ifndef QT_NO_DATESTRING
   420         case QVariant::Date:
   419         case QVariant::Date:
   421             {
   420             {
   422             QDate d = QDeclarativeStringConverters::dateFromString(string);
   421             QDate d = QDeclarativeStringConverters::dateFromString(string);
   423             instr.type = QDeclarativeInstruction::StoreDate;
   422             instr.type = QDeclarativeInstruction::StoreDate;
   424             instr.storeDate.propertyIndex = prop.propertyIndex();
   423             instr.storeDate.propertyIndex = prop.propertyIndex();
   448             instr.type = QDeclarativeInstruction::StoreDateTime;
   447             instr.type = QDeclarativeInstruction::StoreDateTime;
   449             instr.storeDateTime.propertyIndex = prop.propertyIndex();
   448             instr.storeDateTime.propertyIndex = prop.propertyIndex();
   450             instr.storeDateTime.valueIndex = index;
   449             instr.storeDateTime.valueIndex = index;
   451             }
   450             }
   452             break;
   451             break;
   453 #endif // QT_NO_TEXTDATE
   452 #endif // QT_NO_DATESTRING
   454         case QVariant::Point:
   453         case QVariant::Point:
   455         case QVariant::PointF:
   454         case QVariant::PointF:
   456             {
   455             {
   457             bool ok;
   456             bool ok;
   458             QPointF point =
   457             QPointF point =
   560     If the environment variant QML_COMPILER_DUMP is set
   559     If the environment variant QML_COMPILER_DUMP is set
   561     (eg. QML_COMPILER_DUMP=1) the compiled instructions will be dumped to stderr
   560     (eg. QML_COMPILER_DUMP=1) the compiled instructions will be dumped to stderr
   562     on a successful compiler.
   561     on a successful compiler.
   563 */
   562 */
   564 bool QDeclarativeCompiler::compile(QDeclarativeEngine *engine,
   563 bool QDeclarativeCompiler::compile(QDeclarativeEngine *engine,
   565                                    QDeclarativeCompositeTypeData *unit,
   564                                    QDeclarativeTypeData *unit,
   566                                    QDeclarativeCompiledData *out)
   565                                    QDeclarativeCompiledData *out)
   567 {
   566 {
   568     exceptions.clear();
   567     exceptions.clear();
   569 
   568 
   570     Q_ASSERT(out);
   569     Q_ASSERT(out);
   571     reset(out);
   570     reset(out);
   572 
   571 
   573     output = out;
   572     output = out;
   574 
   573 
   575     // Compile types
   574     // Compile types
   576     for (int ii = 0; ii < unit->types.count(); ++ii) {
   575     const QList<QDeclarativeTypeData::TypeReference>  &resolvedTypes = unit->resolvedTypes();
   577         QDeclarativeCompositeTypeData::TypeReference &tref = unit->types[ii];
   576     QList<QDeclarativeScriptParser::TypeReference *> referencedTypes = unit->parser().referencedTypes();
       
   577 
       
   578     for (int ii = 0; ii < resolvedTypes.count(); ++ii) {
   578         QDeclarativeCompiledData::TypeReference ref;
   579         QDeclarativeCompiledData::TypeReference ref;
   579         QDeclarativeScriptParser::TypeReference *parserRef = unit->data.referencedTypes().at(ii);
   580 
       
   581         const QDeclarativeTypeData::TypeReference &tref = resolvedTypes.at(ii);
       
   582         QDeclarativeScriptParser::TypeReference *parserRef = referencedTypes.at(ii);
       
   583 
   580         if (tref.type) {
   584         if (tref.type) {
   581             ref.type = tref.type;
   585             ref.type = tref.type;
   582             if (!ref.type->isCreatable()) {
   586             if (!ref.type->isCreatable()) {
   583                 QString err = ref.type->noCreationReason();
   587                 QString err = ref.type->noCreationReason();
   584                 if (err.isEmpty())
   588                 if (err.isEmpty())
   585                     err = tr( "Element is not creatable.");
   589                     err = tr( "Element is not creatable.");
   586                 COMPILE_EXCEPTION(parserRef->refObjects.first(), err);
   590                 COMPILE_EXCEPTION(parserRef->refObjects.first(), err);
   587             }
   591             }
   588         } else if (tref.unit) {
   592         } else if (tref.typeData) {
   589             ref.component = tref.unit->toComponent(engine);
   593             ref.component = tref.typeData->component();
   590 
   594             ref.ref = tref.typeData;
   591             if (ref.component->isError()) {
       
   592                 QDeclarativeError error;
       
   593                 error.setUrl(output->url);
       
   594                 error.setDescription(QLatin1String("Unable to create type ") +
       
   595                                      parserRef->name);
       
   596                 if (!parserRef->refObjects.isEmpty()) {
       
   597                     QDeclarativeParser::Object *parserObject = parserRef->refObjects.first();
       
   598                     error.setLine(parserObject->location.start.line);
       
   599                     error.setColumn(parserObject->location.start.column);
       
   600                 }
       
   601 
       
   602                 exceptions << error;
       
   603                 exceptions << ref.component->errors();
       
   604                 reset(out);
       
   605                 return false;
       
   606             }
       
   607             ref.ref = tref.unit;
       
   608             ref.ref->addref();
   595             ref.ref->addref();
   609         }
   596         }
   610         ref.className = parserRef->name.toUtf8();
   597         ref.className = parserRef->name.toUtf8();
   611         out->types << ref;
   598         out->types << ref;
   612     }
   599     }
   613 
   600 
   614     Object *root = unit->data.tree();
   601     Object *root = unit->parser().tree();
   615     Q_ASSERT(root);
   602     Q_ASSERT(root);
   616 
   603 
   617     this->engine = engine;
   604     this->engine = engine;
   618     this->enginePrivate = QDeclarativeEnginePrivate::get(engine);
   605     this->enginePrivate = QDeclarativeEnginePrivate::get(engine);
   619     this->unit = unit;
   606     this->unit = unit;
   662 
   649 
   663     // Build global import scripts
   650     // Build global import scripts
   664     QHash<QString, Object::ScriptBlock> importedScripts;
   651     QHash<QString, Object::ScriptBlock> importedScripts;
   665     QStringList importedScriptIndexes;
   652     QStringList importedScriptIndexes;
   666 
   653 
   667     for (int ii = 0; ii < unit->scripts.count(); ++ii) {
   654     foreach (const QDeclarativeTypeData::ScriptReference &script, unit->resolvedScripts()) {
   668         QString scriptCode = QString::fromUtf8(unit->scripts.at(ii).resource->data);
   655         QString scriptCode = script.script->scriptSource();
   669         Object::ScriptBlock::Pragmas pragmas = QDeclarativeScriptParser::extractPragmas(scriptCode);
   656         Object::ScriptBlock::Pragmas pragmas = script.script->pragmas();
       
   657 
       
   658         Q_ASSERT(!importedScripts.contains(script.qualifier));
   670 
   659 
   671         if (!scriptCode.isEmpty()) {
   660         if (!scriptCode.isEmpty()) {
   672             Object::ScriptBlock &scriptBlock = importedScripts[unit->scripts.at(ii).qualifier];
   661             Object::ScriptBlock &scriptBlock = importedScripts[script.qualifier];
   673 
   662 
   674             scriptBlock.codes.append(scriptCode);
   663             scriptBlock.code = scriptCode;
   675             scriptBlock.lineNumbers.append(1);
   664             scriptBlock.file = script.script->finalUrl().toString();
   676             scriptBlock.files.append(unit->scripts.at(ii).resource->url);
   665             scriptBlock.pragmas = pragmas;
   677             scriptBlock.pragmas.append(pragmas);
       
   678         }
   666         }
   679     }
   667     }
   680 
   668 
   681     for (QHash<QString, Object::ScriptBlock>::Iterator iter = importedScripts.begin(); 
   669     for (QHash<QString, Object::ScriptBlock>::Iterator iter = importedScripts.begin(); 
   682          iter != importedScripts.end(); ++iter) {
   670          iter != importedScripts.end(); ++iter) {
   701     output->importCache = new QDeclarativeTypeNameCache(engine);
   689     output->importCache = new QDeclarativeTypeNameCache(engine);
   702 
   690 
   703     for (int ii = 0; ii < importedScriptIndexes.count(); ++ii) 
   691     for (int ii = 0; ii < importedScriptIndexes.count(); ++ii) 
   704         output->importCache->add(importedScriptIndexes.at(ii), ii);
   692         output->importCache->add(importedScriptIndexes.at(ii), ii);
   705 
   693 
   706     unit->imports.cache(output->importCache, engine);
   694     unit->imports().populateCache(output->importCache, engine);
   707 
   695 
   708     Q_ASSERT(tree->metatype);
   696     Q_ASSERT(tree->metatype);
   709 
   697 
   710     if (tree->metadata.isEmpty()) {
   698     if (tree->metadata.isEmpty()) {
   711         output->root = tree->metatype;
   699         output->root = tree->metatype;
   984         id.setId.index = obj->idIndex;
   972         id.setId.index = obj->idIndex;
   985         output->bytecode << id;
   973         output->bytecode << id;
   986     }
   974     }
   987 
   975 
   988     // Begin the class
   976     // Begin the class
   989     if (obj->parserStatusCast != -1) {
   977     if (tr.type && obj->parserStatusCast != -1) {
   990         QDeclarativeInstruction begin;
   978         QDeclarativeInstruction begin;
   991         begin.type = QDeclarativeInstruction::BeginObject;
   979         begin.type = QDeclarativeInstruction::BeginObject;
   992         begin.begin.castValue = obj->parserStatusCast;
   980         begin.begin.castValue = obj->parserStatusCast;
   993         begin.line = obj->location.start.line;
   981         begin.line = obj->location.start.line;
   994         output->bytecode << begin;
   982         output->bytecode << begin;
  1068             store.line = v->location.start.line;
  1056             store.line = v->location.start.line;
  1069             store.storeSignal.signalIndex = prop->index;
  1057             store.storeSignal.signalIndex = prop->index;
  1070             store.storeSignal.value =
  1058             store.storeSignal.value =
  1071                 output->indexForString(v->value.asScript().trimmed());
  1059                 output->indexForString(v->value.asScript().trimmed());
  1072             store.storeSignal.context = ctxt.stack;
  1060             store.storeSignal.context = ctxt.stack;
       
  1061             store.storeSignal.name = output->indexForByteArray(prop->name);
  1073             output->bytecode << store;
  1062             output->bytecode << store;
  1074 
  1063 
  1075         }
  1064         }
  1076 
  1065 
  1077     }
  1066     }
  1371         if (prop->isDefault) {
  1360         if (prop->isDefault) {
  1372             QMetaProperty p = QDeclarativeMetaType::defaultProperty(mo);
  1361             QMetaProperty p = QDeclarativeMetaType::defaultProperty(mo);
  1373             return p.name() != 0;
  1362             return p.name() != 0;
  1374         } else {
  1363         } else {
  1375             int idx = mo->indexOfProperty(prop->name.constData());
  1364             int idx = mo->indexOfProperty(prop->name.constData());
  1376             return idx != -1;
  1365             return idx != -1 && mo->property(idx).isScriptable();
  1377         }
  1366         }
  1378     }
  1367     }
  1379 
  1368 
  1380     return false;
  1369     return false;
  1381 }
  1370 }
  1400             COMPILE_EXCEPTION(prop, tr("Attached properties cannot be used here"));
  1389             COMPILE_EXCEPTION(prop, tr("Attached properties cannot be used here"));
  1401         }
  1390         }
  1402 
  1391 
  1403         QDeclarativeType *type = 0;
  1392         QDeclarativeType *type = 0;
  1404         QDeclarativeImportedNamespace *typeNamespace = 0;
  1393         QDeclarativeImportedNamespace *typeNamespace = 0;
  1405         enginePrivate->importDatabase.resolveType(unit->imports, prop->name, 
  1394         unit->imports().resolveType(prop->name, &type, 0, 0, 0, &typeNamespace);
  1406                                                   &type, 0, 0, 0, &typeNamespace);
       
  1407 
  1395 
  1408         if (typeNamespace) {
  1396         if (typeNamespace) {
  1409             // ### We might need to indicate that this property is a namespace 
  1397             // ### We might need to indicate that this property is a namespace 
  1410             // for the DOM API
  1398             // for the DOM API
  1411             COMPILE_CHECK(buildPropertyInNamespace(typeNamespace, prop, obj, 
  1399             COMPILE_CHECK(buildPropertyInNamespace(typeNamespace, prop, obj, 
  1437             prop->index = metaObject->indexOfProperty(prop->name.constData());
  1425             prop->index = metaObject->indexOfProperty(prop->name.constData());
  1438 
  1426 
  1439             if (prop->index != -1) {
  1427             if (prop->index != -1) {
  1440                 p = metaObject->property(prop->index);
  1428                 p = metaObject->property(prop->index);
  1441                 Q_ASSERT(p.name());
  1429                 Q_ASSERT(p.name());
       
  1430 
       
  1431                 if (!p.isScriptable()) {
       
  1432                     prop->index = -1;
       
  1433                     p = QMetaProperty();
       
  1434                 }
  1442             }
  1435             }
  1443         }
  1436         }
  1444 
  1437 
  1445         // We can't error here as the "id" property does not require a
  1438         // We can't error here as the "id" property does not require a
  1446         // successful index resolution
  1439         // successful index resolution
  1509             COMPILE_EXCEPTION(prop, tr("Not an attached property name"));
  1502             COMPILE_EXCEPTION(prop, tr("Not an attached property name"));
  1510 
  1503 
  1511         // Setup attached property data
  1504         // Setup attached property data
  1512 
  1505 
  1513         QDeclarativeType *type = 0;
  1506         QDeclarativeType *type = 0;
  1514         enginePrivate->importDatabase.resolveTypeInNamespace(ns, prop->name, &type, 0, 0, 0);
  1507         unit->imports().resolveType(ns, prop->name, &type, 0, 0, 0);
  1515 
  1508 
  1516         if (!type || !type->attachedPropertiesType()) 
  1509         if (!type || !type->attachedPropertiesType()) 
  1517             COMPILE_EXCEPTION(prop, tr("Non-existent attached object"));
  1510             COMPILE_EXCEPTION(prop, tr("Non-existent attached object"));
  1518 
  1511 
  1519         if (!prop->value)
  1512         if (!prop->value)
  1769 {
  1762 {
  1770     Q_ASSERT(prop->type != 0);
  1763     Q_ASSERT(prop->type != 0);
  1771     Q_ASSERT(prop->index != -1);
  1764     Q_ASSERT(prop->index != -1);
  1772 
  1765 
  1773     if (QDeclarativeValueTypeFactory::isValueType(prop->type)) {
  1766     if (QDeclarativeValueTypeFactory::isValueType(prop->type)) {
  1774         QDeclarativeEnginePrivate *ep =
  1767         if (prop->type >= 0 /* QVariant == -1 */ && enginePrivate->valueTypes[prop->type]) {
  1775             static_cast<QDeclarativeEnginePrivate *>(QObjectPrivate::get(engine));
       
  1776         if (prop->type >= 0 /* QVariant == -1 */ && ep->valueTypes[prop->type]) {
       
  1777 
  1768 
  1778             if (prop->values.count()) {
  1769             if (prop->values.count()) {
  1779                 if (prop->values.at(0)->location < prop->value->location) {
  1770                 if (prop->values.at(0)->location < prop->value->location) {
  1780                     COMPILE_EXCEPTION(prop->value, tr( "Property has already been assigned a value"));
  1771                     COMPILE_EXCEPTION(prop->value, tr( "Property has already been assigned a value"));
  1781                 } else {
  1772                 } else {
  1785 
  1776 
  1786             if (!obj->metaObject()->property(prop->index).isWritable()) {
  1777             if (!obj->metaObject()->property(prop->index).isWritable()) {
  1787                 COMPILE_EXCEPTION(prop, tr( "Invalid property assignment: \"%1\" is a read-only property").arg(QString::fromUtf8(prop->name)));
  1778                 COMPILE_EXCEPTION(prop, tr( "Invalid property assignment: \"%1\" is a read-only property").arg(QString::fromUtf8(prop->name)));
  1788             }
  1779             }
  1789 
  1780 
  1790             COMPILE_CHECK(buildValueTypeProperty(ep->valueTypes[prop->type],
  1781             COMPILE_CHECK(buildValueTypeProperty(enginePrivate->valueTypes[prop->type],
  1791                                                  prop->value, obj, ctxt.incr()));
  1782                                                  prop->value, obj, ctxt.incr()));
  1792             obj->addValueTypeProperty(prop);
  1783             obj->addValueTypeProperty(prop);
  1793         } else {
  1784         } else {
  1794             COMPILE_EXCEPTION(prop, tr("Invalid grouped property access"));
  1785             COMPILE_EXCEPTION(prop, tr("Invalid grouped property access"));
  1795         }
  1786         }
  1823     foreach (Property *prop, obj->properties) {
  1814     foreach (Property *prop, obj->properties) {
  1824         int idx = type->metaObject()->indexOfProperty(prop->name.constData());
  1815         int idx = type->metaObject()->indexOfProperty(prop->name.constData());
  1825         if (idx == -1)
  1816         if (idx == -1)
  1826             COMPILE_EXCEPTION(prop, tr("Cannot assign to non-existent property \"%1\"").arg(QString::fromUtf8(prop->name)));
  1817             COMPILE_EXCEPTION(prop, tr("Cannot assign to non-existent property \"%1\"").arg(QString::fromUtf8(prop->name)));
  1827         QMetaProperty p = type->metaObject()->property(idx);
  1818         QMetaProperty p = type->metaObject()->property(idx);
       
  1819         if (!p.isScriptable())
       
  1820             COMPILE_EXCEPTION(prop, tr("Cannot assign to non-existent property \"%1\"").arg(QString::fromUtf8(prop->name)));
  1828         prop->index = idx;
  1821         prop->index = idx;
  1829         prop->type = p.userType();
  1822         prop->type = p.userType();
  1830         prop->isValueTypeSubProperty = true;
  1823         prop->isValueTypeSubProperty = true;
  1831 
  1824 
  1832         if (prop->value)
  1825         if (prop->value)
  2136     if (parts.count() != 2)
  2129     if (parts.count() != 2)
  2137         return true;
  2130         return true;
  2138 
  2131 
  2139     QString typeName = parts.at(0);
  2132     QString typeName = parts.at(0);
  2140     QDeclarativeType *type = 0;
  2133     QDeclarativeType *type = 0;
  2141     enginePrivate->importDatabase.resolveType(unit->imports, typeName.toUtf8(),
  2134     unit->imports().resolveType(typeName.toUtf8(), &type, 0, 0, 0, 0);
  2142                                               &type, 0, 0, 0, 0);
       
  2143 
  2135 
  2144     if (!type || obj->typeName != type->qmlTypeName())
  2136     if (!type || obj->typeName != type->qmlTypeName())
  2145         return true;
  2137         return true;
  2146 
  2138 
  2147     QString enumValue = parts.at(1);
  2139     QString enumValue = parts.at(1);
  2164 int QDeclarativeCompiler::evaluateEnum(const QByteArray& script) const
  2156 int QDeclarativeCompiler::evaluateEnum(const QByteArray& script) const
  2165 {
  2157 {
  2166     int dot = script.indexOf('.');
  2158     int dot = script.indexOf('.');
  2167     if (dot > 0) {
  2159     if (dot > 0) {
  2168         QDeclarativeType *type = 0;
  2160         QDeclarativeType *type = 0;
  2169         enginePrivate->importDatabase.resolveType(unit->imports, script.left(dot), &type, 0, 0, 0, 0);
  2161         unit->imports().resolveType(script.left(dot), &type, 0, 0, 0, 0);
  2170         if (!type)
  2162         if (!type)
  2171             return -1;
  2163             return -1;
  2172         const QMetaObject *mo = type->metaObject();
  2164         const QMetaObject *mo = type->metaObject();
  2173         const char *key = script.constData() + dot+1;
  2165         const char *key = script.constData() + dot+1;
  2174         int i = mo->enumeratorCount();
  2166         int i = mo->enumeratorCount();
  2182 }
  2174 }
  2183 
  2175 
  2184 const QMetaObject *QDeclarativeCompiler::resolveType(const QByteArray& name) const
  2176 const QMetaObject *QDeclarativeCompiler::resolveType(const QByteArray& name) const
  2185 {
  2177 {
  2186     QDeclarativeType *qmltype = 0;
  2178     QDeclarativeType *qmltype = 0;
  2187     if (!enginePrivate->importDatabase.resolveType(unit->imports, name, &qmltype, 
  2179     if (!unit->imports().resolveType(name, &qmltype, 0, 0, 0, 0)) 
  2188                                                    0, 0, 0, 0)) 
       
  2189         return 0;
  2180         return 0;
  2190     if (!qmltype)
  2181     if (!qmltype)
  2191         return 0;
  2182         return 0;
  2192     return qmltype->metaObject();
  2183     return qmltype->metaObject();
  2193 }
  2184 }
  2212         }
  2203         }
  2213 
  2204 
  2214         if (propNames.contains(prop.name))
  2205         if (propNames.contains(prop.name))
  2215             COMPILE_EXCEPTION(&prop, tr("Duplicate property name"));
  2206             COMPILE_EXCEPTION(&prop, tr("Duplicate property name"));
  2216 
  2207 
  2217         if (QString::fromUtf8(prop.name).at(0).isUpper()) 
  2208         QString propName = QString::fromUtf8(prop.name);
       
  2209         if (propName.at(0).isUpper())
  2218             COMPILE_EXCEPTION(&prop, tr("Property names cannot begin with an upper case letter"));
  2210             COMPILE_EXCEPTION(&prop, tr("Property names cannot begin with an upper case letter"));
  2219 
  2211 
  2220         if (QDeclarativeEnginePrivate::get(engine)->globalClass->illegalNames().contains(prop.name))
  2212         if (enginePrivate->globalClass->illegalNames().contains(propName))
  2221             COMPILE_EXCEPTION(&prop, tr("Illegal property name"));
  2213             COMPILE_EXCEPTION(&prop, tr("Illegal property name"));
  2222 
  2214 
  2223         propNames.insert(prop.name);
  2215         propNames.insert(prop.name);
  2224     }
  2216     }
  2225 
  2217 
  2226     for (int ii = 0; ii < obj->dynamicSignals.count(); ++ii) {
  2218     for (int ii = 0; ii < obj->dynamicSignals.count(); ++ii) {
  2227         QByteArray name = obj->dynamicSignals.at(ii).name;
  2219         QByteArray name = obj->dynamicSignals.at(ii).name;
  2228         if (methodNames.contains(name))
  2220         if (methodNames.contains(name))
  2229             COMPILE_EXCEPTION(obj, tr("Duplicate signal name"));
  2221             COMPILE_EXCEPTION(obj, tr("Duplicate signal name"));
  2230         if (QString::fromUtf8(name).at(0).isUpper()) 
  2222         QString nameStr = QString::fromUtf8(name);
       
  2223         if (nameStr.at(0).isUpper())
  2231             COMPILE_EXCEPTION(obj, tr("Signal names cannot begin with an upper case letter"));
  2224             COMPILE_EXCEPTION(obj, tr("Signal names cannot begin with an upper case letter"));
  2232         if (QDeclarativeEnginePrivate::get(engine)->globalClass->illegalNames().contains(name))
  2225         if (enginePrivate->globalClass->illegalNames().contains(nameStr))
  2233             COMPILE_EXCEPTION(obj, tr("Illegal signal name"));
  2226             COMPILE_EXCEPTION(obj, tr("Illegal signal name"));
  2234         methodNames.insert(name);
  2227         methodNames.insert(name);
  2235     }
  2228     }
  2236     for (int ii = 0; ii < obj->dynamicSlots.count(); ++ii) {
  2229     for (int ii = 0; ii < obj->dynamicSlots.count(); ++ii) {
  2237         QByteArray name = obj->dynamicSlots.at(ii).name;
  2230         QByteArray name = obj->dynamicSlots.at(ii).name;
  2238         if (methodNames.contains(name))
  2231         if (methodNames.contains(name))
  2239             COMPILE_EXCEPTION(obj, tr("Duplicate method name"));
  2232             COMPILE_EXCEPTION(obj, tr("Duplicate method name"));
  2240         if (QString::fromUtf8(name).at(0).isUpper()) 
  2233         QString nameStr = QString::fromUtf8(name);
       
  2234         if (nameStr.at(0).isUpper())
  2241             COMPILE_EXCEPTION(obj, tr("Method names cannot begin with an upper case letter"));
  2235             COMPILE_EXCEPTION(obj, tr("Method names cannot begin with an upper case letter"));
  2242         if (QDeclarativeEnginePrivate::get(engine)->globalClass->illegalNames().contains(name))
  2236         if (enginePrivate->globalClass->illegalNames().contains(nameStr))
  2243             COMPILE_EXCEPTION(obj, tr("Illegal method name"));
  2237             COMPILE_EXCEPTION(obj, tr("Illegal method name"));
  2244         methodNames.insert(name);
  2238         methodNames.insert(name);
  2245     }
  2239     }
  2246 
  2240 
  2247     return true;
  2241     return true;
  2338         case Object::DynamicProperty::Custom:
  2332         case Object::DynamicProperty::Custom:
  2339             {
  2333             {
  2340                 QByteArray customTypeName;
  2334                 QByteArray customTypeName;
  2341                 QDeclarativeType *qmltype = 0;
  2335                 QDeclarativeType *qmltype = 0;
  2342                 QUrl url;
  2336                 QUrl url;
  2343                 if (!enginePrivate->importDatabase.resolveType(unit->imports, p.customType, &qmltype, 
  2337                 if (!unit->imports().resolveType(p.customType, &qmltype, &url, 0, 0, 0)) 
  2344                                                                &url, 0, 0, 0)) 
       
  2345                     COMPILE_EXCEPTION(&p, tr("Invalid property type"));
  2338                     COMPILE_EXCEPTION(&p, tr("Invalid property type"));
  2346 
  2339 
  2347                 if (!qmltype) {
  2340                 if (!qmltype) {
  2348                     QDeclarativeCompositeTypeData *tdata = enginePrivate->typeManager.get(url);
  2341                     QDeclarativeTypeData *tdata = enginePrivate->typeLoader.get(url);
  2349                     Q_ASSERT(tdata);
  2342                     Q_ASSERT(tdata);
  2350                     Q_ASSERT(tdata->status == QDeclarativeCompositeTypeData::Complete);
  2343                     Q_ASSERT(tdata->isComplete());
  2351 
  2344 
  2352                     QDeclarativeCompiledData *data = tdata->toCompiledComponent(engine);
  2345                     QDeclarativeCompiledData *data = tdata->compiledData();
  2353                     customTypeName = data->root->className();
  2346                     customTypeName = data->root->className();
       
  2347                     data->release();
       
  2348                     tdata->release();
  2354                 } else {
  2349                 } else {
  2355                     customTypeName = qmltype->typeName();
  2350                     customTypeName = qmltype->typeName();
  2356                 }
  2351                 }
  2357 
  2352 
  2358                 if (p.type == Object::DynamicProperty::Custom) {
  2353                 if (p.type == Object::DynamicProperty::Custom) {
  2414         dynamicData.append((char *)&propertyData, sizeof(propertyData));
  2409         dynamicData.append((char *)&propertyData, sizeof(propertyData));
  2415 
  2410 
  2416         builder.addSignal(p.name + "Changed()");
  2411         builder.addSignal(p.name + "Changed()");
  2417         QMetaPropertyBuilder propBuilder = 
  2412         QMetaPropertyBuilder propBuilder = 
  2418             builder.addProperty(p.name, type, builder.methodCount() - 1);
  2413             builder.addProperty(p.name, type, builder.methodCount() - 1);
  2419         propBuilder.setScriptable(true);
       
  2420         propBuilder.setWritable(!readonly);
  2414         propBuilder.setWritable(!readonly);
  2421     }
  2415     }
  2422 
  2416 
  2423     if (mode == ResolveAliases) {
  2417     for (int ii = 0; ii < obj->dynamicProperties.count(); ++ii) {
  2424         for (int ii = 0; ii < obj->dynamicProperties.count(); ++ii) {
  2418         const Object::DynamicProperty &p = obj->dynamicProperties.at(ii);
  2425             const Object::DynamicProperty &p = obj->dynamicProperties.at(ii);
  2419 
  2426 
  2420         if (p.type == Object::DynamicProperty::Alias) {
  2427             if (p.type == Object::DynamicProperty::Alias) {
  2421             if (mode == ResolveAliases) {
  2428                 ((QDeclarativeVMEMetaData *)dynamicData.data())->aliasCount++;
  2422                 ((QDeclarativeVMEMetaData *)dynamicData.data())->aliasCount++;
  2429                 compileAlias(builder, dynamicData, obj, p);
  2423                 compileAlias(builder, dynamicData, obj, p);
       
  2424             } else {
       
  2425                 // Need a fake signal so that the metaobject remains consistent across
       
  2426                 // the resolve and non-resolve alias runs
       
  2427                 builder.addSignal(p.name + "Changed()");
  2430             }
  2428             }
  2431         }
  2429         }
  2432     }
  2430     }
  2433 
  2431 
  2434     for (int ii = 0; ii < obj->dynamicSignals.count(); ++ii) {
  2432     for (int ii = 0; ii < obj->dynamicSignals.count(); ++ii) {
  2580 
  2578 
  2581         if (-1 == propIdx)
  2579         if (-1 == propIdx)
  2582             COMPILE_EXCEPTION(prop.defaultValue, tr("Invalid alias location"));
  2580             COMPILE_EXCEPTION(prop.defaultValue, tr("Invalid alias location"));
  2583 
  2581 
  2584         QMetaProperty aliasProperty = idObject->metaObject()->property(propIdx);
  2582         QMetaProperty aliasProperty = idObject->metaObject()->property(propIdx);
       
  2583         if (!aliasProperty.isScriptable())
       
  2584             COMPILE_EXCEPTION(prop.defaultValue, tr("Invalid alias location"));
       
  2585 
  2585         writable = aliasProperty.isWritable();
  2586         writable = aliasProperty.isWritable();
  2586 
  2587 
  2587         if (aliasProperty.isEnumType()) 
  2588         if (aliasProperty.isEnumType()) 
  2588             typeName = "int";  // Avoid introducing a dependency on the aliased metaobject
  2589             typeName = "int";  // Avoid introducing a dependency on the aliased metaobject
  2589         else
  2590         else
  2616     data.append((const char *)&flags, sizeof(flags));
  2617     data.append((const char *)&flags, sizeof(flags));
  2617 
  2618 
  2618     builder.addSignal(prop.name + "Changed()");
  2619     builder.addSignal(prop.name + "Changed()");
  2619     QMetaPropertyBuilder propBuilder = 
  2620     QMetaPropertyBuilder propBuilder = 
  2620         builder.addProperty(prop.name, typeName.constData(), builder.methodCount() - 1);
  2621         builder.addProperty(prop.name, typeName.constData(), builder.methodCount() - 1);
  2621     propBuilder.setScriptable(true);
       
  2622     propBuilder.setWritable(writable);
  2622     propBuilder.setWritable(writable);
  2623     return true;
  2623     return true;
  2624 }
  2624 }
  2625 
  2625 
  2626 bool QDeclarativeCompiler::buildBinding(QDeclarativeParser::Value *value,
  2626 bool QDeclarativeCompiler::buildBinding(QDeclarativeParser::Value *value,
  2743         BindingReference &binding = *iter;
  2743         BindingReference &binding = *iter;
  2744 
  2744 
  2745         expr.context = binding.bindingContext.object;
  2745         expr.context = binding.bindingContext.object;
  2746         expr.property = binding.property;
  2746         expr.property = binding.property;
  2747         expr.expression = binding.expression;
  2747         expr.expression = binding.expression;
  2748         expr.imports = unit->imports;
  2748         expr.imports = unit->imports();
  2749 
  2749 
  2750         int index = bindingCompiler.compile(expr, enginePrivate);
  2750         int index = bindingCompiler.compile(expr, enginePrivate);
  2751         if (index != -1) {
  2751         if (index != -1) {
  2752             binding.dataType = BindingReference::Experimental;
  2752             binding.dataType = BindingReference::Experimental;
  2753             binding.compiledIndex = index;
  2753             binding.compiledIndex = index;
  2763         // ### Optimize
  2763         // ### Optimize
  2764         QDeclarativeRewrite::SharedBindingTester sharableTest;
  2764         QDeclarativeRewrite::SharedBindingTester sharableTest;
  2765         bool isSharable = sharableTest.isSharable(expression);
  2765         bool isSharable = sharableTest.isSharable(expression);
  2766         
  2766         
  2767         QDeclarativeRewrite::RewriteBinding rewriteBinding;
  2767         QDeclarativeRewrite::RewriteBinding rewriteBinding;
       
  2768         rewriteBinding.setName('$'+binding.property->name);
  2768         expression = rewriteBinding(expression);
  2769         expression = rewriteBinding(expression);
  2769 
  2770 
  2770         quint32 length = expression.length();
  2771         quint32 length = expression.length();
  2771         quint32 pc; 
  2772         quint32 pc; 
  2772         
  2773