Skip to content

Commit 21c2f00

Browse files
authored
Code formatting using ClangFormat 6.0 (#230)
**Changes** * Add `.clang-format` with configuration settings that are similar to the current codebase * Add two custom targets: * `format`: format code * `check-format`: check code and exit 0 on success * Setup CI to check code formatting using `check-format` target * Format the code Resolves #177
1 parent ccb67fa commit 21c2f00

19 files changed

+809
-646
lines changed

.ci/install_linux.sh

+5
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,11 @@ $SUDO apt-get -y install lcov
3030
$SUDO apt-get -y install python-dev python3-dev
3131
$SUDO apt-get -y install libpython-dev libpython3-dev
3232

33+
# Install ClangFormat 6
34+
if [ $(lsb_release -sc) = "bionic" ]; then
35+
$SUDO apt-get -y install clang-format-6.0
36+
fi
37+
3338
# Install pybind11 from source (we need pybind11 (>=2.2.0))
3439
git clone https://github.com/pybind/pybind11.git
3540
cd pybind11

.ci/script.sh

+4
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,10 @@ else
1414
cmake "-DCMAKE_BUILD_TYPE=${BUILD_TYPE}" "-DLLVM_DIR=${LLVM_DIR}" "-DCODECOV=OFF" ..
1515
fi
1616

17+
if [ "$OS_NAME" = "linux" ] && [ $(lsb_release -sc) = "bionic" ]; then
18+
make check-format
19+
fi
20+
1721
make -j4 binding_tests
1822

1923
if [ $BUILD_NAME = TRUSTY_GCC_DEBUG ]; then

.clang-format

+89
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
---
2+
Language: Cpp
3+
BasedOnStyle: LLVM
4+
AccessModifierOffset: -4
5+
AlignAfterOpenBracket: Align
6+
AlignEscapedNewlinesLeft: false
7+
AlignOperands: true
8+
AlignTrailingComments: true
9+
AllowAllParametersOfDeclarationOnNextLine: true
10+
AllowShortBlocksOnASingleLine: false
11+
AllowShortCaseLabelsOnASingleLine: false
12+
AllowShortFunctionsOnASingleLine: None
13+
AllowShortIfStatementsOnASingleLine: false
14+
AllowShortLoopsOnASingleLine: false
15+
AlwaysBreakAfterDefinitionReturnType: false
16+
AlwaysBreakBeforeMultilineStrings: true
17+
AlwaysBreakTemplateDeclarations: true
18+
BinPackArguments: true
19+
BinPackParameters: true
20+
BraceWrapping:
21+
AfterClass: true
22+
AfterControlStatement: true
23+
AfterEnum: true
24+
AfterFunction: true
25+
AfterNamespace: true
26+
AfterObjCDeclaration: true
27+
AfterStruct: true
28+
AfterUnion: true
29+
BeforeCatch: true
30+
BeforeElse: true
31+
IndentBraces: false
32+
BreakBeforeBinaryOperators: All
33+
BreakBeforeBraces: Custom
34+
BreakBeforeTernaryOperators: true
35+
BreakConstructorInitializersBeforeComma: true
36+
ColumnLimit: 80
37+
CommentPragmas: ''
38+
ConstructorInitializerAllOnOneLineOrOnePerLine: true
39+
ConstructorInitializerIndentWidth: 2
40+
ContinuationIndentWidth: 4
41+
Cpp11BracedListStyle: true
42+
DerivePointerAlignment: false
43+
DisableFormat: false
44+
ExperimentalAutoDetectBinPacking: false
45+
FixNamespaceComments: true
46+
ForEachMacros: [ foreach, Q_FOREACH, BOOST_FOREACH ]
47+
# Sort headers by main include file (implicit priority 0),
48+
# then project and private includes, then system headers
49+
IncludeCategories:
50+
- Regex: '^<([a-z|_]+)>' # standard library headers
51+
Priority: 1
52+
- Regex: '^(<[A-z]+)' # dependency headers
53+
Priority: 2
54+
- Regex: '^(<|")chimera/' # Chimera headers
55+
Priority: 3
56+
- Regex: '^".*' # headers relative to this project
57+
Priority: 4
58+
IndentCaseLabels: true
59+
IndentFunctionDeclarationAfterType: false
60+
IndentWidth: 4
61+
IndentWrappedFunctionNames: false
62+
KeepEmptyLinesAtTheStartOfBlocks: true
63+
MacroBlockBegin: ''
64+
MacroBlockEnd: ''
65+
MaxEmptyLinesToKeep: 1
66+
NamespaceIndentation: None
67+
ObjCBlockIndentWidth: 2
68+
ObjCSpaceAfterProperty: false
69+
PenaltyBreakBeforeFirstCallParameter: 1
70+
PenaltyBreakComment: 300
71+
PenaltyBreakFirstLessLess: 120
72+
PenaltyBreakString: 1000
73+
PenaltyExcessCharacter: 1000000
74+
PenaltyReturnTypeOnItsOwnLine: 200
75+
PointerAlignment: Right
76+
SpaceAfterCStyleCast: false
77+
SpaceBeforeAssignmentOperators: true
78+
SpaceBeforeParens: ControlStatements
79+
SpaceInEmptyParentheses: false
80+
SpacesBeforeTrailingComments: 1
81+
SpacesInAngles: false
82+
SpacesInContainerLiterals: true
83+
SpacesInCStyleCastParentheses: false
84+
SpacesInParentheses: false
85+
SpacesInSquareBrackets: false
86+
Standard: Auto
87+
TabWidth: 4
88+
UseTab: Never
89+
...

CMakeLists.txt

+17
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,10 @@ set(SHARE_INSTALL_DIR "share/${PROJECT_NAME}")
99
## SETUP ##
1010
###########
1111

12+
# Preset for code formatting
13+
include(ClangFormat)
14+
clang_format_setup()
15+
1216
## Find necessary packages.
1317
find_package(LLVM REQUIRED CONFIG)
1418
include_directories(SYSTEM ${LLVM_INCLUDE_DIRS})
@@ -124,6 +128,12 @@ target_link_libraries("${PROJECT_NAME}"
124128
add_subdirectory(bindings)
125129
target_link_libraries(chimera chimera_bindings)
126130

131+
# Add main sources for code formatting
132+
clang_format_add_sources(
133+
${${PROJECT_NAME}_HEADERS}
134+
${${PROJECT_NAME}_SOURCES}
135+
)
136+
127137
#############
128138
## INSTALL ##
129139
#############
@@ -154,3 +164,10 @@ install(FILES "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake"
154164
# Enable unit testing by including the `test` subdirectory.
155165
enable_testing()
156166
add_subdirectory(test EXCLUDE_FROM_ALL)
167+
168+
#####################
169+
## CODE FORMATTING ##
170+
#####################
171+
172+
# Define 'format' target that runs ClangFormat
173+
clang_format_add_targets()

cmake/ClangFormat.cmake

+67
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
function(clang_format_setup)
2+
find_program(CLANG_FORMAT_EXECUTABLE NAMES clang-format-6.0)
3+
if(NOT CLANG_FORMAT_EXECUTABLE)
4+
message(STATUS "Looking for clang-format - NOT found, please install "
5+
"clang-format to enable automatic code formatting."
6+
)
7+
return()
8+
endif()
9+
10+
message(STATUS "Found clang-format.")
11+
endfunction()
12+
13+
#===============================================================================
14+
function(_property_add property_name)
15+
get_property(is_defined GLOBAL PROPERTY ${property_name} DEFINED)
16+
if(NOT is_defined)
17+
define_property(GLOBAL PROPERTY ${property_name}
18+
BRIEF_DOCS "${property_name}"
19+
FULL_DOCS "Global properties for ${property_name}"
20+
)
21+
endif()
22+
foreach(item ${ARGN})
23+
set_property(GLOBAL APPEND PROPERTY ${property_name} "${item}")
24+
endforeach()
25+
endfunction()
26+
27+
#===============================================================================
28+
function(clang_format_add_sources)
29+
foreach(source ${ARGN})
30+
if(IS_ABSOLUTE "${source}")
31+
set(source_abs "${source}")
32+
else()
33+
get_filename_component(source_abs
34+
"${CMAKE_CURRENT_LIST_DIR}/${source}" ABSOLUTE)
35+
endif()
36+
if(EXISTS "${source_abs}")
37+
_property_add(CLANG_FORMAT_FORMAT_FILES "${source_abs}")
38+
else()
39+
message(FATAL_ERROR
40+
"Source file '${source}' does not exist at absolute path"
41+
" '${source_abs}'. This should never happen. Did you recently delete"
42+
" this file or modify 'CMAKE_CURRENT_LIST_DIR'")
43+
endif()
44+
endforeach()
45+
endfunction()
46+
47+
#===============================================================================
48+
function(clang_format_add_targets)
49+
get_property(formatting_files GLOBAL PROPERTY CLANG_FORMAT_FORMAT_FILES)
50+
list(LENGTH formatting_files formatting_files_length)
51+
message(STATUS "Formatting on ${formatting_files_length} source files.")
52+
53+
add_custom_target(format
54+
COMMAND ${CMAKE_COMMAND} -E echo "Formatting ${formatting_files_length} files..."
55+
COMMAND ${CLANG_FORMAT_EXECUTABLE} -style=file -i ${formatting_files}
56+
COMMAND ${CMAKE_COMMAND} -E echo "Done."
57+
DEPENDS ${CLANG_FORMAT_EXECUTABLE}
58+
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
59+
)
60+
add_custom_target(check-format
61+
COMMAND ${CMAKE_COMMAND} -E echo "Checking ${formatting_files_length} files..."
62+
COMMAND ${CMAKE_SOURCE_DIR}/tools/check_format.sh ${CLANG_FORMAT_EXECUTABLE} ${formatting_files}
63+
COMMAND ${CMAKE_COMMAND} -E echo "Done."
64+
DEPENDS ${CLANG_FORMAT_EXECUTABLE}
65+
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
66+
)
67+
endfunction()

include/chimera/binding.h

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
#ifndef __CHIMERA_BINDING_H__
22
#define __CHIMERA_BINDING_H__
33

4-
#include <string>
54
#include <map>
5+
#include <string>
66

77
namespace chimera
88
{
@@ -12,7 +12,8 @@ namespace binding
1212
/**
1313
* Interface for defining a built-in language binding.
1414
*/
15-
struct Definition {
15+
struct Definition
16+
{
1617
std::string class_cpp;
1718
std::string enum_cpp;
1819
std::string function_cpp;

include/chimera/configuration.h

+28-27
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,13 @@
33

44
#include "chimera/binding.h"
55

6+
#include <map>
7+
#include <memory>
8+
#include <set>
69
#include <clang/AST/DeclBase.h>
710
#include <clang/AST/Mangle.h>
811
#include <clang/Frontend/CompilerInstance.h>
9-
#include <map>
10-
#include <memory>
1112
#include <mstch/mstch.hpp>
12-
#include <set>
1313
#include <yaml-cpp/yaml.h>
1414

1515
namespace chimera
@@ -23,9 +23,8 @@ class Function;
2323
class Variable;
2424
class Namespace;
2525

26-
} // mstch
27-
} // chimera
28-
26+
} // namespace mstch
27+
} // namespace chimera
2928

3029
namespace chimera
3130
{
@@ -35,13 +34,13 @@ class CompiledConfiguration;
3534
class Configuration
3635
{
3736
public:
38-
Configuration(const Configuration&) = delete;
39-
Configuration &operator=(const Configuration&) = delete;
37+
Configuration(const Configuration &) = delete;
38+
Configuration &operator=(const Configuration &) = delete;
4039

4140
/**
4241
* Get the chimera configuration singleton for this process.
4342
*/
44-
static Configuration& GetInstance();
43+
static Configuration &GetInstance();
4544

4645
/**
4746
* Load the specified file to use as the YAML configuration.
@@ -81,28 +80,28 @@ class Configuration
8180
/**
8281
* Process the configuration settings against the current AST.
8382
*/
84-
std::unique_ptr<CompiledConfiguration>
85-
Process(clang::CompilerInstance *ci) const;
83+
std::unique_ptr<CompiledConfiguration> Process(
84+
clang::CompilerInstance *ci) const;
8685

8786
/**
8887
* Get the root node of the YAML configuration structure.
8988
*/
90-
const YAML::Node& GetRoot() const;
89+
const YAML::Node &GetRoot() const;
9190

9291
/**
9392
* Get the filename of the loaded YAML configuration file, if it exists.
9493
*/
95-
const std::string& GetConfigFilename() const;
94+
const std::string &GetConfigFilename() const;
9695

9796
/**
9897
* Get the desired output path for bindings.
9998
*/
100-
const std::string& GetOutputPath() const;
99+
const std::string &GetOutputPath() const;
101100

102101
/**
103102
* Get the desired output python module name for top-level binding.
104103
*/
105-
const std::string& GetOutputModuleName() const;
104+
const std::string &GetOutputModuleName() const;
106105

107106
private:
108107
Configuration();
@@ -123,14 +122,14 @@ class CompiledConfiguration
123122
{
124123
public:
125124
virtual ~CompiledConfiguration();
126-
CompiledConfiguration(const CompiledConfiguration&) = delete;
127-
CompiledConfiguration &operator=(const CompiledConfiguration&) = delete;
125+
CompiledConfiguration(const CompiledConfiguration &) = delete;
126+
CompiledConfiguration &operator=(const CompiledConfiguration &) = delete;
128127

129128
/**
130129
* Adds a namespace to an ordered set of traversed namespaces.
131130
* This set can later be rendered in a template.
132131
*/
133-
void AddTraversedNamespace(const clang::NamespaceDecl* decl);
132+
void AddTraversedNamespace(const clang::NamespaceDecl *decl);
134133

135134
/**
136135
* Return list of namespace declarations that should be included.
@@ -139,24 +138,25 @@ class CompiledConfiguration
139138
* is desirable since parent namespaces will naturally be lexically
140139
* ordered before their children.
141140
*/
142-
const std::set<const clang::NamespaceDecl*>& GetNamespacesIncluded() const;
141+
const std::set<const clang::NamespaceDecl *> &GetNamespacesIncluded() const;
143142

144143
/**
145144
* Returns list of namespace declarations that should be skipped.
146145
*/
147-
const std::set<const clang::NamespaceDecl*>& GetNamespacesSuppressed() const;
146+
const std::set<const clang::NamespaceDecl *> &GetNamespacesSuppressed()
147+
const;
148148

149149
/**
150150
* Get the YAML configuration associated with a specific declaration,
151151
* or return an empty YAML node if no configuration was found.
152152
*/
153-
const YAML::Node& GetDeclaration(const clang::Decl *decl) const;
153+
const YAML::Node &GetDeclaration(const clang::Decl *decl) const;
154154

155155
/**
156156
* Get the YAML configuration associated with a specific qualified type,
157157
* or return an empty YAML node if no configuration was found.
158158
*/
159-
const YAML::Node& GetType(const clang::QualType type) const;
159+
const YAML::Node &GetType(const clang::QualType type) const;
160160

161161
/**
162162
* Gets the compiler instance used by this configuration.
@@ -198,7 +198,8 @@ class CompiledConfiguration
198198

199199
/**
200200
* Render a particular mstch template based on some declaration.
201-
* This context must contain a "mangled_name" from which to create the filename.
201+
* This context must contain a "mangled_name" from which to create the
202+
* filename.
202203
*/
203204
bool Render(const std::shared_ptr<chimera::mstch::CXXRecord> context);
204205
bool Render(const std::shared_ptr<chimera::mstch::Enum> context);
@@ -220,13 +221,13 @@ class CompiledConfiguration
220221
chimera::binding::Definition bindingDefinition_;
221222
clang::CompilerInstance *ci_;
222223
std::vector<std::pair<const clang::QualType, YAML::Node>> types_;
223-
std::map<const clang::Decl*, YAML::Node> declarations_;
224-
std::set<const clang::NamespaceDecl*> namespacesIncluded_;
225-
std::set<const clang::NamespaceDecl*> namespacesSuppressed_;
224+
std::map<const clang::Decl *, YAML::Node> declarations_;
225+
std::set<const clang::NamespaceDecl *> namespacesIncluded_;
226+
std::set<const clang::NamespaceDecl *> namespacesSuppressed_;
226227

227228
std::vector<std::string> binding_names_;
228229
std::vector<std::shared_ptr<chimera::mstch::Namespace>> binding_namespaces_;
229-
std::set<const clang::NamespaceDecl*> binding_namespace_decls_;
230+
std::set<const clang::NamespaceDecl *> binding_namespace_decls_;
230231

231232
friend class Configuration;
232233
};

0 commit comments

Comments
 (0)