forked from qt-creator/qt-creator
		
	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>
		
			
				
	
	
		
			180 lines
		
	
	
		
			6.3 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			180 lines
		
	
	
		
			6.3 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
#!/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()
 |