Xcode: Chained trailing closures created without autocomplete should auto-indent to the root call's indentation level

Originator:dennis
Number:rdar://22205716 Date Originated:09-Aug-2015
Status:Open Resolved:
Product:Developer Tools Product Version:Xcode Version 7.0 beta 5 (7A176x)
Classification: Reproducible:Always
 
Short version: Calling a chained method with trailing closure syntax as in the following example indents trailing closures properly ONLY if you use Xcode autocomplete:

array.filter { (element) in 
    return true
}.map { (element) -> OtherClass in
    return OtherClass.process(element)
}

BUT, if you type the filter call and then MANUALLY type ".map {", Xcode will auto-indent it with an extra level of indentation. I believe the Xcode dev team agrees that the autocomplete-provided trailing closure indentation is correct, but if not, you can read below for a philosophical explanation of why I think that it is: 



When I use multiple trailing closures in any configuration, for example array.filter { ... }.map { ... }, or Async.userInitiated { ... }.main { ... }, as is a common idiom in my Swift development so far, Xcode auto-indents the first trailing closure normally but then auto-indents the second trailing closure one tab ahead, which causes it to appear on a higher level than the rest of the line. Unfortunately, this detracts from the readability of synchronous closure-based code, and also presents an inconsistency with similar code in objective-C (e.g. calling [MagicalRecord saveWithBlock:^{ ... } completion:^{ ... }] would indent both blocks to the same indentation level in objC).

Steps to Reproduce:
1. Open a Swift file in Xcode
2. Enter the following line: let array: [Int?] = [1, 3, 5, nil]
3. Type "array.filter" and press enter twice to expand the trailing closure auto-complete; fill in the parentheses with "num", press tab and fill in the body of the closure with "return num != nil"
4. Move down a line to the closing brace from the filter call and type ".map {" -- WITHOUT PRESSING ENTER TO AUTOCOMPLETE.



Expected Results:
The line that I just typed on says "}.map {" and stays on the same level of indentation as the line containing its opening brace.

Actual Results:
The line that I just typed on says "}.map {" and indents an extra level past the level of indentation of the line containing its opening brace.

Comments


Please note: Reports posted here will not necessarily be seen by Apple. All problems should be submitted at bugreport.apple.com before they are posted here. Please only post information for Radars that you have filed yourself, and please do not include Apple confidential information in your posts. Thank you!