1 //===-- ExpandAutoTypeTests.cpp ---------------------------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8
9 #include "TestTU.h"
10 #include "TweakTesting.h"
11 #include "gmock/gmock-matchers.h"
12 #include "gmock/gmock.h"
13 #include "gtest/gtest.h"
14
15 using ::testing::StartsWith;
16
17 namespace clang {
18 namespace clangd {
19 namespace {
20
21 TWEAK_TEST(ExpandAutoType);
22
TEST_F(ExpandAutoTypeTest,Test)23 TEST_F(ExpandAutoTypeTest, Test) {
24 Header = R"cpp(
25 namespace ns {
26 struct Class {
27 struct Nested {};
28 };
29 void Func();
30 }
31 inline namespace inl_ns {
32 namespace {
33 struct Visible {};
34 }
35 }
36 )cpp";
37
38 EXPECT_AVAILABLE("^a^u^t^o^ i = 0;");
39 EXPECT_UNAVAILABLE("auto ^i^ ^=^ ^0^;^");
40
41 // check primitive type
42 EXPECT_EQ(apply("[[auto]] i = 0;"), "int i = 0;");
43 EXPECT_EQ(apply("au^to i = 0;"), "int i = 0;");
44 // check classes and namespaces
45 EXPECT_EQ(apply("^auto C = ns::Class::Nested();"),
46 "ns::Class::Nested C = ns::Class::Nested();");
47 // check that namespaces are shortened
48 EXPECT_EQ(apply("namespace ns { void f() { ^auto C = Class(); } }"),
49 "namespace ns { void f() { Class C = Class(); } }");
50 // undefined functions should not be replaced
51 EXPECT_THAT(apply("au^to x = doesnt_exist(); // error-ok"),
52 StartsWith("fail: Could not deduce type for 'auto' type"));
53 // function pointers should not be replaced
54 EXPECT_THAT(apply("au^to x = &ns::Func;"),
55 StartsWith("fail: Could not expand type of function pointer"));
56 // lambda types are not replaced
57 EXPECT_UNAVAILABLE("au^to x = []{};");
58 // inline namespaces
59 EXPECT_EQ(apply("au^to x = inl_ns::Visible();"),
60 "Visible x = inl_ns::Visible();");
61 // local class
62 EXPECT_EQ(apply("namespace x { void y() { struct S{}; ^auto z = S(); } }"),
63 "namespace x { void y() { struct S{}; S z = S(); } }");
64 // replace array types
65 EXPECT_EQ(apply(R"cpp(au^to x = "test";)cpp"),
66 R"cpp(const char * x = "test";)cpp");
67
68 EXPECT_UNAVAILABLE("dec^ltype(au^to) x = 10;");
69 // expanding types in structured bindings is syntactically invalid.
70 EXPECT_UNAVAILABLE("const ^auto &[x,y] = (int[]){1,2};");
71
72 // FIXME: Auto-completion in a template requires disabling delayed template
73 // parsing.
74 ExtraArgs.push_back("-fno-delayed-template-parsing");
75 // unknown types in a template should not be replaced
76 EXPECT_THAT(apply("template <typename T> void x() { ^auto y = T::z(); }"),
77 StartsWith("fail: Could not deduce type for 'auto' type"));
78 }
79
80 } // namespace
81 } // namespace clangd
82 } // namespace clang
83