From 0e45db9a04c339ee7aa0e692e5ad3827db388628 Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Wed, 15 Aug 2018 13:18:32 +0200 Subject: 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 --- src/qml/compiler/qv4compileddata.cpp | 42 ++++++++++++++++++++++++++++++++++++ src/qml/compiler/qv4compileddata_p.h | 2 ++ 2 files changed, 44 insertions(+) (limited to 'src/qml/compiler') 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 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 *resolveSet) { if (!m_module) @@ -512,6 +523,37 @@ const ExportEntry *CompilationUnit::lookupNameInExportTable(const ExportEntry *f return matchingExport; } +void CompilationUnit::getExportedNamesRecursively(QStringList *names, QVector *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 *resolveSet); const ExportEntry *lookupNameInExportTable(const ExportEntry *firstExportEntry, int tableSize, QV4::String *name) const; + void getExportedNamesRecursively(QStringList *names, QVector *exportNameSet, bool includeDefaultExport = true) const; QString m_fileName; // initialized from data->sourceFileIndex QString m_finalUrlString; // initialized from data->finalUrlIndex -- cgit v1.2.3