summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikolai Kosjar <nikolai.kosjar@digia.com>2013-10-21 13:39:48 +0200
committerNikolai Kosjar <nikolai.kosjar@digia.com>2013-10-24 11:49:17 +0200
commitf8653a59bc1f079b9f7fe399cfcce6a4e43cc3eb (patch)
tree9829fc46cb0a8bcb56fb13fd79f53fe1f9c9fc66
parentb1472eefae33a96af24028e1296701e9dc35e326 (diff)
downloadqt-creator-f8653a59bc1f079b9f7fe399cfcce6a4e43cc3eb.tar.gz
CppEditor: Selecting an override of a virtual function jumps to definition
...instead declaration (F2 on a virtual function call). Task-number: QTCREATORBUG-10287 Change-Id: Ib913bd4e777c7253659458ae17584354c7416d23 Reviewed-by: Orgad Shaneh <orgads@gmail.com> Reviewed-by: Erik Verbruggen <erik.verbruggen@digia.com>
-rw-r--r--src/plugins/cppeditor/cppeditorplugin.h2
-rw-r--r--src/plugins/cppeditor/cppvirtualfunctionassistprovider.cpp24
-rw-r--r--src/plugins/cppeditor/followsymbol_switchmethoddecldef_test.cpp80
3 files changed, 84 insertions, 22 deletions
diff --git a/src/plugins/cppeditor/cppeditorplugin.h b/src/plugins/cppeditor/cppeditorplugin.h
index 3a4eaa19f4..c9e6f5e873 100644
--- a/src/plugins/cppeditor/cppeditorplugin.h
+++ b/src/plugins/cppeditor/cppeditorplugin.h
@@ -138,6 +138,8 @@ private slots:
void test_FollowSymbolUnderCursor_virtualFunctionCall_allOverrides();
void test_FollowSymbolUnderCursor_virtualFunctionCall_possibleOverrides1();
void test_FollowSymbolUnderCursor_virtualFunctionCall_possibleOverrides2();
+ void test_FollowSymbolUnderCursor_virtualFunctionCall_fallbackToDeclaration();
+ void test_FollowSymbolUnderCursor_virtualFunctionCall_itemOrder();
void test_FollowSymbolUnderCursor_virtualFunctionCall_onDotMemberAccessOfReferenceTypes();
void test_FollowSymbolUnderCursor_virtualFunctionCall_notOnDotMemberAccessOfNonReferenceType();
void test_FollowSymbolUnderCursor_virtualFunctionCall_notOnQualified();
diff --git a/src/plugins/cppeditor/cppvirtualfunctionassistprovider.cpp b/src/plugins/cppeditor/cppvirtualfunctionassistprovider.cpp
index a9668bc3fc..5c86bf455b 100644
--- a/src/plugins/cppeditor/cppvirtualfunctionassistprovider.cpp
+++ b/src/plugins/cppeditor/cppvirtualfunctionassistprovider.cpp
@@ -40,6 +40,8 @@
#include <coreplugin/actionmanager/actionmanager.h>
#include <coreplugin/actionmanager/command.h>
+#include <cpptools/symbolfinder.h>
+
#include <texteditor/codeassist/basicproposalitemlistmodel.h>
#include <texteditor/codeassist/genericproposal.h>
#include <texteditor/codeassist/genericproposalwidget.h>
@@ -124,7 +126,7 @@ public:
hintItem->setOrder(-1000);
QList<BasicProposalItem *> items;
- items << itemFromSymbol(m_function, m_function);
+ items << itemFromSymbol(maybeDefinitionFor(m_function));
items << hintItem;
return new VirtualFunctionProposal(interface->position(),
new BasicProposalItemListModel(items),
@@ -142,16 +144,28 @@ public:
const QList<Symbol *> overrides = FunctionHelper::overrides(m_startClass, m_function,
m_snapshot);
+ if (overrides.isEmpty())
+ return 0;
+
QList<BasicProposalItem *> items;
foreach (Symbol *symbol, overrides)
- items << itemFromSymbol(symbol, m_function);
+ items << itemFromSymbol(maybeDefinitionFor(symbol));
+ items.first()->setOrder(1000); // Ensure top position for function of static type
return new VirtualFunctionProposal(interface->position(),
new BasicProposalItemListModel(items),
m_openInNextSplit);
}
- BasicProposalItem *itemFromSymbol(Symbol *symbol, Symbol *firstSymbol) const
+private:
+ Symbol *maybeDefinitionFor(Symbol *symbol)
+ {
+ if (Function *definition = m_finder.findMatchingDefinition(symbol, m_snapshot))
+ return definition;
+ return symbol;
+ }
+
+ BasicProposalItem *itemFromSymbol(Symbol *symbol) const
{
const QString text = m_overview.prettyName(LookupContext::fullyQualifiedName(symbol));
const CPPEditorWidget::Link link = CPPEditorWidget::linkToSymbol(symbol);
@@ -159,19 +173,17 @@ public:
BasicProposalItem *item = new VirtualFunctionProposalItem(link, m_openInNextSplit);
item->setText(text);
item->setIcon(m_icons.iconForSymbol(symbol));
- if (symbol == firstSymbol)
- item->setOrder(1000); // Ensure top position for function of static type
return item;
}
-private:
Class *m_startClass;
Function *m_function;
Snapshot m_snapshot;
bool m_openInNextSplit;
Overview m_overview;
Icons m_icons;
+ CppTools::SymbolFinder m_finder;
};
VirtualFunctionAssistProvider::VirtualFunctionAssistProvider()
diff --git a/src/plugins/cppeditor/followsymbol_switchmethoddecldef_test.cpp b/src/plugins/cppeditor/followsymbol_switchmethoddecldef_test.cpp
index 99be9591d5..f9dc85b528 100644
--- a/src/plugins/cppeditor/followsymbol_switchmethoddecldef_test.cpp
+++ b/src/plugins/cppeditor/followsymbol_switchmethoddecldef_test.cpp
@@ -1274,14 +1274,14 @@ void CppEditorPlugin::test_FollowSymbolUnderCursor_virtualFunctionCall_allOverri
;
const OverrideItemList immediateResults = OverrideItemList()
- << OverrideItem(QLatin1String("A::virt"), 1)
+ << OverrideItem(QLatin1String("A::virt"), 2)
<< OverrideItem(QLatin1String("...searching overrides"));
const OverrideItemList finalResults = OverrideItemList()
- << OverrideItem(QLatin1String("A::virt"), 1)
- << OverrideItem(QLatin1String("B::virt"), 4)
- << OverrideItem(QLatin1String("C::virt"), 7)
- << OverrideItem(QLatin1String("CD1::virt"), 10)
- << OverrideItem(QLatin1String("CD2::virt"), 13);
+ << OverrideItem(QLatin1String("A::virt"), 2)
+ << OverrideItem(QLatin1String("B::virt"), 5)
+ << OverrideItem(QLatin1String("C::virt"), 8)
+ << OverrideItem(QLatin1String("CD1::virt"), 11)
+ << OverrideItem(QLatin1String("CD2::virt"), 14);
TestCase test(TestCase::FollowSymbolUnderCursorAction, source, immediateResults, finalResults);
test.run();
@@ -1311,13 +1311,13 @@ void CppEditorPlugin::test_FollowSymbolUnderCursor_virtualFunctionCall_possibleO
;
const OverrideItemList immediateResults = OverrideItemList()
- << OverrideItem(QLatin1String("B::virt"), 4)
+ << OverrideItem(QLatin1String("B::virt"), 5)
<< OverrideItem(QLatin1String("...searching overrides"));
const OverrideItemList finalResults = OverrideItemList()
- << OverrideItem(QLatin1String("B::virt"), 4)
- << OverrideItem(QLatin1String("C::virt"), 7)
- << OverrideItem(QLatin1String("CD1::virt"), 10)
- << OverrideItem(QLatin1String("CD2::virt"), 13);
+ << OverrideItem(QLatin1String("B::virt"), 5)
+ << OverrideItem(QLatin1String("C::virt"), 8)
+ << OverrideItem(QLatin1String("CD1::virt"), 11)
+ << OverrideItem(QLatin1String("CD2::virt"), 14);
TestCase test(TestCase::FollowSymbolUnderCursorAction, source, immediateResults, finalResults);
test.run();
@@ -1340,11 +1340,59 @@ void CppEditorPlugin::test_FollowSymbolUnderCursor_virtualFunctionCall_possibleO
;
const OverrideItemList immediateResults = OverrideItemList()
- << OverrideItem(QLatin1String("B::virt"), 4)
+ << OverrideItem(QLatin1String("B::virt"), 5)
+ << OverrideItem(QLatin1String("...searching overrides"));
+ const OverrideItemList finalResults = OverrideItemList()
+ << OverrideItem(QLatin1String("B::virt"), 5)
+ << OverrideItem(QLatin1String("D::virt"), 10);
+
+ TestCase test(TestCase::FollowSymbolUnderCursorAction, source, immediateResults, finalResults);
+ test.run();
+}
+
+/// Check: If no definition is found, fallback to the declaration.
+void CppEditorPlugin::test_FollowSymbolUnderCursor_virtualFunctionCall_fallbackToDeclaration()
+{
+ const QByteArray source =
+ "struct A { virtual void virt(); };\n"
+ "\n"
+ "int f(A *o) { o->$@virt(); }\n"
+ ;
+
+ const OverrideItemList immediateResults = OverrideItemList()
+ << OverrideItem(QLatin1String("A::virt"), 1)
<< OverrideItem(QLatin1String("...searching overrides"));
const OverrideItemList finalResults = OverrideItemList()
- << OverrideItem(QLatin1String("B::virt"), 4)
- << OverrideItem(QLatin1String("D::virt"), 9);
+ << OverrideItem(QLatin1String("A::virt"), 1);
+
+ TestCase test(TestCase::FollowSymbolUnderCursorAction, source, immediateResults, finalResults);
+ test.run();
+}
+
+/// Check: Ensure that the first entry in the final results is the same as the first in the
+/// immediate results.
+void CppEditorPlugin::test_FollowSymbolUnderCursor_virtualFunctionCall_itemOrder()
+{
+ const QByteArray source =
+ "struct C { virtual void virt() = 0; };\n"
+ "void C::virt() {}\n"
+ "\n"
+ "struct B : C { void virt(); };\n"
+ "void B::virt() {}\n"
+ "\n"
+ "struct A : B { void virt(); };\n"
+ "void A::virt() {}\n"
+ "\n"
+ "int f(C *o) { o->$@virt(); }\n"
+ ;
+
+ const OverrideItemList immediateResults = OverrideItemList()
+ << OverrideItem(QLatin1String("C::virt"), 2)
+ << OverrideItem(QLatin1String("...searching overrides"));
+ const OverrideItemList finalResults = OverrideItemList()
+ << OverrideItem(QLatin1String("C::virt"), 2)
+ << OverrideItem(QLatin1String("A::virt"), 8)
+ << OverrideItem(QLatin1String("B::virt"), 5);
TestCase test(TestCase::FollowSymbolUnderCursorAction, source, immediateResults, finalResults);
test.run();
@@ -1361,10 +1409,10 @@ void CppEditorPlugin::test_FollowSymbolUnderCursor_virtualFunctionCall_onDotMemb
;
const OverrideItemList immediateResults = OverrideItemList()
- << OverrideItem(QLatin1String("A::virt"), 1)
+ << OverrideItem(QLatin1String("A::virt"), 2)
<< OverrideItem(QLatin1String("...searching overrides"));
const OverrideItemList finalResults = OverrideItemList()
- << OverrideItem(QLatin1String("A::virt"), 1);
+ << OverrideItem(QLatin1String("A::virt"), 2);
TestCase test(TestCase::FollowSymbolUnderCursorAction, source, immediateResults, finalResults);
test.run();