@@ -168,11 +168,24 @@ extension Parser {
168
168
}
169
169
}
170
170
171
+ /// Information about the syntactic position of the declaration being parsed.
172
+ /// Used to tweak recovery and to permit missing bodies.
173
+ enum DeclarationParsingContext {
174
+ /// The declaration is at the top level of a file.
175
+ case topLevelCode
176
+
177
+ /// The declaration is nested inside the member list of a DeclGroupSyntax.
178
+ case memberList
179
+
180
+ /// The declaration is nested inside the argument list of an attribute.
181
+ case attribute
182
+ }
183
+
171
184
/// Parse a declaration.
172
185
///
173
- /// If `inMemberDeclList ` is `true `, we know that the next item must be a
186
+ /// If `parseContext ` is `memberList `, we know that the next item must be a
174
187
/// declaration and thus start with a keyword. This allows further recovery.
175
- mutating func parseDeclaration( inMemberDeclList : Bool = false ) -> RawDeclSyntax {
188
+ mutating func parseDeclaration( in parseContext : DeclarationParsingContext = . topLevelCode ) -> RawDeclSyntax {
176
189
// If we are at a `#if` of attributes, the `#if` directive should be
177
190
// parsed when we're parsing the attributes.
178
191
if self . at ( . poundIf) && !self . withLookahead ( { $0. consumeIfConfigOfAttributes ( ) } ) {
@@ -221,7 +234,14 @@ extension Parser {
221
234
// to parse.
222
235
// If we are inside a memberDecl list, we don't want to eat closing braces (which most likely close the outer context)
223
236
// while recovering to the declaration start.
224
- let recoveryPrecedence = inMemberDeclList ? TokenPrecedence . closingBrace : nil
237
+ let recoveryPrecedence = switch parseContext {
238
+ case . topLevelCode:
239
+ Optional< TokenPrecedence> . none
240
+ case . memberList:
241
+ Optional ( TokenPrecedence . closingBrace)
242
+ case . attribute:
243
+ Optional ( TokenPrecedence . weakBracketed ( closingDelimiter: . rightParen) )
244
+ }
225
245
recoveryResult = self . canRecoverTo ( anyIn: DeclarationKeyword . self, overrideRecoveryPrecedence: recoveryPrecedence)
226
246
}
227
247
@@ -230,28 +250,28 @@ extension Parser {
230
250
return RawDeclSyntax ( self . parseImportDeclaration ( attrs, handle) )
231
251
case ( . lhs( . class) , let handle) ? :
232
252
return RawDeclSyntax (
233
- self . parseNominalTypeDeclaration ( for: RawClassDeclSyntax . self, attrs: attrs, introucerHandle: handle)
253
+ self . parseNominalTypeDeclaration ( for: RawClassDeclSyntax . self, attrs: attrs, introucerHandle: handle, parseContext : parseContext )
234
254
)
235
255
case ( . lhs( . enum) , let handle) ? :
236
256
return RawDeclSyntax (
237
- self . parseNominalTypeDeclaration ( for: RawEnumDeclSyntax . self, attrs: attrs, introucerHandle: handle)
257
+ self . parseNominalTypeDeclaration ( for: RawEnumDeclSyntax . self, attrs: attrs, introucerHandle: handle, parseContext : parseContext )
238
258
)
239
259
case ( . lhs( . case) , let handle) ? :
240
260
return RawDeclSyntax ( self . parseEnumCaseDeclaration ( attrs, handle) )
241
261
case ( . lhs( . struct) , let handle) ? :
242
262
return RawDeclSyntax (
243
- self . parseNominalTypeDeclaration ( for: RawStructDeclSyntax . self, attrs: attrs, introucerHandle: handle)
263
+ self . parseNominalTypeDeclaration ( for: RawStructDeclSyntax . self, attrs: attrs, introucerHandle: handle, parseContext : parseContext )
244
264
)
245
265
case ( . lhs( . protocol) , let handle) ? :
246
266
return RawDeclSyntax (
247
- self . parseNominalTypeDeclaration ( for: RawProtocolDeclSyntax . self, attrs: attrs, introucerHandle: handle)
267
+ self . parseNominalTypeDeclaration ( for: RawProtocolDeclSyntax . self, attrs: attrs, introucerHandle: handle, parseContext : parseContext )
248
268
)
249
269
case ( . lhs( . associatedtype) , let handle) ? :
250
270
return RawDeclSyntax ( self . parseAssociatedTypeDeclaration ( attrs, handle) )
251
271
case ( . lhs( . typealias) , let handle) ? :
252
272
return RawDeclSyntax ( self . parseTypealiasDeclaration ( attrs, handle) )
253
273
case ( . lhs( . extension) , let handle) ? :
254
- return RawDeclSyntax ( self . parseExtensionDeclaration ( attrs, handle) )
274
+ return RawDeclSyntax ( self . parseExtensionDeclaration ( attrs, handle, parseContext : parseContext ) )
255
275
case ( . lhs( . func) , let handle) ? :
256
276
return RawDeclSyntax ( self . parseFuncDeclaration ( attrs, handle) )
257
277
case ( . lhs( . subscript) , let handle) ? :
@@ -266,19 +286,19 @@ extension Parser {
266
286
return RawDeclSyntax ( self . parsePrecedenceGroupDeclaration ( attrs, handle) )
267
287
case ( . lhs( . actor ) , let handle) ? :
268
288
return RawDeclSyntax (
269
- self . parseNominalTypeDeclaration ( for: RawActorDeclSyntax . self, attrs: attrs, introucerHandle: handle)
289
+ self . parseNominalTypeDeclaration ( for: RawActorDeclSyntax . self, attrs: attrs, introucerHandle: handle, parseContext : parseContext )
270
290
)
271
291
case ( . lhs( . macro) , let handle) ? :
272
292
return RawDeclSyntax ( self . parseMacroDeclaration ( attrs: attrs, introducerHandle: handle) )
273
293
case ( . lhs( . pound) , let handle) ? :
274
294
return RawDeclSyntax ( self . parseMacroExpansionDeclaration ( attrs, handle) )
275
295
case ( . rhs, let handle) ? :
276
- return RawDeclSyntax ( self . parseBindingDeclaration ( attrs, handle, inMemberDeclList: inMemberDeclList ) )
296
+ return RawDeclSyntax ( self . parseBindingDeclaration ( attrs, handle, inMemberDeclList: parseContext != . topLevelCode ) )
277
297
case nil :
278
298
break
279
299
}
280
300
281
- if inMemberDeclList {
301
+ if parseContext != . topLevelCode {
282
302
let isProbablyVarDecl = self . at ( . identifier, . wildcard) && self . peek ( isAt: . colon, . equal, . comma)
283
303
let isProbablyTupleDecl = self . at ( . leftParen) && self . peek ( isAt: . identifier, . wildcard)
284
304
@@ -377,7 +397,8 @@ extension Parser {
377
397
/// Parse an extension declaration.
378
398
mutating func parseExtensionDeclaration(
379
399
_ attrs: DeclAttributes ,
380
- _ handle: RecoveryConsumptionHandle
400
+ _ handle: RecoveryConsumptionHandle ,
401
+ parseContext: DeclarationParsingContext
381
402
) -> RawExtensionDeclSyntax {
382
403
let ( unexpectedBeforeExtensionKeyword, extensionKeyword) = self . eat ( handle)
383
404
let type = self . parseType ( )
@@ -395,7 +416,12 @@ extension Parser {
395
416
} else {
396
417
whereClause = nil
397
418
}
398
- let memberBlock = self . parseMemberBlock ( introducer: extensionKeyword)
419
+ let memberBlock : RawMemberBlockSyntax ?
420
+ if parseContext == . attribute && !self . at ( . leftBrace) {
421
+ memberBlock = nil
422
+ } else {
423
+ memberBlock = self . parseMemberBlock ( introducer: extensionKeyword)
424
+ }
399
425
return RawExtensionDeclSyntax (
400
426
attributes: attrs. attributes,
401
427
modifiers: attrs. modifiers,
@@ -746,7 +772,7 @@ extension Parser {
746
772
if self . at ( . poundSourceLocation) {
747
773
decl = RawDeclSyntax ( self . parsePoundSourceLocationDirective ( ) )
748
774
} else {
749
- decl = self . parseDeclaration ( inMemberDeclList : true )
775
+ decl = self . parseDeclaration ( in : . memberList )
750
776
}
751
777
752
778
let semi = self . consume ( if: . semicolon)
0 commit comments