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 {
160
160
let misplacedSpecifiers = parseMisplacedSpecifiers ( )
161
161
162
162
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 ( ) }
164
168
let type : RawTypeSyntax ?
165
- if colon != nil {
169
+ if canParseType {
166
170
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) )
167
180
} else {
168
181
type = nil
169
182
}
Original file line number Diff line number Diff line change @@ -2875,6 +2875,77 @@ final class StatementExpressionTests: ParserTestCase {
2875
2875
)
2876
2876
}
2877
2877
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
+
2878
2949
func testTypedThrowsDisambiguation() {
2879
2950
assertParse(
2880
2951
" [() throws(MyError) 1️⃣async -> Void]() " ,
You can’t perform that action at this time.
0 commit comments