blob: 2b574a53fc3235d22411298c49cdace497f36267 [file] [log] [blame]
Eric Liu4d221722018-09-18 08:51:08 +00001//===--- IndexTests.cpp - Test indexing actions -----------------*- C++ -*-===//
2//
Chandler Carruth2946cd72019-01-19 08:50:56 +00003// 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
Eric Liu4d221722018-09-18 08:51:08 +00006//
7//===----------------------------------------------------------------------===//
8
9#include "clang/AST/ASTConsumer.h"
10#include "clang/AST/Decl.h"
Eric Liu4d221722018-09-18 08:51:08 +000011#include "clang/Frontend/CompilerInstance.h"
12#include "clang/Frontend/FrontendAction.h"
13#include "clang/Index/IndexDataConsumer.h"
14#include "clang/Index/IndexSymbol.h"
15#include "clang/Index/IndexingAction.h"
16#include "clang/Lex/Preprocessor.h"
17#include "clang/Tooling/Tooling.h"
18#include "llvm/ADT/StringRef.h"
Jonas Devliegherefc514902018-10-10 13:27:25 +000019#include "llvm/Support/VirtualFileSystem.h"
Eric Liu4d221722018-09-18 08:51:08 +000020#include "gmock/gmock.h"
21#include "gtest/gtest.h"
22#include <memory>
23
24namespace clang {
25namespace index {
26
27struct TestSymbol {
28 std::string QName;
29 // FIXME: add more information.
30};
31
32llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const TestSymbol &S) {
33 return OS << S.QName;
34}
35
36namespace {
37class Indexer : public IndexDataConsumer {
38public:
39 bool handleDeclOccurence(const Decl *D, SymbolRoleSet Roles,
40 ArrayRef<SymbolRelation>, SourceLocation,
41 ASTNodeInfo) override {
42 const auto *ND = llvm::dyn_cast<NamedDecl>(D);
43 if (!ND)
44 return true;
45 TestSymbol S;
46 S.QName = ND->getQualifiedNameAsString();
47 Symbols.push_back(std::move(S));
48 return true;
49 }
50
51 bool handleMacroOccurence(const IdentifierInfo *Name, const MacroInfo *,
52 SymbolRoleSet, SourceLocation) override {
53 TestSymbol S;
54 S.QName = Name->getName();
55 Symbols.push_back(std::move(S));
56 return true;
57 }
58
59 std::vector<TestSymbol> Symbols;
60};
61
62class IndexAction : public ASTFrontendAction {
63public:
64 IndexAction(std::shared_ptr<Indexer> Index,
65 IndexingOptions Opts = IndexingOptions())
66 : Index(std::move(Index)), Opts(Opts) {}
67
68protected:
69 std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,
70 StringRef InFile) override {
71 class Consumer : public ASTConsumer {
72 std::shared_ptr<Indexer> Index;
73 std::shared_ptr<Preprocessor> PP;
74 IndexingOptions Opts;
75
76 public:
77 Consumer(std::shared_ptr<Indexer> Index, std::shared_ptr<Preprocessor> PP,
78 IndexingOptions Opts)
79 : Index(std::move(Index)), PP(std::move(PP)), Opts(Opts) {}
80
81 void HandleTranslationUnit(ASTContext &Ctx) override {
82 std::vector<Decl *> DeclsToIndex(
83 Ctx.getTranslationUnitDecl()->decls().begin(),
84 Ctx.getTranslationUnitDecl()->decls().end());
85 indexTopLevelDecls(Ctx, *PP, DeclsToIndex, *Index, Opts);
86 }
87 };
88 return llvm::make_unique<Consumer>(Index, CI.getPreprocessorPtr(), Opts);
89 }
90
91private:
92 std::shared_ptr<Indexer> Index;
93 IndexingOptions Opts;
94};
95
96using testing::Contains;
97using testing::Not;
98using testing::UnorderedElementsAre;
99
100MATCHER_P(QName, Name, "") { return arg.QName == Name; }
101
102TEST(IndexTest, Simple) {
103 auto Index = std::make_shared<Indexer>();
104 tooling::runToolOnCode(new IndexAction(Index), "class X {}; void f() {}");
105 EXPECT_THAT(Index->Symbols, UnorderedElementsAre(QName("X"), QName("f")));
106}
107
108TEST(IndexTest, IndexPreprocessorMacros) {
109 std::string Code = "#define INDEX_MAC 1";
110 auto Index = std::make_shared<Indexer>();
111 IndexingOptions Opts;
112 Opts.IndexMacrosInPreprocessor = true;
113 tooling::runToolOnCode(new IndexAction(Index, Opts), Code);
114 EXPECT_THAT(Index->Symbols, Contains(QName("INDEX_MAC")));
115
116 Opts.IndexMacrosInPreprocessor = false;
117 Index->Symbols.clear();
118 tooling::runToolOnCode(new IndexAction(Index, Opts), Code);
119 EXPECT_THAT(Index->Symbols, UnorderedElementsAre());
120}
121
Kadir Cetinkaya0468fc02019-02-11 13:02:21 +0000122TEST(IndexTest, IndexParametersInDecls) {
123 std::string Code = "void foo(int bar);";
124 auto Index = std::make_shared<Indexer>();
125 IndexingOptions Opts;
126 Opts.IndexFunctionLocals = true;
127 Opts.IndexParametersInDeclarations = true;
128 tooling::runToolOnCode(new IndexAction(Index, Opts), Code);
129 EXPECT_THAT(Index->Symbols, Contains(QName("bar")));
130
131 Opts.IndexParametersInDeclarations = false;
132 Index->Symbols.clear();
133 tooling::runToolOnCode(new IndexAction(Index, Opts), Code);
134 EXPECT_THAT(Index->Symbols, Not(Contains(QName("bar"))));
135}
136
Eric Liu4d221722018-09-18 08:51:08 +0000137} // namespace
138} // namespace index
139} // namespace clang