inline T *New();
inline QString *NewString(const QString &);
+ inline QByteArray *NewByteArray(const QByteArray &);
private:
struct StringClass : public QString, public Class {
};
+ struct ByteArrayClass : public QByteArray, public Class {
+ };
inline void *allocate(int size);
void newpage();
return rv;
}
+QByteArray *QDeclarativePool::NewByteArray(const QByteArray &s)
+{
+ QByteArray *rv = New<ByteArrayClass>();
+ *rv = s;
+ return rv;
+}
+
void *QDeclarativePool::allocate(int size)
{
if (!_page || (_page->header.free + size) > (_page->memory + Page::pageSize))
#include <QtCore/qglobal.h>
#include <QtCore/qmetatype.h>
+#include <private/qhashedstring_p.h>
+
QT_BEGIN_NAMESPACE
class QFastMetaBuilder
inline StringRef(const StringRef &);
inline StringRef &operator=(const StringRef &);
+ inline void load(const QHashedStringRef &);
inline void load(const QByteArray &);
inline void load(const char *);
return _l;
}
+void QFastMetaBuilder::StringRef::load(const QHashedStringRef &str)
+{
+ Q_ASSERT(str.length() == _l);
+ str.writeUtf8(data());
+ *(data() + _l) = 0;
+}
+
void QFastMetaBuilder::StringRef::load(const QByteArray &str)
{
Q_ASSERT(str.length() == _l);
void QFastMetaBuilder::StringRef::load(const char *str)
{
- Q_ASSERT(strlen(str) == _l);
+ Q_ASSERT(strlen(str) == (uint)_l);
strcpy(data(), str);
}
}
return true;
}
+
+// Unicode stuff
+static inline bool isUnicodeNonCharacter(uint ucs4)
+{
+ // Unicode has a couple of "non-characters" that one can use internally,
+ // but are not allowed to be used for text interchange.
+ //
+ // Those are the last two entries each Unicode Plane (U+FFFE, U+FFFF,
+ // U+1FFFE, U+1FFFF, etc.) as well as the entries between U+FDD0 and
+ // U+FDEF (inclusive)
+
+ return (ucs4 & 0xfffe) == 0xfffe
+ || (ucs4 - 0xfdd0U) < 16;
+}
+
+static int utf8LengthFromUtf16(const QChar *uc, int len)
+{
+ int length = 0;
+
+ int surrogate_high = -1;
+
+ const QChar *ch = uc;
+ int invalid = 0;
+
+ const QChar *end = ch + len;
+ while (ch < end) {
+ uint u = ch->unicode();
+ if (surrogate_high >= 0) {
+ if (u >= 0xdc00 && u < 0xe000) {
+ u = (surrogate_high - 0xd800)*0x400 + (u - 0xdc00) + 0x10000;
+ surrogate_high = -1;
+ } else {
+ // high surrogate without low
+ ++ch;
+ ++invalid;
+ surrogate_high = -1;
+ continue;
+ }
+ } else if (u >= 0xdc00 && u < 0xe000) {
+ // low surrogate without high
+ ++ch;
+ ++invalid;
+ continue;
+ } else if (u >= 0xd800 && u < 0xdc00) {
+ surrogate_high = u;
+ ++ch;
+ continue;
+ }
+
+ if (u < 0x80) {
+ ++length;
+ } else {
+ if (u < 0x0800) {
+ ++length;
+ } else {
+ // is it one of the Unicode non-characters?
+ if (isUnicodeNonCharacter(u)) {
+ ++length;
+ ++ch;
+ ++invalid;
+ continue;
+ }
+
+ if (u > 0xffff) {
+ ++length;
+ ++length;
+ } else {
+ ++length;
+ }
+ ++length;
+ }
+ ++length;
+ }
+ ++ch;
+ }
+
+ return length;
+}
+
+// Writes the utf8 version of uc to output. uc is of length len.
+// There must be at least utf8LengthFromUtf16(uc, len) bytes in output.
+// A null terminator is not written.
+static void utf8FromUtf16(char *output, const QChar *uc, int len)
+{
+ uchar replacement = '?';
+ int surrogate_high = -1;
+
+ uchar* cursor = (uchar*)output;
+ const QChar *ch = uc;
+ int invalid = 0;
+
+ const QChar *end = ch + len;
+ while (ch < end) {
+ uint u = ch->unicode();
+ if (surrogate_high >= 0) {
+ if (u >= 0xdc00 && u < 0xe000) {
+ u = (surrogate_high - 0xd800)*0x400 + (u - 0xdc00) + 0x10000;
+ surrogate_high = -1;
+ } else {
+ // high surrogate without low
+ *cursor = replacement;
+ ++ch;
+ ++invalid;
+ surrogate_high = -1;
+ continue;
+ }
+ } else if (u >= 0xdc00 && u < 0xe000) {
+ // low surrogate without high
+ *cursor = replacement;
+ ++ch;
+ ++invalid;
+ continue;
+ } else if (u >= 0xd800 && u < 0xdc00) {
+ surrogate_high = u;
+ ++ch;
+ continue;
+ }
+
+ if (u < 0x80) {
+ *cursor++ = (uchar)u;
+ } else {
+ if (u < 0x0800) {
+ *cursor++ = 0xc0 | ((uchar) (u >> 6));
+ } else {
+ // is it one of the Unicode non-characters?
+ if (isUnicodeNonCharacter(u)) {
+ *cursor++ = replacement;
+ ++ch;
+ ++invalid;
+ continue;
+ }
+
+ if (u > 0xffff) {
+ *cursor++ = 0xf0 | ((uchar) (u >> 18));
+ *cursor++ = 0x80 | (((uchar) (u >> 12)) & 0x3f);
+ } else {
+ *cursor++ = 0xe0 | (((uchar) (u >> 12)) & 0x3f);
+ }
+ *cursor++ = 0x80 | (((uchar) (u >> 6)) & 0x3f);
+ }
+ *cursor++ = 0x80 | ((uchar) (u&0x3f));
+ }
+ ++ch;
+ }
+}
+
+void QHashedStringRef::computeUtf8Length() const
+{
+ if (m_length)
+ m_utf8length = utf8LengthFromUtf16(m_data, m_length);
+ else
+ m_utf8length = 0;
+}
+
+QHashedStringRef QHashedStringRef::mid(int offset, int length) const
+{
+ Q_ASSERT(offset < m_length);
+ return QHashedStringRef(m_data + offset,
+ (length == -1 || (offset + length) > m_length)?(m_length - offset):length);
+}
+
+bool QHashedStringRef::endsWith(const QString &s) const
+{
+ return s.length() < m_length &&
+ QHashedString::compare(s.constData(), m_data + m_length - s.length(), s.length());
+}
+
+bool QHashedStringRef::startsWith(const QString &s) const
+{
+ return s.length() < m_length &&
+ QHashedString::compare(s.constData(), m_data, s.length());
+}
+
+QString QHashedStringRef::toString() const
+{
+ if (m_length == 0)
+ return QString();
+ return QString(m_data, m_length);
+}
+
+QByteArray QHashedStringRef::toUtf8() const
+{
+ if (m_length == 0)
+ return QByteArray();
+
+ QByteArray result;
+ result.resize(utf8length());
+ writeUtf8(result.data());
+ return result;
+}
+
+void QHashedStringRef::writeUtf8(char *output) const
+{
+ if (m_length) {
+ int ulen = utf8length();
+ if (ulen == m_length) {
+ // Must be a latin1 string
+ uchar *o = (uchar *)output;
+ const QChar *c = m_data;
+ while (ulen--)
+ *o++ = (uchar)((*c++).unicode());
+ } else {
+ utf8FromUtf16(output, m_data, m_length);
+ }
+ }
+}
inline quint32 existingHash() const;
static inline bool isUpper(const QChar &);
+
+ static bool compare(const QChar *lhs, const QChar *rhs, int length);
+ static inline bool compare(const QChar *lhs, const char *rhs, int length);
+ static inline bool compare(const char *lhs, const char *rhs, int length);
private:
friend class QHashedStringRef;
friend class QStringHashNode;
void computeHash() const;
mutable quint32 m_hash;
-
- static bool compare(const QChar *lhs, const QChar *rhs, int length);
- static inline bool compare(const QChar *lhs, const char *rhs, int length);
- static inline bool compare(const char *lhs, const char *rhs, int length);
};
class Q_AUTOTEST_EXPORT QHashedV8String
public:
inline QHashedStringRef();
inline QHashedStringRef(const QString &);
+ inline QHashedStringRef(const QStringRef &);
inline QHashedStringRef(const QChar *, int);
inline QHashedStringRef(const QChar *, int, quint32);
inline QHashedStringRef(const QHashedString &);
inline QHashedStringRef(const QHashedStringRef &);
+ inline QHashedStringRef &operator=(const QHashedStringRef &);
+ 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 QString &string) const;
+ inline bool operator!=(const QHashedString &string) const;
+ inline bool operator!=(const QHashedStringRef &string) const;
inline quint32 hash() const;
+ inline const QChar &at(int) const;
inline const QChar *constData() const;
+ bool startsWith(const QString &) const;
+ bool endsWith(const QString &) const;
+ QHashedStringRef mid(int, int) const;
+
+ inline bool isEmpty() const;
inline int length() const;
inline bool startsWithUpper() const;
+ QString toString() const;
+
+ inline int utf8length() const;
+ QByteArray toUtf8() const;
+ void writeUtf8(char *) const;
private:
friend class QHashedString;
void computeHash() const;
+ void computeUtf8Length() const;
const QChar *m_data;
int m_length;
+ mutable int m_utf8length;
mutable quint32 m_hash;
};
{
public:
QStringHashNode()
- : nlist(0), next(0), length(0), hash(0), pooled(0), ckey(0), symbolId()
+ : nlist(0), next(0), length(0), hash(0), pooled(0), ckey(0), ukey(0), symbolId()
{
}
QStringHashNode(const QHashedString &key)
- : nlist(0), next(0), length(key.length()), hash(key.hash()), pooled(0), ckey(0), key(key), symbolId(0) {
+ : nlist(0), next(0), length(key.length()), hash(key.hash()), pooled(0), ckey(0), key(key),
+ ukey(key.constData()), symbolId(0) {
}
QStringHashNode(const QHashedCStringRef &key)
- : nlist(0), next(0), length(key.length()), hash(key.hash()), pooled(0), ckey(key.constData()), symbolId(0) {
+ : nlist(0), next(0), length(key.length()), hash(key.hash()), pooled(0), ckey(key.constData()),
+ ukey(0), symbolId(0) {
}
QStringHashNode(const QStringHashNode &o)
- : nlist(0), next(0), length(o.length), hash(o.hash), pooled(0), ckey(o.ckey), key(o.key), symbolId(o.symbolId) {
+ : nlist(0), next(0), length(o.length), hash(o.hash), pooled(0), ckey(o.ckey), key(o.key),
+ ukey(o.ukey), symbolId(o.symbolId) {
}
QStringHashNode *nlist;
quint32 pooled:1;
const char *ckey;
QString key;
+ const QChar *ukey;
quint32 symbolId;
inline bool equals(v8::Handle<v8::String> string) {
return ckey?string->Equals((char*)ckey, length):
- string->Equals((uint16_t*)key.constData(), length);
+ string->Equals((uint16_t*)ukey, length);
}
inline bool symbolEquals(const QHashedV8String &string) {
inline bool equals(const QHashedStringRef &string) {
return length == string.length() &&
hash == string.hash() &&
- ckey?(QHashedString::compare(string.constData(), ckey, length)):
- (QHashedString::compare(string.constData(), key.constData(), length));
+ (ckey?(QHashedString::compare(string.constData(), ckey, length)):
+ (QHashedString::compare(string.constData(), ukey, length)));
}
inline bool equals(const QHashedCStringRef &string) {
return length == string.length() &&
hash == string.hash() &&
- ckey?(QHashedString::compare(string.constData(), ckey, length)):
- (QHashedString::compare(key.constData(), string.constData(), length));
+ (ckey?(QHashedString::compare(string.constData(), ckey, length)):
+ (QHashedString::compare(ukey, string.constData(), length)));
}
};
rv->length = key.length();
rv->hash = key.hash();
rv->key = key;
+ rv->ukey = rv->key.constData();
rv->pooled = 1;
rv->value = value;
return rv;
rv->hash = o.hash;
rv->ckey = o.ckey;
rv->key = o.key;
+ rv->ukey = o.ukey;
rv->pooled = 1;
rv->symbolId = o.symbolId;
rv->value = o.value;
}
QHashedStringRef::QHashedStringRef()
-: m_data(0), m_length(0), m_hash(0)
+: m_data(0), m_length(0), m_utf8length(-1), m_hash(0)
{
}
QHashedStringRef::QHashedStringRef(const QString &str)
-: m_data(str.constData()), m_length(str.length()), m_hash(0)
+: m_data(str.constData()), m_length(str.length()), m_utf8length(0), m_hash(0)
+{
+}
+
+QHashedStringRef::QHashedStringRef(const QStringRef &str)
+: m_data(str.constData()), m_length(str.length()), m_utf8length(0), m_hash(0)
{
}
QHashedStringRef::QHashedStringRef(const QChar *data, int length)
-: m_data(data), m_length(length), m_hash(0)
+: m_data(data), m_length(length), m_utf8length(0), m_hash(0)
{
}
QHashedStringRef::QHashedStringRef(const QChar *data, int length, quint32 hash)
-: m_data(data), m_length(length), m_hash(hash)
+: m_data(data), m_length(length), m_utf8length(0), m_hash(hash)
{
}
QHashedStringRef::QHashedStringRef(const QHashedString &string)
-: m_data(string.constData()), m_length(string.length()), m_hash(string.m_hash)
+: m_data(string.constData()), m_length(string.length()), m_utf8length(0), m_hash(string.m_hash)
{
}
QHashedStringRef::QHashedStringRef(const QHashedStringRef &string)
-: m_data(string.m_data), m_length(string.m_length), m_hash(string.m_hash)
+: m_data(string.m_data), m_length(string.m_length), m_utf8length(string.m_utf8length),
+ m_hash(string.m_hash)
{
}
+QHashedStringRef &QHashedStringRef::operator=(const QHashedStringRef &o)
+{
+ m_data = o.m_data;
+ m_length = o.m_length;
+ m_utf8length = o.m_utf8length;
+ m_hash = o.m_hash;
+ return *this;
+}
+
+bool QHashedStringRef::operator==(const QString &string) const
+{
+ return m_length == string.length() &&
+ QHashedString::compare(string.constData(), m_data, m_length);
+}
+
bool QHashedStringRef::operator==(const QHashedString &string) const
{
return m_length == string.length() &&
QHashedString::compare(string.m_data, m_data, m_length);
}
+bool QHashedStringRef::operator!=(const QString &string) const
+{
+ return m_length != string.length() ||
+ !QHashedString::compare(string.constData(), m_data, m_length);
+}
+
+bool QHashedStringRef::operator!=(const QHashedString &string) const
+{
+ return m_length != string.length() ||
+ (m_hash != string.m_hash && m_hash && string.m_hash) ||
+ !QHashedString::compare(string.constData(), m_data, m_length);
+}
+
+bool QHashedStringRef::operator!=(const QHashedStringRef &string) const
+{
+ return m_length != string.m_length ||
+ (m_hash != string.m_hash && m_hash && string.m_hash) ||
+ QHashedString::compare(string.m_data, m_data, m_length);
+}
+
+const QChar &QHashedStringRef::at(int index) const
+{
+ Q_ASSERT(index < m_length);
+ return m_data[index];
+}
+
const QChar *QHashedStringRef::constData() const
{
return m_data;
}
+bool QHashedStringRef::isEmpty() const
+{
+ return m_length == 0;
+}
+
int QHashedStringRef::length() const
{
return m_length;
}
+int QHashedStringRef::utf8length() const
+{
+ if (m_utf8length < m_length)
+ computeUtf8Length();
+ return m_utf8length;
+}
+
bool QHashedStringRef::startsWithUpper() const
{
if (m_length < 1) return false;
*/
bool QDeclarativeCompiler::isAttachedPropertyName(const QString &name)
{
- return isAttachedPropertyName(QStringRef(&name));
+ return isAttachedPropertyName(QHashedStringRef(&name));
}
-bool QDeclarativeCompiler::isAttachedPropertyName(const QStringRef &name)
+bool QDeclarativeCompiler::isAttachedPropertyName(const QHashedStringRef &name)
{
return !name.isEmpty() && QDeclarativeUtils::isUpper(name.at(0));
}
return isSignalPropertyName(QStringRef(&name));
}
-bool QDeclarativeCompiler::isSignalPropertyName(const QStringRef &name)
+bool QDeclarativeCompiler::isSignalPropertyName(const QHashedStringRef &name)
{
if (name.length() < 3) return false;
if (!name.startsWith(on_string)) return false;
- int ns = name.size();
+ int ns = name.length();
for (int i = 2; i < ns; ++i) {
const QChar curr = name.at(i);
if (curr.unicode() == '_') continue;
enginePrivate->registerCompositeType(output);
}
-static bool QStringList_contains(const QStringList &list, const QStringRef &string)
+static bool QStringList_contains(const QStringList &list, const QHashedStringRef &string)
{
for (int ii = 0; ii < list.count(); ++ii)
- if (list.at(ii) == string)
+ if (string == list.at(ii))
return true;
return false;
{
Q_ASSERT(obj->metaObject());
- QStringRef propName = prop->name();
+ const QHashedStringRef &propName = prop->name();
+
Q_ASSERT(propName.startsWith(on_string));
- QString name = propName.string()->mid(propName.position() + 2, propName.length() - 2);
+ QString name = propName.mid(2, -1).toString();
// Note that the property name could start with any alpha or '_' or '$' character,
// so we need to do the lower-casing of the first alpha character.
// Ensures that the dynamic meta specification on obj is valid
bool QDeclarativeCompiler::checkDynamicMeta(QDeclarativeParser::Object *obj)
{
- QSet<QByteArray> propNames;
+ // XXX aakenned - inefficient copying of the string ref
+ QStringHash<bool> propNames;
QSet<QByteArray> methodNames;
bool seenDefaultProperty = false;
if (propNames.contains(prop.name))
COMPILE_EXCEPTION(&prop, tr("Duplicate property name"));
- QString propName = QString::fromUtf8(prop.name);
- if (QDeclarativeUtils::isUpper(propName.at(0)))
+ if (QDeclarativeUtils::isUpper(prop.name.at(0)))
COMPILE_EXCEPTION(&prop, tr("Property names cannot begin with an upper case letter"));
- if (enginePrivate->v8engine()->illegalNames().contains(propName))
+ if (enginePrivate->v8engine()->illegalNames().contains(prop.name))
COMPILE_EXCEPTION(&prop, tr("Illegal property name"));
- propNames.insert(prop.name);
+ propNames.insert(prop.name.toString(), true);
}
for (Object::DynamicSignal *s = obj->dynamicSignals.first(); s; s = obj->dynamicSignals.next(s)) {
if (!resolveAlias) {
// No point doing this for both the alias and non alias cases
- QString name = QString::fromUtf8(p.name);
- QDeclarativePropertyCache::Data *d = property(obj, QStringRef(&name));
+ QDeclarativePropertyCache::Data *d = property(obj, p.name);
if (d && d->isFinal())
COMPILE_EXCEPTION(&p, tr("Cannot override FINAL property"));
}
Object::DynamicProperty &p = obj->dynamicProperties[ii];
// Reserve space for name
- p.nameRef = builder.newString(p.name.length());
+ p.nameRef = builder.newString(p.name.utf8length());
int propertyType = 0;
bool readonly = false;
Q_ASSERT(p.type == Object::DynamicProperty::CustomList ||
p.type == Object::DynamicProperty::Custom);
+ // XXX don't double resolve this in the case of an alias run
+
QByteArray customTypeName;
QDeclarativeType *qmltype = 0;
QString url;
- if (!unit->imports().resolveType(p.customType, &qmltype, &url, 0, 0, 0))
+ if (!unit->imports().resolveType(p.customType.toUtf8(), &qmltype, &url, 0, 0, 0))
COMPILE_EXCEPTION(&p, tr("Invalid property type"));
if (!qmltype) {
propertyType = qMetaTypeId<QDeclarativeListProperty<QObject> >();
}
- p.resolvedCustomTypeName = customTypeName;
+ p.resolvedCustomTypeName = pool->NewByteArray(customTypeName);
p.typeRef = builder.newString(customTypeName.length());
typeRef = p.typeRef;
}
readonly?QFastMetaBuilder::None:QFastMetaBuilder::Writable,
effectivePropertyIndex);
- p.changedSignatureRef = builder.newString(p.name.length() + strlen("Changed()"));
+ p.changedSignatureRef = builder.newString(p.name.utf8length() + strlen("Changed()"));
builder.setSignal(effectivePropertyIndex, p.changedSignatureRef);
effectivePropertyIndex++;
}
// Even if we aren't resolving the alias, we need a fake signal so that the
// metaobject remains consistent across the resolve and non-resolve alias runs
- p.changedSignatureRef = builder.newString(p.name.length() + strlen("Changed()"));
+ p.changedSignatureRef = builder.newString(p.name.utf8length() + strlen("Changed()"));
builder.setSignal(effectivePropertyIndex, p.changedSignatureRef);
effectivePropertyIndex++;
aliasIndex++;
Object::DynamicProperty &p = obj->dynamicProperties[ii];
char *d = p.changedSignatureRef.data();
- strcpy(d, p.name.constData());
- strcpy(d + p.name.length(), "Changed()");
+ p.name.writeUtf8(d);
+ strcpy(d + p.name.utf8length(), "Changed()");
if (p.type == Object::DynamicProperty::Alias && !resolveAlias)
continue;
p.nameRef.load(p.name);
- if (p.type >= builtinTypeCount)
- p.typeRef.load(p.resolvedCustomTypeName);
+ if (p.type >= builtinTypeCount) {
+ Q_ASSERT(p.resolvedCustomTypeName);
+ p.typeRef.load(*p.resolvedCustomTypeName);
+ }
}
// Allocate default property if necessary
*(vmd->aliasData() + aliasIndex) = aliasData;
prop.nameRef = builder.newString(prop.name.length());
- prop.resolvedCustomTypeName = typeName;
+ prop.resolvedCustomTypeName = pool->NewByteArray(typeName);
prop.typeRef = builder.newString(typeName.length());
builder.setProperty(propIndex, prop.nameRef, prop.typeRef, (QMetaType::Type)type,
Q_ASSERT(prop->parent);
Q_ASSERT(prop->parent->metaObject());
+ // XXX aakenned
QMetaProperty mp = prop->parent->metaObject()->property(prop->index);
if (!mp.isWritable() && !QDeclarativeMetaType::isList(prop->type))
COMPILE_EXCEPTION(prop, tr("Invalid property assignment: \"%1\" is a read-only property").arg(prop->name().toString()));
QString expression = binding.expression.asScript();
QDeclarativeRewrite::RewriteBinding rewriteBinding;
- rewriteBinding.setName(QLatin1Char('$')+binding.property->name());
+ rewriteBinding.setName(QLatin1Char('$')+binding.property->name().toString());
bool isSharable = false;
binding.rewrittenExpression = rewriteBinding(binding.expression.asAST(), expression, &isSharable);
}
QDeclarativePropertyCache::Data *
-QDeclarativeCompiler::property(QDeclarativeParser::Object *object, const QStringRef &name, bool *notInRevision)
+QDeclarativeCompiler::property(QDeclarativeParser::Object *object, const QHashedStringRef &name, bool *notInRevision)
{
if (notInRevision) *notInRevision = false;
else
cache = QDeclarativeEnginePrivate::get(engine)->cache(object->metaObject());
- QDeclarativePropertyCache::Data *d = cache->property(QHashedStringRef(name.constData(), name.length()));
+ QDeclarativePropertyCache::Data *d = cache->property(name);
// Find the first property
while (d && d->isFunction())
// This code must match the semantics of QDeclarativePropertyPrivate::findSignalByName
QDeclarativePropertyCache::Data *
-QDeclarativeCompiler::signal(QDeclarativeParser::Object *object, const QStringRef &name, bool *notInRevision)
+QDeclarativeCompiler::signal(QDeclarativeParser::Object *object, const QHashedStringRef &name, bool *notInRevision)
{
if (notInRevision) *notInRevision = false;
cache = QDeclarativeEnginePrivate::get(engine)->cache(object->metaObject());
- QDeclarativePropertyCache::Data *d = cache->property(QHashedStringRef(name.constData(), name.length()));
+ QDeclarativePropertyCache::Data *d = cache->property(name);
if (notInRevision) *notInRevision = false;
while (d && !(d->isFunction()))
}
if (name.endsWith(Changed_string)) {
- QStringRef propName(name.string(), name.position(), name.length() - Changed_string.length());
+ QHashedStringRef propName = name.mid(0, name.length() - Changed_string.length());
d = property(object, propName, notInRevision);
if (d)
return indexOfProperty(object, QStringRef(&name), notInRevision);
}
-int QDeclarativeCompiler::indexOfProperty(QDeclarativeParser::Object *object, const QStringRef &name,
+int QDeclarativeCompiler::indexOfProperty(QDeclarativeParser::Object *object, const QHashedStringRef &name,
bool *notInRevision)
{
QDeclarativePropertyCache::Data *d = property(object, name, notInRevision);
static bool isAttachedPropertyName(const QString &);
static bool isSignalPropertyName(const QString &);
- static bool isAttachedPropertyName(const QStringRef &);
- static bool isSignalPropertyName(const QStringRef &);
+ static bool isAttachedPropertyName(const QHashedStringRef &);
+ static bool isSignalPropertyName(const QHashedStringRef &);
int evaluateEnum(const QByteArray& script) const; // for QDeclarativeCustomParser::evaluateEnum
const QMetaObject *resolveType(const QByteArray& name) const; // for QDeclarativeCustomParser::resolveType
QStringList deferredProperties(QDeclarativeParser::Object *);
QDeclarativePropertyCache::Data *property(QDeclarativeParser::Object *, int);
- QDeclarativePropertyCache::Data *property(QDeclarativeParser::Object *, const QStringRef &,
+ QDeclarativePropertyCache::Data *property(QDeclarativeParser::Object *, const QHashedStringRef &,
bool *notInRevision = 0);
- QDeclarativePropertyCache::Data *signal(QDeclarativeParser::Object *, const QStringRef &,
+ QDeclarativePropertyCache::Data *signal(QDeclarativeParser::Object *, const QHashedStringRef &,
bool *notInRevision = 0);
- int indexOfProperty(QDeclarativeParser::Object *, const QStringRef &, bool *notInRevision = 0);
+ int indexOfProperty(QDeclarativeParser::Object *, const QHashedStringRef &, bool *notInRevision = 0);
int indexOfProperty(QDeclarativeParser::Object *, const QString &, bool *notInRevision = 0);
int indexOfSignal(QDeclarativeParser::Object *, const QString &, bool *notInRevision = 0);
scriptStringProperties.append(p);
}
-Property *QDeclarativeParser::Object::getProperty(const QStringRef &name, bool create)
+Property *QDeclarativeParser::Object::getProperty(const QHashedStringRef &name, bool create)
{
for (Property *p = properties.first(); p; p = properties.next(p)) {
if (p->name() == name)
}
}
+Property *QDeclarativeParser::Object::getProperty(const QStringRef &name, bool create)
+{
+ return getProperty(QHashedStringRef(name), create);
+}
+
Property *QDeclarativeParser::Object::getProperty(const QString &name, bool create)
{
for (Property *p = properties.first(); p; p = properties.next(p)) {
}
QDeclarativeParser::Object::DynamicProperty::DynamicProperty()
-: isDefaultProperty(false), type(Variant), defaultValue(0)
+: isDefaultProperty(false), type(Variant), defaultValue(0), resolvedCustomTypeName(0)
{
}
customType(o.customType),
name(o.name),
defaultValue(o.defaultValue),
- location(o.location)
+ location(o.location),
+ resolvedCustomTypeName(o.resolvedCustomTypeName)
{
}
}
QDeclarativeParser::Property::Property()
-: parent(0), type(0), index(-1), value(0), _name(0), isDefault(true), isDeferred(false),
+: parent(0), type(0), index(-1), value(0), isDefault(true), isDeferred(false),
isValueTypeSubProperty(false), isAlias(false), scriptStringScope(-1), nextProperty(0),
nextMainProperty(0)
{
#include <private/qfieldlist_p.h>
#include <private/qdeclarativepropertycache_p.h>
#include <private/qfastmetabuilder_p.h>
+#include <private/qhashedstring_p.h>
QT_BEGIN_HEADER
// Content in value and values are mutually exclusive.
Object *value;
// The property name
- QStringRef name() const { return _name; }
- void setName(const QString &n) { _name = QStringRef(pool()->NewString(n)); }
+ const QHashedStringRef &name() const { return _name; }
+ void setName(const QString &n) { _name = QHashedStringRef(pool()->NewString(n)); }
// True if this property was accessed as the default property.
bool isDefault;
// True if the setting of this property will be deferred. Set by the
private:
friend class Object;
- QStringRef _name;
+ QHashedStringRef _name;
};
class Object : public QDeclarativePool::Class
Property *getDefaultProperty();
// name ptr must be guarenteed to remain valid
+ Property *getProperty(const QHashedStringRef &name, bool create=true);
Property *getProperty(const QStringRef &name, bool create=true);
Property *getProperty(const QString &name, bool create=true);
DynamicProperty();
DynamicProperty(const DynamicProperty &);
- enum Type { Variant, Int, Bool, Real, String, Url, Color, Time, Date, DateTime, Alias, Custom, CustomList };
+ enum Type { Variant, Int, Bool, Real, String, Url, Color, Time,
+ Date, DateTime, Alias, Custom, CustomList };
bool isDefaultProperty;
Type type;
- QByteArray customType;
- QByteArray name;
+
+ QHashedStringRef customType;
+ QHashedStringRef name;
QDeclarativeParser::Property *defaultValue;
LocationSpan location;
// Used by the compiler
- QByteArray resolvedCustomTypeName;
+ QByteArray *resolvedCustomTypeName;
QFastMetaBuilder::StringRef typeRef;
QFastMetaBuilder::StringRef nameRef;
QFastMetaBuilder::StringRef changedSignatureRef;
DynamicSignal(const DynamicSignal &);
QByteArray name;
- QList<QByteArray> parameterTypes;
+ QList<QHashedCStringRef> parameterTypes;
QList<QByteArray> parameterNames;
int parameterTypesLength() const;
bool ProcessAST::visit(AST::UiPublicMember *node)
{
- const struct TypeNameToType {
+ static const struct TypeNameToType {
const char *name;
+ int nameLength;
Object::DynamicProperty::Type type;
const char *qtName;
+ int qtNameLength;
} propTypeNameToTypes[] = {
- { "int", Object::DynamicProperty::Int, "int" },
- { "bool", Object::DynamicProperty::Bool, "bool" },
- { "double", Object::DynamicProperty::Real, "double" },
- { "real", Object::DynamicProperty::Real, "qreal" },
- { "string", Object::DynamicProperty::String, "QString" },
- { "url", Object::DynamicProperty::Url, "QUrl" },
- { "color", Object::DynamicProperty::Color, "QColor" },
+ { "int", strlen("int"), Object::DynamicProperty::Int, "int", strlen("int") },
+ { "bool", strlen("bool"), Object::DynamicProperty::Bool, "bool", strlen("bool") },
+ { "double", strlen("double"), Object::DynamicProperty::Real, "double", strlen("double") },
+ { "real", strlen("real"), Object::DynamicProperty::Real, "qreal", strlen("qreal") },
+ { "string", strlen("string"), Object::DynamicProperty::String, "QString", strlen("QString") },
+ { "url", strlen("url"), Object::DynamicProperty::Url, "QUrl", strlen("QUrl") },
+ { "color", strlen("color"), Object::DynamicProperty::Color, "QColor", strlen("QColor") },
// Internally QTime, QDate and QDateTime are all supported.
// To be more consistent with JavaScript we expose only
// QDateTime as it matches closely with the Date JS type.
// We also call it "date" to match.
- // { "time", Object::DynamicProperty::Time, "QTime" },
- // { "date", Object::DynamicProperty::Date, "QDate" },
- { "date", Object::DynamicProperty::DateTime, "QDateTime" },
- { "variant", Object::DynamicProperty::Variant, "QVariant" }
+ // { "time", strlen("time"), Object::DynamicProperty::Time, "QTime", strlen("QTime") },
+ // { "date", strlen("date"), Object::DynamicProperty::Date, "QDate", strlen("QDate") },
+ { "date", strlen("date"), Object::DynamicProperty::DateTime, "QDateTime", strlen("QDateTime") },
+ { "variant", strlen("variant"), Object::DynamicProperty::Variant, "QVariant", strlen("QVariant") }
};
- const int propTypeNameToTypesCount = sizeof(propTypeNameToTypes) /
- sizeof(propTypeNameToTypes[0]);
+ static const int propTypeNameToTypesCount = sizeof(propTypeNameToTypes) /
+ sizeof(propTypeNameToTypes[0]);
if(node->type == AST::UiPublicMember::Signal) {
- const QString name = node->name.toString();
-
Object::DynamicSignal signal;
- signal.name = name.toUtf8();
+ signal.name = node->name.toUtf8();
AST::UiParameterList *p = node->parameters;
while (p) {
- const QString memberType = p->type.toString();
- const char *qtType = 0;
- for(int ii = 0; !qtType && ii < propTypeNameToTypesCount; ++ii) {
- if(QLatin1String(propTypeNameToTypes[ii].name) == memberType)
- qtType = propTypeNameToTypes[ii].qtName;
+ const QStringRef &memberType = p->type;
+
+ const TypeNameToType *type = 0;
+ for(int typeIndex = 0; typeIndex < propTypeNameToTypesCount; ++typeIndex) {
+ const TypeNameToType *t = propTypeNameToTypes + typeIndex;
+ if (t->nameLength == memberType.length() &&
+ QHashedString::compare(memberType.constData(), t->name, t->nameLength)) {
+ type = t;
+ break;
+ }
}
- if (!qtType) {
+ if (!type) {
QDeclarativeError error;
error.setDescription(QCoreApplication::translate("QDeclarativeParser","Expected parameter type"));
error.setLine(node->typeToken.startLine);
return false;
}
- signal.parameterTypes << qtType;
+ signal.parameterTypes << QHashedCStringRef(type->qtName, type->qtNameLength);
signal.parameterNames << p->name.toUtf8();
p = p->finish();
}
signal.location = location(node->typeToken, node->semicolonToken);
_stateStack.top().object->dynamicSignals << signal;
} else {
- const QString memberType = node->memberType.toString();
- const QString name = node->name.toString();
+ const QStringRef &memberType = node->memberType;
+ const QStringRef &name = node->name;
bool typeFound = false;
Object::DynamicProperty::Type type;
- if (memberType == QLatin1String("alias")) {
+ if (memberType.length() == strlen("alias") &&
+ QHashedString::compare(memberType.constData(), "alias", strlen("alias"))) {
type = Object::DynamicProperty::Alias;
typeFound = true;
- }
+ }
for(int ii = 0; !typeFound && ii < propTypeNameToTypesCount; ++ii) {
- if(QLatin1String(propTypeNameToTypes[ii].name) == memberType) {
- type = propTypeNameToTypes[ii].type;
+ const TypeNameToType *t = propTypeNameToTypes + ii;
+ if (t->nameLength == memberType.length() &&
+ QHashedString::compare(memberType.constData(), t->name, t->nameLength)) {
+ type = t->type;
typeFound = true;
}
}
if (!typeFound && memberType.at(0).isUpper()) {
- QString typemodifier;
- if(!node->typeModifier.isNull())
- typemodifier = node->typeModifier.toString();
- if (typemodifier.isEmpty()) {
+ const QStringRef &typeModifier = node->typeModifier;
+
+ if (typeModifier.isEmpty()) {
type = Object::DynamicProperty::Custom;
- } else if(typemodifier == QLatin1String("list")) {
+ } else if(typeModifier.length() == strlen("list") &&
+ QHashedString::compare(typeModifier.constData(), "list", strlen("list"))) {
type = Object::DynamicProperty::CustomList;
} else {
QDeclarativeError error;
return false;
}
+
Object::DynamicProperty property;
property.isDefaultProperty = node->isDefaultMember;
property.type = type;
if (type >= Object::DynamicProperty::Custom) {
QDeclarativeScriptParser::TypeReference *typeRef =
- _parser->findOrCreateType(memberType);
+ _parser->findOrCreateType(memberType.toString());
typeRef->refObjects.append(_stateStack.top().object);
+ property.customType = memberType;
}
- property.customType = memberType.toUtf8();
- property.name = name.toUtf8();
+
+ property.name = QHashedStringRef(name);
property.location = location(node->firstSourceLocation(),
node->lastSourceLocation());
return QDeclarativeEnginePrivate::get(m_engine)->getNetworkAccessManager();
}
-const QSet<QString> &QV8Engine::illegalNames() const
+const QStringHash<bool> &QV8Engine::illegalNames() const
{
return m_illegalNames;
}
v8::Local<v8::Value> names = m_getOwnPropertyNames->Call(global, 1, args);
v8::Local<v8::Array> namesArray = v8::Local<v8::Array>::Cast(names);
for (quint32 ii = 0; ii < namesArray->Length(); ++ii)
- m_illegalNames.insert(toString(namesArray->Get(ii)));
+ m_illegalNames.insert(toString(namesArray->Get(ii)), true);
}
{
virtual QNetworkAccessManager *networkAccessManager();
// Return the list of illegal id names (the names of the properties on the global object)
- const QSet<QString> &illegalNames() const;
+ const QStringHash<bool> &illegalNames() const;
inline void collectGarbage() { gc(); }
static void gc();
QVector<Deletable *> m_extensionData;
Deletable *m_listModelData;
- QSet<QString> m_illegalNames;
+ QStringHash<bool> m_illegalNames;
Exception m_exception;