diff options
author | Simon Hausmann <simon.hausmann@qt.io> | 2018-08-15 13:18:32 +0200 |
---|---|---|
committer | Simon Hausmann <simon.hausmann@qt.io> | 2018-08-15 18:55:53 +0000 |
commit | 0e45db9a04c339ee7aa0e692e5ad3827db388628 (patch) | |
tree | bfe5f6c20051da567785932547a1b405180611d9 /src/qml | |
parent | 7f59171d00d185828b32d5d3e1cc9bcd34e7b003 (diff) |
Fix order of own property names of module namespace objects
They must be sorted, no duplicates and only one default entry at most.
Change-Id: Ia9c0e54a761ce7cbfebb837330bf3769d505eb3b
Reviewed-by: Lars Knoll <lars.knoll@qt.io>
Diffstat (limited to 'src/qml')
-rw-r--r-- | src/qml/compiler/qv4compileddata.cpp | 42 | ||||
-rw-r--r-- | src/qml/compiler/qv4compileddata_p.h | 2 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4engine.cpp | 2 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4engine_p.h | 2 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4module.cpp | 22 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4module_p.h | 2 |
6 files changed, 59 insertions, 13 deletions
diff --git a/src/qml/compiler/qv4compileddata.cpp b/src/qml/compiler/qv4compileddata.cpp index 46034050e0..a4e49377a8 100644 --- a/src/qml/compiler/qv4compileddata.cpp +++ b/src/qml/compiler/qv4compileddata.cpp @@ -440,6 +440,17 @@ const Value *CompilationUnit::resolveExport(QV4::String *exportName) return resolveExportRecursively(exportName, &resolveSet); } +QStringList CompilationUnit::exportedNames() const +{ + QStringList names; + QVector<const CompiledData::CompilationUnit*> exportNameSet; + getExportedNamesRecursively(&names, &exportNameSet); + names.sort(); + auto last = std::unique(names.begin(), names.end()); + names.erase(last, names.end()); + return names; +} + const Value *CompilationUnit::resolveExportRecursively(QV4::String *exportName, QVector<ResolveSetEntry> *resolveSet) { if (!m_module) @@ -512,6 +523,37 @@ const ExportEntry *CompilationUnit::lookupNameInExportTable(const ExportEntry *f return matchingExport; } +void CompilationUnit::getExportedNamesRecursively(QStringList *names, QVector<const CompilationUnit*> *exportNameSet, bool includeDefaultExport) const +{ + if (exportNameSet->contains(this)) + return; + exportNameSet->append(this); + + const auto append = [names, includeDefaultExport](const QString &name) { + if (!includeDefaultExport && name == QLatin1String("default")) + return; + names->append(name); + }; + + for (uint i = 0; i < data->localExportEntryTableSize; ++i) { + const CompiledData::ExportEntry &entry = data->localExportEntryTable()[i]; + append(stringAt(entry.exportName)); + } + + for (uint i = 0; i < data->indirectExportEntryTableSize; ++i) { + const CompiledData::ExportEntry &entry = data->indirectExportEntryTable()[i]; + append(stringAt(entry.exportName)); + } + + for (uint i = 0; i < data->starExportEntryTableSize; ++i) { + const CompiledData::ExportEntry &entry = data->starExportEntryTable()[i]; + auto dependentModuleUnit = engine->loadModule(QUrl(stringAt(entry.moduleRequest)), this); + if (!dependentModuleUnit) + return; + dependentModuleUnit->getExportedNamesRecursively(names, exportNameSet, /*includeDefaultExport*/false); + } +} + void CompilationUnit::evaluate() { if (m_moduleEvaluated) diff --git a/src/qml/compiler/qv4compileddata_p.h b/src/qml/compiler/qv4compileddata_p.h index 7581fe3fff..f0043cc6af 100644 --- a/src/qml/compiler/qv4compileddata_p.h +++ b/src/qml/compiler/qv4compileddata_p.h @@ -1169,6 +1169,7 @@ public: QStringList moduleRequests() const; Heap::Module *instantiate(ExecutionEngine *engine); const Value *resolveExport(QV4::String *exportName); + QStringList exportedNames() const; void evaluate(); QV4::Function *linkToEngine(QV4::ExecutionEngine *engine); @@ -1202,6 +1203,7 @@ private: const Value *resolveExportRecursively(QV4::String *exportName, QVector<ResolveSetEntry> *resolveSet); const ExportEntry *lookupNameInExportTable(const ExportEntry *firstExportEntry, int tableSize, QV4::String *name) const; + void getExportedNamesRecursively(QStringList *names, QVector<const CompilationUnit *> *exportNameSet, bool includeDefaultExport = true) const; QString m_fileName; // initialized from data->sourceFileIndex QString m_finalUrlString; // initialized from data->finalUrlIndex diff --git a/src/qml/jsruntime/qv4engine.cpp b/src/qml/jsruntime/qv4engine.cpp index e92d7c69ba..90c75b204d 100644 --- a/src/qml/jsruntime/qv4engine.cpp +++ b/src/qml/jsruntime/qv4engine.cpp @@ -1700,7 +1700,7 @@ void ExecutionEngine::injectModule(const QQmlRefPointer<CompiledData::Compilatio modules.insert(moduleUnit->finalUrl(), moduleUnit); } -QQmlRefPointer<CompiledData::CompilationUnit> ExecutionEngine::loadModule(const QUrl &_url, CompiledData::CompilationUnit *referrer) +QQmlRefPointer<CompiledData::CompilationUnit> ExecutionEngine::loadModule(const QUrl &_url, const CompiledData::CompilationUnit *referrer) { QUrl url = QQmlTypeLoader::normalize(_url); if (referrer) diff --git a/src/qml/jsruntime/qv4engine_p.h b/src/qml/jsruntime/qv4engine_p.h index 00879511d3..4cd7e40013 100644 --- a/src/qml/jsruntime/qv4engine_p.h +++ b/src/qml/jsruntime/qv4engine_p.h @@ -582,7 +582,7 @@ public: QHash<QUrl, QQmlRefPointer<CompiledData::CompilationUnit>> modules; void injectModule(const QQmlRefPointer<CompiledData::CompilationUnit> &moduleUnit); - QQmlRefPointer<CompiledData::CompilationUnit> loadModule(const QUrl &_url, CompiledData::CompilationUnit *referrer = nullptr); + QQmlRefPointer<CompiledData::CompilationUnit> loadModule(const QUrl &_url, const CompiledData::CompilationUnit *referrer = nullptr); #endif private: diff --git a/src/qml/jsruntime/qv4module.cpp b/src/qml/jsruntime/qv4module.cpp index e8e84ac965..5974c9be73 100644 --- a/src/qml/jsruntime/qv4module.cpp +++ b/src/qml/jsruntime/qv4module.cpp @@ -162,7 +162,9 @@ bool Module::virtualDeleteProperty(Managed *m, PropertyKey id) struct ModuleNamespaceIterator : ObjectOwnPropertyKeyIterator { - uint exportIndex = 0; + QStringList exportedNames; + int exportIndex = 0; + ModuleNamespaceIterator(const QStringList &names) : exportedNames(names) {} ~ModuleNamespaceIterator() override = default; PropertyKey next(const Object *o, Property *pd = nullptr, PropertyAttributes *attrs = nullptr) override; @@ -171,23 +173,23 @@ struct ModuleNamespaceIterator : ObjectOwnPropertyKeyIterator PropertyKey ModuleNamespaceIterator::next(const Object *o, Property *pd, PropertyAttributes *attrs) { const Module *module = static_cast<const Module *>(o); - if (exportIndex < module->d()->unit->unitData()->localExportEntryTableSize) { + if (exportIndex < exportedNames.count()) { if (attrs) *attrs = Attr_Data; - if (pd) { - const CompiledData::ExportEntry &entry = module->d()->unit->unitData()->localExportEntryTable()[exportIndex]; - Scope scope(module->engine()); - ScopedString exportName(scope, module->d()->unit->runtimeStrings[entry.exportName]); - pd->value = *module->d()->unit->resolveExport(exportName); - } + Scope scope(module->engine()); + ScopedString exportName(scope, scope.engine->newString(exportedNames.at(exportIndex))); exportIndex++; + if (pd) + pd->value = *module->d()->unit->resolveExport(exportName); + return exportName->toPropertyKey(); } return ObjectOwnPropertyKeyIterator::next(o, pd, attrs); } -OwnPropertyKeyIterator *Module::virtualOwnPropertyKeys(const Object *) +OwnPropertyKeyIterator *Module::virtualOwnPropertyKeys(const Object *o) { - return new ModuleNamespaceIterator; + const Module *module = static_cast<const Module *>(o); + return new ModuleNamespaceIterator(module->d()->unit->exportedNames()); } Heap::Object *Module::virtualGetPrototypeOf(const Managed *) diff --git a/src/qml/jsruntime/qv4module_p.h b/src/qml/jsruntime/qv4module_p.h index c22e6cd1c3..bb004b3b44 100644 --- a/src/qml/jsruntime/qv4module_p.h +++ b/src/qml/jsruntime/qv4module_p.h @@ -81,7 +81,7 @@ struct Q_QML_EXPORT Module : public Object { static bool virtualDefineOwnProperty(Managed *, PropertyKey, const Property *, PropertyAttributes); static bool virtualPut(Managed *, PropertyKey, const Value &, Value *); static bool virtualDeleteProperty(Managed *m, PropertyKey id); - static OwnPropertyKeyIterator *virtualOwnPropertyKeys(const Object *); + static OwnPropertyKeyIterator *virtualOwnPropertyKeys(const Object *m); static Heap::Object *virtualGetPrototypeOf(const Managed *); static bool virtualSetPrototypeOf(Managed *, const Object *proto); static bool virtualIsExtensible(const Managed *); |