diff options
author | Nikolai Kosjar <nikolai.kosjar@qt.io> | 2017-08-16 08:58:48 +0200 |
---|---|---|
committer | Nikolai Kosjar <nikolai.kosjar@qt.io> | 2017-09-04 06:53:55 +0000 |
commit | 54a43de656a490e4bf30005827b2e10adb725502 (patch) | |
tree | a72deca4c9ab7eb7a58c0256ba05be5e0967f188 | |
parent | 40683aaa4e461553289ae79fdae344084c43ca1c (diff) | |
download | qt-creator-54a43de656a490e4bf30005827b2e10adb725502.tar.gz |
Add experimental .clang-format
This adds a configuration file for clang-format [1] and a test file to
demonstrate benefits and current problems with respect to Qt Creator's
coding rules [2].
This is based on clang-format from the llvm/clang 5.0 branch, which is
about to be released soon in the next days/weeks (already behind
schedule).
Using clang-format for Qt Creator brings these advantages:
* Enforce a bunch of coding rules by a simple tool/shortcut invocation.
* Spend less review cycles for authors and reviewers regarding
formatting. This helps especially for/with first-time contributors.
* clang-format sorts includes and using declarations.
* clang-format adds/updates namespace end comments, e.g.: } //
namespace Foo
See dist/clangformat/README.md for setup instructions und currently
known issues.
[1] https://clang.llvm.org/docs/ClangFormat.html
[2] https://doc-snapshots.qt.io/qtcreator-extending/coding-style.html
Task-number: QTCREATORBUG-17643
Change-Id: I87bdd66b8e492e99a360022962b0053f02a33e57
Reviewed-by: Alessandro Portale <alessandro.portale@qt.io>
Reviewed-by: Eike Ziller <eike.ziller@qt.io>
-rw-r--r-- | .gitignore | 1 | ||||
-rw-r--r-- | dist/clangformat/.clang-format | 115 | ||||
-rw-r--r-- | dist/clangformat/README.md | 156 | ||||
-rw-r--r-- | tests/manual/clang-format-for-qtc/clang-format-for-qtc.pro | 4 | ||||
-rw-r--r-- | tests/manual/clang-format-for-qtc/test.cpp | 690 |
5 files changed, 966 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore index 47924d6b97..cdee18b344 100644 --- a/.gitignore +++ b/.gitignore @@ -29,6 +29,7 @@ .DS_Store /.qmake.cache /.qmake.stash +/.clang-format Makefile* Thumbs.db core diff --git a/dist/clangformat/.clang-format b/dist/clangformat/.clang-format new file mode 100644 index 0000000000..25df05eb26 --- /dev/null +++ b/dist/clangformat/.clang-format @@ -0,0 +1,115 @@ +# .clang-format for Qt Creator +# +# This is for clang-format >= 5.0. +# +# The configuration below follows the Qt Creator Coding Rules [1] as closely as +# possible. For documentation of the options, see [2]. +# +# Use ../../tests/manual/clang-format-for-qtc/test.cpp for documenting problems +# or testing changes. +# +# [1] https://doc-snapshots.qt.io/qtcreator-extending/coding-style.html +# [2] https://clang.llvm.org/docs/ClangFormatStyleOptions.html +# +--- +Language: Cpp +AccessModifierOffset: -4 +AlignAfterOpenBracket: Align +AlignConsecutiveAssignments: false +AlignConsecutiveDeclarations: false +AlignEscapedNewlines: DontAlign +AlignOperands: true +AlignTrailingComments: true +AllowAllParametersOfDeclarationOnNextLine: true +AllowShortBlocksOnASingleLine: false +AllowShortCaseLabelsOnASingleLine: false +AllowShortFunctionsOnASingleLine: Inline +AllowShortIfStatementsOnASingleLine: false +AllowShortLoopsOnASingleLine: false +AlwaysBreakAfterReturnType: None +AlwaysBreakBeforeMultilineStrings: false +AlwaysBreakTemplateDeclarations: true +BinPackArguments: false +BinPackParameters: false +BraceWrapping: + AfterClass: true + AfterControlStatement: false + AfterEnum: false + AfterFunction: true + AfterNamespace: false + AfterObjCDeclaration: false + AfterStruct: true + AfterUnion: false + BeforeCatch: false + BeforeElse: false + IndentBraces: false + SplitEmptyFunction: false + SplitEmptyRecord: false + SplitEmptyNamespace: false +BreakBeforeBinaryOperators: All +BreakBeforeBraces: Custom +BreakBeforeInheritanceComma: false +BreakBeforeTernaryOperators: true +BreakConstructorInitializersBeforeComma: false +BreakConstructorInitializers: BeforeComma +BreakAfterJavaFieldAnnotations: false +BreakStringLiterals: false +ColumnLimit: 100 +CommentPragmas: '^ IWYU pragma:' +CompactNamespaces: false +ConstructorInitializerAllOnOneLineOrOnePerLine: false +ConstructorInitializerIndentWidth: 4 +ContinuationIndentWidth: 4 +Cpp11BracedListStyle: true +DerivePointerAlignment: false +DisableFormat: false +ExperimentalAutoDetectBinPacking: false +FixNamespaceComments: true +ForEachMacros: + - forever # avoids { wrapped to next line + - foreach + - Q_FOREACH + - BOOST_FOREACH +IncludeCategories: + - Regex: '^<Q.*' + Priority: 200 +IncludeIsMainRegex: '(Test)?$' +IndentCaseLabels: false +IndentWidth: 4 +IndentWrappedFunctionNames: false +JavaScriptQuotes: Leave +JavaScriptWrapImports: true +KeepEmptyLinesAtTheStartOfBlocks: false +# Do not add QT_BEGIN_NAMESPACE/QT_END_NAMESPACE as this will indent lines in between. +MacroBlockBegin: "" +MacroBlockEnd: "" +MaxEmptyLinesToKeep: 1 +NamespaceIndentation: None +ObjCBlockIndentWidth: 4 +ObjCSpaceAfterProperty: false +ObjCSpaceBeforeProtocolList: true +PenaltyBreakAssignment: 150 +PenaltyBreakBeforeFirstCallParameter: 300 +PenaltyBreakComment: 500 +PenaltyBreakFirstLessLess: 400 +PenaltyBreakString: 600 +PenaltyExcessCharacter: 50 +PenaltyReturnTypeOnItsOwnLine: 300 +PointerAlignment: Right +ReflowComments: false +SortIncludes: true +SortUsingDeclarations: true +SpaceAfterCStyleCast: true +SpaceAfterTemplateKeyword: false +SpaceBeforeAssignmentOperators: true +SpaceBeforeParens: ControlStatements +SpaceInEmptyParentheses: false +SpacesBeforeTrailingComments: 1 +SpacesInAngles: false +SpacesInContainerLiterals: false +SpacesInCStyleCastParentheses: false +SpacesInParentheses: false +SpacesInSquareBrackets: false +Standard: Cpp11 +TabWidth: 4 +UseTab: Never diff --git a/dist/clangformat/README.md b/dist/clangformat/README.md new file mode 100644 index 0000000000..ae714aad9e --- /dev/null +++ b/dist/clangformat/README.md @@ -0,0 +1,156 @@ +# .clang-format for Qt Creator + +Alongside this file you find an EXPERIMENTAL .clang-format configuration file +for the Qt Creator code base. + +The current configuration is useful, but not fully in accordance with the +coding rules. There is also other undesired formatting. Running clang-format +blindly will not only improve formatting here and there, but will also +normalize/worsen code that is already considered ideally formatted. See section +"Coding rules violated by clang-format" below for more information. + +If needed, clang-format can be instructed to not format code ranges. Do not +overuse this. + + // clang-format off + void unformatted_code ; + // clang-format on + +For more information about clang-format, see + + <https://clang.llvm.org/docs/ClangFormat.html> + +## Prerequisites + + * clang-format >= 5.0 + +## Set up Qt Creator for use with clang-format + +### Install the configuration file + +For a given source file to format, clang-format it will read the configuration +from .clang-format in the closest parent directory for the file to format. + +Hence symlink/copy .clang-format from this directory to e.g. Qt Creator's top +level directory: + +For Linux/macOS: + + $ cd $QTC_SOURCE + $ ln -s dist/clangformat/.clang-format + +For Windows: + + $ cd $QTC_SOURCE + $ copy dist\clangformat\.clang-format # Do not forget to keep this updated + +### Configure Qt Creator + + 1. Enable the Beautifier plugin and restart to load it. + + 2. Configure the plugin: + In Menu: Tools > Options > Beautifier > Tab: Clang Format + * Select a valid clang-format executable + * Use predefined style: File + * Fallback style: None + + 3. Set shortcuts for convenience: + In Menu: Tools > Options > Environment > Keyboard + * ClangFormat / FormatFile - e.g. Alt+C, F + * ClangFormat / FormatSelectedText - e.g. Alt+C, S + +Due to several issues outlined below the FormatFile action might be of limited +use. + +## Coding rules enforced by clang-format + +This is a copy-pasted list of coding rules from +<https://doc-snapshots.qt.io/qtcreator-extending/coding-style.html> that can be +enforced with the current configuration: + +* Formatting + * Whitespace + * Use four spaces for indentation, no tabs. + * Always use only one blank line (to group statements together) + * Pointers and References: For pointers or references, always use a single + space before an asterisk (*) or an ampersand (&), but never after. + * Operator Names and Parentheses: Do not use spaces between operator names + and parentheses. + * Function Names and Parentheses: Do not use spaces between function names + and parentheses. + * Keywords: Always use a single space after a keyword, and before a curly + brace. + * Braces + * As a base rule, place the left curly brace on the same line as the start + of the statement. + * Exception: Function implementations and class declarations always have + the left brace in the beginning of a line + * Line Breaks + * Keep lines shorter than 100 characters + * Insert line breaks if necessary. + * Commas go at the end of a broken line. + * Operators start at the beginning of the new line. + * Namespaces: + * Put the left curly brace on the same line as the namespace keyword. + * Do not indent declarations or definitions inside. + * Optional, but recommended if the namespaces spans more than a few lines: + Add a comment after the right curly brace repeating the namespace. +* Patterns and Practices + * C++11 and C++14 Features / Lambdas: + * Optionally, place the lambda completely on one line if it fits. + * Place a closing parenthesis and semicolon of an enclosing function call + on the same line as the closing brace of the lambda. + +## Coding rules violated by clang-format + +* Formatting / Namespaces + * As an exception, if there is only a single class declaration inside the + namespace, all can go on a single line. Currently this ends up on several + lines, which is noisy. +* Patterns and Practices / C++11 and C++14 Features / Lambdas + * If you are using a lambda in an 'if' statement, start the lambda on a new + line. + +### Other undesired formattings + +For a more complete list of observations and problems, see the "// NOTE: " +comments in ../../tests/manual/clang-format-for-qtc/test.cpp. + +#### Manually aligned complex expressions in e.g. if-conditions are collapsed + +We want: + + if (someFancyAndLongerExpression1 + || someFancyAndLongerExpression2 + || someFancyAndLongerExpression3) { + return value; + } + +Current: + + if (someFancyAndLongerExpression1 || someFancyAndLongerExpression2 + || someFancyAndLongerExpression3) { + return value; + } + +#### connect() calls do not follow the standard two-line pattern + +In general, for middle-sized and longer connect() calls we want to follow this +two-line pattern. + + connect(sender, &SomeFancySender::signal, + receiver, &SomeFancyReceiver::slot); + +Current: + + connect(sender, + &SomeFancySender::signal, + receiver, + &SomeFancySender::slot); + +#### QTC_ASSERT and excess space after return keyword + +For QTC_ASSERT in combination with the return keyword, an excess space is added: + + QTC_ASSERT(headItem, return ); + diff --git a/tests/manual/clang-format-for-qtc/clang-format-for-qtc.pro b/tests/manual/clang-format-for-qtc/clang-format-for-qtc.pro new file mode 100644 index 0000000000..370c349d4a --- /dev/null +++ b/tests/manual/clang-format-for-qtc/clang-format-for-qtc.pro @@ -0,0 +1,4 @@ +QT -= gui +CONFIG += c++14 console +CONFIG -= app_bundle +SOURCES += test.cpp diff --git a/tests/manual/clang-format-for-qtc/test.cpp b/tests/manual/clang-format-for-qtc/test.cpp new file mode 100644 index 0000000000..3edaa85739 --- /dev/null +++ b/tests/manual/clang-format-for-qtc/test.cpp @@ -0,0 +1,690 @@ +/**************************************************************************** +** +** Copyright (C) 2017 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. +** +****************************************************************************/ + +// +// KEEP THIS FILE COMPILABLE TO ENSURE THAT WE TEST AGAINST VALID CODE. +// + +// NOTE: Nice, includes are sorted +#include <QCoreApplication> +#include <QFile> +#include <QLoggingCategory> +#include <QObject> +#include <QVector> + +#include <functional> +#include <iostream> +#include <vector> + +static int aGlobalInt = 3; + +// ------------------------------------------------------------------------------------------------- +// Preprocessor +// ------------------------------------------------------------------------------------------------- + +// NOTE: Ops, preprocessor branches are not indented ("#define" vs "# define") +#if defined(TEXTEDITOR_LIBRARY) +#define TEXTEDITOR_EXPORT Q_DECL_EXPORT +#else +#define TEXTEDITOR_EXPORT Q_DECL_IMPORT +#endif + +// ------------------------------------------------------------------------------------------------- +// Macros +// ------------------------------------------------------------------------------------------------- + +#define QTCREATOR_UTILS_EXPORT + +// qtcassert.h: +namespace Utils { +QTCREATOR_UTILS_EXPORT void writeAssertLocation(const char *msg); +} + +#define QTC_ASSERT_STRINGIFY_HELPER(x) #x +#define QTC_ASSERT_STRINGIFY(x) QTC_ASSERT_STRINGIFY_HELPER(x) +#define QTC_ASSERT_STRING(cond) \ + ::Utils::writeAssertLocation("\"" cond "\" in file " __FILE__ \ + ", line " QTC_ASSERT_STRINGIFY(__LINE__)) + +// NOTE: Ops, macro definitions: are more verbose +#define QTC_ASSERT(cond, action) \ + if (cond) { \ + } else { \ + QTC_ASSERT_STRING(#cond); \ + action; \ + } \ + do { \ + } while (0) +#define QTC_CHECK(cond) \ + if (cond) { \ + } else { \ + QTC_ASSERT_STRING(#cond); \ + } \ + do { \ + } while (0) +#define QTC_GUARD(cond) ((cond) ? true : (QTC_ASSERT_STRING(#cond), false)) + +void lala(int foo) +{ + Q_UNUSED(foo) + Q_UNUSED(foo); + QTC_ASSERT(true, return ); // NOTE: Ops, extra space with QTC_ASSERT macro and return keyword + QTC_ASSERT(true, return;); + while (true) + QTC_ASSERT(true, break); // ...but this is fine +} + +// ------------------------------------------------------------------------------------------------- +// Namespaces +// ------------------------------------------------------------------------------------------------- + +namespace N { +namespace C { + +struct Foo +{}; + +struct Bar +{}; + +namespace { +class ClassInUnnamedNamespace +{}; +} // namespace + +// NOTE: Nice, namespace end comments are added/updated automatically +} // namespace C + +struct Baz +{}; + +} // namespace N +namespace N2 { +} + +// ------------------------------------------------------------------------------------------------- +// Forward declarations +// ------------------------------------------------------------------------------------------------- + +// NOTE: Ops, no one-liner anymore: forward declarations within namespace +namespace N { +struct Baz; +} + +class SourceLocation; +class SourceRange; +class ClangString; + +QT_BEGIN_NAMESPACE +class QString; +QT_END_NAMESPACE + +QT_FORWARD_DECLARE_CLASS(QTextDocument) +QT_FORWARD_DECLARE_CLASS(QTextBlock); + +// ------------------------------------------------------------------------------------------------- +// Using declarations, using directives, using alias, typedefs +// ------------------------------------------------------------------------------------------------- + +// NOTE: OK, using directives are not sorted +using namespace std; +using namespace N2; +using namespace N; + +// NOTE: Nice, using declarations are sorted +using N::C::Bar; +using N::C::Foo; + +// NOTE: OK, typedefs are not sorted +typedef N::C::Foo TypedefedFoor; +typedef N::C::Bar TypedefedBar; + +// NOTE: OK, using aliases are not sorted +using AliasedFoor = N::C::Foo; +using AliasedBar = N::C::Bar; + +// ------------------------------------------------------------------------------------------------- +// Comments +// ------------------------------------------------------------------------------------------------- + +// NOTE: OK, reflowing/wrapping of comments is turned off for now. +// This is a fancy comment that might be reflowed or not or not or not or not or not or not or not or not or not. + +// NOTE: Nice, comments after declarations are aligned +int foo; // fancy comment describing foo +int superDuperFoo; // fancy comment describing superDuperFoo +int lalaFoo; // fancy comment describing lalaFoo + +// ------------------------------------------------------------------------------------------------- +// Function declarations +// ------------------------------------------------------------------------------------------------- + +void f(); + +void f2() {} + +void f3(int parameter1, int parameter2, int parameter3); + +// NOTE: Ops, awkward placement of parameter list, there is no equivalent of +// PenaltyBreakBeforeFirstCallParameter for parameter list +void f3( + int parameter1, int parameter2, int parameter3, int parameter4, int parameter5, int parameter6); + +void f3(int parameter1, + int parameter2, + int parameter3, + int parameter4, + int parameter5, + int parameter6, + int parrameter7, + int p = aGlobalInt); + +bool operator==(N::Baz, N::Baz); + +template<class T> +void fancyTemplateFunction(); + +template<typename... Type> +void variadicTemplateFunction(Type *... arg); + +// ------------------------------------------------------------------------------------------------- +// Inside functions +// ------------------------------------------------------------------------------------------------- + +int myfunction(int parameter1, int parameter2) +{ + // Function calls + myfunction(parameter1, parameter2); + + // Casts + int value = 3; + int z = (int) value; + int a = static_cast<int>(value + z); + + // Pointer/references alignment + int *p = nullptr; + int &r = *p; + + // Operators + int result = parameter1 + parameter1 + parameter1 + parameter1 + parameter1 + parameter1 + + parameter1 + parameter1; + + // Long expressions + int someVeryLooooooooooooooooooooooooooooooooooooooooooooooooooongInt = -1; + bool condition1 = false; + bool condition2 = false; + // NOTE: Ops, alignment of readable, boolean and complex expressions will be reverted + if (condition1 || condition2 + || someVeryLooooooooooooooooooooooooooooooooooooooooooooooooooongInt) { + return value; + } + + // Initializer lists + vector<int> x{1, 2, 3, 4}; + vector<Foo> y{{}, {}, {}, {}}; + new int[3]{1, 2, 3}; + + // Streams + // NOTE: OK, there is a heuristic (endl, '\n') to wrap statements with stream operators. + cout << "Hello" << parameter1 << endl + << parameter2 << endl + << result << endl + << condition1 << someVeryLooooooooooooooooooooooooooooooooooooooooooooooooooongInt; + cout << "Hello" << parameter1 << '\n' + << parameter2 << '\n' + << a << '\n' + << condition1 << someVeryLooooooooooooooooooooooooooooooooooooooooooooooooooongInt; + // ...but here not: + cout << "Hello" << parameter1 << '\t' << parameter2 << '\t' << z << '\t' << condition1 + << someVeryLooooooooooooooooooooooooooooooooooooooooooooooooooongInt << r; + + return 1; +} + +// ------------------------------------------------------------------------------------------------- +// Ternary Operator +// ------------------------------------------------------------------------------------------------- + +bool ternary() +{ + bool someWhatLongerName; + bool someWhatLongerName2; + bool isThatReallyReallyReallyReallyReallyReallyReallyReallyTrue = false; + bool isThatReallyReallyReallyReallyReallyReallyReallyReallyReallyReallyTrue = false; + + bool yesno = true ? true : false; + bool sino = isThatReallyReallyReallyReallyReallyReallyReallyReallyTrue ? someWhatLongerName + : someWhatLongerName2; + bool danet = isThatReallyReallyReallyReallyReallyReallyReallyReallyReallyReallyTrue + ? someWhatLongerName + : someWhatLongerName2; + + return yesno && sino && danet; +} + +// ------------------------------------------------------------------------------------------------- +// Penalty Test +// ------------------------------------------------------------------------------------------------- + +int functionToCall(int parameter1) +{ + return 1; +} + +int functionToCall(int paramter1, int parameter2) +{ + return 1; +} + +int functionToCall(int paramter1, int parameter2, int parameter3) +{ + return 1; +} + +int functionToCall(int paramter1, int parameter2, int parameter3, int parameter4, int parameter5) +{ + return 1; +} + +int functionToCall( + int paramter1, int parameter2, int parameter3, int parameter4, int parameter5, int paramete6) +{ + return 1; +} + +int functionToCall(int paramter1, + int parameter2, + int parameter3, + int parameter4, + int parameter5, + int paramete6, + int parameter6) +{ + return 1; +} + +bool functionToCallSt(const QString ¶mter1, const QStringList &list) +{ + return 1; +} + +void emitAddOutput(const QString &text, int priority) {} +void emitAddOutput(const QString &text, int priority, int category) {} + +void penaltyTests(bool isThatTrue) +{ + int valueX = 3; + int valueY = 1; + int valueZ = 1; + int valueXTimesY = valueX * valueY; + int unbelievableBigValue = 1000000; + int unlimitedValueunbelievableBigValue = 1000000; + QString arguments; + QString argumentsVeryLong; + + const QFile::OpenMode openMode = isThatTrue ? QIODevice::ReadOnly + : (QIODevice::ReadOnly | QIODevice::Text); + + const auto someValue10 = functionToCall(valueX, valueY, valueXTimesY); + const auto someValue11 = functionToCall(valueX, + valueY, + valueXTimesY, + unbelievableBigValue, + unbelievableBigValue); + const auto someValue12 = functionToCall(valueX, + valueY, + valueXTimesY, + unbelievableBigValue, + unbelievableBigValue * unbelievableBigValue, + unbelievableBigValue); + + const auto someValue13 = functionToCall(valueX, + valueY, + valueXTimesY, + unbelievableBigValue, + functionToCall(functionToCall(valueX), + functionToCall(valueY)), + unbelievableBigValue); + + const auto someValue14WithAnOutstandingLongName + = functionToCall(valueX, + valueY, + valueXTimesY, + unbelievableBigValue, + functionToCall(functionToCall(valueX), functionToCall(valueY)), + unbelievableBigValue); + + const bool someValue20 = functionToCall(valueX, valueY, valueXTimesY) || functionToCall(3); + const bool someValue21 = functionToCall(valueX, valueY, valueXTimesY) + || functionToCall(valueX, valueY); + + emitAddOutput(QCoreApplication::tr("Starting: \"%1\" %2") + .arg("/some/very/very/very/very/long/path/to/an/executable", arguments), + functionToCall(3), + functionToCall(3) | valueX); + + emitAddOutput(QCoreApplication::tr("Starting: \"%1\" %2") + .arg("/some/very/very/very/very/long/path/to/an/executable", + argumentsVeryLong), + functionToCall(3), + functionToCall(3) | unlimitedValueunbelievableBigValue + | unlimitedValueunbelievableBigValue); + + const QString path; + const bool someLongerNameNNNNNNNNNN = functionToCallSt(path, + QStringList(QLatin1String("-print-env"))); +} + +// ------------------------------------------------------------------------------------------------- +// Classes and member functions +// ------------------------------------------------------------------------------------------------- + +class Base1 +{}; +class Base2 +{}; + +class MyClass : public Base1, public Base2, public QObject +{ + Q_OBJECT + +public: + friend class FriendX; // for X::foo() + friend class OtherFriendY; // for Y::bar() + + MyClass() {} + + MyClass(int d1) + : data1(d1) + {} + + MyClass(int d1, int d2) + : data1(d1) + , data2(d2) + , data3(d2) + {} + + MyClass(int initialData1, + int initialData2, + int initialData3, + int initialData4, + int initialData5, + int initialData6) + : data1(initialData1) + , data2(initialData2) + , data3(initialData3) + , data4(initialData4) + , data5(initialData5) + , data6(initialData6) + { + // NOTE: Ops, manual alignment of QObject::connect() arguments is reverted + // (we tend to write emitter/receiver on separate lines) + connect(this, &MyClass::inlineZeroStatements, this, &MyClass::nonInlineSingleStatement); + } + + void inlineZeroStatements() {} + void inlineSingleStatement() { aGlobalInt = 2; } + void inlineMultipleStatements() + { + aGlobalInt = 2; + aGlobalInt = 3; + } + + void nonInlineZeroStatements(); + void nonInlineSingleStatement(); + void nonInlineMultipleStatements(); + + virtual void shortVirtual(int parameter1, int parameter2, int parameter3) = 0; + + // NOTE: Ops, awkward placement of "= 0;" + virtual void longerVirtual( + int parameter1, int parameter2, int parameter3, int parameter4, int parameter5) + = 0; + + int someGetter() const; + +private: + int data1 = 0; + int data2 = 0; + int data3 = 0; + int data4 = 0; + int data5 = 0; + int data6 = 0; +}; + +void MyClass::nonInlineZeroStatements() {} + +void MyClass::nonInlineSingleStatement() +{ + aGlobalInt = 2; +} + +void MyClass::nonInlineMultipleStatements() +{ + aGlobalInt = 2; + aGlobalInt = 2; +} + +template<class T> +class TemplateClass +{ +}; + +// ------------------------------------------------------------------------------------------------- +// Enums +// ------------------------------------------------------------------------------------------------- + +// NOTE: OK, enums: one-liner are possible +enum MyEnum { SourceFiles = 0x1, GeneratedFiles = 0x2, AllFiles = SourceFiles | GeneratedFiles }; + +// NOTE: OK, enums: a comment breaks one-liners +enum MyEnumX { + OSourceFiles = 0x1 // fancy +}; + +// NOTE: OK, enums: longer ones are wrapped +enum MyOtherEnum { + XSourceFiles = 0x1, + XGeneratedFiles = 0x2, + XAllFiles = XSourceFiles | XGeneratedFiles +}; + +enum { + Match_None, + Match_TooManyArgs, + Match_TooFewArgs, + Match_Ok +} matchType + = Match_None; // NOTE: Ops, awkward placement of "= value;" at enum definition+use + +// ------------------------------------------------------------------------------------------------- +// Lambdas +// ------------------------------------------------------------------------------------------------- + +void takeLambda(std::function<int()>) {} +void takeLambdaWithSomeLongerNameHa(std::function<int()>) {} +bool UtilsFiltered(QVector<N::Baz>, std::function<int(const N::Baz &)>) +{ + return true; +} + +void lambda() +{ + auto shortLambda = []() { return 1; }; + auto longLambda = []() { + aGlobalInt = 3; + return; + }; + + takeLambda([]() { return true; }); + takeLambda([]() { + aGlobalInt = 3; + return aGlobalInt; + }); + + // NOTE: Ops, lambda: capture and parameter list should be on separate line + int thisCouldBeSomeLongerFunctionCallExpressionOrSoSoSo; + takeLambdaWithSomeLongerNameHa( + [&]() { return thisCouldBeSomeLongerFunctionCallExpressionOrSoSoSo; }); + + QVector<N::Baz> myClasses; + UtilsFiltered(myClasses, [](const N::Baz &) { return 1; }); + + // NOTE: Ops, lambda: lambda not started on new line in if-condition + if (UtilsFiltered(myClasses, [](const N::Baz &) { return 1; })) { + ++aGlobalInt; + } +} + +// ------------------------------------------------------------------------------------------------- +// Control flow +// ------------------------------------------------------------------------------------------------- + +int fn(int, int, int) +{ + return 1; +} + +void controlFlow(int x) +{ + int y = -1; + + // if + if (true) + fn(1, 2, 3); + + int value = 3; + if (value) { + value += value + 1; + --value; + } + + if (x == y) + fn(1, 2, 3); + else if (x > y) + fn(1, 2, 3); + else + fn(1, 2, 3); + + if (x == y) { + fn(1, 2, 3); + return; + } else if (x > y) { + fn(1, 2, 3); + } else { + fn(1, 2, 3); + } + + // switch + switch (x) { + case 0: + ++aGlobalInt; + return; + case 1: + fn(1, 2, 3); + ++aGlobalInt; + break; + case 2: + fn(1, 2, 3); + break; + default: + break; + } + + // do-while + do { + value += value + 1; + ++value; + } while (true); + + // for + QVector<int> myVector; + for (int i = 0; i < myVector.size(); ++i) + ++aGlobalInt; + + for (QVector<int>::const_iterator i = myVector.begin(); i != myVector.end(); ++i) + ++aGlobalInt; + + QVector<int> myVectorWithLongName; + for (QVector<int>::const_iterator i = myVectorWithLongName.begin(), + ei = myVectorWithLongName.end(); + i != ei; + ++i) { + } + + forever { + ++aGlobalInt; + --aGlobalInt; + } +} + +// ------------------------------------------------------------------------------------------------- +// Function declarations and calls - extreme cases +// ------------------------------------------------------------------------------------------------- + +void extremeFunction(const char[]) {} +void extremeFunction( + int uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuunbelievableLongParameter) +{ + extremeFunction( + uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuunbelievableLongParameter); + + int uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuunbelievableLongValue + = 3; + ++uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuunbelievableLongValue; + + extremeFunction( + "some super duper super duper super duper super duper super duper super duper super duper long"); +} + +void extremeFunction2(int parameter1, + int parameter2, + int parameter3WithAVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVerVeryVeryLong) +{ + extremeFunction2(parameter1, + parameter2, + parameter3WithAVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVerVeryVeryLong); +} + +void extremeFunction3(int parameter1, + int parameter2, + int parameter3WithAVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVerVeryVeryLongNameX) +{ + extremeFunction3(parameter1, + parameter2, + parameter3WithAVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVerVeryVeryLongNameX); +} + +// ------------------------------------------------------------------------------------------------- +// Misc +// ------------------------------------------------------------------------------------------------- + +static Q_LOGGING_CATEGORY(log, "qtc.cpptools.builtineditordocumentprocessor") + + int hello; // NOTE: Ops, awkward placement of next token after Q_LOGGING_CATEGORY (semicolon helps) + +// ------------------------------------------------------------------------------------------------- + +int main() {} |