diff options
author | Christian Kandeler <christian.kandeler@qt.io> | 2021-08-30 10:58:08 +0200 |
---|---|---|
committer | Christian Kandeler <christian.kandeler@qt.io> | 2021-09-01 14:53:58 +0000 |
commit | 284817fae6514701902ccdb834c2faa46462f2e8 (patch) | |
tree | 44a8c7d9813dc110b61c4639036366c7696bd7e9 /src/plugins/cpptools/cppcompletion_test.cpp | |
parent | 3e1fa0f170d523971d2c3c12da15a6e291f56511 (diff) | |
download | qt-creator-284817fae6514701902ccdb834c2faa46462f2e8.tar.gz |
Merge CppTools into CppEditor
There was no proper separation of responsibilities between these
plugins. In particular, CppTools had lots of editor-related
functionality, so it's not clear why it was separated out in the first
place.
In fact, for a lot of code, it seemed quite arbitrary where it was put
(just one example: switchHeaderSource() was in CppTools, wheras
switchDeclarationDefinition() was in CppEditor).
Merging the plugins will enable us to get rid of various convoluted
pseudo-abstractions that were only introduced to keep up the artificial
separation.
Change-Id: Iafc3bce625b4794f6d4aa03df6cddc7f2d26716a
Reviewed-by: Christian Stenger <christian.stenger@qt.io>
Diffstat (limited to 'src/plugins/cpptools/cppcompletion_test.cpp')
-rw-r--r-- | src/plugins/cpptools/cppcompletion_test.cpp | 2891 |
1 files changed, 0 insertions, 2891 deletions
diff --git a/src/plugins/cpptools/cppcompletion_test.cpp b/src/plugins/cpptools/cppcompletion_test.cpp deleted file mode 100644 index 1af079083b..0000000000 --- a/src/plugins/cpptools/cppcompletion_test.cpp +++ /dev/null @@ -1,2891 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -****************************************************************************/ - -#include "cppcompletion_test.h" - -#include "cppcompletionassist.h" -#include "cppdoxygen.h" -#include "cppmodelmanager.h" -#include "cpptoolstestcase.h" - -#include <texteditor/codeassist/iassistproposal.h> -#include <texteditor/texteditor.h> -#include <texteditor/textdocument.h> -#include <coreplugin/editormanager/editormanager.h> - -#include <utils/algorithm.h> -#include <utils/changeset.h> -#include <utils/textutils.h> -#include <utils/fileutils.h> - -#include <QDebug> -#include <QDir> -#include <QTextDocument> -#include <QtTest> - -/*! - Tests for code completion. - */ -using namespace CPlusPlus; -using namespace CppTools; -using namespace CppTools::Internal; -using namespace TextEditor; -using namespace Core; - -namespace { - -using _ = QByteArray; - -class CompletionTestCase : public Tests::TestCase -{ -public: - CompletionTestCase(const QByteArray &sourceText, const QByteArray &textToInsert = QByteArray(), - bool isObjC = false) - { - QVERIFY(succeededSoFar()); - m_succeededSoFar = false; - - m_source = sourceText; - m_position = m_source.indexOf('@'); - QVERIFY(m_position != -1); - m_source[m_position] = ' '; - - // Write source to file - m_temporaryDir.reset(new Tests::TemporaryDir()); - QVERIFY(m_temporaryDir->isValid()); - const QByteArray fileExt = isObjC ? "mm" : "h"; - const QString fileName = m_temporaryDir->createFile("file." + fileExt, m_source); - QVERIFY(!fileName.isEmpty()); - - // Open in editor - m_editor = EditorManager::openEditor(fileName); - QVERIFY(m_editor); - closeEditorAtEndOfTestCase(m_editor); - m_editorWidget = TextEditorWidget::fromEditor(m_editor); - QVERIFY(m_editorWidget); - - m_textDocument = m_editorWidget->document(); - - // Get Document - const Document::Ptr document = waitForFileInGlobalSnapshot(fileName); - QVERIFY(document); - QVERIFY(document->diagnosticMessages().isEmpty()); - - m_snapshot.insert(document); - - if (!textToInsert.isEmpty()) - insertText(textToInsert); - - m_succeededSoFar = true; - } - - QStringList getCompletions(bool *replaceAccessOperator = nullptr) const - { - QStringList completions; - LanguageFeatures languageFeatures = LanguageFeatures::defaultFeatures(); - languageFeatures.objCEnabled = false; - CppCompletionAssistInterface *ai - = new CppCompletionAssistInterface(m_editorWidget->textDocument()->filePath(), - m_textDocument, m_position, - ExplicitlyInvoked, m_snapshot, - ProjectExplorer::HeaderPaths(), - languageFeatures); - ai->prepareForAsyncUse(); - ai->recreateTextDocument(); - InternalCppCompletionAssistProcessor processor; - - const QScopedPointer<IAssistProposal> proposal(processor.perform(ai)); - if (!proposal) - return completions; - ProposalModelPtr model = proposal->model(); - if (!model) - return completions; - CppAssistProposalModelPtr listmodel = model.staticCast<CppAssistProposalModel>(); - if (!listmodel) - return completions; - - const int pos = proposal->basePosition(); - const int length = m_position - pos; - const QString prefix = Utils::Text::textAt(QTextCursor(m_textDocument), pos, length); - if (!prefix.isEmpty()) - listmodel->filter(prefix); - if (listmodel->isSortable(prefix)) - listmodel->sort(prefix); - - for (int i = 0; i < listmodel->size(); ++i) - completions << listmodel->text(i); - - if (replaceAccessOperator) - *replaceAccessOperator = listmodel->m_replaceDotForArrow; - - return completions; - } - - void insertText(const QByteArray &text) - { - Utils::ChangeSet change; - change.insert(m_position, QLatin1String(text)); - QTextCursor cursor(m_textDocument); - change.apply(&cursor); - m_position += text.length(); - } - -private: - QByteArray m_source; - int m_position = -1; - Snapshot m_snapshot; - QScopedPointer<Tests::TemporaryDir> m_temporaryDir; - TextEditorWidget *m_editorWidget = nullptr; - QTextDocument *m_textDocument = nullptr; - IEditor *m_editor = nullptr; -}; - -bool isProbablyGlobalCompletion(const QStringList &list) -{ - const int numberOfPrimitivesAndBasicKeywords = (T_LAST_PRIMITIVE - T_FIRST_PRIMITIVE) - + (T_FIRST_OBJC_AT_KEYWORD - T_FIRST_KEYWORD); - - return list.size() >= numberOfPrimitivesAndBasicKeywords - && list.contains(QLatin1String("override")) - && list.contains(QLatin1String("final")) - && list.contains(QLatin1String("if")) - && list.contains(QLatin1String("bool")); -} - -bool isDoxygenTagCompletion(const QStringList &list) -{ - for (int i = 1; i < T_DOXY_LAST_TAG; ++i) { - const QString doxygenTag = QString::fromLatin1(doxygenTagSpell(i)); - if (!list.contains(doxygenTag)) - return false; - } - - return true; -} - -} // anonymous namespace - -void CompletionTest::testCompletionBasic1() -{ - const QByteArray source = - "class Foo\n" - "{\n" - " void foo();\n" - " int m;\n" - "};\n" - "\n" - "void func() {\n" - " Foo f;\n" - " @\n" - "}"; - CompletionTestCase test(source); - QVERIFY(test.succeededSoFar()); - - QStringList basicCompletions = test.getCompletions(); - QVERIFY(!basicCompletions.contains(QLatin1String("foo"))); - QVERIFY(!basicCompletions.contains(QLatin1String("m"))); - QVERIFY(basicCompletions.contains(QLatin1String("Foo"))); - QVERIFY(basicCompletions.contains(QLatin1String("func"))); - QVERIFY(basicCompletions.contains(QLatin1String("f"))); - - test.insertText("f."); - - QStringList memberCompletions = test.getCompletions(); - QVERIFY(memberCompletions.contains(QLatin1String("foo"))); - QVERIFY(memberCompletions.contains(QLatin1String("m"))); - QVERIFY(!memberCompletions.contains(QLatin1String("func"))); - QVERIFY(!memberCompletions.contains(QLatin1String("f"))); -} - -void CompletionTest::testCompletionPrefixFirstQTCREATORBUG_8737() -{ - const QByteArray source = - "void f()\n" - "{\n" - " int a_b_c, a_c, a_c_a;\n" - " @;\n" - "}\n" - ; - CompletionTestCase test(source, "a_c"); - QVERIFY(test.succeededSoFar()); - - QStringList completions = test.getCompletions(); - - QVERIFY(completions.size() >= 2); - QCOMPARE(completions.at(0), QLatin1String("a_c")); - QCOMPARE(completions.at(1), QLatin1String("a_c_a")); - QVERIFY(completions.contains(QLatin1String("a_b_c"))); -} - -void CompletionTest::testCompletionPrefixFirstQTCREATORBUG_9236() -{ - const QByteArray source = - "class r_etclass\n" - "{\n" - "public:\n" - " int raEmTmber;\n" - " void r_e_t(int re_t)\n" - " {\n" - " int r_et;\n" - " int rETUCASE;\n" - " @\n" - " }\n" - "};\n" - ; - CompletionTestCase test(source, "ret"); - QVERIFY(test.succeededSoFar()); - - QStringList completions = test.getCompletions(); - QVERIFY(completions.size() >= 2); - QCOMPARE(completions.at(0), QLatin1String("return")); - QCOMPARE(completions.at(1), QLatin1String("rETUCASE")); - QVERIFY(completions.contains(QLatin1String("r_etclass"))); - QVERIFY(completions.contains(QLatin1String("raEmTmber"))); - QVERIFY(completions.contains(QLatin1String("r_e_t"))); - QVERIFY(completions.contains(QLatin1String("re_t"))); - QVERIFY(completions.contains(QLatin1String("r_et"))); -} - -void CompletionTest::testCompletionTemplateFunction() -{ - QFETCH(QByteArray, code); - QFETCH(QStringList, expectedCompletions); - - CompletionTestCase test(code); - QVERIFY(test.succeededSoFar()); - - QStringList actualCompletions = test.getCompletions(); - QString errorPattern(QLatin1String("Completion not found: %1")); - foreach (const QString &completion, expectedCompletions) { - QByteArray errorMessage = errorPattern.arg(completion).toUtf8(); - QVERIFY2(actualCompletions.contains(completion), errorMessage.data()); - } -} - -void CompletionTest::testCompletionTemplateFunction_data() -{ - QTest::addColumn<QByteArray>("code"); - QTest::addColumn<QStringList>("expectedCompletions"); - - QByteArray code; - QStringList completions; - - code = - "template <class tclass, typename tname, int tint>\n" - "tname Hello(const tclass &e)\n" - "{\n" - " tname e2 = e;\n" - " @\n" - "}"; - - completions.append(QLatin1String("tclass")); - completions.append(QLatin1String("tname")); - completions.append(QLatin1String("tint")); - - QTest::newRow("case: template parameters in template function body") - << code << completions; - - completions.clear(); - - code = - "template <class tclass, typename tname, int tint>\n" - "tname Hello(const tclass &e, @)\n" - "{\n" - " tname e2 = e;\n" - "}"; - - completions.append(QLatin1String("tclass")); - completions.append(QLatin1String("tname")); - completions.append(QLatin1String("tint")); - - QTest::newRow("case: template parameters in template function parameters list") - << code << completions; -} - -void CompletionTest::testCompletion() -{ - QFETCH(QByteArray, code); - QFETCH(QByteArray, prefix); - QFETCH(QStringList, expectedCompletions); - - CompletionTestCase test(code, prefix); - QVERIFY(test.succeededSoFar()); - - QStringList actualCompletions = test.getCompletions(); - actualCompletions.sort(); - expectedCompletions.sort(); - - QEXPECT_FAIL("template_as_base: explicit typedef from base", "QTCREATORBUG-14218", Abort); - QEXPECT_FAIL("enum_in_function_in_struct_in_function", "QTCREATORBUG-13757", Abort); - QEXPECT_FAIL("enum_in_function_in_struct_in_function_cxx11", "QTCREATORBUG-13757", Abort); - QEXPECT_FAIL("enum_in_function_in_struct_in_function_anon", "QTCREATORBUG-13757", Abort); - QEXPECT_FAIL("enum_in_class_accessed_in_member_func_cxx11", "QTCREATORBUG-13757", Abort); - QEXPECT_FAIL("enum_in_class_accessed_in_member_func_inline_cxx11", "QTCREATORBUG-13757", Abort); - QEXPECT_FAIL("pointer_indirect_specialization", "QTCREATORBUG-14141", Abort); - QEXPECT_FAIL("pointer_indirect_specialization_typedef", "QTCREATORBUG-14141", Abort); - QEXPECT_FAIL("pointer_indirect_specialization_double_indirection", "QTCREATORBUG-14141", Abort); - QEXPECT_FAIL("pointer_indirect_specialization_double_indirection_with_base", "QTCREATORBUG-14141", Abort); - QCOMPARE(actualCompletions, expectedCompletions); -} - -void CompletionTest::testGlobalCompletion_data() -{ - QTest::addColumn<QByteArray>("code"); - QTest::addColumn<QByteArray>("prefix"); - QTest::addColumn<QStringList>("requiredCompletionItems"); - - // Check that special completion after '&' for Qt5 signal/slots does not - // interfere global completion after '&' - QTest::newRow("global completion after & in return expression") - << _("void f() { foo(myObject, @); }\n") - << _("&") - << QStringList(); - QTest::newRow("global completion after & in function argument") - << _("int f() { return @; }\n") - << _("&") - << QStringList(); - - // Check global completion after one line comments - const QByteArray codeTemplate = "int myGlobal;\n" - "<REPLACEMENT>\n" - "@\n"; - const QStringList replacements = QStringList({"// text", "// text.", "/// text", "/// text."}); - foreach (const QString &replacement, replacements) { - QByteArray code = codeTemplate; - code.replace("<REPLACEMENT>", replacement.toUtf8()); - const QByteArray tag = _("completion after comment: ") + replacement.toUtf8(); - QTest::newRow(tag) << code << QByteArray() << QStringList("myGlobal"); - } -} - -void CompletionTest::testGlobalCompletion() -{ - QFETCH(QByteArray, code); - QFETCH(QByteArray, prefix); - QFETCH(QStringList, requiredCompletionItems); - - CompletionTestCase test(code, prefix); - QVERIFY(test.succeededSoFar()); - const QStringList completions = test.getCompletions(); - QVERIFY(isProbablyGlobalCompletion(completions)); - QVERIFY(Utils::toSet(completions).contains(Utils::toSet(requiredCompletionItems))); -} - -void CompletionTest::testDoxygenTagCompletion_data() -{ - QTest::addColumn<QByteArray>("code"); - - QTest::newRow("C++ comment") - << _("/// @"); - - QTest::newRow("C comment single line") - << _("/*! @ */"); - - QTest::newRow("C comment multi line") - << _("/*! text\n" - " * @\n" - " */\n"); -} - -void CompletionTest::testDoxygenTagCompletion() -{ - QFETCH(QByteArray, code); - - const QByteArray prefix = "\\"; - - CompletionTestCase test(code, prefix); - QVERIFY(test.succeededSoFar()); - const QStringList completions = test.getCompletions(); - QVERIFY(isDoxygenTagCompletion(completions)); -} - -static void enumTestCase(const QByteArray &tag, const QByteArray &source, - const QByteArray &prefix = QByteArray()) -{ - QByteArray fullSource = source; - fullSource.replace('$', "enum E { val1, val2, val3 };"); - QTest::newRow(tag) << fullSource << (prefix + "val") - << QStringList({"val1", "val2", "val3"}); - - QTest::newRow(QByteArray{tag + "_cxx11"}) << fullSource << QByteArray{prefix + "E::"} - << QStringList({"E", "val1", "val2", "val3"}); - - fullSource.replace("enum E ", "enum "); - QTest::newRow(QByteArray{tag + "_anon"}) << fullSource << QByteArray{prefix + "val"} - << QStringList({"val1", "val2", "val3"}); -} - -void CompletionTest::testCompletion_data() -{ - QTest::addColumn<QByteArray>("code"); - QTest::addColumn<QByteArray>("prefix"); - QTest::addColumn<QStringList>("expectedCompletions"); - - QTest::newRow("forward_declarations_present") << _( - "class Foo\n" - "{\n" - " struct Bar;\n" - " int i;\n" - "};\n" - "\n" - "struct Foo::Bar \n" - "{\n" - " Bar() {}\n" - "};\n" - "\n" - "@\n" - ) << _("Foo::Bar::") << QStringList("Bar"); - - QTest::newRow("inside_parentheses_c_style_conversion") << _( - "class Base\n" - "{\n" - " int i_base;\n" - "};\n" - "\n" - "class Derived : public Base\n" - "{\n" - " int i_derived;\n" - "};\n" - "\n" - "void fun()\n" - "{\n" - " Base *b = new Derived;\n" - " if (1)\n" - " @;\n" - "}\n" - ) << _("((Derived *)b)->") << QStringList({"Derived", "Base", "i_derived", "i_base"}); - - QTest::newRow("inside_parentheses_cast_operator_conversion") << _( - "class Base\n" - "{\n" - " int i_base;\n" - "};\n" - "\n" - "class Derived : public Base\n" - "{\n" - " int i_derived;\n" - "};\n" - "\n" - "void fun()\n" - "{\n" - " Base *b = new Derived;\n" - " if (1)\n" - " @;\n" - "}\n" - ) << _("(static_cast<Derived *>(b))->") << QStringList({"Derived", "Base", "i_derived", - "i_base"}); - - QTest::newRow("template_1") << _( - "template <class T>\n" - "class Foo\n" - "{\n" - " typedef T Type;\n" - " T foo();\n" - " T m;\n" - "};\n" - "\n" - "void func() {\n" - " Foo f;\n" - " @\n" - "}" - ) << _("Foo::") << QStringList({"Foo", "Type", "foo", "m"}); - - QTest::newRow("template_2") << _( - "template <class T>\n" - "struct List\n" - "{\n" - " T &at(int);\n" - "};\n" - "\n" - "struct Tupple { int a; int b; };\n" - "\n" - "void func() {\n" - " List<Tupple> l;\n" - " @\n" - "}" - ) << _("l.at(0).") << QStringList({"Tupple", "a", "b"}); - - QTest::newRow("template_3") << _( - "template <class T>\n" - "struct List\n" - "{\n" - " T t;\n" - "};\n" - "\n" - "struct Tupple { int a; int b; };\n" - "\n" - "void func() {\n" - " List<Tupple> l;\n" - " @\n" - "}" - ) << _("l.t.") << QStringList({"Tupple", "a", "b"}); - - QTest::newRow("template_4") << _( - "template <class T>\n" - "struct List\n" - "{\n" - " typedef T U;\n" - " U u;\n" - "};\n" - "\n" - "struct Tupple { int a; int b; };\n" - "\n" - "void func() {\n" - " List<Tupple> l;\n" - " @\n" - "}" - ) << _("l.u.") << QStringList({"Tupple", "a", "b"}); - - QTest::newRow("template_5") << _( - "template <class T>\n" - "struct List\n" - "{\n" - " T u;\n" - "};\n" - "\n" - "struct Tupple { int a; int b; };\n" - "\n" - "void func() {\n" - " typedef List<Tupple> LT;\n" - " LT l;" - " @\n" - "}" - ) << _("l.u.") << QStringList({"Tupple", "a", "b"}); - - QTest::newRow("template_6") << _( - "class Item\n" - "{\n" - " int i;\n" - "};\n" - "\n" - "template <typename T>\n" - "class Container\n" - "{\n" - " T get();\n" - "};\n" - "\n" - "template <typename T> class Container;\n" - "\n" - "class ItemContainer: public Container<Item>\n" - "{};\n" - "ItemContainer container;\n" - "@\n" - ) << _("container.get().") << QStringList({"Item", "i"}); - - QTest::newRow("template_7") << _( - "struct Test\n" - "{\n" - " int i;\n" - "};\n" - "\n" - "template<typename T>\n" - "struct TemplateClass\n" - "{\n" - " T* ptr;\n" - "\n" - " typedef T element_type;\n" - " TemplateClass(T* t) : ptr(t) {}\n" - " element_type* operator->()\n" - " {\n" - " return ptr;\n" - " }\n" - "};\n" - "\n" - "TemplateClass<Test> p(new Test);\n" - "@\n" - ) << _("p->") << QStringList({"Test", "i"}); - - QTest::newRow("type_of_pointer_is_typedef") << _( - "typedef struct Foo\n" - "{\n" - " int foo;\n" - "} Foo;\n" - "Foo *bar;\n" - "@\n" - ) << _("bar->") << QStringList({"Foo", "foo"}); - - QTest::newRow("instantiate_full_specialization") << _( - "template<typename T>\n" - "struct Template\n" - "{\n" - " int templateT_i;\n" - "};\n" - "\n" - "template<>\n" - "struct Template<char>\n" - "{\n" - " int templateChar_i;\n" - "};\n" - "\n" - "Template<char> templateChar;\n" - "@\n" - ) << _("templateChar.") << QStringList({"Template", "templateChar_i"}); - - QTest::newRow("template_as_base: base as template directly") << _( - "class Data { int dataMember; };\n" - "template <class T> class Other : public T { int otherMember; };\n" - "\n" - "void func() {\n" - " Other<Data> c;\n" - " @\n" - "}" - ) << _("c.") << QStringList({"Data", "dataMember", "Other", "otherMember"}); - - QTest::newRow("template_as_base: base as class template") << _( - "class Data { int dataMember; };\n" - "template <class T> class Other : public T { int otherMember; };\n" - "template <class T> class More : public Other<T> { int moreMember; };\n" - "\n" - "void func() {\n" - " More<Data> c;\n" - " @\n" - "}" - ) << _("c.") << QStringList({"Data", "dataMember", "Other", "otherMember", "More", - "moreMember"}); - - QTest::newRow("template_as_base: base as globally qualified class template") << _( - "class Data { int dataMember; };\n" - "template <class T> class Other : public T { int otherMember; };\n" - "template <class T> class More : public ::Other<T> { int moreMember; };\n" - "\n" - "void func() {\n" - " More<Data> c;\n" - " @\n" - "}" - ) << _("c.") << QStringList({"Data", "dataMember", "Other", "otherMember", "More", - "moreMember"}); - - QTest::newRow("template_as_base: base as namespace qualified class template") << _( - "class Data { int dataMember; };\n" - "namespace NS {\n" - "template <class T> class Other : public T { int otherMember; };\n" - "}\n" - "template <class T> class More : public NS::Other<T> { int moreMember; };\n" - "\n" - "void func() {\n" - " More<Data> c;\n" - " @\n" - "}" - ) << _("c.") << QStringList({"Data", "dataMember", "Other", "otherMember", "More", - "moreMember"}); - - QTest::newRow("template_as_base: base as nested template name") << _( - "class Data { int dataMember; };\n" - "namespace NS {\n" - "template <class T> class Delegate { typedef Data<T> Type; };\n" - "}\n" - "template <class T> class Final : public NS::Delegate<T>::Type { int finalMember; };\n" - "\n" - "void func() {\n" - " Final<Data> c;\n" - " @\n" - "}" - ) << _("c.") << QStringList({"Data", "dataMember", "Final", "finalMember"}); - - QTest::newRow("template_as_base: base as nested template name in non-template") << _( - "class Data { int dataMember; };\n" - "namespace NS {\n" - "template <class T> class Delegate { typedef Data<T> Type; };\n" - "}\n" - "class Final : public NS::Delegate<Data>::Type { int finalMember; };\n" - "\n" - "void func() {\n" - " Final c;\n" - " @\n" - "}" - ) << _("c.") << QStringList({"Data", "dataMember", "Final", "finalMember"}); - - QTest::newRow("template_as_base: base as template name in non-template") << _( - "class Data { int dataMember; };\n" - "namespace NS {\n" - "template <class T> class Other : public T { int otherMember; };\n" - "}\n" - "class Final : public NS::Other<Data> { int finalMember; };\n" - "\n" - "void func() {\n" - " Final c;\n" - " @\n" - "}" - ) << _("c.") << QStringList({"Data", "dataMember", "Final", "finalMember", "Other", - "otherMember"}); - - QTest::newRow("template_as_base: typedef not available in derived") << _( - "class Data { int dataMember; };\n" - "template <class T> struct Base { typedef T F; };\n" - "template <class T> struct Derived : Base<T> { F f; };\n" - "\n" - "void func() {\n" - " Derived<Data> d;\n" - " @\n" - "}\n" - ) << _("d.f.") << QStringList(); - - QTest::newRow("template_as_base: explicit typedef from base") << _( - "class Data { int dataMember; };\n" - "template <class T> struct Base { typedef T F; };\n" - "template <class T> struct Derived : Base<T>\n" - "{\n" - " typedef typename Base<T>::F F;\n" - " F f;\n" - "};\n" - "\n" - "void func() {\n" - " Derived<Data> d;\n" - " @\n" - "}\n" - ) << _("d.f.") << QStringList({"Data", "dataMember"}); - - QTest::newRow("use_global_identifier_as_base_class: derived as global and base as global") << _( - "struct Global\n" - "{\n" - " int int_global;\n" - "};\n" - "\n" - "struct Final : ::Global\n" - "{\n" - " int int_final;\n" - "};\n" - "\n" - "Final c;\n" - "@\n" - ) << _("c.") << QStringList({"int_global", "int_final", "Final", "Global"}); - - QTest::newRow("use_global_identifier_as_base_class: derived is inside namespace. " - "base as global") << _( - "struct Global\n" - "{\n" - " int int_global;\n" - "};\n" - "\n" - "namespace NS\n" - "{\n" - "struct Final : ::Global\n" - "{\n" - " int int_final;\n" - "};\n" - "}\n" - "\n" - "NS::Final c;\n" - "@\n" - ) << _("c.") << QStringList({"int_global", "int_final", "Final", "Global"}); - - QTest::newRow("use_global_identifier_as_base_class: derived is enclosed by template. " - "base as global") << _( - "struct Global\n" - "{\n" - " int int_global;\n" - "};\n" - "\n" - "template <typename T>\n" - "struct Enclosing\n" - "{\n" - "struct Final : ::Global\n" - "{\n" - " int int_final;\n" - "};\n" - "};\n" - "\n" - "Enclosing<int>::Final c;\n" - "@\n" - ) << _("c.") << QStringList({"int_global", "int_final", "Final", "Global"}); - - QTest::newRow("base_class_has_name_the_same_as_derived: base class is derived class") << _( - "struct A : A\n" - "{\n" - " int int_a;\n" - "};\n" - "\n" - "A c;\n" - "@\n" - ) << _("c.") << QStringList({"int_a", "A"}); - - QTest::newRow("base_class_has_name_the_same_as_derived: base class is derived class. " - "class is in namespace") << _( - "namespace NS\n" - "{\n" - "struct A : A\n" - "{\n" - " int int_a;\n" - "};\n" - "}\n" - "\n" - "NS::A c;\n" - "@\n" - ) << _("c.") << QStringList({"int_a", "A"}); - - QTest::newRow("base_class_has_name_the_same_as_derived: base class is derived class. " - "class is in namespace. use scope operator for base class") << _( - "namespace NS\n" - "{\n" - "struct A : NS::A\n" - "{\n" - " int int_a;\n" - "};\n" - "}\n" - "\n" - "NS::A c;\n" - "@\n" - ) << _("c.") << QStringList({"int_a", "A"}); - - QTest::newRow("base_class_has_name_the_same_as_derived: base class has the same name as " - "derived but in different namespace") << _( - "namespace NS1\n" - "{\n" - "struct A\n" - "{\n" - " int int_ns1_a;\n" - "};\n" - "}\n" - "namespace NS2\n" - "{\n" - "struct A : NS1::A\n" - "{\n" - " int int_ns2_a;\n" - "};\n" - "}\n" - "\n" - "NS2::A c;\n" - "@\n" - ) << _("c.") << QStringList({"int_ns1_a", "int_ns2_a", "A"}); - - QTest::newRow("base_class_has_name_the_same_as_derived: base class has the same name as " - "derived (in namespace) but is nested by different class") << _( - "struct Enclosing\n" - "{\n" - "struct A\n" - "{\n" - " int int_enclosing_a;\n" - "};\n" - "};\n" - "namespace NS2\n" - "{\n" - "struct A : Enclosing::A\n" - "{\n" - " int int_ns2_a;\n" - "};\n" - "}\n" - "\n" - "NS2::A c;\n" - "@\n" - ) << _("c.") << QStringList({"int_enclosing_a", "int_ns2_a", "A"}); - - QTest::newRow("base_class_has_name_the_same_as_derived: base class has the same name as " - "derived (nested) but is nested by different class") << _( - "struct EnclosingBase\n" - "{\n" - "struct A\n" - "{\n" - " int int_enclosing_base_a;\n" - "};\n" - "};\n" - "struct EnclosingDerived\n" - "{\n" - "struct A : EnclosingBase::A\n" - "{\n" - " int int_enclosing_derived_a;\n" - "};\n" - "};\n" - "\n" - "EnclosingDerived::A c;\n" - "@\n" - ) << _("c.") << QStringList({"int_enclosing_base_a", "int_enclosing_derived_a", "A"}); - - QTest::newRow("base_class_has_name_the_same_as_derived: base class is derived class. " - "class is a template") << _( - "template <typename T>\n" - "struct A : A\n" - "{\n" - " int int_a;\n" - "};\n" - "\n" - "A<int> c;\n" - "@\n" - ) << _("c.") << QStringList({"int_a", "A"}); - - QTest::newRow("cyclic_inheritance: direct cyclic inheritance") << _( - "struct B;\n" - "struct A : B { int _a; };\n" - "struct B : A { int _b; };\n" - "\n" - "A c;\n" - "@\n" - ) << _("c.") << QStringList({"A", "_a", "B", "_b"}); - - QTest::newRow("cyclic_inheritance: indirect cyclic inheritance") << _( - "struct C;\n" - "struct A : C { int _a; };\n" - "struct B : A { int _b; };\n" - "struct C : B { int _c; };\n" - "\n" - "A c;\n" - "@\n" - ) << _("c.") << QStringList({"A", "_a", "B", "_b", "C", "_c"}); - - QTest::newRow("cyclic_inheritance: indirect cyclic inheritance") << _( - "struct B;\n" - "struct A : B { int _a; };\n" - "struct C { int _c; };\n" - "struct B : C, A { int _b; };\n" - "\n" - "A c;\n" - "@\n" - ) << _("c.") << QStringList({"A", "_a", "B", "_b", "C", "_c"}); - - QTest::newRow("cyclic_inheritance: direct cyclic inheritance with templates") << _( - "template< typename T > struct C;\n" - "template< typename T, typename S > struct D : C< S >\n" - "{\n" - " T _d_t;\n" - " S _d_s;\n" - "};\n" - "template< typename T > struct C : D< T, int >\n" - "{\n" - " T _c_t;\n" - "};\n" - "\n" - "D<int, float> c;\n" - "@\n" - ) << _("c.") << QStringList({"D", "_d_t", "_d_s", "C", "_c_t"}); - - QTest::newRow("cyclic_inheritance: indirect cyclic inheritance with templates") << _( - "template< typename T > struct C;\n" - "template< typename T, typename S > struct D : C< S >\n" - "{\n" - " T _d_t;\n" - " S _d_s;\n" - "};\n" - "template< typename T > struct B : D< T, int >\n" - "{\n" - " T _b_t;\n" - "};\n" - "template< typename T > struct C : B<T>\n" - "{\n" - " T _c_t;\n" - "};\n" - "\n" - "D<int, float> c;\n" - "@\n" - ) << _("c.") << QStringList({"D", "_d_t", "_d_s", "C", "_c_t", "B", "_b_t"}); - - QTest::newRow("cyclic_inheritance: direct cyclic inheritance with templates. " - "more complex situation") << _( - "namespace NS\n" - "{\n" - "template <typename T> struct SuperClass\n" - "{\n" - " typedef T Type;\n" - " Type super_class_type;\n" - "};\n" - "}\n" - "\n" - "template <typename T>\n" - "struct Class;\n" - "\n" - "template <typename T, typename S>\n" - "struct ClassRecurse : Class<S>\n" - "{\n" - " T class_recurse_t;\n" - " S class_recurse_s;\n" - "};\n" - "\n" - "template <typename T>\n" - "struct Class : ClassRecurse< T, typename ::NS::SuperClass<T>::Type >\n" - "{\n" - " T class_t;\n" - "};\n" - "\n" - "Class<int> c;\n" - "@\n" - ) << _("c.") << QStringList({"Class", "ClassRecurse", "class_t", "class_recurse_s", - "class_recurse_t"}); - - QTest::newRow("enclosing_template_class: nested class with enclosing template class") << _( - "template<typename T>\n" - "struct Enclosing\n" - "{\n" - " struct Nested { int int_nested; }; \n" - " int int_enclosing;\n" - "};\n" - "\n" - "Enclosing<int>::Nested c;" - "@\n" - ) << _("c.") << QStringList({"Nested", "int_nested"}); - - QTest::newRow("enclosing_template_class: nested template class with enclosing template " - "class") << _( - "template<typename T>\n" - "struct Enclosing\n" - "{\n" - " template<typename T> struct Nested { int int_nested; }; \n" - " int int_enclosing;\n" - "};\n" - "\n" - "Enclosing<int>::Nested<int> c;" - "@\n" - ) << _("c.") << QStringList({"Nested", "int_nested"}); - - QTest::newRow("instantiate_nested_class_when_enclosing_is_template") << _( - "struct Foo \n" - "{\n" - " int foo_i;\n" - "};\n" - "\n" - "template <typename T>\n" - "struct Enclosing\n" - "{\n" - " struct Nested\n" - " {\n" - " T nested_t;\n" - " } nested;\n" - "\n" - " T enclosing_t;\n" - "};\n" - "\n" - "Enclosing<Foo> enclosing;\n" - "@\n" - ) << _("enclosing.nested.nested_t.") << QStringList({"Foo", "foo_i"}); - - QTest::newRow("instantiate_nested_of_nested_class_when_enclosing_is_template") << _( - "struct Foo \n" - "{\n" - " int foo_i;\n" - "};\n" - "\n" - "template <typename T>\n" - "struct Enclosing\n" - "{\n" - " struct Nested\n" - " {\n" - " T nested_t;\n" - " struct NestedNested\n" - " {\n" - " T nestedNested_t;\n" - " } nestedNested;\n" - " } nested;\n" - "\n" - " T enclosing_t;\n" - "};\n" - "\n" - "Enclosing<Foo> enclosing;\n" - "@\n" - ) << _("enclosing.nested.nestedNested.nestedNested_t.") << QStringList({"Foo", "foo_i"}); - - QTest::newRow("instantiate_template_with_default_argument_type") << _( - "struct Foo\n" - "{\n" - " int bar;\n" - "};\n" - "\n" - "template <typename T = Foo>\n" - "struct Template\n" - "{\n" - " T t;\n" - "};\n" - "\n" - "Template<> templateWithDefaultTypeOfArgument;\n" - "@\n" - ) << _("templateWithDefaultTypeOfArgument.t.") << QStringList({"Foo", "bar"}); - - QTest::newRow("instantiate_template_with_default_argument_type_as_template") << _( - "struct Foo\n" - "{\n" - " int bar;\n" - "};\n" - "\n" - "template <typename T>\n" - "struct TemplateArg\n" - "{\n" - " T t;\n" - "};\n" - "template <typename T, typename S = TemplateArg<T> >\n" - "struct Template\n" - "{\n" - " S s;\n" - "};\n" - "\n" - "Template<Foo> templateWithDefaultTypeOfArgument;\n" - "@\n" - ) << _("templateWithDefaultTypeOfArgument.s.t.") << QStringList({"Foo", "bar"}); - - QTest::newRow("typedef_of_pointer") << _( - "struct Foo { int bar; };\n" - "typedef Foo *FooPtr;\n" - "void main()\n" - "{\n" - " FooPtr ptr;\n" - " @\n" - "}" - ) << _("ptr->") << QStringList({"Foo", "bar"}); - - QTest::newRow("typedef_of_pointer_inside_function") << _( - "struct Foo { int bar; };\n" - "void f()\n" - "{\n" - " typedef Foo *FooPtr;\n" - " FooPtr ptr;\n" - " @\n" - "}" - ) << _("ptr->") << QStringList({"Foo", "bar"}); - - QTest::newRow("typedef_is_inside_function_before_declaration_block") << _( - "struct Foo { int bar; };\n" - "void f()\n" - "{\n" - " typedef Foo *FooPtr;\n" - " if (true) {\n" - " FooPtr ptr;\n" - " @\n" - " }" - "}" - ) << _("ptr->") << QStringList({"Foo", "bar"}); - - QTest::newRow("resolve_complex_typedef_with_template") << _( - "template <typename T>\n" - "struct Template2\n" - "{\n" - " typedef typename T::template Template1<T>::TT TemplateTypedef;\n" - " TemplateTypedef templateTypedef;\n" - "};\n" - "struct Foo\n" - "{\n" - " int bar;\n" - " template <typename T>\n" - " struct Template1\n" - " {\n" - " typedef T TT;\n" - " };\n" - "};\n" - "void fun()\n" - "{\n" - " Template2<Foo> template2;\n" - " @\n" - "}\n" - ) << _("template2.templateTypedef.") << QStringList({"Foo", "bar", "Template1"}); - - QTest::newRow("template_specialization_with_pointer") << _( - "template <typename T>\n" - "struct Template\n" - "{\n" - " T variable;\n" - "};\n" - "template <typename T>\n" - "struct Template<T *>\n" - "{\n" - " T *pointer;\n" - "};\n" - "Template<int*> templ;\n" - "@\n" - ) << _("templ.") << QStringList({"Template", "pointer"}); - - QTest::newRow("typedef_using_templates1") << _( - "namespace NS1\n" - "{\n" - "template<typename T>\n" - "struct NS1Struct\n" - "{\n" - " typedef T *pointer;\n" - " pointer bar;\n" - "};\n" - "}\n" - "namespace NS2\n" - "{\n" - "using NS1::NS1Struct;\n" - "\n" - "template <typename T>\n" - "struct NS2Struct\n" - "{\n" - " typedef NS1Struct<T> NS1StructTypedef;\n" - " typedef typename NS1StructTypedef::pointer pointer;\n" - " pointer p;\n" - "};\n" - "}\n" - "struct Foo\n" - "{\n" - " int bar;\n" - "};\n" - "void fun()\n" - "{\n" - " NS2::NS2Struct<Foo> s;\n" - " @\n" - "}\n" - ) << _("s.p->") << QStringList({"Foo", "bar"}); - - QTest::newRow("typedef_using_templates2") << _( - "namespace NS1\n" - "{\n" - "template<typename T>\n" - "struct NS1Struct\n" - "{\n" - " typedef T *pointer;\n" - " pointer bar;\n" - "};\n" - "}\n" - "namespace NS2\n" - "{\n" - "using NS1::NS1Struct;\n" - "\n" - "template <typename T>\n" - "struct NS2Struct\n" - "{\n" - " typedef NS1Struct<T> NS1StructTypedef;\n" - " typedef typename NS1StructTypedef::pointer pointer;\n" - " pointer p;\n" - "};\n" - "}\n" - "struct Foo\n" - "{\n" - " int bar;\n" - "};\n" - "void fun()\n" - "{\n" - " NS2::NS2Struct<Foo>::pointer p;\n" - " @\n" - "}\n" - ) << _("p->") << QStringList({"Foo", "bar"}); - - QTest::newRow("namespace_alias_with_many_namespace_declarations") << _( - "namespace NS1\n" - "{\n" - "namespace NS2\n" - "{\n" - "struct Foo1\n" - "{\n" - " int bar1;\n" - "};\n" - "}\n" - "}\n" - "namespace NS1\n" - "{\n" - "namespace NS2\n" - "{\n" - "struct Foo2\n" - "{\n" - " int bar2;\n" - "};\n" - "}\n" - "}\n" - "namespace NS = NS1::NS2;\n" - "int main()\n" - "{\n" - " @\n" - "}\n" - ) << _("NS::") << QStringList({"Foo1", "Foo2"}); - - QTest::newRow("QTCREATORBUG9098") << _( - "template <typename T>\n" - "class B\n" - "{\n" - "public:\n" - " C<T> c;\n" - "};\n" - "template <typename T>\n" - "class A\n" - "{\n" - "public:\n" - " B<T> b;\n" - " void fun()\n" - " {\n" - " @\n" - " }\n" - "};\n" - ) << _("b.") << QStringList({"c", "B"}); - - QTest::newRow("type_and_using_declaration: type and using declaration inside function") << _( - "namespace NS\n" - "{\n" - "struct C { int m; };\n" - "}\n" - "void foo()\n" - "{\n" - " using NS::C;\n" - " C c;\n" - " @\n" - "}\n" - ) << _("c.") << QStringList({"C", "m"}); - - QTest::newRow("type_and_using_declaration: type and using declaration in global " - "namespace") << _( - "namespace NS\n" - "{\n" - "struct C { int m; };\n" - "}\n" - "using NS::C;\n" - "void foo()\n" - "{\n" - " C c;\n" - " @\n" - "}\n" - ) << _("c.") << QStringList({"C", "m"}); - - QTest::newRow("type_and_using_declaration: type in global namespace and using declaration in " - "NS namespace") << _( - "struct C { int m; };\n" - "namespace NS\n" - "{\n" - " using ::C;\n" - " void foo()\n" - " {\n" - " C c;\n" - " @\n" - " }\n" - "}\n" - ) << _("c.") << QStringList({"C", "m"}); - - QTest::newRow("type_and_using_declaration: type in global namespace and using declaration " - "inside function in NS namespace") << _( - "struct C { int m; };\n" - "namespace NS\n" - "{\n" - " void foo()\n" - " {\n" - " using ::C;\n" - " C c;\n" - " @\n" - " }\n" - "}\n" - ) << _("c.") << QStringList({"C", "m"}); - - QTest::newRow("type_and_using_declaration: type inside namespace NS1 and using declaration in " - "function inside NS2 namespace") << _( - "namespace NS1\n" - "{\n" - "struct C { int m; };\n" - "}\n" - "namespace NS2\n" - "{\n" - " void foo()\n" - " {\n" - " using NS1::C;\n" - " C c;\n" - " @\n" - " }\n" - "}\n" - ) << _("c.") << QStringList({"C", "m"}); - - QTest::newRow("type_and_using_declaration: type inside namespace NS1 and using declaration " - "inside NS2 namespace") << _( - "namespace NS1\n" - "{\n" - "struct C { int m; };\n" - "}\n" - "namespace NS2\n" - "{\n" - " using NS1::C;\n" - " void foo()\n" - " {\n" - " C c;\n" - " @\n" - " }\n" - "}\n" - ) << _("c.") << QStringList({"C", "m"}); - - QTest::newRow("instantiate_template_with_anonymous_class") << _( - "template <typename T>\n" - "struct S\n" - "{\n" - " union { int i; char c; };\n" - "};\n" - "void fun()\n" - "{\n" - " S<int> s;\n" - " @\n" - "}\n" - ) << _("s.") << QStringList({"S", "i", "c"}); - - QTest::newRow("instantiate_template_function") << _( - "template <typename T>\n" - "T* templateFunction() { return 0; }\n" - "struct A { int a; };\n" - "void foo()\n" - "{\n" - " @\n" - "}\n" - ) << _("templateFunction<A>()->") << QStringList({ "A", "a" }); - - QTest::newRow("nested_named_class_declaration_inside_function") << _( - "int foo()\n" - "{\n" - " struct Nested\n" - " {\n" - " int i;\n" - " } n;\n" - " @;\n" - "}\n" - ) << _("n.") << QStringList({"Nested", "i"}); - - QTest::newRow("nested_class_inside_member_function") << _( - "struct User { void use(); };\n" - "void User::use()\n" - "{\n" - " struct Foo { int bar; };\n" - " Foo foo;\n" - " @\n" - "}\n" - ) << _("foo.") << QStringList({"Foo", "bar"}); - - QTest::newRow("nested_typedef_inside_member_function") << _( - "struct User { void use(); };\n" - "template<class T>\n" - "struct Pointer { T *operator->(); };\n" - "struct Foo\n" - "{\n" - " typedef Pointer<Foo> Ptr;\n" - " int bar;\n" - "};\n" - "\n" - "void User::use()\n" - "{\n" - " typedef Foo MyFoo;\n" - " MyFoo::Ptr myfoo;\n" - " @\n" - "}\n" - ) << _("myfoo->") << QStringList({"Foo", "Ptr", "bar"}); - - QTest::newRow("nested_anonymous_class_QTCREATORBUG10876_1") << _( - "struct EnclosingStruct\n" - "{\n" - " int memberOfEnclosingStruct;\n" - " struct\n" - " {\n" - " int memberNestedAnonymousClass;\n" - " };\n" - " void fun()\n" - " {\n" - " @\n" - " }\n" - "};\n" - ) << _("member") << QStringList({"memberNestedAnonymousClass", - "memberOfEnclosingStruct"}); - - QTest::newRow("nested_anonymous_class_QTCREATORBUG10876_2") << _( - "struct EnclosingStruct\n" - "{\n" - " int memberOfEnclosingStruct;\n" - " struct\n" - " {\n" - " int memberOfNestedAnonymousClass;\n" - " struct\n" - " {\n" - " int memberOfNestedOfNestedAnonymousClass;\n" - " };\n" - " };\n" - " void fun()\n" - " {\n" - " @\n" - " }\n" - "};\n" - ) << _("member") << QStringList({"memberOfNestedAnonymousClass", - "memberOfNestedOfNestedAnonymousClass", - "memberOfEnclosingStruct"}); - - QTest::newRow("nested_anonymous_class_QTCREATORBUG10876_3") << _( - "struct EnclosingStruct\n" - "{\n" - " int memberOfEnclosingStruct;\n" - " struct\n" - " {\n" - " int memberOfNestedAnonymousClass;\n" - " struct\n" - " {\n" - " int memberOfNestedOfNestedAnonymousClass;\n" - " } nestedOfNestedAnonymousClass;\n" - " };\n" - " void fun()\n" - " {\n" - " @\n" - " }\n" - "};\n" - ) << _("nestedOfNestedAnonymousClass.") << QStringList("memberOfNestedOfNestedAnonymousClass"); - - QTest::newRow("nested_anonymous_class_inside_function") << _( - "void fun()\n" - "{\n" - " union\n" - " {\n" - " int foo1;\n" - " int foo2;\n" - " };\n" - " @\n" - "}\n" - ) << _("foo") << QStringList({"foo1", "foo2"}); - - QTest::newRow("crash_cloning_template_class_QTCREATORBUG9329") << _( - "struct A {};\n" - "template <typename T>\n" - "struct Templ {};\n" - "struct B : A, Templ<A>\n" - "{\n" - " int f()\n" - " {\n" - " @\n" - " }\n" - "};\n" - ) << _("this->") << QStringList({"A", "B", "Templ", "f"}); - - QTest::newRow("recursive_auto_declarations1_QTCREATORBUG9503") << _( - "void f()\n" - "{\n" - " auto object2 = object1;\n" - " auto object1 = object2;\n" - " @;\n" - "}\n" - ) << _("object1.") << QStringList(); - - QTest::newRow("recursive_auto_declarations2_QTCREATORBUG9503") << _( - "void f()\n" - "{\n" - " auto object3 = object1;\n" - " auto object2 = object3;\n" - " auto object1 = object2;\n" - " @;\n" - "}\n" - ) << _("object1.") << QStringList(); - - QTest::newRow("recursive_typedefs_declarations1") << _( - "void f()\n" - "{\n" - " typedef A B;\n" - " typedef B A;\n" - " A a;\n" - " @;\n" - "}\n" - ) << _("a.") << QStringList(); - - QTest::newRow("recursive_typedefs_declarations2") << _( - "void f()\n" - "{\n" - " typedef A C;\n" - " typedef C B;\n" - " typedef B A;\n" - " A a;\n" - " @;\n" - "}\n" - ) << _("a.") << QStringList(); - - QTest::newRow("recursive_using_declarations1") << _( - "void f()\n" - "{\n" - " using B = A;\n" - " using A = B;\n" - " A a;\n" - " @;\n" - "}\n" - ) << _("a.") << QStringList(); - - QTest::newRow("recursive_using_declarations2") << _( - "void f()\n" - "{\n" - " using C = A;\n" - " using B = C;\n" - " using A = B;\n" - " A a;\n" - " @;\n" - "}\n" - ) << _("a.") << QStringList(); - - QTest::newRow("recursive_using_typedef_declarations") << _( - "void f()\n" - "{\n" - " using B = A;\n" - " typedef B A;\n" - " A a;\n" - " @;\n" - "}\n" - ) << _("a.") << QStringList(); - - QTest::newRow("recursive_typedefs_in_templates1") << _( - "template<typename From>\n" - "struct simplify_type {\n" - " typedef From SimpleType;\n" - "};\n" - "\n" - "template<class To, class From>\n" - "struct cast_retty {\n" - " typedef typename cast_retty_wrap<To, From,\n" - " typename simplify_type<From>::SimpleType>::ret_type ret_type;\n" - "};\n" - "\n" - "template<class To, class From, class SimpleFrom>\n" - "struct cast_retty_wrap {\n" - " typedef typename cast_retty<To, SimpleFrom>::ret_type ret_type;\n" - "};\n" - "\n" - "void f()\n" - "{\n" - " @;\n" - "}\n" - ) << _("cast_retty<T1, T2>::ret_type.") << QStringList(); - - QTest::newRow("recursive_typedefs_in_templates2") << _( - "template<class T>\n" - "struct recursive {\n" - " typedef typename recursive<T>::ret_type ret_type;\n" - "};\n" - "\n" - "void f()\n" - "{\n" - " @;\n" - "}\n" - ) << _("recursive<T1>::ret_type.foo") << QStringList(); - - QTest::newRow("class_declaration_inside_function_or_block_QTCREATORBUG3620: " - "class definition inside function") << _( - "void foo()\n" - "{\n" - " struct C { int m; };\n" - " C c;\n" - " @\n" - "}\n" - ) << _("c.") << QStringList({"C", "m"}); - - QTest::newRow("class_declaration_inside_function_or_block_QTCREATORBUG3620: " - "class definition inside block inside function") << _( - "void foo()\n" - "{\n" - " {\n" - " struct C { int m; };\n" - " C c;\n" - " @\n" - " }\n" - "}\n" - ) << _("c.") << QStringList({"C", "m"}); - - QTest::newRow("class_declaration_inside_function_or_block_QTCREATORBUG3620: " - "class definition with the same name inside different block inside function") << _( - "void foo()\n" - "{\n" - " {\n" - " struct C { int m1; };\n" - " }\n" - " {\n" - " struct C { int m2; };\n" - " C c;\n" - " @\n" - " }\n" - "}\n" - ) << _("c.") << QStringList({"C", "m2"}); - - QTest::newRow("namespace_alias_inside_function_or_block_QTCREATORBUG166: " - "namespace alias inside function") << _( - "namespace NS1\n" - "{\n" - "namespace NS2\n" - "{\n" - " struct C\n" - " {\n" - " int m;\n" - " };\n" - "}\n" - "}\n" - "void foo()\n" - "{\n" - " namespace NS = NS1::NS2;\n" - " NS::C c;\n" - " @\n" - "}\n" - ) << _("c.") << QStringList({"C", "m"}); - - QTest::newRow("namespace_alias_inside_function_or_block_QTCREATORBUG166: " - "namespace alias inside block inside function") << _( - "namespace NS1\n" - "{\n" - "namespace NS2\n" - "{\n" - " struct C\n" - " {\n" - " int m;\n" - " };\n" - "}\n" - "}\n" - "void foo()\n" - "{\n" - " {\n" - " namespace NS = NS1::NS2;\n" - " NS::C c;\n" - " @\n" - " }\n" - "}\n" - ) << _("c.") << QStringList({"C", "m"}); - - QTest::newRow("class_declaration_inside_function_or_block_QTCREATORBUG3620_static_member") << _( - "void foo()\n" - "{\n" - " {\n" - " struct C { static void staticFun1(); int m1; };\n" - " }\n" - " {\n" - " struct C { static void staticFun2(); int m2; };\n" - " @\n" - " }\n" - "}\n" - ) << _("C::") << QStringList({"C", "staticFun2", "m2"}); - - enumTestCase( - "enum_inside_block_inside_function", - "void foo()\n" - "{\n" - " {\n" - " $\n" - " @\n" - " }\n" - "}\n" - ); - - enumTestCase( - "enum_inside_function", - "void foo()\n" - "{\n" - " $\n" - " @\n" - "}\n" - ); - - enumTestCase( - "enum_in_function_in_struct_in_function", - "void foo()\n" - "{\n" - " struct S {\n" - " void fun()\n" - " {\n" - " $\n" - " @\n" - " }\n" - " };\n" - "}\n" - ); - - enumTestCase( - "enum_inside_class", - "struct Foo\n" - "{\n" - " $\n" - " @\n" - "};\n", - "Foo::" - ); - - enumTestCase( - "enum_inside_namespace", - "namespace Ns\n" - "{\n" - " $\n" - " @\n" - "}\n", - "Ns::" - ); - - enumTestCase( - "enum_inside_member_function", - "class Foo { void func(); };\n" - "void Foo::func()\n" - "{\n" - " $\n" - " @\n" - "}\n" - ); - - enumTestCase( - "enum_in_class_accessed_in_member_func_inline", - "class Foo\n" - "{\n" - " $\n" - " void func()\n" - " {\n" - " @\n" - " }\n" - "};\n" - ); - - enumTestCase( - "enum_in_class_accessed_in_member_func", - "class Foo\n" - "{\n" - " $\n" - " void func();\n" - "};\n" - "void Foo::func()\n" - "{\n" - " @\n" - "}\n" - ); - - QTest::newRow("nested_anonymous_with___attribute__") << _( - "struct Enclosing\n" - "{\n" - " struct __attribute__((aligned(8)))\n" - " {\n" - " int i;\n" - " };\n" - "};\n" - "Enclosing e;\n" - "@\n" - ) << _("e.") << QStringList({"Enclosing", "i"}); - - QTest::newRow("lambdaCalls_1") << _( - "struct S { int bar; };\n" - "void foo()\n" - "{\n" - " @\n" - "}\n" - ) << _("[](){ return new S; } ()->") << QStringList({"S", "bar"}); - - QTest::newRow("lambdaCalls_2") << _( - "struct S { int bar; };\n" - "void foo()\n" - "{\n" - " @\n" - "}\n" - ) << _("[] { return new S; } ()->") << QStringList({"S", "bar"}); - - QTest::newRow("lambdaCalls_3") << _( - "struct S { int bar; };\n" - "void foo()\n" - "{\n" - " @\n" - "}\n" - ) << _("[]() ->S* { return new S; } ()->") << QStringList({"S", "bar"}); - - QTest::newRow("lambdaCalls_4") << _( - "struct S { int bar; };\n" - "void foo()\n" - "{\n" - " @\n" - "}\n" - ) << _("[]() throw() { return new S; } ()->") << QStringList({"S", "bar"}); - - QTest::newRow("lambdaCalls_5") << _( - "struct S { int bar; };\n" - "void foo()\n" - "{\n" - " @\n" - "}\n" - ) << _("[]() throw()->S* { return new S; } ()->") << QStringList({"S", "bar"}); - - QTest::newRow("local_type_and_member_1") << _( - "struct OtherType { int otherTypeMember; };\n" - "void foo()\n" - "{\n" - " struct LocalType\n" - " {\n" - " int localTypeMember;\n" - " OtherType ot;\n" - " };\n" - " LocalType lt;\n" - " @\n" - "}\n" - ) << _("lt.ot.") << QStringList({"OtherType", "otherTypeMember"}); - - QTest::newRow("local_type_and_member_2") << _( - "void foo()\n" - "{\n" - " struct OtherType { int otherTypeMember; };\n" - " struct LocalType\n" - " {\n" - " int localTypeMember;\n" - " OtherType ot;\n" - " };\n" - " LocalType lt;\n" - " @\n" - "}\n" - ) << _("lt.ot.") << QStringList({"OtherType", "otherTypeMember"}); - - QTest::newRow("local_type_and_member_3") << _( - "void foo()\n" - "{\n" - " struct OtherType { int otherTypeMember; };\n" - " {\n" - " struct LocalType\n" - " {\n" - " int localTypeMember;\n" - " OtherType ot;\n" - " };\n" - " LocalType lt;\n" - " @\n" - " }\n" - "}\n" - ) << _("lt.ot.") << QStringList({"OtherType", "otherTypeMember"}); - - QTest::newRow("local_type_and_member_4") << _( - "namespace NS {struct OtherType { int otherTypeMember; };}\n" - "void foo()\n" - "{\n" - " struct LocalType\n" - " {\n" - " int localTypeMember;\n" - " NS::OtherType ot;\n" - " };\n" - " LocalType lt;\n" - " @\n" - "}\n" - ) << _("lt.ot.") << QStringList({"OtherType", "otherTypeMember"}); - - QTest::newRow("local_type_and_member_5") << _( - "namespace NS {struct OtherType { int otherTypeMember; };}\n" - "void foo()\n" - "{\n" - " using namespace NS;\n" - " struct LocalType\n" - " {\n" - " int localTypeMember;\n" - " OtherType ot;\n" - " };\n" - " LocalType lt;\n" - " @\n" - "}\n" - ) << _("lt.ot.") << QStringList({"OtherType", "otherTypeMember"}); - - QTest::newRow("local_type_and_member_6") << _( - "namespace NS {struct OtherType { int otherTypeMember; };}\n" - "void foo()\n" - "{\n" - " using NS::OtherType;\n" - " struct LocalType\n" - " {\n" - " int localTypeMember;\n" - " OtherType ot;\n" - " };\n" - " LocalType lt;\n" - " @\n" - "}\n" - ) << _("lt.ot.") << QStringList({"OtherType", "otherTypeMember"}); - - QTest::newRow("template_parameter_defined_inside_scope_of_declaration_QTCREATORBUG9169_1") << _( - "struct A\n" - "{\n" - " void foo();\n" - " struct B\n" - " {\n" - " int b;\n" - " };\n" - "};\n" - "template<typename T>\n" - "struct Template\n" - "{\n" - " T* get();\n" - "};\n" - "namespace foo\n" - "{\n" - " struct B\n" - " {\n" - " int foo_b;\n" - " };\n" - "}\n" - "using namespace foo;\n" - "void A::foo()\n" - "{\n" - " Template<B> templ;\n" - " @\n" - "}\n" - ) << _("templ.get()->") << QStringList({"B", "b"}); - - QTest::newRow("template_parameter_defined_inside_scope_of_declaration_QTCREATORBUG9169_2") << _( - "struct A\n" - "{\n" - " void foo();\n" - " struct B\n" - " {\n" - " int b;\n" - " };\n" - "};\n" - "template<typename T>\n" - "struct Template\n" - "{\n" - " T t;\n" - "};\n" - "namespace foo\n" - "{\n" - " struct B\n" - " {\n" - " int foo_b;\n" - " };\n" - "}\n" - "using namespace foo;\n" - "void A::foo()\n" - "{\n" - " Template<B> templ;\n" - " @\n" - "}\n" - ) << _("templ.t.") << QStringList({"B", "b"}); - - QTest::newRow("template_parameter_defined_inside_scope_of_declaration_QTCREATORBUG8852_1") << _( - "template <typename T>\n" - "struct QList\n" - "{\n" - " T at(int i) const;\n" - "};\n" - "namespace ns\n" - "{\n" - " struct Foo { int bar; };\n" - " void foo()\n" - " {\n" - " QList<Foo> list;\n" - " @\n" - " }\n" - "}\n" - ) << _("list.at(0).") << QStringList({"Foo", "bar"}); - - QTest::newRow("template_parameter_defined_inside_scope_of_declaration_QTCREATORBUG8852_2") << _( - "template <typename T>\n" - "struct QList\n" - "{\n" - " T at(int i) const;\n" - "};\n" - "namespace ns\n" - "{\n" - " struct Foo { int bar; };\n" - " namespace nested\n" - " {\n" - " void foo()\n" - " {\n" - " QList<Foo> list;\n" - " @\n" - " }\n" - " }\n" - "}\n" - ) << _("list.at(0).") << QStringList({"Foo", "bar"}); - - QTest::newRow("template_parameter_defined_inside_scope_of_declaration_QTCREATORBUG8852_3") << _( - "template <typename T>\n" - "struct QList\n" - "{\n" - " T at(int i) const;\n" - "};\n" - "namespace ns\n" - "{\n" - " struct Foo { int bar; };\n" - "}\n" - "void foo()\n" - "{\n" - " using namespace ns;\n" - " QList<Foo> list;\n" - " @\n" - "}\n" - ) << _("list.at(0).") << QStringList({"Foo", "bar"}); - - const QByteArray commonSignalSlotCompletionTestCode = - "#define SIGNAL(a) #a\n" - "#define SLOT(a) #a\n" - "#define signals public\n" - "#define slots\n" - "#define Q_OBJECT virtual const QMetaObject *metaObject() const;" - "\n" - "namespace N {\n" - "\n" - "class Base : public QObject\n" - "{\n" - " Q_OBJECT\n" - "public:\n" - " void hiddenFunction();\n" - " void baseFunction();\n" - "signals:\n" - " void hiddenSignal();\n" - " void baseSignal1();\n" - " void baseSignal2(int newValue);\n" - "public slots:\n" - " void baseSlot1();\n" - " void baseSlot2(int newValue);\n" - "};\n" - "\n" - "class Derived : public Base\n" - "{\n" - " Q_OBJECT\n" - "public:\n" - " void hiddenFunction();\n" - " void derivedFunction();\n" - "signals:\n" - " void hiddenSignal();\n" - " void derivedSignal1();\n" - " void derivedSignal2(int newValue);\n" - "public slots:\n" - " void derivedSlot1();\n" - " void derivedSlot2(int newValue);\n" - "};\n" - "\n" - "} // namespace N\n" - "\n" - "void client()\n" - "{\n" - " N::Derived *myObject = new N::Derived;\n" - " @\n" - "}\n"; - - QTest::newRow("SIGNAL(") - << commonSignalSlotCompletionTestCode - << _("connect(myObject, SIGNAL(") << QStringList({"baseSignal1()", "baseSignal2(int)", - "hiddenSignal()", "derivedSignal1()", - "derivedSignal2(int)"}); - - QTest::newRow("SLOT(") - << commonSignalSlotCompletionTestCode - << _("connect(myObject, SIGNAL(baseSignal1()), myObject, SLOT(") - << QStringList({"baseSlot1()", "baseSlot2(int)", "derivedSlot1()", "derivedSlot2(int)"}); - - QTest::newRow("Qt5 signals: complete class after & at 2nd connect arg") - << commonSignalSlotCompletionTestCode - << _("connect(myObject, &") << QStringList("N::Derived"); - - QTest::newRow("Qt5 signals: complete class after & at 4th connect arg") - << commonSignalSlotCompletionTestCode - << _("connect(myObject, &MyObject::timeout, myObject, &") << QStringList("N::Derived"); - - QTest::newRow("Qt5 signals: complete signals") - << commonSignalSlotCompletionTestCode - << _("connect(myObject, &N::Derived::") - << QStringList({"baseSignal1", "baseSignal2", "hiddenSignal", "derivedSignal1", - "derivedSignal2"}); - - QTest::newRow("Qt5 slots") - << commonSignalSlotCompletionTestCode - << _("connect(myObject, &N::Derived, myObject, &N::Derived::") - << QStringList({"baseFunction", "baseSignal1", "baseSignal2", "baseSlot1", "baseSlot2", - "derivedFunction", "derivedSignal1", "derivedSignal2", "derivedSlot1", - "derivedSlot2", "hiddenFunction", "hiddenSignal"}); - - QTest::newRow("Qt5 signals: fallback to scope completion") - << commonSignalSlotCompletionTestCode - << _("connect(myObject, &N::") << QStringList({"Base", "Derived"}); - - QTest::newRow("Qt5 slots: fallback to scope completion") - << commonSignalSlotCompletionTestCode - << _("connect(myObject, &N::Derived, myObject, &N::") << QStringList({"Base", "Derived"}); - - QTest::newRow("signals_hide_QPrivateSignal") << _( - "#define SIGNAL(a) #a\n" - "#define SLOT(a) #a\n" - "#define signals public\n" - "#define Q_OBJECT struct QPrivateSignal {};\n" - "\n" - "class QObject\n" - "{\n" - "public:\n" - " void connect(QObject *, char *, QObject *, char *);\n" - "};\n" - "\n" - "class Timer : public QObject\n" - "{\n" - " Q_OBJECT\n" - "signals:\n" - " void timeout(QPrivateSignal);\n" - "};\n" - "\n" - "void client()\n" - "{\n" - " Timer *timer = new Timer;\n" - " @\n" - "}\n" - ) << _("connect(timer, SIGNAL(") << QStringList("timeout()"); - - QTest::newRow("member_of_class_accessed_by_using_QTCREATORBUG9037_1") << _( - "namespace NS { struct S { int member; void fun(); }; }\n" - "using NS::S;\n" - "void S::fun()\n" - "{\n" - " @\n" - "}\n" - ) << _("mem") << QStringList("member"); - - QTest::newRow("member_of_class_accessed_by_using_QTCREATORBUG9037_2") << _( - "namespace NS \n" - "{\n" - " namespace Internal\n" - " {\n" - " struct S { int member; void fun(); };\n" - " }\n" - " using Internal::S;\n" - "}\n" - "using NS::S;\n" - "void S::fun()\n" - "{\n" - " @\n" - "}\n" - ) << _("mem") << QStringList("member"); - - QTest::newRow("no_binding_block_as_instantiationOrigin_QTCREATORBUG-11424") << _( - "template <typename T>\n" - "class QVector\n" - "{\n" - "public:\n" - " inline const_iterator constBegin() const;\n" - "};\n" - "\n" - "typedef struct { double value; } V;\n" - "\n" - "double getValue(const QVector<V>& d) const {\n" - " typedef QVector<V>::ConstIterator Iter;\n" - " @\n" - "}\n" - ) << _("double val = d.constBegin()->") << QStringList(); - - QTest::newRow("nested_class_in_template_class_QTCREATORBUG-11752") << _( - "template <typename T>\n" - "struct Temp\n" - "{\n" - " struct Nested1 { T t; };\n" - " struct Nested2 { Nested1 n1; };\n" - "};\n" - "struct Foo { int foo; };\n" - "void fun() {\n" - " Temp<Foo>::Nested2 n2;\n" - " @\n" - "}\n" - ) << _("n2.n1.t.") << QStringList({"foo", "Foo"}); - - QTest::newRow("infiniteLoopLocalTypedef_QTCREATORBUG-11999") << _( - "template <typename T>\n" - "struct Temp\n" - "{\n" - " struct Nested\n" - " {\n" - " typedef Temp<T> TempT;\n" - " T t;\n" - " };\n" - " Nested nested;\n" - "};\n" - "struct Foo { int foo; };\n" - "void fun() {\n" - " Temp<Foo> tempFoo;\n" - " @\n" - "}\n" - ) << _("tempFoo.nested.t.") << QStringList({"foo", "Foo"}); - - QTest::newRow("lambda_parameter") << _( - "auto func = [](int arg1) { return @; };\n" - ) << _("ar") << QStringList("arg1"); - - QTest::newRow("default_arguments_for_class_templates_and_base_class_QTCREATORBUG-12605") << _( - "struct Foo { int foo; };\n" - "template <typename T = Foo>\n" - "struct Derived : T {};\n" - "void fun() {\n" - " Derived<> derived;\n" - " @\n" - "}\n" - ) << _("derived.") << QStringList({"Derived", "foo", "Foo"}); - - QTest::newRow("default_arguments_for_class_templates_and_template_base_class_QTCREATORBUG-12606") << _( - "struct Foo { int foo; };\n" - "template <typename T>\n" - "struct Base { T t; };\n" - "template <typename T = Foo>\n" - "struct Derived : Base<T> {};\n" - "void fun() {\n" - " Derived<> derived;\n" - " @\n" - "}\n" - ) << _("derived.t.") << QStringList({"foo", "Foo"}); - - QTest::newRow("template_specialization_and_initialization_with_pointer1") << _( - "template <typename T>\n" - "struct S {};\n" - "template <typename T>\n" - "struct S<T*> { T *t; };\n" - "struct Foo { int foo; };\n" - "void fun() {\n" - " S<Foo*> s;\n" - " @\n" - "}\n" - ) << _("s.t->") << QStringList({"foo", "Foo"}); - - // this is not a valid code(is not compile) but it caused a crash - QTest::newRow("template_specialization_and_initialization_with_pointer2") << _( - "template <typename T1, typename T2 = int>\n" - "struct S {};\n" - "template <typename T1, typename T2>\n" - "struct S<T1*> { T1 *t; };\n" - "struct Foo { int foo; };\n" - "void fun() {\n" - " S<Foo*> s;\n" - " @\n" - "}\n" - ) << _("s.t->") << QStringList({"foo", "Foo"}); - - QTest::newRow("typedef_of_pointer_of_array_QTCREATORBUG-12703") << _( - "struct Foo { int foo; };\n" - "typedef Foo *FooArr[10];\n" - "void fun() {\n" - " FooArr arr;\n" - " @\n" - "}\n" - ) << _("arr[0]->") << QStringList({"foo", "Foo"}); - - QTest::newRow("template_specialization_with_array1") << _( - "template <typename T>\n" - "struct S {};\n" - "template <typename T>\n" - "struct S<T[]> { int foo; };\n" - "void fun() {\n" - " S<int[]> s;\n" - " @\n" - "}\n" - ) << _("s.") << QStringList({"foo", "S"}); - - QTest::newRow("template_specialization_with_array2") << _( - "template <typename T>\n" - "struct S {};\n" - "template <typename T, size_t N>\n" - "struct S<T[N]> { int foo; };\n" - "void fun() {\n" - " S<int[3]> s;\n" - " @\n" - "}\n" - ) << _("s.") << QStringList({"foo", "S"}); - - QTest::newRow("template_specialization_with_array3") << _( - "struct Bar {};\n" - "template <typename T>\n" - "struct S {};\n" - "template <>\n" - "struct S<Bar[]> { int foo; };\n" - "void fun() {\n" - " S<int[]> s;\n" - " @\n" - "}\n" - ) << _("s.") << QStringList("S"); - - QTest::newRow("auto_declaration_in_if_condition") << _( - "struct Foo { int bar; };\n" - "void fun() {\n" - " if (auto s = new Foo) {\n" - " @\n" - " }\n" - "}\n" - ) << _("s->") << QStringList({"Foo", "bar"}); - - QTest::newRow("dereference_of_nested_type_opertor_*") << _( - "template<typename T>\n" - "struct QList\n" - "{\n" - " struct iterator\n" - " {\n" - " T &operator*() { return t; }\n" - " T t;\n" - " };\n" - " iterator begin() { return iterator(); }\n" - "};\n" - "struct Foo { int bar; };\n" - "void fun() {\n" - " QList<Foo> list;\n" - " @\n" - "}\n" - ) << _("(*list.begin()).") << QStringList({"Foo", "bar"}); - - QTest::newRow("dereference_of_nested_type_opertor_->") << _( - "template<typename T>\n" - "struct QList\n" - "{\n" - " struct iterator\n" - " {\n" - " T *operator->() { return &t; }\n" - " T t;\n" - " };\n" - " iterator begin() { return iterator(); }\n" - "};\n" - "struct Foo { int bar; };\n" - "void fun() {\n" - " QList<Foo> list;\n" - " @\n" - "}\n" - ) << _("list.begin()->") << QStringList({"Foo", "bar"}); - - QTest::newRow("dereference_of_nested_type_opertor_*_and_auto") << _( - "template<typename T>\n" - "struct QList\n" - "{\n" - " struct iterator\n" - " {\n" - " T &operator*() { return t; }\n" - " T t;\n" - " };\n" - " iterator begin() { return iterator(); }\n" - "};\n" - "struct Foo { int bar; };\n" - "void fun() {\n" - " QList<Foo> list;\n" - " auto a = list.begin();\n" - " @\n" - "}\n" - ) << _("(*a).") << QStringList({"Foo", "bar"}); - - QTest::newRow("dereference_of_nested_type_opertor_->_and_auto") << _( - "template<typename T>\n" - "struct QList\n" - "{\n" - " struct iterator\n" - " {\n" - " T *operator->() { return &t; }\n" - " T t;\n" - " };\n" - " iterator begin() { return iterator(); }\n" - "};\n" - "struct Foo { int bar; };\n" - "void fun() {\n" - " QList<Foo> list;\n" - " auto a = list.begin();\n" - " @\n" - "}\n" - ) << _("a->") << QStringList({"Foo", "bar"}); - - QTest::newRow("direct_nested_template_type_access") << _( - "template<typename T>\n" - "struct QList\n" - "{\n" - " struct iterator\n" - " {\n" - " T *operator->() { return &t; }\n" - " T t;\n" - " };\n" - " iterator begin() { return iterator(); }\n" - "};\n" - "struct Foo { int bar; };\n" - "void fun() {\n" - " auto a = QList<Foo>::begin();\n" - " @\n" - "}\n" - ) << _("a.") << QStringList({"operator ->", "t", "iterator"}); - - QTest::newRow("pointer_indirect_specialization") << _( - "template<typename T>\n" - "struct Traits { typedef typename T::pointer pointer; };\n" - "\n" - "template<typename _Tp>\n" - "struct Traits<_Tp*> { typedef _Tp *pointer; };\n" - "\n" - "template<typename T>\n" - "class Temp\n" - "{\n" - "protected:\n" - " typedef Traits<T> TraitsT;\n" - "\n" - "public:\n" - " typedef typename TraitsT::pointer pointer;\n" - " pointer p;\n" - "};\n" - "\n" - "struct Foo { int bar; };\n" - "\n" - "void func()\n" - "{\n" - " Temp<Foo *> t;\n" - " @\n" - "}\n" - ) << _("t.p->") << QStringList({"Foo", "bar"}); - - QTest::newRow("pointer_indirect_specialization_typedef") << _( - "template<typename T>\n" - "struct Traits { typedef typename T::pointer pointer; };\n" - "\n" - "template<typename _Tp>\n" - "struct Traits<_Tp*> { typedef _Tp *pointer; };\n" - "\n" - "struct Foo { int bar; };\n" - "\n" - "class Temp\n" - "{\n" - "protected:\n" - " typedef Foo *FooPtr;\n" - " typedef Traits<FooPtr> TraitsT;\n" - "\n" - "public:\n" - " typedef typename TraitsT::pointer pointer;\n" - " pointer p;\n" - "};\n" - "\n" - "void func()\n" - "{\n" - " Temp t;\n" - " @\n" - "}\n" - ) << _("t.p->") << QStringList({"Foo", "bar"}); - - QTest::newRow("pointer_indirect_specialization_double_indirection") << _( - "template<typename _Tp>\n" - "struct Traits { };\n" - "\n" - "template<typename _Tp>\n" - "struct Traits<_Tp*> { typedef _Tp *pointer; };\n" - "\n" - "struct Foo { int bar; };\n" - "\n" - "template<typename _Tp>\n" - "struct IndirectT\n" - "{\n" - " typedef Traits<_Tp> TraitsT;\n" - " typedef typename TraitsT::pointer pointer;\n" - " pointer p;\n" - "};\n" - "\n" - "template<typename _Tp>\n" - "struct Temp\n" - "{\n" - " typedef _Tp *pointer;\n" - " typedef IndirectT<pointer> indirect;\n" - "};\n" - "\n" - "void func()\n" - "{\n" - " Temp<Foo>::indirect t;\n" - " @\n" - "}\n" - ) << _("t.p->") << QStringList({"Foo", "bar"}); - - QTest::newRow("pointer_indirect_specialization_double_indirection_with_base") << _( - "template<typename _Tp>\n" - "struct Traits { };\n" - "\n" - "template<typename _Tp>\n" - "struct Traits<_Tp*> { typedef _Tp *pointer; };\n" - "\n" - "struct Foo { int bar; };\n" - "\n" - "template<typename _Tp>\n" - "struct IndirectT\n" - "{\n" - " typedef Traits<_Tp> TraitsT;\n" - " typedef typename TraitsT::pointer pointer;\n" - " pointer p;\n" - "};\n" - "\n" - "template<typename _Tp>\n" - "struct TempBase { typedef _Tp *pointer; };\n" - "\n" - "template<typename _Tp>\n" - "struct Temp : public TempBase<_Tp>\n" - "{\n" - " typedef TempBase<_Tp> _Base;\n" - " typedef typename _Base::pointer pointer;\n" - " typedef IndirectT<pointer> indirect;\n" - "};\n" - "\n" - "void func()\n" - "{\n" - " Temp<Foo>::indirect t;\n" - " @\n" - "}\n" - ) << _("t.p->") << QStringList({"Foo", "bar"}); - - QTest::newRow("fix_code_completion_for_unique_ptr_operator_arrow") << _( - "namespace std {\n" - "template<typename _Tp>\n" - "struct unique_ptr\n" - "{\n" - " typedef FOO pointer;\n" - " pointer operator->();\n" - "};\n" - "}\n" - "\n" - "struct Foo { int bar; };\n" - "\n" - "void func()\n" - "{\n" - " std::unique_ptr<Foo> ptr;\n" - " @\n" - "}\n" - ) << _("ptr->") << QStringList({"Foo", "bar"}); - QTest::newRow("fix_code_completion_for_unique_ptr_method_get") << _( - "namespace std {\n" - "template<typename _Tp>\n" - "struct unique_ptr\n" - "{\n" - " typedef FOO pointer;\n" - " pointer get();\n" - "};\n" - "}\n" - "\n" - "struct Foo { int bar; };\n" - "\n" - "void func()\n" - "{\n" - " std::unique_ptr<Foo> ptr;\n" - " @\n" - "}\n" - ) << _("ptr.get()->") << QStringList({"Foo", "bar"}); - QTest::newRow("fix_code_completion_for_std_vector_method_at") << _( - "namespace std {\n" - "template<typename _Tp>\n" - "struct vector\n" - "{\n" - " typedef FOO reference;\n" - " reference at(size_t i);\n" - "};\n" - "}\n" - "\n" - "struct Foo { int bar; };\n" - "\n" - "void func()\n" - "{\n" - " std::vector<Foo> v;\n" - " @\n" - "}\n" - ) << _("v.at(0).") << QStringList({"Foo", "bar"}); - QTest::newRow("fix_code_completion_for_std_vector_operator_square_brackets") << _( - "namespace std {\n" - "template<typename _Tp>\n" - "struct vector\n" - "{\n" - " typedef FOO reference;\n" - " reference operator[](size_t i);\n" - "};\n" - "}\n" - "\n" - "struct Foo { int bar; };\n" - "\n" - "void func()\n" - "{\n" - " std::vector<Foo> v;\n" - " @\n" - "}\n" - ) << _("v[0].") << QStringList({"Foo", "bar"}); - QTest::newRow("fix_code_completion_for_std_list_method_front") << _( - "namespace std {\n" - "template<typename _Tp>\n" - "struct list\n" - "{\n" - " typedef FOO reference;\n" - " reference front();\n" - "};\n" - "}\n" - "\n" - "struct Foo { int bar; };\n" - "\n" - "void func()\n" - "{\n" - " std::list<Foo> l;\n" - " @\n" - "}\n" - ) << _("l.front().") << QStringList({"Foo", "bar"}); - QTest::newRow("fix_code_completion_for_std_queue_method_front") << _( - "namespace std {\n" - "template<typename _Tp>\n" - "struct queue\n" - "{\n" - " typedef FOO reference;\n" - " reference front();\n" - "};\n" - "}\n" - "\n" - "struct Foo { int bar; };\n" - "\n" - "void func()\n" - "{\n" - " std::queue<Foo> l;\n" - " @\n" - "}\n" - ) << _("l.front().") << QStringList({"Foo", "bar"}); - QTest::newRow("fix_code_completion_for_std_set_method_begin") << _( - "namespace std {\n" - "template<typename _Tp>\n" - "struct set\n" - "{\n" - " typedef FOO iterator;\n" - " iterator begin();\n" - "};\n" - "}\n" - "\n" - "struct Foo { int bar; };\n" - "\n" - "void func()\n" - "{\n" - " std::set<Foo> s;\n" - " @\n" - "}\n" - ) << _("s.begin()->") << QStringList({"Foo", "bar"}); - QTest::newRow("fix_code_completion_for_std_multiset_method_begin") << _( - "namespace std {\n" - "template<typename _Tp>\n" - "struct multiset\n" - "{\n" - " typedef FOO iterator;\n" - " iterator begin();\n" - "};\n" - "}\n" - "\n" - "struct Foo { int bar; };\n" - "\n" - "void func()\n" - "{\n" - " std::multiset<Foo> s;\n" - " @\n" - "}\n" - ) << _("s.begin()->") << QStringList({"Foo", "bar"}); - QTest::newRow("fix_code_completion_for_std_unordered_set_method_begin") << _( - "namespace std {\n" - "template<typename _Tp>\n" - "struct unordered_set\n" - "{\n" - " typedef FOO iterator;\n" - " iterator begin();\n" - "};\n" - "}\n" - "\n" - "struct Foo { int bar; };\n" - "\n" - "void func()\n" - "{\n" - " std::unordered_set<Foo> s;\n" - " @\n" - "}\n" - ) << _("s.begin()->") << QStringList({"Foo", "bar"}); -} - -void CompletionTest::testCompletionMemberAccessOperator() -{ - QFETCH(QByteArray, code); - QFETCH(QByteArray, prefix); - QFETCH(QStringList, expectedCompletions); - QFETCH(bool, isObjC); - QFETCH(bool, expectedReplaceAccessOperator); - - CompletionTestCase test(code, prefix, isObjC); - QVERIFY(test.succeededSoFar()); - - bool replaceAccessOperator = false; - QStringList completions = test.getCompletions(&replaceAccessOperator); - - completions.sort(); - expectedCompletions.sort(); - - QCOMPARE(completions, expectedCompletions); - QCOMPARE(replaceAccessOperator, expectedReplaceAccessOperator); -} - -void CompletionTest::testCompletionMemberAccessOperator_data() -{ - QTest::addColumn<QByteArray>("code"); - QTest::addColumn<QByteArray>("prefix"); - QTest::addColumn<QStringList>("expectedCompletions"); - QTest::addColumn<bool>("isObjC"); - QTest::addColumn<bool>("expectedReplaceAccessOperator"); - - QTest::newRow("member_access_operator") << _( - "struct S { void t(); };\n" - "void f() { S *s;\n" - "@\n" - "}\n" - ) << _("s.") << QStringList({ "S", "t" }) - << false - << true; - - QTest::newRow("objc_not_replacing") << _( - "typedef struct objc_object Bar;" - "class Foo {\n" - " Bar *bar;\n" - " void func() { @ }" - "};\n" - ) << _("bar.") << QStringList() - << true - << false; - - QTest::newRow("typedef_of_type_and_decl_of_type_no_replace_access_operator") << _( - "struct S { int m; };\n" - "typedef S SType;\n" - "SType p;\n" - "@\n" - ) << _("p.") << QStringList({"S", "m"}) - << false - << false; - - QTest::newRow("typedef_of_pointer_and_decl_of_pointer_no_replace_access_operator") << _( - "struct S { int m; };\n" - "typedef S *SType;\n" - "SType *p;\n" - "@\n" - ) << _("p.") << QStringList() - << false - << false; - - QTest::newRow("typedef_of_type_and_decl_of_pointer_replace_access_operator") << _( - "struct S { int m; };\n" - "typedef S SType;\n" - "SType *p;\n" - "@\n" - ) << _("p.") << QStringList({"S", "m"}) - << false - << true; - - QTest::newRow("typedef_of_pointer_and_decl_of_type_replace_access_operator") << _( - "struct S { int m; };\n" - "typedef S* SPtr;\n" - "SPtr p;\n" - "@\n" - ) << _("p.") << QStringList({"S", "m"}) - << false - << true; - - QTest::newRow("predecl_typedef_of_type_and_decl_of_pointer_replace_access_operator") << _( - "typedef struct S SType;\n" - "struct S { int m; };\n" - "SType *p;\n" - "@\n" - ) << _("p.") << QStringList({"S", "m"}) - << false - << true; - - QTest::newRow("predecl_typedef_of_type_and_decl_type_no_replace_access_operator") << _( - "typedef struct S SType;\n" - "struct S { int m; };\n" - "SType p;\n" - "@\n" - ) << _("p.") << QStringList({"S", "m"}) - << false - << false; - - QTest::newRow("predecl_typedef_of_pointer_and_decl_of_pointer_no_replace_access_operator") << _( - "typedef struct S *SType;\n" - "struct S { int m; };\n" - "SType *p;\n" - "@\n" - ) << _("p.") << QStringList() - << false - << false; - - QTest::newRow("predecl_typedef_of_pointer_and_decl_of_type_replace_access_operator") << _( - "typedef struct S *SType;\n" - "struct S { int m; };\n" - "SType p;\n" - "@\n" - ) << _("p.") << QStringList({"S", "m"}) - << false - << true; - - QTest::newRow("typedef_of_pointer_of_type_replace_access_operator") << _( - "struct S { int m; };\n" - "typedef struct S SType;\n" - "typedef struct SType *STypePtr;\n" - "STypePtr p;\n" - "@\n" - ) << _("p.") << QStringList({"S", "m"}) - << false - << true; - - QTest::newRow("typedef_of_pointer_of_type_no_replace_access_operator") << _( - "struct S { int m; };\n" - "typedef struct S SType;\n" - "typedef struct SType *STypePtr;\n" - "STypePtr p;\n" - "@\n" - ) << _("p->") << QStringList({"S", "m"}) - << false - << false; -} |