[Code completion] Code complete compound function names within #selector.

When we're code completing a postfix or dot expression inside the
subexpression of an #selector expression, prefer compound function
names. This helps us write, e.g.,

  #selector(UIView.

and get completions such as "insertSubview(_:aboveSubview:)". Fixes
rdar://problem/24470075.
This commit is contained in:
Doug Gregor
2016-02-02 16:03:02 -08:00
parent 9736d54a77
commit f5cb1151c1
4 changed files with 134 additions and 0 deletions

View File

@@ -1086,6 +1086,7 @@ class CodeCompletionCallbacksImpl : public CodeCompletionCallbacks {
bool HasSpace = false;
bool HasRParen = false;
bool ShouldCompleteCallPatternAfterParen = true;
bool PreferFunctionReferencesToCalls = false;
Optional<DeclKind> AttTargetDK;
SmallVector<StringRef, 3> ParsedKeywords;
@@ -1420,6 +1421,7 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
bool HaveRParen = false;
bool IsSuperRefExpr = false;
bool IsDynamicLookup = false;
bool PreferFunctionReferencesToCalls = false;
bool HaveLeadingSpace = false;
/// \brief True if we are code completing inside a static method.
@@ -1567,6 +1569,10 @@ public:
IsDynamicLookup = true;
}
void setPreferFunctionReferencesToCalls() {
PreferFunctionReferencesToCalls = true;
}
void setHaveLeadingSpace(bool value) { HaveLeadingSpace = value; }
void addExpressionSpecificDecl(const Decl *D) {
@@ -2404,6 +2410,43 @@ public:
Builder.addDeclAttrKeyword(Name, Annotation);
}
/// Add the compound function name for the given function.
void addCompoundFunctionName(AbstractFunctionDecl *AFD,
DeclVisibilityKind Reason) {
CommandWordsPairs Pairs;
CodeCompletionResultBuilder Builder(
Sink, CodeCompletionResult::ResultKind::Declaration,
getSemanticContext(AFD, Reason), ExpectedTypes);
setClangDeclKeywords(AFD, Pairs, Builder);
Builder.setAssociatedDecl(AFD);
// Base name
addLeadingDot(Builder);
Builder.addTextChunk(AFD->getFullName().getBaseName().str());
// Add the argument labels.
auto ArgLabels = AFD->getFullName().getArgumentNames();
if (ArgLabels.size() > 0) {
if (!HaveLParen)
Builder.addLeftParen();
else
Builder.addAnnotatedLeftParen();
for (auto ArgLabel : ArgLabels) {
if (ArgLabel.empty())
Builder.addTextChunk("_");
else
Builder.addTextChunk(ArgLabel.str());
Builder.addTextChunk(":");
}
if (!HaveRParen)
Builder.addRightParen();
else
Builder.addAnnotatedRightParen();
}
}
// Implement swift::VisibleDeclConsumer.
void foundDecl(ValueDecl *D, DeclVisibilityKind Reason) override {
// Hide private stdlib declarations.
@@ -2426,6 +2469,12 @@ public:
switch (Kind) {
case LookupKind::ValueExpr:
if (auto *CD = dyn_cast<ConstructorDecl>(D)) {
// Do we want compound function names here?
if (PreferFunctionReferencesToCalls) {
addCompoundFunctionName(CD, Reason);
return;
}
if (auto MT = ExprType->getRValueType()->getAs<AnyMetatypeType>()) {
if (HaveDot) {
Type Ty;
@@ -2483,6 +2532,12 @@ public:
if (FD->isAccessor())
return;
// Do we want compound function names here?
if (PreferFunctionReferencesToCalls) {
addCompoundFunctionName(FD, Reason);
return;
}
addMethodCall(FD, Reason);
return;
}
@@ -3765,6 +3820,9 @@ void CodeCompletionCallbacksImpl::completeDotExpr(Expr *E, SourceLoc DotLoc) {
return;
Kind = CompletionKind::DotExpr;
if (InObjCSelectorExpr)
PreferFunctionReferencesToCalls = true;
ParsedExpr = E;
this->DotLoc = DotLoc;
CurDeclContext = P.CurDeclContext;
@@ -3786,6 +3844,9 @@ void CodeCompletionCallbacksImpl::completePostfixExprBeginning(CodeCompletionExp
return;
Kind = CompletionKind::PostfixExprBeginning;
if (InObjCSelectorExpr)
PreferFunctionReferencesToCalls = true;
CurDeclContext = P.CurDeclContext;
CStyleForLoopIterationVariable =
CodeCompletionCallbacks::CStyleForLoopIterationVariable;
@@ -3801,6 +3862,9 @@ void CodeCompletionCallbacksImpl::completePostfixExpr(Expr *E, bool hasSpace) {
HasSpace = hasSpace;
Kind = CompletionKind::PostfixExpr;
if (InObjCSelectorExpr)
PreferFunctionReferencesToCalls = true;
ParsedExpr = E;
CurDeclContext = P.CurDeclContext;
}
@@ -3839,6 +3903,9 @@ void CodeCompletionCallbacksImpl::completeExprSuper(SuperRefExpr *SRE) {
return;
Kind = CompletionKind::SuperExpr;
if (InObjCSelectorExpr)
PreferFunctionReferencesToCalls = true;
ParsedExpr = SRE;
CurDeclContext = P.CurDeclContext;
}
@@ -3849,6 +3916,9 @@ void CodeCompletionCallbacksImpl::completeExprSuperDot(SuperRefExpr *SRE) {
return;
Kind = CompletionKind::SuperExprDot;
if (InObjCSelectorExpr)
PreferFunctionReferencesToCalls = true;
ParsedExpr = SRE;
CurDeclContext = P.CurDeclContext;
}
@@ -4389,6 +4459,8 @@ void CodeCompletionCallbacksImpl::doneParsing() {
if (ExprType) {
Lookup.setIsStaticMetatype(ParsedExpr->isStaticallyDerivedMetatype());
}
if (PreferFunctionReferencesToCalls)
Lookup.setPreferFunctionReferencesToCalls();
auto DoPostfixExprBeginning = [&] (){
if (CStyleForLoopIterationVariable)