diff options
author | Stephen Hines <srhines@google.com> | 2015-03-23 12:09:02 -0700 |
---|---|---|
committer | Stephen Hines <srhines@google.com> | 2015-03-31 17:07:53 -0700 |
commit | 0e2c34f92f00628d48968dfea096d36381f494cb (patch) | |
tree | 03a142fc9174f13e1e3120853592c56778f14fe5 /unittests | |
parent | f6595cb19f570efe109abe570c726ebd7afd3973 (diff) | |
download | clang-0e2c34f92f00628d48968dfea096d36381f494cb.tar.gz |
Update aosp/master clang for rebase to r230699.
Change-Id: I6a546ab3d4ae37119eebb735e102cca4f80ab520
Diffstat (limited to 'unittests')
-rw-r--r-- | unittests/AST/ASTVectorTest.cpp | 1 | ||||
-rw-r--r-- | unittests/AST/EvaluateAsRValueTest.cpp | 8 | ||||
-rw-r--r-- | unittests/ASTMatchers/ASTMatchersTest.cpp | 87 | ||||
-rw-r--r-- | unittests/ASTMatchers/ASTMatchersTest.h | 12 | ||||
-rw-r--r-- | unittests/Basic/CMakeLists.txt | 1 | ||||
-rw-r--r-- | unittests/Basic/DiagnosticTest.cpp | 49 | ||||
-rw-r--r-- | unittests/Basic/FileManagerTest.cpp | 2 | ||||
-rw-r--r-- | unittests/CodeGen/BufferSourceTest.cpp | 9 | ||||
-rw-r--r-- | unittests/Format/FormatTest.cpp | 443 | ||||
-rw-r--r-- | unittests/Format/FormatTestJS.cpp | 206 | ||||
-rw-r--r-- | unittests/Format/FormatTestJava.cpp | 247 | ||||
-rw-r--r-- | unittests/Tooling/ToolingTest.cpp | 33 | ||||
-rw-r--r-- | unittests/libclang/LibclangTest.cpp | 2 |
13 files changed, 937 insertions, 163 deletions
diff --git a/unittests/AST/ASTVectorTest.cpp b/unittests/AST/ASTVectorTest.cpp index 4b5d569a80..55c06d0071 100644 --- a/unittests/AST/ASTVectorTest.cpp +++ b/unittests/AST/ASTVectorTest.cpp @@ -15,7 +15,6 @@ #include "clang/AST/ASTContext.h" #include "clang/AST/ASTVector.h" #include "clang/Basic/Builtins.h" - #include "gtest/gtest.h" using namespace clang; diff --git a/unittests/AST/EvaluateAsRValueTest.cpp b/unittests/AST/EvaluateAsRValueTest.cpp index b5f9b32740..820edbc7c3 100644 --- a/unittests/AST/EvaluateAsRValueTest.cpp +++ b/unittests/AST/EvaluateAsRValueTest.cpp @@ -12,16 +12,14 @@ // //===----------------------------------------------------------------------===// -#include <map> -#include <string> - +#include "clang/AST/ASTConsumer.h" #include "clang/AST/ASTConsumer.h" #include "clang/AST/ASTContext.h" #include "clang/AST/RecursiveASTVisitor.h" #include "clang/Tooling/Tooling.h" #include "gtest/gtest.h" - -#include "clang/AST/ASTConsumer.h" +#include <map> +#include <string> using namespace clang::tooling; diff --git a/unittests/ASTMatchers/ASTMatchersTest.cpp b/unittests/ASTMatchers/ASTMatchersTest.cpp index c88a197643..0d27b5db03 100644 --- a/unittests/ASTMatchers/ASTMatchersTest.cpp +++ b/unittests/ASTMatchers/ASTMatchersTest.cpp @@ -379,6 +379,21 @@ TEST(DeclarationMatcher, hasDeclContext) { EXPECT_TRUE(matches("class D{};", decl(hasDeclContext(decl())))); } +TEST(DeclarationMatcher, translationUnitDecl) { + const std::string Code = "int MyVar1;\n" + "namespace NameSpace {\n" + "int MyVar2;\n" + "} // namespace NameSpace\n"; + EXPECT_TRUE(matches( + Code, varDecl(hasName("MyVar1"), hasDeclContext(translationUnitDecl())))); + EXPECT_FALSE(matches( + Code, varDecl(hasName("MyVar2"), hasDeclContext(translationUnitDecl())))); + EXPECT_TRUE(matches( + Code, + varDecl(hasName("MyVar2"), + hasDeclContext(decl(hasDeclContext(translationUnitDecl())))))); +} + TEST(DeclarationMatcher, LinkageSpecification) { EXPECT_TRUE(matches("extern \"C\" { void foo() {}; }", linkageSpecDecl())); EXPECT_TRUE(notMatches("void foo() {};", linkageSpecDecl())); @@ -2104,8 +2119,16 @@ TEST(Matcher, FloatLiterals) { EXPECT_TRUE(matches("double i = 10.0;", HasFloatLiteral)); EXPECT_TRUE(matches("double i = 10.0L;", HasFloatLiteral)); EXPECT_TRUE(matches("double i = 1e10;", HasFloatLiteral)); + EXPECT_TRUE(matches("double i = 5.0;", floatLiteral(equals(5.0)))); + EXPECT_TRUE(matches("double i = 5.0;", floatLiteral(equals(5.0f)))); + EXPECT_TRUE( + matches("double i = 5.0;", floatLiteral(equals(llvm::APFloat(5.0))))); EXPECT_TRUE(notMatches("float i = 10;", HasFloatLiteral)); + EXPECT_TRUE(notMatches("double i = 5.0;", floatLiteral(equals(6.0)))); + EXPECT_TRUE(notMatches("double i = 5.0;", floatLiteral(equals(6.0f)))); + EXPECT_TRUE( + notMatches("double i = 5.0;", floatLiteral(equals(llvm::APFloat(6.0))))); } TEST(Matcher, NullPtrLiteral) { @@ -3136,6 +3159,12 @@ TEST(InitListExpression, MatchesInitListExpression) { initListExpr(hasType(asString("int [2]"))))); EXPECT_TRUE(matches("struct B { int x, y; }; B b = { 5, 6 };", initListExpr(hasType(recordDecl(hasName("B")))))); + EXPECT_TRUE(matches("struct S { S(void (*a)()); };" + "void f();" + "S s[1] = { &f };", + declRefExpr(to(functionDecl(hasName("f")))))); + EXPECT_TRUE( + matches("int i[1] = {42, [0] = 43};", integerLiteral(equals(42)))); } TEST(UsingDeclaration, MatchesUsingDeclarations) { @@ -3857,6 +3886,11 @@ TEST(TypeMatching, MatchesTypes) { EXPECT_TRUE(matches("struct S {};", qualType().bind("loc"))); } +TEST(TypeMatching, MatchesVoid) { + EXPECT_TRUE( + matches("struct S { void func(); };", methodDecl(returns(voidType())))); +} + TEST(TypeMatching, MatchesArrayTypes) { EXPECT_TRUE(matches("int a[] = {2,3};", arrayType())); EXPECT_TRUE(matches("int a[42];", arrayType())); @@ -4625,5 +4659,58 @@ TEST(EqualsBoundNodeMatcher, UnlessDescendantsOfAncestorsMatch) { .bind("data"))); } +TEST(TypeDefDeclMatcher, Match) { + EXPECT_TRUE(matches("typedef int typedefDeclTest;", + typedefDecl(hasName("typedefDeclTest")))); +} + +// FIXME: Figure out how to specify paths so the following tests pass on Windows. +#ifndef LLVM_ON_WIN32 + +TEST(Matcher, IsExpansionInMainFileMatcher) { + EXPECT_TRUE(matches("class X {};", + recordDecl(hasName("X"), isExpansionInMainFile()))); + EXPECT_TRUE(notMatches("", recordDecl(isExpansionInMainFile()))); + FileContentMappings M; + M.push_back(std::make_pair("/other", "class X {};")); + EXPECT_TRUE(matchesConditionally("#include <other>\n", + recordDecl(isExpansionInMainFile()), false, + "-isystem/", M)); +} + +TEST(Matcher, IsExpansionInSystemHeader) { + FileContentMappings M; + M.push_back(std::make_pair("/other", "class X {};")); + EXPECT_TRUE(matchesConditionally( + "#include \"other\"\n", recordDecl(isExpansionInSystemHeader()), true, + "-isystem/", M)); + EXPECT_TRUE(matchesConditionally("#include \"other\"\n", + recordDecl(isExpansionInSystemHeader()), + false, "-I/", M)); + EXPECT_TRUE(notMatches("class X {};", + recordDecl(isExpansionInSystemHeader()))); + EXPECT_TRUE(notMatches("", recordDecl(isExpansionInSystemHeader()))); +} + +TEST(Matcher, IsExpansionInFileMatching) { + FileContentMappings M; + M.push_back(std::make_pair("/foo", "class A {};")); + M.push_back(std::make_pair("/bar", "class B {};")); + EXPECT_TRUE(matchesConditionally( + "#include <foo>\n" + "#include <bar>\n" + "class X {};", + recordDecl(isExpansionInFileMatching("b.*"), hasName("B")), true, + "-isystem/", M)); + EXPECT_TRUE(matchesConditionally( + "#include <foo>\n" + "#include <bar>\n" + "class X {};", + recordDecl(isExpansionInFileMatching("f.*"), hasName("X")), false, + "-isystem/", M)); +} + +#endif // LLVM_ON_WIN32 + } // end namespace ast_matchers } // end namespace clang diff --git a/unittests/ASTMatchers/ASTMatchersTest.h b/unittests/ASTMatchers/ASTMatchersTest.h index 2e5b3da5a5..a2ab9feee2 100644 --- a/unittests/ASTMatchers/ASTMatchersTest.h +++ b/unittests/ASTMatchers/ASTMatchersTest.h @@ -22,6 +22,7 @@ using clang::tooling::buildASTFromCodeWithArgs; using clang::tooling::newFrontendActionFactory; using clang::tooling::runToolOnCodeWithArgs; using clang::tooling::FrontendActionFactory; +using clang::tooling::FileContentMappings; class BoundNodesCallback { public: @@ -58,10 +59,10 @@ private: }; template <typename T> -testing::AssertionResult matchesConditionally(const std::string &Code, - const T &AMatcher, - bool ExpectMatch, - llvm::StringRef CompileArg) { +testing::AssertionResult matchesConditionally( + const std::string &Code, const T &AMatcher, bool ExpectMatch, + llvm::StringRef CompileArg, + const FileContentMappings &VirtualMappedFiles = FileContentMappings()) { bool Found = false, DynamicFound = false; MatchFinder Finder; VerifyMatch VerifyFound(nullptr, &Found); @@ -73,7 +74,8 @@ testing::AssertionResult matchesConditionally(const std::string &Code, newFrontendActionFactory(&Finder)); // Some tests use typeof, which is a gnu extension. std::vector<std::string> Args(1, CompileArg); - if (!runToolOnCodeWithArgs(Factory->create(), Code, Args)) { + if (!runToolOnCodeWithArgs(Factory->create(), Code, Args, "input.cc", + VirtualMappedFiles)) { return testing::AssertionFailure() << "Parsing error in \"" << Code << "\""; } if (Found != DynamicFound) { diff --git a/unittests/Basic/CMakeLists.txt b/unittests/Basic/CMakeLists.txt index b8f69bf357..3cb3cb8d3c 100644 --- a/unittests/Basic/CMakeLists.txt +++ b/unittests/Basic/CMakeLists.txt @@ -4,6 +4,7 @@ set(LLVM_LINK_COMPONENTS add_clang_unittest(BasicTests CharInfoTest.cpp + DiagnosticTest.cpp FileManagerTest.cpp SourceManagerTest.cpp VirtualFileSystemTest.cpp diff --git a/unittests/Basic/DiagnosticTest.cpp b/unittests/Basic/DiagnosticTest.cpp new file mode 100644 index 0000000000..fa2b56e083 --- /dev/null +++ b/unittests/Basic/DiagnosticTest.cpp @@ -0,0 +1,49 @@ +//===- unittests/Basic/DiagnosticTest.cpp -- Diagnostic engine tests ------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "clang/Basic/Diagnostic.h" +#include "clang/Basic/DiagnosticIDs.h" +#include "gtest/gtest.h" + +using namespace llvm; +using namespace clang; + +namespace { + +// Check that DiagnosticErrorTrap works with SuppressAllDiagnostics. +TEST(DiagnosticTest, suppressAndTrap) { + DiagnosticsEngine Diags(new DiagnosticIDs(), + new DiagnosticOptions, + new IgnoringDiagConsumer()); + Diags.setSuppressAllDiagnostics(true); + + { + DiagnosticErrorTrap trap(Diags); + + // Diag that would set UncompilableErrorOccurred and ErrorOccurred. + Diags.Report(diag::err_target_unknown_triple) << "unknown"; + + // Diag that would set UnrecoverableErrorOccurred and ErrorOccurred. + Diags.Report(diag::err_cannot_open_file) << "file" << "error"; + + // Diag that would set FatalErrorOccurred + // (via non-note following a fatal error). + Diags.Report(diag::warn_mt_message) << "warning"; + + EXPECT_TRUE(trap.hasErrorOccurred()); + EXPECT_TRUE(trap.hasUnrecoverableErrorOccurred()); + } + + EXPECT_FALSE(Diags.hasErrorOccurred()); + EXPECT_FALSE(Diags.hasFatalErrorOccurred()); + EXPECT_FALSE(Diags.hasUncompilableErrorOccurred()); + EXPECT_FALSE(Diags.hasUnrecoverableErrorOccurred()); +} + +} diff --git a/unittests/Basic/FileManagerTest.cpp b/unittests/Basic/FileManagerTest.cpp index e53213b4bc..dd8cf2410a 100644 --- a/unittests/Basic/FileManagerTest.cpp +++ b/unittests/Basic/FileManagerTest.cpp @@ -10,8 +10,8 @@ #include "clang/Basic/FileManager.h" #include "clang/Basic/FileSystemOptions.h" #include "clang/Basic/FileSystemStatCache.h" -#include "gtest/gtest.h" #include "llvm/Config/llvm-config.h" +#include "gtest/gtest.h" using namespace llvm; using namespace clang; diff --git a/unittests/CodeGen/BufferSourceTest.cpp b/unittests/CodeGen/BufferSourceTest.cpp index f9d0991933..b2a8ba5808 100644 --- a/unittests/CodeGen/BufferSourceTest.cpp +++ b/unittests/CodeGen/BufferSourceTest.cpp @@ -10,16 +10,16 @@ #include "clang/AST/ASTConsumer.h" #include "clang/AST/ASTContext.h" #include "clang/AST/RecursiveASTVisitor.h" +#include "clang/Basic/TargetInfo.h" +#include "clang/CodeGen/ModuleBuilder.h" #include "clang/Frontend/CompilerInstance.h" #include "clang/Lex/Preprocessor.h" -#include "clang/CodeGen/ModuleBuilder.h" -#include "clang/Sema/Sema.h" #include "clang/Parse/ParseAST.h" -#include "clang/Basic/TargetInfo.h" +#include "clang/Sema/Sema.h" #include "llvm/ADT/Triple.h" +#include "llvm/IR/LLVMContext.h" #include "llvm/Support/Host.h" #include "llvm/Support/MemoryBuffer.h" -#include "llvm/IR/LLVMContext.h" #include "gtest/gtest.h" using namespace llvm; @@ -63,7 +63,6 @@ TEST(BufferSourceTest, EmitCXXGlobalInitFunc) { compiler.getDiagnostics(), "EmitCXXGlobalInitFuncTest", compiler.getCodeGenOpts(), - compiler.getTargetOpts(), llvm::getGlobalContext()))); compiler.createSema(clang::TU_Prefix,NULL); diff --git a/unittests/Format/FormatTest.cpp b/unittests/Format/FormatTest.cpp index a6bbe16d86..9738877e45 100644 --- a/unittests/Format/FormatTest.cpp +++ b/unittests/Format/FormatTest.cpp @@ -67,6 +67,12 @@ protected: verifyFormat(llvm::Twine("void f() { " + text + " }").str()); } + /// \brief Verify that clang-format does not crash on the given input. + void verifyNoCrash(llvm::StringRef Code, + const FormatStyle &Style = getLLVMStyle()) { + format(Code, Style); + } + int ReplacementCount; }; @@ -487,6 +493,11 @@ TEST_F(FormatTest, ElseIf) { "} else if (aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(\n" " aaaaaaaaaaaaaaaaaaaaaaaaaaaa)) {\n" "}"); + verifyFormat("if (a) {\n" + "} else if (\n" + " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa) {\n" + "}", + getLLVMStyleWithColumns(62)); } TEST_F(FormatTest, FormatsForLoop) { @@ -745,10 +756,21 @@ TEST_F(FormatTest, ShortCaseLabels) { "case 3:\n" "case 4:\n" "case 5: return;\n" + "case 6: // comment\n" + " return;\n" + "case 7:\n" + " // comment\n" + " return;\n" "default: y = 1; break;\n" "}", Style); verifyFormat("switch (a) {\n" + "#if FOO\n" + "case 0: return 0;\n" + "#endif\n" + "}", + Style); + verifyFormat("switch (a) {\n" "case 1: {\n" "}\n" "case 2: {\n" @@ -987,6 +1009,14 @@ TEST_F(FormatTest, UnderstandsSingleLineComments) { " // first\n" "// at start\n" "otherLine();")); + EXPECT_EQ("void f() {\n" + " lineWith(); // comment\n" + " // at start\n" + "}", + format("void f() {\n" + " lineWith(); // comment\n" + " // at start\n" + "}")); verifyFormat( "#define A \\\n" @@ -1010,6 +1040,9 @@ TEST_F(FormatTest, UnderstandsSingleLineComments) { " // spanning two lines\n" " x + 3) {\n" "}")); + + verifyNoCrash("/\\\n/"); + verifyNoCrash("/\\\n* */"); } TEST_F(FormatTest, KeepsParameterWithTrailingCommentsOnTheirOwnLine) { @@ -2058,6 +2091,21 @@ TEST_F(FormatTest, FormatsNSEnums) { " // Information about aThirdDecentlyLongValue.\n" " aThirdDecentlyLongValue\n" "};"); + verifyGoogleFormat("typedef NS_OPTIONS(NSInteger, MyType) {\n" + " a = 1,\n" + " b = 2,\n" + " c = 3,\n" + "};"); + verifyGoogleFormat("typedef CF_ENUM(NSInteger, MyType) {\n" + " a = 1,\n" + " b = 2,\n" + " c = 3,\n" + "};"); + verifyGoogleFormat("typedef CF_OPTIONS(NSInteger, MyType) {\n" + " a = 1,\n" + " b = 2,\n" + " c = 3,\n" + "};"); } TEST_F(FormatTest, FormatsBitfields) { @@ -2157,11 +2205,11 @@ TEST_F(FormatTest, FormatsInlineASM) { " : \"a\"(value));"); EXPECT_EQ( "void NS_InvokeByIndex(void *that, unsigned int methodIndex) {\n" - " __asm {\n" + " __asm {\n" " mov edx,[that] // vtable in edx\n" " mov eax,methodIndex\n" " call [edx][eax*4] // stdcall\n" - " }\n" + " }\n" "}", format("void NS_InvokeByIndex(void *that, unsigned int methodIndex) {\n" " __asm {\n" @@ -2170,6 +2218,10 @@ TEST_F(FormatTest, FormatsInlineASM) { " call [edx][eax*4] // stdcall\n" " }\n" "}")); + verifyFormat("void function() {\n" + " // comment\n" + " asm(\"\");\n" + "}"); } TEST_F(FormatTest, FormatTryCatch) { @@ -2192,6 +2244,29 @@ TEST_F(FormatTest, FormatTryCatch) { " throw;\n" " }\n" "};\n"); + + // Incomplete try-catch blocks. + verifyFormat("try {} catch ("); +} + +TEST_F(FormatTest, FormatSEHTryCatch) { + verifyFormat("__try {\n" + " int a = b * c;\n" + "} __except (EXCEPTION_EXECUTE_HANDLER) {\n" + " // Do nothing.\n" + "}"); + + verifyFormat("__try {\n" + " int a = b * c;\n" + "} __finally {\n" + " // Do nothing.\n" + "}"); + + verifyFormat("DEBUG({\n" + " __try {\n" + " } __finally {\n" + " }\n" + "});\n"); } TEST_F(FormatTest, IncompleteTryCatchBlocks) { @@ -2226,6 +2301,20 @@ TEST_F(FormatTest, FormatTryCatchBraceStyles) { " // something\n" "}", Style); + verifyFormat("__try {\n" + " // something\n" + "}\n" + "__finally {\n" + " // something\n" + "}", + Style); + verifyFormat("@try {\n" + " // something\n" + "}\n" + "@finally {\n" + " // something\n" + "}", + Style); Style.BreakBeforeBraces = FormatStyle::BS_Allman; verifyFormat("try\n" "{\n" @@ -2251,13 +2340,16 @@ TEST_F(FormatTest, FormatTryCatchBraceStyles) { TEST_F(FormatTest, FormatObjCTryCatch) { verifyFormat("@try {\n" " f();\n" - "}\n" - "@catch (NSException e) {\n" + "} @catch (NSException e) {\n" " @throw;\n" - "}\n" - "@finally {\n" + "} @finally {\n" " exit(42);\n" "}"); + verifyFormat("DEBUG({\n" + " @try {\n" + " } @finally {\n" + " }\n" + "});\n"); } TEST_F(FormatTest, StaticInitializers) { @@ -2418,6 +2510,10 @@ TEST_F(FormatTest, DoesntRemoveUnknownTokens) { "\\na : b);", format("const char * c = STRINGIFY(\n" "\\na : b);")); + + verifyFormat("a\r\\"); + verifyFormat("a\v\\"); + verifyFormat("a\f\\"); } TEST_F(FormatTest, IndentsPPDirectiveInReducedSpace) { @@ -2558,6 +2654,13 @@ TEST_F(FormatTest, MacroDefinitionsWithIncompleteCode) { verifyFormat("#pragma omp threadprivate( \\\n" " y)), // expected-warning", getLLVMStyleWithColumns(28)); + verifyFormat("#d, = };"); + verifyFormat("#if \"a"); + + verifyNoCrash("#if a\na(\n#else\n#endif\n{a"); + verifyNoCrash("a={0,1\n#if a\n#else\n;\n#endif\n}"); + verifyNoCrash("#if a\na(\n#else\n#endif\n) a {a,b,c,d,f,g};"); + verifyNoCrash("#ifdef A\n a(\n #else\n #endif\n) = []() { \n)}"); } TEST_F(FormatTest, MacrosWithoutTrailingSemicolon) { @@ -2598,6 +2701,9 @@ TEST_F(FormatTest, MacrosWithoutTrailingSemicolon) { EXPECT_EQ("SOME_WEIRD_LOG_MACRO << SomeThing;", format("SOME_WEIRD_LOG_MACRO\n" "<< SomeThing;")); + + verifyFormat("VISIT_GL_CALL(GenBuffers, void, (GLsizei n, GLuint* buffers), " + "(n, buffers))\n", getChromiumStyle(FormatStyle::LK_Cpp)); } TEST_F(FormatTest, MacroCallsWithoutTrailingSemicolon) { @@ -2775,6 +2881,17 @@ TEST_F(FormatTest, NoEscapedNewlineHandlingInBlockComments) { EXPECT_EQ("/* \\ \\ \\\n*/", format("\\\n/* \\ \\ \\\n*/")); } +TEST_F(FormatTest, DontCrashOnBlockComments) { + EXPECT_EQ( + "int xxxxxxxxx; /* " + "yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy\n" + "zzzzzz\n" + "0*/", + format("int xxxxxxxxx; /* " + "yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy zzzzzz\n" + "0*/")); +} + TEST_F(FormatTest, CalculateSpaceOnConsecutiveLinesInMacro) { verifyFormat("#define A \\\n" " int v( \\\n" @@ -2867,6 +2984,12 @@ TEST_F(FormatTest, LayoutStatementsAroundPreprocessorDirectives) { "#if a\n" "#else\n" "#endif"); + + verifyFormat("void f(\n" + "#if A\n" + " );\n" + "#else\n" + "#endif"); } TEST_F(FormatTest, GraciouslyHandleIncorrectPreprocessorConditions) { @@ -2895,11 +3018,19 @@ TEST_F(FormatTest, LayoutBlockInsideParens) { "});", format(" functionCall ( {int i;int j;} );")); EXPECT_EQ("functionCall({\n" - " int i;\n" - " int j;\n" - " },\n" - " aaaa, bbbb, cccc);", + " int i;\n" + " int j;\n" + "}, aaaa, bbbb, cccc);", format(" functionCall ( {int i;int j;}, aaaa, bbbb, cccc);")); + EXPECT_EQ("functionCall(\n" + " {\n" + " int i;\n" + " int j;\n" + " },\n" + " aaaa, bbbb, // comment\n" + " cccc);", + format(" functionCall ( {int i;int j;}, aaaa, bbbb, // comment\n" + "cccc);")); EXPECT_EQ("functionCall(aaaa, bbbb, { int i; });", format(" functionCall (aaaa, bbbb, {int i;});")); EXPECT_EQ("functionCall(aaaa, bbbb, {\n" @@ -2910,7 +3041,8 @@ TEST_F(FormatTest, LayoutBlockInsideParens) { EXPECT_EQ("functionCall(aaaa, bbbb, { int i; });", format(" functionCall (aaaa, bbbb, {int i;});")); verifyFormat( - "Aaa({\n" + "Aaa(\n" // FIXME: There shouldn't be a linebreak here. + " {\n" " int i; // break\n" " },\n" " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb,\n" @@ -2992,10 +3124,11 @@ TEST_F(FormatTest, LayoutNestedBlocks) { FormatStyle Style = getGoogleStyle(); Style.ColumnLimit = 45; verifyFormat("Debug(aaaaa, {\n" - " if (aaaaaaaaaaaaaaaaaaaaaaaa)\n" - " return;\n" - " },\n" - " a);", Style); + " if (aaaaaaaaaaaaaaaaaaaaaaaa) return;\n" + "}, a);", + Style); + + verifyNoCrash("^{v^{a}}"); } TEST_F(FormatTest, IndividualStatementsOfNestedBlocks) { @@ -3236,40 +3369,44 @@ TEST_F(FormatTest, ExpressionIndentationBreakingBeforeOperators) { Style.BreakBeforeBinaryOperators = FormatStyle::BOS_All; verifyFormat( "bool value = aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" - " + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" - " + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" - " == aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" - " * bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\n" - " + bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\n" + " + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" + " + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" + " == aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" + " * bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\n" + " + bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\n" " && aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" - " * aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" - " > ccccccccccccccccccccccccccccccccccccccccc;", + " * aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" + " > ccccccccccccccccccccccccccccccccccccccccc;", Style); verifyFormat("if (aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" - " * aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" - " + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" + " * aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" + " + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" " == bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb) {\n}", Style); verifyFormat("if (aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" - " + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" - " * aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" + " + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" + " * aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" " == bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb) {\n}", Style); verifyFormat("if (aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" " == aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" - " * aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" - " + bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb) {\n}", + " * aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" + " + bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb) {\n}", Style); verifyFormat("if () {\n" "} else if (aaaaa\n" " && bbbbb // break\n" - " > ccccc) {\n" + " > ccccc) {\n" "}", Style); verifyFormat("return (a)\n" " // comment\n" " + b;", Style); + verifyFormat("int aaaaaa = aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" + " * bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\n" + " + cc;", + Style); // Forced by comments. verifyFormat( @@ -3290,13 +3427,46 @@ TEST_F(FormatTest, ExpressionIndentationBreakingBeforeOperators) { Style); } +TEST_F(FormatTest, NoOperandAlignment) { + FormatStyle Style = getLLVMStyle(); + Style.AlignOperands = false; + Style.BreakBeforeBinaryOperators = FormatStyle::BOS_NonAssignment; + verifyFormat( + "bool value = aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" + " + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" + " + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" + " == aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" + " * bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\n" + " + bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\n" + " && aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" + " * aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" + " > ccccccccccccccccccccccccccccccccccccccccc;", + Style); + + verifyFormat("int aaaaaa = aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" + " * bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\n" + " + cc;", + Style); + verifyFormat("int a = aa\n" + " + bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\n" + " * cccccccccccccccccccccccccccccccccccc;", + Style); + + Style.AlignAfterOpenBracket = false; + verifyFormat("return (a > b\n" + " // comment1\n" + " // comment2\n" + " || c);", + Style); +} + TEST_F(FormatTest, BreakingBeforeNonAssigmentOperators) { FormatStyle Style = getLLVMStyle(); Style.BreakBeforeBinaryOperators = FormatStyle::BOS_NonAssignment; verifyFormat("int aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa =\n" " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" - " + bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb;", Style); - + " + bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb;", + Style); } TEST_F(FormatTest, ConstructorInitializers) { @@ -4064,6 +4234,28 @@ TEST_F(FormatTest, AlignsAfterOpenBracket) { Style); } +TEST_F(FormatTest, ParenthesesAndOperandAlignment) { + FormatStyle Style = getLLVMStyleWithColumns(40); + verifyFormat("int a = f(aaaaaaaaaaaaaaaaaaaaaa &&\n" + " bbbbbbbbbbbbbbbbbbbbbb);", + Style); + Style.AlignAfterOpenBracket = true; + Style.AlignOperands = false; + verifyFormat("int a = f(aaaaaaaaaaaaaaaaaaaaaa &&\n" + " bbbbbbbbbbbbbbbbbbbbbb);", + Style); + Style.AlignAfterOpenBracket = false; + Style.AlignOperands = true; + verifyFormat("int a = f(aaaaaaaaaaaaaaaaaaaaaa &&\n" + " bbbbbbbbbbbbbbbbbbbbbb);", + Style); + Style.AlignAfterOpenBracket = false; + Style.AlignOperands = false; + verifyFormat("int a = f(aaaaaaaaaaaaaaaaaaaaaa &&\n" + " bbbbbbbbbbbbbbbbbbbbbb);", + Style); +} + TEST_F(FormatTest, BreaksConditionalExpressions) { verifyFormat( "aaaa(aaaaaaaaaaaaaaaaaaaa, aaaaaaaaaaaaaaaaaaaaaaaaaa\n" @@ -4472,6 +4664,9 @@ TEST_F(FormatTest, AlwaysBreakBeforeMultilineStrings) { format("NSString *const kString = @\"aaaa\"\n" "\"bbbb\";", Break)); + + Break.ColumnLimit = 0; + verifyFormat("const char *hello = \"hello llvm\";", Break); } TEST_F(FormatTest, AlignsPipes) { @@ -4570,6 +4765,11 @@ TEST_F(FormatTest, AlignsPipes) { " CHECK_EQ(aaaa, (*bbbbbbbbb)->cccccc)\n" " << \"qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq\";\n" "}"); + + // Handle 'endl'. + verifyFormat("llvm::errs() << aaaaaaaaaaaaaaaaaaaaaa << endl\n" + " << bbbbbbbbbbbbbbbbbbbbbb << endl;"); + verifyFormat("llvm::errs() << endl << bbbbbbbbbbbbbbbbbbbbbb << endl;"); } TEST_F(FormatTest, UnderstandsEquals) { @@ -4835,6 +5035,7 @@ TEST_F(FormatTest, UnderstandsTemplateParameters) { verifyFormat("f<int>();"); verifyFormat("template <typename T> void f() {}"); + verifyFormat("struct A<std::enable_if<sizeof(T2) < sizeof(int32)>::type>;"); // Not template parameters. verifyFormat("return a < b && c > d;"); @@ -4968,17 +5169,42 @@ TEST_F(FormatTest, UnderstandsOverloadedOperators) { verifyFormat("using A::operator+;"); - verifyFormat("Deleted &operator=(const Deleted &)& = default;"); - verifyFormat("Deleted &operator=(const Deleted &)&& = delete;"); - verifyGoogleFormat("Deleted& operator=(const Deleted&)& = default;"); - verifyGoogleFormat("Deleted& operator=(const Deleted&)&& = delete;"); - verifyFormat("string // break\n" "operator()() & {}"); verifyFormat("string // break\n" "operator()() && {}"); } +TEST_F(FormatTest, UnderstandsFunctionRefQualification) { + verifyFormat("Deleted &operator=(const Deleted &)& = default;"); + verifyFormat("Deleted &operator=(const Deleted &)&& = delete;"); + verifyFormat("SomeType MemberFunction(const Deleted &)& = delete;"); + verifyFormat("SomeType MemberFunction(const Deleted &)&& = delete;"); + verifyFormat("Deleted &operator=(const Deleted &)&;"); + verifyFormat("Deleted &operator=(const Deleted &)&&;"); + verifyFormat("SomeType MemberFunction(const Deleted &)&;"); + verifyFormat("SomeType MemberFunction(const Deleted &)&&;"); + + verifyGoogleFormat("Deleted& operator=(const Deleted&)& = default;"); + verifyGoogleFormat("SomeType MemberFunction(const Deleted&)& = delete;"); + verifyGoogleFormat("Deleted& operator=(const Deleted&)&;"); + verifyGoogleFormat("SomeType MemberFunction(const Deleted&)&;"); + + FormatStyle Spaces = getLLVMStyle(); + Spaces.SpacesInCStyleCastParentheses = true; + verifyFormat("Deleted &operator=(const Deleted &)& = default;", Spaces); + verifyFormat("SomeType MemberFunction(const Deleted &)& = delete;", Spaces); + verifyFormat("Deleted &operator=(const Deleted &)&;", Spaces); + verifyFormat("SomeType MemberFunction(const Deleted &)&;", Spaces); + + Spaces.SpacesInCStyleCastParentheses = false; + Spaces.SpacesInParentheses = true; + verifyFormat("Deleted &operator=( const Deleted & )& = default;", Spaces); + verifyFormat("SomeType MemberFunction( const Deleted & )& = delete;", Spaces); + verifyFormat("Deleted &operator=( const Deleted & )&;", Spaces); + verifyFormat("SomeType MemberFunction( const Deleted & )&;", Spaces); +} + TEST_F(FormatTest, UnderstandsNewAndDelete) { verifyFormat("void f() {\n" " A *a = new A;\n" @@ -5068,6 +5294,8 @@ TEST_F(FormatTest, UnderstandsUsesOfStarAndAmp) { "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(\n" " aaaaaaaaaaaaaaaaaaaaaaaaaaaa, *aaaaaaaaaaaaaaaaaaaaaaaaaaaaa);"); + verifyGoogleFormat("**outparam = 1;"); + verifyGoogleFormat("*outparam = a * b;"); verifyGoogleFormat("int main(int argc, char** argv) {}"); verifyGoogleFormat("A<int*> a;"); verifyGoogleFormat("A<int**> a;"); @@ -5378,6 +5606,11 @@ TEST_F(FormatTest, FormatsFunctionTypes) { verifyFormat("void f() { function(*some_pointer_var)[0] = 10; }"); } +TEST_F(FormatTest, FormatsPointersToArrayTypes) { + verifyFormat("A (*foo_)[6];"); + verifyFormat("vector<int> (*foo_)[6];"); +} + TEST_F(FormatTest, BreaksLongVariableDeclarations) { verifyFormat("LoooooooooooooooooooooooooooooooooooooooongType\n" " LoooooooooooooooooooooooooooooooooooooooongVariable;"); @@ -5492,6 +5725,8 @@ TEST_F(FormatTest, FormatsArrays) { "aaaaaaaaaaa aaaaaaaaaaaaaaa = aaaaaaaaaaaaaaaaaaaaaaaaaa->aaaaaaaaa[0]\n" " .aaaaaaa[0]\n" " .aaaaaaaaaaaaaaaaaaaaaa();"); + + verifyNoCrash("a[,Y?)]", getLLVMStyleWithColumns(10)); } TEST_F(FormatTest, LineStartsWithSpecialCharacter) { @@ -5533,6 +5768,10 @@ TEST_F(FormatTest, HandlesIncludeDirectives) { Style.AlwaysBreakBeforeMultilineStrings = true; Style.ColumnLimit = 0; verifyFormat("#import \"abc.h\"", Style); + + // But 'import' might also be a regular C++ namespace. + verifyFormat("import::SomeFunction(aaaaaaaaaaaaaaaaaaaaaaaaaaa,\n" + " aaaaaaaaaaaaaaaaaaaaaaaaaaaaa);"); } //===----------------------------------------------------------------------===// @@ -5615,6 +5854,7 @@ TEST_F(FormatTest, IncorrectAccessSpecifier) { TEST_F(FormatTest, IncorrectCodeUnbalancedBraces) { verifyFormat("{"); verifyFormat("#})"); + verifyNoCrash("(/**/[:!] ?[)."); } TEST_F(FormatTest, IncorrectCodeDoNoWhile) { @@ -5703,6 +5943,11 @@ TEST_F(FormatTest, LayoutCxx11BraceInitializers) { verifyFormat("std::vector<int> v = {1, 0 /* comment */};"); verifyFormat("Node n{1, Node{1000}, //\n" " 2};"); + verifyFormat("Aaaa aaaaaaa{\n" + " {\n" + " aaaa,\n" + " },\n" + "};"); // In combination with BinPackParameters = false. FormatStyle NoBinPacking = getLLVMStyle(); @@ -5812,8 +6057,7 @@ TEST_F(FormatTest, LayoutCxx11BraceInitializers) { " BracedList{ // comment 1 (Forcing interesting break)\n" " param1, param2,\n" " // comment 2\n" - " param3, param4\n" - " });", + " param3, param4 });", ExtraSpaces); verifyFormat( "std::this_thread::sleep_for(\n" @@ -5897,6 +6141,8 @@ TEST_F(FormatTest, FormatsBracedListsInColumnLayout) { // No column layout should be used here. verifyFormat("aaaaaaaaaaaaaaa = {aaaaaaaaaaaaaaaaaaaaaaaaaaa, 0, 0,\n" " bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb};"); + + verifyNoCrash("a<,"); } TEST_F(FormatTest, PullTrivialFunctionDefinitionsIntoSingleLine) { @@ -6682,6 +6928,7 @@ TEST_F(FormatTest, FormatObjCMethodExpr) { // Whew! verifyFormat("return in[42];"); + verifyFormat("for (auto v : in[1]) {\n}"); verifyFormat("for (id foo in [self getStuffFor:bla]) {\n" "}"); verifyFormat("[self aaaaa:MACRO(a, b:, c:)];"); @@ -7284,24 +7531,22 @@ TEST_F(FormatTest, BreaksWideAndNSStringLiterals) { EXPECT_EQ("@\"NSString \"\n" "@\"literal\";", format("@\"NSString literal\";", getGoogleStyleWithColumns(19))); + + // This input makes clang-format try to split the incomplete unicode escape + // sequence, which used to lead to a crasher. + verifyNoCrash( + "aaaaaaaaaaaaaaaaaaaa = L\"\\udff\"'; // aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + getLLVMStyleWithColumns(60)); } -TEST_F(FormatTest, BreaksRawStringLiterals) { - EXPECT_EQ("R\"x(raw )x\"\n" - "R\"x(literal)x\";", - format("R\"x(raw literal)x\";", getGoogleStyleWithColumns(15))); - EXPECT_EQ("uR\"x(raw )x\"\n" - "uR\"x(literal)x\";", - format("uR\"x(raw literal)x\";", getGoogleStyleWithColumns(16))); - EXPECT_EQ("u8R\"x(raw )x\"\n" - "u8R\"x(literal)x\";", - format("u8R\"x(raw literal)x\";", getGoogleStyleWithColumns(17))); - EXPECT_EQ("LR\"x(raw )x\"\n" - "LR\"x(literal)x\";", - format("LR\"x(raw literal)x\";", getGoogleStyleWithColumns(16))); - EXPECT_EQ("UR\"x(raw )x\"\n" - "UR\"x(literal)x\";", - format("UR\"x(raw literal)x\";", getGoogleStyleWithColumns(16))); +TEST_F(FormatTest, DoesNotBreakRawStringLiterals) { + FormatStyle Style = getGoogleStyleWithColumns(15); + EXPECT_EQ("R\"x(raw literal)x\";", format("R\"x(raw literal)x\";", Style)); + EXPECT_EQ("uR\"x(raw literal)x\";", format("uR\"x(raw literal)x\";", Style)); + EXPECT_EQ("LR\"x(raw literal)x\";", format("LR\"x(raw literal)x\";", Style)); + EXPECT_EQ("UR\"x(raw literal)x\";", format("UR\"x(raw literal)x\";", Style)); + EXPECT_EQ("u8R\"x(raw literal)x\";", + format("u8R\"x(raw literal)x\";", Style)); } TEST_F(FormatTest, BreaksStringLiteralsWithin_TMacro) { @@ -7490,11 +7735,6 @@ TEST_F(FormatTest, DoNotBreakStringLiteralsInEscapeSequence) { "\"00000000\"\n" "\"1\"", format("\"test\\000000000001\"", getLLVMStyleWithColumns(10))); - // FIXME: We probably don't need to care about escape sequences in raw - // literals. - EXPECT_EQ("R\"(\\x)\"\n" - "R\"(\\x00)\"\n", - format("R\"(\\x\\x00)\"\n", getGoogleStyleWithColumns(7))); } TEST_F(FormatTest, DoNotCreateUnreasonableUnwrappedLines) { @@ -7682,11 +7922,10 @@ TEST_F(FormatTest, ConfigurableUseOfTab) { Tab); verifyFormat("{\n" "\tQ({\n" - "\t\t int a;\n" - "\t\t someFunction(aaaaaaaaaa,\n" - "\t\t bbbbbbbbb);\n" - "\t },\n" - "\t p);\n" + "\t\tint a;\n" + "\t\tsomeFunction(aaaaaaaa,\n" + "\t\t bbbbbbb);\n" + "\t}, p);\n" "}", Tab); EXPECT_EQ("{\n" @@ -8276,6 +8515,11 @@ TEST_F(FormatTest, AllmanBraceBreaking) { " [object someMethod:@{ @\"a\" : @\"b\" }];\n" "}", AllmanBraceStyle); + verifyFormat("int f()\n" + "{ // comment\n" + " return 42;\n" + "}", + AllmanBraceStyle); AllmanBraceStyle.ColumnLimit = 19; verifyFormat("void f() { int i; }", AllmanBraceStyle); @@ -8561,7 +8805,9 @@ TEST_F(FormatTest, GetsCorrectBasedOnStyle) { TEST_F(FormatTest, ParsesConfigurationBools) { FormatStyle Style = {}; Style.Language = FormatStyle::LK_Cpp; + CHECK_PARSE_BOOL(AlignAfterOpenBracket); CHECK_PARSE_BOOL(AlignEscapedNewlinesLeft); + CHECK_PARSE_BOOL(AlignOperands); CHECK_PARSE_BOOL(AlignTrailingComments); CHECK_PARSE_BOOL(AllowAllParametersOfDeclarationOnNextLine); CHECK_PARSE_BOOL(AllowShortBlocksOnASingleLine); @@ -8662,6 +8908,8 @@ TEST_F(FormatTest, ParsesConfiguration) { AllowShortFunctionsOnASingleLine, FormatStyle::SFS_None); CHECK_PARSE("AllowShortFunctionsOnASingleLine: Inline", AllowShortFunctionsOnASingleLine, FormatStyle::SFS_Inline); + CHECK_PARSE("AllowShortFunctionsOnASingleLine: Empty", + AllowShortFunctionsOnASingleLine, FormatStyle::SFS_Empty); CHECK_PARSE("AllowShortFunctionsOnASingleLine: All", AllowShortFunctionsOnASingleLine, FormatStyle::SFS_All); // For backward compatibility: @@ -9167,6 +9415,11 @@ TEST_F(FormatTest, FormatsWithWebKitStyle) { "double b; // align comments.", Style); + // Do not align operands. + EXPECT_EQ("ASSERT(aaaa\n" + " || bbbb);", + format("ASSERT ( aaaa\n||bbbb);", Style)); + // Accept input's line breaks. EXPECT_EQ("if (aaaaaaaaaaaaaaa\n" " || bbbbbbbbbbbbbbb) {\n" @@ -9262,25 +9515,34 @@ TEST_F(FormatTest, FormatsLambdas) { verifyFormat("string abc = SomeFunction(aaaaaaaaaaaaa, aaaaa, []() {\n" " SomeOtherFunctioooooooooooooooooooooooooon();\n" "});"); + verifyFormat("Constructor()\n" + " : Field([] { // comment\n" + " int i;\n" + " }) {}"); // Lambdas with return types. verifyFormat("int c = []() -> int { return 2; }();\n"); verifyFormat("int c = []() -> vector<int> { return {2}; }();\n"); verifyFormat("Foo([]() -> std::vector<int> { return {2}; }());"); + verifyGoogleFormat("auto a = [&b, c](D* d) -> D* {};"); + verifyGoogleFormat("auto a = [&b, c](D* d) -> pair<D*, D*> {};"); + verifyGoogleFormat("auto a = [&b, c](D* d) -> D& {};"); + verifyGoogleFormat("auto a = [&b, c](D* d) -> const D* {};"); verifyFormat("auto aaaaaaaa = [](int i, // break for some reason\n" " int j) -> int {\n" " return ffffffffffffffffffffffffffffffffffffffffffff(i * j);\n" "};"); // Multiple lambdas in the same parentheses change indentation rules. - verifyFormat("SomeFunction([]() {\n" - " int i = 42;\n" - " return i;\n" - " },\n" - " []() {\n" - " int j = 43;\n" - " return j;\n" - " });"); + verifyFormat("SomeFunction(\n" + " []() {\n" + " int i = 42;\n" + " return i;\n" + " },\n" + " []() {\n" + " int j = 43;\n" + " return j;\n" + " });"); // More complex introducers. verifyFormat("return [i, args...] {};"); @@ -9303,6 +9565,19 @@ TEST_F(FormatTest, FormatsLambdas) { verifyFormat("void f() {\n" " MACRO((const AA &a) { return 1; });\n" "}"); + + verifyFormat("if (blah_blah(whatever, whatever, [] {\n" + " doo_dah();\n" + " doo_dah();\n" + " })) {\n" + "}"); + verifyFormat("auto lambda = []() {\n" + " int a = 2\n" + "#if A\n" + " + 2\n" + "#endif\n" + " ;\n" + "};"); } TEST_F(FormatTest, FormatsBlocks) { @@ -9396,6 +9671,7 @@ TEST_F(FormatTest, FormatsBlocks) { " }\n" " }\n" "});"); + verifyFormat("Block b = ^int *(A *a, B *b) {}"); FormatStyle FourIndent = getLLVMStyle(); FourIndent.ObjCBlockIndentWidth = 4; @@ -9501,6 +9777,29 @@ TEST_F(FormatTest, SpacesInAngles) { verifyFormat("A<A<int>>();", Spaces); } +TEST_F(FormatTest, TripleAngleBrackets) { + verifyFormat("f<<<1, 1>>>();"); + verifyFormat("f<<<1, 1, 1, s>>>();"); + verifyFormat("f<<<a, b, c, d>>>();"); + EXPECT_EQ("f<<<1, 1>>>();", + format("f <<< 1, 1 >>> ();")); + verifyFormat("f<param><<<1, 1>>>();"); + verifyFormat("f<1><<<1, 1>>>();"); + EXPECT_EQ("f<param><<<1, 1>>>();", + format("f< param > <<< 1, 1 >>> ();")); + verifyFormat("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + "aaaaaaaaaaa<<<\n 1, 1>>>();"); +} + +TEST_F(FormatTest, MergeLessLessAtEnd) { + verifyFormat("<<"); + EXPECT_EQ("< < <", format("\\\n<<<")); + verifyFormat("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + "aaallvm::outs() <<"); + verifyFormat("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + "aaaallvm::outs()\n <<"); +} + TEST_F(FormatTest, HandleUnbalancedImplicitBracesAcrossPPBranches) { std::string code = "#if A\n" "#if B\n" diff --git a/unittests/Format/FormatTestJS.cpp b/unittests/Format/FormatTestJS.cpp index 6ee150c662..55e89da621 100644 --- a/unittests/Format/FormatTestJS.cpp +++ b/unittests/Format/FormatTestJS.cpp @@ -94,7 +94,10 @@ TEST_F(FormatTestJS, LiteralOperatorsCanBeKeywords) { TEST_F(FormatTestJS, ES6DestructuringAssignment) { verifyFormat("var [a, b, c] = [1, 2, 3];"); - verifyFormat("var {a, b} = {a: 1, b: 2};"); + verifyFormat("var {a, b} = {\n" + " a: 1,\n" + " b: 2\n" + "};"); } TEST_F(FormatTestJS, ContainerLiterals) { @@ -131,20 +134,25 @@ TEST_F(FormatTestJS, ContainerLiterals) { " //\n" " a\n" "};"); + verifyFormat("var obj = {\n" + " fooooooooo: function(x) {\n" + " return x.zIsTooLongForOneLineWithTheDeclarationLine();\n" + " }\n" + "};"); } TEST_F(FormatTestJS, SpacesInContainerLiterals) { verifyFormat("var arr = [1, 2, 3];"); - verifyFormat("var obj = {a: 1, b: 2, c: 3};"); + verifyFormat("f({a: 1, b: 2, c: 3});"); verifyFormat("var object_literal_with_long_name = {\n" " a: 'aaaaaaaaaaaaaaaaaa',\n" " b: 'bbbbbbbbbbbbbbbbbb'\n" "};"); - verifyFormat("var obj = {a: 1, b: 2, c: 3};", + verifyFormat("f({a: 1, b: 2, c: 3});", getChromiumStyle(FormatStyle::LK_JavaScript)); - verifyFormat("someVariable = {'a': [{}]};"); + verifyFormat("f({'a': [{}]});"); } TEST_F(FormatTestJS, SingleQuoteStrings) { @@ -158,6 +166,22 @@ TEST_F(FormatTestJS, GoogScopes) { "}); // goog.scope"); } +TEST_F(FormatTestJS, GoogModules) { + verifyFormat("goog.module('this.is.really.absurdly.long');", + getGoogleJSStyleWithColumns(40)); + verifyFormat("goog.require('this.is.really.absurdly.long');", + getGoogleJSStyleWithColumns(40)); + verifyFormat("goog.provide('this.is.really.absurdly.long');", + getGoogleJSStyleWithColumns(40)); + verifyFormat("var long = goog.require('this.is.really.absurdly.long');", + getGoogleJSStyleWithColumns(40)); + + // These should be wrapped normally. + verifyFormat( + "var MyLongClassName =\n" + " goog.module.get('my.long.module.name.followedBy.MyLongClassName');"); +} + TEST_F(FormatTestJS, FormatsFreestandingFunctions) { verifyFormat("function outer1(a, b) {\n" " function inner1(a, b) { return a; }\n" @@ -182,14 +206,13 @@ TEST_F(FormatTestJS, FunctionLiterals) { " style: {direction: ''}\n" " }\n" "};"); - // FIXME: The formatting here probably isn't ideal. EXPECT_EQ("abc = xyz ?\n" " function() {\n" " return 1;\n" " } :\n" " function() {\n" - " return -1;\n" - "};", + " return -1;\n" + " };", format("abc=xyz?function(){return 1;}:function(){return -1;};")); verifyFormat("var closure = goog.bind(\n" @@ -211,13 +234,18 @@ TEST_F(FormatTestJS, FunctionLiterals) { " };\n" " }\n" "};"); + verifyFormat("{\n" + " var someVariable = function(x) {\n" + " return x.zIsTooLongForOneLineWithTheDeclarationLine();\n" + " };\n" + "}"); - verifyFormat("var x = {a: function() { return 1; }};", - getGoogleJSStyleWithColumns(38)); - verifyFormat("var x = {\n" + verifyFormat("f({a: function() { return 1; }});", + getGoogleJSStyleWithColumns(33)); + verifyFormat("f({\n" " a: function() { return 1; }\n" - "};", - getGoogleJSStyleWithColumns(37)); + "});", + getGoogleJSStyleWithColumns(32)); verifyFormat("return {\n" " a: function SomeFunction() {\n" @@ -225,6 +253,23 @@ TEST_F(FormatTestJS, FunctionLiterals) { " return 1;\n" " }\n" "};"); + verifyFormat("this.someObject.doSomething(aaaaaaaaaaaaaaaaaaaaaaaaaa)\n" + " .then(goog.bind(function(aaaaaaaaaaa) {\n" + " someFunction();\n" + " someFunction();\n" + " }, this), aaaaaaaaaaaaaaaaa);"); + + // FIXME: This is not ideal yet. + verifyFormat("someFunction(goog.bind(\n" + " function() {\n" + " doSomething();\n" + " doSomething();\n" + " },\n" + " this),\n" + " goog.bind(function() {\n" + " doSomething();\n" + " doSomething();\n" + " }, this));"); } TEST_F(FormatTestJS, InliningFunctionLiterals) { @@ -312,7 +357,10 @@ TEST_F(FormatTestJS, MultipleFunctionLiterals) { verifyFormat("getSomeLongPromise()\n" " .then(function(value) { body(); })\n" - " .thenCatch(function(error) { body(); });"); + " .thenCatch(function(error) {\n" + " body();\n" + " body();\n" + " });"); verifyFormat("getSomeLongPromise()\n" " .then(function(value) {\n" " body();\n" @@ -322,6 +370,11 @@ TEST_F(FormatTestJS, MultipleFunctionLiterals) { " body();\n" " body();\n" " });"); + + // FIXME: This is bad, but it used to be formatted correctly by accident. + verifyFormat("getSomeLongPromise().then(function(value) {\n" + " body();\n" + "}).thenCatch(function(error) { body(); });"); } TEST_F(FormatTestJS, ReturnStatements) { @@ -345,6 +398,8 @@ TEST_F(FormatTestJS, TryCatch) { // But, of course, "catch" is a perfectly fine function name in JavaScript. verifyFormat("someObject.catch();"); + verifyFormat("someObject.new();"); + verifyFormat("someObject.delete();"); } TEST_F(FormatTestJS, StringLiteralConcatenation) { @@ -427,11 +482,136 @@ TEST_F(FormatTestJS, RegexLiteralLength) { verifyFormat("var regex =\n" " /aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/;", getGoogleJSStyleWithColumns(60)); + verifyFormat("var regex = /\\xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/;", + getGoogleJSStyleWithColumns(50)); } TEST_F(FormatTestJS, RegexLiteralExamples) { verifyFormat("var regex = search.match(/(?:\?|&)times=([^?&]+)/i);"); } +TEST_F(FormatTestJS, TypeAnnotations) { + verifyFormat("var x: string;"); + verifyFormat("function x(): string {\n return 'x';\n}"); + verifyFormat("function x(y: string): string {\n return 'x';\n}"); + verifyFormat("for (var y: string in x) {\n x();\n}"); + verifyFormat("((a: string, b: number): string => a + b);"); + verifyFormat("var x: (y: number) => string;"); + verifyFormat("var x: P<string, (a: number) => string>;"); +} + +TEST_F(FormatTestJS, ClassDeclarations) { + verifyFormat("class C {\n x: string = 12;\n}"); + verifyFormat("class C {\n x(): string => 12;\n}"); + verifyFormat("class C {\n ['x' + 2]: string = 12;\n}"); + verifyFormat("class C {\n private x: string = 12;\n}"); + verifyFormat("class C {\n private static x: string = 12;\n}"); + verifyFormat("class C {\n static x(): string { return 'asd'; }\n}"); + verifyFormat("class C extends P implements I {}"); +} + +TEST_F(FormatTestJS, MetadataAnnotations) { + verifyFormat("@A\nclass C {\n}"); + verifyFormat("@A({arg: 'value'})\nclass C {\n}"); + verifyFormat("@A\n@B\nclass C {\n}"); + verifyFormat("class C {\n @A x: string;\n}"); + verifyFormat("class C {\n" + " @A\n" + " private x(): string {\n" + " return 'y';\n" + " }\n" + "}"); + verifyFormat("class X {}\n" + "class Y {}"); +} + +TEST_F(FormatTestJS, Modules) { + verifyFormat("import SomeThing from 'some/module.js';"); + verifyFormat("import {X, Y} from 'some/module.js';"); + verifyFormat("import {\n" + " VeryLongImportsAreAnnoying,\n" + " VeryLongImportsAreAnnoying,\n" + " VeryLongImportsAreAnnoying,\n" + " VeryLongImportsAreAnnoying\n" + "} from 'some/module.js';"); + verifyFormat("import {\n" + " X,\n" + " Y,\n" + "} from 'some/module.js';"); + verifyFormat("import {\n" + " X,\n" + " Y,\n" + "} from 'some/long/module.js';", + getGoogleJSStyleWithColumns(20)); + verifyFormat("import {X as myLocalX, Y as myLocalY} from 'some/module.js';"); + verifyFormat("import * as lib from 'some/module.js';"); + verifyFormat("var x = {\n import: 1\n};\nx.import = 2;"); + + verifyFormat("export function fn() {\n" + " return 'fn';\n" + "}"); + verifyFormat("export const x = 12;"); + verifyFormat("export default class X {}"); + verifyFormat("export {X, Y} from 'some/module.js';"); + verifyFormat("export {\n" + " X,\n" + " Y,\n" + "} from 'some/module.js';"); + verifyFormat("export class C {\n" + " x: number;\n" + " y: string;\n" + "}"); + verifyFormat("export class X { y: number; }"); + verifyFormat("export default class X { y: number }"); + verifyFormat("export default function() {\n return 1;\n}"); + verifyFormat("export var x = 12;"); + verifyFormat("export var x: number = 12;"); + verifyFormat("export const y = {\n" + " a: 1,\n" + " b: 2\n" + "};"); +} + +TEST_F(FormatTestJS, TemplateStrings) { + // Keeps any whitespace/indentation within the template string. + EXPECT_EQ("var x = `hello\n" + " ${ name }\n" + " !`;", + format("var x = `hello\n" + " ${ name }\n" + " !`;")); + + // FIXME: +1 / -1 offsets are to work around clang-format miscalculating + // widths for unknown tokens that are not whitespace (e.g. '`'). Remove when + // the code is corrected. + + verifyFormat("var x =\n" + " `hello ${world}` >= some();", + getGoogleJSStyleWithColumns(34)); // Barely doesn't fit. + verifyFormat("var x = `hello ${world}` >= some();", + getGoogleJSStyleWithColumns(35 + 1)); // Barely fits. + EXPECT_EQ("var x = `hello\n" + " ${world}` >=\n" + " some();", + format("var x =\n" + " `hello\n" + " ${world}` >= some();", + getGoogleJSStyleWithColumns(21))); // Barely doesn't fit. + EXPECT_EQ("var x = `hello\n" + " ${world}` >= some();", + format("var x =\n" + " `hello\n" + " ${world}` >= some();", + getGoogleJSStyleWithColumns(22))); // Barely fits. + + verifyFormat("var x =\n `h`;", getGoogleJSStyleWithColumns(13 - 1)); + EXPECT_EQ( + "var x =\n `multi\n line`;", + format("var x = `multi\n line`;", getGoogleJSStyleWithColumns(14 - 1))); + + // Two template strings. + verifyFormat("var x = `hello` == `hello`;"); +} + } // end namespace tooling } // end namespace clang diff --git a/unittests/Format/FormatTestJava.cpp b/unittests/Format/FormatTestJava.cpp index cb96756e3d..8d6daa62a5 100644 --- a/unittests/Format/FormatTestJava.cpp +++ b/unittests/Format/FormatTestJava.cpp @@ -54,6 +54,46 @@ TEST_F(FormatTestJava, NoAlternativeOperatorNames) { verifyFormat("someObject.and();"); } +TEST_F(FormatTestJava, UnderstandsCasts) { + verifyFormat("a[b >> 1] = (byte) (c() << 4);"); +} + +TEST_F(FormatTestJava, FormatsInstanceOfLikeOperators) { + FormatStyle Style = getStyleWithColumns(50); + verifyFormat("return aaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" + " instanceof bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb;", + Style); + Style.BreakBeforeBinaryOperators = FormatStyle::BOS_None; + verifyFormat("return aaaaaaaaaaaaaaaaaaaaaaaaaaaaa instanceof\n" + " bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb;", + Style); +} + +TEST_F(FormatTestJava, Chromium) { + verifyFormat("class SomeClass {\n" + " void f() {}\n" + " int g() {\n" + " return 0;\n" + " }\n" + " void h() {\n" + " while (true) f();\n" + " for (;;) f();\n" + " if (true) f();\n" + " }\n" + "}", + getChromiumStyle(FormatStyle::LK_Java)); +} + +TEST_F(FormatTestJava, QualifiedNames) { + verifyFormat("public some.package.Type someFunction( // comment\n" + " int parameter) {}"); +} + +TEST_F(FormatTestJava, ClassKeyword) { + verifyFormat("SomeClass.class.getName();"); + verifyFormat("Class c = SomeClass.class;"); +} + TEST_F(FormatTestJava, ClassDeclarations) { verifyFormat("public class SomeClass {\n" " private int a;\n" @@ -89,13 +129,11 @@ TEST_F(FormatTestJava, ClassDeclarations) { getStyleWithColumns(60)); verifyFormat("@SomeAnnotation()\n" "abstract class aaaaaaaaaaaa\n" - " extends bbbbbbbbbbbbbbb implements cccccccccccc {\n" - "}", + " extends bbbbbbbbbbbbbbb implements cccccccccccc {}", getStyleWithColumns(76)); verifyFormat("@SomeAnnotation()\n" "abstract class aaaaaaaaa<a>\n" - " extends bbbbbbbbbbbb<b> implements cccccccccccc {\n" - "}", + " extends bbbbbbbbbbbb<b> implements cccccccccccc {}", getStyleWithColumns(76)); verifyFormat("interface SomeInterface<A> extends Foo, Bar {\n" " void doStuff(int theStuff);\n" @@ -123,31 +161,26 @@ TEST_F(FormatTestJava, EnumDeclarations) { "}"); verifyFormat("public class SomeClass {\n" " enum SomeThing { ABC, CDE }\n" - " void f() {\n" - " }\n" + " void f() {}\n" "}"); verifyFormat("public class SomeClass implements SomeInterface {\n" " enum SomeThing { ABC, CDE }\n" - " void f() {\n" - " }\n" + " void f() {}\n" "}"); verifyFormat("enum SomeThing {\n" " ABC,\n" " CDE;\n" - " void f() {\n" - " }\n" + " void f() {}\n" "}"); verifyFormat("enum SomeThing {\n" " ABC(1, \"ABC\"),\n" " CDE(2, \"CDE\");\n" - " Something(int i, String s) {\n" - " }\n" + " Something(int i, String s) {}\n" "}"); verifyFormat("enum SomeThing {\n" - " ABC(new int[]{1, 2}),\n" - " CDE(new int[]{2, 3});\n" - " Something(int[] i) {\n" - " }\n" + " ABC(new int[] {1, 2}),\n" + " CDE(new int[] {2, 3});\n" + " Something(int[] i) {}\n" "}"); verifyFormat("public enum SomeThing {\n" " ABC {\n" @@ -161,8 +194,7 @@ TEST_F(FormatTestJava, EnumDeclarations) { " return \"CDE\";\n" " }\n" " };\n" - " public void f() {\n" - " }\n" + " public void f() {}\n" "}"); verifyFormat("private enum SomeEnum implements Foo<?, B> {\n" " ABC {\n" @@ -180,32 +212,53 @@ TEST_F(FormatTestJava, EnumDeclarations) { "}"); } +TEST_F(FormatTestJava, ArrayInitializers) { + verifyFormat("new int[] {1, 2, 3, 4};"); + verifyFormat("new int[] {\n" + " 1, 2, 3, 4,\n" + "};"); + + FormatStyle Style = getStyleWithColumns(65); + Style.Cpp11BracedListStyle = false; + verifyFormat( + "expected = new int[] { 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,\n" + " 100, 100, 100, 100, 100, 100, 100, 100, 100, 100 };", + Style); +} + TEST_F(FormatTestJava, ThrowsDeclarations) { verifyFormat("public void doSooooooooooooooooooooooooooomething()\n" - " throws LooooooooooooooooooooooooooooongException {\n}"); + " throws LooooooooooooooooooooooooooooongException {}"); + verifyFormat("public void doSooooooooooooooooooooooooooomething()\n" + " throws LoooooooooongException, LooooooooooongException {}"); } TEST_F(FormatTestJava, Annotations) { verifyFormat("@Override\n" - "public String toString() {\n}"); + "public String toString() {}"); verifyFormat("@Override\n" "@Nullable\n" - "public String getNameIfPresent() {\n}"); + "public String getNameIfPresent() {}"); + verifyFormat("@Override // comment\n" + "@Nullable\n" + "public String getNameIfPresent() {}"); + verifyFormat("@java.lang.Override // comment\n" + "@Nullable\n" + "public String getNameIfPresent() {}"); verifyFormat("@SuppressWarnings(value = \"unchecked\")\n" - "public void doSomething() {\n}"); + "public void doSomething() {}"); verifyFormat("@SuppressWarnings(value = \"unchecked\")\n" "@Author(name = \"abc\")\n" - "public void doSomething() {\n}"); + "public void doSomething() {}"); verifyFormat("DoSomething(new A() {\n" " @Override\n" - " public String toString() {\n" - " }\n" + " public String toString() {}\n" "});"); - verifyFormat("void SomeFunction(@Nullable String something) {\n" - "}"); + verifyFormat("void SomeFunction(@Nullable String something) {}"); + verifyFormat("void SomeFunction(@org.llvm.Nullable String something) {}"); verifyFormat("@Partial @Mock DataLoader loader;"); verifyFormat("@SuppressWarnings(value = \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\")\n" @@ -213,6 +266,33 @@ TEST_F(FormatTestJava, Annotations) { verifyFormat("@SomeAnnotation(\"With some really looooooooooooooong text\")\n" "private static final long something = 0L;"); + verifyFormat("@org.llvm.Qualified(\"With some really looooooooooong text\")\n" + "private static final long something = 0L;"); + verifyFormat("@Mock\n" + "DataLoader loooooooooooooooooooooooader =\n" + " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa;", + getStyleWithColumns(60)); + verifyFormat("@org.llvm.QualifiedMock\n" + "DataLoader loooooooooooooooooooooooader =\n" + " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa;", + getStyleWithColumns(60)); + verifyFormat("@Test(a)\n" + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa =\n" + " aaaaaaaaaaaaaaaaaaaaaaaaaaaa(aaaaaaaaaaaaaaaaaaaaaaa);"); + verifyFormat("@SomeAnnotation(\n" + " aaaaaaaaaaaaaaaaa, aaaaaaaaaaaaaaaaaaaa)\n" + "int i;", + getStyleWithColumns(50)); + verifyFormat("@Test\n" + "ReturnType doSomething(\n" + " String aaaaaaaaaaaaa, String bbbbbbbbbbbbbbb) {}", + getStyleWithColumns(60)); + verifyFormat("{\n" + " boolean someFunction(\n" + " @Param(aaaaaaaaaaaaaaaa) String aaaaa,\n" + " String bbbbbbbbbbbbbbb) {}\n" + "}", + getStyleWithColumns(60)); } TEST_F(FormatTestJava, Generics) { @@ -223,17 +303,24 @@ TEST_F(FormatTestJava, Generics) { verifyFormat("A.<B>doSomething();"); verifyFormat("@Override\n" - "public Map<String, ?> getAll() {\n}"); - - verifyFormat("public <R> ArrayList<R> get() {\n}"); - verifyFormat("protected <R> ArrayList<R> get() {\n}"); - verifyFormat("private <R> ArrayList<R> get() {\n}"); - verifyFormat("public static <R> ArrayList<R> get() {\n}"); + "public Map<String, ?> getAll() {}"); + + verifyFormat("public <R> ArrayList<R> get() {}"); + verifyFormat("protected <R> ArrayList<R> get() {}"); + verifyFormat("private <R> ArrayList<R> get() {}"); + verifyFormat("public static <R> ArrayList<R> get() {}"); + verifyFormat("public static native <R> ArrayList<R> get();"); + verifyFormat("public final <X> Foo foo() {}"); + verifyFormat("public abstract <X> Foo foo();"); verifyFormat("<T extends B> T getInstance(Class<T> type);"); verifyFormat("Function<F, ? extends T> function;"); verifyFormat("private Foo<X, Y>[] foos;"); verifyFormat("Foo<X, Y>[] foos = this.foos;"); + verifyFormat("return (a instanceof List<?>)\n" + " ? aaaaaaaaaaaaaaaaaaaaaaa(aaaaaaaaaaaaaaaaaaaaa)\n" + " : aaaaaaaaaaaaaaaaaaaaaaa;", + getStyleWithColumns(60)); verifyFormat( "SomeLoooooooooooooooooooooongType name =\n" @@ -245,7 +332,7 @@ TEST_F(FormatTestJava, Generics) { TEST_F(FormatTestJava, StringConcatenation) { verifyFormat("String someString = \"abc\"\n" - " + \"cde\";"); + " + \"cde\";"); } TEST_F(FormatTestJava, TryCatchFinally) { @@ -274,25 +361,41 @@ TEST_F(FormatTestJava, TryCatchFinally) { "}"); } +TEST_F(FormatTestJava, TryWithResources) { + verifyFormat("try (SomeResource rs = someFunction()) {\n" + " Something();\n" + "}"); + verifyFormat("try (SomeResource rs = someFunction()) {\n" + " Something();\n" + "} catch (SomeException e) {\n" + " HandleException(e);\n" + "}"); +} + TEST_F(FormatTestJava, SynchronizedKeyword) { verifyFormat("synchronized (mData) {\n" " // ...\n" "}"); } +TEST_F(FormatTestJava, PackageDeclarations) { + verifyFormat("package some.really.loooooooooooooooooooooong.package;", + getStyleWithColumns(50)); +} + TEST_F(FormatTestJava, ImportDeclarations) { verifyFormat("import some.really.loooooooooooooooooooooong.imported.Class;", getStyleWithColumns(50)); + verifyFormat("import static some.really.looooooooooooooooong.imported.Class;", + getStyleWithColumns(50)); } TEST_F(FormatTestJava, MethodDeclarations) { verifyFormat("void methodName(Object arg1,\n" - " Object arg2, Object arg3) {\n" - "}", + " Object arg2, Object arg3) {}", getStyleWithColumns(40)); verifyFormat("void methodName(\n" - " Object arg1, Object arg2) {\n" - "}", + " Object arg1, Object arg2) {}", getStyleWithColumns(40)); } @@ -315,6 +418,74 @@ TEST_F(FormatTestJava, NeverAlignAfterReturn) { " .bbbbbbbbbbbbbbbbbbb()\n" " .ccccccccccccccccccc();", getStyleWithColumns(40)); + verifyFormat("return aaaaaaaaaaaaaaaaaaa()\n" + " .bbbbbbbbbbbbbbbbbbb(\n" + " ccccccccccccccc)\n" + " .ccccccccccccccccccc();", + getStyleWithColumns(40)); +} + +TEST_F(FormatTestJava, FormatsInnerBlocks) { + verifyFormat("someObject.someFunction(new Runnable() {\n" + " @Override\n" + " public void run() {\n" + " System.out.println(42);\n" + " }\n" + "}, someOtherParameter);"); + verifyFormat("someFunction(new Runnable() {\n" + " public void run() {\n" + " System.out.println(42);\n" + " }\n" + "});"); + verifyFormat("someObject.someFunction(\n" + " new Runnable() {\n" + " @Override\n" + " public void run() {\n" + " System.out.println(42);\n" + " }\n" + " },\n" + " new Runnable() {\n" + " @Override\n" + " public void run() {\n" + " System.out.println(43);\n" + " }\n" + " },\n" + " someOtherParameter);"); +} + +TEST_F(FormatTestJava, FormatsLambdas) { + verifyFormat("(aaaaaaaaaa, bbbbbbbbbb) -> aaaaaaaaaa + bbbbbbbbbb;"); + verifyFormat("(aaaaaaaaaa, bbbbbbbbbb)\n" + " -> aaaaaaaaaa + bbbbbbbbbb;", + getStyleWithColumns(40)); + verifyFormat("Runnable someLambda = () -> DoSomething();"); + verifyFormat("Runnable someLambda = () -> {\n" + " DoSomething();\n" + "}"); + + verifyFormat("Runnable someLambda =\n" + " (int aaaaa) -> DoSomething(aaaaa);", + getStyleWithColumns(40)); +} + +TEST_F(FormatTestJava, BreaksStringLiterals) { + // FIXME: String literal breaking is currently disabled for Java and JS, as it + // requires strings to be merged using "+" which we don't support. + EXPECT_EQ("\"some text other\";", + format("\"some text other\";", getStyleWithColumns(14))); +} + +TEST_F(FormatTestJava, AlignsBlockComments) { + EXPECT_EQ("/*\n" + " * Really multi-line\n" + " * comment.\n" + " */\n" + "void f() {}", + format(" /*\n" + " * Really multi-line\n" + " * comment.\n" + " */\n" + " void f() {}")); } } // end namespace tooling diff --git a/unittests/Tooling/ToolingTest.cpp b/unittests/Tooling/ToolingTest.cpp index 98b70081b9..5a93e38c80 100644 --- a/unittests/Tooling/ToolingTest.cpp +++ b/unittests/Tooling/ToolingTest.cpp @@ -19,6 +19,7 @@ #include "llvm/ADT/STLExtras.h" #include "llvm/Config/llvm-config.h" #include "gtest/gtest.h" +#include <algorithm> #include <string> namespace clang { @@ -260,25 +261,6 @@ TEST(runToolOnCodeWithArgs, TestNoDepFile) { EXPECT_FALSE(llvm::sys::fs::remove(DepFilePath.str())); } -struct CheckSyntaxOnlyAdjuster: public ArgumentsAdjuster { - bool &Found; - bool &Ran; - - CheckSyntaxOnlyAdjuster(bool &Found, bool &Ran) : Found(Found), Ran(Ran) { } - - virtual CommandLineArguments - Adjust(const CommandLineArguments &Args) override { - Ran = true; - for (unsigned I = 0, E = Args.size(); I != E; ++I) { - if (Args[I] == "-fsyntax-only") { - Found = true; - break; - } - } - return Args; - } -}; - TEST(ClangToolTest, ArgumentAdjusters) { FixedCompilationDatabase Compilations("/", std::vector<std::string>()); @@ -290,15 +272,22 @@ TEST(ClangToolTest, ArgumentAdjusters) { bool Found = false; bool Ran = false; - Tool.appendArgumentsAdjuster(new CheckSyntaxOnlyAdjuster(Found, Ran)); + ArgumentsAdjuster CheckSyntaxOnlyAdjuster = + [&Found, &Ran](const CommandLineArguments &Args) { + Ran = true; + if (std::find(Args.begin(), Args.end(), "-fsyntax-only") != Args.end()) + Found = true; + return Args; + }; + Tool.appendArgumentsAdjuster(CheckSyntaxOnlyAdjuster); Tool.run(Action.get()); EXPECT_TRUE(Ran); EXPECT_TRUE(Found); Ran = Found = false; Tool.clearArgumentsAdjusters(); - Tool.appendArgumentsAdjuster(new CheckSyntaxOnlyAdjuster(Found, Ran)); - Tool.appendArgumentsAdjuster(new ClangSyntaxOnlyAdjuster()); + Tool.appendArgumentsAdjuster(CheckSyntaxOnlyAdjuster); + Tool.appendArgumentsAdjuster(getClangSyntaxOnlyAdjuster()); Tool.run(Action.get()); EXPECT_TRUE(Ran); EXPECT_FALSE(Found); diff --git a/unittests/libclang/LibclangTest.cpp b/unittests/libclang/LibclangTest.cpp index ee56e22936..a21881429e 100644 --- a/unittests/libclang/LibclangTest.cpp +++ b/unittests/libclang/LibclangTest.cpp @@ -8,11 +8,11 @@ //===----------------------------------------------------------------------===// #include "clang-c/Index.h" -#include "gtest/gtest.h" #include "llvm/Support/Debug.h" #include "llvm/Support/FileSystem.h" #include "llvm/Support/Path.h" #include "llvm/Support/raw_ostream.h" +#include "gtest/gtest.h" #include <fstream> #include <set> #define DEBUG_TYPE "libclang-test" |