brintos

brintos / llvm-project-archived public Read only

0
0
Text · 8.2 KiB · de5f533 Raw
242 lines · cpp
1//===-- CodeCompletionStringsTests.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 9#include "CodeCompletionStrings.h"10#include "TestTU.h"11#include "clang/Sema/CodeCompleteConsumer.h"12#include "gmock/gmock.h"13#include "gtest/gtest.h"14 15namespace clang {16namespace clangd {17namespace {18 19class CompletionStringTest : public ::testing::Test {20public:21  CompletionStringTest()22      : Allocator(std::make_shared<clang::GlobalCodeCompletionAllocator>()),23        CCTUInfo(Allocator), Builder(*Allocator, CCTUInfo) {}24 25protected:26  void computeSignature(const CodeCompletionString &CCS,27                        CodeCompletionResult::ResultKind ResultKind =28                            CodeCompletionResult::ResultKind::RK_Declaration,29                        bool IncludeFunctionArguments = true) {30    Signature.clear();31    Snippet.clear();32    getSignature(CCS, &Signature, &Snippet, ResultKind,33                 /*CursorKind=*/CXCursorKind::CXCursor_NotImplemented,34                 /*IncludeFunctionArguments=*/IncludeFunctionArguments,35                 /*RequiredQualifiers=*/nullptr);36  }37 38  std::shared_ptr<clang::GlobalCodeCompletionAllocator> Allocator;39  CodeCompletionTUInfo CCTUInfo;40  CodeCompletionBuilder Builder;41  std::string Signature;42  std::string Snippet;43};44 45TEST_F(CompletionStringTest, ReturnType) {46  Builder.AddResultTypeChunk("result");47  Builder.AddResultTypeChunk("redundant result no no");48  EXPECT_EQ(getReturnType(*Builder.TakeString()), "result");49}50 51TEST_F(CompletionStringTest, Documentation) {52  Builder.addBriefComment("This is ignored");53  EXPECT_EQ(formatDocumentation(*Builder.TakeString(), "Is this brief?"),54            "Is this brief?");55}56 57TEST_F(CompletionStringTest, DocumentationWithAnnotation) {58  Builder.addBriefComment("This is ignored");59  Builder.AddAnnotation("Ano");60  EXPECT_EQ(formatDocumentation(*Builder.TakeString(), "Is this brief?"),61            "Annotation: Ano\n\nIs this brief?");62}63 64TEST_F(CompletionStringTest, GetDeclCommentBadUTF8) {65  // <ff> is not a valid byte here, should be replaced by encoded <U+FFFD>.66  auto TU = TestTU::withCode("/*x\xffy*/ struct X;");67  auto AST = TU.build();68  EXPECT_EQ("x\xef\xbf\xbdy",69            getDeclComment(AST.getASTContext(), findDecl(AST, "X")));70}71 72TEST_F(CompletionStringTest, MultipleAnnotations) {73  Builder.AddAnnotation("Ano1");74  Builder.AddAnnotation("Ano2");75  Builder.AddAnnotation("Ano3");76 77  EXPECT_EQ(formatDocumentation(*Builder.TakeString(), ""),78            "Annotations: Ano1 Ano2 Ano3\n");79}80 81TEST_F(CompletionStringTest, EmptySignature) {82  Builder.AddTypedTextChunk("X");83  Builder.AddResultTypeChunk("result no no");84  computeSignature(*Builder.TakeString());85  EXPECT_EQ(Signature, "");86  EXPECT_EQ(Snippet, "");87}88 89TEST_F(CompletionStringTest, Function) {90  Builder.AddResultTypeChunk("result no no");91  Builder.addBriefComment("This comment is ignored");92  Builder.AddTypedTextChunk("Foo");93  Builder.AddChunk(CodeCompletionString::CK_LeftParen);94  Builder.AddPlaceholderChunk("p1");95  Builder.AddChunk(CodeCompletionString::CK_Comma);96  Builder.AddPlaceholderChunk("p2");97  Builder.AddChunk(CodeCompletionString::CK_RightParen);98 99  auto *CCS = Builder.TakeString();100  computeSignature(*CCS);101  EXPECT_EQ(Signature, "(p1, p2)");102  EXPECT_EQ(Snippet, "(${1:p1}, ${2:p2})");103  EXPECT_EQ(formatDocumentation(*CCS, "Foo's comment"), "Foo's comment");104}105 106TEST_F(CompletionStringTest, FunctionWithDefaultParams) {107  // return_type foo(p1, p2 = 0, p3 = 0)108  Builder.AddChunk(CodeCompletionString::CK_Comma);109  Builder.AddTypedTextChunk("p3 = 0");110  auto *DefaultParam2 = Builder.TakeString();111 112  Builder.AddChunk(CodeCompletionString::CK_Comma);113  Builder.AddTypedTextChunk("p2 = 0");114  Builder.AddOptionalChunk(DefaultParam2);115  auto *DefaultParam1 = Builder.TakeString();116 117  Builder.AddResultTypeChunk("return_type");118  Builder.AddTypedTextChunk("Foo");119  Builder.AddChunk(CodeCompletionString::CK_LeftParen);120  Builder.AddPlaceholderChunk("p1");121  Builder.AddOptionalChunk(DefaultParam1);122  Builder.AddChunk(CodeCompletionString::CK_RightParen);123 124  auto *CCS = Builder.TakeString();125  computeSignature(*CCS);126  EXPECT_EQ(Signature, "(p1, p2 = 0, p3 = 0)");127  EXPECT_EQ(Snippet, "(${1:p1})");128}129 130TEST_F(CompletionStringTest, EscapeSnippet) {131  Builder.AddTypedTextChunk("Foo");132  Builder.AddChunk(CodeCompletionString::CK_LeftParen);133  Builder.AddPlaceholderChunk("$p}1\\");134  Builder.AddChunk(CodeCompletionString::CK_RightParen);135 136  computeSignature(*Builder.TakeString());137  EXPECT_EQ(Signature, "($p}1\\)");138  EXPECT_EQ(Snippet, "(${1:\\$p\\}1\\\\})");139}140 141TEST_F(CompletionStringTest, SnippetsInPatterns) {142  auto MakeCCS = [this]() -> const CodeCompletionString & {143    CodeCompletionBuilder Builder(*Allocator, CCTUInfo);144    Builder.AddTypedTextChunk("namespace");145    Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);146    Builder.AddPlaceholderChunk("name");147    Builder.AddChunk(CodeCompletionString::CK_Equal);148    Builder.AddPlaceholderChunk("target");149    Builder.AddChunk(CodeCompletionString::CK_SemiColon);150    return *Builder.TakeString();151  };152  computeSignature(MakeCCS());153  EXPECT_EQ(Snippet, " ${1:name} = ${2:target};");154 155  // When completing a pattern, the last placeholder holds the cursor position.156  computeSignature(MakeCCS(),157                   /*ResultKind=*/CodeCompletionResult::ResultKind::RK_Pattern);158  EXPECT_EQ(Snippet, " ${1:name} = $0;");159}160 161TEST_F(CompletionStringTest, DropFunctionArguments) {162  Builder.AddTypedTextChunk("foo");163  Builder.AddChunk(CodeCompletionString::CK_LeftAngle);164  Builder.AddPlaceholderChunk("typename T");165  Builder.AddChunk(CodeCompletionString::CK_Comma);166  Builder.AddPlaceholderChunk("int U");167  Builder.AddChunk(CodeCompletionString::CK_RightAngle);168  Builder.AddChunk(CodeCompletionString::CK_LeftParen);169  Builder.AddPlaceholderChunk("arg1");170  Builder.AddChunk(CodeCompletionString::CK_Comma);171  Builder.AddPlaceholderChunk("arg2");172  Builder.AddChunk(CodeCompletionString::CK_RightParen);173 174  computeSignature(175      *Builder.TakeString(),176      /*ResultKind=*/CodeCompletionResult::ResultKind::RK_Declaration,177      /*IncludeFunctionArguments=*/false);178  // Arguments dropped from snippet, kept in signature.179  EXPECT_EQ(Signature, "<typename T, int U>(arg1, arg2)");180  EXPECT_EQ(Snippet, "<${1:typename T}, ${2:int U}>");181}182 183TEST_F(CompletionStringTest, IgnoreInformativeQualifier) {184  Builder.AddTypedTextChunk("X");185  Builder.AddInformativeChunk("info ok");186  Builder.AddInformativeChunk("info no no::");187  computeSignature(*Builder.TakeString());188  EXPECT_EQ(Signature, "info ok");189  EXPECT_EQ(Snippet, "");190}191 192TEST_F(CompletionStringTest, ObjectiveCMethodNoArguments) {193  Builder.AddResultTypeChunk("void");194  Builder.AddTypedTextChunk("methodName");195 196  auto *CCS = Builder.TakeString();197  computeSignature(*CCS);198  EXPECT_EQ(Signature, "");199  EXPECT_EQ(Snippet, "");200}201 202TEST_F(CompletionStringTest, ObjectiveCMethodOneArgument) {203  Builder.AddResultTypeChunk("void");204  Builder.AddTypedTextChunk("methodWithArg:");205  Builder.AddPlaceholderChunk("(type)");206 207  auto *CCS = Builder.TakeString();208  computeSignature(*CCS);209  EXPECT_EQ(Signature, "(type)");210  EXPECT_EQ(Snippet, "${1:(type)}");211}212 213TEST_F(CompletionStringTest, ObjectiveCMethodTwoArgumentsFromBeginning) {214  Builder.AddResultTypeChunk("int");215  Builder.AddTypedTextChunk("withFoo:");216  Builder.AddPlaceholderChunk("(type)");217  Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);218  Builder.AddTypedTextChunk("bar:");219  Builder.AddPlaceholderChunk("(type2)");220 221  auto *CCS = Builder.TakeString();222  computeSignature(*CCS);223  EXPECT_EQ(Signature, "(type) bar:(type2)");224  EXPECT_EQ(Snippet, "${1:(type)} bar:${2:(type2)}");225}226 227TEST_F(CompletionStringTest, ObjectiveCMethodTwoArgumentsFromMiddle) {228  Builder.AddResultTypeChunk("int");229  Builder.AddInformativeChunk("withFoo:");230  Builder.AddTypedTextChunk("bar:");231  Builder.AddPlaceholderChunk("(type2)");232 233  auto *CCS = Builder.TakeString();234  computeSignature(*CCS);235  EXPECT_EQ(Signature, "(type2)");236  EXPECT_EQ(Snippet, "${1:(type2)}");237}238 239} // namespace240} // namespace clangd241} // namespace clang242