Changeset View
Changeset View
Standalone View
Standalone View
clang-tools-extra/clangd/unittests/tweaks/ExtractFunctionTests.cpp
Show All 24 Lines | TEST_F(ExtractFunctionTest, FunctionTest) { | ||||
// Root statements should have common parent. | // Root statements should have common parent. | ||||
EXPECT_EQ(apply("for(;;) [[1+2; 1+2;]]"), "unavailable"); | EXPECT_EQ(apply("for(;;) [[1+2; 1+2;]]"), "unavailable"); | ||||
// Expressions aren't extracted. | // Expressions aren't extracted. | ||||
EXPECT_EQ(apply("int x = 0; [[x++;]]"), "unavailable"); | EXPECT_EQ(apply("int x = 0; [[x++;]]"), "unavailable"); | ||||
// We don't support extraction from lambdas. | // We don't support extraction from lambdas. | ||||
EXPECT_EQ(apply("auto lam = [](){ [[int x;]] }; "), "unavailable"); | EXPECT_EQ(apply("auto lam = [](){ [[int x;]] }; "), "unavailable"); | ||||
// Partial statements aren't extracted. | // Partial statements aren't extracted. | ||||
EXPECT_THAT(apply("int [[x = 0]];"), "unavailable"); | EXPECT_THAT(apply("int [[x = 0]];"), "unavailable"); | ||||
// FIXME: Support hoisting. | |||||
EXPECT_THAT(apply(" [[int a = 5;]] a++; "), "unavailable"); | // Extract regions that require hoisting | ||||
EXPECT_THAT(apply(" [[int a = 5;]] a++; "), HasSubstr("extracted")); | |||||
// Ensure that end of Zone and Beginning of PostZone being adjacent doesn't | // Ensure that end of Zone and Beginning of PostZone being adjacent doesn't | ||||
// lead to break being included in the extraction zone. | // lead to break being included in the extraction zone. | ||||
EXPECT_THAT(apply("for(;;) { [[int x;]]break; }"), HasSubstr("extracted")); | EXPECT_THAT(apply("for(;;) { [[int x;]]break; }"), HasSubstr("extracted")); | ||||
// FIXME: ExtractFunction should be unavailable inside loop construct | // FIXME: ExtractFunction should be unavailable inside loop construct | ||||
// initializer/condition. | // initializer/condition. | ||||
EXPECT_THAT(apply(" for([[int i = 0;]];);"), HasSubstr("extracted")); | EXPECT_THAT(apply(" for([[int i = 0;]];);"), HasSubstr("extracted")); | ||||
// Extract certain return | // Extract certain return | ||||
▲ Show 20 Lines • Show All 144 Lines • ▼ Show 20 Lines | F (extracted();) | ||||
std::string CompoundFailInput = R"cpp( | std::string CompoundFailInput = R"cpp( | ||||
void f() [[{ | void f() [[{ | ||||
int a; | int a; | ||||
}]] | }]] | ||||
)cpp"; | )cpp"; | ||||
EXPECT_EQ(apply(CompoundFailInput), "unavailable"); | EXPECT_EQ(apply(CompoundFailInput), "unavailable"); | ||||
} | } | ||||
TEST_F(ExtractFunctionTest, Hoisting) { | |||||
ExtraArgs.emplace_back("-std=c++17"); | |||||
std::string HoistingInput = R"cpp( | |||||
int foo() { | |||||
int a = 3; | |||||
[[int x = 39 + a; | |||||
++x; | |||||
int y = x * 2; | |||||
int z = 4;]] | |||||
return x + y + z; | |||||
} | |||||
)cpp"; | |||||
std::string HoistingOutput = R"cpp( | |||||
auto extracted(int &a) { | |||||
int x = 39 + a; | |||||
++x; | |||||
int y = x * 2; | |||||
int z = 4; | |||||
return std::tuple{x, y, z}; | |||||
} | |||||
int foo() { | |||||
int a = 3; | |||||
auto [x, y, z] = extracted(a); | |||||
return x + y + z; | |||||
} | |||||
)cpp"; | |||||
EXPECT_EQ(apply(HoistingInput), HoistingOutput); | |||||
std::string HoistingInput2 = R"cpp( | |||||
int foo() { | |||||
int a{}; | |||||
[[int b = a + 1;]] | |||||
return b; | |||||
} | |||||
)cpp"; | |||||
std::string HoistingOutput2 = R"cpp( | |||||
int extracted(int &a) { | |||||
int b = a + 1; | |||||
return b; | |||||
} | |||||
int foo() { | |||||
int a{}; | |||||
auto b = extracted(a); | |||||
return b; | |||||
} | |||||
)cpp"; | |||||
EXPECT_EQ(apply(HoistingInput2), HoistingOutput2); | |||||
std::string HoistingInput3 = R"cpp( | |||||
int foo(int b) { | |||||
int a{}; | |||||
if (b == 42) { | |||||
[[a = 123; | |||||
return a + b;]] | |||||
} | |||||
a = 456; | |||||
return a; | |||||
} | |||||
)cpp"; | |||||
std::string HoistingOutput3 = R"cpp( | |||||
int extracted(int &b, int &a) { | |||||
a = 123; | |||||
return a + b; | |||||
} | |||||
int foo(int b) { | |||||
int a{}; | |||||
if (b == 42) { | |||||
return extracted(b, a); | |||||
} | |||||
a = 456; | |||||
return a; | |||||
} | |||||
)cpp"; | |||||
EXPECT_EQ(apply(HoistingInput3), HoistingOutput3); | |||||
std::string HoistingInput4 = R"cpp( | |||||
struct A { | |||||
bool flag; | |||||
int val; | |||||
}; | |||||
A bar(); | |||||
int foo(int b) { | |||||
int a = 0; | |||||
[[auto [flag, val] = bar(); | |||||
int c = 4; | |||||
val = c + a;]] | |||||
return a + b + c + val; | |||||
} | |||||
)cpp"; | |||||
std::string HoistingOutput4 = R"cpp( | |||||
struct A { | |||||
bool flag; | |||||
int val; | |||||
}; | |||||
A bar(); | |||||
auto extracted(int &a) { | |||||
auto [flag, val] = bar(); | |||||
int c = 4; | |||||
val = c + a; | |||||
return std::pair{val, c}; | |||||
} | |||||
int foo(int b) { | |||||
int a = 0; | |||||
auto [val, c] = extracted(a); | |||||
return a + b + c + val; | |||||
} | |||||
)cpp"; | |||||
EXPECT_EQ(apply(HoistingInput4), HoistingOutput4); | |||||
} | |||||
TEST_F(ExtractFunctionTest, HoistingCXX11) { | |||||
ExtraArgs.emplace_back("-std=c++11"); | |||||
std::string HoistingInput = R"cpp( | |||||
int foo() { | |||||
int a = 3; | |||||
[[int x = 39 + a; | |||||
++x; | |||||
int y = x * 2; | |||||
int z = 4;]] | |||||
return x + y + z; | |||||
} | |||||
)cpp"; | |||||
EXPECT_THAT(apply(HoistingInput), HasSubstr("unavailable")); | |||||
std::string HoistingInput2 = R"cpp( | |||||
int foo() { | |||||
int a; | |||||
[[int b = a + 1;]] | |||||
return b; | |||||
} | |||||
)cpp"; | |||||
std::string HoistingOutput2 = R"cpp( | |||||
int extracted(int &a) { | |||||
int b = a + 1; | |||||
return b; | |||||
} | |||||
int foo() { | |||||
int a; | |||||
auto b = extracted(a); | |||||
return b; | |||||
} | |||||
)cpp"; | |||||
EXPECT_EQ(apply(HoistingInput2), HoistingOutput2); | |||||
} | |||||
TEST_F(ExtractFunctionTest, HoistingCXX14) { | |||||
ExtraArgs.emplace_back("-std=c++14"); | |||||
std::string HoistingInput = R"cpp( | |||||
int foo() { | |||||
int a = 3; | |||||
[[int x = 39 + a; | |||||
++x; | |||||
int y = x * 2; | |||||
int z = 4;]] | |||||
return x + y + z; | |||||
} | |||||
)cpp"; | |||||
std::string HoistingOutput = R"cpp( | |||||
auto extracted(int &a) { | |||||
int x = 39 + a; | |||||
++x; | |||||
int y = x * 2; | |||||
int z = 4; | |||||
return std::tuple{x, y, z}; | |||||
} | |||||
int foo() { | |||||
int a = 3; | |||||
auto returned = extracted(a); | |||||
auto x = std::get<0>(returned); | |||||
auto y = std::get<1>(returned); | |||||
auto z = std::get<2>(returned); | |||||
return x + y + z; | |||||
} | |||||
)cpp"; | |||||
EXPECT_EQ(apply(HoistingInput), HoistingOutput); | |||||
std::string HoistingInput2 = R"cpp( | |||||
int foo() { | |||||
int a; | |||||
[[int b = a + 1;]] | |||||
return b; | |||||
} | |||||
)cpp"; | |||||
std::string HoistingOutput2 = R"cpp( | |||||
int extracted(int &a) { | |||||
int b = a + 1; | |||||
return b; | |||||
} | |||||
int foo() { | |||||
int a; | |||||
auto b = extracted(a); | |||||
return b; | |||||
} | |||||
)cpp"; | |||||
EXPECT_EQ(apply(HoistingInput2), HoistingOutput2); | |||||
} | |||||
TEST_F(ExtractFunctionTest, DifferentHeaderSourceTest) { | TEST_F(ExtractFunctionTest, DifferentHeaderSourceTest) { | ||||
Header = R"cpp( | Header = R"cpp( | ||||
class SomeClass { | class SomeClass { | ||||
void f(); | void f(); | ||||
}; | }; | ||||
)cpp"; | )cpp"; | ||||
std::string OutOfLineSource = R"cpp( | std::string OutOfLineSource = R"cpp( | ||||
▲ Show 20 Lines • Show All 374 Lines • Show Last 20 Lines |