diff options
author | Michael Brasser <mbrasser@ford.com> | 2017-04-20 15:59:31 +0200 |
---|---|---|
committer | Michael Brasser <michael.brasser@live.com> | 2017-07-13 21:00:55 +0000 |
commit | 22a2cc43387ec3b9f74a6c01f8665378a4541147 (patch) | |
tree | 33acf5a5367302eb3f488b688aba7c85959035ae /src/qml/compiler/qqmlirbuilder.cpp | |
parent | 286f14f1e29e7f4e2db4517d087dd5c92606f971 (diff) |
Add support for enum declarations in QML
Enums can be declared with the following syntax:
enum MyEnum {
Value1,
Value2
}
Grammar changes done by Simon Hausmann.
[ChangeLog][QtQml] Enums can now be declared directly in QML.
Task-number: QTBUG-14861
Change-Id: Ic6b6e032651d01ee2ecf9d5ce5734976cb3ad7ab
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
Diffstat (limited to 'src/qml/compiler/qqmlirbuilder.cpp')
-rw-r--r-- | src/qml/compiler/qqmlirbuilder.cpp | 94 |
1 files changed, 92 insertions, 2 deletions
diff --git a/src/qml/compiler/qqmlirbuilder.cpp b/src/qml/compiler/qqmlirbuilder.cpp index df615e6804..e05c38e14a 100644 --- a/src/qml/compiler/qqmlirbuilder.cpp +++ b/src/qml/compiler/qqmlirbuilder.cpp @@ -86,6 +86,7 @@ void Object::init(QQmlJS::MemoryPool *pool, int typeNameIndex, int idIndex, cons flags = QV4::CompiledData::Object::NoFlag; properties = pool->New<PoolList<Property> >(); aliases = pool->New<PoolList<Alias> >(); + qmlEnums = pool->New<PoolList<Enum>>(); qmlSignals = pool->New<PoolList<Signal> >(); bindings = pool->New<PoolList<Binding> >(); functions = pool->New<PoolList<Function> >(); @@ -118,6 +119,21 @@ QString Object::sanityCheckFunctionNames(const QSet<QString> &illegalNames, QQml return QString(); // no error } +QString Object::appendEnum(Enum *enumeration) +{ + Object *target = declarationsOverride; + if (!target) + target = this; + + for (Enum *e = qmlEnums->first; e; e = e->next) { + if (e->nameIndex == enumeration->nameIndex) + return tr("Duplicate scoped enum name"); + } + + target->qmlEnums->append(enumeration); + return QString(); // no error +} + QString Object::appendSignal(Signal *signal) { Object *target = declarationsOverride; @@ -709,6 +725,48 @@ static QStringList astNodeToStringList(QQmlJS::AST::Node *node) return QStringList(); } +bool IRBuilder::visit(QQmlJS::AST::UiEnumDeclaration *node) +{ + Enum *enumeration = New<Enum>(); + QString enumName = node->name.toString(); + enumeration->nameIndex = registerString(enumName); + + if (enumName.at(0).isLower()) + COMPILE_EXCEPTION(node->enumToken, tr("Scoped enum names must begin with an upper case letter")); + + enumeration->location.line = node->enumToken.startLine; + enumeration->location.column = node->enumToken.startColumn; + + enumeration->enumValues = New<PoolList<EnumValue>>(); + + QQmlJS::AST::UiEnumMemberList *e = node->members; + int i = -1; + while (e) { + EnumValue *enumValue = New<EnumValue>(); + QString member = e->member.toString(); + enumValue->nameIndex = registerString(member); + enumValue->value = ++i; + + if (member.at(0).isLower()) + COMPILE_EXCEPTION(e->memberToken, tr("Enum names must begin with an upper case letter")); + + enumValue->location.line = e->memberToken.startLine; + enumValue->location.column = e->memberToken.startColumn; + enumeration->enumValues->append(enumValue); + + e = e->next; + } + + QString error = _object->appendEnum(enumeration); + if (!error.isEmpty()) { + recordError(node->enumToken, error); + return false; + } + + return false; +} + + bool IRBuilder::visit(QQmlJS::AST::UiPublicMember *node) { static const struct TypeNameToType { @@ -1375,13 +1433,19 @@ QV4::CompiledData::Unit *QmlUnitGenerator::generate(Document &output, const QV4: int objectsSize = 0; for (Object *o : qAsConst(output.objects)) { objectOffsets.insert(o, unitSize + importSize + objectOffsetTableSize + objectsSize); - objectsSize += QV4::CompiledData::Object::calculateSizeExcludingSignals(o->functionCount(), o->propertyCount(), o->aliasCount(), o->signalCount(), o->bindingCount(), o->namedObjectsInComponent.count); + objectsSize += QV4::CompiledData::Object::calculateSizeExcludingSignalsAndEnums(o->functionCount(), o->propertyCount(), o->aliasCount(), o->enumCount(), o->signalCount(), o->bindingCount(), o->namedObjectsInComponent.count); int signalTableSize = 0; for (const Signal *s = o->firstSignal(); s; s = s->next) signalTableSize += QV4::CompiledData::Signal::calculateSize(s->parameters->count); objectsSize += signalTableSize; + + int enumTableSize = 0; + for (const Enum *e = o->firstEnum(); e; e = e->next) + enumTableSize += QV4::CompiledData::Enum::calculateSize(e->enumValues->count); + + objectsSize += enumTableSize; } const int totalSize = unitSize + importSize + objectOffsetTableSize + objectsSize + output.jsGenerator.stringTable.sizeOfTableAndData(); @@ -1455,6 +1519,10 @@ QV4::CompiledData::Unit *QmlUnitGenerator::generate(Document &output, const QV4: objectToWrite->offsetToAliases = nextOffset; nextOffset += objectToWrite->nAliases * sizeof(QV4::CompiledData::Alias); + objectToWrite->nEnums = o->enumCount(); + objectToWrite->offsetToEnums = nextOffset; + nextOffset += objectToWrite->nEnums * sizeof(quint32); + objectToWrite->nSignals = o->signalCount(); objectToWrite->offsetToSignals = nextOffset; nextOffset += objectToWrite->nSignals * sizeof(quint32); @@ -1512,14 +1580,36 @@ QV4::CompiledData::Unit *QmlUnitGenerator::generate(Document &output, const QV4: signalTableSize += size; signalPtr += size; } + nextOffset += signalTableSize; + + quint32_le *enumOffsetTable = reinterpret_cast<quint32_le*>(objectPtr + objectToWrite->offsetToEnums); + quint32 enumTableSize = 0; + char *enumPtr = objectPtr + nextOffset; + for (const Enum *e = o->firstEnum(); e; e = e->next) { + *enumOffsetTable++ = enumPtr - objectPtr; + QV4::CompiledData::Enum *enumToWrite = reinterpret_cast<QV4::CompiledData::Enum*>(enumPtr); + + enumToWrite->nameIndex = e->nameIndex; + enumToWrite->location = e->location; + enumToWrite->nEnumValues = e->enumValues->count; + + QV4::CompiledData::EnumValue *enumValueToWrite = reinterpret_cast<QV4::CompiledData::EnumValue*>(enumPtr + sizeof(*enumToWrite)); + for (EnumValue *enumValue = e->enumValues->first; enumValue; enumValue = enumValue->next, ++enumValueToWrite) + *enumValueToWrite = *enumValue; + + int size = QV4::CompiledData::Enum::calculateSize(e->enumValues->count); + enumTableSize += size; + enumPtr += size; + } quint32_le *namedObjectInComponentPtr = reinterpret_cast<quint32_le *>(objectPtr + objectToWrite->offsetToNamedObjectsInComponent); for (int i = 0; i < o->namedObjectsInComponent.count; ++i) { *namedObjectInComponentPtr++ = o->namedObjectsInComponent.at(i); } - objectPtr += QV4::CompiledData::Object::calculateSizeExcludingSignals(o->functionCount(), o->propertyCount(), o->aliasCount(), o->signalCount(), o->bindingCount(), o->namedObjectsInComponent.count); + objectPtr += QV4::CompiledData::Object::calculateSizeExcludingSignalsAndEnums(o->functionCount(), o->propertyCount(), o->aliasCount(), o->enumCount(), o->signalCount(), o->bindingCount(), o->namedObjectsInComponent.count); objectPtr += signalTableSize; + objectPtr += enumTableSize; } // enable flag if we encountered pragma Singleton |