$$PWD/qdeclarativerefcount_p.h \
$$PWD/qdeclarativepool_p.h \
$$PWD/qfieldlist_p.h \
+ $$PWD/qdeclarativeutils_p.h
SOURCES += \
$$PWD/qintrusivelist.cpp \
$$PWD/qhashedstring.cpp \
$$PWD/qdeclarativerefcount.cpp \
$$PWD/qdeclarativepool.cpp \
-
--- /dev/null
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtDeclarative module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QDECLARATIVEUTIL_P_H
+#define QDECLARATIVEUTIL_P_H
+
+#include <QtCore/QString>
+
+QT_BEGIN_NAMESPACE
+
+namespace QDeclarativeUtils {
+
+inline bool isUpper(const QChar &qc)
+{
+ ushort c = qc.unicode();
+ return ((c >= 'A' && c <= 'Z') || (c > 127 && QChar::category(c) == QChar::Letter_Uppercase));
+}
+
+inline bool isLower(const QChar &qc)
+{
+ ushort c = qc.unicode();
+ return ((c >= 'a' && c <= 'z') || (c > 127 && QChar::category(c) == QChar::Letter_Lowercase));
+}
+
+inline bool isLetter(const QChar &qc)
+{
+ ushort c = qc.unicode();
+ return ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c > 127 && qc.isLetter()));
+}
+
+inline bool isDigit(const QChar &qc)
+{
+ ushort c = qc.unicode();
+ return ((c >= '0' && c <= '9') || (c > 127 && qc.isDigit()));
+}
+
+inline bool isLetterOrNumber(const QChar &qc)
+{
+ ushort c = qc.unicode();
+ return ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9') || (c > 127 && qc.isLetterOrNumber()));
+}
+
+inline bool isSpace(const QChar &qc)
+{
+ ushort c = qc.unicode();
+ return (c == 0x20 || (c >= 0x09 && c <= 0x0D) || c == 0x85 || (c > 127 && qc.isSpace()));
+}
+
+} // namespace QDeclarative
+
+QT_END_NAMESPACE
+
+#endif // QDECLARATIVEUTIL_P_H
#include "qdeclarativejslexer_p.h"
#include "qdeclarativejsengine_p.h"
#include "qdeclarativejsnodepool_p.h"
+#include <private/qdeclarativeutils_p.h>
#include <QtCore/QCoreApplication>
+#include <QtCore/QVarLengthArray>
#include <QtCore/QDebug>
QT_BEGIN_NAMESPACE
_code = code;
_tokenText.clear();
+ _tokenText.reserve(1024);
_errorMessage.clear();
_tokenSpell = QStringRef();
_validTokenText = false;
_tokenLinePtr = _lastLinePtr;
- while (_char.isSpace()) {
+ while (QDeclarativeUtils::isSpace(_char)) {
if (_char == QLatin1Char('\n')) {
_tokenLinePtr = _codePtr;
return T_DIVIDE_;
case '.':
- if (_char.isDigit()) {
- QByteArray chars;
- chars.reserve(32);
+ if (QDeclarativeUtils::isDigit(_char)) {
+ QVarLengthArray<char,32> chars;
- chars += ch.unicode(); // append the `.'
+ chars.append(ch.unicode()); // append the `.'
- while (_char.isDigit()) {
- chars += _char.unicode();
+ while (QDeclarativeUtils::isDigit(_char)) {
+ chars.append(_char.unicode());
scanChar();
}
- if (_char.toLower() == QLatin1Char('e')) {
- if (_codePtr[0].isDigit() || ((_codePtr[0] == QLatin1Char('+') || _codePtr[0] == QLatin1Char('-')) &&
- _codePtr[1].isDigit())) {
+ if (_char == QLatin1Char('e') || _char == QLatin1Char('E')) {
+ if (QDeclarativeUtils::isDigit(_codePtr[0]) || ((_codePtr[0] == QLatin1Char('+') || _codePtr[0] == QLatin1Char('-')) &&
+ QDeclarativeUtils::isDigit(_codePtr[1]))) {
- chars += _char.unicode();
+ chars.append(_char.unicode());
scanChar(); // consume `e'
if (_char == QLatin1Char('+') || _char == QLatin1Char('-')) {
- chars += _char.unicode();
+ chars.append(_char.unicode());
scanChar(); // consume the sign
}
- while (_char.isDigit()) {
- chars += _char.unicode();
+ while (QDeclarativeUtils::isDigit(_char)) {
+ chars.append(_char.unicode());
scanChar();
}
}
}
+ chars.append('\0');
+
const char *begin = chars.constData();
const char *end = 0;
bool ok = false;
_tokenValue = qstrtod(begin, &end, &ok);
- if (end != chars.end()) {
+ if (end - begin != chars.size() - 1) {
_errorCode = IllegalExponentIndicator;
_errorMessage = QCoreApplication::translate("QDeclarativeParser", "Illegal syntax for exponential number");
return T_ERROR;
case '\'':
case '"': {
const QChar quote = ch;
- _tokenText.clear();
+ _tokenText.resize(0);
_validTokenText = true;
bool multilineStringLiteral = false;
}
default:
- if (ch.isLetter() || ch == QLatin1Char('$') || ch == QLatin1Char('_') || (ch == QLatin1Char('\\') && _char == QLatin1Char('u'))) {
+ if (QDeclarativeUtils::isLetter(ch) || ch == QLatin1Char('$') || ch == QLatin1Char('_') || (ch == QLatin1Char('\\') && _char == QLatin1Char('u'))) {
bool identifierWithEscapeChars = false;
if (ch == QLatin1Char('\\')) {
identifierWithEscapeChars = true;
- _tokenText.clear();
+ _tokenText.resize(0);
bool ok = false;
_tokenText += decodeUnicodeEscapeCharacter(&ok);
_validTokenText = true;
}
}
while (true) {
- if (_char.isLetterOrNumber() || _char == QLatin1Char('$') || _char == QLatin1Char('_')) {
+ if (QDeclarativeUtils::isLetterOrNumber(_char) || _char == QLatin1Char('$') || _char == QLatin1Char('_')) {
if (identifierWithEscapeChars)
_tokenText += _char;
} else if (_char == QLatin1Char('\\') && _codePtr[0] == QLatin1Char('u')) {
if (! identifierWithEscapeChars) {
identifierWithEscapeChars = true;
- _tokenText = QString(_tokenStartPtr, _codePtr - _tokenStartPtr - 1);
+ _tokenText.resize(0);
+ _tokenText.insert(0, _tokenStartPtr, _codePtr - _tokenStartPtr - 1);
_validTokenText = true;
}
return kind;
}
}
- } else if (ch.isDigit()) {
- QByteArray chars;
- chars.reserve(32);
- chars += ch.unicode();
+ } else if (QDeclarativeUtils::isDigit(ch)) {
+ QVarLengthArray<char,32> chars;
+ chars.append(ch.unicode());
if (ch == QLatin1Char('0') && (_char == 'x' || _char == 'X')) {
// parse hex integer literal
- chars += _char.unicode();
+ chars.append(_char.unicode());
scanChar(); // consume `x'
while (isHexDigit(_char)) {
- chars += _char.unicode();
+ chars.append(_char.unicode());
scanChar();
}
}
// decimal integer literal
- while (_char.isDigit()) {
- chars += _char.unicode();
+ while (QDeclarativeUtils::isDigit(_char)) {
+ chars.append(_char.unicode());
scanChar(); // consume the digit
}
if (_char == QLatin1Char('.')) {
- chars += _char.unicode();
+ chars.append(_char.unicode());
scanChar(); // consume `.'
- while (_char.isDigit()) {
- chars += _char.unicode();
+ while (QDeclarativeUtils::isDigit(_char)) {
+ chars.append(_char.unicode());
scanChar();
}
- if (_char.toLower() == QLatin1Char('e')) {
- if (_codePtr[0].isDigit() || ((_codePtr[0] == QLatin1Char('+') || _codePtr[0] == QLatin1Char('-')) &&
- _codePtr[1].isDigit())) {
+ if (_char == QLatin1Char('e') || _char == QLatin1Char('E')) {
+ if (QDeclarativeUtils::isDigit(_codePtr[0]) || ((_codePtr[0] == QLatin1Char('+') || _codePtr[0] == QLatin1Char('-')) &&
+ QDeclarativeUtils::isDigit(_codePtr[1]))) {
- chars += _char.unicode();
+ chars.append(_char.unicode());
scanChar(); // consume `e'
if (_char == QLatin1Char('+') || _char == QLatin1Char('-')) {
- chars += _char.unicode();
+ chars.append(_char.unicode());
scanChar(); // consume the sign
}
- while (_char.isDigit()) {
- chars += _char.unicode();
+ while (QDeclarativeUtils::isDigit(_char)) {
+ chars.append(_char.unicode());
scanChar();
}
}
}
- } else if (_char.toLower() == QLatin1Char('e')) {
- if (_codePtr[0].isDigit() || ((_codePtr[0] == QLatin1Char('+') || _codePtr[0] == QLatin1Char('-')) &&
- _codePtr[1].isDigit())) {
+ } else if (_char == QLatin1Char('e') || _char == QLatin1Char('E')) {
+ if (QDeclarativeUtils::isDigit(_codePtr[0]) || ((_codePtr[0] == QLatin1Char('+') || _codePtr[0] == QLatin1Char('-')) &&
+ QDeclarativeUtils::isDigit(_codePtr[1]))) {
- chars += _char.unicode();
+ chars.append(_char.unicode());
scanChar(); // consume `e'
if (_char == QLatin1Char('+') || _char == QLatin1Char('-')) {
- chars += _char.unicode();
+ chars.append(_char.unicode());
scanChar(); // consume the sign
}
- while (_char.isDigit()) {
- chars += _char.unicode();
+ while (QDeclarativeUtils::isDigit(_char)) {
+ chars.append(_char.unicode());
scanChar();
}
}
}
+ chars.append('\0');
+
const char *begin = chars.constData();
const char *end = 0;
bool ok = false;
_tokenValue = qstrtod(begin, &end, &ok);
- if (end != chars.end()) {
+ if (end - begin != chars.size() - 1) {
_errorCode = IllegalExponentIndicator;
_errorMessage = QCoreApplication::translate("QDeclarativeParser", "Illegal syntax for exponential number");
return T_ERROR;
bool Lexer::scanRegExp(RegExpBodyPrefix prefix)
{
- _tokenText.clear();
+ _tokenText.resize(0);
_validTokenText = true;
_patternFlags = 0;
#include "private/qdeclarativescriptparser_p.h"
#include "private/qdeclarativebinding_p.h"
#include "private/qdeclarativev4compiler_p.h"
+#include "private/qdeclarativeutils_p.h"
#include <QColor>
#include <QDebug>
bool QDeclarativeCompiler::isAttachedPropertyName(const QStringRef &name)
{
- return !name.isEmpty() && name.at(0) >= 'A' && name.at(0) <= 'Z';
+ return !name.isEmpty() && QDeclarativeUtils::isUpper(name.at(0));
}
/*!
if (!name.startsWith(on_string)) return false;
int ns = name.size();
for (int i = 2; i < ns; ++i) {
- QChar curr = name.at(i);
- if (curr == QLatin1Char('_')) continue;
- if (curr >= QLatin1Char('A') && curr <= QLatin1Char('Z')) return true;
+ const QChar curr = name.at(i);
+ if (curr.unicode() == '_') continue;
+ if (QDeclarativeUtils::isUpper(curr)) return true;
return false;
}
return false; // consists solely of underscores - invalid.
// 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.
for (int firstAlphaIndex = 0; firstAlphaIndex < name.size(); ++firstAlphaIndex) {
- if (name.at(firstAlphaIndex) >= QLatin1Char('A') && name.at(firstAlphaIndex) <= QLatin1Char('Z')) {
+ if (QDeclarativeUtils::isUpper(name.at(firstAlphaIndex))) {
name[firstAlphaIndex] = name.at(firstAlphaIndex).toLower();
break;
}
COMPILE_EXCEPTION(v, tr("Invalid property assignment: \"%1\" is a read-only property").arg(QString::fromUtf8(prop.name())));
QString string = v->value.asString();
- if (!string.at(0).isUpper())
+ if (!QDeclarativeUtils::isUpper(string.at(0)))
return true;
QStringList parts = string.split(QLatin1Char('.'));
COMPILE_EXCEPTION(&prop, tr("Duplicate property name"));
QString propName = QString::fromUtf8(prop.name);
- if (propName.at(0).isUpper())
+ if (QDeclarativeUtils::isUpper(propName.at(0)))
COMPILE_EXCEPTION(&prop, tr("Property names cannot begin with an upper case letter"));
if (enginePrivate->v8engine()->illegalNames().contains(propName))
propNames.insert(prop.name);
}
- for (int ii = 0; ii < obj->dynamicSignals.count(); ++ii) {
- const QDeclarativeParser::Object::DynamicSignal &currSig = obj->dynamicSignals.at(ii);
- QByteArray name = currSig.name;
- if (methodNames.contains(name))
- COMPILE_EXCEPTION(&currSig, tr("Duplicate signal name"));
- QString nameStr = QString::fromUtf8(name);
- if (nameStr.at(0).isUpper())
+ for (Object::DynamicSignal *s = obj->dynamicSignals.first(); s; s = obj->dynamicSignals.next(s)) {
+ const QDeclarativeScript::Object::DynamicSignal &currSig = *s;
+
+ if (methodNames.testAndSet(currSig.name.hash())) {
+ for (Object::DynamicSignal *s2 = obj->dynamicSignals.first(); s2 != s;
+ s2 = obj->dynamicSignals.next(s2)) {
+ if (s2->name == currSig.name)
+ COMPILE_EXCEPTION(&currSig, tr("Duplicate signal name"));
+ }
+ }
+
+ if (currSig.name.at(0).isUpper())
COMPILE_EXCEPTION(&currSig, tr("Signal names cannot begin with an upper case letter"));
- if (enginePrivate->v8engine()->illegalNames().contains(nameStr))
+ if (enginePrivate->v8engine()->illegalNames().contains(currSig.name))
COMPILE_EXCEPTION(&currSig, tr("Illegal signal name"));
- methodNames.insert(name);
}
- for (int ii = 0; ii < obj->dynamicSlots.count(); ++ii) {
- const QDeclarativeParser::Object::DynamicSlot &currSlot = obj->dynamicSlots.at(ii);
- QByteArray name = currSlot.name;
- if (methodNames.contains(name))
- COMPILE_EXCEPTION(&currSlot, tr("Duplicate method name"));
- QString nameStr = QString::fromUtf8(name);
- if (nameStr.at(0).isUpper())
+
+ for (Object::DynamicSlot *s = obj->dynamicSlots.first(); s; s = obj->dynamicSlots.next(s)) {
+ const QDeclarativeScript::Object::DynamicSlot &currSlot = *s;
+
+ if (methodNames.testAndSet(currSlot.name.hash())) {
+ for (Object::DynamicSignal *s2 = obj->dynamicSignals.first(); s2;
+ s2 = obj->dynamicSignals.next(s2)) {
+ if (s2->name == currSlot.name)
+ COMPILE_EXCEPTION(&currSlot, tr("Duplicate method name"));
+ }
+ for (Object::DynamicSlot *s2 = obj->dynamicSlots.first(); s2 != s;
+ s2 = obj->dynamicSlots.next(s2)) {
+ if (s2->name == currSlot.name)
+ COMPILE_EXCEPTION(&currSlot, tr("Duplicate method name"));
+ }
+ }
+
+ if (currSlot.name.at(0).isUpper())
COMPILE_EXCEPTION(&currSlot, tr("Method names cannot begin with an upper case letter"));
- if (enginePrivate->v8engine()->illegalNames().contains(nameStr))
+ if (enginePrivate->v8engine()->illegalNames().contains(currSlot.name))
COMPILE_EXCEPTION(&currSlot, tr("Illegal method name"));
- methodNames.insert(name);
}
return true;
int lastSlash = path.lastIndexOf(QLatin1Char('/'));
if (lastSlash > -1) {
QString nameBase = path.mid(lastSlash + 1, path.length()-lastSlash-5);
- if (!nameBase.isEmpty() && nameBase.at(0).isUpper())
+ if (!nameBase.isEmpty() && QDeclarativeUtils::isUpper(nameBase.at(0)))
newClassName = nameBase.toUtf8() + "_QMLTYPE_" + QByteArray::number(idx);
}
}
if (val.isEmpty())
COMPILE_EXCEPTION(v, tr( "Invalid empty ID"));
- if (val.at(0).isLetter() && !val.at(0).isLower())
+ QChar ch = val.at(0);
+ if (QDeclarativeUtils::isLetter(ch) && !QDeclarativeUtils::isLower(ch))
COMPILE_EXCEPTION(v, tr( "IDs cannot start with an uppercase letter"));
QChar u(QLatin1Char('_'));
- for (int ii = 0; ii < val.count(); ++ii) {
+ if (!QDeclarativeUtils::isLetter(ch) && ch != u)
+ COMPILE_EXCEPTION(v, tr( "IDs must start with a letter or underscore"));
- if (ii == 0 && !val.at(ii).isLetter() && val.at(ii) != u) {
- COMPILE_EXCEPTION(v, tr( "IDs must start with a letter or underscore"));
- } else if (ii != 0 && !val.at(ii).isLetterOrNumber() && val.at(ii) != u) {
+ for (int ii = 1; ii < val.count(); ++ii) {
+ ch = val.at(ii);
+ if (!QDeclarativeUtils::isLetterOrNumber(ch) && ch != u)
COMPILE_EXCEPTION(v, tr( "IDs must contain only letters, numbers, and underscores"));
- }
-
}
if (enginePrivate->v8engine()->illegalNames().contains(val))
#include "private/qdeclarativedirparser_p.h"
#include "qdeclarativeerror.h"
#include <private/qdeclarativeglobal_p.h>
+#include <private/qdeclarativeutils_p.h>
#include <QtCore/QTextStream>
#include <QtCore/QFile>
while (index != length) {
const QChar ch = line.at(index);
- if (ch.isSpace()) {
+ if (QDeclarativeUtils::isSpace(ch)) {
do { ++index; }
- while (index != length && line.at(index).isSpace());
+ while (index != length && QDeclarativeUtils::isSpace(line.at(index)));
} else if (ch == QLatin1Char('#')) {
// recognized a comment
const int start = index;
do { ++index; }
- while (index != length && !line.at(index).isSpace());
+ while (index != length && !QDeclarativeUtils::isSpace(line.at(index)));
const QString lexeme = line.mid(start, index - start);
#include <private/qsganchors_p_p.h> // For AnchorLine
#include <private/qdeclarativetypenamecache_p.h>
+#include <private/qdeclarativeutils_p.h>
DEFINE_BOOL_CONFIG_OPTION(qmlVerboseCompiler, QML_VERBOSE_COMPILER)
break;
case IR::Name::AttachType:
- if (name.at(0).isUpper()) {
+ if (QDeclarativeUtils::isUpper(name.at(0))) {
QByteArray utf8Name = name.toUtf8();
const char *enumName = utf8Name.constData();