qmljs: (QString -> Utils::FilePath)++

convert more QString containing paths to Utils::FilePath

Change-Id: I1219d7d147993e48cfa641dc9bea72ab38c90f51
Reviewed-by: Tim Jenssen <tim.jenssen@qt.io>
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: <github-actions-qt-creator@cristianadam.eu>
This commit is contained in:
Fawzi Mohamed
2022-06-20 12:35:13 +02:00
committed by Tim Jenssen
parent 0bb272d411
commit fd89043de2
79 changed files with 844 additions and 680 deletions

View File

@@ -119,11 +119,11 @@ public:
if (!url.isValid() && !url.isEmpty()) { if (!url.isValid() && !url.isEmpty()) {
setMessage(ErrInvalidUrl); setMessage(ErrInvalidUrl);
} else { } else {
QString fileName = url.toLocalFile(); Utils::FilePath fileName = Utils::FilePath::fromString(url.toLocalFile());
if (!fileName.isEmpty()) { if (!fileName.isEmpty()) {
if (QFileInfo(fileName).isRelative()) if (fileName.isRelativePath())
fileName = QString("/%1%2").arg(_doc->path(), fileName); fileName = _doc->path().pathAppended(fileName.path());
if (!QFileInfo::exists(fileName)) if (!fileName.exists())
setMessage(WarnFileOrDirectoryDoesNotExist); setMessage(WarnFileOrDirectoryDoesNotExist);
} }
} }
@@ -967,7 +967,7 @@ void Check::visitQmlObject(Node *ast, UiQualifiedId *typeId,
if (checkTypeForDesignerSupport(typeId)) if (checkTypeForDesignerSupport(typeId))
addMessage(WarnUnsupportedTypeInVisualDesigner, typeErrorLocation, typeName); addMessage(WarnUnsupportedTypeInVisualDesigner, typeErrorLocation, typeName);
if (typeId->next == nullptr && QFileInfo(_doc->fileName()).baseName() == typeName) if (typeId->next == nullptr && _doc->fileName().baseName() == typeName)
addMessage(ErrTypeIsInstantiatedRecursively, typeErrorLocation, typeName); addMessage(ErrTypeIsInstantiatedRecursively, typeErrorLocation, typeName);
if (checkTypeForQmlUiSupport(typeId)) if (checkTypeForQmlUiSupport(typeId))

View File

@@ -87,20 +87,19 @@ using namespace QmlJS::AST;
threads finish and new information becomes available. threads finish and new information becomes available.
*/ */
Document::Document(const QString &fileName, Dialect language) Document::Document(const Utils::FilePath &fileName, Dialect language)
: _engine(nullptr) : _engine(nullptr)
, _ast(nullptr) , _ast(nullptr)
, _bind(nullptr) , _bind(nullptr)
, _fileName(QDir::cleanPath(fileName)) , _fileName(fileName.cleanPath())
, _editorRevision(0) , _editorRevision(0)
, _language(language) , _language(language)
, _parsedCorrectly(false) , _parsedCorrectly(false)
{ {
QFileInfo fileInfo(fileName); _path = fileName.absoluteFilePath().parentDir().cleanPath();
_path = QDir::cleanPath(fileInfo.absolutePath());
if (language.isQmlLikeLanguage()) { if (language.isQmlLikeLanguage()) {
_componentName = fileInfo.baseName(); _componentName = fileName.baseName();
if (! _componentName.isEmpty()) { if (! _componentName.isEmpty()) {
// ### TODO: check the component name. // ### TODO: check the component name.
@@ -120,7 +119,7 @@ Document::~Document()
delete _engine; delete _engine;
} }
Document::MutablePtr Document::create(const QString &fileName, Dialect language) Document::MutablePtr Document::create(const Utils::FilePath &fileName, Dialect language)
{ {
Document::MutablePtr doc(new Document(fileName, language)); Document::MutablePtr doc(new Document(fileName, language));
doc->_ptr = doc; doc->_ptr = doc;
@@ -149,7 +148,7 @@ void Document::setLanguage(Dialect l)
QString Document::importId() const QString Document::importId() const
{ {
return _fileName; return _fileName.toString();
} }
QByteArray Document::fingerprint() const QByteArray Document::fingerprint() const
@@ -213,13 +212,13 @@ void Document::setEditorRevision(int revision)
_editorRevision = revision; _editorRevision = revision;
} }
QString Document::fileName() const Utils::FilePath Document::fileName() const
{ {
return _fileName; return _fileName;
} }
QString Document::path() const Utils::FilePath Document::path() const
{ {
return _path; return _path;
} }
@@ -244,7 +243,7 @@ class CollectDirectives : public Directives
QList<SourceLocation> _locations; QList<SourceLocation> _locations;
public: public:
CollectDirectives(const QString &documentPath) CollectDirectives(const Utils::FilePath &documentPath)
: documentPath(documentPath) : documentPath(documentPath)
, isLibrary(false) , isLibrary(false)
@@ -272,7 +271,7 @@ public:
virtual QList<SourceLocation> locations() { return _locations; } virtual QList<SourceLocation> locations() { return _locations; }
const QString documentPath; const Utils::FilePath documentPath;
bool isLibrary; bool isLibrary;
QList<ImportInfo> imports; QList<ImportInfo> imports;
}; };
@@ -471,29 +470,29 @@ Snapshot::~Snapshot()
void Snapshot::insert(const Document::Ptr &document, bool allowInvalid) void Snapshot::insert(const Document::Ptr &document, bool allowInvalid)
{ {
if (document && (allowInvalid || document->qmlProgram() || document->jsProgram())) { if (document && (allowInvalid || document->qmlProgram() || document->jsProgram())) {
const QString fileName = document->fileName(); const Utils::FilePath fileName = document->fileName();
const QString path = document->path(); const Utils::FilePath path = document->path();
remove(fileName); remove(fileName);
_documentsByPath[path].append(document); _documentsByPath[path].append(document);
_documents.insert(fileName, document); _documents.insert(fileName, document);
CoreImport cImport; CoreImport cImport;
cImport.importId = document->importId(); cImport.importId = document->importId();
cImport.language = document->language(); cImport.language = document->language();
cImport.addPossibleExport(Export(ImportKey(ImportType::File, fileName), cImport.addPossibleExport(
{}, true, QFileInfo(fileName).baseName())); Export(ImportKey(ImportType::File, fileName.toString()), {}, true, fileName.baseName()));
cImport.fingerprint = document->fingerprint(); cImport.fingerprint = document->fingerprint();
_dependencies.addCoreImport(cImport); _dependencies.addCoreImport(cImport);
} }
} }
void Snapshot::insertLibraryInfo(const QString &path, const LibraryInfo &info) void Snapshot::insertLibraryInfo(const Utils::FilePath &path, const LibraryInfo &info)
{ {
QTC_CHECK(!path.isEmpty()); QTC_CHECK(!path.isEmpty());
QTC_CHECK(info.fingerprint() == info.calculateFingerprint()); QTC_CHECK(info.fingerprint() == info.calculateFingerprint());
_libraries.insert(QDir::cleanPath(path), info); _libraries.insert(path.cleanPath(), info);
if (!info.wasFound()) return; if (!info.wasFound()) return;
CoreImport cImport; CoreImport cImport;
cImport.importId = path; cImport.importId = path.toString();
cImport.language = Dialect::AnyLanguage; cImport.language = Dialect::AnyLanguage;
QSet<ImportKey> packages; QSet<ImportKey> packages;
foreach (const ModuleApiInfo &moduleInfo, info.moduleApis()) { foreach (const ModuleApiInfo &moduleInfo, info.moduleApis()) {
@@ -509,7 +508,7 @@ void Snapshot::insertLibraryInfo(const QString &path, const LibraryInfo &info)
} }
} }
QStringList splitPath = path.split(QLatin1Char('/')); QStringList splitPath = path.path().split(QLatin1Char('/'));
const QRegularExpression vNr(QLatin1String("^(.+)\\.([0-9]+)(?:\\.([0-9]+))?$")); const QRegularExpression vNr(QLatin1String("^(.+)\\.([0-9]+)(?:\\.([0-9]+))?$"));
const QRegularExpression safeName(QLatin1String("^[a-zA-Z_][[a-zA-Z0-9_]*$")); const QRegularExpression safeName(QLatin1String("^[a-zA-Z_][[a-zA-Z0-9_]*$"));
foreach (const ImportKey &importKey, packages) { foreach (const ImportKey &importKey, packages) {
@@ -526,12 +525,17 @@ void Snapshot::insertLibraryInfo(const QString &path, const LibraryInfo &info)
break; break;
ImportKey iKey(ImportType::Library, QStringList(myPath.mid(iPath)).join(QLatin1Char('.')), ImportKey iKey(ImportType::Library, QStringList(myPath.mid(iPath)).join(QLatin1Char('.')),
importKey.majorVersion, importKey.minorVersion); importKey.majorVersion, importKey.minorVersion);
cImport.addPossibleExport(Export(iKey, (iPath == 1) ? QLatin1String("/") : Utils::FilePath newP(path);
QStringList(myPath.mid(0, iPath)).join(QLatin1Char('/')), true)); newP.setPath((iPath == 1)
? QLatin1String("/")
: QStringList(myPath.mid(0, iPath)).join(QLatin1Char('/')));
cImport.addPossibleExport(Export(iKey, newP, true));
} }
} else { } else {
QString requiredPath = QStringList(splitPath.mid(0, splitPath.size() - importKey.splitPath.size())) Utils::FilePath requiredPath(path);
.join(QLatin1String("/")); requiredPath.setPath(
QStringList(splitPath.mid(0, splitPath.size() - importKey.splitPath.size()))
.join(QLatin1String("/")));
cImport.addPossibleExport(Export(importKey, requiredPath, true)); cImport.addPossibleExport(Export(importKey, requiredPath, true));
} }
} }
@@ -567,8 +571,11 @@ void Snapshot::insertLibraryInfo(const QString &path, const LibraryInfo &info)
break; break;
ImportKey iKey(ImportType::Library, QStringList(splitPath.mid(iPath)).join(QLatin1Char('.')), ImportKey iKey(ImportType::Library, QStringList(splitPath.mid(iPath)).join(QLatin1Char('.')),
majorVersion, minorVersion); majorVersion, minorVersion);
cImport.addPossibleExport(Export(iKey, (iPath == 1) ? QLatin1String("/") : Utils::FilePath newP(path);
QStringList(splitPath.mid(0, iPath)).join(QLatin1Char('/')), true)); newP.setPath((iPath == 1)
? QLatin1String("/")
: QStringList(splitPath.mid(0, iPath)).join(QLatin1Char('/')));
cImport.addPossibleExport(Export(iKey, newP, true));
} }
} }
foreach (const QmlDirParser::Component &component, info.components()) { foreach (const QmlDirParser::Component &component, info.components()) {
@@ -580,11 +587,11 @@ void Snapshot::insertLibraryInfo(const QString &path, const LibraryInfo &info)
_dependencies.addCoreImport(cImport); _dependencies.addCoreImport(cImport);
} }
void Snapshot::remove(const QString &fileName) void Snapshot::remove(const Utils::FilePath &fileName)
{ {
Document::Ptr doc = _documents.value(fileName); Document::Ptr doc = _documents.value(fileName);
if (!doc.isNull()) { if (!doc.isNull()) {
const QString &path = doc->path(); const Utils::FilePath &path = doc->path();
QList<Document::Ptr> docs = _documentsByPath.value(path); QList<Document::Ptr> docs = _documentsByPath.value(path);
docs.removeAll(doc); docs.removeAll(doc);
@@ -604,9 +611,9 @@ QmlJS::ImportDependencies *Snapshot::importDependencies()
return &_dependencies; return &_dependencies;
} }
Document::MutablePtr Snapshot::documentFromSource( Document::MutablePtr Snapshot::documentFromSource(const QString &code,
const QString &code, const QString &fileName, const Utils::FilePath &fileName,
Dialect language) const Dialect language) const
{ {
Document::MutablePtr newDoc = Document::create(fileName, language); Document::MutablePtr newDoc = Document::create(fileName, language);
@@ -617,24 +624,19 @@ Document::MutablePtr Snapshot::documentFromSource(
return newDoc; return newDoc;
} }
Document::Ptr Snapshot::document(const QString &fileName) const Document::Ptr Snapshot::document(const Utils::FilePath &fileName) const
{ {
return _documents.value(QDir::cleanPath(fileName)); return _documents.value(fileName.cleanPath());
} }
QList<Document::Ptr> Snapshot::documentsInDirectory(const QString &path) const QList<Document::Ptr> Snapshot::documentsInDirectory(const Utils::FilePath &path) const
{ {
return _documentsByPath.value(QDir::cleanPath(path)); return _documentsByPath.value(path.cleanPath());
}
LibraryInfo Snapshot::libraryInfo(const QString &path) const
{
return _libraries.value(QDir::cleanPath(path));
} }
LibraryInfo Snapshot::libraryInfo(const Utils::FilePath &path) const LibraryInfo Snapshot::libraryInfo(const Utils::FilePath &path) const
{ {
return _libraries.value(path.cleanPath().toString()); return _libraries.value(path.cleanPath());
} }
void ModuleApiInfo::addToHash(QCryptographicHash &hash) const void ModuleApiInfo::addToHash(QCryptographicHash &hash) const

View File

@@ -53,12 +53,12 @@ public:
typedef QSharedPointer<const Document> Ptr; typedef QSharedPointer<const Document> Ptr;
typedef QSharedPointer<Document> MutablePtr; typedef QSharedPointer<Document> MutablePtr;
protected: protected:
Document(const QString &fileName, Dialect language); Document(const Utils::FilePath &fileName, Dialect language);
public: public:
~Document(); ~Document();
static MutablePtr create(const QString &fileName, Dialect language); static MutablePtr create(const Utils::FilePath &fileName, Dialect language);
Document::Ptr ptr() const; Document::Ptr ptr() const;
@@ -93,8 +93,8 @@ public:
int editorRevision() const; int editorRevision() const;
void setEditorRevision(int revision); void setEditorRevision(int revision);
QString fileName() const; Utils::FilePath fileName() const;
QString path() const; Utils::FilePath path() const;
QString componentName() const; QString componentName() const;
QList<SourceLocation> jsDirectives() const; QList<SourceLocation> jsDirectives() const;
@@ -107,8 +107,8 @@ private:
AST::Node *_ast; AST::Node *_ast;
Bind *_bind; Bind *_bind;
QList<QmlJS::DiagnosticMessage> _diagnosticMessages; QList<QmlJS::DiagnosticMessage> _diagnosticMessages;
QString _fileName; Utils::FilePath _fileName;
QString _path; Utils::FilePath _path;
QString _componentName; QString _componentName;
QString _source; QString _source;
QList<SourceLocation> _jsdirectives; QList<SourceLocation> _jsdirectives;
@@ -231,10 +231,10 @@ public:
class QMLJS_EXPORT Snapshot class QMLJS_EXPORT Snapshot
{ {
typedef QHash<QString, Document::Ptr> Base; typedef QHash<Utils::FilePath, Document::Ptr> Base;
QHash<QString, Document::Ptr> _documents; QHash<Utils::FilePath, Document::Ptr> _documents;
QHash<QString, QList<Document::Ptr> > _documentsByPath; QHash<Utils::FilePath, QList<Document::Ptr>> _documentsByPath;
QHash<QString, LibraryInfo> _libraries; QHash<Utils::FilePath, LibraryInfo> _libraries;
ImportDependencies _dependencies; ImportDependencies _dependencies;
public: public:
@@ -248,20 +248,19 @@ public:
const_iterator end() const { return _documents.end(); } const_iterator end() const { return _documents.end(); }
void insert(const Document::Ptr &document, bool allowInvalid = false); void insert(const Document::Ptr &document, bool allowInvalid = false);
void insertLibraryInfo(const QString &path, const LibraryInfo &info); void insertLibraryInfo(const Utils::FilePath &path, const LibraryInfo &info);
void remove(const QString &fileName); void remove(const Utils::FilePath &fileName);
const ImportDependencies *importDependencies() const; const ImportDependencies *importDependencies() const;
ImportDependencies *importDependencies(); ImportDependencies *importDependencies();
Document::Ptr document(const QString &fileName) const; Document::Ptr document(const Utils::FilePath &fileName) const;
QList<Document::Ptr> documentsInDirectory(const QString &path) const; QList<Document::Ptr> documentsInDirectory(const Utils::FilePath &path) const;
LibraryInfo libraryInfo(const QString &path) const; // FIXME: Remove
LibraryInfo libraryInfo(const Utils::FilePath &path) const; LibraryInfo libraryInfo(const Utils::FilePath &path) const;
Document::MutablePtr documentFromSource(const QString &code, Document::MutablePtr documentFromSource(const QString &code,
const QString &fileName, const Utils::FilePath &fileName,
Dialect language) const; Dialect language) const;
}; };
} // namespace QmlJS } // namespace QmlJS

View File

@@ -535,8 +535,14 @@ Export::Export()
: intrinsic(false) : intrinsic(false)
{ } { }
Export::Export(ImportKey exportName, const QString &pathRequired, bool intrinsic, const QString &typeName) Export::Export(ImportKey exportName,
: exportName(exportName), pathRequired(pathRequired), typeName(typeName), intrinsic(intrinsic) const Utils::FilePath &pathRequired,
bool intrinsic,
const QString &typeName)
: exportName(exportName)
, pathRequired(pathRequired)
, typeName(typeName)
, intrinsic(intrinsic)
{ } { }
bool Export::visibleInVContext(const ViewerContext &vContext) const bool Export::visibleInVContext(const ViewerContext &vContext) const
@@ -783,7 +789,8 @@ void ImportDependencies::addCoreImport(const CoreImport &import)
if (importsLog().isDebugEnabled()) { if (importsLog().isDebugEnabled()) {
QString msg = QString::fromLatin1("added import %1 for").arg(newImport.importId); QString msg = QString::fromLatin1("added import %1 for").arg(newImport.importId);
foreach (const Export &e, newImport.possibleExports) foreach (const Export &e, newImport.possibleExports)
msg += QString::fromLatin1("\n %1(%2)").arg(e.exportName.toString(), e.pathRequired); msg += QString::fromLatin1("\n %1(%2)")
.arg(e.exportName.toString(), e.pathRequired.toUserOutput());
qCDebug(importsLog) << msg; qCDebug(importsLog) << msg;
} }
} }
@@ -820,8 +827,10 @@ void ImportDependencies::removeImportCacheEntry(const ImportKey &importKey, cons
m_importCache.remove(importKey); m_importCache.remove(importKey);
} }
void ImportDependencies::addExport(const QString &importId, const ImportKey &importKey, void ImportDependencies::addExport(const QString &importId,
const QString &requiredPath, const QString &typeName) const ImportKey &importKey,
const Utils::FilePath &requiredPath,
const QString &typeName)
{ {
if (!m_coreImports.contains(importId)) { if (!m_coreImports.contains(importId)) {
CoreImport newImport(importId); CoreImport newImport(importId);
@@ -838,8 +847,10 @@ void ImportDependencies::addExport(const QString &importId, const ImportKey &imp
<< " (" << requiredPath << ")"; << " (" << requiredPath << ")";
} }
void ImportDependencies::removeExport(const QString &importId, const ImportKey &importKey, void ImportDependencies::removeExport(const QString &importId,
const QString &requiredPath, const QString &typeName) const ImportKey &importKey,
const Utils::FilePath &requiredPath,
const QString &typeName)
{ {
if (!m_coreImports.contains(importId)) { if (!m_coreImports.contains(importId)) {
qCWarning(importsLog) << "non existing core import for removeExport(" << importId << ", " qCWarning(importsLog) << "non existing core import for removeExport(" << importId << ", "

View File

@@ -128,10 +128,12 @@ class QMLJS_EXPORT Export
public: public:
static QString libraryTypeName(); static QString libraryTypeName();
Export(); Export();
Export(ImportKey exportName, const QString &pathRequired, bool intrinsic = false, Export(ImportKey exportName,
const Utils::FilePath &pathRequired,
bool intrinsic = false,
const QString &typeName = libraryTypeName()); const QString &typeName = libraryTypeName());
ImportKey exportName; ImportKey exportName;
QString pathRequired; Utils::FilePath pathRequired;
QString typeName; QString typeName;
bool intrinsic; bool intrinsic;
bool visibleInVContext(const ViewerContext &vContext) const; bool visibleInVContext(const ViewerContext &vContext) const;
@@ -231,10 +233,14 @@ public:
void addCoreImport(const CoreImport &import); void addCoreImport(const CoreImport &import);
void removeCoreImport(const QString &importId); void removeCoreImport(const QString &importId);
void addExport(const QString &importId, const ImportKey &importKey, void addExport(const QString &importId,
const QString &requiredPath, const QString &typeName = Export::libraryTypeName()); const ImportKey &importKey,
void removeExport(const QString &importId, const ImportKey &importKey, const Utils::FilePath &requiredPath,
const QString &requiredPath, const QString &typeName = Export::libraryTypeName()); const QString &typeName = Export::libraryTypeName());
void removeExport(const QString &importId,
const ImportKey &importKey,
const Utils::FilePath &requiredPath,
const QString &typeName = Export::libraryTypeName());
void iterateOnLibraryImports(const ViewerContext &vContext, void iterateOnLibraryImports(const ViewerContext &vContext,
std::function<bool(const ImportMatchStrength &, std::function<bool(const ImportMatchStrength &,

View File

@@ -712,7 +712,7 @@ Value::~Value()
{ {
} }
bool Value::getSourceLocation(QString *, int *, int *) const bool Value::getSourceLocation(Utils::FilePath *, int *, int *) const
{ {
return false; return false;
} }
@@ -1872,7 +1872,7 @@ const ASTObjectValue *ASTObjectValue::asAstObjectValue() const
return this; return this;
} }
bool ASTObjectValue::getSourceLocation(QString *fileName, int *line, int *column) const bool ASTObjectValue::getSourceLocation(Utils::FilePath *fileName, int *line, int *column) const
{ {
*fileName = m_doc->fileName(); *fileName = m_doc->fileName();
*line = m_typeName->identifierToken.startLine; *line = m_typeName->identifierToken.startLine;
@@ -1962,7 +1962,7 @@ const Value *ASTVariableReference::value(ReferenceContext *referenceContext) con
return res; return res;
} }
bool ASTVariableReference::getSourceLocation(QString *fileName, int *line, int *column) const bool ASTVariableReference::getSourceLocation(Utils::FilePath *fileName, int *line, int *column) const
{ {
*fileName = m_doc->fileName(); *fileName = m_doc->fileName();
*line = m_ast->identifierToken.startLine; *line = m_ast->identifierToken.startLine;
@@ -2053,7 +2053,7 @@ const ASTFunctionValue *ASTFunctionValue::asAstFunctionValue() const
return this; return this;
} }
bool ASTFunctionValue::getSourceLocation(QString *fileName, int *line, int *column) const bool ASTFunctionValue::getSourceLocation(Utils::FilePath *fileName, int *line, int *column) const
{ {
*fileName = m_doc->fileName(); *fileName = m_doc->fileName();
*line = m_ast->identifierToken.startLine; *line = m_ast->identifierToken.startLine;
@@ -2110,7 +2110,7 @@ const ASTPropertyReference *ASTPropertyReference::asAstPropertyReference() const
return this; return this;
} }
bool ASTPropertyReference::getSourceLocation(QString *fileName, int *line, int *column) const bool ASTPropertyReference::getSourceLocation(Utils::FilePath *fileName, int *line, int *column) const
{ {
*fileName = m_doc->fileName(); *fileName = m_doc->fileName();
*line = m_ast->identifierToken.startLine; *line = m_ast->identifierToken.startLine;
@@ -2205,7 +2205,7 @@ QString ASTSignal::argumentName(int index) const
return param->name.toString(); return param->name.toString();
} }
bool ASTSignal::getSourceLocation(QString *fileName, int *line, int *column) const bool ASTSignal::getSourceLocation(Utils::FilePath *fileName, int *line, int *column) const
{ {
*fileName = m_doc->fileName(); *fileName = m_doc->fileName();
*line = m_ast->identifierToken.startLine; *line = m_ast->identifierToken.startLine;
@@ -2234,20 +2234,23 @@ ImportInfo ImportInfo::moduleImport(QString uri, ComponentVersion version,
return info; return info;
} }
ImportInfo ImportInfo::pathImport(const QString &docPath, const QString &path, ImportInfo ImportInfo::pathImport(const Utils::FilePath &docPath,
ComponentVersion version, const QString &as, UiImport *ast) const QString &path,
ComponentVersion version,
const QString &as,
UiImport *ast)
{ {
ImportInfo info; ImportInfo info;
info.m_name = path; info.m_name = path;
QFileInfo importFileInfo(path); Utils::FilePath importFilePath = Utils::FilePath::fromString(path);
if (!importFileInfo.isAbsolute()) if (!importFilePath.isAbsolutePath())
importFileInfo = QFileInfo(docPath + QLatin1Char('/') + path); importFilePath = docPath.pathAppended(path);
info.m_path = importFileInfo.absoluteFilePath(); info.m_path = importFilePath.absoluteFilePath().path();
if (importFileInfo.isFile()) { if (importFilePath.isFile()) {
info.m_type = ImportType::File; info.m_type = ImportType::File;
} else if (importFileInfo.isDir()) { } else if (importFilePath.isDir()) {
info.m_type = ImportType::Directory; info.m_type = ImportType::Directory;
} else if (path.startsWith(QLatin1String("qrc:"))) { } else if (path.startsWith(QLatin1String("qrc:"))) {
ModelManagerInterface *model = ModelManagerInterface::instance(); ModelManagerInterface *model = ModelManagerInterface::instance();
@@ -2258,11 +2261,11 @@ ImportInfo ImportInfo::pathImport(const QString &docPath, const QString &path,
? ImportType::QrcDirectory ? ImportType::QrcDirectory
: ImportType::QrcFile; : ImportType::QrcFile;
} else { } else {
QDir dir(docPath); Utils::FilePath dir = docPath;
while (dir.dirName().startsWith("+")) while (dir.fileName().startsWith("+"))
dir.cdUp(); dir = dir.parentDir();
const QString docPathStripped = dir.absolutePath(); const Utils::FilePath docPathStripped = dir.absolutePath();
if (docPathStripped != docPath) if (docPathStripped != docPath)
return pathImport(docPathStripped, path, version, as, ast); return pathImport(docPathStripped, path, version, as, ast);

View File

@@ -150,7 +150,7 @@ public:
virtual void accept(ValueVisitor *) const = 0; virtual void accept(ValueVisitor *) const = 0;
virtual bool getSourceLocation(QString *fileName, int *line, int *column) const; virtual bool getSourceLocation(Utils::FilePath *fileName, int *line, int *column) const;
}; };
template <typename RetTy> const RetTy *value_cast(const Value *) template <typename RetTy> const RetTy *value_cast(const Value *)
@@ -891,7 +891,7 @@ public:
const AST::PatternElement *ast() const; const AST::PatternElement *ast() const;
private: private:
const Value *value(ReferenceContext *referenceContext) const override; const Value *value(ReferenceContext *referenceContext) const override;
bool getSourceLocation(QString *fileName, int *line, int *column) const override; bool getSourceLocation(Utils::FilePath *fileName, int *line, int *column) const override;
}; };
class QMLJS_EXPORT ASTFunctionValue: public FunctionValue class QMLJS_EXPORT ASTFunctionValue: public FunctionValue
@@ -912,7 +912,7 @@ public:
bool isVariadic() const override; bool isVariadic() const override;
const ASTFunctionValue *asAstFunctionValue() const override; const ASTFunctionValue *asAstFunctionValue() const override;
bool getSourceLocation(QString *fileName, int *line, int *column) const override; bool getSourceLocation(Utils::FilePath *fileName, int *line, int *column) const override;
}; };
class QMLJS_EXPORT ASTPropertyReference: public Reference class QMLJS_EXPORT ASTPropertyReference: public Reference
@@ -930,7 +930,7 @@ public:
AST::UiPublicMember *ast() const { return m_ast; } AST::UiPublicMember *ast() const { return m_ast; }
QString onChangedSlotName() const { return m_onChangedSlotName; } QString onChangedSlotName() const { return m_onChangedSlotName; }
bool getSourceLocation(QString *fileName, int *line, int *column) const override; bool getSourceLocation(Utils::FilePath *fileName, int *line, int *column) const override;
private: private:
const Value *value(ReferenceContext *referenceContext) const override; const Value *value(ReferenceContext *referenceContext) const override;
@@ -959,7 +959,7 @@ public:
QString argumentName(int index) const override; QString argumentName(int index) const override;
// Value interface // Value interface
bool getSourceLocation(QString *fileName, int *line, int *column) const override; bool getSourceLocation(Utils::FilePath *fileName, int *line, int *column) const override;
}; };
class QMLJS_EXPORT ASTObjectValue: public ObjectValue class QMLJS_EXPORT ASTObjectValue: public ObjectValue
@@ -980,7 +980,7 @@ public:
const ASTObjectValue *asAstObjectValue() const override; const ASTObjectValue *asAstObjectValue() const override;
bool getSourceLocation(QString *fileName, int *line, int *column) const override; bool getSourceLocation(Utils::FilePath *fileName, int *line, int *column) const override;
void processMembers(MemberProcessor *processor) const override; void processMembers(MemberProcessor *processor) const override;
QString defaultPropertyName() const; QString defaultPropertyName() const;
@@ -997,9 +997,11 @@ public:
static ImportInfo moduleImport(QString uri, LanguageUtils::ComponentVersion version, static ImportInfo moduleImport(QString uri, LanguageUtils::ComponentVersion version,
const QString &as, AST::UiImport *ast = nullptr); const QString &as, AST::UiImport *ast = nullptr);
static ImportInfo pathImport(const QString &docPath, const QString &path, static ImportInfo pathImport(const Utils::FilePath &docPath,
const QString &path,
LanguageUtils::ComponentVersion version, LanguageUtils::ComponentVersion version,
const QString &as, AST::UiImport *ast = nullptr); const QString &as,
AST::UiImport *ast = nullptr);
static ImportInfo invalidImport(AST::UiImport *ast = nullptr); static ImportInfo invalidImport(AST::UiImport *ast = nullptr);
static ImportInfo implicitDirectoryImport(const QString &directory); static ImportInfo implicitDirectoryImport(const QString &directory);
static ImportInfo qrcDirectoryImport(const QString &directory); static ImportInfo qrcDirectoryImport(const QString &directory);
@@ -1041,7 +1043,7 @@ public:
ImportInfo info; ImportInfo info;
DependencyInfo::ConstPtr deps; DependencyInfo::ConstPtr deps;
// uri imports: path to library, else empty // uri imports: path to library, else empty
QString libraryPath; Utils::FilePath libraryPath;
// whether the import succeeded // whether the import succeeded
bool valid; bool valid;
mutable bool used; mutable bool used;

View File

@@ -32,6 +32,8 @@
#include "qmljsmodelmanagerinterface.h" #include "qmljsmodelmanagerinterface.h"
#include "qmljsconstants.h" #include "qmljsconstants.h"
#include <utils/algorithm.h>
#include <utils/filepath.h>
#include <utils/porting.h> #include <utils/porting.h>
#include <utils/qrcparser.h> #include <utils/qrcparser.h>
@@ -93,14 +95,15 @@ public:
const ImportInfo &importInfo); const ImportInfo &importInfo);
bool importLibrary(const Document::Ptr &doc, bool importLibrary(const Document::Ptr &doc,
const QString &libraryPath, const Utils::FilePath &libraryPath,
Import *import, ObjectValue *targetObject, Import *import,
const QString &importPath = QString(), ObjectValue *targetObject,
const Utils::FilePath &importPath = Utils::FilePath(),
bool optional = false); bool optional = false);
void loadQmldirComponents(ObjectValue *import, void loadQmldirComponents(ObjectValue *import,
LanguageUtils::ComponentVersion version, LanguageUtils::ComponentVersion version,
const LibraryInfo &libraryInfo, const LibraryInfo &libraryInfo,
const QString &libraryPath); const Utils::FilePath &libraryPath);
void loadImplicitDirectoryImports(Imports *imports, const Document::Ptr &doc); void loadImplicitDirectoryImports(Imports *imports, const Document::Ptr &doc);
void loadImplicitDefaultImports(Imports *imports); void loadImplicitDefaultImports(Imports *imports);
@@ -113,8 +116,8 @@ private:
Snapshot m_snapshot; Snapshot m_snapshot;
ValueOwner *m_valueOwner = nullptr; ValueOwner *m_valueOwner = nullptr;
QStringList m_importPaths; QList<Utils::FilePath> m_importPaths;
QStringList m_applicationDirectories; QList<Utils::FilePath> m_applicationDirectories;
LibraryInfo m_builtins; LibraryInfo m_builtins;
ViewerContext m_vContext; ViewerContext m_vContext;
@@ -124,7 +127,7 @@ private:
Document::Ptr document; Document::Ptr document;
QList<DiagnosticMessage> *diagnosticMessages = nullptr; QList<DiagnosticMessage> *diagnosticMessages = nullptr;
QHash<QString, QList<DiagnosticMessage>> *allDiagnosticMessages = nullptr; QHash<Utils::FilePath, QList<DiagnosticMessage>> *allDiagnosticMessages = nullptr;
}; };
/*! /*!
@@ -182,7 +185,7 @@ Link::Link(const Snapshot &snapshot, const ViewerContext &vContext, const Librar
fi.reportFinished(); fi.reportFinished();
} }
ContextPtr Link::operator()(QHash<QString, QList<DiagnosticMessage> > *messages) ContextPtr Link::operator()(QHash<Utils::FilePath, QList<DiagnosticMessage>> *messages)
{ {
d->allDiagnosticMessages = messages; d->allDiagnosticMessages = messages;
return Context::create(d->m_snapshot, d->m_valueOwner, d->linkImports(), d->m_vContext); return Context::create(d->m_snapshot, d->m_valueOwner, d->linkImports(), d->m_vContext);
@@ -339,7 +342,8 @@ Import LinkPrivate::importFileOrDirectory(const Document::Ptr &doc, const Import
import.object = nullptr; import.object = nullptr;
import.valid = true; import.valid = true;
QString path = importInfo.path(); QString pathStr = importInfo.path();
Utils::FilePath path = Utils::FilePath::fromString(pathStr);
if (importInfo.type() == ImportType::Directory if (importInfo.type() == ImportType::Directory
|| importInfo.type() == ImportType::ImplicitDirectory) { || importInfo.type() == ImportType::ImplicitDirectory) {
@@ -360,11 +364,15 @@ Import LinkPrivate::importFileOrDirectory(const Document::Ptr &doc, const Import
} else if (importInfo.type() == ImportType::QrcFile) { } else if (importInfo.type() == ImportType::QrcFile) {
QLocale locale; QLocale locale;
QStringList filePaths = ModelManagerInterface::instance() QStringList filePaths = ModelManagerInterface::instance()
->filesAtQrcPath(path, &locale, nullptr, ModelManagerInterface::ActiveQrcResources); ->filesAtQrcPath(pathStr,
&locale,
nullptr,
ModelManagerInterface::ActiveQrcResources);
if (filePaths.isEmpty()) if (filePaths.isEmpty())
filePaths = ModelManagerInterface::instance()->filesAtQrcPath(path); filePaths = ModelManagerInterface::instance()->filesAtQrcPath(pathStr);
if (!filePaths.isEmpty()) { if (!filePaths.isEmpty()) {
if (Document::Ptr importedDoc = m_snapshot.document(filePaths.at(0))) if (Document::Ptr importedDoc = m_snapshot.document(
Utils::FilePath::fromString(filePaths.at(0))))
import.object = importedDoc->bind()->rootObjectValue(); import.object = importedDoc->bind()->rootObjectValue();
} }
} else if (importInfo.type() == ImportType::QrcDirectory){ } else if (importInfo.type() == ImportType::QrcDirectory){
@@ -372,11 +380,13 @@ Import LinkPrivate::importFileOrDirectory(const Document::Ptr &doc, const Import
importLibrary(doc, path, &import, import.object); importLibrary(doc, path, &import, import.object);
const QMap<QString, QStringList> paths const QMap<QString, QStringList> paths = ModelManagerInterface::instance()->filesInQrcPath(
= ModelManagerInterface::instance()->filesInQrcPath(path); pathStr);
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(Utils::FilePath::fromString(iter.key()))
Document::Ptr importedDoc = m_snapshot.document(iter.value().at(0)); .isQmlLikeLanguage()) {
Document::Ptr importedDoc = m_snapshot.document(
Utils::FilePath::fromString(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());
@@ -414,21 +424,24 @@ Import LinkPrivate::importNonFile(const Document::Ptr &doc, const ImportInfo &im
const QString packageName = importInfo.name(); const QString packageName = importInfo.name();
const ComponentVersion version = importInfo.version(); const ComponentVersion version = importInfo.version();
QStringList libraryPaths = modulePaths(packageName, version.toString(), m_importPaths + m_applicationDirectories); QList<Utils::FilePath> libraryPaths = modulePaths(packageName,
version.toString(),
m_importPaths + m_applicationDirectories);
bool importFound = false; bool importFound = false;
for (const QString &libPath : libraryPaths) { for (const Utils::FilePath &libPath : libraryPaths) {
importFound = !libPath.isEmpty() && importLibrary(doc, libPath, &import, import.object); importFound = !libPath.isEmpty() && importLibrary(doc, libPath, &import, import.object);
if (importFound) if (importFound)
break; break;
} }
if (!importFound) { if (!importFound) {
for (const QString &dir : qAsConst(m_applicationDirectories)) { for (const Utils::FilePath &dir : qAsConst(m_applicationDirectories)) {
QDirIterator it(dir, QStringList { "*.qmltypes" }, QDir::Files); auto qmltypes = dir.dirEntries(
Utils::FileFilter(QStringList{"*.qmltypes"}, QDir::Files));
// This adds the types to the C++ types, to be found below if applicable. // This adds the types to the C++ types, to be found below if applicable.
if (it.hasNext()) if (!qmltypes.isEmpty())
importLibrary(doc, dir, &import, import.object); importLibrary(doc, dir, &import, import.object);
} }
} }
@@ -455,8 +468,9 @@ Import LinkPrivate::importNonFile(const Document::Ptr &doc, const ImportInfo &im
if (!importFound && importInfo.ast()) { if (!importFound && importInfo.ast()) {
import.valid = false; import.valid = false;
error(doc, locationFromRange(importInfo.ast()->firstSourceLocation(), error(doc,
importInfo.ast()->lastSourceLocation()), locationFromRange(importInfo.ast()->firstSourceLocation(),
importInfo.ast()->lastSourceLocation()),
Link::tr( Link::tr(
"QML module not found (%1).\n\n" "QML module not found (%1).\n\n"
"Import paths:\n" "Import paths:\n"
@@ -467,19 +481,21 @@ Import LinkPrivate::importNonFile(const Document::Ptr &doc, const ImportInfo &im
"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" "For CMake projects, make sure QML_IMPORT_PATH variable is in CMakeCache.txt.\n"
"For qmlRegister... calls, make sure that you define the Module URI as a string literal.\n") "For qmlRegister... calls, make sure that you define the Module URI as a string literal.\n")
.arg(importInfo.name(), m_importPaths.join(QLatin1Char('\n')))); .arg(importInfo.name(),
Utils::transform(m_importPaths, [](const Utils::FilePath &p) {
return p.toString();
}).join("\n")));
} }
return import; return import;
} }
bool LinkPrivate::importLibrary(const Document::Ptr &doc, bool LinkPrivate::importLibrary(const Document::Ptr &doc,
const QString &libraryPath, const Utils::FilePath &libraryPath,
Import *import, Import *import,
ObjectValue *targetObject, ObjectValue *targetObject,
const QString &importPath, const Utils::FilePath &importPath,
bool optional bool optional)
)
{ {
const ImportInfo &importInfo = import->info; const ImportInfo &importInfo = import->info;
@@ -513,25 +529,36 @@ bool LinkPrivate::importLibrary(const Document::Ptr &doc,
subImport.valid = true; subImport.valid = true;
subImport.info = ImportInfo::moduleImport(importName, vNow, importInfo.as(), importInfo.ast()); subImport.info = ImportInfo::moduleImport(importName, vNow, importInfo.as(), importInfo.ast());
const QStringList libraryPaths = modulePaths(importName, vNow.toString(), m_importPaths); const QList<Utils::FilePath> libraryPaths = modulePaths(importName,
vNow.toString(),
m_importPaths);
subImport.libraryPath = libraryPaths.value(0); // first is the best match subImport.libraryPath = libraryPaths.value(0); // first is the best match
bool subImportFound = importLibrary(doc, subImport.libraryPath, &subImport, targetObject, importPath, true); bool subImportFound = importLibrary(doc, subImport.libraryPath, &subImport, targetObject, importPath, true);
if (!subImportFound && errorLoc.isValid()) { if (!subImportFound && errorLoc.isValid()) {
import->valid = false; import->valid = false;
if (!(optional || (toImport.flags & QmlDirParser::Import::Optional))) if (!(optional || (toImport.flags & QmlDirParser::Import::Optional))) {
error(doc, errorLoc, error(doc,
Link::tr( errorLoc,
"Implicit import '%1' of QML module '%2' not found.\n\n" Link::tr("Implicit import '%1' of QML module '%2' not found.\n\n"
"Import paths:\n" "Import paths:\n"
"%3\n\n" "%3\n\n"
"For qmake projects, use the QML_IMPORT_PATH variable to add import paths.\n" "For qmake projects, use the QML_IMPORT_PATH variable to add import "
"For Qbs projects, declare and set a qmlImportPaths property in your product " "paths.\n"
"to add import paths.\n" "For Qbs projects, declare and set a qmlImportPaths property in "
"For qmlproject projects, use the importPaths property to add import paths.\n" "your product "
"For CMake projects, make sure QML_IMPORT_PATH variable is in CMakeCache.txt.\n") "to add import paths.\n"
.arg(importName, importInfo.name(), m_importPaths.join(QLatin1Char('\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(importName,
importInfo.name(),
Utils::transform(m_importPaths, [](const Utils::FilePath &p) {
return p.toString();
}).join(QLatin1Char('\n'))));
}
} else if (!subImport.valid) { } else if (!subImport.valid) {
import->valid = false; import->valid = false;
} }
@@ -576,7 +603,9 @@ bool LinkPrivate::importLibrary(const Document::Ptr &doc,
} }
} else { } else {
const QString packageName = importInfo.name(); const QString packageName = importInfo.name();
m_valueOwner->cppQmlTypes().load(libraryPath, libraryInfo.metaObjects(), packageName); m_valueOwner->cppQmlTypes().load(libraryPath.toString(),
libraryInfo.metaObjects(),
packageName);
const auto objects = m_valueOwner->cppQmlTypes().createObjectsForImport(packageName, const auto objects = m_valueOwner->cppQmlTypes().createObjectsForImport(packageName,
version); version);
for (const CppComponentValue *object : objects) for (const CppComponentValue *object : objects)
@@ -627,8 +656,10 @@ void LinkPrivate::appendDiagnostic(const Document::Ptr &doc, const DiagnosticMes
(*allDiagnosticMessages)[doc->fileName()].append(message); (*allDiagnosticMessages)[doc->fileName()].append(message);
} }
void LinkPrivate::loadQmldirComponents(ObjectValue *import, ComponentVersion version, void LinkPrivate::loadQmldirComponents(ObjectValue *import,
const LibraryInfo &libraryInfo, const QString &libraryPath) ComponentVersion version,
const LibraryInfo &libraryInfo,
const Utils::FilePath &libraryPath)
{ {
// if the version isn't valid, import the latest // if the version isn't valid, import the latest
if (!version.isValid()) if (!version.isValid())
@@ -647,7 +678,7 @@ void LinkPrivate::loadQmldirComponents(ObjectValue *import, ComponentVersion ver
importedTypes.insert(component.typeName); importedTypes.insert(component.typeName);
if (Document::Ptr importedDoc = m_snapshot.document( if (Document::Ptr importedDoc = m_snapshot.document(
libraryPath + QLatin1Char('/') + component.fileName)) { libraryPath.pathAppended(component.fileName))) {
if (ObjectValue *v = importedDoc->bind()->rootObjectValue()) if (ObjectValue *v = importedDoc->bind()->rootObjectValue())
import->setMember(component.typeName, v); import->setMember(component.typeName, v);
} }
@@ -667,7 +698,7 @@ void LinkPrivate::loadImplicitDirectoryImports(Imports *imports, const Document:
imports->append(directoryImport); imports->append(directoryImport);
}; };
processImport(ImportInfo::implicitDirectoryImport(doc->path())); processImport(ImportInfo::implicitDirectoryImport(doc->path().path()));
const auto qrcPaths = ModelManagerInterface::instance()->qrcPathsForFile(doc->fileName()); const auto qrcPaths = ModelManagerInterface::instance()->qrcPathsForFile(doc->fileName());
for (const QString &path : qrcPaths) { for (const QString &path : qrcPaths) {
processImport(ImportInfo::qrcDirectoryImport( processImport(ImportInfo::qrcDirectoryImport(

View File

@@ -49,7 +49,7 @@ public:
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<Utils::FilePath, 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'

View File

@@ -84,21 +84,21 @@ static ModelManagerInterface *g_instance = nullptr;
static QMutex g_instanceMutex; static QMutex g_instanceMutex;
static const char *qtQuickUISuffix = "ui.qml"; static const char *qtQuickUISuffix = "ui.qml";
static void maybeAddPath(ViewerContext &context, const QString &path) static void maybeAddPath(ViewerContext &context, const Utils::FilePath &path)
{ {
if (!path.isEmpty() && !context.paths.contains(path)) if (!path.isEmpty() && !context.paths.contains(path))
context.paths.append(path); context.paths.append(path);
} }
static QStringList environmentImportPaths() static QList<Utils::FilePath> environmentImportPaths()
{ {
QStringList paths; QList<Utils::FilePath> paths;
const QStringList importPaths = QString::fromLocal8Bit(qgetenv("QML_IMPORT_PATH")).split( const QStringList importPaths = QString::fromLocal8Bit(qgetenv("QML_IMPORT_PATH")).split(
Utils::HostOsInfo::pathListSeparator(), Qt::SkipEmptyParts); Utils::HostOsInfo::pathListSeparator(), Qt::SkipEmptyParts);
for (const QString &path : importPaths) { for (const QString &path : importPaths) {
const QString canonicalPath = QDir(path).canonicalPath(); const Utils::FilePath canonicalPath = Utils::FilePath::fromString(path).canonicalPath();
if (!canonicalPath.isEmpty() && !paths.contains(canonicalPath)) if (!canonicalPath.isEmpty() && !paths.contains(canonicalPath))
paths.append(canonicalPath); paths.append(canonicalPath);
} }
@@ -177,15 +177,14 @@ static QHash<QString, Dialect> defaultLanguageMapping()
return res; return res;
} }
Dialect ModelManagerInterface::guessLanguageOfFile(const QString &fileName) Dialect ModelManagerInterface::guessLanguageOfFile(const Utils::FilePath &fileName)
{ {
QHash<QString, Dialect> lMapping; QHash<QString, Dialect> lMapping;
if (instance()) if (instance())
lMapping = instance()->languageForSuffix(); lMapping = instance()->languageForSuffix();
else else
lMapping = defaultLanguageMapping(); lMapping = defaultLanguageMapping();
const QFileInfo info(fileName); QString fileSuffix = fileName.suffix();
QString fileSuffix = info.suffix();
/* /*
* I was reluctant to use complete suffix in all cases, because it is a huge * I was reluctant to use complete suffix in all cases, because it is a huge
@@ -193,7 +192,7 @@ Dialect ModelManagerInterface::guessLanguageOfFile(const QString &fileName)
*/ */
if (fileSuffix == QLatin1String("qml")) if (fileSuffix == QLatin1String("qml"))
fileSuffix = info.completeSuffix(); fileSuffix = fileName.completeSuffix();
return lMapping.value(fileSuffix, Dialect::NoLanguage); return lMapping.value(fileSuffix, Dialect::NoLanguage);
} }
@@ -326,7 +325,7 @@ Snapshot ModelManagerInterface::newestSnapshot() const
return m_newestSnapshot; return m_newestSnapshot;
} }
void ModelManagerInterface::updateSourceFiles(const QStringList &files, void ModelManagerInterface::updateSourceFiles(const QList<Utils::FilePath> &files,
bool emitDocumentOnDiskChanged) bool emitDocumentOnDiskChanged)
{ {
if (m_indexerDisabled) if (m_indexerDisabled)
@@ -334,7 +333,7 @@ void ModelManagerInterface::updateSourceFiles(const QStringList &files,
refreshSourceFiles(files, emitDocumentOnDiskChanged); refreshSourceFiles(files, emitDocumentOnDiskChanged);
} }
QFuture<void> ModelManagerInterface::refreshSourceFiles(const QStringList &sourceFiles, QFuture<void> ModelManagerInterface::refreshSourceFiles(const QList<Utils::FilePath> &sourceFiles,
bool emitDocumentOnDiskChanged) bool emitDocumentOnDiskChanged)
{ {
if (sourceFiles.isEmpty()) if (sourceFiles.isEmpty())
@@ -365,21 +364,23 @@ QFuture<void> ModelManagerInterface::refreshSourceFiles(const QStringList &sourc
return result; return result;
} }
void ModelManagerInterface::fileChangedOnDisk(const Utils::FilePath &path)
void ModelManagerInterface::fileChangedOnDisk(const QString &path)
{ {
addFuture(Utils::runAsync(&ModelManagerInterface::parse, addFuture(Utils::runAsync(&ModelManagerInterface::parse,
workingCopyInternal(), QStringList(path), workingCopyInternal(),
this, Dialect(Dialect::AnyLanguage), true)); FilePaths({path}),
this,
Dialect(Dialect::AnyLanguage),
true));
} }
void ModelManagerInterface::removeFiles(const QStringList &files) void ModelManagerInterface::removeFiles(const QList<Utils::FilePath> &files)
{ {
emit aboutToRemoveFiles(files); emit aboutToRemoveFiles(files);
QMutexLocker locker(&m_mutex); QMutexLocker locker(&m_mutex);
for (const QString &file : files) { for (const Utils::FilePath &file : files) {
m_validSnapshot.remove(file); m_validSnapshot.remove(file);
m_newestSnapshot.remove(file); m_newestSnapshot.remove(file);
} }
@@ -389,8 +390,8 @@ namespace {
bool pInfoLessThanActive(const ModelManagerInterface::ProjectInfo &p1, bool pInfoLessThanActive(const ModelManagerInterface::ProjectInfo &p1,
const ModelManagerInterface::ProjectInfo &p2) const ModelManagerInterface::ProjectInfo &p2)
{ {
QStringList s1 = p1.activeResourceFiles; QList<Utils::FilePath> s1 = p1.activeResourceFiles;
QStringList s2 = p2.activeResourceFiles; QList<Utils::FilePath> s2 = p2.activeResourceFiles;
if (s1.size() < s2.size()) if (s1.size() < s2.size())
return true; return true;
if (s1.size() > s2.size()) if (s1.size() > s2.size())
@@ -407,8 +408,8 @@ bool pInfoLessThanActive(const ModelManagerInterface::ProjectInfo &p1,
bool pInfoLessThanAll(const ModelManagerInterface::ProjectInfo &p1, bool pInfoLessThanAll(const ModelManagerInterface::ProjectInfo &p1,
const ModelManagerInterface::ProjectInfo &p2) const ModelManagerInterface::ProjectInfo &p2)
{ {
QStringList s1 = p1.allResourceFiles; QList<Utils::FilePath> s1 = p1.allResourceFiles;
QStringList s2 = p2.allResourceFiles; QList<Utils::FilePath> s2 = p2.allResourceFiles;
if (s1.size() < s2.size()) if (s1.size() < s2.size())
return true; return true;
if (s1.size() > s2.size()) if (s1.size() > s2.size())
@@ -446,11 +447,10 @@ bool pInfoLessThanImports(const ModelManagerInterface::ProjectInfo &p1,
} }
static QList<Utils::FilePath> generatedQrc(QStringList applicationDirectories) static QList<Utils::FilePath> generatedQrc(QList<Utils::FilePath> applicationDirectories)
{ {
QList<Utils::FilePath> res; QList<Utils::FilePath> res;
for (const QString &pathStr : applicationDirectories) { for (const Utils::FilePath &path : applicationDirectories) {
Utils::FilePath path = Utils::FilePath::fromString(pathStr);
Utils::FilePath generatedQrcDir = path.pathAppended(".rcc"); Utils::FilePath generatedQrcDir = path.pathAppended(".rcc");
if (generatedQrcDir.isReadableDir()) { if (generatedQrcDir.isReadableDir()) {
for (const Utils::FilePath & qrcPath: generatedQrcDir.dirEntries(FileFilter(QStringList({QStringLiteral(u"*.qrc")}), QDir::Files))) for (const Utils::FilePath & qrcPath: generatedQrcDir.dirEntries(FileFilter(QStringList({QStringLiteral(u"*.qrc")}), QDir::Files)))
@@ -477,15 +477,14 @@ void ModelManagerInterface::iterateQrcFiles(
QSet<Utils::FilePath> pathsChecked; QSet<Utils::FilePath> pathsChecked;
for (const ModelManagerInterface::ProjectInfo &pInfo : qAsConst(pInfos)) { for (const ModelManagerInterface::ProjectInfo &pInfo : qAsConst(pInfos)) {
QStringList qrcFilePaths; QList<Utils::FilePath> qrcFilePaths;
if (resources == ActiveQrcResources) if (resources == ActiveQrcResources)
qrcFilePaths = pInfo.activeResourceFiles; qrcFilePaths = pInfo.activeResourceFiles;
else else
qrcFilePaths = pInfo.allResourceFiles; qrcFilePaths = pInfo.allResourceFiles;
for (const Utils::FilePath &p : generatedQrc(pInfo.applicationDirectories)) for (const Utils::FilePath &p : generatedQrc(pInfo.applicationDirectories))
qrcFilePaths.append(p.toString()); qrcFilePaths.append(p);
for (const QString &qrcFilePathStr : qAsConst(qrcFilePaths)) { for (const Utils::FilePath &qrcFilePath : qAsConst(qrcFilePaths)) {
auto qrcFilePath = Utils::FilePath::fromString(qrcFilePathStr);
if (pathsChecked.contains(qrcFilePath)) if (pathsChecked.contains(qrcFilePath))
continue; continue;
pathsChecked.insert(qrcFilePath); pathsChecked.insert(qrcFilePath);
@@ -497,13 +496,14 @@ void ModelManagerInterface::iterateQrcFiles(
} }
} }
QStringList ModelManagerInterface::qrcPathsForFile(const QString &file, const QLocale *locale, QStringList ModelManagerInterface::qrcPathsForFile(const Utils::FilePath &file,
const QLocale *locale,
ProjectExplorer::Project *project, ProjectExplorer::Project *project,
QrcResourceSelector resources) QrcResourceSelector resources)
{ {
QStringList res; QStringList res;
iterateQrcFiles(project, resources, [&](const QrcParser::ConstPtr &qrcFile) { iterateQrcFiles(project, resources, [&](const QrcParser::ConstPtr &qrcFile) {
qrcFile->collectResourceFilesForSourceFile(file, &res, locale); qrcFile->collectResourceFilesForSourceFile(file.toString(), &res, locale);
}); });
return res; return res;
} }
@@ -579,21 +579,20 @@ void ModelManagerInterface::updateProjectInfo(const ProjectInfo &pinfo, ProjectE
updateImportPaths(); updateImportPaths();
// remove files that are no longer in the project and have been deleted // remove files that are no longer in the project and have been deleted
QStringList deletedFiles; QList<Utils::FilePath> deletedFiles;
for (const QString &oldFile : qAsConst(oldInfo.sourceFiles)) { for (const Utils::FilePath &oldFile : qAsConst(oldInfo.sourceFiles)) {
if (snapshot.document(oldFile) if (snapshot.document(oldFile) && !pinfo.sourceFiles.contains(oldFile)
&& !pinfo.sourceFiles.contains(oldFile) && !oldFile.exists()) {
&& !QFile::exists(oldFile)) {
deletedFiles += oldFile; deletedFiles += oldFile;
} }
} }
removeFiles(deletedFiles); removeFiles(deletedFiles);
for (const QString &oldFile : qAsConst(deletedFiles)) for (const Utils::FilePath &oldFile : qAsConst(deletedFiles))
m_fileToProject.remove(oldFile, p); m_fileToProject.remove(oldFile, p);
// parse any files not yet in the snapshot // parse any files not yet in the snapshot
QStringList newFiles; QList<Utils::FilePath> newFiles;
for (const QString &file : qAsConst(pinfo.sourceFiles)) { for (const Utils::FilePath &file : qAsConst(pinfo.sourceFiles)) {
if (!m_fileToProject.contains(file, p)) if (!m_fileToProject.contains(file, p))
m_fileToProject.insert(file, p); m_fileToProject.insert(file, p);
if (!snapshot.document(file)) if (!snapshot.document(file))
@@ -604,12 +603,12 @@ void ModelManagerInterface::updateProjectInfo(const ProjectInfo &pinfo, ProjectE
// update qrc cache // update qrc cache
m_qrcContents = pinfo.resourceFileContents; m_qrcContents = pinfo.resourceFileContents;
for (const QString &newQrc : qAsConst(pinfo.allResourceFiles)) for (const Utils::FilePath &newQrc : qAsConst(pinfo.allResourceFiles))
m_qrcCache.addPath(newQrc, m_qrcContents.value(newQrc)); m_qrcCache.addPath(newQrc.toString(), m_qrcContents.value(newQrc));
for (const Utils::FilePath &newQrc : generatedQrc(pinfo.applicationDirectories)) for (const Utils::FilePath &newQrc : generatedQrc(pinfo.applicationDirectories))
m_qrcCache.addPath(newQrc.toString(), m_qrcContents.value(newQrc.toString())); m_qrcCache.addPath(newQrc.toString(), m_qrcContents.value(newQrc));
for (const QString &oldQrc : qAsConst(oldInfo.allResourceFiles)) for (const Utils::FilePath &oldQrc : qAsConst(oldInfo.allResourceFiles))
m_qrcCache.removePath(oldQrc); m_qrcCache.removePath(oldQrc.toString());
m_pluginDumper->loadBuiltinTypes(pinfo); m_pluginDumper->loadBuiltinTypes(pinfo);
emit projectInfoUpdated(pinfo); emit projectInfoUpdated(pinfo);
@@ -635,7 +634,7 @@ void ModelManagerInterface::removeProjectInfo(ProjectExplorer::Project *project)
\note Project pointer will be empty \note Project pointer will be empty
*/ */
ModelManagerInterface::ProjectInfo ModelManagerInterface::projectInfoForPath( ModelManagerInterface::ProjectInfo ModelManagerInterface::projectInfoForPath(
const QString &path) const const Utils::FilePath &path) const
{ {
ProjectInfo res; ProjectInfo res;
const auto allProjectInfos = allProjectInfosForPath(path); const auto allProjectInfos = allProjectInfosForPath(path);
@@ -659,16 +658,14 @@ ModelManagerInterface::ProjectInfo ModelManagerInterface::projectInfoForPath(
Returns list of project infos for \a path Returns list of project infos for \a path
*/ */
QList<ModelManagerInterface::ProjectInfo> ModelManagerInterface::allProjectInfosForPath( QList<ModelManagerInterface::ProjectInfo> ModelManagerInterface::allProjectInfosForPath(
const QString &path) const const Utils::FilePath &path) const
{ {
QList<ProjectExplorer::Project *> projects; QList<ProjectExplorer::Project *> projects;
{ {
QMutexLocker locker(&m_mutex); QMutexLocker locker(&m_mutex);
projects = m_fileToProject.values(path); projects = m_fileToProject.values(path);
if (projects.isEmpty()) { if (projects.isEmpty())
QFileInfo fInfo(path); projects = m_fileToProject.values(path.canonicalPath());
projects = m_fileToProject.values(fInfo.canonicalFilePath());
}
} }
QList<ProjectInfo> infos; QList<ProjectInfo> infos;
for (ProjectExplorer::Project *project : qAsConst(projects)) { for (ProjectExplorer::Project *project : qAsConst(projects)) {
@@ -689,9 +686,9 @@ void ModelManagerInterface::emitDocumentChangedOnDisk(Document::Ptr doc)
emit documentChangedOnDisk(std::move(doc)); emit documentChangedOnDisk(std::move(doc));
} }
void ModelManagerInterface::updateQrcFile(const QString &path) void ModelManagerInterface::updateQrcFile(const Utils::FilePath &path)
{ {
m_qrcCache.updatePath(path, m_qrcContents.value(path)); m_qrcCache.updatePath(path.toString(), m_qrcContents.value(path));
} }
void ModelManagerInterface::updateDocument(const Document::Ptr &doc) void ModelManagerInterface::updateDocument(const Document::Ptr &doc)
@@ -711,30 +708,30 @@ void ModelManagerInterface::updateLibraryInfo(const FilePath &path, const Librar
{ {
QMutexLocker locker(&m_mutex); QMutexLocker locker(&m_mutex);
m_validSnapshot.insertLibraryInfo(path.toString(), info); m_validSnapshot.insertLibraryInfo(path, info);
m_newestSnapshot.insertLibraryInfo(path.toString(), info); m_newestSnapshot.insertLibraryInfo(path, info);
} }
// only emit if we got new useful information // only emit if we got new useful information
if (info.isValid()) if (info.isValid())
emit libraryInfoUpdated(path.toString(), info); emit libraryInfoUpdated(path, info);
} }
static QStringList filesInDirectoryForLanguages(const QString &path, static QList<Utils::FilePath> filesInDirectoryForLanguages(const Utils::FilePath &path,
const QList<Dialect> &languages) const QList<Dialect> &languages)
{ {
const QStringList pattern = ModelManagerInterface::globPatternsForLanguages(languages); const QStringList pattern = ModelManagerInterface::globPatternsForLanguages(languages);
QStringList files; QList<Utils::FilePath> files;
const QDir dir(path); for (const Utils::FilePath &p : path.dirEntries(FileFilter(pattern, QDir::Files)))
const auto entries = dir.entryInfoList(pattern, QDir::Files); files.append(p.absoluteFilePath());
for (const QFileInfo &fi : entries)
files += fi.absoluteFilePath();
return files; return files;
} }
static void findNewImplicitImports(const Document::Ptr &doc, const Snapshot &snapshot, static void findNewImplicitImports(const Document::Ptr &doc,
QStringList *importedFiles, QSet<QString> *scannedPaths) const Snapshot &snapshot,
QList<Utils::FilePath> *importedFiles,
QSet<Utils::FilePath> *scannedPaths)
{ {
// scan files that could be implicitly imported // scan files that could be implicitly imported
// it's important we also do this for JS files, otherwise the isEmpty check will fail // it's important we also do this for JS files, otherwise the isEmpty check will fail
@@ -747,28 +744,33 @@ static void findNewImplicitImports(const Document::Ptr &doc, const Snapshot &sna
} }
} }
static void findNewFileImports(const Document::Ptr &doc, const Snapshot &snapshot, static void findNewFileImports(const Document::Ptr &doc,
QStringList *importedFiles, QSet<QString> *scannedPaths) const Snapshot &snapshot,
QList<Utils::FilePath> *importedFiles,
QSet<Utils::FilePath> *scannedPaths)
{ {
// scan files and directories that are explicitly imported // scan files and directories that are explicitly imported
const auto imports = doc->bind()->imports(); const auto imports = doc->bind()->imports();
for (const ImportInfo &import : imports) { for (const ImportInfo &import : imports) {
const QString &importName = import.path(); const QString &importName = import.path();
Utils::FilePath importPath = Utils::FilePath::fromString(importName);
if (import.type() == ImportType::File) { if (import.type() == ImportType::File) {
if (! snapshot.document(importName)) if (!snapshot.document(importPath))
*importedFiles += importName; *importedFiles += importPath;
} else if (import.type() == ImportType::Directory) { } else if (import.type() == ImportType::Directory) {
if (snapshot.documentsInDirectory(importName).isEmpty()) { if (snapshot.documentsInDirectory(importPath).isEmpty()) {
if (! scannedPaths->contains(importName)) { if (!scannedPaths->contains(importPath)) {
*importedFiles += filesInDirectoryForLanguages( *importedFiles
importName, doc->language().companionLanguages()); += filesInDirectoryForLanguages(importPath,
scannedPaths->insert(importName); doc->language().companionLanguages());
scannedPaths->insert(importPath);
} }
} }
} else if (import.type() == ImportType::QrcFile) { } else if (import.type() == ImportType::QrcFile) {
const QStringList importPaths const QStringList importPaths
= ModelManagerInterface::instance()->filesAtQrcPath(importName); = ModelManagerInterface::instance()->filesAtQrcPath(importName);
for (const QString &importPath : importPaths) { for (const QString &importStr : importPaths) {
Utils::FilePath importPath = Utils::FilePath::fromString(importStr);
if (!snapshot.document(importPath)) if (!snapshot.document(importPath))
*importedFiles += importPath; *importedFiles += importPath;
} }
@@ -776,10 +778,13 @@ static void findNewFileImports(const Document::Ptr &doc, const Snapshot &snapsho
const QMap<QString, QStringList> files const QMap<QString, QStringList> files
= ModelManagerInterface::instance()->filesInQrcPath(importName); = ModelManagerInterface::instance()->filesInQrcPath(importName);
for (auto qrc = files.cbegin(), end = files.cend(); qrc != end; ++qrc) { for (auto qrc = files.cbegin(), end = files.cend(); qrc != end; ++qrc) {
if (ModelManagerInterface::guessLanguageOfFile(qrc.key()).isQmlLikeOrJsLanguage()) { if (ModelManagerInterface::guessLanguageOfFile(
Utils::FilePath::fromString(qrc.key()))
.isQmlLikeOrJsLanguage()) {
for (const QString &sourceFile : qrc.value()) { for (const QString &sourceFile : qrc.value()) {
if (!snapshot.document(sourceFile)) auto sourceFilePath = Utils::FilePath::fromString(sourceFile);
*importedFiles += sourceFile; if (!snapshot.document(sourceFilePath))
*importedFiles += sourceFilePath;
} }
} }
} }
@@ -793,8 +798,9 @@ enum class LibraryStatus {
Unknown Unknown
}; };
static LibraryStatus libraryStatus(const FilePath &path, const Snapshot &snapshot, static LibraryStatus libraryStatus(const FilePath &path,
QSet<QString> *newLibraries) const Snapshot &snapshot,
QSet<Utils::FilePath> *newLibraries)
{ {
if (path.isEmpty()) if (path.isEmpty())
return LibraryStatus::Rejected; return LibraryStatus::Rejected;
@@ -802,7 +808,7 @@ static LibraryStatus libraryStatus(const FilePath &path, const Snapshot &snapsho
const LibraryInfo &existingInfo = snapshot.libraryInfo(path); const LibraryInfo &existingInfo = snapshot.libraryInfo(path);
if (existingInfo.isValid()) if (existingInfo.isValid())
return LibraryStatus::Accepted; return LibraryStatus::Accepted;
if (newLibraries->contains(path.toString())) if (newLibraries->contains(path))
return LibraryStatus::Accepted; return LibraryStatus::Accepted;
// if we looked at the path before, done // if we looked at the path before, done
return existingInfo.wasScanned() return existingInfo.wasScanned()
@@ -813,7 +819,7 @@ static LibraryStatus libraryStatus(const FilePath &path, const Snapshot &snapsho
static bool findNewQmlApplicationInPath(const FilePath &path, static bool findNewQmlApplicationInPath(const FilePath &path,
const Snapshot &snapshot, const Snapshot &snapshot,
ModelManagerInterface *modelManager, ModelManagerInterface *modelManager,
QSet<QString> *newLibraries) QSet<FilePath> *newLibraries)
{ {
switch (libraryStatus(path, snapshot, newLibraries)) { switch (libraryStatus(path, snapshot, newLibraries)) {
case LibraryStatus::Accepted: return true; case LibraryStatus::Accepted: return true;
@@ -821,45 +827,43 @@ static bool findNewQmlApplicationInPath(const FilePath &path,
default: break; default: break;
} }
QString qmltypesFile; FilePath qmltypesFile;
QDir dir(path.toString()); QList<Utils::FilePath> qmlTypes = path.dirEntries(
QDirIterator it(path.toString(), QStringList { "*.qmltypes" }, QDir::Files); FileFilter(QStringList{"*.qmltypes"}, QDir::Files));
if (!it.hasNext()) if (qmlTypes.isEmpty())
return false; return false;
qmltypesFile = it.next(); qmltypesFile = qmlTypes.first();
LibraryInfo libraryInfo = LibraryInfo(qmltypesFile); LibraryInfo libraryInfo = LibraryInfo(qmltypesFile.toString());
const QString libraryPath = dir.absolutePath(); const Utils::FilePath libraryPath = path.absolutePath();
newLibraries->insert(libraryPath); newLibraries->insert(libraryPath);
modelManager->updateLibraryInfo(path, libraryInfo); modelManager->updateLibraryInfo(path, libraryInfo);
modelManager->loadPluginTypes(QFileInfo(libraryPath).canonicalFilePath(), libraryPath, modelManager->loadPluginTypes(libraryPath.canonicalPath(), libraryPath, QString(), QString());
QString(), QString());
return true; return true;
} }
static bool findNewQmlLibraryInPath(const QString &path, static bool findNewQmlLibraryInPath(const Utils::FilePath &path,
const Snapshot &snapshot, const Snapshot &snapshot,
ModelManagerInterface *modelManager, ModelManagerInterface *modelManager,
QStringList *importedFiles, QList<Utils::FilePath> *importedFiles,
QSet<QString> *scannedPaths, QSet<Utils::FilePath> *scannedPaths,
QSet<QString> *newLibraries, QSet<Utils::FilePath> *newLibraries,
bool ignoreMissing) bool ignoreMissing)
{ {
switch (libraryStatus(FilePath::fromString(path), snapshot, newLibraries)) { switch (libraryStatus(path, snapshot, newLibraries)) {
case LibraryStatus::Accepted: return true; case LibraryStatus::Accepted: return true;
case LibraryStatus::Rejected: return false; case LibraryStatus::Rejected: return false;
default: break; default: break;
} }
const QDir dir(path); Utils::FilePath qmldirFile = path.pathAppended(QLatin1String("qmldir"));
QFile qmldirFile(dir.filePath(QLatin1String("qmldir")));
if (!qmldirFile.exists()) { if (!qmldirFile.exists()) {
if (!ignoreMissing) { if (!ignoreMissing) {
LibraryInfo libraryInfo(LibraryInfo::NotFound); LibraryInfo libraryInfo(LibraryInfo::NotFound);
modelManager->updateLibraryInfo(FilePath::fromString(path), libraryInfo); modelManager->updateLibraryInfo(path, libraryInfo);
} }
return false; return false;
} }
@@ -869,25 +873,24 @@ static bool findNewQmlLibraryInPath(const QString &path,
} }
// found a new library! // found a new library!
if (!qmldirFile.open(QFile::ReadOnly)) if (!qmldirFile.isReadableFile())
return false; return false;
QString qmldirData = QString::fromUtf8(qmldirFile.readAll()); QString qmldirData = QString::fromUtf8(qmldirFile.fileContents());
QmlDirParser qmldirParser; QmlDirParser qmldirParser;
qmldirParser.parse(qmldirData); qmldirParser.parse(qmldirData);
const QString libraryPath = QFileInfo(qmldirFile).absolutePath(); const Utils::FilePath libraryPath = qmldirFile.absolutePath();
newLibraries->insert(libraryPath); newLibraries->insert(libraryPath);
modelManager->updateLibraryInfo(FilePath::fromString(libraryPath), LibraryInfo(qmldirParser)); modelManager->updateLibraryInfo(libraryPath, LibraryInfo(qmldirParser));
modelManager->loadPluginTypes(QFileInfo(libraryPath).canonicalFilePath(), libraryPath, modelManager->loadPluginTypes(libraryPath.canonicalPath(), libraryPath, QString(), QString());
QString(), QString());
// scan the qml files in the library // scan the qml files in the library
const auto components = qmldirParser.components(); const auto components = qmldirParser.components();
for (const QmlDirParser::Component &component : components) { for (const QmlDirParser::Component &component : components) {
if (!component.fileName.isEmpty()) { if (!component.fileName.isEmpty()) {
const QFileInfo componentFileInfo(dir.filePath(component.fileName)); const FilePath componentFile = path.pathAppended(component.fileName);
const QString path = QDir::cleanPath(componentFileInfo.absolutePath()); const FilePath path = componentFile.absolutePath().cleanPath();
if (!scannedPaths->contains(path)) { if (!scannedPaths->contains(path)) {
*importedFiles += filesInDirectoryForLanguages(path, Dialect(Dialect::AnyLanguage) *importedFiles += filesInDirectoryForLanguages(path, Dialect(Dialect::AnyLanguage)
.companionLanguages()); .companionLanguages());
@@ -899,31 +902,39 @@ static bool findNewQmlLibraryInPath(const QString &path,
return true; return true;
} }
static QString modulePath(const ImportInfo &import, const QStringList &paths) static FilePath modulePath(const ImportInfo &import, const QList<FilePath> &paths)
{ {
if (!import.version().isValid()) if (!import.version().isValid())
return QString(); return FilePath();
const QStringList modPaths = modulePaths(import.name(), import.version().toString(), paths); const QList<FilePath> modPaths = modulePaths(import.name(), import.version().toString(), paths);
return modPaths.value(0); // first is best match return modPaths.value(0); // first is best match
} }
static void findNewLibraryImports(const Document::Ptr &doc, const Snapshot &snapshot, static void findNewLibraryImports(const Document::Ptr &doc,
ModelManagerInterface *modelManager, QStringList *importedFiles, const Snapshot &snapshot,
QSet<QString> *scannedPaths, QSet<QString> *newLibraries) ModelManagerInterface *modelManager,
QList<FilePath> *importedFiles,
QSet<Utils::FilePath> *scannedPaths,
QSet<Utils::FilePath> *newLibraries)
{ {
// scan current dir // scan current dir
findNewQmlLibraryInPath(doc->path(), snapshot, modelManager, findNewQmlLibraryInPath(doc->path(), snapshot, modelManager,
importedFiles, scannedPaths, newLibraries, false); importedFiles, scannedPaths, newLibraries, false);
// scan dir and lib imports // scan dir and lib imports
const QStringList importPaths = modelManager->importPathsNames(); const QList<FilePath> importPaths = modelManager->importPathsNames();
const auto imports = doc->bind()->imports(); const auto imports = doc->bind()->imports();
for (const ImportInfo &import : imports) { for (const ImportInfo &import : imports) {
switch (import.type()) { switch (import.type()) {
case ImportType::Directory: case ImportType::Directory:
findNewQmlLibraryInPath(import.path(), snapshot, modelManager, findNewQmlLibraryInPath(Utils::FilePath::fromString(import.path()),
importedFiles, scannedPaths, newLibraries, false); snapshot,
modelManager,
importedFiles,
scannedPaths,
newLibraries,
false);
break; break;
case ImportType::Library: case ImportType::Library:
findNewQmlLibraryInPath(modulePath(import, importPaths), snapshot, modelManager, findNewQmlLibraryInPath(modulePath(import, importPaths), snapshot, modelManager,
@@ -935,10 +946,10 @@ static void findNewLibraryImports(const Document::Ptr &doc, const Snapshot &snap
} }
} }
void ModelManagerInterface::parseLoop(QSet<QString> &scannedPaths, void ModelManagerInterface::parseLoop(QSet<Utils::FilePath> &scannedPaths,
QSet<QString> &newLibraries, QSet<Utils::FilePath> &newLibraries,
const WorkingCopy &workingCopy, const WorkingCopy &workingCopy,
QStringList files, QList<Utils::FilePath> files,
ModelManagerInterface *modelManager, ModelManagerInterface *modelManager,
Dialect mainLanguage, Dialect mainLanguage,
bool emitDocChangedOnDisk, bool emitDocChangedOnDisk,
@@ -948,7 +959,7 @@ void ModelManagerInterface::parseLoop(QSet<QString> &scannedPaths,
if (!reportProgress(qreal(i) / files.size())) if (!reportProgress(qreal(i) / files.size()))
return; return;
const QString fileName = files.at(i); const Utils::FilePath fileName = files.at(i);
Dialect language = guessLanguageOfFile(fileName); Dialect language = guessLanguageOfFile(fileName);
if (language == Dialect::NoLanguage) { if (language == Dialect::NoLanguage) {
@@ -971,12 +982,9 @@ void ModelManagerInterface::parseLoop(QSet<QString> &scannedPaths,
contents = entry.first; contents = entry.first;
documentRevision = entry.second; documentRevision = entry.second;
} else { } else {
QFile inFile(fileName); if (fileName.isReadableFile()) {
QTextStream ins(fileName.fileContents());
if (inFile.open(QIODevice::ReadOnly)) {
QTextStream ins(&inFile);
contents = ins.readAll(); contents = ins.readAll();
inFile.close();
} else { } else {
continue; continue;
} }
@@ -999,7 +1007,7 @@ void ModelManagerInterface::parseLoop(QSet<QString> &scannedPaths,
} }
#endif #endif
// get list of referenced files not yet in snapshot or in directories already scanned // get list of referenced files not yet in snapshot or in directories already scanned
QStringList importedFiles; QList<Utils::FilePath> importedFiles;
// update snapshot. requires synchronization, but significantly reduces amount of file // update snapshot. requires synchronization, but significantly reduces amount of file
// system queries for library imports because queries are cached in libraryInfo // system queries for library imports because queries are cached in libraryInfo
@@ -1015,7 +1023,7 @@ void ModelManagerInterface::parseLoop(QSet<QString> &scannedPaths,
} }
// add new files to parse list // add new files to parse list
for (const QString &file : qAsConst(importedFiles)) { for (const Utils::FilePath &file : qAsConst(importedFiles)) {
if (!files.contains(file)) if (!files.contains(file))
files.append(file); files.append(file);
} }
@@ -1048,7 +1056,7 @@ private:
void ModelManagerInterface::parse(QFutureInterface<void> &future, void ModelManagerInterface::parse(QFutureInterface<void> &future,
const WorkingCopy &workingCopy, const WorkingCopy &workingCopy,
QStringList files, QList<Utils::FilePath> files,
ModelManagerInterface *modelManager, ModelManagerInterface *modelManager,
Dialect mainLanguage, Dialect mainLanguage,
bool emitDocChangedOnDisk) bool emitDocChangedOnDisk)
@@ -1058,16 +1066,16 @@ void ModelManagerInterface::parse(QFutureInterface<void> &future,
future.setProgressRange(0, progressMax); future.setProgressRange(0, progressMax);
// paths we have scanned for files and added to the files list // paths we have scanned for files and added to the files list
QSet<QString> scannedPaths; QSet<Utils::FilePath> scannedPaths;
// libraries we've found while scanning imports // libraries we've found while scanning imports
QSet<QString> newLibraries; QSet<Utils::FilePath> newLibraries;
parseLoop(scannedPaths, newLibraries, workingCopy, std::move(files), modelManager, mainLanguage, parseLoop(scannedPaths, newLibraries, workingCopy, std::move(files), modelManager, mainLanguage,
emitDocChangedOnDisk, reporter); emitDocChangedOnDisk, reporter);
future.setProgressValue(progressMax); future.setProgressValue(progressMax);
} }
struct ScanItem { struct ScanItem {
QString path; Utils::FilePath path;
int depth = 0; int depth = 0;
Dialect language = Dialect::AnyLanguage; Dialect language = Dialect::AnyLanguage;
}; };
@@ -1079,20 +1087,20 @@ void ModelManagerInterface::importScan(QFutureInterface<void> &future,
bool emitDocChangedOnDisk, bool libOnly, bool forceRescan) bool emitDocChangedOnDisk, bool libOnly, bool forceRescan)
{ {
// paths we have scanned for files and added to the files list // paths we have scanned for files and added to the files list
QSet<QString> scannedPaths; QSet<Utils::FilePath> scannedPaths;
{ {
QMutexLocker l(&modelManager->m_mutex); QMutexLocker l(&modelManager->m_mutex);
scannedPaths = modelManager->m_scannedPaths; scannedPaths = modelManager->m_scannedPaths;
} }
// libraries we've found while scanning imports // libraries we've found while scanning imports
QSet<QString> newLibraries; QSet<Utils::FilePath> newLibraries;
QVector<ScanItem> pathsToScan; QVector<ScanItem> pathsToScan;
pathsToScan.reserve(paths.size()); pathsToScan.reserve(paths.size());
{ {
QMutexLocker l(&modelManager->m_mutex); QMutexLocker l(&modelManager->m_mutex);
for (const auto &path : paths) { for (const auto &path : paths) {
QString cPath = QDir::cleanPath(path.path().toString()); Utils::FilePath cPath = path.path().cleanPath();
if (!forceRescan && modelManager->m_scannedPaths.contains(cPath)) if (!forceRescan && modelManager->m_scannedPaths.contains(cPath))
continue; continue;
pathsToScan.append({cPath, 0, path.language()}); pathsToScan.append({cPath, 0, path.language()});
@@ -1111,7 +1119,7 @@ void ModelManagerInterface::importScan(QFutureInterface<void> &future,
pathsToScan.pop_back(); pathsToScan.pop_back();
int pathBudget = (1 << (maxScanDepth + 2 - toScan.depth)); int pathBudget = (1 << (maxScanDepth + 2 - toScan.depth));
if (forceRescan || !scannedPaths.contains(toScan.path)) { if (forceRescan || !scannedPaths.contains(toScan.path)) {
QStringList importedFiles; QList<Utils::FilePath> importedFiles;
if (forceRescan || if (forceRescan ||
(!findNewQmlLibraryInPath(toScan.path, snapshot, modelManager, &importedFiles, (!findNewQmlLibraryInPath(toScan.path, snapshot, modelManager, &importedFiles,
&scannedPaths, &newLibraries, true) &scannedPaths, &newLibraries, true)
@@ -1135,12 +1143,12 @@ void ModelManagerInterface::importScan(QFutureInterface<void> &future,
} }
// always descend tree, as we might have just scanned with a smaller depth // always descend tree, as we might have just scanned with a smaller depth
if (toScan.depth < maxScanDepth) { if (toScan.depth < maxScanDepth) {
QDir dir(toScan.path); Utils::FilePath dir = toScan.path;
QStringList subDirs(dir.entryList(QDir::Dirs | QDir::NoDotAndDotDot)); const QList<Utils::FilePath> subDirs = dir.dirEntries(QDir::Dirs | QDir::NoDotAndDotDot);
workDone += 1; workDone += 1;
totalWork += pathBudget / 2 * subDirs.size() - pathBudget * 3 / 4 + 1; totalWork += pathBudget / 2 * subDirs.size() - pathBudget * 3 / 4 + 1;
for (const QString &path : qAsConst(subDirs)) for (const Utils::FilePath &path : subDirs)
pathsToScan.append({dir.absoluteFilePath(path), toScan.depth + 1, toScan.language}); pathsToScan.append({path.absoluteFilePath(), toScan.depth + 1, toScan.language});
} else { } else {
workDone += pathBudget * 3 / 4; workDone += pathBudget * 3 / 4;
} }
@@ -1152,17 +1160,17 @@ void ModelManagerInterface::importScan(QFutureInterface<void> &future,
// assume no work has been done // assume no work has been done
QMutexLocker l(&modelManager->m_mutex); QMutexLocker l(&modelManager->m_mutex);
for (const auto &path : paths) for (const auto &path : paths)
modelManager->m_scannedPaths.remove(path.path().toString()); modelManager->m_scannedPaths.remove(path.path());
} }
} }
QStringList ModelManagerInterface::importPathsNames() const QList<Utils::FilePath> ModelManagerInterface::importPathsNames() const
{ {
QStringList names; QList<Utils::FilePath> names;
QMutexLocker l(&m_mutex); QMutexLocker l(&m_mutex);
names.reserve(m_allImportPaths.size()); names.reserve(m_allImportPaths.size());
for (const PathAndLanguage &x: m_allImportPaths) for (const PathAndLanguage &x: m_allImportPaths)
names << x.path().toString(); names << x.path();
return names; return names;
} }
@@ -1186,7 +1194,7 @@ void ModelManagerInterface::maybeScan(const PathsAndLanguages &importPaths)
{ {
QMutexLocker l(&m_mutex); QMutexLocker l(&m_mutex);
for (const PathAndLanguage &importPath : importPaths) for (const PathAndLanguage &importPath : importPaths)
if (!m_scannedPaths.contains(importPath.path().toString())) if (!m_scannedPaths.contains(importPath.path()))
pathToScan.maybeInsert(importPath); pathToScan.maybeInsert(importPath);
} }
@@ -1199,12 +1207,11 @@ void ModelManagerInterface::maybeScan(const PathsAndLanguages &importPaths)
} }
} }
static QList<Utils::FilePath> minimalPrefixPaths(const QStringList &paths) static QList<Utils::FilePath> minimalPrefixPaths(const QList<Utils::FilePath> &paths)
{ {
QList<Utils::FilePath> sortedPaths; QList<Utils::FilePath> sortedPaths;
// find minimal prefix, ensure '/' at end // find minimal prefix, ensure '/' at end
for (const QString &pathStr : qAsConst(paths)) { for (Utils::FilePath path : qAsConst(paths)) {
Utils::FilePath path = Utils::FilePath::fromString(pathStr);
if (!path.endsWith("/")) if (!path.endsWith("/"))
path.setPath(path.path() + "/"); path.setPath(path.path() + "/");
if (path.path().length() > 1) if (path.path().length() > 1)
@@ -1227,7 +1234,7 @@ void ModelManagerInterface::updateImportPaths()
if (m_indexerDisabled) if (m_indexerDisabled)
return; return;
PathsAndLanguages allImportPaths; PathsAndLanguages allImportPaths;
QStringList allApplicationDirectories; QList<Utils::FilePath> allApplicationDirectories;
QmlLanguageBundles activeBundles; QmlLanguageBundles activeBundles;
QmlLanguageBundles extendedBundles; QmlLanguageBundles extendedBundles;
for (const ProjectInfo &pInfo : qAsConst(m_projects)) { for (const ProjectInfo &pInfo : qAsConst(m_projects)) {
@@ -1242,8 +1249,8 @@ void ModelManagerInterface::updateImportPaths()
} }
for (const ViewerContext &vContext : qAsConst(m_defaultVContexts)) { for (const ViewerContext &vContext : qAsConst(m_defaultVContexts)) {
for (const QString &path : vContext.paths) for (const Utils::FilePath &path : vContext.paths)
allImportPaths.maybeInsert(Utils::FilePath::fromString(path), vContext.language); allImportPaths.maybeInsert(path, vContext.language);
allApplicationDirectories.append(vContext.applicationDirectories); allApplicationDirectories.append(vContext.applicationDirectories);
} }
@@ -1275,8 +1282,8 @@ void ModelManagerInterface::updateImportPaths()
allImportPaths.maybeInsert(importPath); allImportPaths.maybeInsert(importPath);
} }
for (const QString &path : qAsConst(m_defaultImportPaths)) for (const Utils::FilePath &path : qAsConst(m_defaultImportPaths))
allImportPaths.maybeInsert(Utils::FilePath::fromString(path), Dialect::Qml); allImportPaths.maybeInsert(path, Dialect::Qml);
allImportPaths.compact(); allImportPaths.compact();
allApplicationDirectories = Utils::filteredUnique(allApplicationDirectories); allApplicationDirectories = Utils::filteredUnique(allApplicationDirectories);
@@ -1291,18 +1298,17 @@ void ModelManagerInterface::updateImportPaths()
// check if any file in the snapshot imports something new in the new paths // check if any file in the snapshot imports something new in the new paths
Snapshot snapshot = m_validSnapshot; Snapshot snapshot = m_validSnapshot;
QStringList importedFiles; QList<Utils::FilePath> importedFiles;
QSet<QString> scannedPaths; QSet<Utils::FilePath> scannedPaths;
QSet<QString> newLibraries; QSet<Utils::FilePath> newLibraries;
for (const Document::Ptr &doc : qAsConst(snapshot)) for (const Document::Ptr &doc : qAsConst(snapshot))
findNewLibraryImports(doc, snapshot, this, &importedFiles, &scannedPaths, &newLibraries); findNewLibraryImports(doc, snapshot, this, &importedFiles, &scannedPaths, &newLibraries);
for (const QString &pathStr : qAsConst(allApplicationDirectories)) { for (const Utils::FilePath &path : qAsConst(allApplicationDirectories)) {
Utils::FilePath path = Utils::FilePath::fromString(pathStr);
allImportPaths.maybeInsert(path, Dialect::Qml); allImportPaths.maybeInsert(path, Dialect::Qml);
findNewQmlApplicationInPath(path, snapshot, this, &newLibraries); findNewQmlApplicationInPath(path, snapshot, this, &newLibraries);
} }
for (const Utils::FilePath &qrcPath : generatedQrc(allApplicationDirectories)) for (const Utils::FilePath &qrcPath : generatedQrc(allApplicationDirectories))
updateQrcFile(qrcPath.toString()); updateQrcFile(qrcPath);
updateSourceFiles(importedFiles, true); updateSourceFiles(importedFiles, true);
@@ -1311,8 +1317,10 @@ void ModelManagerInterface::updateImportPaths()
maybeScan(allImportPaths); maybeScan(allImportPaths);
} }
void ModelManagerInterface::loadPluginTypes(const QString &libraryPath, const QString &importPath, void ModelManagerInterface::loadPluginTypes(const Utils::FilePath &libraryPath,
const QString &importUri, const QString &importVersion) const Utils::FilePath &importPath,
const QString &importUri,
const QString &importVersion)
{ {
m_pluginDumper->loadPluginTypes(libraryPath, importPath, importUri, importVersion); m_pluginDumper->loadPluginTypes(libraryPath, importPath, importUri, importVersion);
} }
@@ -1526,25 +1534,25 @@ ViewerContext ModelManagerInterface::getVContext(const ViewerContext &vCtx,
Q_FALLTHROUGH(); Q_FALLTHROUGH();
case ViewerContext::AddAllPaths: case ViewerContext::AddAllPaths:
{ {
for (const QString &path : qAsConst(defaultVCtx.paths)) for (const Utils::FilePath &path : qAsConst(defaultVCtx.paths))
maybeAddPath(res, path); maybeAddPath(res, path);
switch (res.language.dialect()) { switch (res.language.dialect()) {
case Dialect::AnyLanguage: case Dialect::AnyLanguage:
case Dialect::Qml: case Dialect::Qml:
maybeAddPath(res, info.qtQmlPath.toString()); maybeAddPath(res, info.qtQmlPath);
Q_FALLTHROUGH(); Q_FALLTHROUGH();
case Dialect::QmlQtQuick2: case Dialect::QmlQtQuick2:
case Dialect::QmlQtQuick2Ui: case Dialect::QmlQtQuick2Ui:
{ {
if (res.language == Dialect::QmlQtQuick2 || res.language == Dialect::QmlQtQuick2Ui) if (res.language == Dialect::QmlQtQuick2 || res.language == Dialect::QmlQtQuick2Ui)
maybeAddPath(res, info.qtQmlPath.toString()); maybeAddPath(res, info.qtQmlPath);
QList<Dialect> languages = res.language.companionLanguages(); QList<Dialect> languages = res.language.companionLanguages();
auto addPathsOnLanguageMatch = [&](const PathsAndLanguages &importPaths) { auto addPathsOnLanguageMatch = [&](const PathsAndLanguages &importPaths) {
for (const auto &importPath : importPaths) { for (const auto &importPath : importPaths) {
if (languages.contains(importPath.language()) if (languages.contains(importPath.language())
|| importPath.language().companionLanguages().contains(res.language)) { || importPath.language().companionLanguages().contains(res.language)) {
maybeAddPath(res, importPath.path().toString()); maybeAddPath(res, importPath.path());
} }
} }
}; };
@@ -1561,7 +1569,7 @@ ViewerContext ModelManagerInterface::getVContext(const ViewerContext &vCtx,
addPathsOnLanguageMatch(pInfo.importPaths); addPathsOnLanguageMatch(pInfo.importPaths);
} }
const auto environmentPaths = environmentImportPaths(); const auto environmentPaths = environmentImportPaths();
for (const QString &path : environmentPaths) for (const Utils::FilePath &path : environmentPaths)
maybeAddPath(res, path); maybeAddPath(res, path);
break; break;
} }
@@ -1579,14 +1587,14 @@ ViewerContext ModelManagerInterface::getVContext(const ViewerContext &vCtx,
res.selectors.append(defaultVCtx.selectors); res.selectors.append(defaultVCtx.selectors);
Q_FALLTHROUGH(); Q_FALLTHROUGH();
case ViewerContext::AddDefaultPaths: case ViewerContext::AddDefaultPaths:
for (const QString &path : qAsConst(defaultVCtx.paths)) for (const Utils::FilePath &path : qAsConst(defaultVCtx.paths))
maybeAddPath(res, path); maybeAddPath(res, path);
if (res.language == Dialect::AnyLanguage || res.language == Dialect::Qml) if (res.language == Dialect::AnyLanguage || res.language == Dialect::Qml)
maybeAddPath(res, info.qtQmlPath.toString()); maybeAddPath(res, info.qtQmlPath);
if (res.language == Dialect::AnyLanguage || res.language == Dialect::Qml if (res.language == Dialect::AnyLanguage || res.language == Dialect::Qml
|| res.language == Dialect::QmlQtQuick2 || res.language == Dialect::QmlQtQuick2Ui) { || res.language == Dialect::QmlQtQuick2 || res.language == Dialect::QmlQtQuick2Ui) {
const auto environemntPaths = environmentImportPaths(); const auto environemntPaths = environmentImportPaths();
for (const QString &path : environemntPaths) for (const Utils::FilePath &path : environemntPaths)
maybeAddPath(res, path); maybeAddPath(res, path);
} }
break; break;
@@ -1676,7 +1684,7 @@ void ModelManagerInterface::addFuture(const QFuture<void> &future)
m_futureSynchronizer.addFuture(future); m_futureSynchronizer.addFuture(future);
} }
Document::Ptr ModelManagerInterface::ensuredGetDocumentForPath(const QString &filePath) Document::Ptr ModelManagerInterface::ensuredGetDocumentForPath(const Utils::FilePath &filePath)
{ {
QmlJS::Document::Ptr document = newestSnapshot().document(filePath); QmlJS::Document::Ptr document = newestSnapshot().document(filePath);
if (!document) { if (!document) {
@@ -1691,7 +1699,7 @@ Document::Ptr ModelManagerInterface::ensuredGetDocumentForPath(const QString &fi
void ModelManagerInterface::resetCodeModel() void ModelManagerInterface::resetCodeModel()
{ {
QStringList documents; QList<Utils::FilePath> documents;
{ {
QMutexLocker locker(&m_mutex); QMutexLocker locker(&m_mutex);

View File

@@ -68,12 +68,12 @@ public:
struct ProjectInfo struct ProjectInfo
{ {
QPointer<ProjectExplorer::Project> project; QPointer<ProjectExplorer::Project> project;
QStringList sourceFiles; QList<Utils::FilePath> sourceFiles;
PathsAndLanguages importPaths; PathsAndLanguages importPaths;
QStringList activeResourceFiles; QList<Utils::FilePath> activeResourceFiles;
QStringList allResourceFiles; QList<Utils::FilePath> allResourceFiles;
QHash<QString, QString> resourceFileContents; QHash<Utils::FilePath, QString> resourceFileContents;
QStringList applicationDirectories; QList<Utils::FilePath> applicationDirectories;
QHash<QString, QString> moduleMappings; // E.g.: QtQuick.Controls -> MyProject.MyControls QHash<QString, QString> moduleMappings; // E.g.: QtQuick.Controls -> MyProject.MyControls
// whether trying to run qmldump makes sense // whether trying to run qmldump makes sense
@@ -91,18 +91,18 @@ public:
class WorkingCopy class WorkingCopy
{ {
public: public:
using Table = QHash<QString, QPair<QString, int>>; using Table = QHash<Utils::FilePath, QPair<QString, int>>;
void insert(const QString &fileName, const QString &source, int revision = 0) void insert(const Utils::FilePath &fileName, const QString &source, int revision = 0)
{ m_elements.insert(fileName, {source, revision}); } { m_elements.insert(fileName, {source, revision}); }
bool contains(const QString &fileName) const bool contains(const Utils::FilePath &fileName) const
{ return m_elements.contains(fileName); } { return m_elements.contains(fileName); }
QString source(const QString &fileName) const QString source(const Utils::FilePath &fileName) const
{ return m_elements.value(fileName).first; } { return m_elements.value(fileName).first; }
QPair<QString, int> get(const QString &fileName) const QPair<QString, int> get(const Utils::FilePath &fileName) const
{ return m_elements.value(fileName); } { return m_elements.value(fileName); }
Table all() const Table all() const
@@ -124,7 +124,7 @@ public:
ModelManagerInterface(QObject *parent = nullptr); ModelManagerInterface(QObject *parent = nullptr);
~ModelManagerInterface() override; ~ModelManagerInterface() override;
static Dialect guessLanguageOfFile(const QString &fileName); static Dialect guessLanguageOfFile(const Utils::FilePath &fileName);
static QStringList globPatternsForLanguages(const QList<Dialect> &languages); static QStringList globPatternsForLanguages(const QList<Dialect> &languages);
static ModelManagerInterface *instance(); static ModelManagerInterface *instance();
static ModelManagerInterface *instanceForFuture(const QFuture<void> &future); static ModelManagerInterface *instanceForFuture(const QFuture<void> &future);
@@ -135,11 +135,11 @@ public:
QmlJS::Snapshot newestSnapshot() const; QmlJS::Snapshot newestSnapshot() const;
void activateScan(); void activateScan();
void updateSourceFiles(const QStringList &files, void updateSourceFiles(const QList<Utils::FilePath> &files, bool emitDocumentOnDiskChanged);
bool emitDocumentOnDiskChanged); void fileChangedOnDisk(const Utils::FilePath &path);
void fileChangedOnDisk(const QString &path); void removeFiles(const QList<Utils::FilePath> &files);
void removeFiles(const QStringList &files); QStringList qrcPathsForFile(const Utils::FilePath &file,
QStringList qrcPathsForFile(const QString &file, const QLocale *locale = nullptr, const QLocale *locale = nullptr,
ProjectExplorer::Project *project = nullptr, ProjectExplorer::Project *project = nullptr,
QrcResourceSelector resources = AllQrcResources); QrcResourceSelector resources = AllQrcResources);
QStringList filesAtQrcPath(const QString &path, const QLocale *locale = nullptr, QStringList filesAtQrcPath(const QString &path, const QLocale *locale = nullptr,
@@ -160,16 +160,18 @@ public:
void updateDocument(const QmlJS::Document::Ptr& doc); void updateDocument(const QmlJS::Document::Ptr& doc);
void updateLibraryInfo(const Utils::FilePath &path, const QmlJS::LibraryInfo &info); void updateLibraryInfo(const Utils::FilePath &path, const QmlJS::LibraryInfo &info);
void emitDocumentChangedOnDisk(QmlJS::Document::Ptr doc); void emitDocumentChangedOnDisk(QmlJS::Document::Ptr doc);
void updateQrcFile(const QString &path); void updateQrcFile(const Utils::FilePath &path);
ProjectInfo projectInfoForPath(const QString &path) const; ProjectInfo projectInfoForPath(const Utils::FilePath &path) const;
QList<ProjectInfo> allProjectInfosForPath(const QString &path) const; QList<ProjectInfo> allProjectInfosForPath(const Utils::FilePath &path) const;
QStringList importPathsNames() const; QList<Utils::FilePath> importPathsNames() const;
QmlJS::QmlLanguageBundles activeBundles() const; QmlJS::QmlLanguageBundles activeBundles() const;
QmlJS::QmlLanguageBundles extendedBundles() const; QmlJS::QmlLanguageBundles extendedBundles() const;
void loadPluginTypes(const QString &libraryPath, const QString &importPath, void loadPluginTypes(const Utils::FilePath &libraryPath,
const QString &importUri, const QString &importVersion); const Utils::FilePath &importPath,
const QString &importUri,
const QString &importVersion);
CppDataHash cppData() const; CppDataHash cppData() const;
LibraryInfo builtins(const Document::Ptr &doc) const; LibraryInfo builtins(const Document::Ptr &doc) const;
@@ -192,7 +194,7 @@ public:
void addFuture(const QFuture<T> &future) { addFuture(QFuture<void>(future)); } void addFuture(const QFuture<T> &future) { addFuture(QFuture<void>(future)); }
void addFuture(const QFuture<void> &future); void addFuture(const QFuture<void> &future);
QmlJS::Document::Ptr ensuredGetDocumentForPath(const QString &filePath); QmlJS::Document::Ptr ensuredGetDocumentForPath(const Utils::FilePath &filePath);
static void importScan(QFutureInterface<void> &future, const WorkingCopy& workingCopyInternal, static void importScan(QFutureInterface<void> &future, const WorkingCopy& workingCopyInternal,
const PathsAndLanguages& paths, ModelManagerInterface *modelManager, const PathsAndLanguages& paths, ModelManagerInterface *modelManager,
bool emitDocChangedOnDisk, bool libOnly = true, bool emitDocChangedOnDisk, bool libOnly = true,
@@ -205,10 +207,10 @@ public:
signals: signals:
void documentUpdated(QmlJS::Document::Ptr doc); void documentUpdated(QmlJS::Document::Ptr doc);
void documentChangedOnDisk(QmlJS::Document::Ptr doc); void documentChangedOnDisk(QmlJS::Document::Ptr doc);
void aboutToRemoveFiles(const QStringList &files); void aboutToRemoveFiles(const QList<Utils::FilePath> &files);
void libraryInfoUpdated(const QString &path, const QmlJS::LibraryInfo &info); void libraryInfoUpdated(const Utils::FilePath &path, const QmlJS::LibraryInfo &info);
void projectInfoUpdated(const ProjectInfo &pinfo); void projectInfoUpdated(const ProjectInfo &pinfo);
void projectPathChanged(const QString &projectPath); void projectPathChanged(const Utils::FilePath &projectPath);
protected: protected:
Q_INVOKABLE void queueCppQmlTypeUpdate(const CPlusPlus::Document::Ptr &doc, bool scan); Q_INVOKABLE void queueCppQmlTypeUpdate(const CPlusPlus::Document::Ptr &doc, bool scan);
@@ -221,17 +223,20 @@ protected:
virtual void addTaskInternal(const QFuture<void> &result, const QString &msg, virtual void addTaskInternal(const QFuture<void> &result, const QString &msg,
const char *taskId) const; const char *taskId) const;
QFuture<void> refreshSourceFiles(const QStringList &sourceFiles, QFuture<void> refreshSourceFiles(const QList<Utils::FilePath> &sourceFiles,
bool emitDocumentOnDiskChanged); bool emitDocumentOnDiskChanged);
static void parseLoop(QSet<QString> &scannedPaths, QSet<QString> &newLibraries, static void parseLoop(QSet<Utils::FilePath> &scannedPaths,
const WorkingCopy &workingCopyInternal, QStringList files, QSet<Utils::FilePath> &newLibraries,
const WorkingCopy &workingCopyInternal,
QList<Utils::FilePath> files,
ModelManagerInterface *modelManager, ModelManagerInterface *modelManager,
QmlJS::Dialect mainLanguage, bool emitDocChangedOnDisk, QmlJS::Dialect mainLanguage,
bool emitDocChangedOnDisk,
const std::function<bool(qreal)> &reportProgress); const std::function<bool(qreal)> &reportProgress);
static void parse(QFutureInterface<void> &future, static void parse(QFutureInterface<void> &future,
const WorkingCopy &workingCopyInternal, const WorkingCopy &workingCopyInternal,
QStringList files, QList<Utils::FilePath> files,
ModelManagerInterface *modelManager, ModelManagerInterface *modelManager,
QmlJS::Dialect mainLanguage, QmlJS::Dialect mainLanguage,
bool emitDocChangedOnDisk); bool emitDocChangedOnDisk);
@@ -257,19 +262,19 @@ private:
QmlJS::Snapshot m_newestSnapshot; QmlJS::Snapshot m_newestSnapshot;
PathsAndLanguages m_allImportPaths; PathsAndLanguages m_allImportPaths;
QList<Utils::FilePath> m_applicationPaths; QList<Utils::FilePath> m_applicationPaths;
QStringList m_defaultImportPaths; QList<Utils::FilePath> m_defaultImportPaths;
QmlJS::QmlLanguageBundles m_activeBundles; QmlJS::QmlLanguageBundles m_activeBundles;
QmlJS::QmlLanguageBundles m_extendedBundles; QmlJS::QmlLanguageBundles m_extendedBundles;
QHash<Dialect, QmlJS::ViewerContext> m_defaultVContexts; QHash<Dialect, QmlJS::ViewerContext> m_defaultVContexts;
bool m_shouldScanImports = false; bool m_shouldScanImports = false;
QSet<QString> m_scannedPaths; QSet<Utils::FilePath> m_scannedPaths;
QTimer *m_updateCppQmlTypesTimer = nullptr; QTimer *m_updateCppQmlTypesTimer = nullptr;
QTimer *m_asyncResetTimer = nullptr; QTimer *m_asyncResetTimer = nullptr;
QHash<QString, QPair<CPlusPlus::Document::Ptr, bool>> m_queuedCppDocuments; QHash<QString, QPair<CPlusPlus::Document::Ptr, bool>> m_queuedCppDocuments;
QFuture<void> m_cppQmlTypesUpdater; QFuture<void> m_cppQmlTypesUpdater;
Utils::QrcCache m_qrcCache; Utils::QrcCache m_qrcCache;
QHash<QString, QString> m_qrcContents; QHash<Utils::FilePath, QString> m_qrcContents;
CppDataHash m_cppDataHash; CppDataHash m_cppDataHash;
QHash<QString, QList<CPlusPlus::Document::Ptr>> m_cppDeclarationFiles; QHash<QString, QList<CPlusPlus::Document::Ptr>> m_cppDeclarationFiles;
@@ -279,7 +284,7 @@ private:
QMap<ProjectExplorer::Project *, ProjectInfo> m_projects; QMap<ProjectExplorer::Project *, ProjectInfo> m_projects;
ProjectInfo m_defaultProjectInfo; ProjectInfo m_defaultProjectInfo;
ProjectExplorer::Project *m_defaultProject = nullptr; ProjectExplorer::Project *m_defaultProject = nullptr;
QMultiHash<QString, ProjectExplorer::Project *> m_fileToProject; QMultiHash<Utils::FilePath, ProjectExplorer::Project *> m_fileToProject;
PluginDumper *m_pluginDumper = nullptr; PluginDumper *m_pluginDumper = nullptr;

View File

@@ -71,7 +71,10 @@ void PluginDumper::loadBuiltinTypes(const QmlJS::ModelManagerInterface::ProjectI
metaObject()->invokeMethod(this, [=] { onLoadBuiltinTypes(info); }); metaObject()->invokeMethod(this, [=] { onLoadBuiltinTypes(info); });
} }
void PluginDumper::loadPluginTypes(const QString &libraryPath, const QString &importPath, const QString &importUri, const QString &importVersion) void PluginDumper::loadPluginTypes(const Utils::FilePath &libraryPath,
const Utils::FilePath &importPath,
const QString &importUri,
const QString &importVersion)
{ {
// move to the owning thread // move to the owning thread
metaObject()->invokeMethod(this, [=] { onLoadPluginTypes(libraryPath, importPath, metaObject()->invokeMethod(this, [=] { onLoadPluginTypes(libraryPath, importPath,
@@ -113,9 +116,12 @@ void PluginDumper::onLoadBuiltinTypes(const QmlJS::ModelManagerInterface::Projec
m_qtToInfo.insert(info.qtQmlPath.toString(), info); m_qtToInfo.insert(info.qtQmlPath.toString(), info);
} }
void PluginDumper::onLoadPluginTypes(const QString &libraryPath, const QString &importPath, const QString &importUri, const QString &importVersion) void PluginDumper::onLoadPluginTypes(const Utils::FilePath &libraryPath,
const Utils::FilePath &importPath,
const QString &importUri,
const QString &importVersion)
{ {
const FilePath canonicalLibraryPath = FilePath::fromUserInput(libraryPath).cleanPath(); const FilePath canonicalLibraryPath = libraryPath.cleanPath();
if (m_runningQmldumps.values().contains(canonicalLibraryPath)) if (m_runningQmldumps.values().contains(canonicalLibraryPath))
return; return;
const Snapshot snapshot = m_modelManager->snapshot(); const Snapshot snapshot = m_modelManager->snapshot();
@@ -389,7 +395,7 @@ QFuture<PluginDumper::QmlTypeDescription> PluginDumper::loadQmlTypeDescription(c
* \sa QmlJs::modulePath * \sa QmlJs::modulePath
* \sa LinkPrivate::importNonFile * \sa LinkPrivate::importNonFile
*/ */
QString PluginDumper::buildQmltypesPath(const QString &name) const Utils::FilePath PluginDumper::buildQmltypesPath(const QString &name) const
{ {
QString qualifiedName; QString qualifiedName;
QString version; QString version;
@@ -401,18 +407,19 @@ QString PluginDumper::buildQmltypesPath(const QString &name) const
version = m.captured("major") + QLatin1Char('.') + m.captured("minor"); version = m.captured("major") + QLatin1Char('.') + m.captured("minor");
} }
const QStringList paths = modulePaths(qualifiedName, version, m_modelManager->importPathsNames()); const QList<Utils::FilePath> paths = modulePaths(qualifiedName,
version,
m_modelManager->importPathsNames());
if (paths.isEmpty()) if (paths.isEmpty())
return QString(); return Utils::FilePath();
for (const QString &path : paths) { for (const Utils::FilePath &path : paths) {
QDirIterator it(path, QStringList { "*.qmltypes" }, QDir::Files); auto qmltypes = path.dirEntries(FileFilter(QStringList{"*.qmltypes"}, QDir::Files));
if (!qmltypes.isEmpty())
if (it.hasNext()) return qmltypes.first();
return it.next();
} }
return QString(); return Utils::FilePath();
} }
/*! /*!
@@ -434,11 +441,11 @@ QFuture<PluginDumper::DependencyInfo> PluginDumper::loadDependencies(const FileP
visited = QSharedPointer<QSet<FilePath>>(new QSet<FilePath>()); visited = QSharedPointer<QSet<FilePath>>(new QSet<FilePath>());
FilePaths dependenciesPaths; FilePaths dependenciesPaths;
QString path; FilePath path;
for (const FilePath &name : dependencies) { for (const FilePath &name : dependencies) {
path = buildQmltypesPath(name.toString()); path = buildQmltypesPath(name.toString());
if (!path.isNull()) if (!path.isEmpty())
dependenciesPaths << FilePath::fromString(path); dependenciesPaths << path;
visited->insert(name); visited->insert(name);
} }
@@ -665,7 +672,8 @@ void PluginDumper::dump(const Plugin &plugin)
args << QLatin1String("-nonrelocatable"); args << QLatin1String("-nonrelocatable");
args << plugin.importUri; args << plugin.importUri;
args << plugin.importVersion; args << plugin.importVersion;
args << (plugin.importPath.isEmpty() ? QLatin1String(".") : plugin.importPath); args << (plugin.importPath.isEmpty() ? Utils::FilePath::fromString(".") : plugin.importPath)
.toString();
runQmlDump(info, args, plugin.qmldirPath); runQmlDump(info, args, plugin.qmldirPath);
} }

View File

@@ -49,15 +49,19 @@ public:
public: public:
void loadBuiltinTypes(const QmlJS::ModelManagerInterface::ProjectInfo &info); void loadBuiltinTypes(const QmlJS::ModelManagerInterface::ProjectInfo &info);
void loadPluginTypes(const QString &libraryPath, const QString &importPath, void loadPluginTypes(const Utils::FilePath &libraryPath,
const QString &importUri, const QString &importVersion); const Utils::FilePath &importPath,
const QString &importUri,
const QString &importVersion);
void scheduleRedumpPlugins(); void scheduleRedumpPlugins();
private: private:
Q_INVOKABLE void onLoadBuiltinTypes(const QmlJS::ModelManagerInterface::ProjectInfo &info, Q_INVOKABLE void onLoadBuiltinTypes(const QmlJS::ModelManagerInterface::ProjectInfo &info,
bool force = false); bool force = false);
Q_INVOKABLE void onLoadPluginTypes(const QString &libraryPath, const QString &importPath, Q_INVOKABLE void onLoadPluginTypes(const Utils::FilePath &libraryPath,
const QString &importUri, const QString &importVersion); const Utils::FilePath &importPath,
const QString &importUri,
const QString &importVersion);
Q_INVOKABLE void dumpAllPlugins(); Q_INVOKABLE void dumpAllPlugins();
void qmlPluginTypeDumpDone(Utils::QtcProcess *process); void qmlPluginTypeDumpDone(Utils::QtcProcess *process);
void pluginChanged(const QString &pluginLibrary); void pluginChanged(const QString &pluginLibrary);
@@ -66,7 +70,7 @@ private:
class Plugin { class Plugin {
public: public:
Utils::FilePath qmldirPath; Utils::FilePath qmldirPath;
QString importPath; Utils::FilePath importPath;
QString importUri; QString importUri;
QString importVersion; QString importVersion;
Utils::FilePaths typeInfoPaths; Utils::FilePaths typeInfoPaths;
@@ -92,7 +96,7 @@ private:
const Utils::FilePath &importPath); const Utils::FilePath &importPath);
void dump(const Plugin &plugin); void dump(const Plugin &plugin);
QFuture<QmlTypeDescription> loadQmlTypeDescription(const Utils::FilePaths &path) const; QFuture<QmlTypeDescription> loadQmlTypeDescription(const Utils::FilePaths &path) const;
QString buildQmltypesPath(const QString &name) const; Utils::FilePath buildQmltypesPath(const QString &name) const;
QFuture<PluginDumper::DependencyInfo> loadDependencies(const Utils::FilePaths &dependencies, QFuture<PluginDumper::DependencyInfo> loadDependencies(const Utils::FilePaths &dependencies,
QSharedPointer<QSet<Utils::FilePath> > visited) const; QSharedPointer<QSet<Utils::FilePath> > visited) const;

View File

@@ -291,7 +291,7 @@ static void addInstantiatingComponents(ContextPtr context, QmlComponentChain *ch
const QString &comment = chain->document()->source().mid(commentLoc.begin(), commentLoc.length); const QString &comment = chain->document()->source().mid(commentLoc.begin(), commentLoc.length);
// find all @scope annotations // find all @scope annotations
QStringList additionalScopes; QList<Utils::FilePath> additionalScopes;
int lastOffset = -1; int lastOffset = -1;
QRegularExpressionMatch match; QRegularExpressionMatch match;
forever { forever {
@@ -299,13 +299,16 @@ static void addInstantiatingComponents(ContextPtr context, QmlComponentChain *ch
lastOffset = match.capturedStart(); lastOffset = match.capturedStart();
if (lastOffset == -1) if (lastOffset == -1)
break; break;
additionalScopes << QFileInfo(chain->document()->path() + QLatin1Char('/') + match.captured(1).trimmed()).absoluteFilePath(); additionalScopes << chain->document()
->path()
.pathAppended(match.captured(1).trimmed())
.absoluteFilePath();
} }
foreach (const QmlComponentChain *c, chain->instantiatingComponents()) foreach (const QmlComponentChain *c, chain->instantiatingComponents())
additionalScopes.removeAll(c->document()->fileName()); additionalScopes.removeAll(c->document()->fileName());
foreach (const QString &scope, additionalScopes) { foreach (const Utils::FilePath &scope, additionalScopes) {
Document::Ptr doc = context->snapshot().document(scope); Document::Ptr doc = context->snapshot().document(scope);
if (doc) { if (doc) {
QmlComponentChain *ch = new QmlComponentChain(doc); QmlComponentChain *ch = new QmlComponentChain(doc);
@@ -343,10 +346,12 @@ void ScopeChain::initializeRootScope()
if (!m_document->bind()->isJsLibrary()) { if (!m_document->bind()->isJsLibrary()) {
foreach (Document::Ptr otherDoc, snapshot) { foreach (Document::Ptr otherDoc, snapshot) {
foreach (const ImportInfo &import, otherDoc->bind()->imports()) { foreach (const ImportInfo &import, otherDoc->bind()->imports()) {
if ((import.type() == ImportType::File && m_document->fileName() == import.path()) if ((import.type() == ImportType::File
|| (import.type() == ImportType::QrcFile && m_document->fileName().toString() == import.path())
&& ModelManagerInterface::instance()->filesAtQrcPath(import.path()) || (import.type() == ImportType::QrcFile
.contains(m_document->fileName()))) { && ModelManagerInterface::instance()
->filesAtQrcPath(import.path())
.contains(m_document->fileName().path()))) {
QmlComponentChain *component = new QmlComponentChain(otherDoc); QmlComponentChain *component = new QmlComponentChain(otherDoc);
componentScopes.insert(otherDoc.data(), component); componentScopes.insert(otherDoc.data(), component);
chain->addInstantiatingComponent(component); chain->addInstantiatingComponent(component);

View File

@@ -27,6 +27,7 @@
#include "parser/qmljsast_p.h" #include "parser/qmljsast_p.h"
#include <utils/filepath.h>
#include <utils/stringutils.h> #include <utils/stringutils.h>
#include <QColor> #include <QColor>
@@ -256,8 +257,9 @@ const QStringList QmlJS::splitVersion(const QString &version)
* \return The module paths if found, an empty string otherwise * \return The module paths if found, an empty string otherwise
* \see qmlimportscanner in qtdeclarative/tools * \see qmlimportscanner in qtdeclarative/tools
*/ */
QStringList QmlJS::modulePaths(const QString &name, const QString &version, QList<Utils::FilePath> QmlJS::modulePaths(const QString &name,
const QStringList &importPaths) const QString &version,
const QList<Utils::FilePath> &importPaths)
{ {
Q_ASSERT(maybeModuleVersion(version)); Q_ASSERT(maybeModuleVersion(version));
if (importPaths.isEmpty()) if (importPaths.isEmpty())
@@ -267,27 +269,27 @@ QStringList QmlJS::modulePaths(const QString &name, const QString &version,
const QStringList parts = name.split('.', Qt::SkipEmptyParts); const QStringList parts = name.split('.', Qt::SkipEmptyParts);
auto mkpath = [](const QStringList &xs) -> QString { return xs.join(QLatin1Char('/')); }; auto mkpath = [](const QStringList &xs) -> QString { return xs.join(QLatin1Char('/')); };
QStringList result; QList<Utils::FilePath> result;
QString candidate; Utils::FilePath candidate;
for (const QString &versionPart : splitVersion(sanitizedVersion)) { for (const QString &versionPart : splitVersion(sanitizedVersion)) {
for (const QString &path : importPaths) { for (const Utils::FilePath &path : importPaths) {
for (int i = parts.count() - 1; i >= 0; --i) { for (int i = parts.count() - 1; i >= 0; --i) {
candidate = QDir::cleanPath(QString::fromLatin1("%1/%2.%3/%4") candidate = path.pathAppended(QString::fromLatin1("%2.%3/%4")
.arg(path, .arg(mkpath(parts.mid(0, i + 1)),
mkpath(parts.mid(0, i + 1)), versionPart,
versionPart, mkpath(parts.mid(i + 1))))
mkpath(parts.mid(i + 1)))); .cleanPath();
if (QDir(candidate).exists()) if (candidate.exists())
result << candidate; result << candidate;
} }
} }
} }
// Version is empty // Version is empty
for (const QString &path: importPaths) { for (const Utils::FilePath &path : importPaths) {
candidate = QDir::cleanPath(QString::fromLatin1("%1/%2").arg(path, mkpath(parts))); candidate = path.pathAppended(mkpath(parts)).cleanPath();
if (QDir(candidate).exists()) if (candidate.exists())
result << candidate; result << candidate;
} }

View File

@@ -25,11 +25,12 @@
#pragma once #pragma once
#include "parser/qmljsastfwd_p.h"
#include "parser/qmljsdiagnosticmessage_p.h"
#include "parser/qmljsengine_p.h"
#include "qmljs_global.h" #include "qmljs_global.h"
#include "qmljsconstants.h" #include "qmljsconstants.h"
#include "parser/qmljsastfwd_p.h" #include <utils/filepath.h>
#include "parser/qmljsengine_p.h"
#include "parser/qmljsdiagnosticmessage_p.h"
QT_FORWARD_DECLARE_CLASS(QColor) QT_FORWARD_DECLARE_CLASS(QColor)
@@ -58,8 +59,9 @@ QMLJS_EXPORT DiagnosticMessage errorMessage(const SourceLocation &loc,
QMLJS_EXPORT bool maybeModuleVersion(const QString &version); QMLJS_EXPORT bool maybeModuleVersion(const QString &version);
QMLJS_EXPORT const QStringList splitVersion(const QString &version); QMLJS_EXPORT const QStringList splitVersion(const QString &version);
QMLJS_EXPORT QStringList modulePaths(const QString &moduleImportName, const QString &version, QMLJS_EXPORT QList<Utils::FilePath> modulePaths(const QString &moduleImportName,
const QStringList &importPaths); const QString &version,
const QList<Utils::FilePath> &importPaths);
template <class T> template <class T>
SourceLocation locationFromRange(const T *node) SourceLocation locationFromRange(const T *node)

View File

@@ -43,8 +43,8 @@ struct QMLJS_EXPORT ViewerContext
}; };
QStringList selectors; QStringList selectors;
QStringList paths; QList<Utils::FilePath> paths;
QStringList applicationDirectories; QList<Utils::FilePath> applicationDirectories;
Dialect language = Dialect::Qml; Dialect language = Dialect::Qml;
Flags flags = AddAllPaths; Flags flags = AddAllPaths;
}; };

View File

@@ -27,6 +27,8 @@
#include "qtcassert.h" #include "qtcassert.h"
#include <utils/filepath.h>
#include <QCoreApplication> #include <QCoreApplication>
#include <QDir> #include <QDir>
#include <QDomDocument> #include <QDomDocument>

View File

@@ -172,37 +172,45 @@ QString QuickTestParser::quickTestName(const CPlusPlus::Document::Ptr &doc) cons
return {}; return {};
} }
QList<Document::Ptr> QuickTestParser::scanDirectoryForQuickTestQmlFiles(const QString &srcDir) QList<Document::Ptr> QuickTestParser::scanDirectoryForQuickTestQmlFiles(const Utils::FilePath &srcDir)
{ {
QStringList dirs(srcDir); Utils::FilePaths dirs({srcDir});
QStringList dirsStr({srcDir.toString()});
ModelManagerInterface *qmlJsMM = QmlJSTools::Internal::ModelManager::instance(); ModelManagerInterface *qmlJsMM = QmlJSTools::Internal::ModelManager::instance();
// make sure even files not listed in pro file are available inside the snapshot // make sure even files not listed in pro file are available inside the snapshot
QFutureInterface<void> future; QFutureInterface<void> future;
PathsAndLanguages paths; PathsAndLanguages paths;
paths.maybeInsert(Utils::FilePath::fromString(srcDir), Dialect::Qml); paths.maybeInsert(srcDir, Dialect::Qml);
ModelManagerInterface::importScan(future, ModelManagerInterface::workingCopy(), paths, qmlJsMM, ModelManagerInterface::importScan(future, ModelManagerInterface::workingCopy(), paths, qmlJsMM,
false /*emitDocumentChanges*/, false /*onlyTheLib*/, true /*forceRescan*/ ); false /*emitDocumentChanges*/, false /*onlyTheLib*/, true /*forceRescan*/ );
const Snapshot snapshot = QmlJSTools::Internal::ModelManager::instance()->snapshot(); const Snapshot snapshot = QmlJSTools::Internal::ModelManager::instance()->snapshot();
QDirIterator it(srcDir, QDir::Dirs | QDir::NoDotAndDotDot, QDirIterator::Subdirectories);
QDirIterator it(srcDir.toString(),
QDir::Dirs | QDir::NoDotAndDotDot,
QDirIterator::Subdirectories);
while (it.hasNext()) { while (it.hasNext()) {
it.next(); it.next();
QFileInfo fi(it.fileInfo().canonicalFilePath()); auto subDir = Utils::FilePath::fromFileInfo(it.fileInfo()).canonicalPath();
dirs.append(fi.filePath()); dirs.append(subDir);
dirsStr.append(subDir.toString());
} }
QMetaObject::invokeMethod(this, [this, dirs] { QuickTestParser::doUpdateWatchPaths(dirs); }, QMetaObject::invokeMethod(
Qt::QueuedConnection); this,
[this, dirsStr] { QuickTestParser::doUpdateWatchPaths(dirsStr); },
Qt::QueuedConnection);
QList<Document::Ptr> foundDocs; QList<Document::Ptr> foundDocs;
for (const QString &path : qAsConst(dirs)) { for (const Utils::FilePath &path : qAsConst(dirs)) {
const QList<Document::Ptr> docs = snapshot.documentsInDirectory(path); const QList<Document::Ptr> docs = snapshot.documentsInDirectory(path);
for (const Document::Ptr &doc : docs) { for (const Document::Ptr &doc : docs) {
const QFileInfo fi(doc->fileName()); Utils::FilePath fi = doc->fileName();
//const QFileInfo fi(doc->fileName());
// using working copy above might provide no more existing files // using working copy above might provide no more existing files
if (!fi.exists()) if (!fi.exists())
continue; continue;
const QString fileName(fi.fileName()); const QString fileName = fi.fileName();
if (fileName.startsWith("tst_") && fileName.endsWith(".qml")) if (fileName.startsWith("tst_") && fileName.endsWith(".qml"))
foundDocs << doc; foundDocs << doc;
} }
@@ -273,7 +281,8 @@ bool QuickTestParser::handleQtQuickTest(QFutureInterface<TestParseResultPtr> &fu
const Utils::FilePath cppFileName = Utils::FilePath::fromString(document->fileName()); const Utils::FilePath cppFileName = Utils::FilePath::fromString(document->fileName());
const Utils::FilePath proFile = Utils::FilePath::fromString(ppList.at(0)->projectFile); const Utils::FilePath proFile = Utils::FilePath::fromString(ppList.at(0)->projectFile);
m_mainCppFiles.insert(cppFileName, proFile); m_mainCppFiles.insert(cppFileName, proFile);
const QString srcDir = quickTestSrcDir(modelManager, cppFileName); const Utils::FilePath srcDir = Utils::FilePath::fromString(
quickTestSrcDir(modelManager, cppFileName));
if (srcDir.isEmpty()) if (srcDir.isEmpty())
return false; return false;
@@ -383,7 +392,7 @@ bool QuickTestParser::processDocument(QFutureInterface<TestParseResultPtr> &futu
const Utils::FilePath &proFile = m_proFilesForQmlFiles.value(fileName); const Utils::FilePath &proFile = m_proFilesForQmlFiles.value(fileName);
if (proFile.isEmpty()) if (proFile.isEmpty())
return false; return false;
Document::Ptr qmlJSDoc = m_qmlSnapshot.document(fileName.toString()); Document::Ptr qmlJSDoc = m_qmlSnapshot.document(fileName);
return checkQmlDocumentForQuickTestCode(futureInterface, qmlJSDoc, framework(), proFile); return checkQmlDocumentForQuickTestCode(futureInterface, qmlJSDoc, framework(), proFile);
} }
if (!m_cppSnapshot.contains(fileName) || !selectedForBuilding(fileName)) if (!m_cppSnapshot.contains(fileName) || !selectedForBuilding(fileName))

View File

@@ -57,7 +57,7 @@ private:
void handleDirectoryChanged(const QString &directory); void handleDirectoryChanged(const QString &directory);
void doUpdateWatchPaths(const QStringList &directories); void doUpdateWatchPaths(const QStringList &directories);
QString quickTestName(const CPlusPlus::Document::Ptr &doc) const; QString quickTestName(const CPlusPlus::Document::Ptr &doc) const;
QList<QmlJS::Document::Ptr> scanDirectoryForQuickTestQmlFiles(const QString &srcDir); QList<QmlJS::Document::Ptr> scanDirectoryForQuickTestQmlFiles(const Utils::FilePath &srcDir);
QmlJS::Snapshot m_qmlSnapshot; QmlJS::Snapshot m_qmlSnapshot;
QHash<Utils::FilePath, Utils::FilePath> m_proFilesForQmlFiles; QHash<Utils::FilePath, Utils::FilePath> m_proFilesForQmlFiles;
QFileSystemWatcher m_directoryWatcher; QFileSystemWatcher m_directoryWatcher;

View File

@@ -99,7 +99,7 @@ bool TestQmlVisitor::visit(QmlJS::AST::UiObjectDefinition *ast)
m_objectIsTestStack.top() = true; m_objectIsTestStack.top() = true;
const auto sourceLocation = ast->firstSourceLocation(); const auto sourceLocation = ast->firstSourceLocation();
QuickTestCaseSpec currentSpec; QuickTestCaseSpec currentSpec;
currentSpec.m_locationAndType.m_filePath = Utils::FilePath::fromString(m_currentDoc->fileName()); currentSpec.m_locationAndType.m_filePath = m_currentDoc->fileName();
currentSpec.m_locationAndType.m_line = sourceLocation.startLine; currentSpec.m_locationAndType.m_line = sourceLocation.startLine;
currentSpec.m_locationAndType.m_column = sourceLocation.startColumn - 1; currentSpec.m_locationAndType.m_column = sourceLocation.startColumn - 1;
currentSpec.m_locationAndType.m_type = TestTreeItem::TestCase; currentSpec.m_locationAndType.m_type = TestTreeItem::TestCase;
@@ -143,7 +143,7 @@ bool TestQmlVisitor::visit(QmlJS::AST::FunctionDeclaration *ast)
const auto sourceLocation = ast->firstSourceLocation(); const auto sourceLocation = ast->firstSourceLocation();
TestCodeLocationAndType locationAndType; TestCodeLocationAndType locationAndType;
locationAndType.m_name = name; locationAndType.m_name = name;
locationAndType.m_filePath = Utils::FilePath::fromString(m_currentDoc->fileName()); locationAndType.m_filePath = m_currentDoc->fileName();
locationAndType.m_line = sourceLocation.startLine; locationAndType.m_line = sourceLocation.startLine;
locationAndType.m_column = sourceLocation.startColumn - 1; locationAndType.m_column = sourceLocation.startColumn - 1;
if (specialFunctions.contains(name)) if (specialFunctions.contains(name))

View File

@@ -189,9 +189,9 @@ void TestCodeParser::onCppDocumentUpdated(const CPlusPlus::Document::Ptr &docume
void TestCodeParser::onQmlDocumentUpdated(const QmlJS::Document::Ptr &document) void TestCodeParser::onQmlDocumentUpdated(const QmlJS::Document::Ptr &document)
{ {
const QString fileName = document->fileName(); const Utils::FilePath fileName = document->fileName();
if (!fileName.endsWith(".qbs")) if (!fileName.endsWith(".qbs"))
onDocumentUpdated(Utils::FilePath::fromString(fileName), true); onDocumentUpdated(fileName, true);
} }
void TestCodeParser::onStartupProjectChanged(Project *project) void TestCodeParser::onStartupProjectChanged(Project *project)

View File

@@ -127,12 +127,11 @@ void TestTreeModel::setupParsingConnections()
QmlJS::ModelManagerInterface *qmlJsMM = QmlJS::ModelManagerInterface::instance(); QmlJS::ModelManagerInterface *qmlJsMM = QmlJS::ModelManagerInterface::instance();
connect(qmlJsMM, &QmlJS::ModelManagerInterface::documentUpdated, connect(qmlJsMM, &QmlJS::ModelManagerInterface::documentUpdated,
m_parser, &TestCodeParser::onQmlDocumentUpdated, Qt::QueuedConnection); m_parser, &TestCodeParser::onQmlDocumentUpdated, Qt::QueuedConnection);
connect(qmlJsMM, &QmlJS::ModelManagerInterface::aboutToRemoveFiles, connect(qmlJsMM,
this, [this](const QStringList files) { &QmlJS::ModelManagerInterface::aboutToRemoveFiles,
const Utils::FilePaths filesToRemove this,
= Utils::transform(files, &Utils::FilePath::fromString); &TestTreeModel::removeFiles,
removeFiles(filesToRemove); Qt::QueuedConnection);
}, Qt::QueuedConnection);
connectionsInitialized = true; connectionsInitialized = true;
} }

View File

@@ -425,21 +425,23 @@ void QmakeBuildSystem::updateQmlJSCodeModel()
} }
const QStringList &exactResources = file->variableValue(Variable::ExactResource); const QStringList &exactResources = file->variableValue(Variable::ExactResource);
const QStringList &cumulativeResources = file->variableValue(Variable::CumulativeResource); const QStringList &cumulativeResources = file->variableValue(Variable::CumulativeResource);
projectInfo.activeResourceFiles.append(exactResources);
projectInfo.allResourceFiles.append(exactResources);
projectInfo.allResourceFiles.append(cumulativeResources);
QString errorMessage; QString errorMessage;
foreach (const QString &rc, exactResources) { for (const QString &rc : exactResources) {
Utils::FilePath rcPath = Utils::FilePath::fromString(rc);
projectInfo.activeResourceFiles.append(rcPath);
projectInfo.allResourceFiles.append(rcPath);
QString contents; QString contents;
int id = m_qmakeVfs->idForFileName(rc, QMakeVfs::VfsExact); int id = m_qmakeVfs->idForFileName(rc, QMakeVfs::VfsExact);
if (m_qmakeVfs->readFile(id, &contents, &errorMessage) == QMakeVfs::ReadOk) if (m_qmakeVfs->readFile(id, &contents, &errorMessage) == QMakeVfs::ReadOk)
projectInfo.resourceFileContents[rc] = contents; projectInfo.resourceFileContents[rcPath] = contents;
} }
foreach (const QString &rc, cumulativeResources) { for (const QString &rc : cumulativeResources) {
Utils::FilePath rcPath = Utils::FilePath::fromString(rc);
projectInfo.allResourceFiles.append(rcPath);
QString contents; QString contents;
int id = m_qmakeVfs->idForFileName(rc, QMakeVfs::VfsCumulative); int id = m_qmakeVfs->idForFileName(rc, QMakeVfs::VfsCumulative);
if (m_qmakeVfs->readFile(id, &contents, &errorMessage) == QMakeVfs::ReadOk) if (m_qmakeVfs->readFile(id, &contents, &errorMessage) == QMakeVfs::ReadOk)
projectInfo.resourceFileContents[rc] = contents; projectInfo.resourceFileContents[rcPath] = contents;
} }
if (!hasQmlLib) { if (!hasQmlLib) {
QStringList qtLibs = file->variableValue(Variable::Qt); QStringList qtLibs = file->variableValue(Variable::Qt);
@@ -455,8 +457,8 @@ void QmakeBuildSystem::updateQmlJSCodeModel()
// or QQmlEngine/QQuickView (QtQuick 2) instances. // or QQmlEngine/QQuickView (QtQuick 2) instances.
project()->setProjectLanguage(ProjectExplorer::Constants::QMLJS_LANGUAGE_ID, hasQmlLib); project()->setProjectLanguage(ProjectExplorer::Constants::QMLJS_LANGUAGE_ID, hasQmlLib);
projectInfo.activeResourceFiles.removeDuplicates(); projectInfo.activeResourceFiles = Utils::filteredUnique(projectInfo.activeResourceFiles);
projectInfo.allResourceFiles.removeDuplicates(); projectInfo.allResourceFiles = Utils::filteredUnique(projectInfo.allResourceFiles);
modelManager->updateProjectInfo(projectInfo, project()); modelManager->updateProjectInfo(projectInfo, project());
} }

View File

@@ -238,8 +238,9 @@ void ActionEditor::prepareConnections()
if (slotName.startsWith("q_") || slotName.startsWith("_q_")) if (slotName.startsWith("q_") || slotName.startsWith("_q_"))
continue; continue;
QmlJS::Document::MutablePtr newDoc = QmlJS::Document::create( QmlJS::Document::MutablePtr newDoc
QLatin1String("<expression>"), QmlJS::Dialect::JavaScript); = QmlJS::Document::create(Utils::FilePath::fromString("<expression>"),
QmlJS::Dialect::JavaScript);
newDoc->setSource(modelNode.id() + "." + QLatin1String(slotName)); newDoc->setSource(modelNode.id() + "." + QLatin1String(slotName));
newDoc->parseExpression(); newDoc->parseExpression();

View File

@@ -77,7 +77,8 @@ void ActionEditorDialog::adjustProperties()
{ {
// Analyze the current connection editor statement/expression // Analyze the current connection editor statement/expression
const auto qmlJSDocument = bindingEditorWidget()->qmlJsEditorDocument(); const auto qmlJSDocument = bindingEditorWidget()->qmlJsEditorDocument();
auto doc = QmlJS::Document::create(QLatin1String("<expression>"), QmlJS::Dialect::JavaScript); auto doc = QmlJS::Document::create(Utils::FilePath::fromString("<expression>"),
QmlJS::Dialect::JavaScript);
doc->setSource(qmlJSDocument->plainText()); doc->setSource(qmlJSDocument->plainText());
bool parseResult = doc->parseExpression(); bool parseResult = doc->parseExpression();

View File

@@ -261,13 +261,14 @@ QString matchingLine(unsigned position, const QString &source)
FindImplementation::FindImplementation() = default; FindImplementation::FindImplementation() = default;
QList<QmlJSEditor::FindReferences::Usage> FindImplementation::run(const QString &fileName, QList<QmlJSEditor::FindReferences::Usage> FindImplementation::run(const QString &fileNameStr,
const QString &typeName, const QString &typeName,
const QString &itemName) const QString &itemName)
{ {
QList<QmlJSEditor::FindReferences::Usage> usages; QList<QmlJSEditor::FindReferences::Usage> usages;
QmlJS::ModelManagerInterface *modelManager = ModelManagerInterface::instance(); QmlJS::ModelManagerInterface *modelManager = ModelManagerInterface::instance();
Utils::FilePath fileName = Utils::FilePath::fromString(fileNameStr);
//Parse always the latest version of document //Parse always the latest version of document
QmlJS::Dialect dialect = QmlJS::ModelManagerInterface::guessLanguageOfFile(fileName); QmlJS::Dialect dialect = QmlJS::ModelManagerInterface::guessLanguageOfFile(fileName);

View File

@@ -682,7 +682,8 @@ void addSignalHandlerOrGotoImplementation(const SelectionContext &selectionState
QStringList signalNames = cleanSignalNames(getSortedSignalNameList(selectionState.selectedModelNodes().constFirst())); QStringList signalNames = cleanSignalNames(getSortedSignalNameList(selectionState.selectedModelNodes().constFirst()));
QList<QmlJSEditor::FindReferences::Usage> usages = QmlJSEditor::FindReferences::findUsageOfType(fileName, typeName); QList<QmlJSEditor::FindReferences::Usage> usages
= QmlJSEditor::FindReferences::findUsageOfType(currentDesignDocument, typeName);
if (usages.isEmpty()) { if (usages.isEmpty()) {
QString title = QCoreApplication::translate("ModelNodeOperations", "Go to Implementation"); QString title = QCoreApplication::translate("ModelNodeOperations", "Go to Implementation");
@@ -691,14 +692,13 @@ void addSignalHandlerOrGotoImplementation(const SelectionContext &selectionState
return; return;
} }
usages = FindImplementation::run(usages.constFirst().path, typeName, itemId); usages = FindImplementation::run(usages.constFirst().path.toString(), typeName, itemId);
Core::ModeManager::activateMode(Core::Constants::MODE_EDIT); Core::ModeManager::activateMode(Core::Constants::MODE_EDIT);
if (!usages.isEmpty() && (addAlwaysNewSlot || usages.count() < 2) && (!isModelNodeRoot || addAlwaysNewSlot)) { if (!usages.isEmpty() && (addAlwaysNewSlot || usages.count() < 2) && (!isModelNodeRoot || addAlwaysNewSlot)) {
Core::EditorManager::openEditorAt({Utils::FilePath::fromString(usages.constFirst().path), Core::EditorManager::openEditorAt(
usages.constFirst().line, {usages.constFirst().path, usages.constFirst().line, usages.constFirst().col});
usages.constFirst().col});
if (!signalNames.isEmpty()) { if (!signalNames.isEmpty()) {
auto dialog = new AddSignalHandlerDialog(Core::ICore::dialogParent()); auto dialog = new AddSignalHandlerDialog(Core::ICore::dialogParent());
@@ -730,9 +730,8 @@ void addSignalHandlerOrGotoImplementation(const SelectionContext &selectionState
return; return;
} }
Core::EditorManager::openEditorAt({Utils::FilePath::fromString(usages.constFirst().path), Core::EditorManager::openEditorAt(
usages.constFirst().line, {usages.constFirst().path, usages.constFirst().line, usages.constFirst().col + 1});
usages.constFirst().col + 1});
} }
void removeLayout(const SelectionContext &selectionContext) void removeLayout(const SelectionContext &selectionContext)

View File

@@ -372,7 +372,7 @@ void DesignDocument::updateQrcFiles()
const auto srcFiles = currentProject->files(ProjectExplorer::Project::SourceFiles); const auto srcFiles = currentProject->files(ProjectExplorer::Project::SourceFiles);
for (const Utils::FilePath &fileName : srcFiles) { for (const Utils::FilePath &fileName : srcFiles) {
if (fileName.endsWith(".qrc")) if (fileName.endsWith(".qrc"))
QmlJS::ModelManagerInterface::instance()->updateQrcFile(fileName.toString()); QmlJS::ModelManagerInterface::instance()->updateQrcFile(fileName);
} }
} }
} }

View File

@@ -274,7 +274,7 @@ void TextEditorView::reformatFile()
if (document->isSemanticInfoOutdated()) { if (document->isSemanticInfoOutdated()) {
QmlJS::Document::MutablePtr latestDocument; QmlJS::Document::MutablePtr latestDocument;
const QString fileName = document->filePath().toString(); const Utils::FilePath fileName = document->filePath();
latestDocument = snapshot.documentFromSource(QString::fromUtf8(document->contents()), latestDocument = snapshot.documentFromSource(QString::fromUtf8(document->contents()),
fileName, fileName,
QmlJS::ModelManagerInterface::guessLanguageOfFile(fileName)); QmlJS::ModelManagerInterface::guessLanguageOfFile(fileName));

View File

@@ -31,8 +31,9 @@
using namespace QmlDesigner; using namespace QmlDesigner;
ASTObjectTextExtractor::ASTObjectTextExtractor(const QString &text): ASTObjectTextExtractor::ASTObjectTextExtractor(const QString &text)
m_document(QmlJS::Document::create(QLatin1String("<ASTObjectTextExtractor>"), QmlJS::Dialect::Qml)) : m_document(QmlJS::Document::create(Utils::FilePath::fromString("<ASTObjectTextExtractor>"),
QmlJS::Dialect::Qml))
{ {
m_document->setSource(text); m_document->setSource(text);
m_document->parseQml(); m_document->parseQml();

View File

@@ -32,8 +32,8 @@
using namespace QmlDesigner; using namespace QmlDesigner;
FirstDefinitionFinder::FirstDefinitionFinder(const QString &text): FirstDefinitionFinder::FirstDefinitionFinder(const QString &text)
m_doc(QmlJS::Document::create(QLatin1String("<internal>"), QmlJS::Dialect::Qml)) : m_doc(QmlJS::Document::create(Utils::FilePath::fromString("<internal>"), QmlJS::Dialect::Qml))
{ {
m_doc->setSource(text); m_doc->setSource(text);
bool ok = m_doc->parseQml(); bool ok = m_doc->parseQml();

View File

@@ -29,8 +29,8 @@
using namespace QmlDesigner; using namespace QmlDesigner;
ObjectLengthCalculator::ObjectLengthCalculator(): ObjectLengthCalculator::ObjectLengthCalculator()
m_doc(QmlJS::Document::create(QLatin1String("<internal>"), QmlJS::Dialect::Qml)) : m_doc(QmlJS::Document::create(Utils::FilePath::fromString("<internal>"), QmlJS::Dialect::Qml))
{ {
} }

View File

@@ -182,11 +182,10 @@ static QString qualifiedTypeNameForContext(const ObjectValue *objectValue,
// remove the search path prefix. // remove the search path prefix.
// this means that the same relative path wrt. different import paths will clash // this means that the same relative path wrt. different import paths will clash
QString filePath = e.exportName.path(); QString filePath = e.exportName.path();
for (const QString &path : qAsConst(vContext.paths)) { for (const Utils::FilePath &path : qAsConst(vContext.paths)) {
if (filePath.startsWith(path) && filePath.size() > path.size() if (filePath.startsWith(path.path()) && filePath.size() > path.path().size()
&& filePath.at(path.size()) == QLatin1Char('/')) && filePath.at(path.path().size()) == QLatin1Char('/')) {
{ filePath = filePath.mid(path.path().size() + 1);
filePath = filePath.mid(path.size() + 1);
break; break;
} }
} }
@@ -1157,11 +1156,11 @@ QString NodeMetaInfoPrivate::componentFileName() const
if (isFileComponent()) { if (isFileComponent()) {
const ASTObjectValue * astObjectValue = value_cast<ASTObjectValue>(getObjectValue()); const ASTObjectValue * astObjectValue = value_cast<ASTObjectValue>(getObjectValue());
if (astObjectValue) { if (astObjectValue) {
QString fileName; Utils::FilePath fileName;
int line; int line;
int column; int column;
if (astObjectValue->getSourceLocation(&fileName, &line, &column)) if (astObjectValue->getSourceLocation(&fileName, &line, &column))
return fileName; return fileName.toString();
} }
} }
return QString(); return QString();

View File

@@ -231,7 +231,8 @@ void ModelToTextMerger::applyChanges()
m_rewriterView->emitCustomNotification(StartRewriterApply); m_rewriterView->emitCustomNotification(StartRewriterApply);
Document::MutablePtr tmpDocument(Document::create(QStringLiteral("<ModelToTextMerger>"), Dialect::Qml)); Document::MutablePtr tmpDocument(
Document::create(Utils::FilePath::fromString("<ModelToTextMerger>"), Dialect::Qml));
tmpDocument->setSource(m_rewriterView->textModifier()->text()); tmpDocument->setSource(m_rewriterView->textModifier()->text());
if (!tmpDocument->parseQml()) { if (!tmpDocument->parseQml()) {
qDebug() << "*** Possible problem: QML file wasn't parsed correctly."; qDebug() << "*** Possible problem: QML file wasn't parsed correctly.";

View File

@@ -1024,7 +1024,8 @@ QString RewriterView::pathForImport(const Import &import)
QStringList RewriterView::importDirectories() const QStringList RewriterView::importDirectories() const
{ {
return m_textToModelMerger->vContext().paths; return Utils::transform(m_textToModelMerger->vContext().paths,
[](const Utils::FilePath &p) { return p.toString(); });
} }
QSet<QPair<QString, QString> > RewriterView::qrcMapping() const QSet<QPair<QString, QString> > RewriterView::qrcMapping() const

View File

@@ -493,7 +493,7 @@ public:
typeName.prepend(name + QLatin1Char('.')); typeName.prepend(name + QLatin1Char('.'));
} else if (importInfo.isValid() && importInfo.type() == ImportType::Directory) { } else if (importInfo.isValid() && importInfo.type() == ImportType::Directory) {
QString path = importInfo.path(); QString path = importInfo.path();
QDir dir(m_doc->path()); QDir dir = m_doc->path().toDir();
// should probably try to make it relatve to some import path, not to the document path // should probably try to make it relatve to some import path, not to the document path
QString relativeDir = dir.relativeFilePath(path); QString relativeDir = dir.relativeFilePath(path);
QString name = relativeDir.replace(QLatin1Char('/'), QLatin1Char('.')); QString name = relativeDir.replace(QLatin1Char('/'), QLatin1Char('.'));
@@ -997,7 +997,8 @@ void TextToModelMerger::setupPossibleImports(const QmlJS::Snapshot &snapshot, co
QList<QmlDesigner::Import> possibleImports = generatePossibleLibraryImports(filteredPossibleImportKeys); QList<QmlDesigner::Import> possibleImports = generatePossibleLibraryImports(filteredPossibleImportKeys);
if (document()->fileName() != "<internal>") if (document()->fileName() != "<internal>")
possibleImports.append(generatePossibleFileImports(document()->path(), imports->all())); possibleImports.append(
generatePossibleFileImports(document()->path().toString(), imports->all()));
if (m_rewriterView->isAttached()) if (m_rewriterView->isAttached())
m_rewriterView->model()->setPossibleImports(possibleImports); m_rewriterView->model()->setPossibleImports(possibleImports);
@@ -1052,14 +1053,17 @@ Document::MutablePtr TextToModelMerger::createParsedDocument(const QUrl &url, co
return {}; return {};
} }
const QString fileName = url.toLocalFile(); Utils::FilePath fileName = Utils::FilePath::fromString(url.toLocalFile());
Dialect dialect = ModelManagerInterface::guessLanguageOfFile(fileName); Dialect dialect = ModelManagerInterface::guessLanguageOfFile(fileName);
if (dialect == Dialect::AnyLanguage if (dialect == Dialect::AnyLanguage
|| dialect == Dialect::NoLanguage) || dialect == Dialect::NoLanguage)
dialect = Dialect::Qml; dialect = Dialect::Qml;
Document::MutablePtr doc = Document::create(fileName.isEmpty() ? QStringLiteral("<internal>") : fileName, dialect); Document::MutablePtr doc = Document::create(fileName.isEmpty()
? Utils::FilePath::fromString("<internal>")
: fileName,
dialect);
doc->setSource(data); doc->setSource(data);
doc->parseQml(); doc->parseQml();
@@ -1067,7 +1071,7 @@ Document::MutablePtr TextToModelMerger::createParsedDocument(const QUrl &url, co
if (errors) { if (errors) {
const QList<QmlJS::DiagnosticMessage> messages = doc->diagnosticMessages(); const QList<QmlJS::DiagnosticMessage> messages = doc->diagnosticMessages();
for (const QmlJS::DiagnosticMessage &message : messages) for (const QmlJS::DiagnosticMessage &message : messages)
errors->append(DocumentMessage(message, QUrl::fromLocalFile(doc->fileName()))); errors->append(DocumentMessage(message, doc->fileName().toUrl()));
} }
return Document::MutablePtr(); return Document::MutablePtr();
} }
@@ -2134,7 +2138,8 @@ void TextToModelMerger::collectLinkErrors(QList<DocumentMessage> *errors, const
if (diagnosticMessage.kind == QmlJS::Severity::ReadingTypeInfoWarning) if (diagnosticMessage.kind == QmlJS::Severity::ReadingTypeInfoWarning)
m_rewriterView->setIncompleteTypeInformation(true); m_rewriterView->setIncompleteTypeInformation(true);
errors->append(DocumentMessage(diagnosticMessage, QUrl::fromLocalFile(m_document->fileName()))); errors->append(
DocumentMessage(diagnosticMessage, QUrl::fromLocalFile(m_document->fileName().path())));
} }
} }
@@ -2142,7 +2147,8 @@ void TextToModelMerger::collectImportErrors(QList<DocumentMessage> *errors)
{ {
if (m_rewriterView->model()->imports().isEmpty()) { if (m_rewriterView->model()->imports().isEmpty()) {
const QmlJS::DiagnosticMessage diagnosticMessage(QmlJS::Severity::Error, SourceLocation(0, 0, 0, 0), QCoreApplication::translate("QmlDesigner::TextToModelMerger", "No import statements found.")); const QmlJS::DiagnosticMessage diagnosticMessage(QmlJS::Severity::Error, SourceLocation(0, 0, 0, 0), QCoreApplication::translate("QmlDesigner::TextToModelMerger", "No import statements found."));
errors->append(DocumentMessage(diagnosticMessage, QUrl::fromLocalFile(m_document->fileName()))); errors->append(
DocumentMessage(diagnosticMessage, QUrl::fromLocalFile(m_document->fileName().path())));
} }
bool hasQtQuick = false; bool hasQtQuick = false;
@@ -2168,9 +2174,9 @@ void TextToModelMerger::collectImportErrors(QList<DocumentMessage> *errors)
QCoreApplication::translate( QCoreApplication::translate(
"QmlDesigner::TextToModelMerger", "QmlDesigner::TextToModelMerger",
"Qt Quick 6 is not supported with a Qt 5 kit.")); "Qt Quick 6 is not supported with a Qt 5 kit."));
errors->prepend( errors->prepend(DocumentMessage(diagnosticMessage,
DocumentMessage(diagnosticMessage, QUrl::fromLocalFile(
QUrl::fromLocalFile(m_document->fileName()))); m_document->fileName().path())));
} }
} else { } else {
const QmlJS::DiagnosticMessage const QmlJS::DiagnosticMessage
@@ -2181,7 +2187,7 @@ void TextToModelMerger::collectImportErrors(QList<DocumentMessage> *errors)
"The Design Mode requires a valid Qt kit.")); "The Design Mode requires a valid Qt kit."));
errors->prepend( errors->prepend(
DocumentMessage(diagnosticMessage, DocumentMessage(diagnosticMessage,
QUrl::fromLocalFile(m_document->fileName()))); QUrl::fromLocalFile(m_document->fileName().path())));
} }
} }
#endif #endif
@@ -2193,7 +2199,7 @@ void TextToModelMerger::collectImportErrors(QList<DocumentMessage> *errors)
QCoreApplication::translate("QmlDesigner::TextToModelMerger", QCoreApplication::translate("QmlDesigner::TextToModelMerger",
"Unsupported Qt Quick version.")); "Unsupported Qt Quick version."));
errors->append(DocumentMessage(diagnosticMessage, errors->append(DocumentMessage(diagnosticMessage,
QUrl::fromLocalFile(m_document->fileName()))); QUrl::fromLocalFile(m_document->fileName().path())));
} }
} }
} }
@@ -2220,7 +2226,7 @@ void TextToModelMerger::collectSemanticErrorsAndWarnings(QList<DocumentMessage>
check.enableQmlDesignerChecks(); check.enableQmlDesignerChecks();
QUrl fileNameUrl = QUrl::fromLocalFile(m_document->fileName()); QUrl fileNameUrl = QUrl::fromLocalFile(m_document->fileName().toString());
const QList<StaticAnalysis::Message> messages = check(); const QList<StaticAnalysis::Message> messages = check();
for (const StaticAnalysis::Message &message : messages) { for (const StaticAnalysis::Message &message : messages) {
if (message.severity == Severity::Error) { if (message.severity == Severity::Error) {

View File

@@ -158,7 +158,8 @@ static bool checkIfEditorIsQtQuick(Core::IEditor *editor)
&& (editor->document()->id() == QmlJSEditor::Constants::C_QMLJSEDITOR_ID && (editor->document()->id() == QmlJSEditor::Constants::C_QMLJSEDITOR_ID
|| editor->document()->id() == QmlJSEditor::Constants::C_QTQUICKDESIGNEREDITOR_ID)) { || editor->document()->id() == QmlJSEditor::Constants::C_QTQUICKDESIGNEREDITOR_ID)) {
QmlJS::ModelManagerInterface *modelManager = QmlJS::ModelManagerInterface::instance(); QmlJS::ModelManagerInterface *modelManager = QmlJS::ModelManagerInterface::instance();
QmlJS::Document::Ptr document = modelManager->ensuredGetDocumentForPath(editor->document()->filePath().toString()); QmlJS::Document::Ptr document = modelManager->ensuredGetDocumentForPath(
editor->document()->filePath());
if (!document.isNull()) if (!document.isNull())
return document->language() == QmlJS::Dialect::QmlQtQuick2 return document->language() == QmlJS::Dialect::QmlQtQuick2
|| document->language() == QmlJS::Dialect::QmlQtQuick2Ui || document->language() == QmlJS::Dialect::QmlQtQuick2Ui

View File

@@ -126,8 +126,8 @@ ExpressionNode *QmlExpressionUnderCursor::operator()(const QTextCursor &cursor)
ExpressionUnderCursor expressionUnderCursor; ExpressionUnderCursor expressionUnderCursor;
_text = expressionUnderCursor(cursor); _text = expressionUnderCursor(cursor);
Document::MutablePtr newDoc = Document::create( Document::MutablePtr newDoc = Document::create(Utils::FilePath::fromString("<expression>"),
QLatin1String("<expression>"), Dialect::JavaScript); Dialect::JavaScript);
newDoc->setSource(_text); newDoc->setSource(_text);
newDoc->parseExpression(); newDoc->parseExpression();
exprDoc = newDoc; exprDoc = newDoc;

View File

@@ -648,7 +648,7 @@ IAssistProposal *QmlJSCompletionAssistProcessor::perform(const AssistInterface *
if (contextFinder.isInImport()) { if (contextFinder.isInImport()) {
QStringList patterns; QStringList patterns;
patterns << QLatin1String("*.qml") << QLatin1String("*.js"); patterns << QLatin1String("*.qml") << QLatin1String("*.js");
if (completeFileName(document->path(), literalText, patterns)) if (completeFileName(document->path().toString(), literalText, patterns))
return createContentProposal(); return createContentProposal();
return nullptr; return nullptr;
} }
@@ -658,7 +658,7 @@ IAssistProposal *QmlJSCompletionAssistProcessor::perform(const AssistInterface *
if (!value) { if (!value) {
// do nothing // do nothing
} else if (value->asUrlValue()) { } else if (value->asUrlValue()) {
if (completeUrl(document->path(), literalText)) if (completeUrl(document->path().toString(), literalText))
return createContentProposal(); return createContentProposal();
} }

View File

@@ -107,8 +107,9 @@ public:
{ {
QString componentName = m_componentName; QString componentName = m_componentName;
const QString currentFileName = currentFile->qmljsDocument()->fileName(); const Utils::FilePath currentFileName = currentFile->qmljsDocument()->fileName();
QString path = QFileInfo(currentFileName).path(); Utils::FilePath path = currentFileName.parentDir();
QString pathStr = path.toUserOutput();
QmlJS::PropertyReader propertyReader(currentFile->qmljsDocument(), m_initializer); QmlJS::PropertyReader propertyReader(currentFile->qmljsDocument(), m_initializer);
QStringList result; QStringList result;
@@ -133,20 +134,23 @@ public:
for (const QString &property : qAsConst(sortedPropertiesWithoutId)) for (const QString &property : qAsConst(sortedPropertiesWithoutId))
sourcePreview.append(QLatin1String(" ") + property + QLatin1String(": ") + propertyReader.readAstValue(property)); sourcePreview.append(QLatin1String(" ") + property + QLatin1String(": ") + propertyReader.readAstValue(property));
const bool confirm = ComponentNameDialog::go(&componentName, &path, &suffix, const bool confirm = ComponentNameDialog::go(&componentName,
sortedPropertiesWithoutId, &pathStr,
sourcePreview, &suffix,
QFileInfo(currentFileName).fileName(), sortedPropertiesWithoutId,
&result, sourcePreview,
Core::ICore::dialogParent()); currentFileName.fileName(),
&result,
Core::ICore::dialogParent());
if (!confirm) if (!confirm)
return; return;
path = Utils::FilePath::fromUserInput(pathStr);
if (componentName.isEmpty() || path.isEmpty()) if (componentName.isEmpty() || path.isEmpty())
return; return;
const QString newFileName = path + QLatin1Char('/') + componentName const Utils::FilePath newFileName = path.pathAppended(componentName + QLatin1String(".")
+ QLatin1String(".") + suffix; + suffix);
QString imports; QString imports;
UiProgram *prog = currentFile->qmljsDocument()->qmlProgram(); UiProgram *prog = currentFile->qmljsDocument()->qmlProgram();
@@ -190,18 +194,18 @@ public:
// stop if we can't create the new file // stop if we can't create the new file
const bool reindent = true; const bool reindent = true;
const bool openEditor = false; const bool openEditor = false;
const Utils::FilePath newFilePath = Utils::FilePath::fromString(newFileName); const Utils::FilePath newFilePath = newFileName;
if (!refactoring.createFile(newFilePath, newComponentSource, reindent, openEditor)) if (!refactoring.createFile(newFileName, newComponentSource, reindent, openEditor))
return; return;
if (path == QFileInfo(currentFileName).path()) { if (path.toString() == currentFileName.toFileInfo().path()) {
// hack for the common case, next version should use the wizard // hack for the common case, next version should use the wizard
ProjectExplorer::Node * oldFileNode = ProjectExplorer::Node *oldFileNode = ProjectExplorer::ProjectTree::nodeForFile(
ProjectExplorer::ProjectTree::nodeForFile(Utils::FilePath::fromString(currentFileName)); currentFileName);
if (oldFileNode) { if (oldFileNode) {
ProjectExplorer::FolderNode *containingFolder = oldFileNode->parentFolderNode(); ProjectExplorer::FolderNode *containingFolder = oldFileNode->parentFolderNode();
if (containingFolder) if (containingFolder)
containingFolder->addFiles({FilePath::fromString(newFileName)}); containingFolder->addFiles({newFileName});
} }
} }
@@ -218,20 +222,21 @@ public:
currentFile->appendIndentRange(Range(start, end + 1)); currentFile->appendIndentRange(Range(start, end + 1));
currentFile->apply(); currentFile->apply();
Core::IVersionControl *versionControl = Core::IVersionControl *versionControl = Core::VcsManager::findVersionControlForDirectory(
Core::VcsManager::findVersionControlForDirectory(FilePath::fromString(path)); path);
if (versionControl if (versionControl
&& versionControl->supportsOperation(Core::IVersionControl::AddOperation)) { && versionControl->supportsOperation(Core::IVersionControl::AddOperation)) {
const QMessageBox::StandardButton button = QMessageBox::question( const QMessageBox::StandardButton button = QMessageBox::question(
Core::ICore::dialogParent(), Core::ICore::dialogParent(),
Core::VcsManager::msgAddToVcsTitle(), Core::VcsManager::msgAddToVcsTitle(),
Core::VcsManager::msgPromptToAddToVcs(QStringList(newFileName), versionControl), Core::VcsManager::msgPromptToAddToVcs(QStringList(newFileName.toString()),
versionControl),
QMessageBox::Yes | QMessageBox::No); QMessageBox::Yes | QMessageBox::No);
if (button == QMessageBox::Yes && !versionControl->vcsAdd(FilePath::fromString(newFileName))) { if (button == QMessageBox::Yes && !versionControl->vcsAdd(newFileName)) {
QMessageBox::warning(Core::ICore::dialogParent(), QMessageBox::warning(Core::ICore::dialogParent(),
Core::VcsManager::msgAddToVcsFailedTitle(), Core::VcsManager::msgAddToVcsFailedTitle(),
Core::VcsManager::msgToAddToVcsFailed(QStringList(newFileName), Core::VcsManager::msgToAddToVcsFailed(
versionControl)); QStringList(newFileName.toString()), versionControl));
} }
} }
} }

View File

@@ -259,7 +259,7 @@ void QmlJSEditorWidget::foldAuxiliaryData()
void QmlJSEditorWidget::updateModificationChange(bool changed) void QmlJSEditorWidget::updateModificationChange(bool changed)
{ {
if (!changed && m_modelManager) if (!changed && m_modelManager)
m_modelManager->fileChangedOnDisk(textDocument()->filePath().toString()); m_modelManager->fileChangedOnDisk(textDocument()->filePath());
} }
bool QmlJSEditorWidget::isOutlineCursorChangesBlocked() bool QmlJSEditorWidget::isOutlineCursorChangesBlocked()
@@ -789,12 +789,13 @@ void QmlJSEditorWidget::findLinkAt(const QTextCursor &cursor,
Utils::Link link; Utils::Link link;
link.linkTextStart = literal->literalToken.begin(); link.linkTextStart = literal->literalToken.begin();
link.linkTextEnd = literal->literalToken.end(); link.linkTextEnd = literal->literalToken.end();
if (semanticInfo.snapshot.document(text)) { Utils::FilePath targetFilePath = Utils::FilePath::fromUserInput(text);
link.targetFilePath = Utils::FilePath::fromString(text); if (semanticInfo.snapshot.document(targetFilePath)) {
link.targetFilePath = targetFilePath;
processLinkCallback(link); processLinkCallback(link);
return; return;
} }
const Utils::FilePath relative = Utils::FilePath::fromString(semanticInfo.document->path()).pathAppended(text); const Utils::FilePath relative = semanticInfo.document->path().pathAppended(text);
if (relative.exists()) { if (relative.exists()) {
link.targetFilePath = m_modelManager->fileToSource(relative); link.targetFilePath = m_modelManager->fileToSource(relative);
processLinkCallback(link); processLinkCallback(link);
@@ -806,14 +807,14 @@ void QmlJSEditorWidget::findLinkAt(const QTextCursor &cursor,
Evaluate evaluator(&scopeChain); Evaluate evaluator(&scopeChain);
const Value *value = evaluator.reference(node); const Value *value = evaluator.reference(node);
QString fileName; Utils::FilePath fileName;
int line = 0, column = 0; int line = 0, column = 0;
if (! (value && value->getSourceLocation(&fileName, &line, &column))) if (! (value && value->getSourceLocation(&fileName, &line, &column)))
return processLinkCallback(Utils::Link()); return processLinkCallback(Utils::Link());
Utils::Link link; Utils::Link link;
link.targetFilePath = m_modelManager->fileToSource(FilePath::fromString(fileName)); link.targetFilePath = m_modelManager->fileToSource(fileName);
link.targetLine = line; link.targetLine = line;
link.targetColumn = column - 1; // adjust the column link.targetColumn = column - 1; // adjust the column
@@ -845,12 +846,12 @@ void QmlJSEditorWidget::findLinkAt(const QTextCursor &cursor,
void QmlJSEditorWidget::findUsages() void QmlJSEditorWidget::findUsages()
{ {
m_findReferences->findUsages(textDocument()->filePath().toString(), textCursor().position()); m_findReferences->findUsages(textDocument()->filePath(), textCursor().position());
} }
void QmlJSEditorWidget::renameSymbolUnderCursor() void QmlJSEditorWidget::renameSymbolUnderCursor()
{ {
m_findReferences->renameUsages(textDocument()->filePath().toString(), textCursor().position()); m_findReferences->renameUsages(textDocument()->filePath(), textCursor().position());
} }
void QmlJSEditorWidget::showContextPane() void QmlJSEditorWidget::showContextPane()

View File

@@ -42,6 +42,7 @@
#include <qmljstools/qmljsmodelmanager.h> #include <qmljstools/qmljsmodelmanager.h>
#include <qmljstools/qmljsqtstylecodeformatter.h> #include <qmljstools/qmljsqtstylecodeformatter.h>
#include <utils/fileutils.h>
#include <utils/infobar.h> #include <utils/infobar.h>
#include <QDebug> #include <QDebug>
@@ -512,7 +513,7 @@ QmlJSEditorDocumentPrivate::QmlJSEditorDocumentPrivate(QmlJSEditorDocument *pare
connect(&m_updateOutlineModelTimer, &QTimer::timeout, connect(&m_updateOutlineModelTimer, &QTimer::timeout,
this, &QmlJSEditorDocumentPrivate::updateOutlineModel); this, &QmlJSEditorDocumentPrivate::updateOutlineModel);
modelManager->updateSourceFiles(QStringList(parent->filePath().toString()), false); modelManager->updateSourceFiles(Utils::FilePaths({parent->filePath()}), false);
} }
QmlJSEditorDocumentPrivate::~QmlJSEditorDocumentPrivate() QmlJSEditorDocumentPrivate::~QmlJSEditorDocumentPrivate()
@@ -533,13 +534,12 @@ void QmlJSEditorDocumentPrivate::invalidateFormatterCache()
void QmlJSEditorDocumentPrivate::reparseDocument() void QmlJSEditorDocumentPrivate::reparseDocument()
{ {
ModelManagerInterface::instance()->updateSourceFiles(QStringList(q->filePath().toString()), ModelManagerInterface::instance()->updateSourceFiles(Utils::FilePaths({q->filePath()}), false);
false);
} }
void QmlJSEditorDocumentPrivate::onDocumentUpdated(Document::Ptr doc) void QmlJSEditorDocumentPrivate::onDocumentUpdated(Document::Ptr doc)
{ {
if (q->filePath().toString() != doc->fileName()) if (q->filePath() != doc->fileName())
return; return;
// text document has changed, simply wait for the next onDocumentUpdated // text document has changed, simply wait for the next onDocumentUpdated

View File

@@ -261,7 +261,7 @@ void QmlJSEditorPluginPrivate::reformatFile()
if (m_currentDocument->isSemanticInfoOutdated()) { if (m_currentDocument->isSemanticInfoOutdated()) {
QmlJS::Document::MutablePtr latestDocument; QmlJS::Document::MutablePtr latestDocument;
const QString fileName = m_currentDocument->filePath().toString(); const Utils::FilePath fileName = m_currentDocument->filePath();
latestDocument = snapshot.documentFromSource(QString::fromUtf8(m_currentDocument->contents()), latestDocument = snapshot.documentFromSource(QString::fromUtf8(m_currentDocument->contents()),
fileName, fileName,
QmlJS::ModelManagerInterface::guessLanguageOfFile(fileName)); QmlJS::ModelManagerInterface::guessLanguageOfFile(fileName));

View File

@@ -739,7 +739,7 @@ public:
: context(context), name(name), scope(scope), future(future) : context(context), name(name), scope(scope), future(future)
{ } { }
QList<Usage> operator()(const QString &fileName) QList<Usage> operator()(const Utils::FilePath &fileName)
{ {
QList<Usage> usages; QList<Usage> usages;
if (future->isPaused()) if (future->isPaused())
@@ -755,7 +755,11 @@ public:
FindUsages findUsages(doc, context); FindUsages findUsages(doc, context);
const FindUsages::Result results = findUsages(name, scope); const FindUsages::Result results = findUsages(name, scope);
for (const SourceLocation &loc : results) for (const SourceLocation &loc : results)
usages.append(Usage(modelManager->fileToSource(Utils::FilePath::fromString(fileName)).toString(), matchingLine(loc.offset, doc->source()), loc.startLine, loc.startColumn - 1, loc.length)); usages.append(Usage(modelManager->fileToSource(fileName),
matchingLine(loc.offset, doc->source()),
loc.startLine,
loc.startColumn - 1,
loc.length));
if (future->isPaused()) if (future->isPaused())
future->waitForResume(); future->waitForResume();
return usages; return usages;
@@ -782,7 +786,7 @@ public:
: context(context), name(name), scope(scope), future(future) : context(context), name(name), scope(scope), future(future)
{ } { }
QList<Usage> operator()(const QString &fileName) QList<Usage> operator()(const Utils::FilePath &fileName)
{ {
QList<Usage> usages; QList<Usage> usages;
if (future->isPaused()) if (future->isPaused())
@@ -842,7 +846,7 @@ FindReferences::~FindReferences() = default;
static void find_helper(QFutureInterface<FindReferences::Usage> &future, static void find_helper(QFutureInterface<FindReferences::Usage> &future,
const ModelManagerInterface::WorkingCopy &workingCopy, const ModelManagerInterface::WorkingCopy &workingCopy,
Snapshot snapshot, Snapshot snapshot,
const QString &fileName, const Utils::FilePath &fileName,
quint32 offset, quint32 offset,
QString replacement) QString replacement)
{ {
@@ -851,7 +855,7 @@ static void find_helper(QFutureInterface<FindReferences::Usage> &future,
// ### this is a great candidate for map-reduce // ### this is a great candidate for map-reduce
const ModelManagerInterface::WorkingCopy::Table &all = workingCopy.all(); const ModelManagerInterface::WorkingCopy::Table &all = workingCopy.all();
for (auto it = all.cbegin(), end = all.cend(); it != end; ++it) { for (auto it = all.cbegin(), end = all.cend(); it != end; ++it) {
const QString fileName = it.key(); const Utils::FilePath fileName = it.key();
Document::Ptr oldDoc = snapshot.document(fileName); Document::Ptr oldDoc = snapshot.document(fileName);
if (oldDoc && oldDoc->editorRevision() == it.value().second) if (oldDoc && oldDoc->editorRevision() == it.value().second)
continue; continue;
@@ -895,17 +899,17 @@ static void find_helper(QFutureInterface<FindReferences::Usage> &future,
if (!replacement.isNull() && replacement.isEmpty()) if (!replacement.isNull() && replacement.isEmpty())
replacement = name; replacement = name;
QStringList files; Utils::FilePaths files;
for (const Document::Ptr &doc : qAsConst(snapshot)) { for (const Document::Ptr &doc : qAsConst(snapshot)) {
// ### skip files that don't contain the name token // ### skip files that don't contain the name token
files.append(modelManager->fileToSource(Utils::FilePath::fromString(doc->fileName())).toString()); files.append(modelManager->fileToSource(doc->fileName()));
} }
files = Utils::filteredUnique(files); files = Utils::filteredUnique(files);
future.setProgressRange(0, files.size()); future.setProgressRange(0, files.size());
// report a dummy usage to indicate the search is starting // report a dummy usage to indicate the search is starting
FindReferences::Usage searchStarting(replacement, name, 0, 0, 0); FindReferences::Usage searchStarting(Utils::FilePath::fromString(replacement), name, 0, 0, 0);
if (findTarget.typeKind() == findTarget.TypeKind){ if (findTarget.typeKind() == findTarget.TypeKind){
const ObjectValue *typeValue = value_cast<ObjectValue>(findTarget.targetValue()); const ObjectValue *typeValue = value_cast<ObjectValue>(findTarget.targetValue());
@@ -936,7 +940,7 @@ static void find_helper(QFutureInterface<FindReferences::Usage> &future,
future.setProgressValue(files.size()); future.setProgressValue(files.size());
} }
void FindReferences::findUsages(const QString &fileName, quint32 offset) void FindReferences::findUsages(const Utils::FilePath &fileName, quint32 offset)
{ {
ModelManagerInterface *modelManager = ModelManagerInterface::instance(); ModelManagerInterface *modelManager = ModelManagerInterface::instance();
@@ -946,7 +950,8 @@ void FindReferences::findUsages(const QString &fileName, quint32 offset)
m_synchronizer.addFuture(result); m_synchronizer.addFuture(result);
} }
void FindReferences::renameUsages(const QString &fileName, quint32 offset, void FindReferences::renameUsages(const Utils::FilePath &fileName,
quint32 offset,
const QString &replacement) const QString &replacement)
{ {
ModelManagerInterface *modelManager = ModelManagerInterface::instance(); ModelManagerInterface *modelManager = ModelManagerInterface::instance();
@@ -962,7 +967,8 @@ void FindReferences::renameUsages(const QString &fileName, quint32 offset,
m_synchronizer.addFuture(result); m_synchronizer.addFuture(result);
} }
QList<FindReferences::Usage> FindReferences::findUsageOfType(const QString &fileName, const QString &typeName) QList<FindReferences::Usage> FindReferences::findUsageOfType(const Utils::FilePath &fileName,
const QString &typeName)
{ {
QList<Usage> usages; QList<Usage> usages;
ModelManagerInterface *modelManager = ModelManagerInterface::instance(); ModelManagerInterface *modelManager = ModelManagerInterface::instance();
@@ -979,9 +985,9 @@ QList<FindReferences::Usage> FindReferences::findUsageOfType(const QString &file
QmlJS::Snapshot snapshot = modelManager->snapshot(); QmlJS::Snapshot snapshot = modelManager->snapshot();
QSet<QString> docDone; QSet<Utils::FilePath> docDone;
for (const QmlJS::Document::Ptr &doc : qAsConst(snapshot)) { for (const QmlJS::Document::Ptr &doc : qAsConst(snapshot)) {
QString sourceFile = modelManager->fileToSource(Utils::FilePath::fromString(doc->fileName())).toString(); Utils::FilePath sourceFile = modelManager->fileToSource(doc->fileName());
if (docDone.contains(sourceFile)) if (docDone.contains(sourceFile))
continue; continue;
docDone.insert(sourceFile); docDone.insert(sourceFile);
@@ -1006,7 +1012,7 @@ void FindReferences::displayResults(int first, int last)
// the first usage is always a dummy to indicate we now start searching // the first usage is always a dummy to indicate we now start searching
if (first == 0) { if (first == 0) {
Usage dummy = m_watcher.future().resultAt(0); Usage dummy = m_watcher.future().resultAt(0);
const QString replacement = dummy.path; const QString replacement = dummy.path.toString();
const QString symbolName = dummy.lineText; const QString symbolName = dummy.lineText;
const QString label = tr("QML/JS Usages:"); const QString label = tr("QML/JS Usages:");
@@ -1044,7 +1050,7 @@ void FindReferences::displayResults(int first, int last)
for (int index = first; index != last; ++index) { for (int index = first; index != last; ++index) {
Usage result = m_watcher.future().resultAt(index); Usage result = m_watcher.future().resultAt(index);
SearchResultItem item; SearchResultItem item;
item.setFilePath(Utils::FilePath::fromString(result.path)); item.setFilePath(result.path);
item.setLineText(result.lineText); item.setLineText(result.lineText);
item.setMainRange(result.line, result.col, result.len); item.setMainRange(result.line, result.col, result.len);
item.setUseTextEditorFont(true); item.setUseTextEditorFont(true);
@@ -1078,13 +1084,13 @@ void FindReferences::onReplaceButtonClicked(const QString &text, const QList<Sea
preserveCase); preserveCase);
// files that are opened in an editor are changed, but not saved // files that are opened in an editor are changed, but not saved
QStringList changedOnDisk; Utils::FilePaths changedOnDisk;
QStringList changedUnsavedEditors; Utils::FilePaths changedUnsavedEditors;
for (const Utils::FilePath &filePath : filePaths) { for (const Utils::FilePath &filePath : filePaths) {
if (DocumentModel::documentForFilePath(filePath)) if (DocumentModel::documentForFilePath(filePath))
changedOnDisk += filePath.toString(); changedOnDisk += filePath;
else else
changedUnsavedEditors += filePath.toString(); changedUnsavedEditors += filePath;
} }
if (!changedOnDisk.isEmpty()) if (!changedOnDisk.isEmpty())

View File

@@ -27,6 +27,7 @@
#include "qmljseditor_global.h" #include "qmljseditor_global.h"
#include <utils/filepath.h>
#include <utils/futuresynchronizer.h> #include <utils/futuresynchronizer.h>
#include <QObject> #include <QObject>
@@ -49,11 +50,16 @@ public:
class Usage class Usage
{ {
public: public:
Usage(const QString &path, const QString &lineText, int line, int col, int len) Usage(const Utils::FilePath &path, const QString &lineText, int line, int col, int len)
: path(path), lineText(lineText), line(line), col(col), len(len) {} : path(path)
, lineText(lineText)
, line(line)
, col(col)
, len(len)
{}
public: public:
QString path; Utils::FilePath path;
QString lineText; QString lineText;
int line = 0; int line = 0;
int col = 0; int col = 0;
@@ -68,11 +74,12 @@ signals:
void changed(); void changed();
public: public:
void findUsages(const QString &fileName, quint32 offset); void findUsages(const Utils::FilePath &fileName, quint32 offset);
void renameUsages(const QString &fileName, quint32 offset, void renameUsages(const Utils::FilePath &fileName,
quint32 offset,
const QString &replacement = QString()); const QString &replacement = QString());
static QList<Usage> findUsageOfType(const QString &fileName, const QString &typeName); static QList<Usage> findUsageOfType(const Utils::FilePath &fileName, const QString &typeName);
private: private:
void displayResults(int first, int last); void displayResults(int first, int last);

View File

@@ -125,7 +125,7 @@ static inline QString getModuleName(const ScopeChain &scopeChain, const Document
+ QString::number(minorVersion) ; + QString::number(minorVersion) ;
} else if (importInfo.isValid() && importInfo.type() == ImportType::Directory) { } else if (importInfo.isValid() && importInfo.type() == ImportType::Directory) {
const QString path = importInfo.path(); const QString path = importInfo.path();
const QDir dir(qmlDocument->path()); const QDir dir = qmlDocument->path().toDir();
// should probably try to make it relatve to some import path, not to the document path // should probably try to make it relatve to some import path, not to the document path
QString relativeDir = dir.relativeFilePath(path); QString relativeDir = dir.relativeFilePath(path);
const QString name = relativeDir.replace(QLatin1Char('/'), QLatin1Char('.')); const QString name = relativeDir.replace(QLatin1Char('/'), QLatin1Char('.'));
@@ -364,7 +364,7 @@ void QmlJSHoverHandler::handleImport(const ScopeChain &scopeChain, AST::UiImport
if (import.info.ast() == node) { if (import.info.ast() == node) {
if (import.info.type() == ImportType::Library if (import.info.type() == ImportType::Library
&& !import.libraryPath.isEmpty()) { && !import.libraryPath.isEmpty()) {
QString msg = tr("Library at %1").arg(import.libraryPath); QString msg = tr("Library at %1").arg(import.libraryPath.toString());
const LibraryInfo &libraryInfo = scopeChain.context()->snapshot().libraryInfo(import.libraryPath); const LibraryInfo &libraryInfo = scopeChain.context()->snapshot().libraryInfo(import.libraryPath);
if (libraryInfo.pluginTypeInfoStatus() == LibraryInfo::DumpDone) { if (libraryInfo.pluginTypeInfoStatus() == LibraryInfo::DumpDone) {
msg += QLatin1Char('\n'); msg += QLatin1Char('\n');

View File

@@ -56,7 +56,7 @@ void QmlJSQuickFixOperation::perform()
{ {
QmlJSRefactoringChanges refactoring(ModelManagerInterface::instance(), QmlJSRefactoringChanges refactoring(ModelManagerInterface::instance(),
m_interface->semanticInfo().snapshot); m_interface->semanticInfo().snapshot);
QmlJSRefactoringFilePtr current = refactoring.file(Utils::FilePath::fromString(fileName())); QmlJSRefactoringFilePtr current = refactoring.file(fileName());
performChanges(current, refactoring); performChanges(current, refactoring);
} }
@@ -66,7 +66,7 @@ const QmlJSQuickFixAssistInterface *QmlJSQuickFixOperation::assistInterface() co
return m_interface.data(); return m_interface.data();
} }
QString QmlJSQuickFixOperation::fileName() const Utils::FilePath QmlJSQuickFixOperation::fileName() const
{ {
return m_interface->semanticInfo().document->fileName(); return m_interface->semanticInfo().document->fileName();
} }

View File

@@ -66,7 +66,7 @@ protected:
const Internal::QmlJSQuickFixAssistInterface *assistInterface() const; const Internal::QmlJSQuickFixAssistInterface *assistInterface() const;
/// \returns The name of the file for for which this operation is invoked. /// \returns The name of the file for for which this operation is invoked.
QString fileName() const; Utils::FilePath fileName() const;
private: private:
QmlJSQuickFixInterface m_interface; QmlJSQuickFixInterface m_interface;

View File

@@ -123,7 +123,8 @@ QmlJSTools::SemanticInfo SemanticInfoUpdater::makeNewSemanticInfo(const QmlJS::D
semanticInfo.setRootScopeChain(QSharedPointer<const ScopeChain>(scopeChain)); semanticInfo.setRootScopeChain(QSharedPointer<const ScopeChain>(scopeChain));
if (doc->language() == Dialect::Json) { if (doc->language() == Dialect::Json) {
Utils::JsonSchema *schema = QmlJSEditorPlugin::jsonManager()->schemaForFile(doc->fileName()); Utils::JsonSchema *schema = QmlJSEditorPlugin::jsonManager()->schemaForFile(
doc->fileName().toString());
if (schema) { if (schema) {
JsonCheck jsonChecker(doc); JsonCheck jsonChecker(doc);
semanticInfo.staticAnalysisMessages = jsonChecker(schema); semanticInfo.staticAnalysisMessages = jsonChecker(schema);

View File

@@ -880,8 +880,7 @@ void QmlOutlineModel::reparentNodes(QmlOutlineItem *targetItem, int row, QList<Q
} }
QmlJSRefactoringChanges refactoring(ModelManagerInterface::instance(), m_semanticInfo.snapshot); QmlJSRefactoringChanges refactoring(ModelManagerInterface::instance(), m_semanticInfo.snapshot);
TextEditor::RefactoringFilePtr file = refactoring.file( TextEditor::RefactoringFilePtr file = refactoring.file(m_semanticInfo.document->fileName());
Utils::FilePath::fromString(m_semanticInfo.document->fileName()));
file->setChangeSet(changeSet); file->setChangeSet(changeSet);
for (const Utils::ChangeSet::Range &range : qAsConst(changedRanges)) { for (const Utils::ChangeSet::Range &range : qAsConst(changedRanges)) {
file->appendIndentRange(range); file->appendIndentRange(range);

View File

@@ -86,14 +86,14 @@ void QmlTaskManager::collectMessages(QFutureInterface<FileErrorMessages> &future
bool updateSemantic) bool updateSemantic)
{ {
for (const ModelManagerInterface::ProjectInfo &info : projectInfos) { for (const ModelManagerInterface::ProjectInfo &info : projectInfos) {
QHash<QString, QList<DiagnosticMessage> > linkMessages; QHash<Utils::FilePath, QList<DiagnosticMessage>> linkMessages;
ContextPtr context; ContextPtr context;
if (updateSemantic) { if (updateSemantic) {
QmlJS::Link link(snapshot, vContext, QmlJS::LibraryInfo()); QmlJS::Link link(snapshot, vContext, QmlJS::LibraryInfo());
context = link(&linkMessages); context = link(&linkMessages);
} }
for (const QString &fileName : qAsConst(info.sourceFiles)) { for (const Utils::FilePath &fileName : qAsConst(info.sourceFiles)) {
Document::Ptr document = snapshot.document(fileName); Document::Ptr document = snapshot.document(fileName);
if (!document) if (!document)
continue; continue;
@@ -102,17 +102,17 @@ void QmlTaskManager::collectMessages(QFutureInterface<FileErrorMessages> &future
result.fileName = fileName; result.fileName = fileName;
if (document->language().isFullySupportedLanguage()) { if (document->language().isFullySupportedLanguage()) {
result.tasks = convertToTasks(document->diagnosticMessages(), result.tasks = convertToTasks(document->diagnosticMessages(),
FilePath::fromString(fileName), fileName,
Constants::TASK_CATEGORY_QML); Constants::TASK_CATEGORY_QML);
if (updateSemantic) { if (updateSemantic) {
result.tasks += convertToTasks(linkMessages.value(fileName), result.tasks += convertToTasks(linkMessages.value(fileName),
FilePath::fromString(fileName), fileName,
Constants::TASK_CATEGORY_QML_ANALYSIS); Constants::TASK_CATEGORY_QML_ANALYSIS);
Check checker(document, context); Check checker(document, context);
result.tasks += convertToTasks(checker(), result.tasks += convertToTasks(checker(),
FilePath::fromString(fileName), fileName,
Constants::TASK_CATEGORY_QML_ANALYSIS); Constants::TASK_CATEGORY_QML_ANALYSIS);
} }
} }
@@ -156,9 +156,9 @@ void QmlTaskManager::updateMessagesNow(bool updateSemantic)
m_messageCollector.setFuture(future); m_messageCollector.setFuture(future);
} }
void QmlTaskManager::documentsRemoved(const QStringList &path) void QmlTaskManager::documentsRemoved(const Utils::FilePaths &path)
{ {
for (const QString &item : path) for (const Utils::FilePath &item : path)
removeTasksForFile(item); removeTasksForFile(item);
} }
@@ -180,13 +180,13 @@ void QmlTaskManager::displayAllResults()
void QmlTaskManager::insertTask(const Task &task) void QmlTaskManager::insertTask(const Task &task)
{ {
Tasks tasks = m_docsWithTasks.value(task.file.toString()); Tasks tasks = m_docsWithTasks.value(task.file);
tasks.append(task); tasks.append(task);
m_docsWithTasks.insert(task.file.toString(), tasks); m_docsWithTasks.insert(task.file, tasks);
TaskHub::addTask(task); TaskHub::addTask(task);
} }
void QmlTaskManager::removeTasksForFile(const QString &fileName) void QmlTaskManager::removeTasksForFile(const Utils::FilePath &fileName)
{ {
if (m_docsWithTasks.contains(fileName)) { if (m_docsWithTasks.contains(fileName)) {
const Tasks tasks = m_docsWithTasks.value(fileName); const Tasks tasks = m_docsWithTasks.value(fileName);

View File

@@ -49,7 +49,7 @@ public:
void updateMessages(); void updateMessages();
void updateSemanticMessagesNow(); void updateSemanticMessagesNow();
void documentsRemoved(const QStringList &path); void documentsRemoved(const Utils::FilePaths &path);
private: private:
void displayResults(int begin, int end); void displayResults(int begin, int end);
@@ -57,14 +57,14 @@ private:
void updateMessagesNow(bool updateSemantic = false); void updateMessagesNow(bool updateSemantic = false);
void insertTask(const ProjectExplorer::Task &task); void insertTask(const ProjectExplorer::Task &task);
void removeTasksForFile(const QString &fileName); void removeTasksForFile(const Utils::FilePath &fileName);
void removeAllTasks(bool clearSemantic); void removeAllTasks(bool clearSemantic);
private: private:
class FileErrorMessages class FileErrorMessages
{ {
public: public:
QString fileName; Utils::FilePath fileName;
ProjectExplorer::Tasks tasks; ProjectExplorer::Tasks tasks;
}; };
static void collectMessages(QFutureInterface<FileErrorMessages> &future, static void collectMessages(QFutureInterface<FileErrorMessages> &future,
@@ -74,7 +74,7 @@ private:
bool updateSemantic); bool updateSemantic);
private: private:
QHash<QString, ProjectExplorer::Tasks > m_docsWithTasks; QHash<Utils::FilePath, ProjectExplorer::Tasks> m_docsWithTasks;
QFutureWatcher<FileErrorMessages> m_messageCollector; QFutureWatcher<FileErrorMessages> m_messageCollector;
QTimer m_updateDelay; QTimer m_updateDelay;
bool m_updatingSemantic = false; bool m_updatingSemantic = false;

View File

@@ -219,7 +219,7 @@ void QuickToolBar::apply(TextEditor::TextEditorWidget *editorWidget, Document::P
else else
contextWidget()->rePosition(p3 , p1, p2, QmlJsEditingSettings::get().pinContextPane()); contextWidget()->rePosition(p3 , p1, p2, QmlJsEditingSettings::get().pinContextPane());
contextWidget()->setOptions(QmlJsEditingSettings::get().enableContextPane(), QmlJsEditingSettings::get().pinContextPane()); contextWidget()->setOptions(QmlJsEditingSettings::get().enableContextPane(), QmlJsEditingSettings::get().pinContextPane());
contextWidget()->setPath(document->path()); contextWidget()->setPath(document->path().toString());
contextWidget()->setProperties(&propertyReader); contextWidget()->setProperties(&propertyReader);
m_doc = document; m_doc = document;
m_node = node; m_node = node;

View File

@@ -61,7 +61,7 @@ QList<Core::LocatorFilterEntry> FunctionFilter::matchesFor(
if (!regexp.isValid()) if (!regexp.isValid())
return {}; return {};
const QHash<QString, QList<LocatorData::Entry> > locatorEntries = m_data->entries(); const QHash<Utils::FilePath, QList<LocatorData::Entry>> locatorEntries = m_data->entries();
for (const QList<LocatorData::Entry> &items : locatorEntries) { for (const QList<LocatorData::Entry> &items : locatorEntries) {
if (future.isCanceled()) if (future.isCanceled())
break; break;
@@ -102,6 +102,5 @@ void FunctionFilter::accept(const Core::LocatorFilterEntry &selection,
Q_UNUSED(selectionStart) Q_UNUSED(selectionStart)
Q_UNUSED(selectionLength) Q_UNUSED(selectionLength)
const LocatorData::Entry entry = qvariant_cast<LocatorData::Entry>(selection.internalData); const LocatorData::Entry entry = qvariant_cast<LocatorData::Entry>(selection.internalData);
Core::EditorManager::openEditorAt( Core::EditorManager::openEditorAt({entry.fileName, entry.line, entry.column});
{Utils::FilePath::fromString(entry.fileName), entry.line, entry.column});
} }

View File

@@ -47,13 +47,15 @@ LocatorData::LocatorData()
// Force the updating of source file when updating a project (they could be cached, in such // Force the updating of source file when updating a project (they could be cached, in such
// case LocatorData::onDocumentUpdated will not be called. // case LocatorData::onDocumentUpdated will not be called.
connect(manager, &ModelManagerInterface::projectInfoUpdated, connect(manager,
&ModelManagerInterface::projectInfoUpdated,
[manager](const ModelManagerInterface::ProjectInfo &info) { [manager](const ModelManagerInterface::ProjectInfo &info) {
QStringList files; Utils::FilePaths files;
for (const Utils::FilePath &f: info.project->files(ProjectExplorer::Project::SourceFiles)) for (const Utils::FilePath &f :
files << f.toString(); info.project->files(ProjectExplorer::Project::SourceFiles))
manager->updateSourceFiles(files, true); files << f;
}); manager->updateSourceFiles(files, true);
});
connect(manager, &ModelManagerInterface::documentUpdated, connect(manager, &ModelManagerInterface::documentUpdated,
this, &LocatorData::onDocumentUpdated); this, &LocatorData::onDocumentUpdated);
@@ -86,7 +88,7 @@ public:
if (!doc->componentName().isEmpty()) if (!doc->componentName().isEmpty())
m_documentContext = doc->componentName(); m_documentContext = doc->componentName();
else else
m_documentContext = Utils::FilePath::fromString(doc->fileName()).fileName(); m_documentContext = doc->fileName().fileName();
accept(doc->ast(), m_documentContext); accept(doc->ast(), m_documentContext);
return m_entries; return m_entries;
} }
@@ -236,7 +238,7 @@ protected:
}; };
} // anonymous namespace } // anonymous namespace
QHash<QString, QList<LocatorData::Entry> > LocatorData::entries() const QHash<Utils::FilePath, QList<LocatorData::Entry>> LocatorData::entries() const
{ {
QMutexLocker l(&m_mutex); QMutexLocker l(&m_mutex);
return m_entries; return m_entries;
@@ -249,10 +251,10 @@ void LocatorData::onDocumentUpdated(const Document::Ptr &doc)
m_entries.insert(doc->fileName(), entries); m_entries.insert(doc->fileName(), entries);
} }
void LocatorData::onAboutToRemoveFiles(const QStringList &files) void LocatorData::onAboutToRemoveFiles(const Utils::FilePaths &files)
{ {
QMutexLocker l(&m_mutex); QMutexLocker l(&m_mutex);
for (const QString &file : files) { for (const Utils::FilePath &file : files) {
m_entries.remove(file); m_entries.remove(file);
} }
} }

View File

@@ -25,6 +25,7 @@
#pragma once #pragma once
#include <utils/filepath.h>
#include <qmljs/qmljsdocument.h> #include <qmljs/qmljsdocument.h>
#include <QObject> #include <QObject>
@@ -53,19 +54,19 @@ public:
QString symbolName; QString symbolName;
QString displayName; QString displayName;
QString extraInfo; QString extraInfo;
QString fileName; Utils::FilePath fileName;
int line; int line;
int column; int column;
}; };
QHash<QString, QList<Entry> > entries() const; QHash<Utils::FilePath, QList<Entry>> entries() const;
private: private:
void onDocumentUpdated(const QmlJS::Document::Ptr &doc); void onDocumentUpdated(const QmlJS::Document::Ptr &doc);
void onAboutToRemoveFiles(const QStringList &files); void onAboutToRemoveFiles(const Utils::FilePaths &files);
mutable QMutex m_mutex; mutable QMutex m_mutex;
QHash<QString, QList<Entry> > m_entries; QHash<Utils::FilePath, QList<Entry>> m_entries;
}; };
} // namespace Internal } // namespace Internal

View File

@@ -115,14 +115,14 @@ ModelManagerInterface::ProjectInfo ModelManager::defaultProjectInfoForProject(
Constants::QMLPROJECT_MIMETYPE, Constants::QMLPROJECT_MIMETYPE,
Constants::QMLTYPES_MIMETYPE, Constants::QMLTYPES_MIMETYPE,
Constants::QMLUI_MIMETYPE }; Constants::QMLUI_MIMETYPE };
projectInfo.sourceFiles = Utils::transform(project->files([&qmlTypeNames](const Node *n) { projectInfo.sourceFiles = project->files([&qmlTypeNames](const Node *n) {
if (!Project::SourceFiles(n)) if (!Project::SourceFiles(n))
return false; return false;
const FileNode *fn = n->asFileNode(); const FileNode *fn = n->asFileNode();
return fn && fn->fileType() == FileType::QML return fn && fn->fileType() == FileType::QML
&& qmlTypeNames.contains(Utils::mimeTypeForFile(fn->filePath(), && qmlTypeNames.contains(Utils::mimeTypeForFile(fn->filePath(),
MimeMatchMode::MatchExtension).name()); MimeMatchMode::MatchExtension).name());
}), &FilePath::toString); });
activeTarget = project->activeTarget(); activeTarget = project->activeTarget();
} }
Kit *activeKit = activeTarget ? activeTarget->kit() : KitManager::defaultKit(); Kit *activeKit = activeTarget ? activeTarget->kit() : KitManager::defaultKit();
@@ -131,15 +131,15 @@ ModelManagerInterface::ProjectInfo ModelManager::defaultProjectInfoForProject(
projectInfo.tryQmlDump = false; projectInfo.tryQmlDump = false;
if (activeTarget) { if (activeTarget) {
QDir baseDir; FilePath baseDir;
auto addAppDir = [&baseDir, & projectInfo](const QString &mdir) { auto addAppDir = [&baseDir, &projectInfo](const FilePath &mdir) {
auto dir = QDir::cleanPath(mdir); auto dir = mdir.cleanPath();
if (!baseDir.path().isEmpty()) { if (!baseDir.path().isEmpty()) {
auto rDir = baseDir.relativeFilePath(dir); auto rDir = dir.relativePath(baseDir);
// do not add directories outside the build directory // do not add directories outside the build directory
// this might happen for example when we think an executable path belongs to // this might happen for example when we think an executable path belongs to
// a bundle, and we need to remove extra directories, but that was not the case // a bundle, and we need to remove extra directories, but that was not the case
if (rDir.split(u'/').contains(QStringLiteral(u".."))) if (rDir.path().split(u'/').contains(QStringLiteral(u"..")))
return; return;
} }
if (!projectInfo.applicationDirectories.contains(dir)) if (!projectInfo.applicationDirectories.contains(dir))
@@ -153,8 +153,8 @@ ModelManagerInterface::ProjectInfo ModelManager::defaultProjectInfoForProject(
projectInfo.qmlDumpEnvironment.appendOrSet("QML2_IMPORT_PATH", bc->environment().expandedValueForKey("QML2_IMPORT_PATH"), ":"); projectInfo.qmlDumpEnvironment.appendOrSet("QML2_IMPORT_PATH", bc->environment().expandedValueForKey("QML2_IMPORT_PATH"), ":");
// Treat every target (library or application) in the build directory // Treat every target (library or application) in the build directory
QString dir = bc->buildDirectory().toString(); FilePath dir = bc->buildDirectory();
baseDir.setPath(QDir{dir}.absolutePath()); baseDir = dir.absoluteFilePath();
addAppDir(dir); addAppDir(dir);
} }
// Qml loads modules from the following sources // Qml loads modules from the following sources
@@ -169,24 +169,23 @@ ModelManagerInterface::ProjectInfo ModelManager::defaultProjectInfoForProject(
if (target.targetFilePath.isEmpty()) if (target.targetFilePath.isEmpty())
continue; continue;
auto dir = target.targetFilePath.parentDir(); auto dir = target.targetFilePath.parentDir();
projectInfo.applicationDirectories.append(dir.toString()); projectInfo.applicationDirectories.append(dir);
// unfortunately the build directory of the executable where cmake puts the qml // unfortunately the build directory of the executable where cmake puts the qml
// might be different than the directory of the executable: // might be different than the directory of the executable:
#if defined(Q_OS_WIN) if (HostOsInfo::isWindowsHost()) {
// On Windows systems QML type information is located one directory higher as we build // On Windows systems QML type information is located one directory higher as we build
// in dedicated "debug" and "release" directories // in dedicated "debug" and "release" directories
addAppDir( addAppDir(dir.parentDir());
dir.parentDir().toString()); } else if (HostOsInfo::isMacHost()) {
#elif defined(Q_OS_MACOS) // On macOS and iOS when building a bundle this is not the case and
// On macOS and iOS when building a bundle this is not the case and // we have to go up up to three additional directories
// we have to go up up to three additional directories // (BundleName.app/Contents/MacOS or BundleName.app/Contents for iOS)
// (BundleName.app/Contents/MacOS or BundleName.app/Contents for iOS) if (dir.fileName() == u"MacOS")
if (dir.fileName() == u"MacOS") dir = dir.parentDir();
dir = dir.parentDir(); if (dir.fileName() == u"Contents")
if (dir.fileName() == u"Contents") dir = dir.parentDir().parentDir();
dir = dir.parentDir().parentDir(); addAppDir(dir);
addAppDir(dir.toString()); }
#endif
} }
} }
if (qtVersion && qtVersion->isValid()) { if (qtVersion && qtVersion->isValid()) {
@@ -271,7 +270,7 @@ void ModelManager::delayedInitialization()
ViewerContext qbsVContext; ViewerContext qbsVContext;
qbsVContext.language = Dialect::QmlQbs; qbsVContext.language = Dialect::QmlQbs;
qbsVContext.paths.append(ICore::resourcePath("qbs").toString()); qbsVContext.paths.append(ICore::resourcePath("qbs"));
setDefaultVContext(qbsVContext); setDefaultVContext(qbsVContext);
} }
@@ -297,7 +296,7 @@ ModelManagerInterface::WorkingCopy ModelManager::workingCopyInternal() const
const QList<IDocument *> documents = DocumentModel::openedDocuments(); const QList<IDocument *> documents = DocumentModel::openedDocuments();
for (IDocument *document : documents) { for (IDocument *document : documents) {
const QString key = document->filePath().toString(); const Utils::FilePath key = document->filePath();
if (auto textDocument = qobject_cast<const TextEditor::TextDocument *>(document)) { if (auto textDocument = qobject_cast<const TextEditor::TextDocument *>(document)) {
// TODO the language should be a property on the document, not the editor // TODO the language should be a property on the document, not the editor
if (DocumentModel::editorsForDocument(document).constFirst() if (DocumentModel::editorsForDocument(document).constFirst()

View File

@@ -90,7 +90,7 @@ public:
void fileChanged(const Utils::FilePath &filePath) override void fileChanged(const Utils::FilePath &filePath) override
{ {
m_modelManager->updateSourceFiles({filePath.toString()}, true); m_modelManager->updateSourceFiles({filePath}, true);
} }
ModelManagerInterface *m_modelManager; ModelManagerInterface *m_modelManager;
@@ -129,7 +129,7 @@ QmlJSRefactoringFile::QmlJSRefactoringFile(
: RefactoringFile(filePath, data) : RefactoringFile(filePath, data)
{ {
// the RefactoringFile is invalid if its not for a file with qml or js code // the RefactoringFile is invalid if its not for a file with qml or js code
if (ModelManagerInterface::guessLanguageOfFile(filePath.toString()) == Dialect::NoLanguage) if (ModelManagerInterface::guessLanguageOfFile(filePath) == Dialect::NoLanguage)
m_filePath.clear(); m_filePath.clear();
} }
@@ -138,18 +138,19 @@ QmlJSRefactoringFile::QmlJSRefactoringFile(TextEditor::TextEditorWidget *editor,
, m_qmljsDocument(document) , m_qmljsDocument(document)
{ {
if (document) if (document)
m_filePath = Utils::FilePath::fromString(document->fileName()); m_filePath = document->fileName();
} }
Document::Ptr QmlJSRefactoringFile::qmljsDocument() const Document::Ptr QmlJSRefactoringFile::qmljsDocument() const
{ {
if (!m_qmljsDocument) { if (!m_qmljsDocument) {
const QString source = document()->toPlainText(); const QString source = document()->toPlainText();
const QString name = filePath().toString();
const Snapshot &snapshot = data()->m_snapshot; const Snapshot &snapshot = data()->m_snapshot;
Document::MutablePtr newDoc = snapshot.documentFromSource(source, name, Document::MutablePtr newDoc
ModelManagerInterface::guessLanguageOfFile(name)); = snapshot.documentFromSource(source,
filePath(),
ModelManagerInterface::guessLanguageOfFile(filePath()));
newDoc->parse(); newDoc->parse();
m_qmljsDocument = newDoc; m_qmljsDocument = newDoc;
} }

View File

@@ -43,10 +43,9 @@ void QmlJSToolsPlugin::test_basic()
{ {
ModelManagerInterface *modelManager = ModelManagerInterface::instance(); ModelManagerInterface *modelManager = ModelManagerInterface::instance();
const QString qmlFilePath = Core::ICore::resourcePath( const Utils::FilePath qmlFilePath = Core::ICore::resourcePath(
"qmldesigner/itemLibraryQmlSources/ItemDelegate.qml") "qmldesigner/itemLibraryQmlSources/ItemDelegate.qml");
.toString(); modelManager->updateSourceFiles(QList<Utils::FilePath>({qmlFilePath}), false);
modelManager->updateSourceFiles(QStringList(qmlFilePath), false);
modelManager->test_joinAllThreads(); modelManager->test_joinAllThreads();
Snapshot snapshot = modelManager->snapshot(); Snapshot snapshot = modelManager->snapshot();

View File

@@ -506,8 +506,11 @@ void QmlPreviewPluginPrivate::checkFile(const QString &fileName)
const QByteArray contents = m_fileLoader(fileName, &success); const QByteArray contents = m_fileLoader(fileName, &success);
if (success) { if (success) {
emit q->checkDocument(fileName, contents, emit q->checkDocument(fileName,
QmlJS::ModelManagerInterface::guessLanguageOfFile(fileName).dialect()); contents,
QmlJS::ModelManagerInterface::guessLanguageOfFile(
Utils::FilePath::fromUserInput(fileName))
.dialect());
} }
} }
@@ -533,7 +536,8 @@ void QmlPreviewParser::parse(const QString &name, const QByteArray &contents,
return; return;
} }
QmlJS::Document::MutablePtr qmljsDoc = QmlJS::Document::create(name, dialect); QmlJS::Document::MutablePtr qmljsDoc = QmlJS::Document::create(Utils::FilePath::fromString(name),
dialect);
qmljsDoc->setSource(QString::fromUtf8(contents)); qmljsDoc->setSource(QString::fromUtf8(contents));
if (qmljsDoc->parse()) if (qmljsDoc->parse())
emit success(name, contents); emit success(name, contents);

View File

@@ -73,7 +73,7 @@ set(QMLPROFILER_CPP_SOURCES
if(${Qt5_VERSION} VERSION_LESS "6.2.0") if(${Qt5_VERSION} VERSION_LESS "6.2.0")
add_qtc_plugin(QmlProfiler add_qtc_plugin(QmlProfiler
DEPENDS QmlDebug QmlJS Tracing Qt5::QuickWidgets DEPENDS QmlDebug QmlJS Tracing Qt5::QuickWidgets Utils
PLUGIN_DEPENDS Core Debugger ProjectExplorer QtSupport TextEditor PLUGIN_DEPENDS Core Debugger ProjectExplorer QtSupport TextEditor
SOURCES SOURCES
${TEST_SOURCES} ${TEST_SOURCES}

View File

@@ -106,7 +106,7 @@ QmlProfilerDetailsRewriter::QmlProfilerDetailsRewriter(QObject *parent)
void QmlProfilerDetailsRewriter::requestDetailsForLocation(int typeId, void QmlProfilerDetailsRewriter::requestDetailsForLocation(int typeId,
const QmlEventLocation &location) const QmlEventLocation &location)
{ {
const QString localFile = getLocalFile(location.filename()); const Utils::FilePath localFile = getLocalFile(location.filename());
if (localFile.isEmpty()) if (localFile.isEmpty())
return; return;
@@ -116,16 +116,15 @@ void QmlProfilerDetailsRewriter::requestDetailsForLocation(int typeId,
m_pendingEvents.insert(localFile, {location, typeId}); m_pendingEvents.insert(localFile, {location, typeId});
} }
QString QmlProfilerDetailsRewriter::getLocalFile(const QString &remoteFile) Utils::FilePath QmlProfilerDetailsRewriter::getLocalFile(const QString &remoteFile)
{ {
const QString localFile = m_projectFinder.findFile(remoteFile).constFirst().toString(); const Utils::FilePath localFile = m_projectFinder.findFile(remoteFile).constFirst();
const QFileInfo fileInfo(localFile); if (!localFile.exists() || !localFile.isReadableFile())
if (!fileInfo.exists() || !fileInfo.isReadable()) return Utils::FilePath();
return QString();
if (!QmlJS::ModelManagerInterface::guessLanguageOfFile(localFile).isQmlLikeOrJsLanguage()) if (!QmlJS::ModelManagerInterface::guessLanguageOfFile(localFile).isQmlLikeOrJsLanguage())
return QString(); return Utils::FilePath();
return fileInfo.canonicalFilePath(); return localFile.canonicalPath();
} }
void QmlProfilerDetailsRewriter::reloadDocuments() void QmlProfilerDetailsRewriter::reloadDocuments()
@@ -182,7 +181,7 @@ void QmlProfilerDetailsRewriter::clear()
void QmlProfilerDetailsRewriter::documentReady(QmlJS::Document::Ptr doc) void QmlProfilerDetailsRewriter::documentReady(QmlJS::Document::Ptr doc)
{ {
const QString &fileName = doc->fileName(); const Utils::FilePath &fileName = doc->fileName();
auto first = m_pendingEvents.find(fileName); auto first = m_pendingEvents.find(fileName);
// this could be triggered by an unrelated reload in Creator // this could be triggered by an unrelated reload in Creator

View File

@@ -44,7 +44,7 @@ public:
void clear(); void clear();
void requestDetailsForLocation(int typeId, const QmlEventLocation &location); void requestDetailsForLocation(int typeId, const QmlEventLocation &location);
QString getLocalFile(const QString &remoteFile); Utils::FilePath getLocalFile(const QString &remoteFile);
void reloadDocuments(); void reloadDocuments();
void populateFileFinder(const ProjectExplorer::Target *target); void populateFileFinder(const ProjectExplorer::Target *target);
@@ -58,7 +58,7 @@ private:
int typeId; int typeId;
}; };
QMultiHash<QString, PendingEvent> m_pendingEvents; QMultiHash<Utils::FilePath, PendingEvent> m_pendingEvents;
Utils::FileInProjectFinder m_projectFinder; Utils::FileInProjectFinder m_projectFinder;
void rewriteDetailsForLocation(const QString &source, QmlJS::Document::Ptr doc, int typeId, void rewriteDetailsForLocation(const QString &source, QmlJS::Document::Ptr doc, int typeId,

View File

@@ -284,7 +284,7 @@ void QmlProfilerModelManager::populateFileFinder(const ProjectExplorer::Target *
d->detailsRewriter->populateFileFinder(target); d->detailsRewriter->populateFileFinder(target);
} }
QString QmlProfilerModelManager::findLocalFile(const QString &remoteFile) Utils::FilePath QmlProfilerModelManager::findLocalFile(const QString &remoteFile)
{ {
return d->detailsRewriter->getLocalFile(remoteFile); return d->detailsRewriter->getLocalFile(remoteFile);
} }
@@ -323,8 +323,10 @@ int QmlProfilerModelManager::appendEventType(QmlEventType &&type)
const QmlEventLocation &location = type.location(); const QmlEventLocation &location = type.location();
if (location.isValid()) { if (location.isValid()) {
const RangeType rangeType = type.rangeType(); const RangeType rangeType = type.rangeType();
const QmlEventLocation localLocation(d->detailsRewriter->getLocalFile(location.filename()), const QmlEventLocation localLocation(d->detailsRewriter->getLocalFile(location.filename())
location.line(), location.column()); .toString(),
location.line(),
location.column());
// location and type are invalid after this // location and type are invalid after this
const int typeIndex = TimelineTraceManager::appendEventType(std::move(type)); const int typeIndex = TimelineTraceManager::appendEventType(std::move(type));
@@ -350,9 +352,12 @@ void QmlProfilerModelManager::setEventType(int typeIndex, QmlEventType &&type)
// Only bindings and signal handlers need rewriting // Only bindings and signal handlers need rewriting
if (type.rangeType() == Binding || type.rangeType() == HandlingSignal) if (type.rangeType() == Binding || type.rangeType() == HandlingSignal)
d->detailsRewriter->requestDetailsForLocation(typeIndex, location); d->detailsRewriter->requestDetailsForLocation(typeIndex, location);
d->textMarkModel->addTextMarkId(typeIndex, QmlEventLocation( d->textMarkModel->addTextMarkId(typeIndex,
d->detailsRewriter->getLocalFile(location.filename()), QmlEventLocation(d->detailsRewriter
location.line(), location.column())); ->getLocalFile(location.filename())
.toString(),
location.line(),
location.column()));
} }
TimelineTraceManager::setEventType(typeIndex, std::move(type)); TimelineTraceManager::setEventType(typeIndex, std::move(type));

View File

@@ -70,7 +70,7 @@ public:
void finalize() override; void finalize() override;
void populateFileFinder(const ProjectExplorer::Target *target = nullptr); void populateFileFinder(const ProjectExplorer::Target *target = nullptr);
QString findLocalFile(const QString &remoteFile); Utils::FilePath findLocalFile(const QString &remoteFile);
static const char *featureName(ProfileFeature feature); static const char *featureName(ProfileFeature feature);

View File

@@ -420,8 +420,7 @@ void QmlProfilerTool::gotoSourceLocation(const QString &fileUrl, int lineNumber,
if (lineNumber < 0 || fileUrl.isEmpty()) if (lineNumber < 0 || fileUrl.isEmpty())
return; return;
const auto projectFileName = FilePath::fromString( const auto projectFileName = d->m_profilerModelManager->findLocalFile(fileUrl);
d->m_profilerModelManager->findLocalFile(fileUrl));
if (!projectFileName.exists() || !projectFileName.isReadableFile()) if (!projectFileName.exists() || !projectFileName.isReadableFile())
return; return;

View File

@@ -34,6 +34,7 @@
#include <projectexplorer/session.h> #include <projectexplorer/session.h>
#include <projectexplorer/kitinformation.h> #include <projectexplorer/kitinformation.h>
#include <projectexplorer/buildconfiguration.h> #include <projectexplorer/buildconfiguration.h>
#include <utils/filepath.h>
#include <QLibraryInfo> #include <QLibraryInfo>
#include <QTest> #include <QTest>
@@ -165,16 +166,16 @@ void QmlProfilerDetailsRewriterTest::testGetLocalFile()
Q_UNUSED(factory) Q_UNUSED(factory)
seedRewriter(); seedRewriter();
QCOMPARE(m_rewriter.getLocalFile("notthere.qml"), QString()); QCOMPARE(m_rewriter.getLocalFile("notthere.qml"), Utils::FilePath());
QCOMPARE(m_rewriter.getLocalFile("Test.qml"), QCOMPARE(m_rewriter.getLocalFile("Test.qml"),
QString::fromLatin1(":/qmlprofiler/tests/Test.qml")); Utils::FilePath::fromString(":/qmlprofiler/tests/Test.qml"));
QCOMPARE(m_rewriter.getLocalFile("qmlprofilerdetailsrewriter_test.cpp"), QString()); QCOMPARE(m_rewriter.getLocalFile("qmlprofilerdetailsrewriter_test.cpp"), Utils::FilePath());
} }
void QmlProfilerDetailsRewriterTest::testPopulateFileFinder() void QmlProfilerDetailsRewriterTest::testPopulateFileFinder()
{ {
m_rewriter.populateFileFinder(nullptr); m_rewriter.populateFileFinder(nullptr);
QCOMPARE(m_rewriter.getLocalFile("Test.qml"), QString()); QCOMPARE(m_rewriter.getLocalFile("Test.qml"), Utils::FilePath());
// Test that the rewriter will populate from available projects if given nullptr as parameter. // Test that the rewriter will populate from available projects if given nullptr as parameter.
DummyProject *project1 = new DummyProject(":/nix.nix"); DummyProject *project1 = new DummyProject(":/nix.nix");
@@ -183,7 +184,7 @@ void QmlProfilerDetailsRewriterTest::testPopulateFileFinder()
ProjectExplorer::SessionManager::addProject(project2); ProjectExplorer::SessionManager::addProject(project2);
m_rewriter.populateFileFinder(nullptr); m_rewriter.populateFileFinder(nullptr);
QCOMPARE(m_rewriter.getLocalFile("Test.qml"), QCOMPARE(m_rewriter.getLocalFile("Test.qml"),
QString::fromLatin1(":/qmlprofiler/tests/Test.qml")); Utils::FilePath::fromString(":/qmlprofiler/tests/Test.qml"));
ProjectExplorer::SessionManager::removeProject(project1); ProjectExplorer::SessionManager::removeProject(project1);
ProjectExplorer::SessionManager::removeProject(project2); ProjectExplorer::SessionManager::removeProject(project2);
@@ -208,7 +209,7 @@ void QmlProfilerDetailsRewriterTest::seedRewriter()
const QString content = QString::fromUtf8(file.readAll()); const QString content = QString::fromUtf8(file.readAll());
file.close(); file.close();
QmlJS::Document::MutablePtr doc = QmlJS::Document::create(filename, QmlJS::Dialect::Qml); QmlJS::Document::MutablePtr doc = QmlJS::Document::create(Utils::FilePath::fromString(filename), QmlJS::Dialect::Qml);
doc->setSource(content); doc->setSource(content);
doc->parse(); doc->parse();
QVERIFY(!doc->source().isEmpty()); QVERIFY(!doc->source().isEmpty());

View File

@@ -234,9 +234,15 @@ void QmlBuildSystem::parseProject(RefreshOptions options)
if (m_projectItem->targetDirectory().isEmpty()) if (m_projectItem->targetDirectory().isEmpty())
m_projectItem->setTargetDirectory(canonicalProjectDir().toString()); m_projectItem->setTargetDirectory(canonicalProjectDir().toString());
if (auto modelManager = QmlJS::ModelManagerInterface::instance()) if (auto modelManager = QmlJS::ModelManagerInterface::instance()) {
modelManager->updateSourceFiles(m_projectItem->files(), true); QStringList files = m_projectItem->files();
Utils::FilePaths filePaths(files.size());
std::transform(files.cbegin(),
files.cend(),
filePaths.begin(),
[](const QString &p) { return Utils::FilePath::fromString(p); });
modelManager->updateSourceFiles(filePaths, true);
}
QString mainFilePath = m_projectItem->mainFile(); QString mainFilePath = m_projectItem->mainFile();
if (!mainFilePath.isEmpty()) { if (!mainFilePath.isEmpty()) {
mainFilePath mainFilePath
@@ -522,8 +528,14 @@ void QmlBuildSystem::refreshFiles(const QSet<QString> &/*added*/, const QSet<QSt
} }
refresh(Files); refresh(Files);
if (!removed.isEmpty()) { if (!removed.isEmpty()) {
if (auto modelManager = QmlJS::ModelManagerInterface::instance()) if (auto modelManager = QmlJS::ModelManagerInterface::instance()) {
modelManager->removeFiles(Utils::toList(removed)); Utils::FilePaths pathsRemoved(removed.size());
std::transform(removed.cbegin(),
removed.cend(),
pathsRemoved.begin(),
[](const QString &s) { return Utils::FilePath::fromString(s); });
modelManager->removeFiles(pathsRemoved);
}
} }
refreshTargetDirectory(); refreshTargetDirectory();
} }

View File

@@ -171,8 +171,8 @@ bool QmlProjectPlugin::checkIfEditorIsuiQml(Core::IEditor *editor)
&& (editor->document()->id() == QmlJSEditor::Constants::C_QMLJSEDITOR_ID && (editor->document()->id() == QmlJSEditor::Constants::C_QMLJSEDITOR_ID
|| editor->document()->id() == QmlJSEditor::Constants::C_QTQUICKDESIGNEREDITOR_ID)) { || editor->document()->id() == QmlJSEditor::Constants::C_QTQUICKDESIGNEREDITOR_ID)) {
QmlJS::ModelManagerInterface *modelManager = QmlJS::ModelManagerInterface::instance(); QmlJS::ModelManagerInterface *modelManager = QmlJS::ModelManagerInterface::instance();
QmlJS::Document::Ptr document = QmlJS::Document::Ptr document = modelManager->ensuredGetDocumentForPath(
modelManager->ensuredGetDocumentForPath(editor->document()->filePath().toString()); editor->document()->filePath());
if (!document.isNull()) if (!document.isNull())
return document->language() == QmlJS::Dialect::QmlQtQuick2Ui; return document->language() == QmlJS::Dialect::QmlQtQuick2Ui;
} }

View File

@@ -45,7 +45,7 @@ QmlJsTodoItemsScanner::QmlJsTodoItemsScanner(const KeywordList &keywordList, QOb
setParams(keywordList); setParams(keywordList);
} }
bool QmlJsTodoItemsScanner::shouldProcessFile(const QString &fileName) bool QmlJsTodoItemsScanner::shouldProcessFile(const Utils::FilePath &fileName)
{ {
QmlJS::ModelManagerInterface *modelManager = QmlJS::ModelManagerInterface::instance(); QmlJS::ModelManagerInterface *modelManager = QmlJS::ModelManagerInterface::instance();
foreach (const QmlJS::ModelManagerInterface::ProjectInfo &info, modelManager->projectInfos()) { foreach (const QmlJS::ModelManagerInterface::ProjectInfo &info, modelManager->projectInfos()) {
@@ -63,8 +63,8 @@ void QmlJsTodoItemsScanner::scannerParamsChanged()
QmlJS::ModelManagerInterface *modelManager = QmlJS::ModelManagerInterface::instance(); QmlJS::ModelManagerInterface *modelManager = QmlJS::ModelManagerInterface::instance();
QStringList filesToBeUpdated; Utils::FilePaths filesToBeUpdated;
foreach (const QmlJS::ModelManagerInterface::ProjectInfo &info, modelManager->projectInfos()) for (const QmlJS::ModelManagerInterface::ProjectInfo &info : modelManager->projectInfos())
filesToBeUpdated << info.sourceFiles; filesToBeUpdated << info.sourceFiles;
modelManager->updateSourceFiles(filesToBeUpdated, false); modelManager->updateSourceFiles(filesToBeUpdated, false);
@@ -89,12 +89,12 @@ void QmlJsTodoItemsScanner::processDocument(QmlJS::Document::Ptr doc)
quint32 startLine = sourceLocation.startLine; quint32 startLine = sourceLocation.startLine;
for (int j = 0; j < commentLines.count(); ++j) { for (int j = 0; j < commentLines.count(); ++j) {
const QString &commentLine = commentLines.at(j); const QString &commentLine = commentLines.at(j);
processCommentLine(doc->fileName(), commentLine, startLine + j, itemList); processCommentLine(doc->fileName().toString(), commentLine, startLine + j, itemList);
} }
} }
emit itemsFetched(doc->fileName(), itemList); emit itemsFetched(doc->fileName().toString(), itemList);
} }
} }

View File

@@ -28,6 +28,7 @@
#include "todoitemsscanner.h" #include "todoitemsscanner.h"
#include <utils/filepath.h>
#include <qmljs/qmljsmodelmanagerinterface.h> #include <qmljs/qmljsmodelmanagerinterface.h>
namespace Todo { namespace Todo {
@@ -39,7 +40,7 @@ public:
explicit QmlJsTodoItemsScanner(const KeywordList &keywordList, QObject *parent = nullptr); explicit QmlJsTodoItemsScanner(const KeywordList &keywordList, QObject *parent = nullptr);
protected: protected:
bool shouldProcessFile(const QString &fileName); bool shouldProcessFile(const Utils::FilePath &fileName);
void scannerParamsChanged() override; void scannerParamsChanged() override;
private: private:

View File

@@ -124,10 +124,11 @@ void tst_Check::test_data()
void tst_Check::test() void tst_Check::test()
{ {
QFETCH(QString, path); QFETCH(QString, path);
Utils::FilePath pathPath = Utils::FilePath::fromString(path);
auto mm = ModelManagerInterface::instance(); auto mm = ModelManagerInterface::instance();
Snapshot snapshot = mm->snapshot(); Snapshot snapshot = mm->snapshot();
Document::MutablePtr doc = Document::create(path, Dialect::Qml); Document::MutablePtr doc = Document::create(pathPath, Dialect::Qml);
QFile file(doc->fileName()); QFile file(doc->fileName().toString());
file.open(QFile::ReadOnly | QFile::Text); file.open(QFile::ReadOnly | QFile::Text);
doc->setSource(QString::fromUtf8(file.readAll())); doc->setSource(QString::fromUtf8(file.readAll()));
file.close(); file.close();

View File

@@ -47,6 +47,7 @@
#include <qmljs/qmljsmodelmanagerinterface.h> #include <qmljs/qmljsmodelmanagerinterface.h>
#include <qmljstools/qmljssemanticinfo.h> #include <qmljstools/qmljssemanticinfo.h>
#include <extensionsystem/pluginmanager.h> #include <extensionsystem/pluginmanager.h>
#include <utils/filepath.h>
using namespace QmlJS; using namespace QmlJS;
using namespace QmlJS::AST; using namespace QmlJS::AST;
@@ -77,7 +78,7 @@ static TestData testData(const QString &path) {
const QString content = QString::fromUtf8(file.readAll()); const QString content = QString::fromUtf8(file.readAll());
file.close(); file.close();
Document::MutablePtr doc = Document::create(path, Dialect::Qml); Document::MutablePtr doc = Document::create(Utils::FilePath::fromString(path), Dialect::Qml);
doc->setSource(content); doc->setSource(content);
doc->parse(); doc->parse();
const QString nSemantic = getValue(content, "//\\s*ExpectedSemanticMessages: (\\d+)"); const QString nSemantic = getValue(content, "//\\s*ExpectedSemanticMessages: (\\d+)");

View File

@@ -75,11 +75,12 @@ struct TestData
static TestData testData(const QString &path) static TestData testData(const QString &path)
{ {
QFile file(path); QFile file(path);
Utils::FilePath pathPath = Utils::FilePath::fromString(path);
file.open(QFile::ReadOnly | QFile::Text); file.open(QFile::ReadOnly | QFile::Text);
const QString content = QString::fromUtf8(file.readAll()); const QString content = QString::fromUtf8(file.readAll());
file.close(); file.close();
Document::MutablePtr doc = Document::create(path, Dialect::Qml); Document::MutablePtr doc = Document::create(pathPath, Dialect::Qml);
doc->setSource(content); doc->setSource(content);
doc->parse(); doc->parse();
const QString nSemantic = getValue(content, "//\\s*ExpectedSemanticMessages: (\\d+)"); const QString nSemantic = getValue(content, "//\\s*ExpectedSemanticMessages: (\\d+)");

View File

@@ -33,6 +33,7 @@
#include <QStringList> #include <QStringList>
#include <QtTest> #include <QtTest>
#include <utils/algorithm.h>
#include <qmljs/qmljsbind.h> #include <qmljs/qmljsbind.h>
#include <qmljs/qmljscheck.h> #include <qmljs/qmljscheck.h>
#include <qmljs/qmljscontext.h> #include <qmljs/qmljscontext.h>
@@ -71,14 +72,15 @@ private:
void scanDirectory(const QString &dir) void scanDirectory(const QString &dir)
{ {
auto dirPath = Utils::FilePath::fromString(dir);
QFutureInterface<void> result; QFutureInterface<void> result;
PathsAndLanguages paths; PathsAndLanguages paths;
paths.maybeInsert(Utils::FilePath::fromString(dir), Dialect::Qml); paths.maybeInsert(dirPath, Dialect::Qml);
ModelManagerInterface::importScan(result, ModelManagerInterface::workingCopy(), paths, ModelManagerInterface::importScan(result, ModelManagerInterface::workingCopy(), paths,
ModelManagerInterface::instance(), false); ModelManagerInterface::instance(), false);
ModelManagerInterface::instance()->test_joinAllThreads(); ModelManagerInterface::instance()->test_joinAllThreads();
ViewerContext vCtx; ViewerContext vCtx;
vCtx.paths.append(dir); vCtx.paths.append(dirPath);
Snapshot snap = ModelManagerInterface::instance()->snapshot(); Snapshot snap = ModelManagerInterface::instance()->snapshot();
ImportDependencies *iDeps = snap.importDependencies(); ImportDependencies *iDeps = snap.importDependencies();
@@ -185,15 +187,18 @@ void tst_ImportCheck::test()
QFETCH(QStringList, expectedLibraries); QFETCH(QStringList, expectedLibraries);
QFETCH(QStringList, expectedFiles); QFETCH(QStringList, expectedFiles);
const auto pathPaths = Utils::transform(paths, [](const QString &s) {
return Utils::FilePath::fromString(s);
});
QFutureInterface<void> result; QFutureInterface<void> result;
PathsAndLanguages lPaths; PathsAndLanguages lPaths;
foreach (const QString &path, paths) for (const Utils::FilePath &path : pathPaths)
lPaths.maybeInsert(Utils::FilePath::fromString(path), Dialect::Qml); lPaths.maybeInsert(path, Dialect::Qml);
ModelManagerInterface::importScan(result, ModelManagerInterface::workingCopy(), lPaths, ModelManagerInterface::importScan(result, ModelManagerInterface::workingCopy(), lPaths,
ModelManagerInterface::instance(), false); ModelManagerInterface::instance(), false);
ModelManagerInterface::instance()->test_joinAllThreads(); ModelManagerInterface::instance()->test_joinAllThreads();
ViewerContext vCtx; ViewerContext vCtx;
vCtx.paths.append(paths); vCtx.paths.append(pathPaths);
Snapshot snap = ModelManagerInterface::instance()->snapshot(); Snapshot snap = ModelManagerInterface::instance()->snapshot();
ImportDependencies *iDeps = snap.importDependencies(); ImportDependencies *iDeps = snap.importDependencies();
@@ -260,6 +265,7 @@ void tst_ImportCheck::importTypes()
QFETCH(QString, qmlFile); QFETCH(QString, qmlFile);
QFETCH(QString, importPath); QFETCH(QString, importPath);
QFETCH(QStringList, expectedTypes); QFETCH(QStringList, expectedTypes);
auto qmlFilePath = Utils::FilePath::fromString(qmlFile);
// full reset // full reset
delete ModelManagerInterface::instance(); delete ModelManagerInterface::instance();
@@ -271,11 +277,11 @@ void tst_ImportCheck::importTypes()
modelManager->setDefaultProject(defaultProject, nullptr); modelManager->setDefaultProject(defaultProject, nullptr);
modelManager->activateScan(); modelManager->activateScan();
modelManager->updateSourceFiles(QStringList(qmlFile), false); modelManager->updateSourceFiles(Utils::FilePaths({qmlFilePath}), false);
modelManager->test_joinAllThreads(); modelManager->test_joinAllThreads();
Snapshot snapshot = modelManager->newestSnapshot(); Snapshot snapshot = modelManager->newestSnapshot();
Document::Ptr doc = snapshot.document(qmlFile); Document::Ptr doc = snapshot.document(qmlFilePath);
// It's unfortunate, but nowadays linking can trigger async module loads, // It's unfortunate, but nowadays linking can trigger async module loads,
// so do it once to start the process, then do it again for real once the // so do it once to start the process, then do it again for real once the
@@ -288,7 +294,7 @@ void tst_ImportCheck::importTypes()
getContext(); getContext();
modelManager->test_joinAllThreads(); modelManager->test_joinAllThreads();
snapshot = modelManager->newestSnapshot(); snapshot = modelManager->newestSnapshot();
doc = snapshot.document(qmlFile); doc = snapshot.document(qmlFilePath);
ContextPtr context = getContext(); ContextPtr context = getContext();
@@ -346,6 +352,7 @@ void tst_ImportCheck::moduleMapping()
QFETCH(StrStrHash, moduleMappings); QFETCH(StrStrHash, moduleMappings);
QFETCH(QStringList, expectedTypes); QFETCH(QStringList, expectedTypes);
QFETCH(bool, expectedResult); QFETCH(bool, expectedResult);
auto qmlFilePath = Utils::FilePath::fromString(qmlFile);
// full reset // full reset
delete ModelManagerInterface::instance(); delete ModelManagerInterface::instance();
@@ -363,11 +370,11 @@ void tst_ImportCheck::moduleMapping()
scanDirectory(importPath); scanDirectory(importPath);
scanDirectory(qtQuickImportPath); scanDirectory(qtQuickImportPath);
modelManager->updateSourceFiles(QStringList(qmlFile), false); modelManager->updateSourceFiles(Utils::FilePaths({qmlFilePath}), false);
modelManager->test_joinAllThreads(); modelManager->test_joinAllThreads();
Snapshot snapshot = modelManager->newestSnapshot(); Snapshot snapshot = modelManager->newestSnapshot();
Document::Ptr doc = snapshot.document(qmlFile); Document::Ptr doc = snapshot.document(qmlFilePath);
QVERIFY(!doc.isNull()); QVERIFY(!doc.isNull());
// It's unfortunate, but nowadays linking can trigger async module loads, // It's unfortunate, but nowadays linking can trigger async module loads,
@@ -381,7 +388,7 @@ void tst_ImportCheck::moduleMapping()
getContext(); getContext();
modelManager->test_joinAllThreads(); modelManager->test_joinAllThreads();
snapshot = modelManager->newestSnapshot(); snapshot = modelManager->newestSnapshot();
doc = snapshot.document(qmlFile); doc = snapshot.document(qmlFilePath);
ContextPtr context = getContext(); ContextPtr context = getContext();

View File

@@ -115,7 +115,7 @@ public:
{ {
//loadQmlTypeDescriptions(resourcePath()); //loadQmlTypeDescriptions(resourcePath());
} }
void updateSourceFiles(const QStringList &files, bool emitDocumentOnDiskChanged) void updateSourceFiles(const QList<Utils::FilePath> &files, bool emitDocumentOnDiskChanged)
{ {
refreshSourceFiles(files, emitDocumentOnDiskChanged).waitForFinished(); refreshSourceFiles(files, emitDocumentOnDiskChanged).waitForFinished();
} }

View File

@@ -1,5 +1,5 @@
add_qtc_test(tst_qml_reformatter add_qtc_test(tst_qml_reformatter
DEPENDS QmlJS DEPENDS QmlJS Utils
DEFINES DEFINES
QT_CREATOR QT_CREATOR
QTCREATORDIR="${PROJECT_SOURCE_DIR}" QTCREATORDIR="${PROJECT_SOURCE_DIR}"

View File

@@ -35,6 +35,7 @@
#include <qmljs/qmljsreformatter.h> #include <qmljs/qmljsreformatter.h>
#include <qmljs/parser/qmljsast_p.h> #include <qmljs/parser/qmljsast_p.h>
#include <qmljs/parser/qmljsengine_p.h> #include <qmljs/parser/qmljsengine_p.h>
#include <utils/filepath.h>
#include <QtTest> #include <QtTest>
#include <algorithm> #include <algorithm>
@@ -74,9 +75,10 @@ void tst_Reformatter::test_data()
void tst_Reformatter::test() void tst_Reformatter::test()
{ {
QFETCH(QString, path); QFETCH(QString, path);
Utils::FilePath fPath = Utils::FilePath::fromString(path);
Document::MutablePtr doc = Document::create(path, ModelManagerInterface::guessLanguageOfFile(path)); Document::MutablePtr doc = Document::create(fPath, ModelManagerInterface::guessLanguageOfFile(fPath));
QFile file(doc->fileName()); QFile file(doc->fileName().toString());
file.open(QFile::ReadOnly | QFile::Text); file.open(QFile::ReadOnly | QFile::Text);
QString source = QString::fromUtf8(file.readAll()); QString source = QString::fromUtf8(file.readAll());
doc->setSource(source); doc->setSource(source);