[CodeCompletion] Associate callee declaration with call patterns

In `addFunctionCallPattern()` we should associate declarations if
possible.

rdar://problem/49158044
This commit is contained in:
Rintaro Ishizaki
2019-04-01 11:01:40 -07:00
parent b5610e77f1
commit 0c38f2df8a
13 changed files with 138 additions and 80 deletions

View File

@@ -1643,6 +1643,7 @@ public:
void setExpectedTypes(ArrayRef<Type> Types, bool isSingleExpressionBody) {
expectedTypeContext.isSingleExpressionBody = isSingleExpressionBody;
expectedTypeContext.possibleTypes.clear();
expectedTypeContext.possibleTypes.reserve(Types.size());
for (auto T : Types)
if (T)
@@ -2238,22 +2239,56 @@ public:
Builder.addRightParen();
}
SemanticContextKind getSemanticContextKind(const AbstractFunctionDecl *AFD) {
// FIXME: to get the corect semantic context we need to know how lookup
// would have found the declaration AFD. For now, just infer a reasonable
// semantics.
if (!AFD)
return SemanticContextKind::CurrentModule;
DeclContext *calleeDC = AFD->getDeclContext();
if (calleeDC->isTypeContext())
// FIXME: We should distinguish CurrentNominal and Super. We need to
// propagate the base type to do that.
return SemanticContextKind::CurrentNominal;
if (calleeDC->isLocalContext())
return SemanticContextKind::Local;
if (calleeDC->getParentModule() == CurrDeclContext->getParentModule())
return SemanticContextKind::CurrentModule;
return SemanticContextKind::OtherModule;
}
void addFunctionCallPattern(const AnyFunctionType *AFT,
const AbstractFunctionDecl *AFD = nullptr) {
if (AFD) {
auto genericSig =
AFD->getInnermostDeclContext()->getGenericSignatureOfContext();
AFT = eraseArchetypes(CurrDeclContext->getParentModule(),
const_cast<AnyFunctionType *>(AFT), genericSig)
->castTo<AnyFunctionType>();
}
// Add the pattern, possibly including any default arguments.
auto addPattern = [&](ArrayRef<const ParamDecl *> declParams = {},
bool includeDefaultArgs = true) {
// FIXME: to get the corect semantic context we need to know how lookup
// would have found the declaration AFD. For now, just choose a reasonable
// default, it's most likely to be CurrentModule or CurrentNominal.
CommandWordsPairs Pairs;
CodeCompletionResultBuilder Builder(
Sink, CodeCompletionResult::ResultKind::Pattern,
SemanticContextKind::CurrentModule, expectedTypeContext);
Sink,
AFD ? CodeCompletionResult::ResultKind::Declaration
: CodeCompletionResult::ResultKind::Pattern,
getSemanticContextKind(AFD), expectedTypeContext);
if (!HaveLParen)
Builder.addLeftParen();
else
Builder.addAnnotatedLeftParen();
if (AFD) {
Builder.setAssociatedDecl(AFD);
setClangDeclKeywords(AFD, Pairs, Builder);
}
addCallArgumentPatterns(Builder, AFT->getParams(), declParams,
includeDefaultArgs);
@@ -5063,14 +5098,17 @@ void CodeCompletionCallbacksImpl::doneParsing() {
Lookup.setHaveLParen(true);
ExprContextInfo ContextInfo(CurDeclContext, CodeCompleteTokenExpr);
Lookup.setExpectedTypes(ContextInfo.getPossibleTypes(),
ContextInfo.isSingleExpressionBody());
if (ShouldCompleteCallPatternAfterParen) {
if (ExprType) {
ExprContextInfo ParentContextInfo(CurDeclContext, ParsedExpr);
Lookup.setExpectedTypes(ParentContextInfo.getPossibleTypes(),
ParentContextInfo.isSingleExpressionBody());
if (ExprType && ((*ExprType)->is<AnyFunctionType>() ||
(*ExprType)->is<AnyMetatypeType>())) {
Lookup.getValueExprCompletions(*ExprType, ReferencedDecl.getDecl());
} else {
for (auto &typeAndDecl : ContextInfo.getPossibleCallees())
Lookup.getValueExprCompletions(typeAndDecl.first, typeAndDecl.second);
Lookup.tryFunctionCallCompletions(typeAndDecl.first, typeAndDecl.second);
}
} else {
// Add argument labels, then fallthrough to get values.
@@ -5080,6 +5118,8 @@ void CodeCompletionCallbacksImpl::doneParsing() {
if (!Lookup.FoundFunctionCalls ||
(Lookup.FoundFunctionCalls &&
Lookup.FoundFunctionsWithoutFirstKeyword)) {
Lookup.setExpectedTypes(ContextInfo.getPossibleTypes(),
ContextInfo.isSingleExpressionBody());
Lookup.setHaveLParen(false);
DoPostfixExprBeginning();
}