brintos

brintos / llvm-project-archived public Read only

0
0
Text · 12.8 KiB · 95b6eae Raw
408 lines · cpp
1//===-- SymbolInfoTests.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-exception6//7//===----------------------------------------------------------------------===//8#include "Annotations.h"9#include "ParsedAST.h"10#include "TestTU.h"11#include "XRefs.h"12#include "gmock/gmock.h"13#include "gtest/gtest.h"14#include <optional>15 16namespace clang {17namespace clangd {18namespace {19 20using ::testing::UnorderedElementsAreArray;21 22// Partial SymbolDetails with the rest filled in at testing time.23struct ExpectedSymbolDetails {24  std::string Name;25  std::string Container;26  std::string USR;27  const char *DeclMarker = nullptr;28  const char *DefMarker = nullptr;29};30 31TEST(SymbolInfoTests, All) {32  std::pair<const char *, std::vector<ExpectedSymbolDetails>>33      TestInputExpectedOutput[] = {34          {35              R"cpp( // Simple function reference - declaration36          void $decl[[foo]]();37          int bar() {38            fo^o();39            return 0;40          }41        )cpp",42              {ExpectedSymbolDetails{"foo", "", "c:@F@foo#", "decl"}}},43          {44              R"cpp( // Simple function reference - definition45          void $def[[foo]]() {}46          int bar() {47            fo^o();48            return 0;49          }50        )cpp",51              {ExpectedSymbolDetails{"foo", "", "c:@F@foo#", "def", "def"}}},52          {53              R"cpp( // Simple function reference - decl and def54          void $decl[[foo]]();55          void $def[[foo]]() {}56          int bar() {57            fo^o();58            return 0;59          }60        )cpp",61              {ExpectedSymbolDetails{"foo", "", "c:@F@foo#", "decl", "def"}}},62          {63              R"cpp( // Simple class reference - decl and def64          @interface $decl[[Foo]]65          @end66          @implementation $def[[Foo]]67          @end68          void doSomething(F^oo *obj) {}69        )cpp",70              {ExpectedSymbolDetails{"Foo", "", "c:objc(cs)Foo", "decl",71                                     "def"}}},72          {73              R"cpp( // Simple method reference - decl and def74          @interface Foo75          - (void)$decl[[foo]];76          @end77          @implementation Foo78          - (void)$def[[fo^o]] {}79          @end80        )cpp",81              {ExpectedSymbolDetails{"foo", "Foo::", "c:objc(cs)Foo(im)foo",82                                     "decl", "def"}}},83          {84              R"cpp( // Function in namespace reference85          namespace bar {86            void $decl[[foo]]();87            int baz() {88              fo^o();89              return 0;90            }91          }92        )cpp",93              {ExpectedSymbolDetails{"foo", "bar::", "c:@N@bar@F@foo#",94                                     "decl"}}},95          {96              R"cpp( // Function in different namespace reference97          namespace bar {98            void $decl[[foo]]();99          }100          namespace barbar {101            int baz() {102              bar::fo^o();103              return 0;104            }105          }106        )cpp",107              {ExpectedSymbolDetails{"foo", "bar::", "c:@N@bar@F@foo#",108                                     "decl"}}},109          {110              R"cpp( // Function in global namespace reference111          void $decl[[foo]]();112          namespace Nbar {113            namespace Nbaz {114              int baz() {115                ::fo^o();116              return 0;117              }118            }119          }120        )cpp",121              {ExpectedSymbolDetails{"foo", "", "c:@F@foo#", "decl"}}},122          {123              R"cpp( // Function in anonymous namespace reference124          namespace {125            void $decl[[foo]]();126          }127          namespace barbar {128            int baz() {129              fo^o();130              return 0;131            }132          }133        )cpp",134              {ExpectedSymbolDetails{"foo", "(anonymous)",135                                     "c:TestTU.cpp@aN@F@foo#", "decl"}}},136          {137              R"cpp( // Function reference - ADL138          namespace bar {139            struct BarType {};140            void $decl[[foo]](const BarType&);141          }142          namespace barbar {143            int baz() {144              bar::BarType b;145              fo^o(b);146              return 0;147            }148          }149        )cpp",150              {ExpectedSymbolDetails{151                  "foo", "bar::", "c:@N@bar@F@foo#&1$@N@bar@S@BarType#",152                  "decl"}}},153          {154              R"cpp( // Global value reference155          int $def[[value]];156          void foo(int) { }157          void bar() {158            foo(val^ue);159          }160        )cpp",161              {ExpectedSymbolDetails{"value", "", "c:@value", "def", "def"}}},162          {163              R"cpp( // Local value reference164          void foo() { int $def[[aaa]]; int bbb = aa^a; }165        )cpp",166              {ExpectedSymbolDetails{"aaa", "foo", "c:TestTU.cpp@49@F@foo#@aaa",167                                     "def", "def"}}},168          {169              R"cpp( // Function param170          void bar(int $def[[aaa]]) {171            int bbb = a^aa;172          }173        )cpp",174              {ExpectedSymbolDetails{175                  "aaa", "bar", "c:TestTU.cpp@38@F@bar#I#@aaa", "def", "def"}}},176          {177              R"cpp( // Lambda capture178          void foo() {179            int $def[[ii]];180            auto lam = [ii]() {181              return i^i;182            };183          }184        )cpp",185              {ExpectedSymbolDetails{"ii", "foo", "c:TestTU.cpp@54@F@foo#@ii",186                                     "def", "def"}}},187          {188              R"cpp( // Macro reference189          #define MACRO 5\nint i = MAC^RO;190        )cpp",191              {ExpectedSymbolDetails{"MACRO", "",192                                     "c:TestTU.cpp@38@macro@MACRO"}}},193          {194              R"cpp( // Macro reference195          #define MACRO 5\nint i = MACRO^;196        )cpp",197              {ExpectedSymbolDetails{"MACRO", "",198                                     "c:TestTU.cpp@38@macro@MACRO"}}},199          {200              R"cpp( // Multiple symbols returned - using overloaded function name201          void $def[[foo]]() {}202          void $def_bool[[foo]](bool) {}203          void $def_int[[foo]](int) {}204          namespace bar {205            using ::$decl[[fo^o]];206          }207        )cpp",208              {ExpectedSymbolDetails{"foo", "", "c:@F@foo#", "def", "def"},209               ExpectedSymbolDetails{"foo", "", "c:@F@foo#b#", "def_bool",210                                     "def_bool"},211               ExpectedSymbolDetails{"foo", "", "c:@F@foo#I#", "def_int",212                                     "def_int"},213               ExpectedSymbolDetails{"foo", "bar::", "c:@N@bar@UD@foo",214                                     "decl"}}},215          {216              R"cpp( // Multiple symbols returned - implicit conversion217          struct foo {};218          struct bar {219            bar(const foo&) {}220          };221          void func_baz1(bar) {}222          void func_baz2() {223            foo $def[[ff]];224            func_baz1(f^f);225          }226        )cpp",227              {ExpectedSymbolDetails{"ff", "func_baz2",228                                     "c:TestTU.cpp@218@F@func_baz2#@ff", "def",229                                     "def"}}},230          {231              R"cpp( // Type reference - declaration232          struct $decl[[foo]];233          void bar(fo^o*);234        )cpp",235              {ExpectedSymbolDetails{"foo", "", "c:@S@foo", "decl"}}},236          {237              R"cpp( // Type reference - definition238          struct $def[[foo]] {};239          void bar(fo^o*);240        )cpp",241              {ExpectedSymbolDetails{"foo", "", "c:@S@foo", "def", "def"}}},242          {243              R"cpp( // Type Reference - template argument244          struct $def[[foo]] {};245          template<class T> struct bar {};246          void baz() {247            bar<fo^o> b;248          }249        )cpp",250              {ExpectedSymbolDetails{"foo", "", "c:@S@foo", "def", "def"}}},251          {252              R"cpp( // Template parameter reference - type param253          template<class $def[[TT]]> struct bar {254            T^T t;255          };256        )cpp",257              {ExpectedSymbolDetails{"TT", "bar::", "c:TestTU.cpp@65", "def",258                                     "def"}}},259          {260              R"cpp( // Template parameter reference - type param261          template<int $def[[NN]]> struct bar {262            int a = N^N;263          };264        )cpp",265              {ExpectedSymbolDetails{"NN", "bar::", "c:TestTU.cpp@65", "def",266                                     "def"}}},267          {268              R"cpp( // Class member reference - objec269          struct foo {270            int $def[[aa]];271          };272          void bar() {273            foo f;274            f.a^a;275          }276        )cpp",277              {ExpectedSymbolDetails{"aa", "foo::", "c:@S@foo@FI@aa", "def",278                                     "def"}}},279          {280              R"cpp( // Class member reference - pointer281          struct foo {282            int $def[[aa]];283          };284          void bar() {285            &foo::a^a;286          }287        )cpp",288              {ExpectedSymbolDetails{"aa", "foo::", "c:@S@foo@FI@aa", "def",289                                     "def"}}},290          {291              R"cpp( // Class method reference - objec292          struct foo {293            void $def[[aa]]() {}294          };295          void bar() {296            foo f;297            f.a^a();298          }299        )cpp",300              {ExpectedSymbolDetails{"aa", "foo::", "c:@S@foo@F@aa#", "def",301                                     "def"}}},302          {303              R"cpp( // Class method reference - pointer304          struct foo {305            void $def[[aa]]() {}306          };307          void bar() {308            &foo::a^a;309          }310        )cpp",311              {ExpectedSymbolDetails{"aa", "foo::", "c:@S@foo@F@aa#", "def",312                                     "def"}}},313          {314              R"cpp( // Typedef315          typedef int $decl[[foo]];316          void bar() {317            fo^o a;318          }319        )cpp",320              {ExpectedSymbolDetails{"foo", "", "c:TestTU.cpp@T@foo", "decl"}}},321          {322              R"cpp( // Type alias323          using $decl[[foo]] = int;324          void bar() {325            fo^o a;326          }327        )cpp",328              {ExpectedSymbolDetails{"foo", "", "c:@foo", "decl"}}},329          {330              R"cpp( // Namespace reference331          namespace $decl[[foo]] {}332          using namespace fo^o;333        )cpp",334              {ExpectedSymbolDetails{"foo", "", "c:@N@foo", "decl"}}},335          {336              R"cpp( // Enum value reference337          enum foo { $def[[bar]], baz };338          void f() {339            foo fff = ba^r;340          }341        )cpp",342              {ExpectedSymbolDetails{"bar", "foo", "c:@E@foo@bar", "def",343                                     "def"}}},344          {345              R"cpp( // Enum class value reference346          enum class foo { $def[[bar]], baz };347          void f() {348            foo fff = foo::ba^r;349          }350        )cpp",351              {ExpectedSymbolDetails{"bar", "foo::", "c:@E@foo@bar", "def",352                                     "def"}}},353          {354              R"cpp( // Parameters in declarations355          void foo(int $def[[ba^r]]);356        )cpp",357              {ExpectedSymbolDetails{358                  "bar", "foo", "c:TestTU.cpp@50@F@foo#I#@bar", "def", "def"}}},359          {360              R"cpp( // Type inference with auto keyword361          struct foo {};362          foo getfoo() { return foo{}; }363          void f() {364            au^to a = getfoo();365          }366        )cpp",367              {/* not implemented */}},368          {369              R"cpp( // decltype370          struct foo {};371          void f() {372            foo f;373            declt^ype(f);374          }375        )cpp",376              {/* not implemented */}},377      };378 379  for (const auto &T : TestInputExpectedOutput) {380    Annotations TestInput(T.first);381    TestTU TU;382    TU.Code = std::string(TestInput.code());383    TU.ExtraArgs.push_back("-xobjective-c++");384    auto AST = TU.build();385 386    std::vector<SymbolDetails> Expected;387    for (const auto &Sym : T.second) {388      std::optional<Location> Decl, Def;389      if (Sym.DeclMarker)390        Decl = Location{URIForFile::canonicalize(testPath(TU.Filename), ""),391                        TestInput.range(Sym.DeclMarker)};392      if (Sym.DefMarker)393        Def = Location{URIForFile::canonicalize(testPath(TU.Filename), ""),394                       TestInput.range(Sym.DefMarker)};395      Expected.push_back(396          {Sym.Name, Sym.Container, Sym.USR, SymbolID(Sym.USR), Decl, Def});397    }398 399    EXPECT_THAT(getSymbolInfo(AST, TestInput.point()),400                UnorderedElementsAreArray(Expected))401        << T.first;402  }403}404 405} // namespace406} // namespace clangd407} // namespace clang408