[CodeComplete] Default parameter names of completed closure to internal names

If have a function that takes a trailing closure as follows
```
func sort(callback: (_ left: Int, _ right: Int) -> Bool) {}
```
completing a call to `sort` and expanding the trailing closure results in
```
sort { <#Int#>, <#Int#> in
  <#code#>
}
```

We should be doing a better job here and defaulting the trailing closure's to the internal names specified in the function signature. I.e. the final result should be
```
sort { left, right in
  <#code#>
}
```

This commit does exactly that.

Firstly, it keeps track of the closure's internal names (as specified in the declaration of `sort`) in the closure's type through a new `InternalLabel` property in `AnyFunctionType::Param`. Once the type containing the parameter gets canonicalized, the internal label is dropped.

Secondly, it adds a new option to `ASTPrinter` to always try and print parameter labels. With this option set to true, it will always print external paramter labels and, if they are present, print the internal parameter label as `_ <internalLabel>`.

Finally, we can use this new printing mode to print the trailing closure’s type as
```
<#T##callback: (Int, Int) -> Bool##(_ left: Int, _ right: Int) -> Bool#>
```

This is already correctly expanded by code-expand to the desired result. I also added a test case for that behaviour.
This commit is contained in:
Alex Hoppen
2021-03-30 11:20:42 +02:00
parent 74b5eb7b44
commit 865e80f9c4
18 changed files with 163 additions and 39 deletions

View File

@@ -4471,7 +4471,15 @@ bool MissingArgumentsFailure::diagnoseClosure(const ClosureExpr *closure) {
fixText += " ";
interleave(
funcType->getParams(),
[&fixText](const AnyFunctionType::Param &param) { fixText += '_'; },
[&fixText](const AnyFunctionType::Param &param) {
if (param.hasLabel()) {
fixText += param.getLabel().str();
} else if (param.hasInternalLabel()) {
fixText += param.getInternalLabel().str();
} else {
fixText += '_';
}
},
[&fixText] { fixText += ','; });
fixText += " in ";
}