diff --git a/src/plugins/cpptools/cpplocalsymbols_test.cpp b/src/plugins/cpptools/cpplocalsymbols_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..eb986b8430a1d7db2813d021ad4c08487a48744d --- /dev/null +++ b/src/plugins/cpptools/cpplocalsymbols_test.cpp @@ -0,0 +1,186 @@ +/**************************************************************************** +** +** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** 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 Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +****************************************************************************/ + +#include "cpptoolsplugin.h" + +#include "cpplocalsymbols.h" +#include "cppsemanticinfo.h" + +#include +#include + +#include + +namespace { + +class FindFirstFunctionDefinition: protected CPlusPlus::ASTVisitor +{ +public: + FindFirstFunctionDefinition(CPlusPlus::TranslationUnit *translationUnit) + : ASTVisitor(translationUnit) + , m_definition(0) + {} + + CPlusPlus::FunctionDefinitionAST *operator()() + { + accept(translationUnit()->ast()); + return m_definition; + } + +private: + bool preVisit(CPlusPlus::AST *ast) + { + if (CPlusPlus::FunctionDefinitionAST *f = ast->asFunctionDefinition()) { + m_definition = f; + return false; + } + return true; + } + +private: + CPlusPlus::FunctionDefinitionAST *m_definition; +}; + +struct Result +{ + Result() : line(0), column(0), length(0) {} + Result(const QByteArray &name, unsigned line, unsigned column, unsigned length) + : name(name), line(line), column(column), length(length) + {} + + QByteArray name; + unsigned line; + unsigned column; + unsigned length; + + bool operator==(const Result &other) const + { + return name == other.name + && line == other.line + && column == other.column + && length == other.length; + } + + static Result fromHighlightingResult(const CPlusPlus::Symbol *symbol, + TextEditor::HighlightingResult result) + { + const QByteArray name = CPlusPlus::Overview().prettyName(symbol->name()).toLatin1(); + return Result(name, result.line, result.column, result.length); + } + + static QList fromLocalUses(CppTools::SemanticInfo::LocalUseMap localUses) + { + QList result; + + CppTools::SemanticInfo::LocalUseIterator it(localUses); + while (it.hasNext()) { + it.next(); + const CPlusPlus::Symbol *symbol = it.key(); + const QList &uses = it.value(); + foreach (const CppTools::SemanticInfo::Use &use, uses) + result << fromHighlightingResult(symbol, use); + } + + Utils::sort(result, [](const Result &r1, const Result &r2) { + if (r1.line == r2.line) + return r1.column < r2.column; + return r1.line < r2.line; + }); + return result; + } +}; + +} // anonymous namespace + +Q_DECLARE_METATYPE(Result) +Q_DECLARE_METATYPE(QList) + +namespace QTest { + template<> + char *toString(const Result &result) + { + QByteArray ba = "Result("; + ba += "_(\"" + result.name + "\"), "; + ba += QByteArray::number(result.line) + ", "; + ba += QByteArray::number(result.column) + ", "; + ba += QByteArray::number(result.length) + ")"; + return qstrdup(ba.data()); + } +} + +namespace CppTools { +namespace Internal { + +void CppToolsPlugin::test_cpplocalsymbols_data() +{ + QTest::addColumn("source"); + QTest::addColumn>("expectedUses"); + + typedef QByteArray _; + + QTest::newRow("basic") + << _("int f(int arg)\n" + "{\n" + " int local;\n" + " g(&local);\n" + " return local + arg;\n" + "}\n") + << (QList() + << Result(_("arg"), 0, 10, 3) + << Result(_("local"), 2, 9, 5) + << Result(_("local"), 3, 8, 5) + << Result(_("local"), 4, 12, 5) + << Result(_("arg"), 4, 20, 3)); +} + +void CppToolsPlugin::test_cpplocalsymbols() +{ + QFETCH(QByteArray, source); + QFETCH(QList, expectedUses); + + CPlusPlus::Document::Ptr document = CPlusPlus::Document::create(QLatin1String("test.cpp")); + document->setUtf8Source(source); + document->check(); + QVERIFY(document->diagnosticMessages().isEmpty()); + QVERIFY(document->translationUnit()); + QVERIFY(document->translationUnit()->ast()); + QVERIFY(document->globalNamespace()); + FindFirstFunctionDefinition find(document->translationUnit()); + CPlusPlus::DeclarationAST *functionDefinition = find(); + + LocalSymbols localSymbols(document, functionDefinition); + + const QList actualUses = Result::fromLocalUses(localSymbols.uses); +// foreach (const Result &result, actualUses) +// qDebug() << QTest::toString(result); + QCOMPARE(actualUses, expectedUses); +} + +} // namespace Internal +} // namespace CppTools diff --git a/src/plugins/cpptools/cpptools.pro b/src/plugins/cpptools/cpptools.pro index e528f3e3d6caab44085700dfd30c15b806887466..451be6722560fb9dc6b4892425515bf253dde625 100644 --- a/src/plugins/cpptools/cpptools.pro +++ b/src/plugins/cpptools/cpptools.pro @@ -128,6 +128,7 @@ equals(TEST, 1) { cppcodegen_test.cpp \ cppcompletion_test.cpp \ cppheadersource_test.cpp \ + cpplocalsymbols_test.cpp \ cpplocatorfilter_test.cpp \ cppmodelmanager_test.cpp \ cpppointerdeclarationformatter_test.cpp \ diff --git a/src/plugins/cpptools/cpptools.qbs b/src/plugins/cpptools/cpptools.qbs index 53fc46f23c0c491403db96b1a81621784598c9f0..92c4b30391088074585fd3924a6c1912c887237b 100644 --- a/src/plugins/cpptools/cpptools.qbs +++ b/src/plugins/cpptools/cpptools.qbs @@ -87,6 +87,7 @@ QtcPlugin { "cppcodegen_test.cpp", "cppcompletion_test.cpp", "cppheadersource_test.cpp", + "cpplocalsymbols_test.cpp", "cpplocatorfilter_test.cpp", "cppmodelmanager_test.cpp", "cpppointerdeclarationformatter_test.cpp", diff --git a/src/plugins/cpptools/cpptoolsplugin.h b/src/plugins/cpptools/cpptoolsplugin.h index a3e137c640eb975c22fb6fe03555555a087c6cdd..3d54eb0cdee5e85b26f700bc126868ab35395cc6 100644 --- a/src/plugins/cpptools/cpptoolsplugin.h +++ b/src/plugins/cpptools/cpptoolsplugin.h @@ -162,6 +162,9 @@ private slots: void test_typehierarchy_data(); void test_typehierarchy(); + void test_cpplocalsymbols_data(); + void test_cpplocalsymbols(); + void test_includeGroups_detectIncludeGroupsByNewLines(); void test_includeGroups_detectIncludeGroupsByIncludeDir(); void test_includeGroups_detectIncludeGroupsByIncludeType();