mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
[CodeCompletion][Sema] Migrate CallArgurment position completion to the solver-based implementation
This hooks up call argument position completion to the typeCheckForCodeCompletion API to generate completions from all the solutions the constraint solver produces (even those requiring fixes), rather than relying on a single solution being applied to the AST (if any). Co-authored-by: Nathan Hawes <nathan.john.hawes@gmail.com>
This commit is contained in:
@@ -32,6 +32,7 @@
|
||||
#include "swift/ClangImporter/ClangImporter.h"
|
||||
#include "swift/ClangImporter/ClangModule.h"
|
||||
#include "swift/Frontend/FrontendOptions.h"
|
||||
#include "swift/IDE/ArgumentCompletion.h"
|
||||
#include "swift/IDE/CodeCompletionCache.h"
|
||||
#include "swift/IDE/CodeCompletionConsumer.h"
|
||||
#include "swift/IDE/CodeCompletionResultPrinter.h"
|
||||
@@ -830,7 +831,8 @@ static void addObserverKeywords(CodeCompletionResultSink &Sink) {
|
||||
addKeyword(Sink, "didSet", CodeCompletionKeywordKind::None);
|
||||
}
|
||||
|
||||
static void addExprKeywords(CodeCompletionResultSink &Sink, DeclContext *DC) {
|
||||
void swift::ide::addExprKeywords(CodeCompletionResultSink &Sink,
|
||||
DeclContext *DC) {
|
||||
// Expression is invalid at top-level of non-script files.
|
||||
CodeCompletionFlair flair;
|
||||
if (isCodeCompletionAtTopLevelOfLibraryFile(DC)) {
|
||||
@@ -844,7 +846,8 @@ static void addExprKeywords(CodeCompletionResultSink &Sink, DeclContext *DC) {
|
||||
addKeyword(Sink, "await", CodeCompletionKeywordKind::None, "", flair);
|
||||
}
|
||||
|
||||
static void addSuperKeyword(CodeCompletionResultSink &Sink, DeclContext *DC) {
|
||||
void swift::ide::addSuperKeyword(CodeCompletionResultSink &Sink,
|
||||
DeclContext *DC) {
|
||||
if (!DC)
|
||||
return;
|
||||
auto *TC = DC->getInnermostTypeContext();
|
||||
@@ -1373,6 +1376,22 @@ bool CodeCompletionCallbacksImpl::trySolverCompletion(bool MaybeFuncBody) {
|
||||
Lookup.deliverResults(CurDeclContext, DotLoc, CompletionContext, Consumer);
|
||||
return true;
|
||||
}
|
||||
case CompletionKind::CallArg: {
|
||||
assert(CodeCompleteTokenExpr);
|
||||
assert(CurDeclContext);
|
||||
ArgumentTypeCheckCompletionCallback Lookup(CodeCompleteTokenExpr);
|
||||
llvm::SaveAndRestore<TypeCheckCompletionCallback *> CompletionCollector(
|
||||
Context.CompletionCallback, &Lookup);
|
||||
typeCheckContextAt(CurDeclContext, CompletionLoc);
|
||||
|
||||
if (!Lookup.gotCallback()) {
|
||||
Lookup.fallbackTypeCheck(CurDeclContext);
|
||||
}
|
||||
|
||||
Lookup.deliverResults(ShouldCompleteCallPatternAfterParen, CompletionLoc,
|
||||
CurDeclContext, CompletionContext, Consumer);
|
||||
return true;
|
||||
}
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
@@ -1494,6 +1513,7 @@ void CodeCompletionCallbacksImpl::doneParsing() {
|
||||
case CompletionKind::DotExpr:
|
||||
case CompletionKind::UnresolvedMember:
|
||||
case CompletionKind::KeyPathExprSwift:
|
||||
case CompletionKind::CallArg:
|
||||
llvm_unreachable("should be already handled");
|
||||
return;
|
||||
|
||||
@@ -1657,58 +1677,6 @@ void CodeCompletionCallbacksImpl::doneParsing() {
|
||||
Lookup.addImportModuleNames();
|
||||
break;
|
||||
}
|
||||
case CompletionKind::CallArg: {
|
||||
ExprContextInfo ContextInfo(CurDeclContext, CodeCompleteTokenExpr);
|
||||
|
||||
bool shouldPerformGlobalCompletion = true;
|
||||
|
||||
if (ShouldCompleteCallPatternAfterParen &&
|
||||
!ContextInfo.getPossibleCallees().empty()) {
|
||||
Lookup.setHaveLParen(true);
|
||||
for (auto &typeAndDecl : ContextInfo.getPossibleCallees()) {
|
||||
auto apply = ContextInfo.getAnalyzedExpr();
|
||||
if (isa_and_nonnull<SubscriptExpr>(apply)) {
|
||||
Lookup.addSubscriptCallPattern(
|
||||
typeAndDecl.Type,
|
||||
dyn_cast_or_null<SubscriptDecl>(typeAndDecl.Decl),
|
||||
typeAndDecl.SemanticContext);
|
||||
} else {
|
||||
Lookup.addFunctionCallPattern(
|
||||
typeAndDecl.Type,
|
||||
dyn_cast_or_null<AbstractFunctionDecl>(typeAndDecl.Decl),
|
||||
typeAndDecl.SemanticContext);
|
||||
}
|
||||
}
|
||||
Lookup.setHaveLParen(false);
|
||||
|
||||
shouldPerformGlobalCompletion =
|
||||
!Lookup.FoundFunctionCalls ||
|
||||
(Lookup.FoundFunctionCalls &&
|
||||
Lookup.FoundFunctionsWithoutFirstKeyword);
|
||||
} else if (!ContextInfo.getPossibleParams().empty()) {
|
||||
auto params = ContextInfo.getPossibleParams();
|
||||
Lookup.addCallArgumentCompletionResults(params);
|
||||
|
||||
shouldPerformGlobalCompletion = !ContextInfo.getPossibleTypes().empty();
|
||||
// Fallback to global completion if the position is out of number. It's
|
||||
// better than suggest nothing.
|
||||
shouldPerformGlobalCompletion |= llvm::all_of(
|
||||
params, [](const PossibleParamInfo &P) { return !P.Param; });
|
||||
}
|
||||
|
||||
if (shouldPerformGlobalCompletion) {
|
||||
Lookup.setExpectedTypes(ContextInfo.getPossibleTypes(),
|
||||
ContextInfo.isImplicitSingleExpressionReturn());
|
||||
|
||||
// Add any keywords that can be used in an argument expr position.
|
||||
addSuperKeyword(CompletionContext.getResultSink(), CurDeclContext);
|
||||
addExprKeywords(CompletionContext.getResultSink(), CurDeclContext);
|
||||
|
||||
DoPostfixExprBeginning();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case CompletionKind::LabeledTrailingClosure: {
|
||||
ExprContextInfo ContextInfo(CurDeclContext, CodeCompleteTokenExpr);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user