[SourceKit] Compute code completion type relation when wrapping a ContextFreeCodeCompletionResult in a CodeCompletionResult

[CodeCompletion] Make ExpectedTypeContext a class with explicit getters/setters

This simplifies debugging because you can break when the possible types are set and you can also search for references to `setPossibleType` to figure out where the expected types are being set.
This commit is contained in:
Alex Hoppen
2022-01-14 16:27:31 +01:00
parent 50eafca5bf
commit 6bc0de94a2
13 changed files with 460 additions and 280 deletions

View File

@@ -93,30 +93,6 @@ std::vector<Completion *> SourceKit::CodeCompletion::extendCompletions(
if (info.completionContext->typeContextKind ==
TypeContextKind::Required &&
result->getKind() == CodeCompletionResultKind::Declaration) {
// FIXME: because other-module results are cached, they will not be
// given a type-relation of invalid. As a hack, we look at the text of
// the result type and look for 'Void'.
bool isVoid = false;
auto chunks = result->getCompletionString()->getChunks();
for (auto i = chunks.begin(), e = chunks.end(); i != e; ++i) {
using ChunkKind = ide::CodeCompletionString::Chunk::ChunkKind;
bool isVoid = false;
if (i->is(ChunkKind::TypeAnnotation)) {
isVoid = i->getText() == "Void";
break;
} else if (i->is(ChunkKind::TypeAnnotationBegin)) {
auto n = i + 1, t = i + 2;
isVoid =
// i+1 has text 'Void'.
n != e && n->hasText() && n->getText() == "Void" &&
// i+2 terminates the group.
(t == e || t->endsPreviousNestedGroup(i->getNestingLevel()));
break;
}
}
if (isVoid)
builder.setExpectedTypeRelation(
CodeCompletionResultTypeRelation::Invalid);
}
}
@@ -158,12 +134,13 @@ bool SourceKit::CodeCompletion::addCustomCompletions(
new (sink.allocator) ContextFreeCodeCompletionResult(
CodeCompletionResultKind::Pattern, completionString,
CodeCompletionOperatorKind::None, /*BriefDocComment=*/"",
CodeCompletionResultType::unknown(),
ContextFreeNotRecommendedReason::None,
CodeCompletionDiagnosticSeverity::None, /*DiagnosticMessage=*/"");
auto *swiftResult = new (sink.allocator) CodeCompletion::SwiftResult(
*contextFreeResult, SemanticContextKind::Local,
CodeCompletionFlairBit::ExpressionSpecific,
/*NumBytesToErase=*/0, CodeCompletionResultTypeRelation::Unknown,
/*NumBytesToErase=*/0, /*TypeContext=*/nullptr, /*DC=*/nullptr,
ContextualNotRecommendedReason::None,
CodeCompletionDiagnosticSeverity::None, /*DiagnosticMessage=*/"");
@@ -1138,7 +1115,6 @@ bool LimitedResultView::walk(CodeCompletionView::Walker &walker) const {
CompletionBuilder::CompletionBuilder(CompletionSink &sink,
const SwiftResult &base)
: sink(sink), base(base) {
typeRelation = base.getExpectedTypeRelation();
semanticContext = base.getSemanticContext();
flair = base.getFlair();
completionString =
@@ -1194,15 +1170,12 @@ Completion *CompletionBuilder::finish() {
contextFreeBase.getModuleName(),
contextFreeBase.getBriefDocComment(),
contextFreeBase.getAssociatedUSRs(),
contextFreeBase.getResultType(),
contextFreeBase.getNotRecommendedReason(),
contextFreeBase.getDiagnosticSeverity(),
contextFreeBase.getDiagnosticMessage());
newBase = new (sink.allocator) SwiftResult(
*contextFreeResult, semanticContext, flair, base.getNumBytesToErase(),
typeRelation, base.getContextualNotRecommendedReason(),
base.getContextualDiagnosticSeverity(),
base.getContextualDiagnosticMessage());
newBase = base.withContextFreeResultSemanticContextAndFlair(
*contextFreeResult, semanticContext, flair, sink.swiftSink);
llvm::raw_svector_ostream OSS(nameStorage);
ide::printCodeCompletionResultFilterName(*newBase, OSS);