226 } |
226 } |
227 if (!ok) COMPILE_EXCEPTION(v, tr("Invalid property assignment: int expected")); |
227 if (!ok) COMPILE_EXCEPTION(v, tr("Invalid property assignment: int expected")); |
228 } |
228 } |
229 break; |
229 break; |
230 case QMetaType::Float: |
230 case QMetaType::Float: |
231 if (!v->value.isNumber()) COMPILE_EXCEPTION(v, tr("Invalid property assignment: float expected")); |
231 if (!v->value.isNumber()) COMPILE_EXCEPTION(v, tr("Invalid property assignment: number expected")); |
232 break; |
232 break; |
233 case QVariant::Double: |
233 case QVariant::Double: |
234 if (!v->value.isNumber()) COMPILE_EXCEPTION(v, tr("Invalid property assignment: double expected")); |
234 if (!v->value.isNumber()) COMPILE_EXCEPTION(v, tr("Invalid property assignment: number expected")); |
235 break; |
235 break; |
236 case QVariant::Color: |
236 case QVariant::Color: |
237 { |
237 { |
238 bool ok; |
238 bool ok; |
239 QDeclarativeStringConverters::colorFromString(string, &ok); |
239 QDeclarativeStringConverters::colorFromString(string, &ok); |
240 if (!ok) COMPILE_EXCEPTION(v, tr("Invalid property assignment: color expected")); |
240 if (!ok) COMPILE_EXCEPTION(v, tr("Invalid property assignment: color expected")); |
241 } |
241 } |
242 break; |
242 break; |
|
243 #ifndef QT_NO_TEXTDATE |
243 case QVariant::Date: |
244 case QVariant::Date: |
244 { |
245 { |
245 bool ok; |
246 bool ok; |
246 QDeclarativeStringConverters::dateFromString(string, &ok); |
247 QDeclarativeStringConverters::dateFromString(string, &ok); |
247 if (!ok) COMPILE_EXCEPTION(v, tr("Invalid property assignment: date expected")); |
248 if (!ok) COMPILE_EXCEPTION(v, tr("Invalid property assignment: date expected")); |
259 bool ok; |
260 bool ok; |
260 QDeclarativeStringConverters::dateTimeFromString(string, &ok); |
261 QDeclarativeStringConverters::dateTimeFromString(string, &ok); |
261 if (!ok) COMPILE_EXCEPTION(v, tr("Invalid property assignment: datetime expected")); |
262 if (!ok) COMPILE_EXCEPTION(v, tr("Invalid property assignment: datetime expected")); |
262 } |
263 } |
263 break; |
264 break; |
|
265 #endif // QT_NO_TEXTDATE |
264 case QVariant::Point: |
266 case QVariant::Point: |
265 case QVariant::PointF: |
267 case QVariant::PointF: |
266 { |
268 { |
267 bool ok; |
269 bool ok; |
268 QPointF point = QDeclarativeStringConverters::pointFFromString(string, &ok); |
270 QPointF point = QDeclarativeStringConverters::pointFFromString(string, &ok); |
412 instr.type = QDeclarativeInstruction::StoreColor; |
414 instr.type = QDeclarativeInstruction::StoreColor; |
413 instr.storeColor.propertyIndex = prop.propertyIndex(); |
415 instr.storeColor.propertyIndex = prop.propertyIndex(); |
414 instr.storeColor.value = c.rgba(); |
416 instr.storeColor.value = c.rgba(); |
415 } |
417 } |
416 break; |
418 break; |
|
419 #ifndef QT_NO_TEXTDATE |
417 case QVariant::Date: |
420 case QVariant::Date: |
418 { |
421 { |
419 QDate d = QDeclarativeStringConverters::dateFromString(string); |
422 QDate d = QDeclarativeStringConverters::dateFromString(string); |
420 instr.type = QDeclarativeInstruction::StoreDate; |
423 instr.type = QDeclarativeInstruction::StoreDate; |
421 instr.storeDate.propertyIndex = prop.propertyIndex(); |
424 instr.storeDate.propertyIndex = prop.propertyIndex(); |
445 instr.type = QDeclarativeInstruction::StoreDateTime; |
448 instr.type = QDeclarativeInstruction::StoreDateTime; |
446 instr.storeDateTime.propertyIndex = prop.propertyIndex(); |
449 instr.storeDateTime.propertyIndex = prop.propertyIndex(); |
447 instr.storeDateTime.valueIndex = index; |
450 instr.storeDateTime.valueIndex = index; |
448 } |
451 } |
449 break; |
452 break; |
|
453 #endif // QT_NO_TEXTDATE |
450 case QVariant::Point: |
454 case QVariant::Point: |
451 case QVariant::PointF: |
455 case QVariant::PointF: |
452 { |
456 { |
453 bool ok; |
457 bool ok; |
454 QPointF point = |
458 QPointF point = |
809 defaultProperty = obj->defaultProperty; |
813 defaultProperty = obj->defaultProperty; |
810 defaultProperty->addref(); |
814 defaultProperty->addref(); |
811 } |
815 } |
812 } |
816 } |
813 |
817 |
|
818 QDeclarativeCustomParser *cp = 0; |
|
819 if (isCustomParser) |
|
820 cp = output->types.at(obj->type).type->customParser(); |
|
821 |
814 // Build all explicit properties specified |
822 // Build all explicit properties specified |
815 foreach(Property *prop, obj->properties) { |
823 foreach(Property *prop, obj->properties) { |
816 |
824 |
817 if (prop == skipProperty) |
825 if (prop == skipProperty) |
818 continue; |
826 continue; |
819 if (prop->name == "id") |
827 if (prop->name == "id") |
820 continue; |
828 continue; |
|
829 |
|
830 bool canDefer = false; |
|
831 if (isCustomParser) { |
|
832 if (doesPropertyExist(prop, obj) && |
|
833 (!(cp->flags() & QDeclarativeCustomParser::AcceptsAttachedProperties) || |
|
834 !isAttachedPropertyName(prop->name))) { |
|
835 int ids = compileState.ids.count(); |
|
836 COMPILE_CHECK(buildProperty(prop, obj, objCtxt)); |
|
837 canDefer = ids == compileState.ids.count(); |
|
838 } else { |
|
839 customProps << QDeclarativeCustomParserNodePrivate::fromProperty(prop); |
|
840 } |
|
841 } else { |
|
842 if (isSignalPropertyName(prop->name)) { |
|
843 COMPILE_CHECK(buildSignal(prop,obj,objCtxt)); |
|
844 } else { |
|
845 int ids = compileState.ids.count(); |
|
846 COMPILE_CHECK(buildProperty(prop, obj, objCtxt)); |
|
847 canDefer = ids == compileState.ids.count(); |
|
848 } |
|
849 } |
|
850 |
|
851 if (canDefer && !deferredList.isEmpty() && |
|
852 deferredList.contains(QString::fromUtf8(prop->name))) |
|
853 prop->isDeferred = true; |
|
854 |
|
855 } |
|
856 |
|
857 // Build the default property |
|
858 if (defaultProperty) { |
|
859 Property *prop = defaultProperty; |
821 |
860 |
822 bool canDefer = false; |
861 bool canDefer = false; |
823 if (isCustomParser) { |
862 if (isCustomParser) { |
824 if (doesPropertyExist(prop, obj)) { |
863 if (doesPropertyExist(prop, obj)) { |
825 int ids = compileState.ids.count(); |
864 int ids = compileState.ids.count(); |
827 canDefer = ids == compileState.ids.count(); |
866 canDefer = ids == compileState.ids.count(); |
828 } else { |
867 } else { |
829 customProps << QDeclarativeCustomParserNodePrivate::fromProperty(prop); |
868 customProps << QDeclarativeCustomParserNodePrivate::fromProperty(prop); |
830 } |
869 } |
831 } else { |
870 } else { |
832 if (isSignalPropertyName(prop->name)) { |
871 int ids = compileState.ids.count(); |
833 COMPILE_CHECK(buildSignal(prop,obj,objCtxt)); |
872 COMPILE_CHECK(buildProperty(prop, obj, objCtxt)); |
834 } else { |
873 canDefer = ids == compileState.ids.count(); |
835 int ids = compileState.ids.count(); |
|
836 COMPILE_CHECK(buildProperty(prop, obj, objCtxt)); |
|
837 canDefer = ids == compileState.ids.count(); |
|
838 } |
|
839 } |
874 } |
840 |
875 |
841 if (canDefer && !deferredList.isEmpty() && |
876 if (canDefer && !deferredList.isEmpty() && |
842 deferredList.contains(QString::fromUtf8(prop->name))) |
877 deferredList.contains(QString::fromUtf8(prop->name))) |
843 prop->isDeferred = true; |
878 prop->isDeferred = true; |
844 |
|
845 } |
|
846 |
|
847 // Build the default property |
|
848 if (defaultProperty) { |
|
849 Property *prop = defaultProperty; |
|
850 |
|
851 bool canDefer = false; |
|
852 if (isCustomParser) { |
|
853 if (doesPropertyExist(prop, obj)) { |
|
854 int ids = compileState.ids.count(); |
|
855 COMPILE_CHECK(buildProperty(prop, obj, objCtxt)); |
|
856 canDefer = ids == compileState.ids.count(); |
|
857 } else { |
|
858 customProps << QDeclarativeCustomParserNodePrivate::fromProperty(prop); |
|
859 } |
|
860 } else { |
|
861 int ids = compileState.ids.count(); |
|
862 COMPILE_CHECK(buildProperty(prop, obj, objCtxt)); |
|
863 canDefer = ids == compileState.ids.count(); |
|
864 } |
|
865 |
|
866 if (canDefer && !deferredList.isEmpty() && |
|
867 deferredList.contains(QString::fromUtf8(prop->name))) |
|
868 prop->isDeferred = true; |
|
869 } |
879 } |
870 |
880 |
871 if (defaultProperty) |
881 if (defaultProperty) |
872 defaultProperty->release(); |
882 defaultProperty->release(); |
873 |
883 |
874 // Compile custom parser parts |
884 // Compile custom parser parts |
875 if (isCustomParser/* && !customProps.isEmpty()*/) { |
885 if (isCustomParser && !customProps.isEmpty()) { |
876 QDeclarativeCustomParser *cp = output->types.at(obj->type).type->customParser(); |
|
877 cp->clearErrors(); |
886 cp->clearErrors(); |
878 cp->compiler = this; |
887 cp->compiler = this; |
879 cp->object = obj; |
888 cp->object = obj; |
880 obj->custom = cp->compile(customProps); |
889 obj->custom = cp->compile(customProps); |
881 cp->compiler = 0; |
890 cp->compiler = 0; |
1350 |
1359 |
1351 /*! |
1360 /*! |
1352 Returns true if (value) property \a prop exists on obj, false otherwise. |
1361 Returns true if (value) property \a prop exists on obj, false otherwise. |
1353 */ |
1362 */ |
1354 bool QDeclarativeCompiler::doesPropertyExist(QDeclarativeParser::Property *prop, |
1363 bool QDeclarativeCompiler::doesPropertyExist(QDeclarativeParser::Property *prop, |
1355 QDeclarativeParser::Object *obj) |
1364 QDeclarativeParser::Object *obj) |
1356 { |
1365 { |
1357 if(isAttachedPropertyName(prop->name) || prop->name == "id") |
1366 if(isAttachedPropertyName(prop->name) || prop->name == "id") |
1358 return true; |
1367 return true; |
1359 |
1368 |
1360 const QMetaObject *mo = obj->metaObject(); |
1369 const QMetaObject *mo = obj->metaObject(); |
2170 } |
2179 } |
2171 } |
2180 } |
2172 return -1; |
2181 return -1; |
2173 } |
2182 } |
2174 |
2183 |
|
2184 const QMetaObject *QDeclarativeCompiler::resolveType(const QByteArray& name) const |
|
2185 { |
|
2186 QDeclarativeType *qmltype = 0; |
|
2187 if (!enginePrivate->importDatabase.resolveType(unit->imports, name, &qmltype, |
|
2188 0, 0, 0, 0)) |
|
2189 return 0; |
|
2190 if (!qmltype) |
|
2191 return 0; |
|
2192 return qmltype->metaObject(); |
|
2193 } |
|
2194 |
|
2195 |
2175 // Ensures that the dynamic meta specification on obj is valid |
2196 // Ensures that the dynamic meta specification on obj is valid |
2176 bool QDeclarativeCompiler::checkDynamicMeta(QDeclarativeParser::Object *obj) |
2197 bool QDeclarativeCompiler::checkDynamicMeta(QDeclarativeParser::Object *obj) |
2177 { |
2198 { |
2178 QSet<QByteArray> propNames; |
2199 QSet<QByteArray> propNames; |
2179 QSet<QByteArray> methodNames; |
2200 QSet<QByteArray> methodNames; |
2193 if (propNames.contains(prop.name)) |
2214 if (propNames.contains(prop.name)) |
2194 COMPILE_EXCEPTION(&prop, tr("Duplicate property name")); |
2215 COMPILE_EXCEPTION(&prop, tr("Duplicate property name")); |
2195 |
2216 |
2196 if (QString::fromUtf8(prop.name).at(0).isUpper()) |
2217 if (QString::fromUtf8(prop.name).at(0).isUpper()) |
2197 COMPILE_EXCEPTION(&prop, tr("Property names cannot begin with an upper case letter")); |
2218 COMPILE_EXCEPTION(&prop, tr("Property names cannot begin with an upper case letter")); |
|
2219 |
|
2220 if (QDeclarativeEnginePrivate::get(engine)->globalClass->illegalNames().contains(prop.name)) |
|
2221 COMPILE_EXCEPTION(&prop, tr("Illegal property name")); |
|
2222 |
2198 propNames.insert(prop.name); |
2223 propNames.insert(prop.name); |
2199 } |
2224 } |
2200 |
2225 |
2201 for (int ii = 0; ii < obj->dynamicSignals.count(); ++ii) { |
2226 for (int ii = 0; ii < obj->dynamicSignals.count(); ++ii) { |
2202 QByteArray name = obj->dynamicSignals.at(ii).name; |
2227 QByteArray name = obj->dynamicSignals.at(ii).name; |
2203 if (methodNames.contains(name)) |
2228 if (methodNames.contains(name)) |
2204 COMPILE_EXCEPTION(obj, tr("Duplicate signal name")); |
2229 COMPILE_EXCEPTION(obj, tr("Duplicate signal name")); |
2205 if (QString::fromUtf8(name).at(0).isUpper()) |
2230 if (QString::fromUtf8(name).at(0).isUpper()) |
2206 COMPILE_EXCEPTION(obj, tr("Signal names cannot begin with an upper case letter")); |
2231 COMPILE_EXCEPTION(obj, tr("Signal names cannot begin with an upper case letter")); |
|
2232 if (QDeclarativeEnginePrivate::get(engine)->globalClass->illegalNames().contains(name)) |
|
2233 COMPILE_EXCEPTION(obj, tr("Illegal signal name")); |
2207 methodNames.insert(name); |
2234 methodNames.insert(name); |
2208 } |
2235 } |
2209 for (int ii = 0; ii < obj->dynamicSlots.count(); ++ii) { |
2236 for (int ii = 0; ii < obj->dynamicSlots.count(); ++ii) { |
2210 QByteArray name = obj->dynamicSlots.at(ii).name; |
2237 QByteArray name = obj->dynamicSlots.at(ii).name; |
2211 if (methodNames.contains(name)) |
2238 if (methodNames.contains(name)) |
2212 COMPILE_EXCEPTION(obj, tr("Duplicate method name")); |
2239 COMPILE_EXCEPTION(obj, tr("Duplicate method name")); |
2213 if (QString::fromUtf8(name).at(0).isUpper()) |
2240 if (QString::fromUtf8(name).at(0).isUpper()) |
2214 COMPILE_EXCEPTION(obj, tr("Method names cannot begin with an upper case letter")); |
2241 COMPILE_EXCEPTION(obj, tr("Method names cannot begin with an upper case letter")); |
|
2242 if (QDeclarativeEnginePrivate::get(engine)->globalClass->illegalNames().contains(name)) |
|
2243 COMPILE_EXCEPTION(obj, tr("Illegal method name")); |
2215 methodNames.insert(name); |
2244 methodNames.insert(name); |
2216 } |
2245 } |
2217 |
2246 |
2218 return true; |
2247 return true; |
2219 } |
2248 } |
2418 QStringList funcScripts; |
2447 QStringList funcScripts; |
2419 |
2448 |
2420 for (int ii = 0; ii < obj->dynamicSlots.count(); ++ii) { |
2449 for (int ii = 0; ii < obj->dynamicSlots.count(); ++ii) { |
2421 Object::DynamicSlot &s = obj->dynamicSlots[ii]; |
2450 Object::DynamicSlot &s = obj->dynamicSlots[ii]; |
2422 QByteArray sig(s.name + '('); |
2451 QByteArray sig(s.name + '('); |
2423 QString funcScript(QLatin1String("(function(")); |
2452 QString funcScript(QLatin1String("(function ") + s.name + QLatin1Char('(')); |
2424 |
2453 |
2425 for (int jj = 0; jj < s.parameterNames.count(); ++jj) { |
2454 for (int jj = 0; jj < s.parameterNames.count(); ++jj) { |
2426 if (jj) { |
2455 if (jj) { |
2427 sig.append(','); |
2456 sig.append(','); |
2428 funcScript.append(QLatin1Char(',')); |
2457 funcScript.append(QLatin1Char(',')); |