aboutsummaryrefslogtreecommitdiffstats
path: root/scripts
diff options
context:
space:
mode:
authorIvan Donchevskii <ivan.donchevskii@qt.io>2018-05-16 07:58:53 +0200
committerIvan Donchevskii <ivan.donchevskii@qt.io>2018-05-25 09:59:20 +0000
commitbc458c7b5f36802ac35d4e4022c966929b84da61 (patch)
tree6d85e1f27a39dba01b4a9fad562b8ac2774bb5d6 /scripts
parentb1fcbfecceafdf107bfebd95f773013b551088a1 (diff)
Clang: Use the tree instead of the list for Clang-Tidy settings
List of checks does not give enough flexibility to select/unselect specific checks. The tree fixes that. Also remove Clang-Tidy checks line edit because it is now integrated into the tree mode as an alternative way of providing checks by pressing "Plain text edit" button. 'cpptools_clangtidychecks.h' is generated using python script 'generateClangTidyChecks.py' and clang-tidy from our LLVM/Clang 6.0 build. Change-Id: I2ed1738cb2cbbf8dac6aba563469f06f69b11593 Reviewed-by: Nikolai Kosjar <nikolai.kosjar@qt.io> Reviewed-by: Leena Miettinen <riitta-leena.miettinen@qt.io>
Diffstat (limited to 'scripts')
-rw-r--r--scripts/generateClangTidyChecks.py179
1 files changed, 179 insertions, 0 deletions
diff --git a/scripts/generateClangTidyChecks.py b/scripts/generateClangTidyChecks.py
new file mode 100644
index 0000000000..627489521e
--- /dev/null
+++ b/scripts/generateClangTidyChecks.py
@@ -0,0 +1,179 @@
+#!/usr/bin/env python
+############################################################################
+#
+# Copyright (C) 2018 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.
+#
+############################################################################
+
+import argparse
+import collections
+import os
+import re
+import subprocess
+import sys
+
+import common
+
+def next_common(string, common):
+ remaining_string = string[len(common):]
+ parts = re.split("[.\-]+", remaining_string)
+ return string[:(len(common) + len(parts[0]) + 1)]
+
+def extract_similar(group, group_common):
+ subgroups = {}
+ for key, val in group.items():
+ common = next_common(key, group_common)
+ if common == group_common or common == key:
+ continue
+ if key not in group:
+ continue
+
+ subgroup = {}
+ for subkey, subval in group.items():
+ if not subkey.startswith(common):
+ continue
+ subgroup[subkey] = subval
+ del group[subkey]
+ if len(subgroup) == 1:
+ group[key] = val
+ else:
+ extract_similar(subgroup, common)
+ subgroups[common] = subgroup
+ group.update(subgroups)
+ if '' in group:
+ del group['']
+ return group
+
+def print_formatted(group, group_name, indent):
+ index = 0
+ for key in sorted(group):
+ index += 1
+ comma = ','
+ if index == len(group):
+ comma = ''
+ if len(group[key]) == 0:
+ print indent + '"' + key[len(group_name):] + '"' + comma
+ else:
+ print indent + '{'
+ print indent + ' "' + key[len(group_name):] + '",'
+ print indent + ' {'
+ print_formatted(group[key], key, indent + ' ')
+ print indent + ' }'
+ print indent + '}' + comma
+
+def print_to_header_file(group):
+ print '''/****************************************************************************
+**
+** Copyright (C) 2018 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.
+**
+****************************************************************************/
+
+#pragma once
+
+#include <vector>
+
+namespace CppTools {
+namespace Constants {
+
+struct TidyNode
+{
+ const std::vector<TidyNode> children;
+ const char *name = nullptr;
+ TidyNode(const char *name, std::vector<TidyNode> &&children)
+ : children(std::move(children))
+ , name(name)
+ {}
+ TidyNode(const char *name) : name(name) {}
+};
+
+// CLANG-UPGRADE-CHECK: Run 'scripts/generateClangTidyChecks.py' after Clang upgrade to
+// update this header.
+static const TidyNode CLANG_TIDY_CHECKS_ROOT
+{
+ "",
+ {'''
+
+ print_formatted(group, '', ' ')
+
+ print ''' }
+};
+
+} // namespace Constants
+} // namespace CppTools'''
+
+def parse_arguments():
+ parser = argparse.ArgumentParser(description="Clang-Tidy checks header file generator")
+ parser.add_argument('--tidy-path', help='path to clang-tidy binary',
+ default='clang-tidy.exe' if common.is_windows_platform() else 'clang-tidy', dest='tidypath')
+ return parser.parse_args()
+
+def main():
+ arguments = parse_arguments()
+ process = subprocess.Popen([arguments.tidypath, '-checks=*', '-list-checks'], stdout=subprocess.PIPE)
+ lines = process.stdout.read().splitlines()
+ lines.pop(0) # 'Enabled checks:'
+ major_checks = ['android-', 'boost-', 'bugprone-', 'cert-', 'clang-analyzer-',
+ 'cppcoreguidelines-', 'fuchsia-', 'google-', 'hicpp-', 'llvm-', 'misc-', 'modernize-',
+ 'mpi-', 'objc-', 'performance-', 'readability-']
+ current_major = 0
+ major_groups = {}
+ for line in lines:
+ line = line.strip()
+ if current_major < (len(major_checks) - 1) and line.startswith(major_checks[current_major + 1]):
+ current_major += 1
+ if major_checks[current_major] not in major_groups:
+ major_groups[major_checks[current_major]] = {}
+ major_groups[major_checks[current_major]][line] = {}
+
+ for major_check, group in major_groups.items():
+ major_groups[major_check] = extract_similar(group, major_check)
+
+ current_path = os.path.dirname(os.path.abspath(__file__))
+ header_path = os.path.abspath(os.path.join(current_path, '..', 'src', 'plugins', 'cpptools', 'cpptools_clangtidychecks.h'))
+
+ default_stdout = sys.stdout
+ header_file = open(header_path, 'w')
+ sys.stdout = header_file
+ print_to_header_file(major_groups)
+ sys.stdout = default_stdout
+ header_file.close()
+if __name__ == "__main__":
+ main()