mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
[CodeCompletion] Introduce "Flair" in code completion
To describe fine grained priorities. Introduce 'CodeCompletionFlair' that is a set of more descriptive flags for prioritizing completion items. This aims to replace ' SemanticContextKind::ExpressionSpecific' which was a "catch all" prioritization flag.
This commit is contained in:
@@ -26,6 +26,7 @@ using swift::ide::CodeCompletionDeclKind;
|
||||
using swift::ide::CodeCompletionKeywordKind;
|
||||
using swift::ide::CodeCompletionLiteralKind;
|
||||
using swift::ide::SemanticContextKind;
|
||||
using swift::ide::CodeCompletionFlair;
|
||||
using swift::ide::CodeCompletionString;
|
||||
using SwiftResult = swift::ide::CodeCompletionResult;
|
||||
using swift::ide::CompletionKind;
|
||||
@@ -126,6 +127,7 @@ class CompletionBuilder {
|
||||
bool modified = false;
|
||||
Completion::ExpectedTypeRelation typeRelation;
|
||||
SemanticContextKind semanticContext;
|
||||
CodeCompletionFlair flair;
|
||||
CodeCompletionString *completionString;
|
||||
llvm::SmallVector<char, 64> originalName;
|
||||
void *customKind = nullptr;
|
||||
@@ -151,6 +153,10 @@ public:
|
||||
modified = true;
|
||||
semanticContext = kind;
|
||||
}
|
||||
void setFlair(CodeCompletionFlair value) {
|
||||
modified = true;
|
||||
flair = value;
|
||||
}
|
||||
|
||||
void setPopularityFactor(PopularityFactor val) { popularityFactor = val; }
|
||||
|
||||
|
||||
@@ -72,9 +72,7 @@ struct CodeCompletion::Group : public Item {
|
||||
std::vector<Completion *> SourceKit::CodeCompletion::extendCompletions(
|
||||
ArrayRef<SwiftResult *> swiftResults, CompletionSink &sink,
|
||||
SwiftCompletionInfo &info, const NameToPopularityMap *nameToPopularity,
|
||||
const Options &options, Completion *prefix,
|
||||
Optional<SemanticContextKind> overrideContext,
|
||||
Optional<SemanticContextKind> overrideOperatorContext) {
|
||||
const Options &options, Completion *prefix, bool clearFlair) {
|
||||
|
||||
ImportDepth depth;
|
||||
if (info.swiftASTContext) {
|
||||
@@ -125,10 +123,9 @@ std::vector<Completion *> SourceKit::CodeCompletion::extendCompletions(
|
||||
builder.setSemanticContext(prefix->getSemanticContext());
|
||||
}
|
||||
|
||||
if (overrideOperatorContext && result->isOperator()) {
|
||||
builder.setSemanticContext(*overrideOperatorContext);
|
||||
} else if (overrideContext) {
|
||||
builder.setSemanticContext(*overrideContext);
|
||||
if (clearFlair) {
|
||||
builder.setFlair(CodeCompletionFlair());
|
||||
builder.setSemanticContext(SemanticContextKind::None);
|
||||
}
|
||||
|
||||
// If this result is not from the current module, try to get a popularity
|
||||
@@ -157,7 +154,7 @@ bool SourceKit::CodeCompletion::addCustomCompletions(
|
||||
CodeCompletionString::create(sink.allocator, chunk);
|
||||
CodeCompletion::SwiftResult swiftResult(
|
||||
CodeCompletion::SwiftResult::ResultKind::Pattern,
|
||||
SemanticContextKind::ExpressionSpecific,
|
||||
SemanticContextKind::Local, CodeCompletionFlairBit::ExpressionSpecific,
|
||||
/*IsArgumentLabels=*/false, /*NumBytesToErase=*/0, completionString,
|
||||
CodeCompletionResult::ExpectedTypeRelation::Unknown);
|
||||
|
||||
@@ -583,7 +580,6 @@ static double getSemanticContextScore(bool useImportDepth,
|
||||
Completion *completion) {
|
||||
double order = -1.0;
|
||||
switch (completion->getSemanticContext()) {
|
||||
case SemanticContextKind::ExpressionSpecific: order = 0; break;
|
||||
case SemanticContextKind::Local: order = 1; break;
|
||||
case SemanticContextKind::CurrentNominal: order = 2; break;
|
||||
case SemanticContextKind::Super: order = 3; break;
|
||||
@@ -661,10 +657,12 @@ static ResultBucket getResultBucket(Item &item, bool hasRequiredTypes,
|
||||
if (completion->isNotRecommended() && !skipMetaGroups)
|
||||
return ResultBucket::NotRecommended;
|
||||
|
||||
if (completion->getSemanticContext() ==
|
||||
SemanticContextKind::ExpressionSpecific &&
|
||||
!skipMetaGroups)
|
||||
return ResultBucket::ExpressionSpecific;
|
||||
if (!skipMetaGroups) {
|
||||
auto flair = completion->getFlair();
|
||||
if (flair.contains(CodeCompletionFlairBit::ExpressionSpecific) ||
|
||||
flair.contains(CodeCompletionFlairBit::SuperChain))
|
||||
return ResultBucket::ExpressionSpecific;
|
||||
}
|
||||
|
||||
if (completion->isArgumentLabels() && !skipMetaGroups)
|
||||
return ResultBucket::ExpressionSpecific;
|
||||
@@ -1126,6 +1124,7 @@ CompletionBuilder::CompletionBuilder(CompletionSink &sink, SwiftResult &base)
|
||||
: sink(sink), current(base) {
|
||||
typeRelation = current.getExpectedTypeRelation();
|
||||
semanticContext = current.getSemanticContext();
|
||||
flair = current.getFlair();
|
||||
completionString =
|
||||
const_cast<CodeCompletionString *>(current.getCompletionString());
|
||||
|
||||
@@ -1170,14 +1169,14 @@ Completion *CompletionBuilder::finish() {
|
||||
|
||||
if (current.getKind() == SwiftResult::Declaration) {
|
||||
base = SwiftResult(
|
||||
semanticContext, current.isArgumentLabels(),
|
||||
semanticContext, flair, current.isArgumentLabels(),
|
||||
current.getNumBytesToErase(), completionString,
|
||||
current.getAssociatedDeclKind(), current.isSystem(),
|
||||
current.getModuleName(), current.getNotRecommendedReason(),
|
||||
current.getBriefDocComment(), current.getAssociatedUSRs(),
|
||||
current.getDeclKeywords(), typeRelation, opKind);
|
||||
} else {
|
||||
base = SwiftResult(current.getKind(), semanticContext,
|
||||
base = SwiftResult(current.getKind(), semanticContext, flair,
|
||||
current.isArgumentLabels(),
|
||||
current.getNumBytesToErase(), completionString,
|
||||
typeRelation, opKind);
|
||||
|
||||
@@ -66,8 +66,7 @@ extendCompletions(ArrayRef<SwiftResult *> swiftResults, CompletionSink &sink,
|
||||
SwiftCompletionInfo &info,
|
||||
const NameToPopularityMap *nameToPopularity,
|
||||
const Options &options, Completion *prefix = nullptr,
|
||||
Optional<SemanticContextKind> overrideContext = None,
|
||||
Optional<SemanticContextKind> overrideOperatorContext = None);
|
||||
bool clearFlair = false);
|
||||
|
||||
bool addCustomCompletions(CompletionSink &sink,
|
||||
std::vector<Completion *> &completions,
|
||||
|
||||
@@ -492,23 +492,28 @@ bool SwiftToSourceKitCompletionAdapter::handleResult(
|
||||
static UIdent CCCtxCurrentModule("source.codecompletion.context.thismodule");
|
||||
static UIdent CCCtxOtherModule("source.codecompletion.context.othermodule");
|
||||
|
||||
switch (Result->getSemanticContext()) {
|
||||
case SemanticContextKind::None:
|
||||
Info.SemanticContext = CCCtxNone; break;
|
||||
case SemanticContextKind::ExpressionSpecific:
|
||||
Info.SemanticContext = CCCtxExpressionSpecific; break;
|
||||
case SemanticContextKind::Local:
|
||||
Info.SemanticContext = CCCtxLocal; break;
|
||||
case SemanticContextKind::CurrentNominal:
|
||||
Info.SemanticContext = CCCtxCurrentNominal; break;
|
||||
case SemanticContextKind::Super:
|
||||
Info.SemanticContext = CCCtxSuper; break;
|
||||
case SemanticContextKind::OutsideNominal:
|
||||
Info.SemanticContext = CCCtxOutsideNominal; break;
|
||||
case SemanticContextKind::CurrentModule:
|
||||
Info.SemanticContext = CCCtxCurrentModule; break;
|
||||
case SemanticContextKind::OtherModule:
|
||||
Info.SemanticContext = CCCtxOtherModule; break;
|
||||
|
||||
if (Result->getFlair().contains(CodeCompletionFlairBit::ExpressionSpecific) ||
|
||||
Result->getFlair().contains(CodeCompletionFlairBit::SuperChain)) {
|
||||
// NOTE: `CCCtxExpressionSpecific` is to maintain compatibility.
|
||||
Info.SemanticContext = CCCtxExpressionSpecific;
|
||||
} else {
|
||||
switch (Result->getSemanticContext()) {
|
||||
case SemanticContextKind::None:
|
||||
Info.SemanticContext = CCCtxNone; break;
|
||||
case SemanticContextKind::Local:
|
||||
Info.SemanticContext = CCCtxLocal; break;
|
||||
case SemanticContextKind::CurrentNominal:
|
||||
Info.SemanticContext = CCCtxCurrentNominal; break;
|
||||
case SemanticContextKind::Super:
|
||||
Info.SemanticContext = CCCtxSuper; break;
|
||||
case SemanticContextKind::OutsideNominal:
|
||||
Info.SemanticContext = CCCtxOutsideNominal; break;
|
||||
case SemanticContextKind::CurrentModule:
|
||||
Info.SemanticContext = CCCtxCurrentModule; break;
|
||||
case SemanticContextKind::OtherModule:
|
||||
Info.SemanticContext = CCCtxOtherModule; break;
|
||||
}
|
||||
}
|
||||
|
||||
static UIdent CCTypeRelNotApplicable("source.codecompletion.typerelation.notapplicable");
|
||||
@@ -914,14 +919,16 @@ static void transformAndForwardResults(
|
||||
CodeCompletionString::create(innerSink.allocator, chunks);
|
||||
CodeCompletion::SwiftResult paren(
|
||||
CodeCompletion::SwiftResult::ResultKind::BuiltinOperator,
|
||||
SemanticContextKind::ExpressionSpecific, /*IsArgumentLabels=*/false,
|
||||
SemanticContextKind::CurrentNominal,
|
||||
CodeCompletionFlairBit::ExpressionSpecific,
|
||||
/*IsArgumentLabels=*/false,
|
||||
exactMatch ? exactMatch->getNumBytesToErase() : 0, completionString,
|
||||
CodeCompletionResult::ExpectedTypeRelation::NotApplicable);
|
||||
|
||||
SwiftCompletionInfo info;
|
||||
std::vector<Completion *> extended =
|
||||
extendCompletions(&paren, innerSink, info, nameToPopularity, options,
|
||||
exactMatch, SemanticContextKind::ExpressionSpecific);
|
||||
exactMatch);
|
||||
assert(extended.size() == 1);
|
||||
return extended.front();
|
||||
};
|
||||
@@ -1002,11 +1009,11 @@ static void transformAndForwardResults(
|
||||
auto topResults = filterInnerResults(results, options.addInnerResults,
|
||||
options.addInnerOperators, hasDot,
|
||||
hasQDot, hasInit, rules);
|
||||
// FIXME: Overriding the default to context "None" is a hack so that they
|
||||
// won't overwhelm other results that also match the filter text.
|
||||
// FIXME: Clearing the flair (and semantic context) is a hack so that
|
||||
// they won't overwhelm other results that also match the filter text.
|
||||
innerResults = extendCompletions(
|
||||
topResults, innerSink, info, nameToPopularity, options, exactMatch,
|
||||
SemanticContextKind::None, SemanticContextKind::None);
|
||||
/*clearFlair=*/true);
|
||||
});
|
||||
|
||||
auto *inputBuf = session->getBuffer();
|
||||
|
||||
Reference in New Issue
Block a user