File tree Expand file tree Collapse file tree 2 files changed +86
-2
lines changed Expand file tree Collapse file tree 2 files changed +86
-2
lines changed Original file line number Diff line number Diff line change @@ -160,10 +160,23 @@ extension Parser {
160160 let misplacedSpecifiers = parseMisplacedSpecifiers ( )
161161
162162 let names = self . parseParameterNames ( )
163- let colon = self . consume ( if: . colon)
163+ var colon = self . consume ( if: . colon)
164+ // try to parse the type regardless of the presence of the preceding colon
165+ // to tackle any unnamed parameter or missing colon
166+ // e.g. [X], (:[X]) or (x [X])
167+ let canParseType = withLookahead { $0. canParseType ( ) }
164168 let type : RawTypeSyntax ?
165- if colon != nil {
169+ if canParseType {
166170 type = self . parseType ( misplacedSpecifiers: misplacedSpecifiers)
171+ if colon == nil {
172+ // mark the preceding colon as missing if the type is present
173+ // e.g. [X] or (x [X])
174+ colon = missingToken ( . colon)
175+ }
176+ } else if colon != nil {
177+ // mark the type as missing if the preceding colon is present
178+ // e.g. (:) or (_:)
179+ type = RawTypeSyntax ( RawMissingTypeSyntax ( arena: self . arena) )
167180 } else {
168181 type = nil
169182 }
Original file line number Diff line number Diff line change @@ -2875,6 +2875,77 @@ final class StatementExpressionTests: ParserTestCase {
28752875 )
28762876 }
28772877
2878+ func testClosureWithMalformedParameters() {
2879+ assertParse(
2880+ """
2881+ test { ( 1 ️⃣[ X] ) in }
2882+ """ ,
2883+ diagnostics: [
2884+ DiagnosticSpec(message: " expected identifier and ':' in parameter " , fixIts: [ " insert identifier and ':' " ])
2885+ ],
2886+ fixedSource: """
2887+ test { ( < #identifier#> : [ X] ) in }
2888+ """
2889+ )
2890+
2891+ assertParse(
2892+ """
2893+ test { ( 1 ️⃣: [ X] ) in }
2894+ """ ,
2895+ diagnostics: [
2896+ DiagnosticSpec(message: " expected identifier in parameter " , fixIts: [ " insert identifier " ])
2897+ ],
2898+ fixedSource: """
2899+ test { ( < #identifier#> : [ X] ) in }
2900+ """
2901+ )
2902+
2903+ assertParse(
2904+ """
2905+ test { ( 1 ️⃣: 2 ️⃣) in }
2906+ """ ,
2907+ diagnostics: [
2908+ DiagnosticSpec(
2909+ locationMarker: " 1️⃣ " ,
2910+ message: " expected identifier in parameter " ,
2911+ fixIts: [ " insert identifier " ]
2912+ ),
2913+ DiagnosticSpec(
2914+ locationMarker: " 2️⃣ " ,
2915+ message: " expected type in parameter " ,
2916+ fixIts: [ " insert type " ]
2917+ ),
2918+ ],
2919+ fixedSource: """
2920+ test { ( < #identifier#> : < #type#> ) in }
2921+ """
2922+ )
2923+
2924+ assertParse(
2925+ """
2926+ test { ( foo1️⃣ @bar baz ) in }
2927+ """ ,
2928+ diagnostics: [
2929+ DiagnosticSpec(message: " expected ':' in parameter " , fixIts: [ " insert ':' " ])
2930+ ],
2931+ fixedSource: """
2932+ test { ( foo: @bar baz ) in }
2933+ """
2934+ )
2935+
2936+ assertParse(
2937+ """
2938+ test { ( x: 1 ️⃣) in }
2939+ """ ,
2940+ diagnostics: [
2941+ DiagnosticSpec(message: " expected type in parameter " , fixIts: [ " insert type " ])
2942+ ],
2943+ fixedSource: """
2944+ test { ( x: < #type#> ) in }
2945+ """
2946+ )
2947+ }
2948+
28782949 func testTypedThrowsDisambiguation() {
28792950 assertParse(
28802951 " [() throws(MyError) 1️⃣async -> Void]() " ,
You can’t perform that action at this time.
0 commit comments