From 51a9ff7d4ead754838b675c3184ea7f56e0eb2fe Mon Sep 17 00:00:00 2001 From: Kai Koehne <kai.koehne@nokia.com> Date: Tue, 19 Jul 2011 17:48:57 +0200 Subject: [PATCH] Qml Tooling: Fix debugging & profiling of .qml files loaded from resources Don't expect that every url specifying a file is a local file url. Instead let FileInProjectFinder handle urls with other schemes gracefully, too. Change-Id: I72457d502ff1caf52f588e8ec41ab260882d1cf5 Reviewed-on: http://codereview.qt.nokia.com/1840 Reviewed-by: Qt Sanity Bot <qt_sanity_bot@ovi.com> Reviewed-by: Christiaan Janssen <christiaan.janssen@nokia.com> --- src/libs/utils/fileinprojectfinder.cpp | 33 +++++++++++++++---- src/libs/utils/fileinprojectfinder.h | 3 +- src/plugins/debugger/qml/qmlengine.cpp | 19 ++--------- src/plugins/debugger/qml/qmlengine.h | 2 +- .../qmljsinspector/qmljsclientproxy.cpp | 10 +++--- src/plugins/qmljsinspector/qmljsinspector.cpp | 10 ++---- src/plugins/qmljsinspector/qmljsinspector.h | 2 +- .../qmlprofiler/qmlprofilereventview.cpp | 6 ++-- src/plugins/qmlprofiler/qmlprofilertool.cpp | 3 +- src/plugins/qtsupport/qtoutputformatter.cpp | 10 +++--- 10 files changed, 51 insertions(+), 47 deletions(-) diff --git a/src/libs/utils/fileinprojectfinder.cpp b/src/libs/utils/fileinprojectfinder.cpp index f8253e48f1f..aa57785dd57 100644 --- a/src/libs/utils/fileinprojectfinder.cpp +++ b/src/libs/utils/fileinprojectfinder.cpp @@ -34,13 +34,14 @@ #include <utils/qtcassert.h> #include <QtCore/QFileInfo> +#include <QtCore/QUrl> namespace Utils { /*! \class Utils::FileInProjectFinder - \brief Helper class to find the 'original' file in the project directory for a given file path. + \brief Helper class to find the 'original' file in the project directory for a given file url. Often files are copied in the build + deploy process. findFile() searches for an existing file in the project directory for a given file path: @@ -86,17 +87,31 @@ void FileInProjectFinder::setProjectFiles(const QStringList &projectFiles) } /** - Returns the best match for the given originalPath in the project directory. + Returns the best match for the given file url in the project directory. - The method first checks whether the originalPath inside the project directory exists. + The method first checks whether the file inside the project directory exists. If not, the leading directory in the path is stripped, and the - now shorter - path is checked for existence. This continues until either the file is found, or the relative path - does not contain any directories any more: In this case the originalPath is returned. + does not contain any directories any more: In this case the path of the url is returned. Second, we walk the list of project files, and search for a file name match there. */ -QString FileInProjectFinder::findFile(const QString &originalPath, bool *success) const +QString FileInProjectFinder::findFile(const QUrl &fileUrl, bool *success) const { + QString originalPath; + if (fileUrl.isLocalFile()) { + originalPath = fileUrl.toLocalFile(); + } else { + // strip e.g. leading qrc:// + originalPath = fileUrl.path(); + } + + if (originalPath.isEmpty()) { + if (success) + success = false; + return originalPath; + } + if (!m_projectDir.isEmpty()) { int prefixToIgnore = -1; const QChar separator = QLatin1Char('/'); @@ -132,8 +147,14 @@ QString FileInProjectFinder::findFile(const QString &originalPath, bool *success // Strip directories one by one from the beginning of the path, // and see if the new relative path exists in the build directory. - if (prefixToIgnore < 0) + if (prefixToIgnore < 0) { + if (!QFileInfo(originalPath).isAbsolute() + && !originalPath.startsWith(separator)) { + prefixToIgnore = 0; + } else { prefixToIgnore = originalPath.indexOf(separator); + } + } while (prefixToIgnore != -1) { QString candidate = originalPath; candidate.remove(0, prefixToIgnore); diff --git a/src/libs/utils/fileinprojectfinder.h b/src/libs/utils/fileinprojectfinder.h index cecbe0cc6dc..aff9b214d3e 100644 --- a/src/libs/utils/fileinprojectfinder.h +++ b/src/libs/utils/fileinprojectfinder.h @@ -37,6 +37,7 @@ #include <QtCore/QHash> #include <QtCore/QStringList> +#include <QtCore/QUrl> namespace Utils { @@ -50,7 +51,7 @@ public: void setProjectFiles(const QStringList &projectFiles); - QString findFile(const QString &originalPath, bool *success = 0) const; + QString findFile(const QUrl &fileUrl, bool *success = 0) const; private: QString m_projectDir; diff --git a/src/plugins/debugger/qml/qmlengine.cpp b/src/plugins/debugger/qml/qmlengine.cpp index fb7c80da7a7..4634729ec7f 100644 --- a/src/plugins/debugger/qml/qmlengine.cpp +++ b/src/plugins/debugger/qml/qmlengine.cpp @@ -766,27 +766,14 @@ unsigned QmlEngine::debuggerCapabilities() const | AddWatcherCapability;*/ } -QString QmlEngine::toFileInProject(const QString &fileUrl) +QString QmlEngine::toFileInProject(const QUrl &fileUrl) { - if (fileUrl.isEmpty()) - return fileUrl; - - const QString path = QUrl(fileUrl).toLocalFile(); - if (path.isEmpty()) - return fileUrl; - if (d->fileFinder.projectDirectory().isEmpty()) { d->fileFinder.setProjectDirectory(startParameters().projectSourceDirectory); d->fileFinder.setProjectFiles(startParameters().projectSourceFiles); } - // Try to find file with biggest common path in source directory - bool fileFound = false; - QString fileInProject = d->fileFinder.findFile(path, &fileFound); - if (fileFound) - return fileInProject; - - return path; + return d->fileFinder.findFile(fileUrl); } void QmlEngine::messageReceived(const QByteArray &message) @@ -817,7 +804,7 @@ void QmlEngine::messageReceived(const QByteArray &message) StackFrame frame; frame.line = stackFrames.at(i).lineNumber; frame.function = stackFrames.at(i).functionName; - frame.file = toFileInProject(stackFrames.at(i).fileUrl); + frame.file = toFileInProject(QUrl(stackFrames.at(i).fileUrl)); frame.usable = QFileInfo(frame.file).isReadable(); frame.level = i + 1; ideStackFrames << frame; diff --git a/src/plugins/debugger/qml/qmlengine.h b/src/plugins/debugger/qml/qmlengine.h index c4c7e421d59..9dd2b82e219 100644 --- a/src/plugins/debugger/qml/qmlengine.h +++ b/src/plugins/debugger/qml/qmlengine.h @@ -153,7 +153,7 @@ private: LogReceive }; void logMessage(LogDirection direction, const QString &str); - QString toFileInProject(const QString &file); + QString toFileInProject(const QUrl &fileUrl); private: friend class QmlCppEngine; diff --git a/src/plugins/qmljsinspector/qmljsclientproxy.cpp b/src/plugins/qmljsinspector/qmljsclientproxy.cpp index aff9c46e7ff..e2257459d86 100644 --- a/src/plugins/qmljsinspector/qmljsclientproxy.cpp +++ b/src/plugins/qmljsinspector/qmljsclientproxy.cpp @@ -510,23 +510,23 @@ void ClientProxy::objectTreeFetched(QDeclarativeDebugQuery::State state) void ClientProxy::buildDebugIdHashRecursive(const QDeclarativeDebugObjectReference& ref) { - QString filename = ref.source().url().toLocalFile(); + QUrl fileUrl = ref.source().url(); int lineNum = ref.source().lineNumber(); int colNum = ref.source().columnNumber(); int rev = 0; // handle the case where the url contains the revision number encoded. (for object created by the debugger) static QRegExp rx("(.*)_(\\d+):(\\d+)$"); - if (rx.exactMatch(filename)) { - filename = rx.cap(1); + if (rx.exactMatch(fileUrl.path())) { + fileUrl.setPath(rx.cap(1)); rev = rx.cap(2).toInt(); lineNum += rx.cap(3).toInt() - 1; } - filename = InspectorUi::instance()->findFileInProject(filename); + const QString filePath = InspectorUi::instance()->findFileInProject(fileUrl); // append the debug ids in the hash - m_debugIdHash[qMakePair<QString, int>(filename, rev)][qMakePair<int, int>(lineNum, colNum)].append(ref.debugId()); + m_debugIdHash[qMakePair<QString, int>(filePath, rev)][qMakePair<int, int>(lineNum, colNum)].append(ref.debugId()); foreach (const QDeclarativeDebugObjectReference &it, ref.children()) buildDebugIdHashRecursive(it); diff --git a/src/plugins/qmljsinspector/qmljsinspector.cpp b/src/plugins/qmljsinspector/qmljsinspector.cpp index 5a2ffbdcc55..bc204ded6ad 100644 --- a/src/plugins/qmljsinspector/qmljsinspector.cpp +++ b/src/plugins/qmljsinspector/qmljsinspector.cpp @@ -676,12 +676,8 @@ void InspectorUi::gotoObjectReferenceDefinition(const QDeclarativeDebugObjectRef } QDeclarativeDebugFileReference source = obj.source(); - QString fileName = source.url().toLocalFile(); - if (source.lineNumber() < 0 || !QFile::exists(fileName)) - return; - - fileName = m_projectFinder.findFile(fileName); + const QString fileName = m_projectFinder.findFile(source.url()); Core::EditorManager *editorManager = Core::EditorManager::instance(); Core::IEditor *currentEditor = editorManager->currentEditor(); @@ -789,9 +785,9 @@ InspectorUi *InspectorUi::instance() return m_instance; } -QString InspectorUi::findFileInProject(const QString &originalPath) const +QString InspectorUi::findFileInProject(const QUrl &url) const { - return m_projectFinder.findFile(originalPath); + return m_projectFinder.findFile(url); } void InspectorUi::setApplyChangesToQmlInspector(bool applyChanges) diff --git a/src/plugins/qmljsinspector/qmljsinspector.h b/src/plugins/qmljsinspector/qmljsinspector.h index 697011f41e8..72762e363b7 100644 --- a/src/plugins/qmljsinspector/qmljsinspector.h +++ b/src/plugins/qmljsinspector/qmljsinspector.h @@ -95,7 +95,7 @@ public: static InspectorUi *instance(); - QString findFileInProject(const QString &file) const; + QString findFileInProject(const QUrl &fileUrl) const; void setupUi(); bool isConnected() const; diff --git a/src/plugins/qmlprofiler/qmlprofilereventview.cpp b/src/plugins/qmlprofiler/qmlprofilereventview.cpp index 7bfa178fd73..62c990716ac 100644 --- a/src/plugins/qmlprofiler/qmlprofilereventview.cpp +++ b/src/plugins/qmlprofiler/qmlprofilereventview.cpp @@ -146,7 +146,7 @@ void QmlProfilerEventStatistics::addRangedEvent(int type, int nestingLevel, int Q_UNUSED(nestingInType); const QChar colon = QLatin1Char(':'); - QString localName, displayName, location, details; + QString displayName, location, details; if (data.isEmpty()) details = tr("Source code not available"); @@ -165,8 +165,8 @@ void QmlProfilerEventStatistics::addRangedEvent(int type, int nestingLevel, int displayName = tr("<bytecode>"); location = QString("--:%1:%2").arg(QString::number(type), details); } else { - localName = QUrl(fileName).toLocalFile(); - displayName = localName.mid(localName.lastIndexOf(QChar('/')) + 1) + colon + QString::number(line); + const QString filePath = QUrl(fileName).path(); + displayName = filePath.mid(filePath.lastIndexOf(QChar('/')) + 1) + colon + QString::number(line); location = fileName+colon+QString::number(line); } diff --git a/src/plugins/qmlprofiler/qmlprofilertool.cpp b/src/plugins/qmlprofiler/qmlprofilertool.cpp index a72872bce04..50d31c25603 100644 --- a/src/plugins/qmlprofiler/qmlprofilertool.cpp +++ b/src/plugins/qmlprofiler/qmlprofilertool.cpp @@ -420,8 +420,7 @@ void QmlProfilerTool::gotoSourceLocation(const QString &fileUrl, int lineNumber) if (lineNumber < 0 || fileUrl.isEmpty()) return; - const QString fileName = QUrl(fileUrl).toLocalFile(); - const QString projectFileName = d->m_projectFinder.findFile(fileName); + const QString projectFileName = d->m_projectFinder.findFile(fileUrl); Core::EditorManager *editorManager = Core::EditorManager::instance(); Core::IEditor *editor = editorManager->openEditor(projectFileName); diff --git a/src/plugins/qtsupport/qtoutputformatter.cpp b/src/plugins/qtsupport/qtoutputformatter.cpp index 036521ac529..6d75f159096 100644 --- a/src/plugins/qtsupport/qtoutputformatter.cpp +++ b/src/plugins/qtsupport/qtoutputformatter.cpp @@ -196,11 +196,11 @@ void QtOutputFormatter::handleLink(const QString &href) ":(\\d+)$")); // column if (qmlLineColumnLink.indexIn(href) != -1) { - const QString fileName = QUrl(qmlLineColumnLink.cap(1)).toLocalFile(); + const QUrl fileUrl = QUrl(qmlLineColumnLink.cap(1)); const int line = qmlLineColumnLink.cap(2).toInt(); const int column = qmlLineColumnLink.cap(3).toInt(); - TextEditor::BaseTextEditorWidget::openEditorAt(m_projectFinder.findFile(fileName), line, column - 1); + TextEditor::BaseTextEditorWidget::openEditorAt(m_projectFinder.findFile(fileUrl), line, column - 1); return; } @@ -209,9 +209,9 @@ void QtOutputFormatter::handleLink(const QString &href) ":(\\d+)$")); // line if (qmlLineLink.indexIn(href) != -1) { - const QString fileName = QUrl(qmlLineLink.cap(1)).toLocalFile(); + const QUrl fileUrl = QUrl(qmlLineLink.cap(1)); const int line = qmlLineLink.cap(2).toInt(); - TextEditor::BaseTextEditorWidget::openEditorAt(m_projectFinder.findFile(fileName), line); + TextEditor::BaseTextEditorWidget::openEditorAt(m_projectFinder.findFile(fileUrl), line); return; } @@ -253,7 +253,7 @@ void QtOutputFormatter::handleLink(const QString &href) } } else if (!fi.exists()) { // map possible on-device path to source path - fileName = m_projectFinder.findFile(fileName); + fileName = m_projectFinder.findFile(QUrl::fromLocalFile(fileName)); } TextEditor::BaseTextEditorWidget::openEditorAt(fileName, line, 0); return; -- GitLab