aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml
diff options
context:
space:
mode:
authorSimon Hausmann <simon.hausmann@qt.io>2018-08-15 13:18:32 +0200
committerSimon Hausmann <simon.hausmann@qt.io>2018-08-15 18:55:53 +0000
commit0e45db9a04c339ee7aa0e692e5ad3827db388628 (patch)
treebfe5f6c20051da567785932547a1b405180611d9 /src/qml
parent7f59171d00d185828b32d5d3e1cc9bcd34e7b003 (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.cpp42
-rw-r--r--src/qml/compiler/qv4compileddata_p.h2
-rw-r--r--src/qml/jsruntime/qv4engine.cpp2
-rw-r--r--src/qml/jsruntime/qv4engine_p.h2
-rw-r--r--src/qml/jsruntime/qv4module.cpp22
-rw-r--r--src/qml/jsruntime/qv4module_p.h2
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 *);