mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
688 lines
25 KiB
C++
688 lines
25 KiB
C++
//===--- CodeCompletionResult.cpp -----------------------------------------===//
|
|
//
|
|
// This source file is part of the Swift.org open source project
|
|
//
|
|
// Copyright (c) 2022 Apple Inc. and the Swift project authors
|
|
// Licensed under Apache License v2.0 with Runtime Library Exception
|
|
//
|
|
// See https://swift.org/LICENSE.txt for license information
|
|
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "swift/IDE/CodeCompletionResult.h"
|
|
#include "CodeCompletionDiagnostics.h"
|
|
#include "swift/AST/Decl.h"
|
|
#include "swift/AST/Module.h"
|
|
#include "swift/Basic/Assertions.h"
|
|
#include "swift/IDE/CodeCompletionResultPrinter.h"
|
|
#include "swift/IDE/CodeCompletionResultSink.h"
|
|
|
|
using namespace swift;
|
|
using namespace swift::ide;
|
|
|
|
CodeCompletionMacroRoles swift::ide::getCompletionMacroRoles(const Decl *D) {
|
|
CodeCompletionMacroRoles roles;
|
|
|
|
auto *MD = dyn_cast<MacroDecl>(D);
|
|
if (!MD)
|
|
return roles;
|
|
|
|
MacroRoles macroRoles = MD->getMacroRoles();
|
|
if (macroRoles.contains(MacroRole::Expression)) {
|
|
roles |= CodeCompletionMacroRole::Expression;
|
|
}
|
|
if (macroRoles.contains(MacroRole::Declaration)) {
|
|
roles |= CodeCompletionMacroRole::Declaration;
|
|
}
|
|
if (macroRoles.contains(MacroRole::CodeItem)) {
|
|
roles |= CodeCompletionMacroRole::CodeItem;
|
|
}
|
|
if (macroRoles.contains(MacroRole::Accessor)) {
|
|
roles |= CodeCompletionMacroRole::AttachedVar;
|
|
}
|
|
if (macroRoles & MacroRoles({MacroRole::MemberAttribute, MacroRole::Member,
|
|
MacroRole::Conformance,
|
|
MacroRole::Extension,})) {
|
|
roles |= CodeCompletionMacroRole::AttachedContext;
|
|
}
|
|
if (macroRoles.contains(MacroRole::Peer)) {
|
|
roles |= CodeCompletionMacroRole::AttachedDecl;
|
|
}
|
|
if (macroRoles.contains(MacroRole::Body) ||
|
|
macroRoles.contains(MacroRole::Preamble)) {
|
|
roles |= CodeCompletionMacroRole::AttachedFunction;
|
|
}
|
|
|
|
return roles;
|
|
}
|
|
|
|
CodeCompletionMacroRoles
|
|
swift::ide::getCompletionMacroRoles(OptionSet<CustomAttributeKind> kinds) {
|
|
CodeCompletionMacroRoles roles;
|
|
if (kinds.contains(CustomAttributeKind::VarMacro)) {
|
|
roles |= CodeCompletionMacroRole::AttachedVar;
|
|
}
|
|
if (kinds.contains(CustomAttributeKind::ContextMacro)) {
|
|
roles |= CodeCompletionMacroRole::AttachedContext;
|
|
}
|
|
if (kinds.contains(CustomAttributeKind::DeclMacro)) {
|
|
roles |= CodeCompletionMacroRole::AttachedDecl;
|
|
}
|
|
if (kinds.contains(CustomAttributeKind::FunctionMacro)) {
|
|
roles |= CodeCompletionMacroRole::AttachedFunction;
|
|
}
|
|
return roles;
|
|
}
|
|
|
|
CodeCompletionMacroRoles
|
|
swift::ide::getCompletionMacroRoles(CodeCompletionFilter filter) {
|
|
CodeCompletionMacroRoles roles;
|
|
if (filter.contains(CodeCompletionFilterFlag::ExpressionMacro)) {
|
|
roles |= CodeCompletionMacroRole::Expression;
|
|
}
|
|
if (filter.contains(CodeCompletionFilterFlag::DeclarationMacro)) {
|
|
roles |= CodeCompletionMacroRole::Declaration;
|
|
}
|
|
if (filter.contains(CodeCompletionFilterFlag::CodeItemMacro)) {
|
|
roles |= CodeCompletionMacroRole::CodeItem;
|
|
}
|
|
if (filter.contains(CodeCompletionFilterFlag::AttachedVarMacro)) {
|
|
roles |= CodeCompletionMacroRole::AttachedVar;
|
|
}
|
|
if (filter.contains(CodeCompletionFilterFlag::AttachedContextMacro)) {
|
|
roles |= CodeCompletionMacroRole::AttachedContext;
|
|
}
|
|
if (filter.contains(CodeCompletionFilterFlag::AttachedDeclMacro)) {
|
|
roles |= CodeCompletionMacroRole::AttachedDecl;
|
|
}
|
|
if (filter.contains(CodeCompletionFilterFlag::AttachedFunctionMacro)) {
|
|
roles |= CodeCompletionMacroRole::AttachedFunction;
|
|
}
|
|
return roles;
|
|
}
|
|
|
|
CodeCompletionFilter
|
|
swift::ide::getCompletionFilter(CodeCompletionMacroRoles roles) {
|
|
CodeCompletionFilter filter;
|
|
if (roles.contains(CodeCompletionMacroRole::Expression)) {
|
|
filter |= CodeCompletionFilterFlag::ExpressionMacro;
|
|
}
|
|
if (roles.contains(CodeCompletionMacroRole::Declaration)) {
|
|
filter |= CodeCompletionFilterFlag::DeclarationMacro;
|
|
}
|
|
if (roles.contains(CodeCompletionMacroRole::CodeItem)) {
|
|
filter |= CodeCompletionFilterFlag::CodeItemMacro;
|
|
}
|
|
if (roles.contains(CodeCompletionMacroRole::AttachedVar)) {
|
|
filter |= CodeCompletionFilterFlag::AttachedVarMacro;
|
|
}
|
|
if (roles.contains(CodeCompletionMacroRole::AttachedContext)) {
|
|
filter |= CodeCompletionFilterFlag::AttachedContextMacro;
|
|
}
|
|
if (roles.contains(CodeCompletionMacroRole::AttachedDecl)) {
|
|
filter |= CodeCompletionFilterFlag::AttachedDeclMacro;
|
|
}
|
|
if (roles.contains(CodeCompletionMacroRole::AttachedFunction)) {
|
|
filter |= CodeCompletionFilterFlag::AttachedFunctionMacro;
|
|
}
|
|
return filter;
|
|
}
|
|
|
|
// MARK: - ContextFreeCodeCompletionResult
|
|
|
|
ContextFreeCodeCompletionResult *
|
|
ContextFreeCodeCompletionResult::createPatternOrBuiltInOperatorResult(
|
|
CodeCompletionResultSink &Sink, CodeCompletionResultKind Kind,
|
|
CodeCompletionString *CompletionString,
|
|
CodeCompletionOperatorKind KnownOperatorKind, NullTerminatedStringRef BriefDocComment,
|
|
CodeCompletionResultType ResultType,
|
|
ContextFreeNotRecommendedReason NotRecommended,
|
|
CodeCompletionDiagnosticSeverity DiagnosticSeverity,
|
|
NullTerminatedStringRef DiagnosticMessage) {
|
|
if (Sink.shouldProduceContextFreeResults()) {
|
|
ResultType = ResultType.usrBasedType(Sink.getUSRTypeArena());
|
|
}
|
|
NullTerminatedStringRef NameForDiagnostics;
|
|
if (KnownOperatorKind == CodeCompletionOperatorKind::None) {
|
|
NameForDiagnostics = "function";
|
|
} else {
|
|
NameForDiagnostics = "operator";
|
|
}
|
|
return new (Sink.getAllocator()) ContextFreeCodeCompletionResult(
|
|
Kind, /*AssociatedKind=*/0, KnownOperatorKind, /*MacroRoles=*/{},
|
|
/*IsSystem=*/false, /*HasAsyncAlternative=*/false,
|
|
CompletionString,
|
|
/*ModuleName=*/"", BriefDocComment,
|
|
/*AssociatedUSRs=*/{}, ResultType, NotRecommended, DiagnosticSeverity,
|
|
DiagnosticMessage,
|
|
getCodeCompletionResultFilterName(CompletionString, Sink.getAllocator()),
|
|
NameForDiagnostics);
|
|
}
|
|
|
|
ContextFreeCodeCompletionResult *
|
|
ContextFreeCodeCompletionResult::createKeywordResult(
|
|
CodeCompletionResultSink &Sink, CodeCompletionKeywordKind Kind,
|
|
CodeCompletionString *CompletionString,
|
|
NullTerminatedStringRef BriefDocComment,
|
|
CodeCompletionResultType ResultType) {
|
|
if (Sink.shouldProduceContextFreeResults()) {
|
|
ResultType = ResultType.usrBasedType(Sink.getUSRTypeArena());
|
|
}
|
|
return new (Sink.getAllocator()) ContextFreeCodeCompletionResult(
|
|
CodeCompletionResultKind::Keyword, static_cast<uint8_t>(Kind),
|
|
CodeCompletionOperatorKind::None, /*MacroRoles=*/{},
|
|
/*IsSystem=*/false, /*HasAsyncAlternative=*/false, CompletionString,
|
|
/*ModuleName=*/"", BriefDocComment,
|
|
/*AssociatedUSRs=*/{}, ResultType, ContextFreeNotRecommendedReason::None,
|
|
CodeCompletionDiagnosticSeverity::None, /*DiagnosticMessage=*/"",
|
|
getCodeCompletionResultFilterName(CompletionString, Sink.getAllocator()),
|
|
/*NameForDiagnostics=*/"");
|
|
}
|
|
|
|
ContextFreeCodeCompletionResult *
|
|
ContextFreeCodeCompletionResult::createLiteralResult(
|
|
CodeCompletionResultSink &Sink, CodeCompletionLiteralKind LiteralKind,
|
|
CodeCompletionString *CompletionString,
|
|
CodeCompletionResultType ResultType) {
|
|
if (Sink.shouldProduceContextFreeResults()) {
|
|
ResultType = ResultType.usrBasedType(Sink.getUSRTypeArena());
|
|
}
|
|
return new (Sink.getAllocator()) ContextFreeCodeCompletionResult(
|
|
CodeCompletionResultKind::Literal, static_cast<uint8_t>(LiteralKind),
|
|
CodeCompletionOperatorKind::None, /*MacroRoles=*/{},
|
|
/*IsSystem=*/false, /*HasAsyncAlternative=*/false,
|
|
CompletionString,
|
|
/*ModuleName=*/"",
|
|
/*BriefDocComment=*/"",
|
|
/*AssociatedUSRs=*/{}, ResultType, ContextFreeNotRecommendedReason::None,
|
|
CodeCompletionDiagnosticSeverity::None, /*DiagnosticMessage=*/"",
|
|
getCodeCompletionResultFilterName(CompletionString, Sink.getAllocator()),
|
|
/*NameForDiagnostics=*/"");
|
|
}
|
|
|
|
static NullTerminatedStringRef
|
|
getDeclNameForDiagnostics(const Decl *D, CodeCompletionResultSink &Sink) {
|
|
if (auto VD = dyn_cast<ValueDecl>(D)) {
|
|
llvm::SmallString<64> Name;
|
|
llvm::raw_svector_ostream NameOS(Name);
|
|
NameOS << "'";
|
|
llvm::SmallString<64> Scratch;
|
|
VD->getName().printPretty(NameOS);
|
|
NameOS << "'";
|
|
return NullTerminatedStringRef(NameOS.str(), Sink.getAllocator());
|
|
} else {
|
|
return "";
|
|
}
|
|
}
|
|
|
|
ContextFreeCodeCompletionResult *
|
|
ContextFreeCodeCompletionResult::createDeclResult(
|
|
CodeCompletionResultSink &Sink, CodeCompletionString *CompletionString,
|
|
const Decl *AssociatedDecl, bool HasAsyncAlternative,
|
|
NullTerminatedStringRef ModuleName, NullTerminatedStringRef BriefDocComment,
|
|
ArrayRef<NullTerminatedStringRef> AssociatedUSRs,
|
|
CodeCompletionResultType ResultType,
|
|
ContextFreeNotRecommendedReason NotRecommended,
|
|
CodeCompletionDiagnosticSeverity DiagnosticSeverity,
|
|
NullTerminatedStringRef DiagnosticMessage) {
|
|
assert(AssociatedDecl && "should have a decl");
|
|
if (Sink.shouldProduceContextFreeResults()) {
|
|
ResultType = ResultType.usrBasedType(Sink.getUSRTypeArena());
|
|
}
|
|
return new (Sink.getAllocator()) ContextFreeCodeCompletionResult(
|
|
CodeCompletionResultKind::Declaration,
|
|
static_cast<uint8_t>(getCodeCompletionDeclKind(AssociatedDecl)),
|
|
CodeCompletionOperatorKind::None, getCompletionMacroRoles(AssociatedDecl),
|
|
getDeclIsSystem(AssociatedDecl), HasAsyncAlternative,
|
|
CompletionString, ModuleName, BriefDocComment, AssociatedUSRs, ResultType,
|
|
NotRecommended, DiagnosticSeverity, DiagnosticMessage,
|
|
getCodeCompletionResultFilterName(CompletionString, Sink.getAllocator()),
|
|
/*NameForDiagnostics=*/getDeclNameForDiagnostics(AssociatedDecl, Sink));
|
|
}
|
|
|
|
CodeCompletionOperatorKind
|
|
ContextFreeCodeCompletionResult::getCodeCompletionOperatorKind(
|
|
const CodeCompletionString *str) {
|
|
StringRef name = str->getFirstTextChunk(/*includeLeadingPunctuation=*/true);
|
|
using CCOK = CodeCompletionOperatorKind;
|
|
using OpPair = std::pair<StringRef, CCOK>;
|
|
|
|
// This list must be kept in lexicographic order.
|
|
static OpPair ops[] = {
|
|
std::make_pair("!", CCOK::Bang),
|
|
std::make_pair("!=", CCOK::NotEq),
|
|
std::make_pair("!==", CCOK::NotEqEq),
|
|
std::make_pair("%", CCOK::Modulo),
|
|
std::make_pair("%=", CCOK::ModuloEq),
|
|
std::make_pair("&", CCOK::Amp),
|
|
std::make_pair("&&", CCOK::AmpAmp),
|
|
std::make_pair("&*", CCOK::AmpStar),
|
|
std::make_pair("&+", CCOK::AmpPlus),
|
|
std::make_pair("&-", CCOK::AmpMinus),
|
|
std::make_pair("&=", CCOK::AmpEq),
|
|
std::make_pair("(", CCOK::LParen),
|
|
std::make_pair("*", CCOK::Star),
|
|
std::make_pair("*=", CCOK::StarEq),
|
|
std::make_pair("+", CCOK::Plus),
|
|
std::make_pair("+=", CCOK::PlusEq),
|
|
std::make_pair("-", CCOK::Minus),
|
|
std::make_pair("-=", CCOK::MinusEq),
|
|
std::make_pair(".", CCOK::Dot),
|
|
std::make_pair("...", CCOK::DotDotDot),
|
|
std::make_pair("..<", CCOK::DotDotLess),
|
|
std::make_pair("/", CCOK::Slash),
|
|
std::make_pair("/=", CCOK::SlashEq),
|
|
std::make_pair("<", CCOK::Less),
|
|
std::make_pair("<<", CCOK::LessLess),
|
|
std::make_pair("<<=", CCOK::LessLessEq),
|
|
std::make_pair("<=", CCOK::LessEq),
|
|
std::make_pair("=", CCOK::Eq),
|
|
std::make_pair("==", CCOK::EqEq),
|
|
std::make_pair("===", CCOK::EqEqEq),
|
|
std::make_pair(">", CCOK::Greater),
|
|
std::make_pair(">=", CCOK::GreaterEq),
|
|
std::make_pair(">>", CCOK::GreaterGreater),
|
|
std::make_pair(">>=", CCOK::GreaterGreaterEq),
|
|
std::make_pair("?.", CCOK::QuestionDot),
|
|
std::make_pair("^", CCOK::Caret),
|
|
std::make_pair("^=", CCOK::CaretEq),
|
|
std::make_pair("|", CCOK::Pipe),
|
|
std::make_pair("|=", CCOK::PipeEq),
|
|
std::make_pair("||", CCOK::PipePipe),
|
|
std::make_pair("~=", CCOK::TildeEq),
|
|
};
|
|
|
|
auto I = std::lower_bound(
|
|
std::begin(ops), std::end(ops), std::make_pair(name, CCOK::None),
|
|
[](const OpPair &a, const OpPair &b) { return a.first < b.first; });
|
|
|
|
if (I == std::end(ops) || I->first != name)
|
|
return CCOK::Unknown;
|
|
return I->second;
|
|
}
|
|
|
|
CodeCompletionDeclKind
|
|
ContextFreeCodeCompletionResult::getCodeCompletionDeclKind(const Decl *D) {
|
|
switch (D->getKind()) {
|
|
case DeclKind::Import:
|
|
case DeclKind::Extension:
|
|
case DeclKind::PatternBinding:
|
|
case DeclKind::EnumCase:
|
|
case DeclKind::TopLevelCode:
|
|
case DeclKind::Missing:
|
|
case DeclKind::MissingMember:
|
|
case DeclKind::OpaqueType:
|
|
case DeclKind::BuiltinTuple:
|
|
case DeclKind::MacroExpansion:
|
|
case DeclKind::Using:
|
|
llvm_unreachable("not expecting such a declaration result");
|
|
case DeclKind::Module:
|
|
return CodeCompletionDeclKind::Module;
|
|
case DeclKind::TypeAlias:
|
|
return CodeCompletionDeclKind::TypeAlias;
|
|
case DeclKind::AssociatedType:
|
|
return CodeCompletionDeclKind::AssociatedType;
|
|
case DeclKind::GenericTypeParam:
|
|
return CodeCompletionDeclKind::GenericTypeParam;
|
|
case DeclKind::Enum:
|
|
return CodeCompletionDeclKind::Enum;
|
|
case DeclKind::Struct:
|
|
return CodeCompletionDeclKind::Struct;
|
|
case DeclKind::Class:
|
|
if (cast<ClassDecl>(D)->isAnyActor()) {
|
|
return CodeCompletionDeclKind::Actor;
|
|
} else {
|
|
return CodeCompletionDeclKind::Class;
|
|
}
|
|
case DeclKind::Protocol:
|
|
return CodeCompletionDeclKind::Protocol;
|
|
case DeclKind::Var:
|
|
case DeclKind::Param: {
|
|
auto DC = D->getDeclContext();
|
|
if (DC->isTypeContext()) {
|
|
if (cast<VarDecl>(D)->isStatic())
|
|
return CodeCompletionDeclKind::StaticVar;
|
|
else
|
|
return CodeCompletionDeclKind::InstanceVar;
|
|
}
|
|
if (DC->isLocalContext())
|
|
return CodeCompletionDeclKind::LocalVar;
|
|
return CodeCompletionDeclKind::GlobalVar;
|
|
}
|
|
case DeclKind::Constructor:
|
|
return CodeCompletionDeclKind::Constructor;
|
|
case DeclKind::Destructor:
|
|
return CodeCompletionDeclKind::Destructor;
|
|
case DeclKind::Accessor:
|
|
case DeclKind::Func: {
|
|
auto DC = D->getDeclContext();
|
|
auto FD = cast<FuncDecl>(D);
|
|
if (DC->isTypeContext()) {
|
|
if (FD->isStatic())
|
|
return CodeCompletionDeclKind::StaticMethod;
|
|
return CodeCompletionDeclKind::InstanceMethod;
|
|
}
|
|
if (FD->isOperator()) {
|
|
if (auto op = FD->getOperatorDecl()) {
|
|
switch (op->getKind()) {
|
|
case DeclKind::PrefixOperator:
|
|
return CodeCompletionDeclKind::PrefixOperatorFunction;
|
|
case DeclKind::PostfixOperator:
|
|
return CodeCompletionDeclKind::PostfixOperatorFunction;
|
|
case DeclKind::InfixOperator:
|
|
return CodeCompletionDeclKind::InfixOperatorFunction;
|
|
default:
|
|
llvm_unreachable("unexpected operator kind");
|
|
}
|
|
} else {
|
|
return CodeCompletionDeclKind::InfixOperatorFunction;
|
|
}
|
|
}
|
|
return CodeCompletionDeclKind::FreeFunction;
|
|
}
|
|
case DeclKind::InfixOperator:
|
|
return CodeCompletionDeclKind::InfixOperatorFunction;
|
|
case DeclKind::PrefixOperator:
|
|
return CodeCompletionDeclKind::PrefixOperatorFunction;
|
|
case DeclKind::PostfixOperator:
|
|
return CodeCompletionDeclKind::PostfixOperatorFunction;
|
|
case DeclKind::PrecedenceGroup:
|
|
return CodeCompletionDeclKind::PrecedenceGroup;
|
|
case DeclKind::EnumElement:
|
|
return CodeCompletionDeclKind::EnumElement;
|
|
case DeclKind::Subscript:
|
|
return CodeCompletionDeclKind::Subscript;
|
|
case DeclKind::Macro:
|
|
return CodeCompletionDeclKind::Macro;
|
|
}
|
|
llvm_unreachable("invalid DeclKind");
|
|
}
|
|
|
|
bool ContextFreeCodeCompletionResult::getDeclIsSystem(const Decl *D) {
|
|
return D->getModuleContext()->isNonUserModule();
|
|
}
|
|
|
|
ContextualNotRecommendedReason
|
|
ContextFreeCodeCompletionResult::calculateContextualNotRecommendedReason(
|
|
ContextualNotRecommendedReason explicitReason,
|
|
bool canCurrDeclContextHandleAsync) const {
|
|
if (explicitReason != ContextualNotRecommendedReason::None) {
|
|
return explicitReason;
|
|
}
|
|
if (HasAsyncAlternative && canCurrDeclContextHandleAsync) {
|
|
return ContextualNotRecommendedReason::
|
|
NonAsyncAlternativeUsedInAsyncContext;
|
|
}
|
|
return ContextualNotRecommendedReason::None;
|
|
}
|
|
|
|
CodeCompletionResultTypeRelation
|
|
ContextFreeCodeCompletionResult::calculateContextualTypeRelation(
|
|
const DeclContext *dc, const ExpectedTypeContext *typeContext,
|
|
const USRBasedTypeContext *usrTypeContext) const {
|
|
CodeCompletionResultTypeRelation typeRelation =
|
|
getResultType().calculateTypeRelation(typeContext, dc, usrTypeContext);
|
|
if (typeRelation >= CodeCompletionResultTypeRelation::Convertible ||
|
|
!typeContext)
|
|
return typeRelation;
|
|
|
|
CodeCompletionMacroRoles expectedRoles =
|
|
getCompletionMacroRoles(typeContext->getExpectedCustomAttributeKinds());
|
|
if (MacroRoles & expectedRoles)
|
|
return CodeCompletionResultTypeRelation::Convertible;
|
|
return typeRelation;
|
|
}
|
|
|
|
// MARK: - CodeCompletionResult
|
|
|
|
CodeCompletionResult *
|
|
CodeCompletionResult::withFlair(CodeCompletionFlair NewFlair,
|
|
CodeCompletionResultSink &Sink) const {
|
|
return new (*Sink.Allocator)
|
|
CodeCompletionResult(ContextFree, SemanticContext, NewFlair,
|
|
NumBytesToErase, TypeDistance, NotRecommended);
|
|
}
|
|
|
|
CodeCompletionResult *
|
|
CodeCompletionResult::withContextFreeResultSemanticContextAndFlair(
|
|
const ContextFreeCodeCompletionResult &NewContextFree,
|
|
SemanticContextKind NewSemanticContext, CodeCompletionFlair NewFlair,
|
|
CodeCompletionResultSink &Sink) const {
|
|
return new (*Sink.Allocator)
|
|
CodeCompletionResult(NewContextFree, NewSemanticContext, NewFlair,
|
|
NumBytesToErase, TypeDistance, NotRecommended);
|
|
}
|
|
|
|
std::pair<CodeCompletionDiagnosticSeverity, NullTerminatedStringRef>
|
|
CodeCompletionResult::getContextualDiagnosticSeverityAndMessage(
|
|
SmallVectorImpl<char> &Scratch, const ASTContext &Ctx) const {
|
|
llvm::raw_svector_ostream Out(Scratch);
|
|
CodeCompletionDiagnosticSeverity Severity;
|
|
getContextualCompletionDiagnostics(
|
|
NotRecommended, ContextFree.getNameForDiagnostics(), Severity, Out, Ctx);
|
|
Out << '\0';
|
|
NullTerminatedStringRef Message(Out.str().data(), Out.str().size() - 1);
|
|
return std::make_pair(Severity, Message);
|
|
}
|
|
|
|
void CodeCompletionResult::printPrefix(raw_ostream &OS) const {
|
|
llvm::SmallString<64> Prefix;
|
|
switch (getKind()) {
|
|
case CodeCompletionResultKind::Declaration:
|
|
Prefix.append("Decl");
|
|
switch (getAssociatedDeclKind()) {
|
|
case CodeCompletionDeclKind::Class:
|
|
Prefix.append("[Class]");
|
|
break;
|
|
case CodeCompletionDeclKind::Actor:
|
|
Prefix.append("[Actor]");
|
|
break;
|
|
case CodeCompletionDeclKind::Struct:
|
|
Prefix.append("[Struct]");
|
|
break;
|
|
case CodeCompletionDeclKind::Enum:
|
|
Prefix.append("[Enum]");
|
|
break;
|
|
case CodeCompletionDeclKind::EnumElement:
|
|
Prefix.append("[EnumElement]");
|
|
break;
|
|
case CodeCompletionDeclKind::Protocol:
|
|
Prefix.append("[Protocol]");
|
|
break;
|
|
case CodeCompletionDeclKind::TypeAlias:
|
|
Prefix.append("[TypeAlias]");
|
|
break;
|
|
case CodeCompletionDeclKind::AssociatedType:
|
|
Prefix.append("[AssociatedType]");
|
|
break;
|
|
case CodeCompletionDeclKind::GenericTypeParam:
|
|
Prefix.append("[GenericTypeParam]");
|
|
break;
|
|
case CodeCompletionDeclKind::Constructor:
|
|
Prefix.append("[Constructor]");
|
|
break;
|
|
case CodeCompletionDeclKind::Destructor:
|
|
Prefix.append("[Destructor]");
|
|
break;
|
|
case CodeCompletionDeclKind::Subscript:
|
|
Prefix.append("[Subscript]");
|
|
break;
|
|
case CodeCompletionDeclKind::StaticMethod:
|
|
Prefix.append("[StaticMethod]");
|
|
break;
|
|
case CodeCompletionDeclKind::InstanceMethod:
|
|
Prefix.append("[InstanceMethod]");
|
|
break;
|
|
case CodeCompletionDeclKind::PrefixOperatorFunction:
|
|
Prefix.append("[PrefixOperatorFunction]");
|
|
break;
|
|
case CodeCompletionDeclKind::PostfixOperatorFunction:
|
|
Prefix.append("[PostfixOperatorFunction]");
|
|
break;
|
|
case CodeCompletionDeclKind::InfixOperatorFunction:
|
|
Prefix.append("[InfixOperatorFunction]");
|
|
break;
|
|
case CodeCompletionDeclKind::FreeFunction:
|
|
Prefix.append("[FreeFunction]");
|
|
break;
|
|
case CodeCompletionDeclKind::StaticVar:
|
|
Prefix.append("[StaticVar]");
|
|
break;
|
|
case CodeCompletionDeclKind::InstanceVar:
|
|
Prefix.append("[InstanceVar]");
|
|
break;
|
|
case CodeCompletionDeclKind::LocalVar:
|
|
Prefix.append("[LocalVar]");
|
|
break;
|
|
case CodeCompletionDeclKind::GlobalVar:
|
|
Prefix.append("[GlobalVar]");
|
|
break;
|
|
case CodeCompletionDeclKind::Module:
|
|
Prefix.append("[Module]");
|
|
break;
|
|
case CodeCompletionDeclKind::PrecedenceGroup:
|
|
Prefix.append("[PrecedenceGroup]");
|
|
break;
|
|
case CodeCompletionDeclKind::Macro:
|
|
Prefix.append("[Macro]");
|
|
break;
|
|
}
|
|
break;
|
|
case CodeCompletionResultKind::Keyword:
|
|
Prefix.append("Keyword");
|
|
switch (getKeywordKind()) {
|
|
case CodeCompletionKeywordKind::None:
|
|
break;
|
|
#define KEYWORD(X) \
|
|
case CodeCompletionKeywordKind::kw_##X: \
|
|
Prefix.append("[" #X "]"); \
|
|
break;
|
|
#define POUND_KEYWORD(X) \
|
|
case CodeCompletionKeywordKind::pound_##X: \
|
|
Prefix.append("[#" #X "]"); \
|
|
break;
|
|
#include "swift/AST/TokenKinds.def"
|
|
}
|
|
break;
|
|
case CodeCompletionResultKind::Pattern:
|
|
Prefix.append("Pattern");
|
|
break;
|
|
case CodeCompletionResultKind::Literal:
|
|
Prefix.append("Literal");
|
|
switch (getLiteralKind()) {
|
|
case CodeCompletionLiteralKind::ArrayLiteral:
|
|
Prefix.append("[Array]");
|
|
break;
|
|
case CodeCompletionLiteralKind::BooleanLiteral:
|
|
Prefix.append("[Boolean]");
|
|
break;
|
|
case CodeCompletionLiteralKind::ColorLiteral:
|
|
Prefix.append("[_Color]");
|
|
break;
|
|
case CodeCompletionLiteralKind::ImageLiteral:
|
|
Prefix.append("[_Image]");
|
|
break;
|
|
case CodeCompletionLiteralKind::DictionaryLiteral:
|
|
Prefix.append("[Dictionary]");
|
|
break;
|
|
case CodeCompletionLiteralKind::IntegerLiteral:
|
|
Prefix.append("[Integer]");
|
|
break;
|
|
case CodeCompletionLiteralKind::NilLiteral:
|
|
Prefix.append("[Nil]");
|
|
break;
|
|
case CodeCompletionLiteralKind::StringLiteral:
|
|
Prefix.append("[String]");
|
|
break;
|
|
case CodeCompletionLiteralKind::Tuple:
|
|
Prefix.append("[Tuple]");
|
|
break;
|
|
}
|
|
break;
|
|
case CodeCompletionResultKind::BuiltinOperator:
|
|
Prefix.append("BuiltinOperator");
|
|
break;
|
|
}
|
|
Prefix.append("/");
|
|
switch (getSemanticContext()) {
|
|
case SemanticContextKind::None:
|
|
Prefix.append("None");
|
|
break;
|
|
case SemanticContextKind::Local:
|
|
Prefix.append("Local");
|
|
break;
|
|
case SemanticContextKind::CurrentNominal:
|
|
Prefix.append("CurrNominal");
|
|
break;
|
|
case SemanticContextKind::Super:
|
|
Prefix.append("Super");
|
|
break;
|
|
case SemanticContextKind::OutsideNominal:
|
|
Prefix.append("OutNominal");
|
|
break;
|
|
case SemanticContextKind::CurrentModule:
|
|
Prefix.append("CurrModule");
|
|
break;
|
|
case SemanticContextKind::OtherModule:
|
|
Prefix.append("OtherModule");
|
|
if (!getModuleName().empty())
|
|
Prefix.append((Twine("[") + StringRef(getModuleName()) + "]").str());
|
|
break;
|
|
}
|
|
if (getFlair().toRaw()) {
|
|
Prefix.append("/Flair[");
|
|
bool isFirstFlair = true;
|
|
#define PRINT_FLAIR(KIND, NAME) \
|
|
if (getFlair().contains(CodeCompletionFlairBit::KIND)) { \
|
|
if (isFirstFlair) { \
|
|
isFirstFlair = false; \
|
|
} else { \
|
|
Prefix.append(","); \
|
|
} \
|
|
Prefix.append(NAME); \
|
|
}
|
|
PRINT_FLAIR(ExpressionSpecific, "ExprSpecific");
|
|
PRINT_FLAIR(SuperChain, "SuperChain");
|
|
PRINT_FLAIR(ArgumentLabels, "ArgLabels");
|
|
PRINT_FLAIR(CommonKeywordAtCurrentPosition, "CommonKeyword")
|
|
PRINT_FLAIR(RareKeywordAtCurrentPosition, "RareKeyword")
|
|
PRINT_FLAIR(RareTypeAtCurrentPosition, "RareType")
|
|
PRINT_FLAIR(ExpressionAtNonScriptOrMainFileScope, "ExprAtFileScope")
|
|
Prefix.append("]");
|
|
}
|
|
if (isNotRecommended())
|
|
Prefix.append("/NotRecommended");
|
|
if (isSystem())
|
|
Prefix.append("/IsSystem");
|
|
if (NumBytesToErase != 0) {
|
|
Prefix.append("/Erase[");
|
|
Prefix.append(Twine(NumBytesToErase).str());
|
|
Prefix.append("]");
|
|
}
|
|
switch (getExpectedTypeRelation()) {
|
|
case CodeCompletionResultTypeRelation::Invalid:
|
|
Prefix.append("/TypeRelation[Invalid]");
|
|
break;
|
|
case CodeCompletionResultTypeRelation::Convertible:
|
|
Prefix.append("/TypeRelation[Convertible]");
|
|
break;
|
|
case CodeCompletionResultTypeRelation::NotApplicable:
|
|
case CodeCompletionResultTypeRelation::Unknown:
|
|
case CodeCompletionResultTypeRelation::Unrelated:
|
|
break;
|
|
}
|
|
|
|
Prefix.append(": ");
|
|
while (Prefix.size() < 36) {
|
|
Prefix.append(" ");
|
|
}
|
|
OS << Prefix;
|
|
}
|
|
|
|
void CodeCompletionResult::dump() const {
|
|
printPrefix(llvm::errs());
|
|
getCompletionString()->print(llvm::errs());
|
|
llvm::errs() << "\n";
|
|
}
|