10#include "gmock/gmock.h"
11#include "gtest/gtest.h"
13using ::testing::AllOf;
14using ::testing::HasSubstr;
16using ::testing::StartsWith;
24TEST_F(ExtractFunctionTest, FunctionTest) {
28 EXPECT_EQ(apply(
"for(;;) [[1+2; 1+2;]]"),
"unavailable");
30 EXPECT_THAT(apply(
"int x = 0; [[x++;]]"), HasSubstr(
"extracted"));
32 EXPECT_EQ(apply(
"auto lam = [](){ [[int x;]] }; "),
"unavailable");
34 EXPECT_THAT(apply(
"int [[x = 0]];"),
"unavailable");
36 EXPECT_THAT(apply(
" [[int a = 5;]] a++; "),
"unavailable");
40 EXPECT_THAT(apply(
"for(;;) { [[int x;]]break; }"), HasSubstr(
"extracted"));
44 EXPECT_THAT(apply(
" for([[int i = 0;]];);"), HasSubstr(
"extracted"));
50 EXPECT_EQ(apply(
"void use(int); for([[int i = 0;]] i < 10; ++i) use(i);"),
53 EXPECT_THAT(apply(
" if(true) [[{ return; }]] "), HasSubstr(
"extracted"));
55 EXPECT_THAT(apply(
" if(true) [[if (false) return;]] "),
56 StartsWith(
"unavailable"));
58 apply(
"#define RETURN_IF_ERROR(x) if (x) return\nRETU^RN_IF_ERROR(4);"),
59 StartsWith(
"unavailable"));
62TEST_F(ExtractFunctionTest, FileTest) {
67 std::string ParameterCheckInput = R
"cpp(
78 std::string ParameterCheckOutput = R"cpp(
82void extracted(int &a, int b, int *&ptr, const Foo &foo) {
90 extracted(a, b, ptr, foo);
92 EXPECT_EQ(apply(ParameterCheckInput), ParameterCheckOutput);
95 std::string ConstCheckInput = R
"cpp(
99 std::string ConstCheckOutput = R"cpp(
100void extracted(const int c) {
106 EXPECT_EQ(apply(ConstCheckInput), ConstCheckOutput);
109 std::string ConstNamespaceCheckInput = R
"cpp(
110namespace X { struct Y { int z; }; }
111int f(const X::Y &y) {
112 [[return y.z + y.z;]]
114 std::string ConstNamespaceCheckOutput = R"cpp(
115namespace X { struct Y { int z; }; }
116int extracted(const X::Y &y) {
119int f(const X::Y &y) {
122 EXPECT_EQ(apply(ConstNamespaceCheckInput), ConstNamespaceCheckOutput);
125 EXPECT_THAT(apply(
"void f() { [[int a; f();]] }"), StartsWith(
"fail"));
127 std::string MethodInput = R
"cpp(
134 std::string MethodCheckOutput = R"cpp(
144 EXPECT_EQ(apply(MethodInput), MethodCheckOutput);
146 std::string OutOfLineMethodInput = R"cpp(
155 std::string OutOfLineMethodCheckOutput = R"cpp(
161 void T::extracted() {
168 EXPECT_EQ(apply(OutOfLineMethodInput), OutOfLineMethodCheckOutput);
172 std::string TemplateFailInput = R
"cpp(
178 EXPECT_EQ(apply(TemplateFailInput), "unavailable");
180 std::string MacroInput = R
"cpp(
181 #define F(BODY) void f() { BODY }
184 std::string MacroOutput = R"cpp(
185 #define F(BODY) void f() { BODY }
191 EXPECT_EQ(apply(MacroInput), MacroOutput);
194 EXPECT_EQ(apply(
"void f([[int a]]);"),
"unavailable");
195 EXPECT_EQ(apply(
"void f(int a = [[1]]);"),
"unavailable");
197 std::string CompoundFailInput = R
"cpp(
202 EXPECT_EQ(apply(CompoundFailInput), "unavailable");
204 ExtraArgs.push_back(
"-std=c++14");
207 EXPECT_THAT(apply(R
"cpp(
208 void call() { [[1+1]]; }
210 HasSubstr("extracted"));
211 EXPECT_THAT(apply(R
"cpp(
212 void call() { [[1+1;]] }
214 HasSubstr("extracted"));
217TEST_F(ExtractFunctionTest, DifferentHeaderSourceTest) {
224 std::string OutOfLineSource = R"cpp(
225 void SomeClass::f() {
230 std::string OutOfLineSourceOutputCheck = R"cpp(
231 void SomeClass::extracted() {
239 std::string HeaderOutputCheck = R"cpp(
246 llvm::StringMap<std::string> EditedFiles;
248 EXPECT_EQ(apply(OutOfLineSource, &EditedFiles), OutOfLineSourceOutputCheck);
249 EXPECT_EQ(EditedFiles.begin()->second, HeaderOutputCheck);
252TEST_F(ExtractFunctionTest, DifferentFilesNestedTest) {
261 std::string NestedOutOfLineSource = R"cpp(
262 void T::SomeClass::f() {
267 std::string NestedOutOfLineSourceOutputCheck = R"cpp(
268 void T::SomeClass::extracted() {
271void T::SomeClass::f() {
276 std::string NestedHeaderOutputCheck = R"cpp(
285 llvm::StringMap<std::string> EditedFiles;
287 EXPECT_EQ(apply(NestedOutOfLineSource, &EditedFiles),
288 NestedOutOfLineSourceOutputCheck);
289 EXPECT_EQ(EditedFiles.begin()->second, NestedHeaderOutputCheck);
292TEST_F(ExtractFunctionTest, ConstexprDifferentHeaderSourceTest) {
295 constexpr void f() const;
299 std::string OutOfLineSource = R"cpp(
300 constexpr void SomeClass::f() const {
305 std::string OutOfLineSourceOutputCheck = R"cpp(
306 constexpr void SomeClass::extracted() const {
309constexpr void SomeClass::f() const {
314 std::string HeaderOutputCheck = R"cpp(
316 constexpr void extracted() const;
317constexpr void f() const;
321 llvm::StringMap<std::string> EditedFiles;
323 EXPECT_EQ(apply(OutOfLineSource, &EditedFiles), OutOfLineSourceOutputCheck);
324 EXPECT_NE(EditedFiles.begin(), EditedFiles.end())
325 << "The header should be edited and receives the declaration of the new "
328 if (EditedFiles.begin() != EditedFiles.end()) {
329 EXPECT_EQ(EditedFiles.begin()->second, HeaderOutputCheck);
333TEST_F(ExtractFunctionTest, ConstevalDifferentHeaderSourceTest) {
334 ExtraArgs.push_back(
"--std=c++20");
337 consteval void f() const;
341 std::string OutOfLineSource = R"cpp(
342 consteval void SomeClass::f() const {
347 std::string OutOfLineSourceOutputCheck = R"cpp(
348 consteval void SomeClass::extracted() const {
351consteval void SomeClass::f() const {
356 std::string HeaderOutputCheck = R"cpp(
358 consteval void extracted() const;
359consteval void f() const;
363 llvm::StringMap<std::string> EditedFiles;
365 EXPECT_EQ(apply(OutOfLineSource, &EditedFiles), OutOfLineSourceOutputCheck);
366 EXPECT_NE(EditedFiles.begin(), EditedFiles.end())
367 << "The header should be edited and receives the declaration of the new "
370 if (EditedFiles.begin() != EditedFiles.end()) {
371 EXPECT_EQ(EditedFiles.begin()->second, HeaderOutputCheck);
375TEST_F(ExtractFunctionTest, ConstDifferentHeaderSourceTest) {
382 std::string OutOfLineSource = R"cpp(
383 void SomeClass::f() const {
388 std::string OutOfLineSourceOutputCheck = R"cpp(
389 void SomeClass::extracted() const {
392void SomeClass::f() const {
397 std::string HeaderOutputCheck = R"cpp(
399 void extracted() const;
404 llvm::StringMap<std::string> EditedFiles;
406 EXPECT_EQ(apply(OutOfLineSource, &EditedFiles), OutOfLineSourceOutputCheck);
407 EXPECT_NE(EditedFiles.begin(), EditedFiles.end())
408 << "The header should be edited and receives the declaration of the new "
411 if (EditedFiles.begin() != EditedFiles.end()) {
412 EXPECT_EQ(EditedFiles.begin()->second, HeaderOutputCheck);
416TEST_F(ExtractFunctionTest, StaticDifferentHeaderSourceTest) {
423 std::string OutOfLineSource = R"cpp(
424 void SomeClass::f() {
429 std::string OutOfLineSourceOutputCheck = R"cpp(
430 void SomeClass::extracted() {
438 std::string HeaderOutputCheck = R"cpp(
440 static void extracted();
445 llvm::StringMap<std::string> EditedFiles;
447 EXPECT_EQ(apply(OutOfLineSource, &EditedFiles), OutOfLineSourceOutputCheck);
448 EXPECT_NE(EditedFiles.begin(), EditedFiles.end())
449 << "The header should be edited and receives the declaration of the new "
452 if (EditedFiles.begin() != EditedFiles.end()) {
453 EXPECT_EQ(EditedFiles.begin()->second, HeaderOutputCheck);
457TEST_F(ExtractFunctionTest, DifferentContextHeaderSourceTest) {
475 std::string OutOfLineSource = R"cpp(
476 ns::A::C::RType ns::A::T::SomeClass::f() {
482 std::string OutOfLineSourceOutputCheck = R"cpp(
483 ns::A::C::RType ns::A::T::SomeClass::extracted() {
487ns::A::C::RType ns::A::T::SomeClass::f() {
492 std::string HeaderOutputCheck = R"cpp(
502 static ns::A::C::RType extracted();
510 llvm::StringMap<std::string> EditedFiles;
512 EXPECT_EQ(apply(OutOfLineSource, &EditedFiles), OutOfLineSourceOutputCheck);
513 EXPECT_EQ(EditedFiles.begin()->second, HeaderOutputCheck);
516TEST_F(ExtractFunctionTest, DifferentSyntacticContextNamespace) {
517 std::string OutOfLineSource = R"cpp(
527 std::string OutOfLineSourceOutputCheck = R"cpp(
533 void ns::extracted() {
541 EXPECT_EQ(apply(OutOfLineSource), OutOfLineSourceOutputCheck);
544TEST_F(ExtractFunctionTest, ControlFlow) {
547 EXPECT_THAT(apply(
" [[for(;;) if(1) break;]] "), HasSubstr(
"extracted"));
548 EXPECT_THAT(apply(
" for(;;) [[while(1) break;]] "), HasSubstr(
"extracted"));
549 EXPECT_THAT(apply(
" [[switch(1) { break; }]]"), HasSubstr(
"extracted"));
550 EXPECT_THAT(apply(
" [[while(1) switch(1) { continue; }]]"),
551 HasSubstr(
"extracted"));
553 EXPECT_THAT(apply(
" for(;;) [[if(1) continue;]] "), StartsWith(
"fail"));
554 EXPECT_THAT(apply(
" while(1) [[if(1) break;]] "), StartsWith(
"fail"));
555 EXPECT_THAT(apply(
" switch(1) { [[break;]] }"), StartsWith(
"fail"));
556 EXPECT_THAT(apply(
" for(;;) { [[while(1) break; break;]] }"),
560TEST_F(ExtractFunctionTest, ExistingReturnStatement) {
562 const char *Before = R
"cpp(
564 int getNum(bool Superstitious, int Min, int Max) {
565 if (Superstitious) [[{
566 for (int I = Min; I <= Max; ++I)
571 return (Min + Max) / 2;
576 const char *After = R
"cpp(
578 int extracted(int Min, int Max) {
580 for (int I = Min; I <= Max; ++I)
586int getNum(bool Superstitious, int Min, int Max) {
587 if (Superstitious) return extracted(Min, Max); else {
588 return (Min + Max) / 2;
592 EXPECT_EQ(apply(Before), After);
595TEST_F(ExtractFunctionTest, OverloadedOperators) {
597 std::string Before = R"cpp(struct A {
598 int operator+(int x) { return x; }
600 A &operator<<(A &, int);
601 A &operator|(A &, int);
618 int operator+(int x) { return x; }
620 A &operator<<(A &, int);
621 A &operator|(A &, int);
639 EXPECT_EQ(apply(Before), After);
642TEST_F(ExtractFunctionTest, SingleStatement) {
646 EXPECT_THAT(apply(R
"cpp(
651 HasSubstr("extracted"));
657 EXPECT_THAT(apply(R
"cpp(
659 Stream &operator<<(Stream &, const char *);
664 HasSubstr("extracted"));
668 EXPECT_EQ(apply(R
"cpp(
670 Stream &operator<<(Stream &, int);
679 EXPECT_EQ(apply(R
"cpp(
681 Stream &operator<<(Stream &, int);
682 void foo(Stream &, int);
685 foo([[stream << 3]], 4);
690TEST_F(ExtractFunctionTest, ControlFlowConditions) {
694 EXPECT_EQ(apply(R
"cpp(
695 int example(int event1, bool event2, double event3) {
696 if ([[event1 == 2 && event2 && event3 == 10.3]])
702 EXPECT_EQ(apply(
"void f(int x) { while ([[x > 0]]) --x; }"),
"unavailable");
703 EXPECT_EQ(apply(
"void f(int x) { do {} while ([[x > 0]]); }"),
"unavailable");
704 EXPECT_EQ(apply(
"void f(int x) { for (; [[x > 0]];) ; }"),
"unavailable");
705 EXPECT_EQ(apply(
"void f(int x) { switch ([[x + 1]]) {} }"),
"unavailable");
708 EXPECT_EQ(apply(
"bool cond(); void f() { if ([[bool b = cond()]]) ; }"),
715 EXPECT_THAT(apply(
"void f(int x) { for ([[x = 0]]; x < 10; ++x) ; }"),
716 HasSubstr(
"extracted"));
717 EXPECT_THAT(apply(
"void f(int x) { for (;; [[--x]]) ; }"),
718 HasSubstr(
"extracted"));
720 ExtraArgs.push_back(
"-std=c++17");
721 EXPECT_THAT(apply(
"void f(int x) { if ([[x = 0]]; x > 0) ; }"),
722 HasSubstr(
"extracted"));
723 EXPECT_THAT(apply(
"void f(int x) { switch ([[x = 0]]; x) {} }"),
724 HasSubstr(
"extracted"));
727 EXPECT_THAT(apply(
"void f(int x) { if (x > 0) [[x = x * 2;]] }"),
728 HasSubstr(
"extracted"));
731TEST_F(ExtractFunctionTest, RangeBasedFor) {
736 EXPECT_EQ(apply(R
"cpp(
737 struct Vec { int *begin(); int *end(); };
739 void f() { for (auto X : [[V]]) {} }
743 EXPECT_THAT(apply(R
"cpp(
744 struct Vec { int *begin(); int *end(); };
747 void f() { for (auto X : V) { [[foo(X + 1);]] } }
749 HasSubstr("extracted"));
752TEST_F(ExtractFunctionTest, VarDeclInitializer) {
760 EXPECT_EQ(apply(R
"cpp(
762 void f() { auto A = [[func()]]; }
767 EXPECT_EQ(apply(R
"cpp(
769 void f() { int A = [[func()]]; }
774 EXPECT_THAT(apply(R
"cpp(
776 void f() { [[int A = func();]] }
778 HasSubstr("extracted"));
781TEST_F(ExtractFunctionTest, ConstParameters) {
787 EXPECT_THAT(apply(R
"cpp(
789 void f(int x) { [[use(x); use(x);]] }
791 HasSubstr("void extracted(int x)"));
793 EXPECT_THAT(apply(
"void f(int x) { [[x = 1;]] }"),
794 HasSubstr(
"void extracted(int &x)"));
796 EXPECT_THAT(apply(
"void f(int x) { [[x += 1;]] }"),
797 HasSubstr(
"void extracted(int &x)"));
799 EXPECT_THAT(apply(
"void f(int x) { [[++x;]] }"),
800 HasSubstr(
"void extracted(int &x)"));
802 EXPECT_THAT(apply(R
"cpp(
803 struct S { void mutate(); };
804 void f(S s) { [[s.mutate(); s.mutate();]] }
806 HasSubstr("void extracted(S &s)"));
808 EXPECT_THAT(apply(R
"cpp(
809 struct S { void inspect() const; };
810 void f(S s) { [[s.inspect(); s.inspect();]] }
812 HasSubstr("void extracted(const S &s)"));
815 EXPECT_THAT(apply(R
"cpp(
816 void mayMutate(int &);
817 void f(int x) { [[mayMutate(x); mayMutate(x);]] }
819 HasSubstr("void extracted(int &x)"));
822 EXPECT_THAT(apply(R
"cpp(
823 void readOnly(const int &);
824 void f(int x) { [[readOnly(x); readOnly(x);]] }
826 HasSubstr("void extracted(int x)"));
827 EXPECT_THAT(apply(R
"cpp(
829 void f(int x) { [[byValue(x); byValue(x);]] }
831 HasSubstr("void extracted(int x)"));
836 apply(
"void use(int); void f(const int x) { [[use(x); use(x);]] }"),
837 HasSubstr(
"void extracted(const int x)"));
840 EXPECT_THAT(apply(R
"cpp(
843 void f(const S s) { [[use(s); use(s);]] }
845 HasSubstr("void extracted(const S &s)"));
848TEST_F(ExtractFunctionTest, ConstParametersReferenceAliasing) {
856 EXPECT_THAT(apply(R
"cpp(
862 HasSubstr("void extracted(int &x)"));
865TEST_F(ExtractFunctionTest, ConstParametersConservativeAliasing) {
869 EXPECT_THAT(apply(
"void f(int x) { [[int *p = &x;]] }"),
870 HasSubstr(
"void extracted(int &x)"));
872 EXPECT_THAT(apply(
"void f(int x) { [[static_cast<int &>(x) = 1;]] }"),
873 HasSubstr(
"void extracted(int &x)"));
876 EXPECT_THAT(apply(
"void f(int x) { [[auto l = [&x]() { int y = x; };]] }"),
877 HasSubstr(
"int &x"));
880 EXPECT_THAT(apply(
"void f(int x) { [[auto l = [x]() { int y = x; };]] }"),
881 HasSubstr(
"void extracted(int x)"));
886 EXPECT_THAT(apply(
"int f(int x) { [[return x;]] }"), HasSubstr(
"&x"));
888 EXPECT_THAT(apply(
"void f() { int arr[5]; [[arr[0] = 1;]] }"),
889 Not(HasSubstr(
"const")));
892TEST_F(ExtractFunctionTest, ConstParametersMemberCallArguments) {
898 EXPECT_THAT(apply(R
"cpp(
899 struct S { void mayMutate(int &) const; };
900 void f(S s, int x) { [[s.mayMutate(x); s.mayMutate(x);]] }
902 HasSubstr("extracted(const S &s, int &x)"));
906 EXPECT_THAT(apply(R
"cpp(
907 struct S { void operator()(int &) const; };
908 void f(S s, int x) { [[s(x); s(x);]] }
910 HasSubstr("extracted(const S &s, int &x)"));
913 EXPECT_THAT(apply(R
"cpp(
915 void operator+(const S &, int &);
916 void f(S s, int x) { [[s + x; s + x;]] }
918 HasSubstr("extracted(const S &s, int &x)"));
921TEST_F(ExtractFunctionTest, ConstParametersPointerIndirection) {
928 EXPECT_THAT(apply(R
"cpp(
930 void f(S *ptr) { [[ptr->x = 1;]] }
932 HasSubstr("extracted(S *ptr)"));
933 EXPECT_THAT(apply(
"void f(int *p) { [[p[0] = 1;]] }"),
934 HasSubstr(
"extracted(int *p)"));
936 EXPECT_THAT(apply(
"void f(int *p) { [[*p = 1;]] }"),
937 HasSubstr(
"extracted(int *p)"));
940TEST_F(ExtractFunctionTest, ConstParametersConditionalReferenceBinding) {
946 EXPECT_THAT(apply(R
"cpp(
947 void f(bool cond, int c, int d) {
948 [[int &a = cond ? c : d;
952 HasSubstr("extracted(bool cond, int &c, int &d)"));
955TEST_F(ExtractFunctionTest, ConstParametersConditionalMutatingAccess) {
958 EXPECT_THAT(apply(R
"cpp(
960 void f(bool cond, S s1, S s2) {
961 [[(cond ? s1 : s2).n = 0;]]
964 HasSubstr("extracted(bool cond, S &s1, S &s2)"));
967TEST_F(ExtractFunctionTest, ConstParametersStaticOperatorCall) {
972 ExtraArgs.push_back(
"-std=c++23");
973 EXPECT_THAT(apply(R
"cpp(
974 struct S { static void operator()(int); };
975 void f(S s, int x) { [[s(x); s(x);]] }
977 HasSubstr("extracted(const S &s, int x)"));
980TEST_F(ExtractFunctionTest, ConstParametersFunctionPointer) {
986 EXPECT_THAT(apply(
"void f(void (*F)(int)) { [[F(1);]] }"),
987 HasSubstr(
"extracted(void (*F)(int))"));
990TEST_F(ExtractFunctionTest, ConstParametersFunctionReference) {
996 EXPECT_THAT(apply(
"void f(void (&F)(int)) { [[F(0);]] }"),
997 HasSubstr(
"extracted(void (&F)(int))"));
1000TEST_F(ExtractFunctionTest, ConstParametersScalarsByValue) {
1003 EXPECT_THAT(apply(
"void use(int *); void f(int *p) { [[use(p); use(p);]] }"),
1004 HasSubstr(
"extracted(int *p)"));
1006 EXPECT_THAT(apply(R
"cpp(
1009 void f(E e) { [[use(e); use(e);]] }
1011 HasSubstr("extracted(E e)"));
1014 EXPECT_THAT(apply(R
"cpp(
1015 struct Point { int x, y; };
1017 void f(Point p) { [[use(p);]] }
1019 HasSubstr("extracted(const Point &p)"));
1022 EXPECT_THAT(apply(
"void f() { int arr[5]; [[int x = arr[0];]] }"),
1023 HasSubstr(
"extracted(int (&arr)[5])"));
1028TEST_F(ExtractFunctionTest, ReferenceToScalar) {
1030 EXPECT_THAT(apply(R
"cpp(
1040 HasSubstr("extracted(int &A, const int &B)"));
1041 EXPECT_THAT(apply(R
"cpp(
1051 HasSubstr("extracted(int &A, const int &B)"));
1054TEST_F(ExtractFunctionTest, VolatileScalar) {
1056 EXPECT_THAT(apply(R
"cpp(
1057 void bar(const volatile int &, int) {}
1064 HasSubstr("extracted(const volatile int &V)"));
1067TEST_F(ExtractFunctionTest, CFileAllowUnmodifiedScalar) {
1070 EXPECT_THAT(apply(R
"cpp(
1076 HasSubstr("extracted(int j)"));
1079TEST_F(ExtractFunctionTest, CFileModifiedScalarBecomesPointer) {
1085 EXPECT_THAT(apply(R
"cpp(
1090 AllOf(HasSubstr("extracted(int *j)"), HasSubstr(
"(*j) = 0;"),
1091 HasSubstr(
"extracted(&j)")));
1094TEST_F(ExtractFunctionTest, CFileUnmodifiedStructBecomesConstPointer) {
1099 EXPECT_THAT(apply(R
"cpp(
1100 struct pair { int v1; int v2; };
1107 AllOf(HasSubstr("extracted(const struct pair *p)"),
1108 HasSubstr(
"i = p->v1;"), HasSubstr(
"extracted(&p)")));
1111TEST_F(ExtractFunctionTest, CFileStructMixedUses) {
1117 EXPECT_THAT(apply(R
"cpp(
1118 struct pair { int v1; int v2; };
1119 void use(struct pair);
1123 [[use(p); i = p.v1;]]
1125 AllOf(HasSubstr("use((*p));"), HasSubstr(
"i = p->v1;")));
1128TEST_F(ExtractFunctionTest, CFileRejectMacroDot) {
1135 EXPECT_EQ(apply(R
"cpp(
1137 struct pair { int v1; int v2; };
1142 "fail: Too complex to extract.");
1145TEST_F(ExtractFunctionTest, CFileModifiedArrayStaysPlainPointer) {
1154 EXPECT_THAT(apply(R
"cpp(
1159 AllOf(HasSubstr("extracted(int *arr)"), HasSubstr(
"arr[0] = 1;"),
1160 HasSubstr(
"extracted(arr)"), Not(HasSubstr(
"&arr"))));
1163TEST_F(ExtractFunctionTest, CFileStaticFunctionStaysStatic) {
1169 EXPECT_THAT(apply(R
"cpp(
1174 HasSubstr("static void extracted"));
1177TEST_F(ExtractFunctionTest, CFileStaticForwardDeclaredFunctionStaysStatic) {
1184 EXPECT_THAT(apply(R
"cpp(
1190 HasSubstr("static void extracted"));
1193TEST_F(ExtractFunctionTest, CFileRejectArraySizeof) {
1199 EXPECT_EQ(apply(R
"cpp(
1202 [[int n = sizeof(arr);]]
1204 "fail: Too complex to extract.");
1207TEST_F(ExtractFunctionTest, CFileRejectArrayAlignof) {
1213 EXPECT_EQ(apply(R
"cpp(
1216 [[int n = __alignof(arr);]]
1218 "fail: Too complex to extract.");
1221TEST_F(ExtractFunctionTest, CFileRejectArrayTypeof) {
1228 EXPECT_EQ(apply(R
"cpp(
1231 [[__typeof__(arr) copy;]]
1233 "fail: Too complex to extract.");
1236TEST_F(ExtractFunctionTest, CFileAllowSingleDimensionVariableLengthArray) {
1242 EXPECT_THAT(apply(R
"cpp(
1247 HasSubstr("extracted(int *A)"));
1250TEST_F(ExtractFunctionTest, CFileRejectMultiDimensionVariableLengthArray) {
1260 EXPECT_EQ(apply(R
"cpp(
1265 "fail: Too complex to extract.");
1268TEST_F(ExtractFunctionTest, CXXRejectVariableLengthArray) {
1280 EXPECT_EQ(apply(R
"cpp(
1285 "fail: Too complex to extract.");
1288TEST_F(ExtractFunctionTest, CXXRejectSingleDimensionVariableLengthArray) {
1295 EXPECT_EQ(apply(R
"cpp(
1300 "fail: Too complex to extract.");
1303TEST_F(ExtractFunctionTest, CXXRejectPointerToVariableLengthArray) {
1312 EXPECT_EQ(apply(R
"cpp(
1317 "fail: Too complex to extract.");
1320TEST_F(ExtractFunctionTest, CFileRejectMutatedPointerToVariableLengthArray) {
1328 EXPECT_EQ(apply(R
"cpp(
1334 "fail: Too complex to extract.");
1337TEST_F(ExtractFunctionTest, RejectPureForwardingZeroArgCall) {
1341 EXPECT_EQ(apply(
"void foo(); void f() { [[foo();]] }"),
"unavailable");
1344TEST_F(ExtractFunctionTest, RejectPureForwardingSingleArgCall) {
1347 EXPECT_EQ(apply(
"void foo(int); void f(int x) { [[foo(x);]] }"),
1351TEST_F(ExtractFunctionTest, OfferDespitePureForwarding_LiteralArg) {
1354 EXPECT_THAT(apply(
"void foo(int); void f() { [[foo(100);]] }"),
1355 HasSubstr(
"extracted"));
1358TEST_F(ExtractFunctionTest, OfferDespitePureForwarding_GlobalArg) {
1363 EXPECT_THAT(apply(R
"cpp(
1366 void f() { [[foo(globalVar);]] }
1368 HasSubstr("extracted"));
1371TEST_F(ExtractFunctionTest, OfferDespitePureForwarding_ComputedArg) {
1375 EXPECT_THAT(apply(
"void foo(int); void f(int x, int y) { [[foo(x + y);]] }"),
1376 HasSubstr(
"extracted"));
1379TEST_F(ExtractFunctionTest, RejectPureForwardingMethodCall) {
1382 EXPECT_EQ(apply(R
"cpp(
1383 struct S { void method(int); };
1384 void f(S s, int x) { [[s.method(x);]] }
1389TEST_F(ExtractFunctionTest, OfferDespitePureForwarding_GlobalReceiver) {
1393 EXPECT_THAT(apply(R
"cpp(
1394 struct S { void method(); };
1396 void f() { [[globalS.method();]] }
1398 HasSubstr("extracted"));
1401TEST_F(ExtractFunctionTest, RejectPureForwardingOperatorCall) {
1405 EXPECT_EQ(apply(R
"cpp(
1407 void operator+(const S &, int);
1408 void f(S s, int x) { [[s + x;]] }
1413TEST_F(ExtractFunctionTest, RejectPureForwardingFunctionPointerCall) {
1418 EXPECT_EQ(apply(
"void f(void (*fp)(int), int x) { [[fp(x);]] }"),
1422TEST_F(ExtractFunctionTest, OfferDespitePureForwarding_ComputedCallee) {
1427 apply(
"void f(void (*fp[2])(int), int i, int x) { [[fp[i](x);]] }"),
1428 HasSubstr(
"extracted"));
1431TEST_F(ExtractFunctionTest, RejectPureForwardingReturnStmt) {
1435 EXPECT_EQ(apply(
"int foo(int); int f(int x) { [[return foo(x);]] }"),
1439TEST_F(ExtractFunctionTest, RejectPureForwardingReturnStmtImplicitConversion) {
1444 EXPECT_EQ(apply(
"int foo(int); long f(int x) { [[return foo(x);]] }"),
1448TEST_F(ExtractFunctionTest, OfferDespitePureForwarding_ReturnStmtComputedArg) {
1452 apply(
"int foo(int); int f(int x, int y) { [[return foo(x + y);]] }"),
1453 HasSubstr(
"extracted"));
1456TEST_F(ExtractFunctionTest, RejectBareReturnStmt) {
1460 EXPECT_EQ(apply(
"void f() { [[return;]] }"),
"unavailable");
1463TEST_F(ExtractFunctionTest, OfferDespitePureForwarding_PointerToMemberCallee) {
1469 EXPECT_THAT(apply(R
"cpp(
1471 void f(St S, void (St::*table[2])(int), int I, int A) {
1472 [[(S.*table[I])(A);]]
1474 HasSubstr("extracted"));
1477TEST_F(ExtractFunctionTest, RejectPureForwardingImplicitThis) {
1483 EXPECT_EQ(apply(R
"cpp(
1493TEST_F(ExtractFunctionTest, RejectPureForwardingDefaultArg) {
1498 EXPECT_EQ(apply(R
"cpp(
1499 void foo(int A, int B = 0);
1506TEST_F(ExtractFunctionTest, RejectPureForwardingParenthesizedReturn) {
1510 EXPECT_EQ(apply(R
"cpp(
1513 [[return (foo(A));]]
1518TEST_F(ExtractFunctionTest, OfferDespitePureForwarding_RepeatedArg) {
1524 EXPECT_THAT(apply(R
"cpp(
1525 void foo(int A, int B);
1526 void bar(int A, int B) {
1529 HasSubstr("extracted"));
1532TEST_F(ExtractFunctionTest, OfferDespitePureForwarding_ReorderedArgs) {
1541 EXPECT_THAT(apply(R
"cpp(
1542 void foo(int A, int B);
1543 void bar(int A, int B) {
1546 HasSubstr("extracted"));
1549TEST_F(ExtractFunctionTest, RejectPureForwardingPreservedArgOrder) {
1554 EXPECT_EQ(apply(R
"cpp(
1555 void foo(int A, int B);
1556 void bar(int A, int B) {
1562TEST_F(ExtractFunctionTest, RejectPureForwardingFunctionScopeStatic) {
1568 EXPECT_EQ(apply(R
"cpp(
1577TEST_F(ExtractFunctionTest, RejectPureForwardingFunctionScopeThreadLocal) {
1581 EXPECT_EQ(apply(R
"cpp(
1590TEST_F(ExtractFunctionTest, OfferDespitePureForwarding_NamespaceScopeStatic) {
1596 EXPECT_THAT(apply(R
"cpp(
1599 void bar() { [[foo(A);]] }
1601 HasSubstr("extracted"));
1604TEST_F(ExtractFunctionTest, RejectPureForwardingStructuredBinding) {
1609 ExtraArgs.push_back(
"-std=c++17");
1610 EXPECT_EQ(apply(R
"cpp(
1612 struct Pair { int A, B; };
1615 auto [A, B] = make();
#define TWEAK_TEST(TweakID)
A context is an immutable container for per-request data that must be propagated through layers that ...
FIXME: Skip testing on windows temporarily due to the different escaping code mode.
TEST_F(BackgroundIndexTest, NoCrashOnErrorFile)
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//