aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorXavier BESSON <developer@xavi-b.fr>2022-12-07 23:19:07 +0100
committerXavier BESSON (Personal) <developer@xavi-b.fr>2023-12-20 15:03:39 +0000
commit90368e2bba9c71ab6e3fc0b106f1a74942866ebb (patch)
tree409c166603d54e90270b95e6caac3b9b2d773600
parent42c1b1587484b5dd6dc562e7fd80dacbd041bd33 (diff)
QmlJsEditor: navigate from QML code to C++ code
Fixes: QTCREATORBUG-28086 Change-Id: I00acfe49b8e74aa057cb59d8c951d477f8ad487e Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
-rw-r--r--src/libs/languageutils/fakemetaobject.cpp5
-rw-r--r--src/libs/languageutils/fakemetaobject.h4
-rw-r--r--src/libs/qmljs/qmljsinterpreter.cpp8
-rw-r--r--src/libs/qmljs/qmljsinterpreter.h2
-rw-r--r--src/libs/qmljs/qmljstypedescriptionreader.cpp2
-rw-r--r--src/plugins/qmljseditor/qmljseditor.cpp38
6 files changed, 52 insertions, 7 deletions
diff --git a/src/libs/languageutils/fakemetaobject.cpp b/src/libs/languageutils/fakemetaobject.cpp
index c5e577b6e30..4c553cdc7b5 100644
--- a/src/libs/languageutils/fakemetaobject.cpp
+++ b/src/libs/languageutils/fakemetaobject.cpp
@@ -269,6 +269,11 @@ QString FakeMetaObject::className() const
void FakeMetaObject::setClassName(const QString &name)
{ m_className = name; }
+QString FakeMetaObject::filePath() const
+{ return m_filePath; }
+void FakeMetaObject::setFilePath(const QString &path)
+{ m_filePath = path; }
+
void FakeMetaObject::addExport(const QString &name, const QString &package, ComponentVersion version)
{
Export exp;
diff --git a/src/libs/languageutils/fakemetaobject.h b/src/libs/languageutils/fakemetaobject.h
index c9fcb260110..2eb2ecfb22d 100644
--- a/src/libs/languageutils/fakemetaobject.h
+++ b/src/libs/languageutils/fakemetaobject.h
@@ -139,6 +139,7 @@ public:
private:
QString m_className;
+ QString m_filePath;
QList<Export> m_exports;
QString m_superName;
QList<FakeMetaEnum> m_enums;
@@ -160,6 +161,9 @@ public:
QString className() const;
void setClassName(const QString &name);
+ QString filePath() const;
+ void setFilePath(const QString &path);
+
void addExport(const QString &name, const QString &package, ComponentVersion version);
void setExportMetaObjectRevision(int exportIndex, int metaObjectRevision);
const QList<Export> exports() const;
diff --git a/src/libs/qmljs/qmljsinterpreter.cpp b/src/libs/qmljs/qmljsinterpreter.cpp
index 9448ef39b01..5d687d5cd74 100644
--- a/src/libs/qmljs/qmljsinterpreter.cpp
+++ b/src/libs/qmljs/qmljsinterpreter.cpp
@@ -251,6 +251,14 @@ const CppComponentValue *CppComponentValue::asCppComponentValue() const
return this;
}
+bool CppComponentValue::getSourceLocation(Utils::FilePath *fileName, int *line, int *column) const
+{
+ *fileName = Utils::FilePath::fromString(m_metaObject->filePath());
+ *line = 0;
+ *column = 0;
+ return true;
+}
+
void CppComponentValue::processMembers(MemberProcessor *processor) const
{
// process the meta enums
diff --git a/src/libs/qmljs/qmljsinterpreter.h b/src/libs/qmljs/qmljsinterpreter.h
index 8ca9f4ec26c..3fcce78d117 100644
--- a/src/libs/qmljs/qmljsinterpreter.h
+++ b/src/libs/qmljs/qmljsinterpreter.h
@@ -573,6 +573,8 @@ public:
const CppComponentValue *asCppComponentValue() const override;
+ bool getSourceLocation(Utils::FilePath *fileName, int *line, int *column) const override;
+
void processMembers(MemberProcessor *processor) const override;
const Value *valueForCppName(const QString &typeName) const;
diff --git a/src/libs/qmljs/qmljstypedescriptionreader.cpp b/src/libs/qmljs/qmljstypedescriptionreader.cpp
index d8d19eefa3c..9d67ad05b23 100644
--- a/src/libs/qmljs/qmljstypedescriptionreader.cpp
+++ b/src/libs/qmljs/qmljstypedescriptionreader.cpp
@@ -197,6 +197,8 @@ void TypeDescriptionReader::readComponent(UiObjectDefinition *ast)
QString name = toString(script->qualifiedId);
if (name == QLatin1String("name")) {
fmo->setClassName(readStringBinding(script));
+ } else if (name == QLatin1String("file")) {
+ fmo->setFilePath(readStringBinding(script));
} else if (name == QLatin1String("prototype")) {
fmo->setSuperclassName(readStringBinding(script));
} else if (name == QLatin1String("defaultProperty")) {
diff --git a/src/plugins/qmljseditor/qmljseditor.cpp b/src/plugins/qmljseditor/qmljseditor.cpp
index 8219243c29d..710663ae364 100644
--- a/src/plugins/qmljseditor/qmljseditor.cpp
+++ b/src/plugins/qmljseditor/qmljseditor.cpp
@@ -789,13 +789,18 @@ void QmlJSEditorWidget::findLinkAt(const QTextCursor &cursor,
return;
}
+ const ProjectExplorer::Project * const project = ProjectExplorer::ProjectTree::currentProject();
+ ProjectExplorer::ProjectNode* projectRootNode = nullptr;
+ if (project) {
+ projectRootNode = project->rootProjectNode();
+ }
+
// string literals that could refer to a file link to them
if (auto literal = cast<const StringLiteral *>(node)) {
const QString &text = literal->value.toString();
if (text.startsWith("qrc:/")) {
- const ProjectExplorer::Project * const project = ProjectExplorer::ProjectTree::currentProject();
- if (project && project->rootProjectNode()) {
- const ProjectExplorer::Node * const nodeForPath = project->rootProjectNode()->findNode(
+ if (projectRootNode) {
+ const ProjectExplorer::Node * const nodeForPath = projectRootNode->findNode(
[qrcPath = text.mid(text.indexOf(':') + 1)](ProjectExplorer::Node *n) {
if (!n->asFileNode())
return false;
@@ -854,14 +859,33 @@ void QmlJSEditorWidget::findLinkAt(const QTextCursor &cursor,
if (auto q = AST::cast<const AST::UiQualifiedId *>(node)) {
for (const AST::UiQualifiedId *tail = q; tail; tail = tail->next) {
- if (! tail->next && cursorPosition <= tail->identifierToken.end()) {
- link.linkTextStart = tail->identifierToken.begin();
- link.linkTextEnd = tail->identifierToken.end();
+ if (tail->next || !(cursorPosition <= tail->identifierToken.end())) {
+ continue;
+ }
+
+ link.linkTextStart = tail->identifierToken.begin();
+ link.linkTextEnd = tail->identifierToken.end();
+
+ if (!value->asCppComponentValue() || !projectRootNode) {
processLinkCallback(link);
return;
}
- }
+ const ProjectExplorer::Node * const nodeForPath = projectRootNode->findNode(
+ [&fileName](ProjectExplorer::Node *n) {
+ const auto fileNode = n->asFileNode();
+ if (!fileNode)
+ return false;
+ Utils::FilePath filePath = n->filePath();
+ return filePath.endsWith(fileName.toUserOutput());
+ });
+ if (nodeForPath) {
+ link.targetFilePath = nodeForPath->filePath();
+ processLinkCallback(link);
+ return;
+ }
+ // else we will process an empty link below to avoid an error dialog
+ }
} else if (auto id = AST::cast<const AST::IdentifierExpression *>(node)) {
link.linkTextStart = id->firstSourceLocation().begin();
link.linkTextEnd = id->lastSourceLocation().end();