6#include <private/qv4staticvalue_p.h>
7#include <private/qv4compileddata_p.h>
8#include <private/qqmljsparser_p.h>
9#include <private/qqmljslexer_p.h>
10#include <private/qv4compilerscanfunctions_p.h>
11#include <QCoreApplication>
12#include <QCryptographicHash>
23#define COMPILE_EXCEPTION(location, desc) \
25 recordError(location, desc); \
29void Object::simplifyRequiredProperties() {
34 for (
auto it = this->requiredPropertyExtraDataBegin();
it != this->requiredPropertyExtraDataEnd(); ++
it)
35 required.insert(
it->nameIndex);
36 if (required.isEmpty())
38 for (
auto it = this->propertiesBegin();
it != this->propertiesEnd(); ++
it) {
39 auto requiredIt = required.find(
it->nameIndex);
40 if (requiredIt != required.end()) {
41 it->setIsRequired(
true);
42 required.erase(requiredIt);
46 auto current = this->requiredPropertyExtraDatas->first;
48 if (required.contains(current->nameIndex))
51 requiredPropertyExtraDatas->unlink(prev, current);
52 current = current->
next;
64 paramType->
set(listFlag, 0);
68 paramType->
set(listFlag, typeNameIndex);
72 static_cast<quint32>(builtinType));
79 static const struct TypeNameToType {
83 } propTypeNameToTypes[] = {
99 static const int propTypeNameToTypesCount =
sizeof(propTypeNameToTypes) /
100 sizeof(propTypeNameToTypes[0]);
102 for (
int typeIndex = 0; typeIndex < propTypeNameToTypesCount; ++typeIndex) {
103 const TypeNameToType *
t = propTypeNameToTypes + typeIndex;
122 properties =
pool->New<PoolList<Property> >();
123 aliases =
pool->New<PoolList<Alias> >();
124 qmlEnums =
pool->New<PoolList<Enum>>();
125 qmlSignals =
pool->New<PoolList<Signal> >();
126 bindings =
pool->New<PoolList<Binding> >();
127 functions =
pool->New<PoolList<Function> >();
129 inlineComponents =
pool->New<PoolList<InlineComponent>>();
130 requiredPropertyExtraDatas =
pool->New<PoolList<RequiredPropertyExtraData>>();
136 QSet<int> functionNames;
137 for (
auto functionit =
obj->functionsBegin(); functionit !=
obj->functionsEnd(); ++functionit) {
140 errorLocation->startColumn =
f->location.column();
141 if (functionNames.contains(
f->nameIndex))
142 return tr(
"Duplicate method name");
143 functionNames.insert(
f->nameIndex);
145 for (
auto signalit =
obj->signalsBegin(); signalit !=
obj->signalsEnd(); ++signalit) {
147 if (
s->nameIndex ==
f->nameIndex)
148 return tr(
"Duplicate method name");
152 if (
name.at(0).isUpper())
153 return tr(
"Method names cannot begin with an upper case letter");
155 return tr(
"Illegal method name");
166 for (
Enum *e = qmlEnums->first; e; e = e->next) {
167 if (e->nameIndex == enumeration->
nameIndex)
168 return tr(
"Duplicate scoped enum name");
171 target->qmlEnums->append(enumeration);
181 for (
Signal *
s = qmlSignals->first;
s;
s =
s->next) {
182 if (
s->nameIndex ==
signal->nameIndex)
183 return tr(
"Duplicate signal name");
198 return tr(
"Duplicate property name");
202 return tr(
"Property duplicates alias name");
205 return tr(
"Property names cannot begin with an upper case letter");
207 const int index =
target->properties->append(prop);
208 if (isDefaultProperty) {
209 if (
target->indexOfDefaultPropertyOrAlias != -1) {
210 *errorLocation = defaultToken;
211 return tr(
"Duplicate default property");
224 const auto aliasWithSameName = std::find_if(
target->aliases->begin(),
target->aliases->end(), [&alias](
const Alias &targetAlias){
225 return targetAlias.nameIndex() == alias->nameIndex();
227 if (aliasWithSameName !=
target->aliases->end())
228 return tr(
"Duplicate alias name");
230 const auto aliasSameAsProperty = std::find_if(
target->properties->begin(),
target->properties->end(), [&alias](
const Property &targetProp){
231 return targetProp.nameIndex == alias->nameIndex();
234 if (aliasSameAsProperty !=
target->properties->end())
235 return tr(
"Alias has same name as existing property");
237 if (aliasName.constData()->isUpper())
238 return tr(
"Alias names cannot begin with an upper case letter");
242 if (isDefaultProperty) {
243 if (
target->indexOfDefaultPropertyOrAlias != -1) {
244 *errorLocation = defaultToken;
245 return tr(
"Duplicate default property");
248 target->defaultPropertyIsAlias =
true;
260 functions->append(
f);
265 inlineComponents->append(ic);
270 requiredPropertyExtraDatas->append(extraData);
275 const bool bindingToDefaultProperty = (
b->propertyNameIndex ==
quint32(0));
277 && !bindingToDefaultProperty
283 && existing->isValueBinding() ==
b->isValueBinding()
285 return tr(
"Property value set multiple times");
288 if (bindingToDefaultProperty)
291 bindings->prepend(
b);
298 if (
b->propertyNameIndex == nameIndex)
306 bindings->insertAfter(insertionPoint,
b);
314 node = exprStmt->expression;
330 : jsModule(debugMode)
332 , jsGenerator(&jsModule)
338 ,
engine(&doc->jsParserEngine)
339 , jsGenerator(&doc->jsGenerator)
354 import->location.set(lineNumber,
column);
365 import->location.set(lineNumber,
column);
370 : illegalNames(illegalNames)
372 , _propertyDeclaration(
nullptr)
385 QQmlJS::Parser parser(&
output->jsParserEngine);
387 const bool parseResult = parser.parse();
388 const auto diagnosticMessages = parser.diagnosticMessages();
389 if (!parseResult || !diagnosticMessages.isEmpty()) {
430 int rootObjectIndex = -1;
439 for (
auto object:
output->objects)
440 object->simplifyRequiredProperties();
447 return QQmlJS::AST::Visitor::visit(ast);
468 lastId = lastId->
next;
469 bool isType = lastId->
name.
data()->isUpper();
512 auto inlineComponent = New<InlineComponent>();
514 inlineComponent->objectIndex = idx;
526 { location.startLine, location.startColumn }, node->
initializer)) {
551 if (
bindingsTarget()->findBinding(propertyNameIndex) !=
nullptr) {
556 QVarLengthArray<QQmlJS::AST::UiArrayMemberList *, 16> memberList;
559 memberList.append(member);
560 member = member->
next;
562 for (
int i = memberList.size() - 1;
i >= 0; --
i) {
563 member = memberList.at(
i);
569 appendBinding(qualifiedNameLocation,
name->identifierToken, propertyNameIndex, idx,
true);
578 return QQmlJS::AST::Visitor::visit(
list);
583 return QQmlJS::AST::Visitor::visit(ast);
588 return QQmlJS::AST::Visitor::visit(ast);
593 return QQmlJS::AST::Visitor::visit(ast);
598 return QQmlJS::AST::Visitor::visit(
id);
609 Object *declarationsOverride)
612 while (lastName->next)
613 lastName = lastName->next;
614 if (!lastName->name.constData()->isUpper()) {
615 recordError(lastName->identifierToken,
tr(
"Expected type name"));
647 if (!
error.isEmpty()) {
678 if (!qualifier.
at(0).isUpper()) {
722template<
typename Argument>
731 if (!isUnique(builder)) {
734 "QQmlParser",
"Multiple %1 pragmas found").arg(
name()));
738 pragma->type =
type();
743 "QQmlParser",
"Unknown %1 '%2' in pragma").arg(
name(), bad->value));
753 if constexpr (std::is_same_v<Argument, Pragma::ComponentBehaviorValue>) {
755 }
else if constexpr (std::is_same_v<Argument, Pragma::ListPropertyAssignBehaviorValue>) {
757 }
else if constexpr (std::is_same_v<Argument, Pragma::FunctionSignatureBehaviorValue>) {
759 }
else if constexpr (std::is_same_v<Argument, Pragma::NativeMethodBehaviorValue>) {
761 }
else if constexpr (std::is_same_v<Argument, Pragma::ValueTypeBehaviorValue>) {
773 if (!process(
i->value))
785 if constexpr (std::is_same_v<Argument, Pragma::ComponentBehaviorValue>) {
787 if (
value ==
"Unbound"_L1) {
791 if (
value ==
"Bound"_L1) {
797 }
else if constexpr (std::is_same_v<Argument, Pragma::ListPropertyAssignBehaviorValue>) {
799 if (
value ==
"Append"_L1) {
803 if (
value ==
"Replace"_L1) {
807 if (
value ==
"ReplaceIfNotDefault"_L1) {
813 }
else if constexpr (std::is_same_v<Argument, Pragma::FunctionSignatureBehaviorValue>) {
815 if (
value ==
"Ignored"_L1) {
819 if (
value ==
"Enforced"_L1) {
825 }
else if constexpr (std::is_same_v<Argument, Pragma::NativeMethodBehaviorValue>) {
827 if (
value ==
"AcceptThisObject"_L1) {
831 if (
value ==
"RejectThisObject"_L1) {
837 }
else if constexpr (std::is_same_v<Argument, Pragma::ValueTypeBehaviorValue>) {
838 pragma->valueTypeBehavior = Pragma::ValueTypeBehaviorValues().toInt();
841 pragma->valueTypeBehavior
842 = Pragma::ValueTypeBehaviorValues(pragma->valueTypeBehavior)
843 .setFlag(flag,
value).toInt();
846 if (
value ==
"Reference"_L1) {
850 if (
value ==
"Copy"_L1) {
855 if (
value ==
"Inaddressable"_L1) {
859 if (
value ==
"Addressable"_L1) {
868 Q_UNREACHABLE_RETURN(
nullptr);
873 for (
const Pragma *prev : builder->_pragmas) {
874 if (prev->type ==
type())
884 return "list property assign behavior"_L1;
886 return "component behavior"_L1;
888 return "function signature behavior"_L1;
890 return "native method behavior"_L1;
892 return "value type behavior"_L1;
902 Pragma *pragma = New<Pragma>();
905 if (node->
name ==
"Singleton"_L1) {
907 }
else if (node->
name ==
"Strict"_L1) {
909 }
else if (node->
name ==
"ComponentBehavior"_L1) {
912 }
else if (node->
name ==
"ListPropertyAssignBehavior"_L1) {
915 }
else if (node->
name ==
"FunctionSignatureBehavior"_L1) {
918 }
else if (node->
name ==
"NativeMethodBehavior"_L1) {
921 }
else if (node->
name ==
"ValueTypeBehavior"_L1) {
924 }
else if (node->
name ==
"Translator"_L1) {
930 "QQmlParser",
"Unknown pragma '%1'").arg(node->
name));
935 "QQmlParser",
"Empty pragma found"));
965 Enum *enumeration = New<Enum>();
969 if (enumName.
at(0).isLower())
974 enumeration->
enumValues = New<PoolList<EnumValue>>();
979 QString member = e->member.toString();
981 if (member.
at(0).isLower())
985 if (std::modf(e->value, &part) != 0.0)
987 if (e->value > std::numeric_limits<qint32>::max() || e->value < std::numeric_limits<qint32>::min())
989 enumValue->value = e->value;
991 enumValue->location.set(e->memberToken.startLine, e->memberToken.startColumn);
998 if (!
error.isEmpty()) {
1017 signal->parameters = New<PoolList<Parameter> >();
1029 &
param->type, [
this](
const QString &
str) { return registerString(str); },
1032 errStr.append(
p->type->toString());
1040 for (
const QChar &
ch : signalName) {
1045 tr(
"Signal names cannot begin with an upper case letter"));
1053 if (!
error.isEmpty()) {
1064 Property *
property = New<Property>();
1071 property->setCommonType(builtinPropertyType);
1077 property->setIsList(
true);
1078 }
else if (!typeModifier.
isEmpty()) {
1093 error =
tr(
"Illegal property name");
1097 if (!
error.isEmpty()) {
1098 if (errorLocation.startLine == 0)
1127 "QQmlParser",
"Function declaration inside grouped property"));
1132 foe->node = funDecl;
1133 foe->parentNode = funDecl;
1146 &
f->returnType, idGenerator,
1147 funDecl->typeAnnotation ? funDecl->typeAnnotation->type :
nullptr);
1150 int formalsCount = formals.size();
1151 f->formals.allocate(
pool, formalsCount);
1154 for (
const auto &
arg : formals) {
1158 &functionParameter->type, idGenerator,
1159 arg.typeAnnotation.isNull() ?
nullptr :
arg.typeAnnotation->type);
1172 auto extraData = New<RequiredPropertyExtraData>();
1202 if (
string.isEmpty())
1238 binding->
value.b =
true;
1241 binding->
value.b =
false;
1251 }
else if (QQmlJS::AST::cast<QQmlJS::AST::FunctionExpression *>(expr)) {
1258 }
else if (QQmlJS::AST::cast<QQmlJS::AST::NullExpression *>(expr)) {
1260 binding->
value.nullMarker = 0;
1269 expr->
node = statement;
1281 nodeForString = exprStmt->expression;
1295 const auto finalizeTranslationData = [&](
1315 Object *
object =
nullptr;
1330 Object *
object =
nullptr;
1341 Binding *binding = New<Binding>();
1343 binding->
offset = nameLocation.offset;
1344 binding->
location.
set(nameLocation.startLine, nameLocation.startColumn);
1348 if (!
error.isEmpty()) {
1356 recordError(nameLocation,
tr(
"Invalid component id specification"));
1360 Binding *binding = New<Binding>();
1362 binding->
offset = nameLocation.offset;
1363 binding->
location.
set(nameLocation.startLine, nameLocation.startColumn);
1384 binding->
value.objectIndex = objectIndex;
1386 if (!
error.isEmpty()) {
1393 Alias *alias = New<Alias>();
1422 if (aliasReference.isEmpty()) {
1424 COMPILE_EXCEPTION(rhsLoc,
tr(
"Invalid alias reference. An alias reference must be specified as <id>, <id>.<property> or <id>.<value property>.<property>"));
1430 COMPILE_EXCEPTION(rhsLoc,
tr(
"Invalid alias reference. An alias reference must be specified as <id>, <id>.<property> or <id>.<value property>.<property>"));
1433 if (aliasReference.size() < 1 || aliasReference.size() > 3)
1434 COMPILE_EXCEPTION(rhsLoc,
tr(
"Invalid alias reference. An alias reference must be specified as <id>, <id>.<property> or <id>.<value property>.<property>"));
1438 QString propertyValue = aliasReference.value(1);
1439 if (aliasReference.size() == 3)
1440 propertyValue +=
QLatin1Char(
'.') + aliasReference.at(2);
1447 error =
tr(
"Illegal property name");
1451 if (!
error.isEmpty()) {
1452 if (errorLocation.startLine == 0)
1480 node = stmt->expression;
1490 if (
ch.isLetter() && !
ch.isLower())
1494 if (!
ch.isLetter() &&
ch != u)
1497 for (
int ii = 1; ii <
str.
size(); ++ii) {
1499 if (!
ch.isLetterOrNumber() &&
ch != u)
1520 if (qualifiedIdElement->name ==
QLatin1String(
"id") && qualifiedIdElement->next)
1521 COMPILE_EXCEPTION(qualifiedIdElement->identifierToken,
tr(
"Invalid use of id property"));
1524 QString currentName = qualifiedIdElement->name.toString();
1525 if (qualifiedIdElement->next) {
1528 &&
stringAt(import->qualifierIndex) == currentName) {
1529 qualifiedIdElement = qualifiedIdElement->next;
1530 currentName +=
QLatin1Char(
'.') + qualifiedIdElement->name;
1532 if (!qualifiedIdElement->name.data()->isUpper())
1540 while (qualifiedIdElement->next) {
1542 const bool isAttachedProperty = qualifiedIdElement->name.data()->isUpper();
1544 Binding *binding = (*object)->findBinding(propertyNameIndex);
1546 if (isAttachedProperty) {
1554 binding = New<Binding>();
1556 binding->
offset = qualifiedIdElement->identifierToken.offset;
1557 binding->
location.
set(qualifiedIdElement->identifierToken.startLine,
1558 qualifiedIdElement->identifierToken.startColumn);
1559 binding->
valueLocation.
set(qualifiedIdElement->next->identifierToken.startLine,
1560 qualifiedIdElement->next->identifierToken.startColumn);
1566 if (isAttachedProperty)
1574 binding->
value.objectIndex = objIndex;
1576 QString error = (*object)->appendBinding(binding,
false);
1577 if (!
error.isEmpty()) {
1587 qualifiedIdElement = qualifiedIdElement->next;
1588 if (qualifiedIdElement)
1589 currentName = qualifiedIdElement->name.toString();
1591 *nameToResolve = qualifiedIdElement;
1599 error.message = description;
1607 if (QQmlJS::AST::cast<QQmlJS::AST::StringLiteral *>(expr))
1613 else if (QQmlJS::AST::cast<QQmlJS::AST::NumericLiteral *>(expr))
1618 if (QQmlJS::AST::cast<QQmlJS::AST::NumericLiteral *>(unaryMinus->expression)) {
1636 return QQmlJS::AST::cast<QQmlJS::AST::NullExpression *>(expr);
1643 output.jsGenerator.stringTable.registerString(
output.jsModule.fileName);
1644 output.jsGenerator.stringTable.registerString(
output.jsModule.finalUrl);
1646 Unit *jsUnit =
nullptr;
1648 if (!
output.javaScriptCompilationUnit)
1652 if (
output.javaScriptCompilationUnit->unitData()) {
1653 jsUnit =
const_cast<Unit *
>(
output.javaScriptCompilationUnit->unitData());
1654 output.javaScriptCompilationUnit->dynamicStrings
1655 =
output.jsGenerator.stringTable.allStrings();
1658 jsUnit = createdUnit =
output.jsGenerator.generateUnit();
1664 createdUnit->flags |= Unit::IsSingleton;
1667 createdUnit->flags |= Unit::IsStrict;
1671 switch (
p->componentBehavior) {
1673 createdUnit->flags |= Unit::ComponentsBound;
1681 switch (
p->listPropertyAssignBehavior) {
1683 createdUnit->flags |= Unit::ListPropertyAssignReplace;
1686 createdUnit->flags |= Unit::ListPropertyAssignReplaceIfNotDefault;
1694 switch (
p->functionSignatureBehavior) {
1698 createdUnit->flags |= Unit::FunctionSignaturesIgnored;
1703 switch (
p->nativeMethodBehavior) {
1705 createdUnit->flags |= Unit::NativeMethodsAcceptThisObject;
1713 if (Pragma::ValueTypeBehaviorValues(
p->valueTypeBehavior)
1715 createdUnit->flags |= Unit::ValueTypesCopied;
1717 if (Pragma::ValueTypeBehaviorValues(
p->valueTypeBehavior)
1719 createdUnit->flags |= Unit::ValueTypesAddressable;
1723 if (createdUnit->translationTableSize)
1725 *
index =
p->translationContextIndex;
1730 if (dependencyHasher) {
1732 if (
checksum.size() ==
sizeof(createdUnit->dependencyMD5Checksum)) {
1733 memcpy(createdUnit->dependencyMD5Checksum,
checksum.constData(),
1734 sizeof(createdUnit->dependencyMD5Checksum));
1738 createdUnit->sourceFileIndex =
output.jsGenerator.stringTable.getStringId(
output.jsModule.fileName);
1739 createdUnit->finalUrlIndex =
output.jsGenerator.stringTable.getStringId(
output.jsModule.finalUrl);
1743 output.jsGenerator.stringTable.freeze();
1748 QHash<const Object*, quint32> objectOffsets;
1751 uint nextOffset = objectOffset + objectOffsetTableSize;
1753 objectOffsets.insert(
o, nextOffset);
1756 int signalTableSize = 0;
1757 for (
const Signal *
s =
o->firstSignal();
s;
s =
s->next)
1760 nextOffset += signalTableSize;
1762 int enumTableSize = 0;
1763 for (
const Enum *e =
o->firstEnum(); e; e = e->next)
1766 nextOffset += enumTableSize;
1769 const uint totalSize = nextOffset;
1770 char *
data = (
char*)malloc(totalSize);
1771 memset(
data, 0, totalSize);
1782 *importToWrite = *imp;
1788 for (
int i = 0;
i <
output.objects.size(); ++
i) {
1790 char *
const objectPtr =
data + objectOffsets.value(
o);
1791 *objectTable++ = objectOffsets.value(
o);
1795 objectToWrite->indexOfDefaultPropertyOrAlias =
o->indexOfDefaultPropertyOrAlias;
1796 objectToWrite->setHasAliasAsDefaultProperty(
o->defaultPropertyIsAlias);
1797 objectToWrite->setFlags(QV4::CompiledData::Object::Flags(
o->flags));
1798 objectToWrite->idNameIndex =
o->idNameIndex;
1799 objectToWrite->setObjectId(
o->id);
1800 objectToWrite->location =
o->location;
1801 objectToWrite->locationOfIdProperty =
o->locationOfIdProperty;
1805 objectToWrite->nFunctions =
o->functionCount();
1806 objectToWrite->offsetToFunctions = nextOffset;
1807 nextOffset += objectToWrite->nFunctions *
sizeof(
quint32);
1809 objectToWrite->nProperties =
o->propertyCount();
1810 objectToWrite->offsetToProperties = nextOffset;
1813 objectToWrite->nAliases =
o->aliasCount();
1814 objectToWrite->offsetToAliases = nextOffset;
1817 objectToWrite->nEnums =
o->enumCount();
1818 objectToWrite->offsetToEnums = nextOffset;
1819 nextOffset += objectToWrite->nEnums *
sizeof(
quint32);
1821 objectToWrite->nSignals =
o->signalCount();
1822 objectToWrite->offsetToSignals = nextOffset;
1823 nextOffset += objectToWrite->nSignals *
sizeof(
quint32);
1825 objectToWrite->nBindings =
o->bindingCount();
1826 objectToWrite->offsetToBindings = nextOffset;
1829 objectToWrite->nNamedObjectsInComponent =
o->namedObjectsInComponent.size();
1830 objectToWrite->offsetToNamedObjectsInComponent = nextOffset;
1831 nextOffset += objectToWrite->nNamedObjectsInComponent *
sizeof(
quint32);
1833 objectToWrite->nInlineComponents =
o->inlineComponentCount();
1834 objectToWrite->offsetToInlineComponents = nextOffset;
1837 objectToWrite->nRequiredPropertyExtraData =
o->requiredPropertyExtraDataCount();
1838 objectToWrite->offsetToRequiredPropertyExtraData = nextOffset;
1841 quint32_le *functionsTable =
reinterpret_cast<quint32_le *
>(objectPtr + objectToWrite->offsetToFunctions);
1842 for (
const Function *
f =
o->firstFunction();
f;
f =
f->next)
1843 *functionsTable++ =
o->runtimeFunctionIndices.at(
f->index);
1845 char *propertiesPtr = objectPtr + objectToWrite->offsetToProperties;
1846 for (
const Property *
p =
o->firstProperty();
p;
p =
p->next) {
1848 *propertyToWrite = *
p;
1852 char *aliasesPtr = objectPtr + objectToWrite->offsetToAliases;
1853 for (
const Alias *
a =
o->firstAlias();
a;
a =
a->next) {
1859 char *bindingPtr = objectPtr + objectToWrite->offsetToBindings;
1867 quint32_le *signalOffsetTable =
reinterpret_cast<quint32_le *
>(objectPtr + objectToWrite->offsetToSignals);
1869 char *signalPtr = objectPtr + nextOffset;
1870 for (
const Signal *
s =
o->firstSignal();
s;
s =
s->next) {
1871 *signalOffsetTable++ = signalPtr - objectPtr;
1875 signalToWrite->location =
s->location;
1876 signalToWrite->nParameters =
s->parameters->count;
1880 *parameterToWrite = *
param;
1883 signalTableSize +=
size;
1886 nextOffset += signalTableSize;
1888 quint32_le *enumOffsetTable =
reinterpret_cast<quint32_le*
>(objectPtr + objectToWrite->offsetToEnums);
1889 char *enumPtr = objectPtr + nextOffset;
1890 for (
const Enum *e =
o->firstEnum(); e; e = e->next) {
1891 *enumOffsetTable++ = enumPtr - objectPtr;
1895 enumToWrite->location = e->location;
1896 enumToWrite->nEnumValues = e->enumValues->count;
1899 for (
EnumValue *enumValue = e->enumValues->
first; enumValue; enumValue = enumValue->next, ++enumValueToWrite)
1900 *enumValueToWrite = *enumValue;
1906 quint32_le *namedObjectInComponentPtr =
reinterpret_cast<quint32_le *
>(objectPtr + objectToWrite->offsetToNamedObjectsInComponent);
1907 for (
int i = 0;
i <
o->namedObjectsInComponent.size(); ++
i) {
1908 *namedObjectInComponentPtr++ =
o->namedObjectsInComponent.at(
i);
1911 char *inlineComponentPtr = objectPtr + objectToWrite->offsetToInlineComponents;
1912 for (
auto it =
o->inlineComponentsBegin();
it !=
o->inlineComponentsEnd(); ++
it) {
1919 char *requiredPropertyExtraDataPtr = objectPtr + objectToWrite->offsetToRequiredPropertyExtraData;
1920 for (
auto it =
o->requiredPropertyExtraDataBegin();
it !=
o->requiredPropertyExtraDataEnd(); ++
it) {
1923 *extraDataToWrite = *extraData;
1928 if (!
output.javaScriptCompilationUnit->unitData()) {
1932 jsUnit->unitSize += totalSize;
1933 memcpy(jsUnit->qmlUnit(), qmlUnit, totalSize);
1936 qmlUnit = jsUnit->qmlUnit();
1941 qDebug() <<
"Generated QML unit that is" << totalSize <<
"bytes big contains:";
1942 qDebug() <<
" " << jsUnit->functionTableSize <<
"functions";
1943 qDebug() <<
" " << jsUnit->unitSize <<
"for JS unit";
1944 qDebug() <<
" " << importSize <<
"for imports";
1945 qDebug() <<
" " << nextOffset - objectOffset - objectOffsetTableSize <<
"for" << qmlUnit->
nObjects <<
"objects";
1946 quint32 totalBindingCount = 0;
1949 qDebug() <<
" " << totalBindingCount <<
"bindings";
1951 for (
quint32 i = 0;
i < jsUnit->functionTableSize; ++
i)
1952 totalCodeSize += jsUnit->functionAt(
i)->codeSize;
1953 qDebug() <<
" " << totalCodeSize <<
"bytes total byte code";
1954 qDebug() <<
" " << jsUnit->stringTableSize <<
"strings";
1956 for (
quint32 i = 0;
i < jsUnit->stringTableSize; ++
i)
1958 qDebug() <<
" " << totalStringSize <<
"bytes total strings";
1961 output.javaScriptCompilationUnit->setUnitData(
1962 jsUnit, qmlUnit,
output.jsModule.fileName,
output.jsModule.finalUrl);
1965char *QmlUnitGenerator::writeBindings(
char *bindingPtr,
const Object *
o, BindingFilter
filter)
const
1967 for (
const Binding *
b =
o->firstBinding();
b;
b =
b->next) {
1971 *bindingToWrite = *
b;
1973 bindingToWrite->
value.compiledScriptIndex =
o->runtimeFunctionIndices.at(
b->value.compiledScriptIndex);
1981 bool storeSourceLocations)
1982 :
QV4::Compiler::Codegen(&document->jsGenerator,
false, iface,
1983 storeSourceLocations),
1987 _module = &document->jsModule;
1992 const QList<CompiledFunctionOrExpression> &functions)
1995 if (
c.nameIndex != 0)
2000 QVector<int> runtimeFunctionIndices(functions.size());
2007 auto function =
f.node->asFunctionDefinition();
2022 scan(function ? function->body :
f.node);
2028 return QVector<int>();
2032 for (
int i = 0;
i < functions.size(); ++
i) {
2041 name = function->name.toString();
2043 name = qmlName(qmlFunction);
2047 body = function->body;
2063 function ? function->formals :
nullptr, body);
2064 runtimeFunctionIndices[
i] = idx;
2067 return runtimeFunctionIndices;
2072 if (
object->functionsAndExpressions->count == 0)
2075 QList<QmlIR::CompiledFunctionOrExpression> functionsToCompile;
2076 functionsToCompile.reserve(
object->functionsAndExpressions->count);
2079 functionsToCompile << *foe;
2087 runtimeFunctionIndices);
static QString translate(const char *context, const char *key, const char *disambiguation=nullptr, int n=-1)
\threadsafe
qsizetype size() const noexcept
bool isEmpty() const noexcept
const_reference at(qsizetype i) const noexcept
void append(parameter_type t)
virtual SourceLocation firstSourceLocation() const =0
void accept(BaseVisitor *visitor)
virtual Statement * statementCast()
virtual SourceLocation lastSourceLocation() const =0
virtual ExpressionNode * expressionCast()
virtual FunctionExpression * asFunctionDefinition()
@ Kind_IdentifierExpression
@ Kind_FieldMemberExpression
UiQualifiedId * qualifiedId
UiArrayMemberList * members
UiEnumMemberList * members
UiVersionSpecifier * version
SourceLocation importIdToken
UiQualifiedId * importUri
SourceLocation fileNameToken
SourceLocation importToken
SourceLocation firstSourceLocation() const override
UiObjectDefinition * component
UiQualifiedId * qualifiedTypeNameId
UiQualifiedId * qualifiedId
UiObjectInitializer * initializer
UiQualifiedId * qualifiedTypeNameId
UiObjectInitializer * initializer
SourceLocation firstSourceLocation() const override=0
UiPragmaValueList * values
SourceLocation pragmaToken
SourceLocation semicolonToken
UiParameterList * parameters
SourceLocation identifierToken
SourceLocation firstSourceLocation() const override
enum QQmlJS::AST::UiPublicMember::@662 type
SourceLocation defaultToken() const
bool isDefaultMember() const
SourceLocation typeModifierToken
UiQualifiedId * memberType
SourceLocation firstSourceLocation() const override
SourceLocation identifierToken
UiQualifiedId * qualifiedId
SourceLocation firstSourceLocation() const override
void setCode(const QString &code, int lineno, bool qmlMode=true, CodeContinuation codeContinuation=CodeContinuation::Reset)
bool contains(const T &value) const
iterator insert(const T &value)
constexpr bool isEmpty() const noexcept
Returns whether this string view is empty - that is, whether {size() == 0}.
const_pointer data() const noexcept
QString toString() const
Returns a deep copy of this string view's data as a QString.
constexpr bool isNull() const noexcept
Returns whether this string view is null - that is, whether {data() == nullptr}.
constexpr QStringView mid(qsizetype pos, qsizetype n=-1) const noexcept
Returns the substring of length length starting at position start in this object.
\macro QT_RESTRICTED_CAST_FROM_ASCII
QString mid(qsizetype position, qsizetype n=-1) const &
bool isEmpty() const noexcept
Returns true if the string has no characters; otherwise returns false.
const QChar * constData() const
Returns a pointer to the data stored in the QString.
qsizetype size() const noexcept
Returns the number of characters in this string.
QString first(qsizetype n) const &
const QChar at(qsizetype i) const
Returns the character at the given index position in the string.
bool endsWith(const QString &s, Qt::CaseSensitivity cs=Qt::CaseSensitive) const
Returns true if the string ends with s; otherwise returns false.
QString & append(QChar c)
static constexpr QTypeRevision fromMajorVersion(Major majorVersion)
Produces a QTypeRevision from the given majorVersion with an invalid minor version.
static constexpr QTypeRevision fromVersion(Major majorVersion, Minor minorVersion)
Produces a QTypeRevision from the given majorVersion and minorVersion, both of which need to be a val...
QSet< QString > m_globalNames
virtual int defineFunction(const QString &name, QQmlJS::AST::Node *ast, QQmlJS::AST::FormalParameterList *formals, QQmlJS::AST::StatementList *body)
void enterQmlFunction(QQmlJS::AST::FunctionExpression *ast)
void handleTopLevelFunctionFormals(QQmlJS::AST::FunctionExpression *node)
void enterEnvironment(QQmlJS::AST::Node *node, ContextType compilationMode, const QString &name)
void enterGlobalEnvironment(ContextType compilationMode)
void importFile(const QString &jsfile, const QString &module, int lineNumber, int column) override
void importModule(const QString &uri, const QString &version, const QString &module, int lineNumber, int column) override
void pragmaLibrary() override
ScriptDirectivesCollector(QmlIR::Document *doc)
QSet< QString >::iterator it
std::function< QByteArray()> DependentTypesHasher
void tryGeneratingTranslationBindingBase(QStringView base, QQmlJS::AST::ArgumentList *args, RegisterMainString registerMainString, RegisterCommentString registerCommentString, RegisterContextString registerContextString, FinalizeTranslationData finalizeTranslationData)
QList< QString > QStringList
Constructs a string list that contains the given string, str.
DBusConnection const char DBusError * error
EGLOutputLayerEXT EGLint EGLAttrib value
[5]
static quint32 checksum(const QByteArray &table)
static bool isScript(QStringView tag)
GLenum GLsizei GLsizei GLint * values
[15]
GLboolean GLboolean GLboolean b
GLboolean GLboolean GLboolean GLboolean a
[7]
GLenum GLuint GLintptr GLsizeiptr size
[1]
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLint GLint GLint GLint GLint GLint GLint GLbitfield GLenum filter
GLenum const GLint * param
GLenum GLenum GLsizei void GLsizei void * column
GLenum GLenum GLenum input
GLsizei const GLchar *const * string
[0]
static qreal dot(const QPointF &a, const QPointF &b)
static const quint32 emptyStringIndex
#define COMPILE_EXCEPTION(location, desc)
static QStringList astNodeToStringList(QQmlJS::AST::Node *node)
#define qPrintable(string)
QLatin1StringView QLatin1String
#define QStringLiteral(str)
QT_BEGIN_NAMESPACE constexpr void qSwap(T &value1, T &value2) noexcept(std::is_nothrow_swappable_v< T >)
Q_CORE_EXPORT bool qEnvironmentVariableIsSet(const char *varName) noexcept
static int toInt(const QChar &qc, int R)
QT_BEGIN_NAMESPACE typedef uchar * output
QUrl url("example.com")
[constructor-url-reference]
char * toString(const MyType &t)
[31]
static bool run(IRBuilder *builder, QQmlJS::AST::UiPragma *node, Pragma *pragma)
\inmodule QtCore \reentrant
Location referenceLocation
quint32_le propertyNameIndex
void setNameIndex(quint32 nameIndex)
void setIdIndex(quint32 idIndex)
quint32_le propertyNameIndex
bool isSignalHandler() const
bool isAttachedProperty() const
bool isGroupProperty() const
bool isValueBindingNoAlias() const
union QV4::CompiledData::Binding::@545 value
bool isValueBindingToAlias() const
@ InitializerForReadOnlyDeclaration
static int calculateSize(int nEnumValues)
void set(quint32 line, quint32 column)
quint32_le inheritedTypeNameIndex
@ IsPartOfInlineComponent
static int calculateSizeExcludingSignalsAndEnums(int nFunctions, int nProperties, int nAliases, int nEnums, int nSignals, int nBindings, int nNamedObjectsInComponent, int nInlineComponents, int nRequiredPropertyExtraData)
void set(Flags flags, quint32 typeNameIndexOrCommonType)
quint32_le offsetToObjects
const Object * objectAt(int idx) const
quint32_le offsetToImports
static int calculateSize(int nParameters)
static int calculateSize(const QString &str)
quint32_le offsetToQmlUnit
static void generateUnitChecksum(CompiledData::Unit *unit)
int registerTranslation(const CompiledData::TranslationData &translation)
QString stringForIndex(int index) const
int registerConstant(ReturnedValue v)
int registerString(const QString &str)
QString stringForIndex(int index) const
QQmlJS::AST::Node * parentNode
QQmlJS::AST::UiProgram * program
QString stringAt(int index) const
QV4::Compiler::Module jsModule
QV4::Compiler::JSUnitGenerator jsGenerator
QList< const QV4::CompiledData::Import * > imports
QQmlJS::Engine jsParserEngine
QV4::CompiledData::Location location
PoolList< EnumValue > * enumValues
QV4::CompiledData::Location location
QVector< Object * > _objects
bool resolveQualifiedId(QQmlJS::AST::UiQualifiedId **nameToResolve, Object **object, bool onAssignment=false)
QList< const QV4::CompiledData::Import * > _imports
QList< Pragma * > _pragmas
bool defineQMLObject(int *objectIndex, QQmlJS::AST::UiQualifiedId *qualifiedTypeNameId, const QV4::CompiledData::Location &location, QQmlJS::AST::UiObjectInitializer *initializer, Object *declarationsOverride=nullptr)
QStringView asStringRef(QQmlJS::AST::Node *node)
static QTypeRevision extractVersion(QStringView string)
Object * bindingsTarget() const
IRBuilder(const QSet< QString > &illegalNames)
bool setId(const QQmlJS::SourceLocation &idLocation, QQmlJS::AST::Statement *value)
static bool isRedundantNullInitializerForPropertyDeclaration(Property *property, QQmlJS::AST::Statement *statement)
void appendBinding(QQmlJS::AST::UiQualifiedId *name, QQmlJS::AST::Statement *value, QQmlJS::AST::Node *parentNode)
QString stringAt(int index) const
void setBindingValue(QV4::CompiledData::Binding *binding, QQmlJS::AST::Statement *statement, QQmlJS::AST::Node *parentNode)
QQmlJS::MemoryPool * pool
void accept(QQmlJS::AST::Node *node)
bool visit(QQmlJS::AST::UiArrayMemberList *ast) override
Property * _propertyDeclaration
bool generateFromQml(const QString &code, const QString &url, Document *output)
QList< QQmlJS::DiagnosticMessage > errors
bool insideInlineComponent
static bool isStatementNodeScript(QQmlJS::AST::Statement *statement)
QV4::Compiler::JSUnitGenerator * jsGenerator
bool appendAlias(QQmlJS::AST::UiPublicMember *node)
quint32 registerString(const QString &str) const
QSet< QString > inlineComponentsNames
void tryGeneratingTranslationBinding(QStringView base, QQmlJS::AST::ArgumentList *args, QV4::CompiledData::Binding *binding)
static QString asString(QQmlJS::AST::UiQualifiedId *node)
void recordError(const QQmlJS::SourceLocation &location, const QString &description)
QString sanityCheckFunctionNames(Object *obj, const QSet< QString > &illegalNames, QQmlJS::SourceLocation *errorLocation)
QSet< QString > illegalNames
QStringView textRefAt(const QQmlJS::SourceLocation &loc) const
bool generateRuntimeFunctions(QmlIR::Object *object)
JSCodeGen(Document *document, const QSet< QString > &globalNames, QV4::Compiler::CodegenWarningInterface *iface=QV4::Compiler::defaultCodegenWarningInterface(), bool storeSourceLocations=false)
QVector< int > generateJSCodeForFunctionsAndBindings(const QList< CompiledFunctionOrExpression > &functions)
int indexOfDefaultPropertyOrAlias
QString appendEnum(Enum *enumeration)
void appendRequiredPropertyExtraData(RequiredPropertyExtraData *extraData)
void insertSorted(Binding *b)
QString appendBinding(Binding *b, bool isListBinding)
void appendInlineComponent(InlineComponent *ic)
bool defaultPropertyIsAlias
QString appendSignal(Signal *signal)
QString bindingAsString(Document *doc, int scriptIndex) const
void init(QQmlJS::MemoryPool *pool, int typeNameIndex, int idIndex, const QV4::CompiledData::Location &location)
Object * declarationsOverride
QString appendAlias(Alias *prop, const QString &aliasName, bool isDefaultProperty, const QQmlJS::SourceLocation &defaultToken, QQmlJS::SourceLocation *errorLocation)
QString appendProperty(Property *prop, const QString &propertyName, bool isDefaultProperty, const QQmlJS::SourceLocation &defaultToken, QQmlJS::SourceLocation *errorLocation)
PoolList< CompiledFunctionOrExpression > * functionsAndExpressions
void appendFunction(QmlIR::Function *f)
quint32 inheritedTypeNameIndex
QV4::CompiledData::Location locationOfIdProperty
Binding * findBinding(quint32 nameIndex) const
static bool initType(QV4::CompiledData::ParameterType *type, const IdGenerator &idGenerator, const QQmlJS::AST::Type *annotation)
static QV4::CompiledData::CommonType stringToBuiltinType(const QString &typeName)
@ FunctionSignatureBehavior
@ ListPropertyAssignBehavior
void generate(Document &output, const QV4::CompiledData::DependentTypesHasher &dependencyHasher=QV4::CompiledData::DependentTypesHasher())
PoolList< Parameter > * parameters
QStringList parameterStringList(const QV4::Compiler::StringTableGenerator *stringPool) const