--- a/src/declarative/qml/qdeclarativecompiler.cpp Fri Sep 17 08:34:18 2010 +0300
+++ b/src/declarative/qml/qdeclarativecompiler.cpp Mon Oct 04 01:19:32 2010 +0300
@@ -41,7 +41,6 @@
#include "private/qdeclarativecompiler_p.h"
-#include "private/qdeclarativecompositetypedata_p.h"
#include "private/qdeclarativeparser_p.h"
#include "private/qdeclarativescriptparser_p.h"
#include "qdeclarativepropertyvaluesource.h"
@@ -240,7 +239,7 @@
if (!ok) COMPILE_EXCEPTION(v, tr("Invalid property assignment: color expected"));
}
break;
-#ifndef QT_NO_TEXTDATE
+#ifndef QT_NO_DATESTRING
case QVariant::Date:
{
bool ok;
@@ -262,7 +261,7 @@
if (!ok) COMPILE_EXCEPTION(v, tr("Invalid property assignment: datetime expected"));
}
break;
-#endif // QT_NO_TEXTDATE
+#endif // QT_NO_DATESTRING
case QVariant::Point:
case QVariant::PointF:
{
@@ -416,7 +415,7 @@
instr.storeColor.value = c.rgba();
}
break;
-#ifndef QT_NO_TEXTDATE
+#ifndef QT_NO_DATESTRING
case QVariant::Date:
{
QDate d = QDeclarativeStringConverters::dateFromString(string);
@@ -450,7 +449,7 @@
instr.storeDateTime.valueIndex = index;
}
break;
-#endif // QT_NO_TEXTDATE
+#endif // QT_NO_DATESTRING
case QVariant::Point:
case QVariant::PointF:
{
@@ -562,7 +561,7 @@
on a successful compiler.
*/
bool QDeclarativeCompiler::compile(QDeclarativeEngine *engine,
- QDeclarativeCompositeTypeData *unit,
+ QDeclarativeTypeData *unit,
QDeclarativeCompiledData *out)
{
exceptions.clear();
@@ -573,10 +572,15 @@
output = out;
// Compile types
- for (int ii = 0; ii < unit->types.count(); ++ii) {
- QDeclarativeCompositeTypeData::TypeReference &tref = unit->types[ii];
+ const QList<QDeclarativeTypeData::TypeReference> &resolvedTypes = unit->resolvedTypes();
+ QList<QDeclarativeScriptParser::TypeReference *> referencedTypes = unit->parser().referencedTypes();
+
+ for (int ii = 0; ii < resolvedTypes.count(); ++ii) {
QDeclarativeCompiledData::TypeReference ref;
- QDeclarativeScriptParser::TypeReference *parserRef = unit->data.referencedTypes().at(ii);
+
+ const QDeclarativeTypeData::TypeReference &tref = resolvedTypes.at(ii);
+ QDeclarativeScriptParser::TypeReference *parserRef = referencedTypes.at(ii);
+
if (tref.type) {
ref.type = tref.type;
if (!ref.type->isCreatable()) {
@@ -585,33 +589,16 @@
err = tr( "Element is not creatable.");
COMPILE_EXCEPTION(parserRef->refObjects.first(), err);
}
- } else if (tref.unit) {
- ref.component = tref.unit->toComponent(engine);
-
- if (ref.component->isError()) {
- QDeclarativeError error;
- error.setUrl(output->url);
- error.setDescription(QLatin1String("Unable to create type ") +
- parserRef->name);
- if (!parserRef->refObjects.isEmpty()) {
- QDeclarativeParser::Object *parserObject = parserRef->refObjects.first();
- error.setLine(parserObject->location.start.line);
- error.setColumn(parserObject->location.start.column);
- }
-
- exceptions << error;
- exceptions << ref.component->errors();
- reset(out);
- return false;
- }
- ref.ref = tref.unit;
+ } else if (tref.typeData) {
+ ref.component = tref.typeData->component();
+ ref.ref = tref.typeData;
ref.ref->addref();
}
ref.className = parserRef->name.toUtf8();
out->types << ref;
}
- Object *root = unit->data.tree();
+ Object *root = unit->parser().tree();
Q_ASSERT(root);
this->engine = engine;
@@ -664,17 +651,18 @@
QHash<QString, Object::ScriptBlock> importedScripts;
QStringList importedScriptIndexes;
- for (int ii = 0; ii < unit->scripts.count(); ++ii) {
- QString scriptCode = QString::fromUtf8(unit->scripts.at(ii).resource->data);
- Object::ScriptBlock::Pragmas pragmas = QDeclarativeScriptParser::extractPragmas(scriptCode);
+ foreach (const QDeclarativeTypeData::ScriptReference &script, unit->resolvedScripts()) {
+ QString scriptCode = script.script->scriptSource();
+ Object::ScriptBlock::Pragmas pragmas = script.script->pragmas();
+
+ Q_ASSERT(!importedScripts.contains(script.qualifier));
if (!scriptCode.isEmpty()) {
- Object::ScriptBlock &scriptBlock = importedScripts[unit->scripts.at(ii).qualifier];
-
- scriptBlock.codes.append(scriptCode);
- scriptBlock.lineNumbers.append(1);
- scriptBlock.files.append(unit->scripts.at(ii).resource->url);
- scriptBlock.pragmas.append(pragmas);
+ Object::ScriptBlock &scriptBlock = importedScripts[script.qualifier];
+
+ scriptBlock.code = scriptCode;
+ scriptBlock.file = script.script->finalUrl().toString();
+ scriptBlock.pragmas = pragmas;
}
}
@@ -703,7 +691,7 @@
for (int ii = 0; ii < importedScriptIndexes.count(); ++ii)
output->importCache->add(importedScriptIndexes.at(ii), ii);
- unit->imports.cache(output->importCache, engine);
+ unit->imports().populateCache(output->importCache, engine);
Q_ASSERT(tree->metatype);
@@ -986,7 +974,7 @@
}
// Begin the class
- if (obj->parserStatusCast != -1) {
+ if (tr.type && obj->parserStatusCast != -1) {
QDeclarativeInstruction begin;
begin.type = QDeclarativeInstruction::BeginObject;
begin.begin.castValue = obj->parserStatusCast;
@@ -1070,6 +1058,7 @@
store.storeSignal.value =
output->indexForString(v->value.asScript().trimmed());
store.storeSignal.context = ctxt.stack;
+ store.storeSignal.name = output->indexForByteArray(prop->name);
output->bytecode << store;
}
@@ -1373,7 +1362,7 @@
return p.name() != 0;
} else {
int idx = mo->indexOfProperty(prop->name.constData());
- return idx != -1;
+ return idx != -1 && mo->property(idx).isScriptable();
}
}
@@ -1402,8 +1391,7 @@
QDeclarativeType *type = 0;
QDeclarativeImportedNamespace *typeNamespace = 0;
- enginePrivate->importDatabase.resolveType(unit->imports, prop->name,
- &type, 0, 0, 0, &typeNamespace);
+ unit->imports().resolveType(prop->name, &type, 0, 0, 0, &typeNamespace);
if (typeNamespace) {
// ### We might need to indicate that this property is a namespace
@@ -1439,6 +1427,11 @@
if (prop->index != -1) {
p = metaObject->property(prop->index);
Q_ASSERT(p.name());
+
+ if (!p.isScriptable()) {
+ prop->index = -1;
+ p = QMetaProperty();
+ }
}
}
@@ -1511,7 +1504,7 @@
// Setup attached property data
QDeclarativeType *type = 0;
- enginePrivate->importDatabase.resolveTypeInNamespace(ns, prop->name, &type, 0, 0, 0);
+ unit->imports().resolveType(ns, prop->name, &type, 0, 0, 0);
if (!type || !type->attachedPropertiesType())
COMPILE_EXCEPTION(prop, tr("Non-existent attached object"));
@@ -1771,9 +1764,7 @@
Q_ASSERT(prop->index != -1);
if (QDeclarativeValueTypeFactory::isValueType(prop->type)) {
- QDeclarativeEnginePrivate *ep =
- static_cast<QDeclarativeEnginePrivate *>(QObjectPrivate::get(engine));
- if (prop->type >= 0 /* QVariant == -1 */ && ep->valueTypes[prop->type]) {
+ if (prop->type >= 0 /* QVariant == -1 */ && enginePrivate->valueTypes[prop->type]) {
if (prop->values.count()) {
if (prop->values.at(0)->location < prop->value->location) {
@@ -1787,7 +1778,7 @@
COMPILE_EXCEPTION(prop, tr( "Invalid property assignment: \"%1\" is a read-only property").arg(QString::fromUtf8(prop->name)));
}
- COMPILE_CHECK(buildValueTypeProperty(ep->valueTypes[prop->type],
+ COMPILE_CHECK(buildValueTypeProperty(enginePrivate->valueTypes[prop->type],
prop->value, obj, ctxt.incr()));
obj->addValueTypeProperty(prop);
} else {
@@ -1825,6 +1816,8 @@
if (idx == -1)
COMPILE_EXCEPTION(prop, tr("Cannot assign to non-existent property \"%1\"").arg(QString::fromUtf8(prop->name)));
QMetaProperty p = type->metaObject()->property(idx);
+ if (!p.isScriptable())
+ COMPILE_EXCEPTION(prop, tr("Cannot assign to non-existent property \"%1\"").arg(QString::fromUtf8(prop->name)));
prop->index = idx;
prop->type = p.userType();
prop->isValueTypeSubProperty = true;
@@ -2138,8 +2131,7 @@
QString typeName = parts.at(0);
QDeclarativeType *type = 0;
- enginePrivate->importDatabase.resolveType(unit->imports, typeName.toUtf8(),
- &type, 0, 0, 0, 0);
+ unit->imports().resolveType(typeName.toUtf8(), &type, 0, 0, 0, 0);
if (!type || obj->typeName != type->qmlTypeName())
return true;
@@ -2166,7 +2158,7 @@
int dot = script.indexOf('.');
if (dot > 0) {
QDeclarativeType *type = 0;
- enginePrivate->importDatabase.resolveType(unit->imports, script.left(dot), &type, 0, 0, 0, 0);
+ unit->imports().resolveType(script.left(dot), &type, 0, 0, 0, 0);
if (!type)
return -1;
const QMetaObject *mo = type->metaObject();
@@ -2184,8 +2176,7 @@
const QMetaObject *QDeclarativeCompiler::resolveType(const QByteArray& name) const
{
QDeclarativeType *qmltype = 0;
- if (!enginePrivate->importDatabase.resolveType(unit->imports, name, &qmltype,
- 0, 0, 0, 0))
+ if (!unit->imports().resolveType(name, &qmltype, 0, 0, 0, 0))
return 0;
if (!qmltype)
return 0;
@@ -2214,10 +2205,11 @@
if (propNames.contains(prop.name))
COMPILE_EXCEPTION(&prop, tr("Duplicate property name"));
- if (QString::fromUtf8(prop.name).at(0).isUpper())
+ QString propName = QString::fromUtf8(prop.name);
+ if (propName.at(0).isUpper())
COMPILE_EXCEPTION(&prop, tr("Property names cannot begin with an upper case letter"));
- if (QDeclarativeEnginePrivate::get(engine)->globalClass->illegalNames().contains(prop.name))
+ if (enginePrivate->globalClass->illegalNames().contains(propName))
COMPILE_EXCEPTION(&prop, tr("Illegal property name"));
propNames.insert(prop.name);
@@ -2227,9 +2219,10 @@
QByteArray name = obj->dynamicSignals.at(ii).name;
if (methodNames.contains(name))
COMPILE_EXCEPTION(obj, tr("Duplicate signal name"));
- if (QString::fromUtf8(name).at(0).isUpper())
+ QString nameStr = QString::fromUtf8(name);
+ if (nameStr.at(0).isUpper())
COMPILE_EXCEPTION(obj, tr("Signal names cannot begin with an upper case letter"));
- if (QDeclarativeEnginePrivate::get(engine)->globalClass->illegalNames().contains(name))
+ if (enginePrivate->globalClass->illegalNames().contains(nameStr))
COMPILE_EXCEPTION(obj, tr("Illegal signal name"));
methodNames.insert(name);
}
@@ -2237,9 +2230,10 @@
QByteArray name = obj->dynamicSlots.at(ii).name;
if (methodNames.contains(name))
COMPILE_EXCEPTION(obj, tr("Duplicate method name"));
- if (QString::fromUtf8(name).at(0).isUpper())
+ QString nameStr = QString::fromUtf8(name);
+ if (nameStr.at(0).isUpper())
COMPILE_EXCEPTION(obj, tr("Method names cannot begin with an upper case letter"));
- if (QDeclarativeEnginePrivate::get(engine)->globalClass->illegalNames().contains(name))
+ if (enginePrivate->globalClass->illegalNames().contains(nameStr))
COMPILE_EXCEPTION(obj, tr("Illegal method name"));
methodNames.insert(name);
}
@@ -2340,17 +2334,18 @@
QByteArray customTypeName;
QDeclarativeType *qmltype = 0;
QUrl url;
- if (!enginePrivate->importDatabase.resolveType(unit->imports, p.customType, &qmltype,
- &url, 0, 0, 0))
+ if (!unit->imports().resolveType(p.customType, &qmltype, &url, 0, 0, 0))
COMPILE_EXCEPTION(&p, tr("Invalid property type"));
if (!qmltype) {
- QDeclarativeCompositeTypeData *tdata = enginePrivate->typeManager.get(url);
+ QDeclarativeTypeData *tdata = enginePrivate->typeLoader.get(url);
Q_ASSERT(tdata);
- Q_ASSERT(tdata->status == QDeclarativeCompositeTypeData::Complete);
-
- QDeclarativeCompiledData *data = tdata->toCompiledComponent(engine);
+ Q_ASSERT(tdata->isComplete());
+
+ QDeclarativeCompiledData *data = tdata->compiledData();
customTypeName = data->root->className();
+ data->release();
+ tdata->release();
} else {
customTypeName = qmltype->typeName();
}
@@ -2416,17 +2411,20 @@
builder.addSignal(p.name + "Changed()");
QMetaPropertyBuilder propBuilder =
builder.addProperty(p.name, type, builder.methodCount() - 1);
- propBuilder.setScriptable(true);
propBuilder.setWritable(!readonly);
}
- if (mode == ResolveAliases) {
- for (int ii = 0; ii < obj->dynamicProperties.count(); ++ii) {
- const Object::DynamicProperty &p = obj->dynamicProperties.at(ii);
-
- if (p.type == Object::DynamicProperty::Alias) {
+ for (int ii = 0; ii < obj->dynamicProperties.count(); ++ii) {
+ const Object::DynamicProperty &p = obj->dynamicProperties.at(ii);
+
+ if (p.type == Object::DynamicProperty::Alias) {
+ if (mode == ResolveAliases) {
((QDeclarativeVMEMetaData *)dynamicData.data())->aliasCount++;
compileAlias(builder, dynamicData, obj, p);
+ } else {
+ // Need a fake signal so that the metaobject remains consistent across
+ // the resolve and non-resolve alias runs
+ builder.addSignal(p.name + "Changed()");
}
}
}
@@ -2582,6 +2580,9 @@
COMPILE_EXCEPTION(prop.defaultValue, tr("Invalid alias location"));
QMetaProperty aliasProperty = idObject->metaObject()->property(propIdx);
+ if (!aliasProperty.isScriptable())
+ COMPILE_EXCEPTION(prop.defaultValue, tr("Invalid alias location"));
+
writable = aliasProperty.isWritable();
if (aliasProperty.isEnumType())
@@ -2618,7 +2619,6 @@
builder.addSignal(prop.name + "Changed()");
QMetaPropertyBuilder propBuilder =
builder.addProperty(prop.name, typeName.constData(), builder.methodCount() - 1);
- propBuilder.setScriptable(true);
propBuilder.setWritable(writable);
return true;
}
@@ -2745,7 +2745,7 @@
expr.context = binding.bindingContext.object;
expr.property = binding.property;
expr.expression = binding.expression;
- expr.imports = unit->imports;
+ expr.imports = unit->imports();
int index = bindingCompiler.compile(expr, enginePrivate);
if (index != -1) {
@@ -2765,6 +2765,7 @@
bool isSharable = sharableTest.isSharable(expression);
QDeclarativeRewrite::RewriteBinding rewriteBinding;
+ rewriteBinding.setName('$'+binding.property->name);
expression = rewriteBinding(expression);
quint32 length = expression.length();