[CodeCompletion] Suggest #selector and #keyPath after # only if applicable

Also, add type annotation, and make it `TypeRelation[Identical]`.
'ExprSpecific' is too strong.
This commit is contained in:
Rintaro Ishizaki
2019-05-21 16:58:54 -07:00
parent 3c957de1c9
commit e2a4621b14
4 changed files with 80 additions and 56 deletions

View File

@@ -2246,15 +2246,9 @@ public:
// #selector is only available when the Objective-C runtime is.
if (!Ctx.LangOpts.EnableObjCInterop) return;
// After #, this is a very likely result. When just in a String context,
// it's not.
auto semanticContext = needPound ? SemanticContextKind::None
: SemanticContextKind::ExpressionSpecific;
CodeCompletionResultBuilder Builder(
Sink,
CodeCompletionResult::ResultKind::Keyword,
semanticContext, expectedTypeContext);
Sink, CodeCompletionResult::ResultKind::Keyword,
SemanticContextKind::None, {});
if (needPound)
Builder.addTextChunk("#selector");
else
@@ -2262,21 +2256,19 @@ public:
Builder.addLeftParen();
Builder.addSimpleTypedParameter("@objc method", /*IsVarArg=*/false);
Builder.addRightParen();
Builder.addTypeAnnotation("Selector");
// This function is called only if the context type is 'Selector'.
Builder.setExpectedTypeRelation(
CodeCompletionResult::ExpectedTypeRelation::Identical);
}
void addPoundKeyPath(bool needPound) {
// #keyPath is only available when the Objective-C runtime is.
if (!Ctx.LangOpts.EnableObjCInterop) return;
// After #, this is a very likely result. When just in a String context,
// it's not.
auto semanticContext = needPound ? SemanticContextKind::None
: SemanticContextKind::ExpressionSpecific;
CodeCompletionResultBuilder Builder(
Sink,
CodeCompletionResult::ResultKind::Keyword,
semanticContext, expectedTypeContext);
Sink, CodeCompletionResult::ResultKind::Keyword,
SemanticContextKind::None, {});
if (needPound)
Builder.addTextChunk("#keyPath");
else
@@ -2285,6 +2277,10 @@ public:
Builder.addSimpleTypedParameter("@objc property sequence",
/*IsVarArg=*/false);
Builder.addRightParen();
Builder.addTypeAnnotation("String");
// This function is called only if the context type is 'String'.
Builder.setExpectedTypeRelation(
CodeCompletionResult::ExpectedTypeRelation::Identical);
}
SemanticContextKind getSemanticContextKind(const ValueDecl *VD) {
@@ -3679,6 +3675,38 @@ public:
}
}
void addObjCPoundKeywordCompletions(bool needPound) {
if (!Ctx.LangOpts.EnableObjCInterop)
return;
// If the expected type is ObjectiveC.Selector, add #selector. If
// it's String, add #keyPath.
bool addedSelector = false;
bool addedKeyPath = false;
for (auto T : expectedTypeContext.possibleTypes) {
T = T->lookThroughAllOptionalTypes();
if (auto structDecl = T->getStructOrBoundGenericStruct()) {
if (!addedSelector && structDecl->getName() == Ctx.Id_Selector &&
structDecl->getParentModule()->getName() == Ctx.Id_ObjectiveC) {
addPoundSelector(needPound);
if (addedKeyPath)
break;
addedSelector = true;
continue;
}
}
if (!addedKeyPath && T->getAnyNominal() == Ctx.getStringDecl()) {
addPoundKeyPath(needPound);
if (addedSelector)
break;
addedKeyPath = true;
continue;
}
}
}
struct FilteredDeclConsumer : public swift::VisibleDeclConsumer {
swift::VisibleDeclConsumer &Consumer;
DeclFilter Filter;
@@ -3742,33 +3770,7 @@ public:
addPoundLiteralCompletions(/*needPound=*/true);
}
// If the expected type is ObjectiveC.Selector, add #selector. If
// it's String, add #keyPath.
if (Ctx.LangOpts.EnableObjCInterop) {
bool addedSelector = false;
bool addedKeyPath = false;
for (auto T : expectedTypeContext.possibleTypes) {
T = T->lookThroughAllOptionalTypes();
if (auto structDecl = T->getStructOrBoundGenericStruct()) {
if (!addedSelector &&
structDecl->getName() == Ctx.Id_Selector &&
structDecl->getParentModule()->getName() == Ctx.Id_ObjectiveC) {
addPoundSelector(/*needPound=*/true);
if (addedKeyPath) break;
addedSelector = true;
continue;
}
}
if (!addedKeyPath && T->getAnyNominal() == Ctx.getStringDecl()) {
addPoundKeyPath(/*needPound=*/true);
if (addedSelector) break;
addedKeyPath = true;
continue;
}
}
}
addObjCPoundKeywordCompletions(/*needPound=*/true);
}
void getUnresolvedMemberCompletions(Type T) {
@@ -5475,8 +5477,7 @@ void CodeCompletionCallbacksImpl::doneParsing() {
Lookup.addPoundAvailable(ParentStmtKind);
Lookup.addPoundLiteralCompletions(/*needPound=*/false);
Lookup.addPoundSelector(/*needPound=*/false);
Lookup.addPoundKeyPath(/*needPound=*/false);
Lookup.addObjCPoundKeywordCompletions(/*needPound=*/false);
break;
}