15#include "clang/AST/DeclBase.h"
16#include "llvm/Testing/Support/Error.h"
17#include "gmock/gmock.h"
18#include "gtest/gtest.h"
25TEST(InsertionPointTests, Generic) {
26 Annotations Code(R
"cpp(
31 $c^int c1; // trailing comment
38 [&](llvm::StringLiteral S) -> std::function<
bool(
const Decl *)> {
39 return [S](
const Decl *D) {
40 if (
const auto *ND = llvm::dyn_cast<NamedDecl>(D))
41 return llvm::StringRef(ND->getNameAsString()).starts_with(S);
47 auto &NS = cast<NamespaceDecl>(
findDecl(
AST,
"ns"));
50 auto Point = [&](llvm::StringLiteral Prefix,
Anchor::Dir Direction) {
65 auto Chain = [&](llvm::StringLiteral P1, llvm::StringLiteral P2) {
70 EXPECT_EQ(Chain(
"a",
"b"), Code.point(
"a"));
71 EXPECT_EQ(Chain(
"b",
"a"), Code.point(
"b"));
72 EXPECT_EQ(Chain(
"no_match",
"a"), Code.point(
"a"));
76 ASSERT_THAT_EXPECTED(Edit, llvm::Succeeded());
77 EXPECT_EQ(
offsetToPosition(Code.code(), Edit->getOffset()), Code.point(
"b"));
78 EXPECT_EQ(Edit->getReplacementText(),
"foo;");
81 ASSERT_THAT_EXPECTED(Edit, llvm::Succeeded());
89TEST(InsertionPointTests, CXX) {
90 Annotations Code(R
"cpp(
93 $Method^void pubMethod();
98 $method^void privMethod();
99 template <typename T> void privTemplateMethod();
104 const CXXRecordDecl &
C = cast<CXXRecordDecl>(
findDecl(
AST,
"C"));
106 auto IsMethod = [](
const Decl *D) {
return llvm::isa<CXXMethodDecl>(D); };
107 auto Any = [](
const Decl *D) {
return true; };
110 auto Point = [&](Anchor
A, AccessSpecifier Protection) {
114 EXPECT_EQ(Point({IsMethod,
Anchor::Above}, AS_public), Code.point(
"Method"));
115 EXPECT_EQ(Point({IsMethod,
Anchor::Below}, AS_public), Code.point(
"Field"));
116 EXPECT_EQ(Point({Any,
Anchor::Above}, AS_public), Code.point(
"Method"));
117 EXPECT_EQ(Point({Any,
Anchor::Below}, AS_public), Code.point(
"private"));
118 EXPECT_EQ(Point({IsMethod,
Anchor::Above}, AS_private), Code.point(
"method"));
119 EXPECT_EQ(Point({IsMethod,
Anchor::Below}, AS_private), Code.point(
"end"));
120 EXPECT_EQ(Point({Any,
Anchor::Above}, AS_private), Code.point(
"field"));
121 EXPECT_EQ(Point({Any,
Anchor::Below}, AS_private), Code.point(
"end"));
122 EXPECT_EQ(Point({IsMethod,
Anchor::Above}, AS_protected), Position{});
123 EXPECT_EQ(Point({IsMethod,
Anchor::Below}, AS_protected), Position{});
124 EXPECT_EQ(Point({Any,
Anchor::Above}, AS_protected), Position{});
125 EXPECT_EQ(Point({Any,
Anchor::Below}, AS_protected), Position{});
129 ASSERT_THAT_EXPECTED(Edit, llvm::Succeeded());
131 Code.point(
"private"));
134 ASSERT_THAT_EXPECTED(Edit, llvm::Succeeded());
139 ASSERT_THAT_EXPECTED(Edit, llvm::Succeeded());
142 EXPECT_EQ(Edit->getReplacementText(),
"protected:\nx");
146 if (arg.getReplacementText() !=
Text) {
147 *result_listener <<
"replacement is " << arg.getReplacementText().str();
153TEST(InsertionPointTests, CXXAccessProtection) {
156 const CXXRecordDecl &S = cast<CXXRecordDecl>(
findDecl(
AST,
"S"));
157 ASSERT_THAT_EXPECTED(
insertDecl(
"x", S, {}, AS_public),
159 ASSERT_THAT_EXPECTED(
insertDecl(
"x", S, {}, AS_private),
160 HasValue(replacementText(
"private:\nx")));
164 const CXXRecordDecl &
T = cast<CXXRecordDecl>(
findDecl(
AST,
"T"));
165 ASSERT_THAT_EXPECTED(
insertDecl(
"x", T, {}, AS_public),
166 HasValue(replacementText(
"public:\nx")));
167 ASSERT_THAT_EXPECTED(
insertDecl(
"x", T, {}, AS_private),
172 const CXXRecordDecl &U = cast<CXXRecordDecl>(
findDecl(
AST,
"U"));
173 ASSERT_THAT_EXPECTED(
insertDecl(
"x", U, {}, AS_public),
175 ASSERT_THAT_EXPECTED(
insertDecl(
"x", U, {}, AS_private),
180TEST(InsertionPointTests, ObjC) {
181 Annotations Code(R
"objc(
190 TU.Filename =
"TestTU.m";
191 auto AST = TU.build();
194 cast<ObjCImplementationDecl>(
findDecl(
AST, [&](
const NamedDecl &D) {
195 return llvm::isa<ObjCImplementationDecl>(D);
197 auto &Iface = *Impl.getClassInterface();
200 const auto &SM =
AST.getSourceManager();
202 Code.point(
"endIface"));
204 Code.point(
"endImpl"));
const FunctionDecl * Decl
const NamedDecl & findDecl(ParsedAST &AST, llvm::StringRef QName)
Position offsetToPosition(llvm::StringRef Code, size_t Offset)
Turn an offset in Code into a [line, column] pair.
OptionalMatcher< InnerMatcher > HasValue(const InnerMatcher &inner_matcher)
Position sourceLocToPosition(const SourceManager &SM, SourceLocation Loc)
Turn a SourceLocation into a [line, column] pair.
TEST(BackgroundQueueTest, Priority)
SourceLocation insertionPoint(const DeclContext &DC, llvm::ArrayRef< Anchor > Anchors)
llvm::Expected< tooling::Replacement > insertDecl(llvm::StringRef Code, const DeclContext &DC, llvm::ArrayRef< Anchor > Anchors)
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//
static TestTU withCode(llvm::StringRef Code)