• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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