| 1 | /**************************************************************************** | 
| 2 | ** | 
| 3 | ** Copyright (C) 2016 The Qt Company Ltd. | 
| 4 | ** Contact: https://www.qt.io/licensing/ | 
| 5 | ** | 
| 6 | ** This file is part of the tools applications of the Qt Toolkit. | 
| 7 | ** | 
| 8 | ** $QT_BEGIN_LICENSE:LGPL$ | 
| 9 | ** Commercial License Usage | 
| 10 | ** Licensees holding valid commercial Qt licenses may use this file in | 
| 11 | ** accordance with the commercial license agreement provided with the | 
| 12 | ** Software or, alternatively, in accordance with the terms contained in | 
| 13 | ** a written agreement between you and The Qt Company. For licensing terms | 
| 14 | ** and conditions see https://www.qt.io/terms-conditions. For further | 
| 15 | ** information use the contact form at https://www.qt.io/contact-us. | 
| 16 | ** | 
| 17 | ** GNU Lesser General Public License Usage | 
| 18 | ** Alternatively, this file may be used under the terms of the GNU Lesser | 
| 19 | ** General Public License version 3 as published by the Free Software | 
| 20 | ** Foundation and appearing in the file LICENSE.LGPL3 included in the | 
| 21 | ** packaging of this file. Please review the following information to | 
| 22 | ** ensure the GNU Lesser General Public License version 3 requirements | 
| 23 | ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. | 
| 24 | ** | 
| 25 | ** GNU General Public License Usage | 
| 26 | ** Alternatively, this file may be used under the terms of the GNU | 
| 27 | ** General Public License version 2.0 or (at your option) the GNU General | 
| 28 | ** Public license version 3 or any later version approved by the KDE Free | 
| 29 | ** Qt Foundation. The licenses are as published by the Free Software | 
| 30 | ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 | 
| 31 | ** included in the packaging of this file. Please review the following | 
| 32 | ** information to ensure the GNU General Public License requirements will | 
| 33 | ** be met: https://www.gnu.org/licenses/gpl-2.0.html and | 
| 34 | ** https://www.gnu.org/licenses/gpl-3.0.html. | 
| 35 | ** | 
| 36 | ** $QT_END_LICENSE$ | 
| 37 | ** | 
| 38 | ****************************************************************************/ | 
| 39 | #ifndef QQMLIRBUILDER_P_H | 
| 40 | #define QQMLIRBUILDER_P_H | 
| 41 |  | 
| 42 | // | 
| 43 | //  W A R N I N G | 
| 44 | //  ------------- | 
| 45 | // | 
| 46 | // This file is not part of the Qt API.  It exists purely as an | 
| 47 | // implementation detail.  This header file may change from version to | 
| 48 | // version without notice, or even be removed. | 
| 49 | // | 
| 50 | // We mean it. | 
| 51 | // | 
| 52 |  | 
| 53 | #include <private/qqmljsast_p.h> | 
| 54 | #include <private/qqmljsengine_p.h> | 
| 55 | #include <private/qv4compiler_p.h> | 
| 56 | #include <private/qv4compileddata_p.h> | 
| 57 | #include <private/qqmljsmemorypool_p.h> | 
| 58 | #include <private/qqmljsfixedpoolarray_p.h> | 
| 59 | #include <private/qv4codegen_p.h> | 
| 60 | #include <private/qv4compiler_p.h> | 
| 61 | #include <QTextStream> | 
| 62 | #include <QCoreApplication> | 
| 63 |  | 
| 64 | QT_BEGIN_NAMESPACE | 
| 65 |  | 
| 66 | class QQmlPropertyCache; | 
| 67 | class QQmlContextData; | 
| 68 | class QQmlTypeNameCache; | 
| 69 | struct QQmlIRLoader; | 
| 70 |  | 
| 71 | namespace QmlIR { | 
| 72 |  | 
| 73 | struct Document; | 
| 74 |  | 
| 75 | template <typename T> | 
| 76 | struct PoolList | 
| 77 | { | 
| 78 |     PoolList() | 
| 79 |         : first(nullptr) | 
| 80 |         , last(nullptr) | 
| 81 |     {} | 
| 82 |  | 
| 83 |     T *first; | 
| 84 |     T *last; | 
| 85 |     int count = 0; | 
| 86 |  | 
| 87 |     int append(T *item) { | 
| 88 |         item->next = nullptr; | 
| 89 |         if (last) | 
| 90 |             last->next = item; | 
| 91 |         else | 
| 92 |             first = item; | 
| 93 |         last = item; | 
| 94 |         return count++; | 
| 95 |     } | 
| 96 |  | 
| 97 |     void prepend(T *item) { | 
| 98 |         item->next = first; | 
| 99 |         first = item; | 
| 100 |         if (!last) | 
| 101 |             last = first; | 
| 102 |         ++count; | 
| 103 |     } | 
| 104 |  | 
| 105 |     template <typename Sortable, typename Base, Sortable Base::*sortMember> | 
| 106 |     T *findSortedInsertionPoint(T *item) const | 
| 107 |     { | 
| 108 |         T *insertPos = nullptr; | 
| 109 |  | 
| 110 |         for (T *it = first; it; it = it->next) { | 
| 111 |             if (!(it->*sortMember <= item->*sortMember)) | 
| 112 |                 break; | 
| 113 |             insertPos = it; | 
| 114 |         } | 
| 115 |  | 
| 116 |         return insertPos; | 
| 117 |     } | 
| 118 |  | 
| 119 |     void insertAfter(T *insertionPoint, T *item) { | 
| 120 |         if (!insertionPoint) { | 
| 121 |             prepend(item); | 
| 122 |         } else if (insertionPoint == last) { | 
| 123 |             append(item); | 
| 124 |         } else { | 
| 125 |             item->next = insertionPoint->next; | 
| 126 |             insertionPoint->next = item; | 
| 127 |             ++count; | 
| 128 |         } | 
| 129 |     } | 
| 130 |  | 
| 131 |     T *unlink(T *before, T *item) { | 
| 132 |         T * const newNext = item->next; | 
| 133 |  | 
| 134 |         if (before) | 
| 135 |             before->next = newNext; | 
| 136 |         else | 
| 137 |             first = newNext; | 
| 138 |  | 
| 139 |         if (item == last) { | 
| 140 |             if (newNext) | 
| 141 |                 last = newNext; | 
| 142 |             else | 
| 143 |                 last = first; | 
| 144 |         } | 
| 145 |  | 
| 146 |         --count; | 
| 147 |         return newNext; | 
| 148 |     } | 
| 149 |  | 
| 150 |     T *slowAt(int index) const | 
| 151 |     { | 
| 152 |         T *result = first; | 
| 153 |         while (index > 0 && result) { | 
| 154 |             result = result->next; | 
| 155 |             --index; | 
| 156 |         } | 
| 157 |         return result; | 
| 158 |     } | 
| 159 |  | 
| 160 |     struct Iterator { | 
| 161 |         // turn Iterator into a proper iterator | 
| 162 |         using iterator_category = std::forward_iterator_tag; | 
| 163 |         using value_type = T; | 
| 164 |         using difference_type = ptrdiff_t; | 
| 165 |         using pointer = T *; | 
| 166 |         using reference = T &; | 
| 167 |  | 
| 168 |         T *ptr; | 
| 169 |  | 
| 170 |         explicit Iterator(T *p) : ptr(p) {} | 
| 171 |  | 
| 172 |         T *operator->() { | 
| 173 |             return ptr; | 
| 174 |         } | 
| 175 |  | 
| 176 |         const T *operator->() const { | 
| 177 |             return ptr; | 
| 178 |         } | 
| 179 |  | 
| 180 |         T &operator*() { | 
| 181 |             return *ptr; | 
| 182 |         } | 
| 183 |  | 
| 184 |         const T &operator*() const { | 
| 185 |             return *ptr; | 
| 186 |         } | 
| 187 |  | 
| 188 |         Iterator& operator++() { | 
| 189 |             ptr = ptr->next; | 
| 190 |             return *this; | 
| 191 |         } | 
| 192 |  | 
| 193 |         Iterator operator++(int) { | 
| 194 |             Iterator that {ptr}; | 
| 195 |             ptr = ptr->next; | 
| 196 |             return that; | 
| 197 |         } | 
| 198 |  | 
| 199 |         bool operator==(const Iterator &rhs) const { | 
| 200 |             return ptr == rhs.ptr; | 
| 201 |         } | 
| 202 |  | 
| 203 |         bool operator!=(const Iterator &rhs) const { | 
| 204 |             return ptr != rhs.ptr; | 
| 205 |         } | 
| 206 |     }; | 
| 207 |  | 
| 208 |     Iterator begin() { return Iterator(first); } | 
| 209 |     Iterator end() { return Iterator(nullptr); } | 
| 210 |  | 
| 211 |     using iterator = Iterator; | 
| 212 | }; | 
| 213 |  | 
| 214 | struct Object; | 
| 215 |  | 
| 216 | struct EnumValue : public QV4::CompiledData::EnumValue | 
| 217 | { | 
| 218 |     EnumValue *next; | 
| 219 | }; | 
| 220 |  | 
| 221 | struct Enum | 
| 222 | { | 
| 223 |     int nameIndex; | 
| 224 |     QV4::CompiledData::Location location; | 
| 225 |     PoolList<EnumValue> *enumValues; | 
| 226 |  | 
| 227 |     int enumValueCount() const { return enumValues->count; } | 
| 228 |     PoolList<EnumValue>::Iterator enumValuesBegin() const { return enumValues->begin(); } | 
| 229 |     PoolList<EnumValue>::Iterator enumValuesEnd() const { return enumValues->end(); } | 
| 230 |  | 
| 231 |     Enum *next; | 
| 232 | }; | 
| 233 |  | 
| 234 |  | 
| 235 | struct Parameter : public QV4::CompiledData::Parameter | 
| 236 | { | 
| 237 |     Parameter *next; | 
| 238 |  | 
| 239 |     bool init(QV4::Compiler::JSUnitGenerator *stringGenerator, const QString ¶meterName, const QString &typeName); | 
| 240 |     static bool init(QV4::CompiledData::Parameter *param, const QV4::Compiler::JSUnitGenerator *stringGenerator, | 
| 241 |                      int parameterNameIndex, int typeNameIndex); | 
| 242 |     static bool initType(QV4::CompiledData::ParameterType *paramType, | 
| 243 |                          const QV4::Compiler::JSUnitGenerator *stringGenerator, int typeNameIndex); | 
| 244 |  | 
| 245 |     static QV4::CompiledData::BuiltinType stringToBuiltinType(const QString &typeName); | 
| 246 | }; | 
| 247 |  | 
| 248 | struct Signal | 
| 249 | { | 
| 250 |     int nameIndex; | 
| 251 |     QV4::CompiledData::Location location; | 
| 252 |     PoolList<Parameter> *parameters; | 
| 253 |  | 
| 254 |     QStringList parameterStringList(const QV4::Compiler::StringTableGenerator *stringPool) const; | 
| 255 |  | 
| 256 |     int parameterCount() const { return parameters->count; } | 
| 257 |     PoolList<Parameter>::Iterator parametersBegin() const { return parameters->begin(); } | 
| 258 |     PoolList<Parameter>::Iterator parametersEnd() const { return parameters->end(); } | 
| 259 |  | 
| 260 |     Signal *next; | 
| 261 | }; | 
| 262 |  | 
| 263 | struct Property : public QV4::CompiledData::Property | 
| 264 | { | 
| 265 |     Property *next; | 
| 266 | }; | 
| 267 |  | 
| 268 | struct Binding : public QV4::CompiledData::Binding | 
| 269 | { | 
| 270 |     // The offset in the source file where the binding appeared. This is used for sorting to ensure | 
| 271 |     // that assignments to list properties are done in the correct order. We use the offset here instead | 
| 272 |     // of Binding::location as the latter has limited precision. | 
| 273 |     quint32 offset; | 
| 274 |     // Binding's compiledScriptIndex is index in object's functionsAndExpressions | 
| 275 |     Binding *next; | 
| 276 | }; | 
| 277 |  | 
| 278 | struct InlineComponent : public QV4::CompiledData::InlineComponent | 
| 279 | { | 
| 280 |     InlineComponent *next; | 
| 281 | }; | 
| 282 |  | 
| 283 | struct Alias : public QV4::CompiledData::Alias | 
| 284 | { | 
| 285 |     Alias *next; | 
| 286 | }; | 
| 287 |  | 
| 288 | struct  : public QV4::CompiledData::RequiredPropertyExtraData | 
| 289 | { | 
| 290 |     RequiredPropertyExtraData *; | 
| 291 | }; | 
| 292 |  | 
| 293 | struct Function | 
| 294 | { | 
| 295 |     QV4::CompiledData::Location location; | 
| 296 |     int nameIndex; | 
| 297 |     quint32 index; // index in parsedQML::functions | 
| 298 |     QQmlJS::FixedPoolArray<Parameter> formals; | 
| 299 |     QV4::CompiledData::ParameterType returnType; | 
| 300 |  | 
| 301 |     // --- QQmlPropertyCacheCreator interface | 
| 302 |     const Parameter *formalsBegin() const { return formals.begin(); } | 
| 303 |     const Parameter *formalsEnd() const { return formals.end(); } | 
| 304 |     // --- | 
| 305 |  | 
| 306 |     Function *next; | 
| 307 | }; | 
| 308 |  | 
| 309 | struct Q_QMLCOMPILER_PRIVATE_EXPORT CompiledFunctionOrExpression | 
| 310 | { | 
| 311 |     CompiledFunctionOrExpression() | 
| 312 |     {} | 
| 313 |  | 
| 314 |     QQmlJS::AST::Node *parentNode = nullptr; // FunctionDeclaration, Statement or Expression | 
| 315 |     QQmlJS::AST::Node *node = nullptr; // FunctionDeclaration, Statement or Expression | 
| 316 |     quint32 nameIndex = 0; | 
| 317 |     CompiledFunctionOrExpression *next = nullptr; | 
| 318 | }; | 
| 319 |  | 
| 320 | struct Q_QMLCOMPILER_PRIVATE_EXPORT Object | 
| 321 | { | 
| 322 |     Q_DECLARE_TR_FUNCTIONS(Object) | 
| 323 | public: | 
| 324 |     quint32 inheritedTypeNameIndex; | 
| 325 |     quint32 idNameIndex; | 
| 326 |     int id; | 
| 327 |     int indexOfDefaultPropertyOrAlias; | 
| 328 |     bool defaultPropertyIsAlias; | 
| 329 |     bool isInlineComponent = false; | 
| 330 |     quint32 flags; | 
| 331 |  | 
| 332 |     QV4::CompiledData::Location location; | 
| 333 |     QV4::CompiledData::Location locationOfIdProperty; | 
| 334 |  | 
| 335 |     const Property *firstProperty() const { return properties->first; } | 
| 336 |     int propertyCount() const { return properties->count; } | 
| 337 |     Alias *firstAlias() const { return aliases->first; } | 
| 338 |     int aliasCount() const { return aliases->count; } | 
| 339 |     const Enum *firstEnum() const { return qmlEnums->first; } | 
| 340 |     int enumCount() const { return qmlEnums->count; } | 
| 341 |     const Signal *firstSignal() const { return qmlSignals->first; } | 
| 342 |     int signalCount() const { return qmlSignals->count; } | 
| 343 |     Binding *firstBinding() const { return bindings->first; } | 
| 344 |     int bindingCount() const { return bindings->count; } | 
| 345 |     const Function *firstFunction() const { return functions->first; } | 
| 346 |     int functionCount() const { return functions->count; } | 
| 347 |     const InlineComponent *inlineComponent() const { return inlineComponents->first; } | 
| 348 |     int inlineComponentCount() const { return inlineComponents->count; } | 
| 349 |     const RequiredPropertyExtraData *() const {return requiredPropertyExtraDatas->first; } | 
| 350 |     int () const { return requiredPropertyExtraDatas->count; } | 
| 351 |     void simplifyRequiredProperties(); | 
| 352 |  | 
| 353 |     PoolList<Binding>::Iterator bindingsBegin() const { return bindings->begin(); } | 
| 354 |     PoolList<Binding>::Iterator bindingsEnd() const { return bindings->end(); } | 
| 355 |     PoolList<Property>::Iterator propertiesBegin() const { return properties->begin(); } | 
| 356 |     PoolList<Property>::Iterator propertiesEnd() const { return properties->end(); } | 
| 357 |     PoolList<Alias>::Iterator aliasesBegin() const { return aliases->begin(); } | 
| 358 |     PoolList<Alias>::Iterator aliasesEnd() const { return aliases->end(); } | 
| 359 |     PoolList<Enum>::Iterator enumsBegin() const { return qmlEnums->begin(); } | 
| 360 |     PoolList<Enum>::Iterator enumsEnd() const { return qmlEnums->end(); } | 
| 361 |     PoolList<Signal>::Iterator signalsBegin() const { return qmlSignals->begin(); } | 
| 362 |     PoolList<Signal>::Iterator signalsEnd() const { return qmlSignals->end(); } | 
| 363 |     PoolList<Function>::Iterator functionsBegin() const { return functions->begin(); } | 
| 364 |     PoolList<Function>::Iterator functionsEnd() const { return functions->end(); } | 
| 365 |     PoolList<InlineComponent>::Iterator inlineComponentsBegin() const { return inlineComponents->begin(); } | 
| 366 |     PoolList<InlineComponent>::Iterator inlineComponentsEnd() const { return inlineComponents->end(); } | 
| 367 |     PoolList<RequiredPropertyExtraData>::Iterator () const {return requiredPropertyExtraDatas->begin(); } | 
| 368 |     PoolList<RequiredPropertyExtraData>::Iterator () const {return requiredPropertyExtraDatas->end(); } | 
| 369 |  | 
| 370 |     // If set, then declarations for this object (and init bindings for these) should go into the | 
| 371 |     // specified object. Used for declarations inside group properties. | 
| 372 |     Object *declarationsOverride; | 
| 373 |  | 
| 374 |     void init(QQmlJS::MemoryPool *pool, int typeNameIndex, int idIndex, const QQmlJS::SourceLocation &location = QQmlJS::SourceLocation()); | 
| 375 |  | 
| 376 |     QString appendEnum(Enum *enumeration); | 
| 377 |     QString appendSignal(Signal *signal); | 
| 378 |     QString appendProperty(Property *prop, const QString &propertyName, bool isDefaultProperty, const QQmlJS::SourceLocation &defaultToken, QQmlJS::SourceLocation *errorLocation); | 
| 379 |     QString appendAlias(Alias *prop, const QString &aliasName, bool isDefaultProperty, const QQmlJS::SourceLocation &defaultToken, QQmlJS::SourceLocation *errorLocation); | 
| 380 |     void appendFunction(QmlIR::Function *f); | 
| 381 |     void appendInlineComponent(InlineComponent *ic); | 
| 382 |     void (RequiredPropertyExtraData *); | 
| 383 |  | 
| 384 |     QString appendBinding(Binding *b, bool isListBinding); | 
| 385 |     Binding *findBinding(quint32 nameIndex) const; | 
| 386 |     Binding *unlinkBinding(Binding *before, Binding *binding) { return bindings->unlink(before, item: binding); } | 
| 387 |     void insertSorted(Binding *b); | 
| 388 |     QString bindingAsString(Document *doc, int scriptIndex) const; | 
| 389 |  | 
| 390 |     PoolList<CompiledFunctionOrExpression> *functionsAndExpressions; | 
| 391 |     QQmlJS::FixedPoolArray<int> runtimeFunctionIndices; | 
| 392 |  | 
| 393 |     QQmlJS::FixedPoolArray<quint32> namedObjectsInComponent; | 
| 394 |     int namedObjectsInComponentCount() const { return namedObjectsInComponent.size(); } | 
| 395 |     const quint32 *namedObjectsInComponentTable() const { return namedObjectsInComponent.begin(); } | 
| 396 |  | 
| 397 | private: | 
| 398 |     friend struct ::QQmlIRLoader; | 
| 399 |  | 
| 400 |     PoolList<Property> *properties; | 
| 401 |     PoolList<Alias> *aliases; | 
| 402 |     PoolList<Enum> *qmlEnums; | 
| 403 |     PoolList<Signal> *qmlSignals; | 
| 404 |     PoolList<Binding> *bindings; | 
| 405 |     PoolList<Function> *functions; | 
| 406 |     PoolList<InlineComponent> *inlineComponents; | 
| 407 |     PoolList<RequiredPropertyExtraData> *; | 
| 408 | }; | 
| 409 |  | 
| 410 | struct Q_QMLCOMPILER_PRIVATE_EXPORT Pragma | 
| 411 | { | 
| 412 |     enum PragmaType { | 
| 413 |         PragmaSingleton = 0x1 | 
| 414 |     }; | 
| 415 |     quint32 type; | 
| 416 |  | 
| 417 |     QV4::CompiledData::Location location; | 
| 418 | }; | 
| 419 |  | 
| 420 | struct Q_QMLCOMPILER_PRIVATE_EXPORT Document | 
| 421 | { | 
| 422 |     Document(bool debugMode); | 
| 423 |     QString code; | 
| 424 |     QQmlJS::Engine jsParserEngine; | 
| 425 |     QV4::Compiler::Module jsModule; | 
| 426 |     QList<const QV4::CompiledData::Import *> imports; | 
| 427 |     QList<Pragma*> pragmas; | 
| 428 |     QQmlJS::AST::UiProgram *program; | 
| 429 |     QVector<Object*> objects; | 
| 430 |     QV4::Compiler::JSUnitGenerator jsGenerator; | 
| 431 |  | 
| 432 |     QV4::CompiledData::CompilationUnit javaScriptCompilationUnit; | 
| 433 |  | 
| 434 |     int registerString(const QString &str) { return jsGenerator.registerString(str); } | 
| 435 |     QString stringAt(int index) const { return jsGenerator.stringForIndex(index); } | 
| 436 |  | 
| 437 |     int objectCount() const {return objects.size();} | 
| 438 |     Object* objectAt(int i) const {return objects.at(i);} | 
| 439 | }; | 
| 440 |  | 
| 441 | class Q_QMLCOMPILER_PRIVATE_EXPORT ScriptDirectivesCollector : public QQmlJS::Directives | 
| 442 | { | 
| 443 |     QmlIR::Document *document; | 
| 444 |     QQmlJS::Engine *engine; | 
| 445 |     QV4::Compiler::JSUnitGenerator *jsGenerator; | 
| 446 |  | 
| 447 | public: | 
| 448 |     ScriptDirectivesCollector(QmlIR::Document *doc); | 
| 449 |  | 
| 450 |     void pragmaLibrary() override; | 
| 451 |     void importFile(const QString &jsfile, const QString &module, int lineNumber, int column) override; | 
| 452 |     void importModule(const QString &uri, const QString &version, const QString &module, int lineNumber, int column) override; | 
| 453 | }; | 
| 454 |  | 
| 455 | struct Q_QMLCOMPILER_PRIVATE_EXPORT IRBuilder : public QQmlJS::AST::Visitor | 
| 456 | { | 
| 457 |     Q_DECLARE_TR_FUNCTIONS(QQmlCodeGenerator) | 
| 458 | public: | 
| 459 |     IRBuilder(const QSet<QString> &illegalNames); | 
| 460 |     bool generateFromQml(const QString &code, const QString &url, Document *output); | 
| 461 |  | 
| 462 |     static bool isSignalPropertyName(const QString &name); | 
| 463 |  | 
| 464 |     using QQmlJS::AST::Visitor::visit; | 
| 465 |     using QQmlJS::AST::Visitor::endVisit; | 
| 466 |  | 
| 467 |     bool visit(QQmlJS::AST::UiArrayMemberList *ast) override; | 
| 468 |     bool visit(QQmlJS::AST::UiImport *ast) override; | 
| 469 |     bool visit(QQmlJS::AST::UiPragma *ast) override; | 
| 470 |     bool (QQmlJS::AST::UiHeaderItemList *ast) override; | 
| 471 |     bool visit(QQmlJS::AST::UiObjectInitializer *ast) override; | 
| 472 |     bool visit(QQmlJS::AST::UiObjectMemberList *ast) override; | 
| 473 |     bool visit(QQmlJS::AST::UiParameterList *ast) override; | 
| 474 |     bool visit(QQmlJS::AST::UiProgram *) override; | 
| 475 |     bool visit(QQmlJS::AST::UiQualifiedId *ast) override; | 
| 476 |     bool visit(QQmlJS::AST::UiArrayBinding *ast) override; | 
| 477 |     bool visit(QQmlJS::AST::UiObjectBinding *ast) override; | 
| 478 |     bool visit(QQmlJS::AST::UiObjectDefinition *ast) override; | 
| 479 |     bool visit(QQmlJS::AST::UiInlineComponent *ast) override; | 
| 480 |     bool visit(QQmlJS::AST::UiEnumDeclaration *ast) override; | 
| 481 |     bool visit(QQmlJS::AST::UiPublicMember *ast) override; | 
| 482 |     bool visit(QQmlJS::AST::UiScriptBinding *ast) override; | 
| 483 |     bool visit(QQmlJS::AST::UiSourceElement *ast) override; | 
| 484 |     bool visit(QQmlJS::AST::UiRequired *ast) override; | 
| 485 |  | 
| 486 |     void throwRecursionDepthError() override | 
| 487 |     { | 
| 488 |         recordError(location: QQmlJS::SourceLocation(), | 
| 489 |                     QStringLiteral("Maximum statement or expression depth exceeded" )); | 
| 490 |     } | 
| 491 |  | 
| 492 |     void accept(QQmlJS::AST::Node *node); | 
| 493 |  | 
| 494 |     // returns index in _objects | 
| 495 |     bool defineQMLObject(int *objectIndex, QQmlJS::AST::UiQualifiedId *qualifiedTypeNameId, const QQmlJS::SourceLocation &location, QQmlJS::AST::UiObjectInitializer *initializer, Object *declarationsOverride = nullptr); | 
| 496 |     bool defineQMLObject(int *objectIndex, QQmlJS::AST::UiObjectDefinition *node, Object *declarationsOverride = nullptr) | 
| 497 |     { return defineQMLObject(objectIndex, qualifiedTypeNameId: node->qualifiedTypeNameId, location: node->qualifiedTypeNameId->firstSourceLocation(), initializer: node->initializer, declarationsOverride); } | 
| 498 |  | 
| 499 |     static QString asString(QQmlJS::AST::UiQualifiedId *node); | 
| 500 |     QStringRef asStringRef(QQmlJS::AST::Node *node); | 
| 501 |     static void (const QStringRef &string, int *maj, int *min); | 
| 502 |     QStringRef textRefAt(const QQmlJS::SourceLocation &loc) const | 
| 503 |     { return QStringRef(&sourceCode, loc.offset, loc.length); } | 
| 504 |     QStringRef textRefAt(const QQmlJS::SourceLocation &first, | 
| 505 |                          const QQmlJS::SourceLocation &last) const; | 
| 506 |  | 
| 507 |     void setBindingValue(QV4::CompiledData::Binding *binding, QQmlJS::AST::Statement *statement, | 
| 508 |                          QQmlJS::AST::Node *parentNode); | 
| 509 |     void tryGeneratingTranslationBinding(const QStringRef &base, QQmlJS::AST::ArgumentList *args, QV4::CompiledData::Binding *binding); | 
| 510 |  | 
| 511 |     void appendBinding(QQmlJS::AST::UiQualifiedId *name, QQmlJS::AST::Statement *value, | 
| 512 |                        QQmlJS::AST::Node *parentNode); | 
| 513 |     void appendBinding(QQmlJS::AST::UiQualifiedId *name, int objectIndex, bool isOnAssignment = false); | 
| 514 |     void appendBinding(const QQmlJS::SourceLocation &qualifiedNameLocation, | 
| 515 |                        const QQmlJS::SourceLocation &nameLocation, quint32 propertyNameIndex, | 
| 516 |                        QQmlJS::AST::Statement *value, QQmlJS::AST::Node *parentNode); | 
| 517 |     void appendBinding(const QQmlJS::SourceLocation &qualifiedNameLocation, | 
| 518 |                        const QQmlJS::SourceLocation &nameLocation, quint32 propertyNameIndex, | 
| 519 |                        int objectIndex, bool isListItem = false, bool isOnAssignment = false); | 
| 520 |  | 
| 521 |     bool appendAlias(QQmlJS::AST::UiPublicMember *node); | 
| 522 |  | 
| 523 |     Object *bindingsTarget() const; | 
| 524 |  | 
| 525 |     bool setId(const QQmlJS::SourceLocation &idLocation, QQmlJS::AST::Statement *value); | 
| 526 |  | 
| 527 |     // resolves qualified name (font.pixelSize for example) and returns the last name along | 
| 528 |     // with the object any right-hand-side of a binding should apply to. | 
| 529 |     bool resolveQualifiedId(QQmlJS::AST::UiQualifiedId **nameToResolve, Object **object, bool onAssignment = false); | 
| 530 |  | 
| 531 |     void recordError(const QQmlJS::SourceLocation &location, const QString &description); | 
| 532 |  | 
| 533 |     quint32 registerString(const QString &str) const { return jsGenerator->registerString(str); } | 
| 534 |     template <typename _Tp> _Tp *New() { return pool->New<_Tp>(); } | 
| 535 |  | 
| 536 |     QString stringAt(int index) const { return jsGenerator->stringForIndex(index); } | 
| 537 |  | 
| 538 |     static bool isStatementNodeScript(QQmlJS::AST::Statement *statement); | 
| 539 |     static bool isRedundantNullInitializerForPropertyDeclaration(Property *property, QQmlJS::AST::Statement *statement); | 
| 540 |  | 
| 541 |     QString sanityCheckFunctionNames(Object *obj, const QSet<QString> &illegalNames, QQmlJS::SourceLocation *errorLocation); | 
| 542 |  | 
| 543 |     QList<QQmlJS::DiagnosticMessage> errors; | 
| 544 |  | 
| 545 |     QSet<QString> illegalNames; | 
| 546 |     QSet<QString> inlineComponentsNames; | 
| 547 |  | 
| 548 |     QList<const QV4::CompiledData::Import *> _imports; | 
| 549 |     QList<Pragma*> _pragmas; | 
| 550 |     QVector<Object*> _objects; | 
| 551 |  | 
| 552 |     QV4::CompiledData::TypeReferenceMap _typeReferences; | 
| 553 |  | 
| 554 |     Object *_object; | 
| 555 |     Property *_propertyDeclaration; | 
| 556 |  | 
| 557 |     QQmlJS::MemoryPool *pool; | 
| 558 |     QString sourceCode; | 
| 559 |     QV4::Compiler::JSUnitGenerator *jsGenerator; | 
| 560 |  | 
| 561 |     bool insideInlineComponent = false; | 
| 562 | }; | 
| 563 |  | 
| 564 | struct Q_QMLCOMPILER_PRIVATE_EXPORT QmlUnitGenerator | 
| 565 | { | 
| 566 |     void generate(Document &output, const QV4::CompiledData::DependentTypesHasher &dependencyHasher = QV4::CompiledData::DependentTypesHasher()); | 
| 567 |  | 
| 568 | private: | 
| 569 |     typedef bool (Binding::*BindingFilter)() const; | 
| 570 |     char *writeBindings(char *bindingPtr, const Object *o, BindingFilter filter) const; | 
| 571 | }; | 
| 572 |  | 
| 573 | struct Q_QMLCOMPILER_PRIVATE_EXPORT JSCodeGen : public QV4::Compiler::Codegen | 
| 574 | { | 
| 575 |     JSCodeGen(Document *document, const QSet<QString> &globalNames); | 
| 576 |  | 
| 577 |     // Returns mapping from input functions to index in IR::Module::functions / compiledData->runtimeFunctions | 
| 578 |     QVector<int> generateJSCodeForFunctionsAndBindings(const QList<CompiledFunctionOrExpression> &functions); | 
| 579 |  | 
| 580 |     bool generateCodeForComponents(const QVector<quint32> &componentRoots); | 
| 581 |     bool compileComponent(int contextObject); | 
| 582 |     bool compileJavaScriptCodeInObjectsRecursively(int objectIndex, int scopeObjectIndex); | 
| 583 |  | 
| 584 | private: | 
| 585 |     Document *document; | 
| 586 | }; | 
| 587 |  | 
| 588 | } // namespace QmlIR | 
| 589 |  | 
| 590 | QT_END_NAMESPACE | 
| 591 |  | 
| 592 | #endif // QQMLIRBUILDER_P_H | 
| 593 |  |