v8::Handle<v8::String> m_string;
};
+class QHashedCStringRef;
class Q_AUTOTEST_EXPORT QHashedStringRef
{
public:
inline bool operator==(const QString &string) const;
inline bool operator==(const QHashedString &string) const;
inline bool operator==(const QHashedStringRef &string) const;
+ inline bool operator==(const QHashedCStringRef &string) const;
inline bool operator!=(const QString &string) const;
inline bool operator!=(const QHashedString &string) const;
inline bool operator!=(const QHashedStringRef &string) const;
+ inline bool operator!=(const QHashedCStringRef &string) const;
inline quint32 hash() const;
inline const char *constData() const;
inline int length() const;
+
+ QString toUtf16() const;
+ inline int utf16length() const;
+ inline void writeUtf16(QChar *) const;
+ inline void writeUtf16(uint16_t *) const;
private:
+ friend class QHashedStringRef;
+
void computeHash() const;
const char *m_data;
QHashedString::compare(string.m_data, m_data, m_length);
}
+bool QHashedStringRef::operator==(const QHashedCStringRef &string) const
+{
+ return m_length == string.m_length &&
+ (m_hash == string.m_hash || !m_hash || !string.m_hash) &&
+ QHashedString::compare(m_data, string.m_data, m_length);
+}
+
bool QHashedStringRef::operator!=(const QString &string) const
{
return m_length != string.length() ||
QHashedString::compare(string.m_data, m_data, m_length);
}
+bool QHashedStringRef::operator!=(const QHashedCStringRef &string) const
+{
+ return m_length != string.m_length ||
+ (m_hash != string.m_hash && m_hash && string.m_hash) ||
+ QHashedString::compare(m_data, string.m_data, m_length);
+}
+
const QChar &QHashedStringRef::at(int index) const
{
Q_ASSERT(index < m_length);
return m_length;
}
+int QHashedCStringRef::utf16length() const
+{
+ return m_length;
+}
+
+void QHashedCStringRef::writeUtf16(QChar *output) const
+{
+ writeUtf16((uint16_t *)output);
+}
+
+void QHashedCStringRef::writeUtf16(uint16_t *output) const
+{
+ int l = m_length;
+ const char *d = m_data;
+ while (l--)
+ *output++ = *d++;
+}
+
bool QHashedString::compare(const QChar *lhs, const char *rhs, int length)
{
Q_ASSERT(lhs && rhs);
if (obj->defaultProperty) {
defaultProperty = obj->defaultProperty;
- const QMetaObject *metaObject = obj->metaObject();
- Q_ASSERT(metaObject);
- // XXX aakenned
- QMetaProperty p = QDeclarativeMetaType::defaultProperty(metaObject);
- if (p.name()) {
- Property *explicitProperty = obj->getProperty(QString::fromUtf8(p.name()), false);
- if (explicitProperty && !explicitProperty->value && !explicitProperty->values.isEmpty()) {
-
- skipProperty = explicitProperty; // We merge the values into defaultProperty
-
- // Find the correct insertion point
- Value *insertPos = 0;
-
- for (Value *v = defaultProperty->values.first(); v; v = Property::ValueList::next(v)) {
- if (!(v->location.start < explicitProperty->values.first()->location.start))
- break;
- insertPos = v;
- }
+ Property *explicitProperty = 0;
+
+ const QMetaObject *mo = obj->metatype;
+ int idx = mo->indexOfClassInfo("DefaultProperty");
+ if (idx != -1) {
+ QMetaClassInfo info = mo->classInfo(idx);
+ const char *p = info.value();
+ if (p) {
+ int plen = 0;
+ char ord = 0;
+ while (char c = p[plen++]) { ord |= c; };
+ --plen;
+
+ if (ord & 0x80) {
+ // Utf8 - unoptimal, but seldom hit
+ QString *s = pool->NewString(QString::fromUtf8(p, plen));
+ QHashedStringRef r(*s);
+
+ if (obj->propertiesHashField.test(r.hash())) {
+ for (Property *ep = obj->properties.first(); ep; ep = obj->properties.next(ep)) {
+ if (ep->name() == r) {
+ explicitProperty = ep;
+ break;
+ }
+ }
+ }
- defaultProperty->values.insertAfter(insertPos, explicitProperty->values);
+ if (!explicitProperty)
+ defaultProperty->setName(r);
- }
+ } else {
+ QHashedCStringRef r(p, plen);
+
+ if (obj->propertiesHashField.test(r.hash())) {
+ for (Property *ep = obj->properties.first(); ep; ep = obj->properties.next(ep)) {
+ if (ep->name() == r) {
+ explicitProperty = ep;
+ break;
+ }
+ }
+ }
+
+ if (!explicitProperty) {
+ // Set the default property name
+ QChar *buffer = pool->NewRawArray<QChar>(r.length());
+ r.writeUtf16(buffer);
+ defaultProperty->setName(QHashedStringRef(buffer, r.length(), r.hash()));
+ }
+ }
+ }
}
+
+ if (explicitProperty && !explicitProperty->value && !explicitProperty->values.isEmpty()) {
+
+ skipProperty = explicitProperty; // We merge the values into defaultProperty
+
+ // Find the correct insertion point
+ Value *insertPos = 0;
+
+ for (Value *v = defaultProperty->values.first(); v; v = Property::ValueList::next(v)) {
+ if (!(v->location.start < explicitProperty->values.first()->location.start))
+ break;
+ insertPos = v;
+ }
+
+ defaultProperty->values.insertAfter(insertPos, explicitProperty->values);
+ }
}
QDeclarativeCustomParser *cp = 0;
bool QDeclarativeCompiler::doesPropertyExist(QDeclarativeParser::Property *prop,
QDeclarativeParser::Object *obj)
{
+ if (prop->name().isEmpty())
+ return false;
if(isAttachedPropertyName(prop->name()) || prop->name() == id_string)
return true;
- if (prop->isDefault) {
- const QMetaObject *mo = obj->metaObject();
- QMetaProperty p = QDeclarativeMetaType::defaultProperty(mo);
- return p.name() != 0;
- } else {
- return property(obj, prop->name()) != 0;
- }
+ return property(obj, prop->name()) != 0;
}
bool QDeclarativeCompiler::buildProperty(QDeclarativeParser::Property *prop,
prop->value->metatype = type->attachedPropertiesType();
} else {
// Setup regular property data
+ bool notInRevision = false;
+ QDeclarativePropertyCache::Data *d =
+ prop->name().isEmpty()?0:property(obj, prop->name(), ¬InRevision);
- if (prop->isDefault) {
- QMetaProperty p = QDeclarativeMetaType::defaultProperty(metaObject);
-
- if (p.name()) {
- prop->setName(QString::fromLatin1(p.name()));
-
- QDeclarativePropertyCache::Data *d = property(obj, p.propertyIndex());
- prop->index = d->coreIndex;
- prop->core = *d;
- }
-
- } else {
- bool notInRevision = false;
- QDeclarativePropertyCache::Data *d = property(obj, prop->name(), ¬InRevision);
-
- if (d == 0 && notInRevision) {
- const QList<QDeclarativeTypeData::TypeReference> &resolvedTypes = unit->resolvedTypes();
- const QDeclarativeTypeData::TypeReference &type = resolvedTypes.at(obj->type);
- if (type.type) {
- COMPILE_EXCEPTION(prop, tr("\"%1.%2\" is not available in %3 %4.%5.").arg(elementName(obj)).arg(prop->name().toString()).arg(QString::fromUtf8(type.type->module())).arg(type.majorVersion).arg(type.minorVersion));
- } else {
- COMPILE_EXCEPTION(prop, tr("\"%1.%2\" is not available due to component versioning.").arg(elementName(obj)).arg(prop->name().toString()));
- }
- } else if (d) {
- prop->index = d->coreIndex;
- prop->core = *d;
+ if (d == 0 && notInRevision) {
+ const QList<QDeclarativeTypeData::TypeReference> &resolvedTypes = unit->resolvedTypes();
+ const QDeclarativeTypeData::TypeReference &type = resolvedTypes.at(obj->type);
+ if (type.type) {
+ COMPILE_EXCEPTION(prop, tr("\"%1.%2\" is not available in %3 %4.%5.").arg(elementName(obj)).arg(prop->name().toString()).arg(QString::fromUtf8(type.type->module())).arg(type.majorVersion).arg(type.minorVersion));
+ } else {
+ COMPILE_EXCEPTION(prop, tr("\"%1.%2\" is not available due to component versioning.").arg(elementName(obj)).arg(prop->name().toString()));
}
+ } else if (d) {
+ prop->index = d->coreIndex;
+ prop->core = *d;
}
// We can't error here as the "id" property does not require a