aboutsummaryrefslogtreecommitdiffstats
path: root/tests/manual
diff options
context:
space:
mode:
authorNikolai Kosjar <nikolai.kosjar@qt.io>2017-08-16 08:58:48 +0200
committerNikolai Kosjar <nikolai.kosjar@qt.io>2017-09-04 06:53:55 +0000
commit54a43de656a490e4bf30005827b2e10adb725502 (patch)
treea72deca4c9ab7eb7a58c0256ba05be5e0967f188 /tests/manual
parent40683aaa4e461553289ae79fdae344084c43ca1c (diff)
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>
Diffstat (limited to 'tests/manual')
-rw-r--r--tests/manual/clang-format-for-qtc/clang-format-for-qtc.pro4
-rw-r--r--tests/manual/clang-format-for-qtc/test.cpp690
2 files changed, 694 insertions, 0 deletions
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 &paramter1, 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() {}