From 8519ca11c35ca635524ea9641f55b61e304ce9c3 Mon Sep 17 00:00:00 2001
From: Christian Kamm <christian.d.kamm@nokia.com>
Date: Fri, 16 Jul 2010 11:16:22 +0200
Subject: [PATCH] QmlJS: Allow 'follow symbol' to jump to the target of a file
 import.

Task-number: QTCREATORBUG-1736
---
 src/libs/qmljs/qmljsbind.cpp            |  1 +
 src/libs/qmljs/qmljsbind.h              |  1 +
 src/plugins/qmljseditor/qmljseditor.cpp | 33 +++++++++++++++++++++++++
 3 files changed, 35 insertions(+)

diff --git a/src/libs/qmljs/qmljsbind.cpp b/src/libs/qmljs/qmljsbind.cpp
index 0328a7c9a22..a8b7a2a1f3a 100644
--- a/src/libs/qmljs/qmljsbind.cpp
+++ b/src/libs/qmljs/qmljsbind.cpp
@@ -181,6 +181,7 @@ bool Bind::visit(AST::Program *)
 bool Bind::visit(UiImport *ast)
 {
     ImportInfo info;
+    info.ast = ast;
 
     if (ast->versionToken.isValid()) {
         const QString versionString = _doc->source().mid(ast->versionToken.offset, ast->versionToken.length);
diff --git a/src/libs/qmljs/qmljsbind.h b/src/libs/qmljs/qmljsbind.h
index e71f171774d..a836eac18a5 100644
--- a/src/libs/qmljs/qmljsbind.h
+++ b/src/libs/qmljs/qmljsbind.h
@@ -54,6 +54,7 @@ public:
     struct ImportInfo {
         QString name;
         ComponentVersion version;
+        AST::UiImport *ast;
     };
 
     QList<ImportInfo> fileImports() const;
diff --git a/src/plugins/qmljseditor/qmljseditor.cpp b/src/plugins/qmljseditor/qmljseditor.cpp
index 1ab408485db..3cf317bd2ad 100644
--- a/src/plugins/qmljseditor/qmljseditor.cpp
+++ b/src/plugins/qmljseditor/qmljseditor.cpp
@@ -35,6 +35,7 @@
 #include "qmloutlinemodel.h"
 
 #include <qmljs/qmljsindenter.h>
+#include <qmljs/qmljsbind.h>
 #include <qmljs/qmljscheck.h>
 #include <qmljs/qmljsdocument.h>
 #include <qmljs/qmljsicontextpane.h>
@@ -525,6 +526,12 @@ QList<AST::Node *> SemanticInfo::astPath(int cursorPosition) const
     return path;
 }
 
+static bool importContainsCursor(UiImport *importAst, unsigned cursorPosition)
+{
+    return cursorPosition >= importAst->firstSourceLocation().begin()
+           && cursorPosition <= importAst->lastSourceLocation().end();
+}
+
 AST::Node *SemanticInfo::nodeUnderCursor(int pos) const
 {
     if (! document)
@@ -532,6 +539,19 @@ AST::Node *SemanticInfo::nodeUnderCursor(int pos) const
 
     const unsigned cursorPosition = pos;
 
+    foreach (const Bind::ImportInfo &import, document->bind()->fileImports()) {
+        if (importContainsCursor(import.ast, cursorPosition))
+            return import.ast;
+    }
+    foreach (const Bind::ImportInfo &import, document->bind()->directoryImports()) {
+        if (importContainsCursor(import.ast, cursorPosition))
+            return import.ast;
+    }
+    foreach (const Bind::ImportInfo &import, document->bind()->libraryImports()) {
+        if (importContainsCursor(import.ast, cursorPosition))
+            return import.ast;
+    }
+
     CollectASTNodes nodes;
     nodes.accept(document->ast());
 
@@ -1226,6 +1246,19 @@ TextEditor::BaseTextEditor::Link QmlJSTextEditor::findLinkAt(const QTextCursor &
 
     AST::Node *node = semanticInfo.nodeUnderCursor(cursorPosition);
 
+    if (AST::UiImport *importAst = cast<AST::UiImport *>(node)) {
+        // if it's a file import, link to the file
+        foreach (const Bind::ImportInfo &import, semanticInfo.document->bind()->fileImports()) {
+            if (import.ast == importAst) {
+                BaseTextEditor::Link link(import.name);
+                link.begin = importAst->firstSourceLocation().begin();
+                link.end = importAst->lastSourceLocation().end();
+                return link;
+            }
+        }
+        return Link();
+    }
+
     LookupContext::Ptr lookupContext = LookupContext::create(semanticInfo.document, semanticInfo.snapshot, semanticInfo.astPath(cursorPosition));
     const Interpreter::Value *value = lookupContext->evaluate(node);
 
-- 
GitLab