Files
qt-creator/src/plugins/cpptools/cpptoolsplugin.h

190 lines
6.7 KiB
C
Raw Normal View History

/****************************************************************************
2008-12-02 12:01:29 +01:00
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
2008-12-02 12:01:29 +01:00
**
** This file is part of Qt Creator.
2008-12-02 12:01:29 +01:00
**
** 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.
2010-12-17 16:01:08 +01:00
**
****************************************************************************/
2008-12-02 15:08:31 +01:00
#pragma once
2008-12-02 12:01:29 +01:00
#include "cpptools_global.h"
#include "stringtable.h"
#include <projectexplorer/projectexplorer.h>
#include <QSharedPointer>
2008-12-02 12:01:29 +01:00
QT_BEGIN_NAMESPACE
class QFileInfo;
class QDir;
QT_END_NAMESPACE
namespace Utils { class FileName; }
2008-12-02 12:01:29 +01:00
namespace CppTools {
class CppToolsSettings;
class CppCodeModelSettings;
2008-12-02 12:01:29 +01:00
namespace Internal {
struct CppFileSettings;
2008-12-02 12:01:29 +01:00
class CppToolsPlugin : public ExtensionSystem::IPlugin
2008-12-02 12:01:29 +01:00
{
Q_OBJECT
Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QtCreatorPlugin" FILE "CppTools.json")
2008-12-02 12:01:29 +01:00
public:
CppToolsPlugin();
~CppToolsPlugin();
static CppToolsPlugin *instance();
static const QStringList &headerSearchPaths();
static const QStringList &sourceSearchPaths();
static const QStringList &headerPrefixes();
static const QStringList &sourcePrefixes();
static void clearHeaderSourceCache();
static Utils::FileName licenseTemplatePath();
static QString licenseTemplate();
bool initialize(const QStringList &arguments, QString *errorMessage);
2008-12-02 12:01:29 +01:00
void extensionsInitialized();
ShutdownFlag aboutToShutdown();
2008-12-02 12:01:29 +01:00
QSharedPointer<CppCodeModelSettings> codeModelSettings() const;
static StringTable &stringTable();
public slots:
2008-12-02 12:01:29 +01:00
void switchHeaderSource();
void switchHeaderSourceInNextSplit();
#ifdef WITH_TESTS
private slots:
// Init/Cleanup methods implemented in cppheadersource_test.cpp
void initTestCase();
void cleanupTestCase();
void test_codegen_public_in_empty_class();
void test_codegen_public_in_nonempty_class();
void test_codegen_public_before_protected();
void test_codegen_private_after_protected();
void test_codegen_protected_in_nonempty_class();
void test_codegen_protected_between_public_and_private();
void test_codegen_qtdesigner_integration();
void test_codegen_definition_empty_class();
void test_codegen_definition_first_member();
void test_codegen_definition_last_member();
void test_codegen_definition_middle_member();
void test_codegen_definition_middle_member_surrounded_by_undefined();
void test_codegen_definition_member_specific_file();
void test_completion_basic_1();
CppTools: Make completion tests data-driven Mostly done using the following Ruby script: Fname = 'src/plugins/cpptools/cppcompletion_test.cpp' s = File.read(Fname) mod = s.gsub(/(?<declaration>void CppToolsPlugin::test_(?<test_name>[^(]+)\(\)\n\{)(?<body>.*?\n)\}/m) { |func| match = $~ declaration = match['declaration'] body = match['body'] test_name = match['test_name'].sub('_data', '') final = body.gsub(/(?:completions.clear\(\);\s+)?(?: +)[^\n]* =\n(?<code>.*?);\s*(?<completions>(?:completions.append\(QLatin1String\("[^"]*"\)\);\s*)*)QTest::newRow\("case: (?<name>.+?)"\)\s*<< code << _\("(?<prefix>[^"]+)"\) << completions;/m) { m = $~ res = " QTest::newRow(\"#{test_name}: #{m['name']}\") << _(\n#{m['code'].rstrip}\n ) << _(\"#{m['prefix']}\") << (QStringList()" m['completions'].scan(/completions.append\((.+)\);/) { |comp| res << "\n << #{comp[0]}" } res + ');' }.gsub(/(?: +)[^\n]* =\n(?<code>.*?);\n\s*CompletionTestCase test\(.+?, "(?<prefix>.+?)"\);\s*QStringList expected;\s*(?<completions>(?:expected.append\(QLatin1String\("[^"]*"\)\);\s*)*)const QStringList completions = test.getCompletions\(\);\s*QCOMPARE\(completions, expected\);/m) { m = $~ res = " QTest::newRow(\"#{test_name}\") << _(\n#{m['code'].rstrip}\n ) << _(\"#{m['prefix']}\") << (QStringList()" m['completions'].scan(/expected.append\((.+)\);/) { |comp| res << "\n << #{comp[0]}" } res + ');' }.gsub(/(?: +)[^\n]* =\n(?<code>.*?);\n\s*CompletionTestCase test\(.+?(?:, (?<prefix>".+?"))?\);\s*(?:const )?QStringList completions = test.getCompletions\(\);\s*QCOMPARE\(completions.size\(\), \d+\);(?<completions>(?:\s*QVERIFY\(completions.contains\([^\n]+\);)*)\n/m) { |mm| m = $~ res = " QTest::newRow(\"#{test_name}\") << _(\n#{m['code'].rstrip}\n ) << _(#{m['prefix']}) << (QStringList()" m['completions'].scan(/QVERIFY\(completions.contains\((.+?)\)\);/) { |comp| res << "\n << #{comp[0]}" } res + ");\n" }.gsub(/(?: +)[^\n]* =\n(?<code>.*?);\n\s*CompletionTestCase test\(.+?(?:, (?<prefix>".+?"))?\);\s*bool replaceAccessOperator = false;\s*const QStringList completions = test.getCompletions\(\&replaceAccessOperator\);\s*QCOMPARE\(completions.size\(\), \d+\);(?<completions>(?:\s*QVERIFY\(completions.contains\([^\n]+\);)*)\s*QVERIFY\((?<replace>!?)[^)]*\);\n/m) { |mm| m = $~ res = " QTest::newRow(\"#{test_name}\") << _(\n#{m['code'].rstrip}\n ) << _(#{m['prefix']}) << (QStringList()" m['completions'].scan(/QVERIFY\(completions.contains\((.+?)\)\);/) { |comp| res << "\n << #{comp[0]}" } res + ")\n << #{m['replace'].empty?};\n" } if final == body or final['QTest::addColumn'] declaration + final + "}" else final end }.gsub(/QTest::newRow\("([^"]+)"/) { |m| name = $1 if name.size > 73 space = name[0..73].rindex(/[ _]/) "QTest::newRow(\"#{name[0..space]}\"\n \"#{name[space+1..-1]}\"" else m end }.gsub(/\s+QTest::newRow/, "\n\n QTest::newRow") if mod != s File.open(Fname, 'wt').write(mod) end Change-Id: Id6bfb03cdf31ac27b36028fcdc861c340a5398f4 Reviewed-by: Nikolai Kosjar <nikolai.kosjar@digia.com>
2013-12-17 20:17:41 +02:00
void test_completion_template_function_data();
CppTools: Make completion tests data-driven Mostly done using the following Ruby script: Fname = 'src/plugins/cpptools/cppcompletion_test.cpp' s = File.read(Fname) mod = s.gsub(/(?<declaration>void CppToolsPlugin::test_(?<test_name>[^(]+)\(\)\n\{)(?<body>.*?\n)\}/m) { |func| match = $~ declaration = match['declaration'] body = match['body'] test_name = match['test_name'].sub('_data', '') final = body.gsub(/(?:completions.clear\(\);\s+)?(?: +)[^\n]* =\n(?<code>.*?);\s*(?<completions>(?:completions.append\(QLatin1String\("[^"]*"\)\);\s*)*)QTest::newRow\("case: (?<name>.+?)"\)\s*<< code << _\("(?<prefix>[^"]+)"\) << completions;/m) { m = $~ res = " QTest::newRow(\"#{test_name}: #{m['name']}\") << _(\n#{m['code'].rstrip}\n ) << _(\"#{m['prefix']}\") << (QStringList()" m['completions'].scan(/completions.append\((.+)\);/) { |comp| res << "\n << #{comp[0]}" } res + ');' }.gsub(/(?: +)[^\n]* =\n(?<code>.*?);\n\s*CompletionTestCase test\(.+?, "(?<prefix>.+?)"\);\s*QStringList expected;\s*(?<completions>(?:expected.append\(QLatin1String\("[^"]*"\)\);\s*)*)const QStringList completions = test.getCompletions\(\);\s*QCOMPARE\(completions, expected\);/m) { m = $~ res = " QTest::newRow(\"#{test_name}\") << _(\n#{m['code'].rstrip}\n ) << _(\"#{m['prefix']}\") << (QStringList()" m['completions'].scan(/expected.append\((.+)\);/) { |comp| res << "\n << #{comp[0]}" } res + ');' }.gsub(/(?: +)[^\n]* =\n(?<code>.*?);\n\s*CompletionTestCase test\(.+?(?:, (?<prefix>".+?"))?\);\s*(?:const )?QStringList completions = test.getCompletions\(\);\s*QCOMPARE\(completions.size\(\), \d+\);(?<completions>(?:\s*QVERIFY\(completions.contains\([^\n]+\);)*)\n/m) { |mm| m = $~ res = " QTest::newRow(\"#{test_name}\") << _(\n#{m['code'].rstrip}\n ) << _(#{m['prefix']}) << (QStringList()" m['completions'].scan(/QVERIFY\(completions.contains\((.+?)\)\);/) { |comp| res << "\n << #{comp[0]}" } res + ");\n" }.gsub(/(?: +)[^\n]* =\n(?<code>.*?);\n\s*CompletionTestCase test\(.+?(?:, (?<prefix>".+?"))?\);\s*bool replaceAccessOperator = false;\s*const QStringList completions = test.getCompletions\(\&replaceAccessOperator\);\s*QCOMPARE\(completions.size\(\), \d+\);(?<completions>(?:\s*QVERIFY\(completions.contains\([^\n]+\);)*)\s*QVERIFY\((?<replace>!?)[^)]*\);\n/m) { |mm| m = $~ res = " QTest::newRow(\"#{test_name}\") << _(\n#{m['code'].rstrip}\n ) << _(#{m['prefix']}) << (QStringList()" m['completions'].scan(/QVERIFY\(completions.contains\((.+?)\)\);/) { |comp| res << "\n << #{comp[0]}" } res + ")\n << #{m['replace'].empty?};\n" } if final == body or final['QTest::addColumn'] declaration + final + "}" else final end }.gsub(/QTest::newRow\("([^"]+)"/) { |m| name = $1 if name.size > 73 space = name[0..73].rindex(/[ _]/) "QTest::newRow(\"#{name[0..space]}\"\n \"#{name[space+1..-1]}\"" else m end }.gsub(/\s+QTest::newRow/, "\n\n QTest::newRow") if mod != s File.open(Fname, 'wt').write(mod) end Change-Id: Id6bfb03cdf31ac27b36028fcdc861c340a5398f4 Reviewed-by: Nikolai Kosjar <nikolai.kosjar@digia.com>
2013-12-17 20:17:41 +02:00
void test_completion_template_function();
void test_completion_data();
void test_completion();
void test_global_completion_data();
void test_global_completion();
void test_doxygen_tag_completion_data();
void test_doxygen_tag_completion();
CppTools: Make completion tests data-driven Mostly done using the following Ruby script: Fname = 'src/plugins/cpptools/cppcompletion_test.cpp' s = File.read(Fname) mod = s.gsub(/(?<declaration>void CppToolsPlugin::test_(?<test_name>[^(]+)\(\)\n\{)(?<body>.*?\n)\}/m) { |func| match = $~ declaration = match['declaration'] body = match['body'] test_name = match['test_name'].sub('_data', '') final = body.gsub(/(?:completions.clear\(\);\s+)?(?: +)[^\n]* =\n(?<code>.*?);\s*(?<completions>(?:completions.append\(QLatin1String\("[^"]*"\)\);\s*)*)QTest::newRow\("case: (?<name>.+?)"\)\s*<< code << _\("(?<prefix>[^"]+)"\) << completions;/m) { m = $~ res = " QTest::newRow(\"#{test_name}: #{m['name']}\") << _(\n#{m['code'].rstrip}\n ) << _(\"#{m['prefix']}\") << (QStringList()" m['completions'].scan(/completions.append\((.+)\);/) { |comp| res << "\n << #{comp[0]}" } res + ');' }.gsub(/(?: +)[^\n]* =\n(?<code>.*?);\n\s*CompletionTestCase test\(.+?, "(?<prefix>.+?)"\);\s*QStringList expected;\s*(?<completions>(?:expected.append\(QLatin1String\("[^"]*"\)\);\s*)*)const QStringList completions = test.getCompletions\(\);\s*QCOMPARE\(completions, expected\);/m) { m = $~ res = " QTest::newRow(\"#{test_name}\") << _(\n#{m['code'].rstrip}\n ) << _(\"#{m['prefix']}\") << (QStringList()" m['completions'].scan(/expected.append\((.+)\);/) { |comp| res << "\n << #{comp[0]}" } res + ');' }.gsub(/(?: +)[^\n]* =\n(?<code>.*?);\n\s*CompletionTestCase test\(.+?(?:, (?<prefix>".+?"))?\);\s*(?:const )?QStringList completions = test.getCompletions\(\);\s*QCOMPARE\(completions.size\(\), \d+\);(?<completions>(?:\s*QVERIFY\(completions.contains\([^\n]+\);)*)\n/m) { |mm| m = $~ res = " QTest::newRow(\"#{test_name}\") << _(\n#{m['code'].rstrip}\n ) << _(#{m['prefix']}) << (QStringList()" m['completions'].scan(/QVERIFY\(completions.contains\((.+?)\)\);/) { |comp| res << "\n << #{comp[0]}" } res + ");\n" }.gsub(/(?: +)[^\n]* =\n(?<code>.*?);\n\s*CompletionTestCase test\(.+?(?:, (?<prefix>".+?"))?\);\s*bool replaceAccessOperator = false;\s*const QStringList completions = test.getCompletions\(\&replaceAccessOperator\);\s*QCOMPARE\(completions.size\(\), \d+\);(?<completions>(?:\s*QVERIFY\(completions.contains\([^\n]+\);)*)\s*QVERIFY\((?<replace>!?)[^)]*\);\n/m) { |mm| m = $~ res = " QTest::newRow(\"#{test_name}\") << _(\n#{m['code'].rstrip}\n ) << _(#{m['prefix']}) << (QStringList()" m['completions'].scan(/QVERIFY\(completions.contains\((.+?)\)\);/) { |comp| res << "\n << #{comp[0]}" } res + ")\n << #{m['replace'].empty?};\n" } if final == body or final['QTest::addColumn'] declaration + final + "}" else final end }.gsub(/QTest::newRow\("([^"]+)"/) { |m| name = $1 if name.size > 73 space = name[0..73].rindex(/[ _]/) "QTest::newRow(\"#{name[0..space]}\"\n \"#{name[space+1..-1]}\"" else m end }.gsub(/\s+QTest::newRow/, "\n\n QTest::newRow") if mod != s File.open(Fname, 'wt').write(mod) end Change-Id: Id6bfb03cdf31ac27b36028fcdc861c340a5398f4 Reviewed-by: Nikolai Kosjar <nikolai.kosjar@digia.com>
2013-12-17 20:17:41 +02:00
void test_completion_member_access_operator_data();
void test_completion_member_access_operator();
void test_completion_prefix_first_QTCREATORBUG_8737();
void test_completion_prefix_first_QTCREATORBUG_9236();
void test_format_pointerdeclaration_in_simpledeclarations();
void test_format_pointerdeclaration_in_simpledeclarations_data();
void test_format_pointerdeclaration_in_controlflowstatements();
void test_format_pointerdeclaration_in_controlflowstatements_data();
void test_format_pointerdeclaration_multiple_declarators();
void test_format_pointerdeclaration_multiple_declarators_data();
void test_format_pointerdeclaration_multiple_matches();
void test_format_pointerdeclaration_multiple_matches_data();
void test_format_pointerdeclaration_macros();
void test_format_pointerdeclaration_macros_data();
void test_cppsourceprocessor_includes_resolvedUnresolved();
void test_cppsourceprocessor_includes_cyclic();
void test_cppsourceprocessor_includes_allDiagnostics();
void test_cppsourceprocessor_macroUses();
void test_cppsourceprocessor_includeNext();
void test_functionutils_virtualFunctions();
void test_functionutils_virtualFunctions_data();
void test_modelmanager_paths_are_clean();
void test_modelmanager_framework_headers();
void test_modelmanager_refresh_also_includes_of_project_files();
void test_modelmanager_refresh_several_times();
void test_modelmanager_refresh_test_for_changes();
void test_modelmanager_refresh_added_and_purge_removed();
void test_modelmanager_refresh_timeStampModified_if_sourcefiles_change();
void test_modelmanager_refresh_timeStampModified_if_sourcefiles_change_data();
void test_modelmanager_snapshot_after_two_projects();
void test_modelmanager_extraeditorsupport_uiFiles();
void test_modelmanager_gc_if_last_cppeditor_closed();
void test_modelmanager_dont_gc_opened_files();
void test_modelmanager_defines_per_project();
void test_modelmanager_defines_per_editor();
void test_modelmanager_updateEditorsAfterProjectUpdate();
void test_modelmanager_precompiled_headers();
void test_modelmanager_renameIncludes();
void test_modelmanager_renameIncludesInEditor();
void test_modelmanager_documentsAndRevisions();
void test_cpplocatorfilters_CppLocatorFilter();
void test_cpplocatorfilters_CppLocatorFilter_data();
void test_cpplocatorfilters_CppCurrentDocumentFilter();
void test_builtinsymbolsearcher();
void test_builtinsymbolsearcher_data();
void test_headersource_data();
void test_headersource();
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();
#endif
2008-12-02 12:01:29 +01:00
private:
QSharedPointer<CppFileSettings> m_fileSettings;
QSharedPointer<CppCodeModelSettings> m_codeModelSettings;
CppToolsSettings *m_settings = nullptr;
StringTable m_stringTable;
2008-12-02 12:01:29 +01:00
};
} // namespace Internal
} // namespace CppTools