11#include "gmock/gmock.h"
12#include "gtest/gtest.h"
20TEST_F(DefineOutlineTest, TriggersOnFunctionDecl) {
24 [[void [[f^o^o]]() [[{
59 [[void [[Bar::[[b^a^z]]]]() [[{
69 [[vo^id ]]foo[[()]] {[[
76 [[void [[f^o^o]]() [[{
86 [[void [[Bar::[[b^a^z]]]]() [[{
93 [[void [[f^o^o^]]() [[{ return; }]]]]
97 [[void [[f^o^o]]() [[{
105 F^oo(const Foo&) = delete;
111 template <typename> struct Foo { void fo^o(){} };
117 template <typename T> void fo^o() {}
118 template <> void fo^o<int>() {}
124 struct { void b^ar() {} } Bar;
133 struct Bar { void b^ar() {} };
148TEST_F(DefineOutlineTest, FailsWithoutSource) {
150 llvm::StringRef Test =
"void fo^o() { return; }";
152 "fail: Couldn't find a suitable implementation file.";
156TEST_F(DefineOutlineTest, ApplyTest) {
157 ExtraFiles[
"Test.cpp"] =
"";
161 llvm::StringRef Test;
162 llvm::StringRef ExpectedHeader;
163 llvm::StringRef ExpectedSource;
167 "void fo^o() { return; }",
169 "void foo() { return; }",
173 "inline void fo^o() { return; }",
175 " void foo() { return; }",
179 "void fo^o(int x, int y = 5, int = 2, int (*foo)(int) = nullptr) {}",
180 "void foo(int x, int y = 5, int = 2, int (*foo)(int) = nullptr) ;",
181 "void foo(int x, int y , int , int (*foo)(int) ) {}",
184 "struct Bar{Bar();}; void fo^o(Bar x = {}) {}",
185 "struct Bar{Bar();}; void foo(Bar x = {}) ;",
186 "void foo(Bar x ) {}",
191 class Foo {public: Foo(); Foo(int);};
194 Bar(int x) : f1(x) {}
199 class Foo {public: Foo(); Foo(int);};
202 Bar(int x) : f1(x) {}
211 class Foo {public: Foo(); Foo(int);};
214 B^ar(int x) : f1(x), f2(3) {}
219 class Foo {public: Foo(); Foo(int);};
226 "Bar::Bar(int x) : f1(x), f2(3) {}\n",
231 template <typename T> class Foo {
232 F^oo(T z) __attribute__((weak)) : bar(2){}
236 template <typename T> class Foo {
237 Foo(T z) __attribute__((weak)) ;
239 };template <typename T>
240inline Foo<T>::Foo(T z) __attribute__((weak)) : bar(2){}
247 virtual void f^oo() {}
253 " void A::foo() {}\n",
258 virtual virtual void virtual f^oo() {}
262 virtual virtual void virtual foo() ;
264 " void A::foo() {}\n",
269 virtual void foo() = 0;
272 void fo^o() override {}
276 virtual void foo() = 0;
279 void foo() override ;
281 "void B::foo() {}\n",
286 virtual void foo() = 0;
293 virtual void foo() = 0;
298 "void B::foo() {}\n",
303 virtual void foo() = 0;
306 void fo^o() final override {}
310 virtual void foo() = 0;
313 void foo() final override ;
315 "void B::foo() {}\n",
320 static void fo^o() {}
326 " void A::foo() {}\n",
331 static static void fo^o() {}
335 static static void foo() ;
337 " void A::foo() {}\n",
342 explicit Fo^o(int) {}
348 " Foo::Foo(int) {}\n",
353 explicit explicit Fo^o(int) {}
357 explicit explicit Foo(int) ;
359 " Foo::Foo(int) {}\n",
364 inline void f^oo(int) {}
370 " void A::foo(int) {}\n",
375 template <typename T, typename ...U> struct O1 {
376 template <class V, int A> struct O2 {
379 E f^oo(T, U..., V, E) { return E1; }
384 template <typename T, typename ...U> struct O1 {
385 template <class V, int A> struct O2 {
388 E foo(T, U..., V, E) ;
391 };template <typename T, typename ...U>
392template <class V, int A>
393inline typename O1<T, U...>::template O2<V, A>::E O1<T, U...>::template O2<V, A>::I::foo(T, U..., V, E) { return E1; }
398 "class A { ~A^(){} };",
399 "class A { ~A(); };",
407 template <typename T, typename, bool B = true>
408 T ^bar() { return {}; }
412 template <typename T, typename, bool B = true>
414 };template <typename T, typename, bool B>
415inline T Foo::bar() { return {}; }
422 template <typename T> struct Foo {
423 template <typename U, bool> T ^bar(const T& t, const U& u) { return {}; }
426 template <typename T> struct Foo {
427 template <typename U, bool> T bar(const T& t, const U& u) ;
428 };template <typename T>
429template <typename U, bool>
430inline T Foo<T>::bar(const T& t, const U& u) { return {}; }
434 for (
const auto &Case : Cases) {
435 SCOPED_TRACE(Case.Test);
436 llvm::StringMap<std::string> EditedFiles;
437 EXPECT_EQ(apply(Case.Test, &EditedFiles), Case.ExpectedHeader);
438 if (Case.ExpectedSource.empty()) {
439 EXPECT_TRUE(EditedFiles.empty());
441 EXPECT_THAT(EditedFiles, testing::ElementsAre(FileWithContents(
442 testPath(
"Test.cpp"), Case.ExpectedSource)));
447TEST_F(DefineOutlineTest, InCppFile) {
451 llvm::StringRef Test;
452 llvm::StringRef ExpectedSource;
458 struct Foo { void ba^r() {} };
459 struct Bar { void foo(); };
467 struct Foo { void bar() ; };void Foo::bar() {}
468 struct Bar { void foo(); };
475 for (
const auto &Case : Cases) {
476 SCOPED_TRACE(Case.Test);
477 EXPECT_EQ(apply(Case.Test,
nullptr), Case.ExpectedSource);
481TEST_F(DefineOutlineTest, HandleMacros) {
482 llvm::StringMap<std::string> EditedFiles;
483 ExtraFiles[
"Test.cpp"] =
"";
485 ExtraArgs.push_back(
"-DVIRTUAL=virtual");
486 ExtraArgs.push_back(
"-DOVER=override");
489 llvm::StringRef Test;
490 llvm::StringRef ExpectedHeader;
491 llvm::StringRef ExpectedSource;
494 #define BODY { return; }
495 void f^oo()BODY)cpp",
497 #define BODY { return; }
503 void f^oo(){BODY})cpp",
510 #define TARGET void foo()
511 [[TARGET]]{ return; })cpp",
513 #define TARGET void foo()
515 "TARGET{ return; }"},
519 void [[TARGET]](){ return; })cpp",
523 "void TARGET(){ return; }"},
524 {R
"cpp(#define VIRT virtual
528 R"cpp(#define VIRT virtual
532 " void A::foo() {}\n"},
535 VIRTUAL void f^oo() {}
541 " void A::foo() {}\n"},
544 virtual void foo() = 0;
551 virtual void foo() = 0;
556 "void B::foo() {}\n"},
557 {R
"cpp(#define STUPID_MACRO(X) virtual
559 STUPID_MACRO(sizeof sizeof int) void f^oo() {}
561 R"cpp(#define STUPID_MACRO(X) virtual
563 STUPID_MACRO(sizeof sizeof int) void foo() ;
565 " void A::foo() {}\n"},
566 {R
"cpp(#define STAT static
570 R"cpp(#define STAT static
574 " void A::foo() {}\n"},
575 {R
"cpp(#define STUPID_MACRO(X) static
577 STUPID_MACRO(sizeof sizeof int) void f^oo() {}
579 R"cpp(#define STUPID_MACRO(X) static
581 STUPID_MACRO(sizeof sizeof int) void foo() ;
583 " void A::foo() {}\n"},
585 for (
const auto &Case : Cases) {
586 SCOPED_TRACE(Case.Test);
587 EXPECT_EQ(apply(Case.Test, &EditedFiles), Case.ExpectedHeader);
588 EXPECT_THAT(EditedFiles, testing::ElementsAre(FileWithContents(
589 testPath(
"Test.cpp"), Case.ExpectedSource)));
593TEST_F(DefineOutlineTest, QualifyReturnValue) {
595 ExtraFiles[
"Test.cpp"] =
"";
598 llvm::StringRef Test;
599 llvm::StringRef ExpectedHeader;
600 llvm::StringRef ExpectedSource;
603 namespace a { class Foo{}; }
605 Foo fo^o() { return {}; })cpp",
607 namespace a { class Foo{}; }
610 "a::Foo foo() { return {}; }"},
615 Bar fo^o() { return {}; }
625 "a::Foo::Bar a::Foo::foo() { return {}; }\n"},
628 Foo fo^o() { return {}; })cpp",
632 "Foo foo() { return {}; }"},
634 llvm::StringMap<std::string> EditedFiles;
635 for (
auto &Case : Cases) {
636 apply(Case.Test, &EditedFiles);
637 EXPECT_EQ(apply(Case.Test, &EditedFiles), Case.ExpectedHeader);
638 EXPECT_THAT(EditedFiles, testing::ElementsAre(FileWithContents(
639 testPath(
"Test.cpp"), Case.ExpectedSource)));
643TEST_F(DefineOutlineTest, QualifyFunctionName) {
646 llvm::StringRef TestHeader;
647 llvm::StringRef TestSource;
648 llvm::StringRef ExpectedHeader;
649 llvm::StringRef ExpectedSource;
669 "void a::b::Foo::foo() {}\n",
672 "namespace a { namespace b { void f^oo() {} } }",
674 "namespace a { namespace b { void foo() ; } }",
675 "namespace a{void b::foo() {} }",
678 "namespace a { namespace b { void f^oo() {} } }",
679 "using namespace a;",
680 "namespace a { namespace b { void foo() ; } }",
683 "using namespace a;void a::b::foo() {} ",
686 "namespace a { class A { ~A^(){} }; }",
688 "namespace a { class A { ~A(); }; }",
692 "namespace a { class A { ~A^(){} }; }",
694 "namespace a { class A { ~A(); }; }",
695 "namespace a{A::~A(){} }",
698 llvm::StringMap<std::string> EditedFiles;
699 for (
auto &Case : Cases) {
700 ExtraFiles[
"Test.cpp"] = std::string(Case.TestSource);
701 EXPECT_EQ(apply(Case.TestHeader, &EditedFiles), Case.ExpectedHeader);
702 EXPECT_THAT(EditedFiles, testing::ElementsAre(FileWithContents(
703 testPath(
"Test.cpp"), Case.ExpectedSource)))
708TEST_F(DefineOutlineTest, FailsMacroSpecifier) {
710 ExtraFiles[
"Test.cpp"] =
"";
711 ExtraArgs.push_back(
"-DFINALOVER=final override");
713 std::pair<StringRef, StringRef> Cases[] = {
716 #define VIRT virtual void
720 "fail: define outline: couldn't remove `virtual` keyword."},
723 #define OVERFINAL final override
725 virtual void foo() {}
728 void fo^o() OVERFINAL {}
730 "fail: define outline: Can't move out of line as function has a "
731 "macro `override` specifier.\ndefine outline: Can't move out of line "
732 "as function has a macro `final` specifier."},
736 virtual void foo() {}
739 void fo^o() FINALOVER {}
741 "fail: define outline: Can't move out of line as function has a "
742 "macro `override` specifier.\ndefine outline: Can't move out of line "
743 "as function has a macro `final` specifier."},
745 for (
const auto &Case : Cases) {
746 EXPECT_EQ(apply(Case.first), Case.second);
std::vector< const char * > Expected
#define TWEAK_TEST(TweakID)
#define EXPECT_AVAILABLE(MarkedCode)
#define EXPECT_UNAVAILABLE(MarkedCode)
TEST_F(BackgroundIndexTest, NoCrashOnErrorFile)
std::string testPath(PathRef File, llvm::sys::path::Style Style)
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//