QmlJS: Clean up qmljslink.{h|cpp}

Fix linter warnings, apply coding style, avoid foreach, drop dead code.

Change-Id: Ib98488725262c1bd3a04de0db0397a9129e21901
Reviewed-by: Tim Jenssen <tim.jenssen@qt.io>
This commit is contained in:
Ulf Hermann
2019-10-22 17:54:14 +02:00
parent 9760d02b77
commit 3b65c0a5d5
2 changed files with 142 additions and 118 deletions

View File

@@ -46,63 +46,51 @@ class ImportCacheKey
{ {
public: public:
explicit ImportCacheKey(const ImportInfo &info) explicit ImportCacheKey(const ImportInfo &info)
: type(info.type()) : m_type(info.type())
, path(info.path()) , m_path(info.path())
, majorVersion(info.version().majorVersion()) , m_majorVersion(info.version().majorVersion())
, minorVersion(info.version().minorVersion()) , m_minorVersion(info.version().minorVersion())
{} {}
int type; private:
QString path; friend uint qHash(const ImportCacheKey &);
int majorVersion; friend bool operator==(const ImportCacheKey &, const ImportCacheKey &);
int minorVersion;
int m_type;
QString m_path;
int m_majorVersion;
int m_minorVersion;
}; };
uint qHash(const ImportCacheKey &info) uint qHash(const ImportCacheKey &info)
{ {
return ::qHash(info.type) ^ ::qHash(info.path) ^ return ::qHash(info.m_type) ^ ::qHash(info.m_path) ^
::qHash(info.majorVersion) ^ ::qHash(info.minorVersion); ::qHash(info.m_majorVersion) ^ ::qHash(info.m_minorVersion);
} }
bool operator==(const ImportCacheKey &i1, const ImportCacheKey &i2) bool operator==(const ImportCacheKey &i1, const ImportCacheKey &i2)
{ {
return i1.type == i2.type return i1.m_type == i2.m_type
&& i1.path == i2.path && i1.m_path == i2.m_path
&& i1.majorVersion == i2.majorVersion && i1.m_majorVersion == i2.m_majorVersion
&& i1.minorVersion == i2.minorVersion; && i1.m_minorVersion == i2.m_minorVersion;
} }
} }
class LinkPrivate class LinkPrivate
{ {
public: public:
Snapshot snapshot;
ValueOwner *valueOwner;
QStringList importPaths;
LibraryInfo builtins;
ViewerContext vContext;
QHash<ImportCacheKey, Import> importCache;
QHash<QString, QList<ModuleApiInfo> > importableModuleApis;
Document::Ptr document;
QList<DiagnosticMessage> *diagnosticMessages;
QHash<QString, QList<DiagnosticMessage> > *allDiagnosticMessages;
Context::ImportsPerDocument linkImports(); Context::ImportsPerDocument linkImports();
void populateImportedTypes(Imports *imports, Document::Ptr doc); void populateImportedTypes(Imports *imports, const Document::Ptr &doc);
Import importFileOrDirectory( Import importFileOrDirectory(
Document::Ptr doc, const Document::Ptr &doc,
const ImportInfo &importInfo); const ImportInfo &importInfo);
Import importNonFile( Import importNonFile(
Document::Ptr doc, const Document::Ptr &doc,
const ImportInfo &importInfo); const ImportInfo &importInfo);
void importObject(Bind *bind, const QString &name, ObjectValue *object, NameId *targetNamespace);
bool importLibrary(Document::Ptr doc, bool importLibrary(const Document::Ptr &doc,
const QString &libraryPath, const QString &libraryPath,
Import *import, Import *import,
const QString &importPath = QString()); const QString &importPath = QString());
@@ -110,12 +98,29 @@ public:
LanguageUtils::ComponentVersion version, LanguageUtils::ComponentVersion version,
const LibraryInfo &libraryInfo, const LibraryInfo &libraryInfo,
const QString &libraryPath); const QString &libraryPath);
void loadImplicitDirectoryImports(Imports *imports, Document::Ptr doc); void loadImplicitDirectoryImports(Imports *imports, const Document::Ptr &doc);
void loadImplicitDefaultImports(Imports *imports); void loadImplicitDefaultImports(Imports *imports);
void error(const Document::Ptr &doc, const AST::SourceLocation &loc, const QString &message); void error(const Document::Ptr &doc, const AST::SourceLocation &loc, const QString &message);
void warning(const Document::Ptr &doc, const AST::SourceLocation &loc, const QString &message); void warning(const Document::Ptr &doc, const AST::SourceLocation &loc, const QString &message);
void appendDiagnostic(const Document::Ptr &doc, const DiagnosticMessage &message); void appendDiagnostic(const Document::Ptr &doc, const DiagnosticMessage &message);
private:
friend class Link;
Snapshot m_snapshot;
ValueOwner *m_valueOwner = nullptr;
QStringList m_importPaths;
LibraryInfo m_builtins;
ViewerContext m_vContext;
QHash<ImportCacheKey, Import> importCache;
QHash<QString, QList<ModuleApiInfo>> importableModuleApis;
Document::Ptr document;
QList<DiagnosticMessage> *diagnosticMessages = nullptr;
QHash<QString, QList<DiagnosticMessage>> *allDiagnosticMessages = nullptr;
}; };
/*! /*!
@@ -132,11 +137,11 @@ public:
Link::Link(const Snapshot &snapshot, const ViewerContext &vContext, const LibraryInfo &builtins) Link::Link(const Snapshot &snapshot, const ViewerContext &vContext, const LibraryInfo &builtins)
: d(new LinkPrivate) : d(new LinkPrivate)
{ {
d->valueOwner = new ValueOwner; d->m_valueOwner = new ValueOwner;
d->snapshot = snapshot; d->m_snapshot = snapshot;
d->importPaths = vContext.paths; d->m_importPaths = vContext.paths;
d->builtins = builtins; d->m_builtins = builtins;
d->vContext = vContext; d->m_vContext = vContext;
d->diagnosticMessages = nullptr; d->diagnosticMessages = nullptr;
d->allDiagnosticMessages = nullptr; d->allDiagnosticMessages = nullptr;
@@ -147,38 +152,39 @@ Link::Link(const Snapshot &snapshot, const ViewerContext &vContext, const Librar
{ {
// populate engine with types from C++ // populate engine with types from C++
for (auto it = cppDataHash.cbegin(), end = cppDataHash.cend(); it != end; ++it) for (auto it = cppDataHash.cbegin(), end = cppDataHash.cend(); it != end; ++it)
d->valueOwner->cppQmlTypes().load(it.key(), it.value().exportedTypes); d->m_valueOwner->cppQmlTypes().load(it.key(), it.value().exportedTypes);
} }
// build an object with the context properties from C++ // build an object with the context properties from C++
ObjectValue *cppContextProperties = d->valueOwner->newObject(/* prototype = */ nullptr); ObjectValue *cppContextProperties = d->m_valueOwner->newObject(/* prototype = */ nullptr);
for (const ModelManagerInterface::CppData &cppData : cppDataHash) { for (const ModelManagerInterface::CppData &cppData : cppDataHash) {
for (auto it = cppData.contextProperties.cbegin(), end = cppData.contextProperties.cend(); for (auto it = cppData.contextProperties.cbegin(),
it != end; ++it) { end = cppData.contextProperties.cend();
it != end; ++it) {
const Value *value = nullptr; const Value *value = nullptr;
const QString cppTypeName = it.value(); const QString &cppTypeName = it.value();
if (!cppTypeName.isEmpty()) if (!cppTypeName.isEmpty())
value = d->valueOwner->cppQmlTypes().objectByCppName(cppTypeName); value = d->m_valueOwner->cppQmlTypes().objectByCppName(cppTypeName);
if (!value) if (!value)
value = d->valueOwner->unknownValue(); value = d->m_valueOwner->unknownValue();
cppContextProperties->setMember(it.key(), value); cppContextProperties->setMember(it.key(), value);
} }
} }
d->valueOwner->cppQmlTypes().setCppContextProperties(cppContextProperties); d->m_valueOwner->cppQmlTypes().setCppContextProperties(cppContextProperties);
} }
} }
ContextPtr Link::operator()(QHash<QString, QList<DiagnosticMessage> > *messages) ContextPtr Link::operator()(QHash<QString, QList<DiagnosticMessage> > *messages)
{ {
d->allDiagnosticMessages = messages; d->allDiagnosticMessages = messages;
return Context::create(d->snapshot, d->valueOwner, d->linkImports(), d->vContext); return Context::create(d->m_snapshot, d->m_valueOwner, d->linkImports(), d->m_vContext);
} }
ContextPtr Link::operator()(const Document::Ptr &doc, QList<DiagnosticMessage> *messages) ContextPtr Link::operator()(const Document::Ptr &doc, QList<DiagnosticMessage> *messages)
{ {
d->document = doc; d->document = doc;
d->diagnosticMessages = messages; d->diagnosticMessages = messages;
return Context::create(d->snapshot, d->valueOwner, d->linkImports(), d->vContext); return Context::create(d->m_snapshot, d->m_valueOwner, d->linkImports(), d->m_vContext);
} }
Link::~Link() Link::~Link()
@@ -191,34 +197,38 @@ Context::ImportsPerDocument LinkPrivate::linkImports()
Context::ImportsPerDocument importsPerDocument; Context::ImportsPerDocument importsPerDocument;
// load builtin objects // load builtin objects
if (builtins.pluginTypeInfoStatus() == LibraryInfo::DumpDone if (m_builtins.pluginTypeInfoStatus() == LibraryInfo::DumpDone
|| builtins.pluginTypeInfoStatus() == LibraryInfo::TypeInfoFileDone) { || m_builtins.pluginTypeInfoStatus() == LibraryInfo::TypeInfoFileDone) {
valueOwner->cppQmlTypes().load(QLatin1String("<builtins>"), builtins.metaObjects()); m_valueOwner->cppQmlTypes().load(QLatin1String("<builtins>"), m_builtins.metaObjects());
} else { } else {
valueOwner->cppQmlTypes().load(QLatin1String("<defaults>"), CppQmlTypesLoader::defaultQtObjects); m_valueOwner->cppQmlTypes().load(QLatin1String("<defaults>"),
CppQmlTypesLoader::defaultQtObjects);
} }
// load library objects shipped with Creator // load library objects shipped with Creator
valueOwner->cppQmlTypes().load(QLatin1String("<defaultQt4>"), CppQmlTypesLoader::defaultLibraryObjects); m_valueOwner->cppQmlTypes().load(QLatin1String("<defaultQt4>"),
CppQmlTypesLoader::defaultLibraryObjects);
if (document) { if (document) {
// do it on document first, to make sure import errors are shown // do it on document first, to make sure import errors are shown
Imports *imports = new Imports(valueOwner); auto *imports = new Imports(m_valueOwner);
// Add custom imports for the opened document // Add custom imports for the opened document
for (const auto &provider : CustomImportsProvider::allProviders()) for (const auto &provider : CustomImportsProvider::allProviders()) {
foreach (const auto &import, provider->imports(valueOwner, document.data())) const auto providerImports = provider->imports(m_valueOwner, document.data());
for (const auto &import : providerImports)
importCache.insert(ImportCacheKey(import.info), import); importCache.insert(ImportCacheKey(import.info), import);
}
populateImportedTypes(imports, document); populateImportedTypes(imports, document);
importsPerDocument.insert(document.data(), QSharedPointer<Imports>(imports)); importsPerDocument.insert(document.data(), QSharedPointer<Imports>(imports));
} }
foreach (Document::Ptr doc, snapshot) { for (const Document::Ptr &doc : qAsConst(m_snapshot)) {
if (doc == document) if (doc == document)
continue; continue;
Imports *imports = new Imports(valueOwner); auto *imports = new Imports(m_valueOwner);
populateImportedTypes(imports, doc); populateImportedTypes(imports, doc);
importsPerDocument.insert(doc.data(), QSharedPointer<Imports>(imports)); importsPerDocument.insert(doc.data(), QSharedPointer<Imports>(imports));
} }
@@ -226,7 +236,7 @@ Context::ImportsPerDocument LinkPrivate::linkImports()
return importsPerDocument; return importsPerDocument;
} }
void LinkPrivate::populateImportedTypes(Imports *imports, Document::Ptr doc) void LinkPrivate::populateImportedTypes(Imports *imports, const Document::Ptr &doc)
{ {
importableModuleApis.clear(); importableModuleApis.clear();
@@ -239,7 +249,8 @@ void LinkPrivate::populateImportedTypes(Imports *imports, Document::Ptr doc)
loadImplicitDirectoryImports(imports, doc); loadImplicitDirectoryImports(imports, doc);
// explicit imports, whether directories, files or libraries // explicit imports, whether directories, files or libraries
foreach (const ImportInfo &info, doc->bind()->imports()) { const auto docImports = doc->bind()->imports();
for (const ImportInfo &info : docImports) {
Import import = importCache.value(ImportCacheKey(info)); Import import = importCache.value(ImportCacheKey(info));
// ensure usage of the right ImportInfo, the cached import // ensure usage of the right ImportInfo, the cached import
@@ -285,7 +296,7 @@ void LinkPrivate::populateImportedTypes(Imports *imports, Document::Ptr doc)
import "file.js" as Foo import "file.js" as Foo
*/ */
Import LinkPrivate::importFileOrDirectory(Document::Ptr doc, const ImportInfo &importInfo) Import LinkPrivate::importFileOrDirectory(const Document::Ptr &doc, const ImportInfo &importInfo)
{ {
Import import; Import import;
import.info = importInfo; import.info = importInfo;
@@ -296,20 +307,19 @@ Import LinkPrivate::importFileOrDirectory(Document::Ptr doc, const ImportInfo &i
if (importInfo.type() == ImportType::Directory if (importInfo.type() == ImportType::Directory
|| importInfo.type() == ImportType::ImplicitDirectory) { || importInfo.type() == ImportType::ImplicitDirectory) {
import.object = new ObjectValue(valueOwner); import.object = new ObjectValue(m_valueOwner);
importLibrary(doc, path, &import); importLibrary(doc, path, &import);
const QList<Document::Ptr> &documentsInDirectory = snapshot.documentsInDirectory(path); const QList<Document::Ptr> documentsInDirectory = m_snapshot.documentsInDirectory(path);
foreach (Document::Ptr importedDoc, documentsInDirectory) { for (const Document::Ptr &importedDoc : documentsInDirectory) {
if (importedDoc->bind()->rootObjectValue()) { if (importedDoc->bind()->rootObjectValue()) {
const QString targetName = importedDoc->componentName(); const QString targetName = importedDoc->componentName();
import.object->setMember(targetName, importedDoc->bind()->rootObjectValue()); import.object->setMember(targetName, importedDoc->bind()->rootObjectValue());
} }
} }
} else if (importInfo.type() == ImportType::File) { } else if (importInfo.type() == ImportType::File) {
Document::Ptr importedDoc = snapshot.document(path); if (Document::Ptr importedDoc = m_snapshot.document(path))
if (importedDoc)
import.object = importedDoc->bind()->rootObjectValue(); import.object = importedDoc->bind()->rootObjectValue();
} else if (importInfo.type() == ImportType::QrcFile) { } else if (importInfo.type() == ImportType::QrcFile) {
QLocale locale; QLocale locale;
@@ -318,19 +328,19 @@ Import LinkPrivate::importFileOrDirectory(Document::Ptr doc, const ImportInfo &i
if (filePaths.isEmpty()) if (filePaths.isEmpty())
filePaths = ModelManagerInterface::instance()->filesAtQrcPath(path); filePaths = ModelManagerInterface::instance()->filesAtQrcPath(path);
if (!filePaths.isEmpty()) { if (!filePaths.isEmpty()) {
Document::Ptr importedDoc = snapshot.document(filePaths.at(0)); if (Document::Ptr importedDoc = m_snapshot.document(filePaths.at(0)))
if (importedDoc)
import.object = importedDoc->bind()->rootObjectValue(); import.object = importedDoc->bind()->rootObjectValue();
} }
} else if (importInfo.type() == ImportType::QrcDirectory){ } else if (importInfo.type() == ImportType::QrcDirectory){
import.object = new ObjectValue(valueOwner); import.object = new ObjectValue(m_valueOwner);
importLibrary(doc, path, &import); importLibrary(doc, path, &import);
const QMap<QString, QStringList> paths = ModelManagerInterface::instance()->filesInQrcPath(path); const QMap<QString, QStringList> paths
= ModelManagerInterface::instance()->filesInQrcPath(path);
for (auto iter = paths.cbegin(), end = paths.cend(); iter != end; ++iter) { for (auto iter = paths.cbegin(), end = paths.cend(); iter != end; ++iter) {
if (ModelManagerInterface::guessLanguageOfFile(iter.key()).isQmlLikeLanguage()) { if (ModelManagerInterface::guessLanguageOfFile(iter.key()).isQmlLikeLanguage()) {
Document::Ptr importedDoc = snapshot.document(iter.value().at(0)); Document::Ptr importedDoc = m_snapshot.document(iter.value().at(0));
if (importedDoc && importedDoc->bind()->rootObjectValue()) { if (importedDoc && importedDoc->bind()->rootObjectValue()) {
const QString targetName = QFileInfo(iter.key()).baseName(); const QString targetName = QFileInfo(iter.key()).baseName();
import.object->setMember(targetName, importedDoc->bind()->rootObjectValue()); import.object->setMember(targetName, importedDoc->bind()->rootObjectValue());
@@ -341,10 +351,11 @@ Import LinkPrivate::importFileOrDirectory(Document::Ptr doc, const ImportInfo &i
return import; return import;
} }
static ModuleApiInfo findBestModuleApi(const QList<ModuleApiInfo> &apis, const ComponentVersion &version) static ModuleApiInfo findBestModuleApi(const QList<ModuleApiInfo> &apis,
const ComponentVersion &version)
{ {
ModuleApiInfo best; ModuleApiInfo best;
foreach (const ModuleApiInfo &moduleApi, apis) { for (const ModuleApiInfo &moduleApi : apis) {
if (moduleApi.version <= version if (moduleApi.version <= version
&& (!best.version.isValid() || best.version < moduleApi.version)) { && (!best.version.isValid() || best.version < moduleApi.version)) {
best = moduleApi; best = moduleApi;
@@ -357,33 +368,33 @@ static ModuleApiInfo findBestModuleApi(const QList<ModuleApiInfo> &apis, const C
import Qt 4.6 import Qt 4.6
import Qt 4.6 as Xxx import Qt 4.6 as Xxx
*/ */
Import LinkPrivate::importNonFile(Document::Ptr doc, const ImportInfo &importInfo) Import LinkPrivate::importNonFile(const Document::Ptr &doc, const ImportInfo &importInfo)
{ {
Import import; Import import;
import.info = importInfo; import.info = importInfo;
import.object = new ObjectValue(valueOwner); import.object = new ObjectValue(m_valueOwner);
import.valid = true; import.valid = true;
const QString packageName = importInfo.name(); const QString packageName = importInfo.name();
const ComponentVersion version = importInfo.version(); const ComponentVersion version = importInfo.version();
QString libraryPath = modulePath(packageName, version.toString(), importPaths); QString libraryPath = modulePath(packageName, version.toString(), m_importPaths);
bool importFound = !libraryPath.isEmpty() && importLibrary(doc, libraryPath, &import); bool importFound = !libraryPath.isEmpty() && importLibrary(doc, libraryPath, &import);
// if there are cpp-based types for this package, use them too // if there are cpp-based types for this package, use them too
if (valueOwner->cppQmlTypes().hasModule(packageName)) { if (m_valueOwner->cppQmlTypes().hasModule(packageName)) {
importFound = true; importFound = true;
foreach (const CppComponentValue *object, const auto objects = m_valueOwner->cppQmlTypes().createObjectsForImport(packageName,
valueOwner->cppQmlTypes().createObjectsForImport(packageName, version)) { version);
for (const CppComponentValue *object : objects)
import.object->setMember(object->className(), object); import.object->setMember(object->className(), object);
}
} }
// check module apis that previous imports may have enabled // check module apis that previous imports may have enabled
ModuleApiInfo moduleApi = findBestModuleApi(importableModuleApis.value(packageName), version); ModuleApiInfo moduleApi = findBestModuleApi(importableModuleApis.value(packageName), version);
if (moduleApi.version.isValid()) { if (moduleApi.version.isValid()) {
importFound = true; importFound = true;
import.object->setPrototype(valueOwner->cppQmlTypes().objectByCppName(moduleApi.cppName)); import.object->setPrototype(m_valueOwner->cppQmlTypes().objectByCppName(moduleApi.cppName));
} }
// TODO: at the moment there is not any types information on Qbs imports. // TODO: at the moment there is not any types information on Qbs imports.
@@ -402,22 +413,21 @@ Import LinkPrivate::importNonFile(Document::Ptr doc, const ImportInfo &importInf
"For Qbs projects, declare and set a qmlImportPaths property in your product " "For Qbs projects, declare and set a qmlImportPaths property in your product "
"to add import paths.\n" "to add import paths.\n"
"For qmlproject projects, use the importPaths property to add import paths.\n" "For qmlproject projects, use the importPaths property to add import paths.\n"
"For CMake projects, make sure QML_IMPORT_PATH variable is in CMakeCache.txt.\n").arg( "For CMake projects, make sure QML_IMPORT_PATH variable is in CMakeCache.txt.\n")
importInfo.name(), importPaths.join(QLatin1Char('\n')))); .arg(importInfo.name(), m_importPaths.join(QLatin1Char('\n'))));
} }
return import; return import;
} }
bool LinkPrivate::importLibrary(Document::Ptr doc, bool LinkPrivate::importLibrary(const Document::Ptr &doc,
const QString &libraryPath_, const QString &libraryPath,
Import *import, Import *import,
const QString &importPath) const QString &importPath)
{ {
const ImportInfo &importInfo = import->info; const ImportInfo &importInfo = import->info;
QString libraryPath = libraryPath_;
LibraryInfo libraryInfo = snapshot.libraryInfo(libraryPath); LibraryInfo libraryInfo = m_snapshot.libraryInfo(libraryPath);
if (!libraryInfo.isValid()) if (!libraryInfo.isValid())
return false; return false;
@@ -446,9 +456,10 @@ bool LinkPrivate::importLibrary(Document::Ptr doc,
} }
} }
if (errorLoc.isValid()) { if (errorLoc.isValid()) {
appendDiagnostic(doc, DiagnosticMessage(Severity::ReadingTypeInfoWarning, appendDiagnostic(doc, DiagnosticMessage(
errorLoc, Severity::ReadingTypeInfoWarning, errorLoc,
Link::tr("QML module contains C++ plugins, currently reading type information..."))); Link::tr("QML module contains C++ plugins, "
"currently reading type information...")));
import->valid = false; import->valid = false;
} }
} else if (libraryInfo.pluginTypeInfoStatus() == LibraryInfo::DumpError } else if (libraryInfo.pluginTypeInfoStatus() == LibraryInfo::DumpError
@@ -456,21 +467,25 @@ bool LinkPrivate::importLibrary(Document::Ptr doc,
// Only underline import if package isn't described in .qmltypes anyway // Only underline import if package isn't described in .qmltypes anyway
// and is not a private package // and is not a private package
QString packageName = importInfo.name(); QString packageName = importInfo.name();
if (errorLoc.isValid() && (packageName.isEmpty() || !valueOwner->cppQmlTypes().hasModule(packageName)) if (errorLoc.isValid()
&& (packageName.isEmpty()
|| !m_valueOwner->cppQmlTypes().hasModule(packageName))
&& !packageName.endsWith(QLatin1String("private"), Qt::CaseInsensitive)) { && !packageName.endsWith(QLatin1String("private"), Qt::CaseInsensitive)) {
error(doc, errorLoc, libraryInfo.pluginTypeInfoError()); error(doc, errorLoc, libraryInfo.pluginTypeInfoError());
import->valid = false; import->valid = false;
} }
} else { } else {
const QString packageName = importInfo.name(); const QString packageName = importInfo.name();
valueOwner->cppQmlTypes().load(libraryPath, libraryInfo.metaObjects(), packageName); m_valueOwner->cppQmlTypes().load(libraryPath, libraryInfo.metaObjects(), packageName);
foreach (const CppComponentValue *object, valueOwner->cppQmlTypes().createObjectsForImport(packageName, version)) { const auto objects = m_valueOwner->cppQmlTypes().createObjectsForImport(packageName,
version);
for (const CppComponentValue *object : objects)
import->object->setMember(object->className(), object); import->object->setMember(object->className(), object);
}
// all but no-uri module apis become available for import // all but no-uri module apis become available for import
QList<ModuleApiInfo> noUriModuleApis; QList<ModuleApiInfo> noUriModuleApis;
foreach (const ModuleApiInfo &moduleApi, libraryInfo.moduleApis()) { const auto moduleApis = libraryInfo.moduleApis();
for (const ModuleApiInfo &moduleApi : moduleApis) {
if (moduleApi.uri.isEmpty()) if (moduleApi.uri.isEmpty())
noUriModuleApis += moduleApi; noUriModuleApis += moduleApi;
else else
@@ -479,8 +494,10 @@ bool LinkPrivate::importLibrary(Document::Ptr doc,
// if a module api has no uri, it shares the same name // if a module api has no uri, it shares the same name
ModuleApiInfo sameUriModuleApi = findBestModuleApi(noUriModuleApis, version); ModuleApiInfo sameUriModuleApi = findBestModuleApi(noUriModuleApis, version);
if (sameUriModuleApi.version.isValid()) if (sameUriModuleApi.version.isValid()) {
import->object->setPrototype(valueOwner->cppQmlTypes().objectByCppName(sameUriModuleApi.cppName)); import->object->setPrototype(m_valueOwner->cppQmlTypes()
.objectByCppName(sameUriModuleApi.cppName));
}
} }
} }
@@ -489,12 +506,14 @@ bool LinkPrivate::importLibrary(Document::Ptr doc,
return true; return true;
} }
void LinkPrivate::error(const Document::Ptr &doc, const AST::SourceLocation &loc, const QString &message) void LinkPrivate::error(const Document::Ptr &doc, const AST::SourceLocation &loc,
const QString &message)
{ {
appendDiagnostic(doc, DiagnosticMessage(Severity::Error, loc, message)); appendDiagnostic(doc, DiagnosticMessage(Severity::Error, loc, message));
} }
void LinkPrivate::warning(const Document::Ptr &doc, const AST::SourceLocation &loc, const QString &message) void LinkPrivate::warning(const Document::Ptr &doc, const AST::SourceLocation &loc,
const QString &message)
{ {
appendDiagnostic(doc, DiagnosticMessage(Severity::Warning, loc, message)); appendDiagnostic(doc, DiagnosticMessage(Severity::Warning, loc, message));
} }
@@ -516,17 +535,17 @@ void LinkPrivate::loadQmldirComponents(ObjectValue *import, ComponentVersion ver
QSet<QString> importedTypes; QSet<QString> importedTypes;
foreach (const QmlDirParser::Component &component, libraryInfo.components()) { const auto components = libraryInfo.components();
for (const QmlDirParser::Component &component : components) {
if (importedTypes.contains(component.typeName)) if (importedTypes.contains(component.typeName))
continue; continue;
ComponentVersion componentVersion(component.majorVersion, ComponentVersion componentVersion(component.majorVersion, component.minorVersion);
component.minorVersion);
if (version < componentVersion) if (version < componentVersion)
continue; continue;
importedTypes.insert(component.typeName); importedTypes.insert(component.typeName);
if (Document::Ptr importedDoc = snapshot.document( if (Document::Ptr importedDoc = m_snapshot.document(
libraryPath + QLatin1Char('/') + component.fileName)) { libraryPath + QLatin1Char('/') + component.fileName)) {
if (ObjectValue *v = importedDoc->bind()->rootObjectValue()) if (ObjectValue *v = importedDoc->bind()->rootObjectValue())
import->setMember(component.typeName, v); import->setMember(component.typeName, v);
@@ -534,7 +553,7 @@ void LinkPrivate::loadQmldirComponents(ObjectValue *import, ComponentVersion ver
} }
} }
void LinkPrivate::loadImplicitDirectoryImports(Imports *imports, Document::Ptr doc) void LinkPrivate::loadImplicitDirectoryImports(Imports *imports, const Document::Ptr &doc)
{ {
auto processImport = [this, imports, doc](const ImportInfo &importInfo){ auto processImport = [this, imports, doc](const ImportInfo &importInfo){
Import directoryImport = importCache.value(ImportCacheKey(importInfo)); Import directoryImport = importCache.value(ImportCacheKey(importInfo));
@@ -548,8 +567,8 @@ void LinkPrivate::loadImplicitDirectoryImports(Imports *imports, Document::Ptr d
}; };
processImport(ImportInfo::implicitDirectoryImport(doc->path())); processImport(ImportInfo::implicitDirectoryImport(doc->path()));
foreach (const QString &path, const auto qrcPaths = ModelManagerInterface::instance()->qrcPathsForFile(doc->fileName());
ModelManagerInterface::instance()->qrcPathsForFile(doc->fileName())) { for (const QString &path : qrcPaths) {
processImport(ImportInfo::qrcDirectoryImport( processImport(ImportInfo::qrcDirectoryImport(
Utils::QrcParser::qrcDirectoryPathForQrcFilePath(path))); Utils::QrcParser::qrcDirectoryPathForQrcFilePath(path)));
} }
@@ -558,19 +577,21 @@ void LinkPrivate::loadImplicitDirectoryImports(Imports *imports, Document::Ptr d
void LinkPrivate::loadImplicitDefaultImports(Imports *imports) void LinkPrivate::loadImplicitDefaultImports(Imports *imports)
{ {
const QString defaultPackage = CppQmlTypes::defaultPackage; const QString defaultPackage = CppQmlTypes::defaultPackage;
if (valueOwner->cppQmlTypes().hasModule(defaultPackage)) { if (m_valueOwner->cppQmlTypes().hasModule(defaultPackage)) {
const ComponentVersion maxVersion(ComponentVersion::MaxVersion, ComponentVersion::MaxVersion); const ComponentVersion maxVersion(ComponentVersion::MaxVersion,
ComponentVersion::MaxVersion);
const ImportInfo info = ImportInfo::moduleImport(defaultPackage, maxVersion, QString()); const ImportInfo info = ImportInfo::moduleImport(defaultPackage, maxVersion, QString());
Import import = importCache.value(ImportCacheKey(info)); Import import = importCache.value(ImportCacheKey(info));
if (!import.object) { if (!import.object) {
import.valid = true; import.valid = true;
import.info = info; import.info = info;
import.object = new ObjectValue(valueOwner, QLatin1String("<defaults>")); import.object = new ObjectValue(m_valueOwner, QLatin1String("<defaults>"));
foreach (const CppComponentValue *object,
valueOwner->cppQmlTypes().createObjectsForImport( const auto objects = m_valueOwner->cppQmlTypes().createObjectsForImport(defaultPackage,
defaultPackage, maxVersion)) { maxVersion);
for (const CppComponentValue *object : objects)
import.object->setMember(object->className(), object); import.object->setMember(object->className(), object);
}
importCache.insert(ImportCacheKey(info), import); importCache.insert(ImportCacheKey(info), import);
} }
imports->append(import); imports->append(import);

View File

@@ -43,10 +43,13 @@ class QMLJS_EXPORT Link
Q_DECLARE_TR_FUNCTIONS(QmlJS::Link) Q_DECLARE_TR_FUNCTIONS(QmlJS::Link)
public: public:
Link(Link &&) = delete;
Link &operator=(Link &&) = delete;
Link(const Snapshot &snapshot, const ViewerContext &vContext, const LibraryInfo &builtins); Link(const Snapshot &snapshot, const ViewerContext &vContext, const LibraryInfo &builtins);
// Link all documents in snapshot, collecting all diagnostic messages (if messages != 0) // Link all documents in snapshot, collecting all diagnostic messages (if messages != 0)
ContextPtr operator()(QHash<QString, QList<DiagnosticMessage> > *messages = nullptr); ContextPtr operator()(QHash<QString, QList<DiagnosticMessage>> *messages = nullptr);
// Link all documents in snapshot, appending the diagnostic messages // Link all documents in snapshot, appending the diagnostic messages
// for 'doc' in 'messages' // for 'doc' in 'messages'