summaryrefslogtreecommitdiff
path: root/src/plugins/cppeditor/cppvirtualfunctionassistprovider.cpp
diff options
context:
space:
mode:
authorNikolai Kosjar <nikolai.kosjar@digia.com>2013-12-10 11:38:16 +0100
committerNikolai Kosjar <nikolai.kosjar@digia.com>2013-12-11 11:46:33 +0100
commit273192759b08eb356db5492a686b8da6a0d8e3ab (patch)
tree8f6771055bc661375cbbae6aa335f69b6b5309f5 /src/plugins/cppeditor/cppvirtualfunctionassistprovider.cpp
parenta18b5e27a1605d7fe6183ad388d4a827295d6a3f (diff)
downloadqt-creator-273192759b08eb356db5492a686b8da6a0d8e3ab.tar.gz
CppEditor/CppTools: Move FunctionHelper to CppTools
...and rename it to FunctionUtils. Change-Id: If076ec01fd82e8ba728764bdeab7e87e8bc1ff3b Reviewed-by: Erik Verbruggen <erik.verbruggen@digia.com>
Diffstat (limited to 'src/plugins/cppeditor/cppvirtualfunctionassistprovider.cpp')
-rw-r--r--src/plugins/cppeditor/cppvirtualfunctionassistprovider.cpp284
1 files changed, 3 insertions, 281 deletions
diff --git a/src/plugins/cppeditor/cppvirtualfunctionassistprovider.cpp b/src/plugins/cppeditor/cppvirtualfunctionassistprovider.cpp
index aff4973e05..a3f7048909 100644
--- a/src/plugins/cppeditor/cppvirtualfunctionassistprovider.cpp
+++ b/src/plugins/cppeditor/cppvirtualfunctionassistprovider.cpp
@@ -40,6 +40,7 @@
#include <coreplugin/actionmanager/actionmanager.h>
#include <coreplugin/actionmanager/command.h>
+#include <cpptools/functionutils.h>
#include <cpptools/symbolfinder.h>
#include <cpptools/typehierarchybuilder.h>
@@ -55,6 +56,7 @@
using namespace CPlusPlus;
using namespace CppEditor::Internal;
+using namespace CppTools;
using namespace TextEditor;
/// Activate current item with the same shortcut that is configured for Follow Symbol Under Cursor.
@@ -143,7 +145,7 @@ public:
if (!functionsClass)
return 0;
- const QList<Symbol *> overrides = FunctionHelper::overrides(
+ const QList<Symbol *> overrides = FunctionUtils::overrides(
m_params.function, functionsClass, m_params.staticClass, m_params.snapshot);
if (overrides.isEmpty())
return 0;
@@ -208,283 +210,3 @@ IAssistProcessor *VirtualFunctionAssistProvider::createProcessor() const
{
return new VirtualFunctionsAssistProcessor(m_params);
}
-
-enum VirtualType { Virtual, PureVirtual };
-
-static bool isVirtualFunction_helper(const Function *function,
- const LookupContext &context,
- VirtualType virtualType,
- const Function **firstVirtual)
-{
- enum { Unknown, False, True } res = Unknown;
-
- if (firstVirtual)
- *firstVirtual = 0;
-
- if (!function)
- return false;
-
- if (virtualType == PureVirtual)
- res = function->isPureVirtual() ? True : False;
-
- if (function->isVirtual()) {
- if (firstVirtual)
- *firstVirtual = function;
- if (res == Unknown)
- res = True;
- }
-
- if (!firstVirtual && res != Unknown)
- return res == True;
-
- QList<LookupItem> results = context.lookup(function->name(), function->enclosingScope());
- if (!results.isEmpty()) {
- const bool isDestructor = function->name()->isDestructorNameId();
- foreach (const LookupItem &item, results) {
- if (Symbol *symbol = item.declaration()) {
- if (Function *functionType = symbol->type()->asFunctionType()) {
- if (functionType->name()->isDestructorNameId() != isDestructor)
- continue;
- if (functionType == function) // already tested
- continue;
- if (functionType->isFinal())
- return res == True;
- if (functionType->isVirtual()) {
- if (!firstVirtual)
- return true;
- if (res == Unknown)
- res = True;
- *firstVirtual = functionType;
- }
- }
- }
- }
- }
-
- return res == True;
-}
-
-bool FunctionHelper::isVirtualFunction(const Function *function,
- const LookupContext &context,
- const Function **firstVirtual)
-{
- return isVirtualFunction_helper(function, context, Virtual, firstVirtual);
-}
-
-bool FunctionHelper::isPureVirtualFunction(const Function *function,
- const LookupContext &context,
- const Function **firstVirtual)
-{
- return isVirtualFunction_helper(function, context, PureVirtual, firstVirtual);
-}
-
-QList<Symbol *> FunctionHelper::overrides(Function *function, Class *functionsClass,
- Class *staticClass, const Snapshot &snapshot)
-{
- QList<Symbol *> result;
- QTC_ASSERT(function && functionsClass && staticClass, return result);
-
- FullySpecifiedType referenceType = function->type();
- const Name *referenceName = function->name();
- QTC_ASSERT(referenceName && referenceType.isValid(), return result);
-
- // Find overrides
- CppTools::TypeHierarchyBuilder builder(staticClass, snapshot);
- const CppTools::TypeHierarchy &staticClassHierarchy = builder.buildDerivedTypeHierarchy();
-
- QList<CppTools::TypeHierarchy> l;
- l.append(CppTools::TypeHierarchy(functionsClass));
- l.append(staticClassHierarchy);
-
- while (!l.isEmpty()) {
- // Add derived
- const CppTools::TypeHierarchy hierarchy = l.takeFirst();
- QTC_ASSERT(hierarchy.symbol(), continue);
- Class *c = hierarchy.symbol()->asClass();
- QTC_ASSERT(c, continue);
-
- foreach (const CppTools::TypeHierarchy &t, hierarchy.hierarchy()) {
- if (!l.contains(t))
- l << t;
- }
-
- // Check member functions
- for (int i = 0, total = c->memberCount(); i < total; ++i) {
- Symbol *candidate = c->memberAt(i);
- const Name *candidateName = candidate->name();
- const FullySpecifiedType candidateType = candidate->type();
- if (!candidateName || !candidateType.isValid())
- continue;
- if (candidateName->isEqualTo(referenceName) && candidateType.isEqualTo(referenceType))
- result << candidate;
- }
- }
-
- return result;
-}
-
-#ifdef WITH_TESTS
-#include "cppeditorplugin.h"
-
-#include <QList>
-#include <QTest>
-
-namespace CppEditor {
-namespace Internal {
-
-enum Virtuality
-{
- NotVirtual,
- Virtual,
- PureVirtual
-};
-typedef QList<Virtuality> VirtualityList;
-} // Internal namespace
-} // CppEditor namespace
-
-Q_DECLARE_METATYPE(CppEditor::Internal::Virtuality)
-Q_DECLARE_METATYPE(CppEditor::Internal::VirtualityList)
-Q_DECLARE_METATYPE(QList<int>)
-
-namespace CppEditor {
-namespace Internal {
-
-void CppEditorPlugin::test_functionhelper_virtualFunctions()
-{
- // Create and parse document
- QFETCH(QByteArray, source);
- QFETCH(VirtualityList, virtualityList);
- QFETCH(QList<int>, firstVirtualList);
- Document::Ptr document = Document::create(QLatin1String("virtuals"));
- document->setUtf8Source(source);
- document->check(); // calls parse();
- QCOMPARE(document->diagnosticMessages().size(), 0);
- QVERIFY(document->translationUnit()->ast());
- QList<const Function *> allFunctions;
- const Function *firstVirtual = 0;
-
- // Iterate through Function symbols
- Snapshot snapshot;
- snapshot.insert(document);
- const LookupContext context(document, snapshot);
- Control *control = document->translationUnit()->control();
- Symbol **end = control->lastSymbol();
- for (Symbol **it = control->firstSymbol(); it != end; ++it) {
- if (const Function *function = (*it)->asFunction()) {
- allFunctions.append(function);
- QTC_ASSERT(!virtualityList.isEmpty(), return);
- Virtuality virtuality = virtualityList.takeFirst();
- QTC_ASSERT(!firstVirtualList.isEmpty(), return);
- int firstVirtualIndex = firstVirtualList.takeFirst();
- bool isVirtual = FunctionHelper::isVirtualFunction(function, context, &firstVirtual);
- bool isPureVirtual = FunctionHelper::isPureVirtualFunction(function, context,
- &firstVirtual);
-
- // Test for regressions introduced by firstVirtual
- QCOMPARE(FunctionHelper::isVirtualFunction(function, context), isVirtual);
- QCOMPARE(FunctionHelper::isPureVirtualFunction(function, context), isPureVirtual);
- if (isVirtual) {
- if (isPureVirtual)
- QCOMPARE(virtuality, PureVirtual);
- else
- QCOMPARE(virtuality, Virtual);
- } else {
- QEXPECT_FAIL("virtual-dtor-dtor", "Not implemented", Abort);
- if (allFunctions.size() == 3)
- QEXPECT_FAIL("dtor-virtual-dtor-dtor", "Not implemented", Abort);
- QCOMPARE(virtuality, NotVirtual);
- }
- if (firstVirtualIndex == -1)
- QVERIFY(!firstVirtual);
- else
- QCOMPARE(firstVirtual, allFunctions.at(firstVirtualIndex));
- }
- }
- QVERIFY(virtualityList.isEmpty());
- QVERIFY(firstVirtualList.isEmpty());
-}
-
-void CppEditorPlugin::test_functionhelper_virtualFunctions_data()
-{
- typedef QByteArray _;
- QTest::addColumn<QByteArray>("source");
- QTest::addColumn<VirtualityList>("virtualityList");
- QTest::addColumn<QList<int> >("firstVirtualList");
-
- QTest::newRow("none")
- << _("struct None { void foo() {} };\n")
- << (VirtualityList() << NotVirtual)
- << (QList<int>() << -1);
-
- QTest::newRow("single-virtual")
- << _("struct V { virtual void foo() {} };\n")
- << (VirtualityList() << Virtual)
- << (QList<int>() << 0);
-
- QTest::newRow("single-pure-virtual")
- << _("struct PV { virtual void foo() = 0; };\n")
- << (VirtualityList() << PureVirtual)
- << (QList<int>() << 0);
-
- QTest::newRow("virtual-derived-with-specifier")
- << _("struct Base { virtual void foo() {} };\n"
- "struct Derived : Base { virtual void foo() {} };\n")
- << (VirtualityList() << Virtual << Virtual)
- << (QList<int>() << 0 << 0);
-
- QTest::newRow("virtual-derived-implicit")
- << _("struct Base { virtual void foo() {} };\n"
- "struct Derived : Base { void foo() {} };\n")
- << (VirtualityList() << Virtual << Virtual)
- << (QList<int>() << 0 << 0);
-
- QTest::newRow("not-virtual-then-virtual")
- << _("struct Base { void foo() {} };\n"
- "struct Derived : Base { virtual void foo() {} };\n")
- << (VirtualityList() << NotVirtual << Virtual)
- << (QList<int>() << -1 << 1);
-
- QTest::newRow("virtual-final-not-virtual")
- << _("struct Base { virtual void foo() {} };\n"
- "struct Derived : Base { void foo() final {} };\n"
- "struct Derived2 : Derived { void foo() {} };")
- << (VirtualityList() << Virtual << Virtual << NotVirtual)
- << (QList<int>() << 0 << 0 << -1);
-
- QTest::newRow("virtual-then-pure")
- << _("struct Base { virtual void foo() {} };\n"
- "struct Derived : Base { virtual void foo() = 0; };\n"
- "struct Derived2 : Derived { void foo() {} };")
- << (VirtualityList() << Virtual << PureVirtual << Virtual)
- << (QList<int>() << 0 << 0 << 0);
-
- QTest::newRow("virtual-virtual-final-not-virtual")
- << _("struct Base { virtual void foo() {} };\n"
- "struct Derived : Base { virtual void foo() final {} };\n"
- "struct Derived2 : Derived { void foo() {} };")
- << (VirtualityList() << Virtual << Virtual << NotVirtual)
- << (QList<int>() << 0 << 0 << -1);
-
- QTest::newRow("ctor-virtual-dtor")
- << _("struct Base { Base() {} virtual ~Base() {} };\n")
- << (VirtualityList() << NotVirtual << Virtual)
- << (QList<int>() << -1 << 1);
-
- QTest::newRow("virtual-dtor-dtor")
- << _("struct Base { virtual ~Base() {} };\n"
- "struct Derived : Base { ~Derived() {} };\n")
- << (VirtualityList() << Virtual << Virtual)
- << (QList<int>() << 0 << 0);
-
- QTest::newRow("dtor-virtual-dtor-dtor")
- << _("struct Base { ~Base() {} };\n"
- "struct Derived : Base { virtual ~Derived() {} };\n"
- "struct Derived2 : Derived { ~Derived2() {} };\n")
- << (VirtualityList() << NotVirtual << Virtual << Virtual)
- << (QList<int>() << -1 << 1 << 1);
-}
-
-} // namespace Internal
-} // namespace CppEditor
-
-#endif