mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
[CodeCompletion] Support a narrow case for producing trailing closures directly
This adds a narrow special case in code-completion for control-flow-like methods such as DispatchQueue().sync that are () -> (), to add a new completion where the trailing closure is immediately expanded rather than having to invoke placeholder expansion as a second step. rdar://problem/26628804
This commit is contained in:
@@ -72,94 +72,6 @@ static Optional<unsigned> scoreParamAndArgNameTypo(StringRef paramName,
|
||||
return dist;
|
||||
}
|
||||
|
||||
SmallVector<CallArgParam, 4> constraints::decomposeArgType(Type type) {
|
||||
return decomposeParamType(type, nullptr, /*level=*/0);
|
||||
}
|
||||
|
||||
SmallVector<CallArgParam, 4>
|
||||
constraints::decomposeParamType(Type type, ValueDecl *paramOwner,
|
||||
unsigned level) {
|
||||
// Find the corresponding parameter list.
|
||||
ParameterList *paramList = nullptr;
|
||||
if (paramOwner) {
|
||||
if (auto func = dyn_cast<AbstractFunctionDecl>(paramOwner)) {
|
||||
if (level < func->getNumParameterLists())
|
||||
paramList = func->getParameterList(level);
|
||||
} else if (auto subscript = dyn_cast<SubscriptDecl>(paramOwner)) {
|
||||
if (level == 1)
|
||||
paramList = subscript->getIndices();
|
||||
}
|
||||
}
|
||||
|
||||
SmallVector<CallArgParam, 4> result;
|
||||
switch (type->getKind()) {
|
||||
case TypeKind::Tuple: {
|
||||
auto tupleTy = cast<TupleType>(type.getPointer());
|
||||
|
||||
// FIXME: In the weird case where we have a tuple type that should
|
||||
// be wrapped in a ParenType but isn't, just... forget it happened.
|
||||
if (paramList && tupleTy->getNumElements() != paramList->size() &&
|
||||
paramList->size() == 1)
|
||||
paramList = nullptr;
|
||||
|
||||
for (auto i : range(0, tupleTy->getNumElements())) {
|
||||
const auto &elt = tupleTy->getElement(i);
|
||||
|
||||
CallArgParam argParam;
|
||||
argParam.Ty = elt.isVararg() ? elt.getVarargBaseTy() : elt.getType();
|
||||
argParam.Label = elt.getName();
|
||||
argParam.HasDefaultArgument =
|
||||
paramList && paramList->get(i)->isDefaultArgument();
|
||||
argParam.Variadic = elt.isVararg();
|
||||
result.push_back(argParam);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case TypeKind::Paren: {
|
||||
CallArgParam argParam;
|
||||
argParam.Ty = cast<ParenType>(type.getPointer())->getUnderlyingType();
|
||||
argParam.HasDefaultArgument =
|
||||
paramList && paramList->get(0)->isDefaultArgument();
|
||||
result.push_back(argParam);
|
||||
break;
|
||||
}
|
||||
|
||||
default: {
|
||||
CallArgParam argParam;
|
||||
argParam.Ty = type;
|
||||
result.push_back(argParam);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/// Turn a param list into a symbolic and printable representation that does not
|
||||
/// include the types, something like (_:, b:, c:)
|
||||
std::string constraints::getParamListAsString(ArrayRef<CallArgParam> params){
|
||||
std::string result = "(";
|
||||
|
||||
bool isFirst = true;
|
||||
for (auto ¶m : params) {
|
||||
if (isFirst)
|
||||
isFirst = false;
|
||||
else
|
||||
result += ", ";
|
||||
|
||||
if (param.hasLabel())
|
||||
result += param.Label.str();
|
||||
else
|
||||
result += "_";
|
||||
result += ":";
|
||||
}
|
||||
|
||||
|
||||
result += ')';
|
||||
return result;
|
||||
}
|
||||
|
||||
bool constraints::
|
||||
areConservativelyCompatibleArgumentLabels(ValueDecl *decl,
|
||||
unsigned parameterDepth,
|
||||
|
||||
Reference in New Issue
Block a user