[CodeCompletion] Do our best to set NotRecommended on other-module results

These results are cached, so we can't use the type-relation.  Instead we
use a small hack of checking the textual return type for "Void".  This
is obviously not ideal, but it lets us detect the most important cases.

rdar://problem/22810741
This commit is contained in:
Ben Langmuir
2016-03-30 16:34:38 -07:00
parent 379f2b9723
commit 6c2ec9a1b1
3 changed files with 62 additions and 3 deletions

View File

@@ -100,9 +100,24 @@ std::vector<Completion *> SourceKit::CodeCompletion::extendCompletions(
std::vector<Completion *> results;
for (auto *result : swiftResults) {
CompletionBuilder builder(sink, *result);
if (result->getSemanticContext() == SemanticContextKind::OtherModule)
if (result->getSemanticContext() == SemanticContextKind::OtherModule) {
builder.setModuleImportDepth(depth.lookup(result->getModuleName()));
if (info.completionContext->HasExpectedTypeRelation &&
result->getKind() == Completion::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'.
for (auto &chunk : result->getCompletionString()->getChunks()) {
using ChunkKind = ide::CodeCompletionString::Chunk::ChunkKind;
if (chunk.is(ChunkKind::TypeAnnotation) && chunk.hasText() &&
chunk.getText() == "Void") {
builder.setNotRecommended(Completion::TypeMismatch);
}
}
}
}
if (prefix) {
builder.setPrefix(prefix->getCompletionString());
builder.setSemanticContext(prefix->getSemanticContext());
@@ -1116,6 +1131,8 @@ void CompletionBuilder::getDescription(SwiftResult *result, raw_ostream &OS,
CompletionBuilder::CompletionBuilder(CompletionSink &sink, SwiftResult &base)
: sink(sink), current(base) {
isNotRecommended = current.isNotRecommended();
notRecommendedReason = current.getNotRecommendedReason();
semanticContext = current.getSemanticContext();
completionString =
const_cast<CodeCompletionString *>(current.getCompletionString());
@@ -1158,8 +1175,8 @@ Completion *CompletionBuilder::finish() {
if (current.getKind() == SwiftResult::Declaration) {
base = SwiftResult(semanticContext, current.getNumBytesToErase(),
completionString, current.getAssociatedDeclKind(),
current.getModuleName(), current.isNotRecommended(),
current.getNotRecommendedReason(),
current.getModuleName(), isNotRecommended,
notRecommendedReason,
current.getBriefDocComment(),
current.getAssociatedUSRs(),
current.getDeclKeywords());