@@ -168,11 +168,24 @@ extension Parser {
168168 }
169169 }
170170
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+
171184 /// Parse a declaration.
172185 ///
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
174187 /// 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 {
176189 // If we are at a `#if` of attributes, the `#if` directive should be
177190 // parsed when we're parsing the attributes.
178191 if self . at ( . poundIf) && !self . withLookahead ( { $0. consumeIfConfigOfAttributes ( ) } ) {
@@ -221,7 +234,14 @@ extension Parser {
221234 // to parse.
222235 // If we are inside a memberDecl list, we don't want to eat closing braces (which most likely close the outer context)
223236 // 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+ }
225245 recoveryResult = self . canRecoverTo ( anyIn: DeclarationKeyword . self, overrideRecoveryPrecedence: recoveryPrecedence)
226246 }
227247
@@ -230,28 +250,28 @@ extension Parser {
230250 return RawDeclSyntax ( self . parseImportDeclaration ( attrs, handle) )
231251 case ( . lhs( . class) , let handle) ? :
232252 return RawDeclSyntax (
233- self . parseNominalTypeDeclaration ( for: RawClassDeclSyntax . self, attrs: attrs, introucerHandle: handle)
253+ self . parseNominalTypeDeclaration ( for: RawClassDeclSyntax . self, attrs: attrs, introucerHandle: handle, parseContext : parseContext )
234254 )
235255 case ( . lhs( . enum) , let handle) ? :
236256 return RawDeclSyntax (
237- self . parseNominalTypeDeclaration ( for: RawEnumDeclSyntax . self, attrs: attrs, introucerHandle: handle)
257+ self . parseNominalTypeDeclaration ( for: RawEnumDeclSyntax . self, attrs: attrs, introucerHandle: handle, parseContext : parseContext )
238258 )
239259 case ( . lhs( . case) , let handle) ? :
240260 return RawDeclSyntax ( self . parseEnumCaseDeclaration ( attrs, handle) )
241261 case ( . lhs( . struct) , let handle) ? :
242262 return RawDeclSyntax (
243- self . parseNominalTypeDeclaration ( for: RawStructDeclSyntax . self, attrs: attrs, introucerHandle: handle)
263+ self . parseNominalTypeDeclaration ( for: RawStructDeclSyntax . self, attrs: attrs, introucerHandle: handle, parseContext : parseContext )
244264 )
245265 case ( . lhs( . protocol) , let handle) ? :
246266 return RawDeclSyntax (
247- self . parseNominalTypeDeclaration ( for: RawProtocolDeclSyntax . self, attrs: attrs, introucerHandle: handle)
267+ self . parseNominalTypeDeclaration ( for: RawProtocolDeclSyntax . self, attrs: attrs, introucerHandle: handle, parseContext : parseContext )
248268 )
249269 case ( . lhs( . associatedtype) , let handle) ? :
250270 return RawDeclSyntax ( self . parseAssociatedTypeDeclaration ( attrs, handle) )
251271 case ( . lhs( . typealias) , let handle) ? :
252272 return RawDeclSyntax ( self . parseTypealiasDeclaration ( attrs, handle) )
253273 case ( . lhs( . extension) , let handle) ? :
254- return RawDeclSyntax ( self . parseExtensionDeclaration ( attrs, handle) )
274+ return RawDeclSyntax ( self . parseExtensionDeclaration ( attrs, handle, parseContext : parseContext ) )
255275 case ( . lhs( . func) , let handle) ? :
256276 return RawDeclSyntax ( self . parseFuncDeclaration ( attrs, handle) )
257277 case ( . lhs( . subscript) , let handle) ? :
@@ -266,19 +286,19 @@ extension Parser {
266286 return RawDeclSyntax ( self . parsePrecedenceGroupDeclaration ( attrs, handle) )
267287 case ( . lhs( . actor ) , let handle) ? :
268288 return RawDeclSyntax (
269- self . parseNominalTypeDeclaration ( for: RawActorDeclSyntax . self, attrs: attrs, introucerHandle: handle)
289+ self . parseNominalTypeDeclaration ( for: RawActorDeclSyntax . self, attrs: attrs, introucerHandle: handle, parseContext : parseContext )
270290 )
271291 case ( . lhs( . macro) , let handle) ? :
272292 return RawDeclSyntax ( self . parseMacroDeclaration ( attrs: attrs, introducerHandle: handle) )
273293 case ( . lhs( . pound) , let handle) ? :
274294 return RawDeclSyntax ( self . parseMacroExpansionDeclaration ( attrs, handle) )
275295 case ( . rhs, let handle) ? :
276- return RawDeclSyntax ( self . parseBindingDeclaration ( attrs, handle, inMemberDeclList: inMemberDeclList ) )
296+ return RawDeclSyntax ( self . parseBindingDeclaration ( attrs, handle, inMemberDeclList: parseContext != . topLevelCode ) )
277297 case nil :
278298 break
279299 }
280300
281- if inMemberDeclList {
301+ if parseContext != . topLevelCode {
282302 let isProbablyVarDecl = self . at ( . identifier, . wildcard) && self . peek ( isAt: . colon, . equal, . comma)
283303 let isProbablyTupleDecl = self . at ( . leftParen) && self . peek ( isAt: . identifier, . wildcard)
284304
@@ -377,7 +397,8 @@ extension Parser {
377397 /// Parse an extension declaration.
378398 mutating func parseExtensionDeclaration(
379399 _ attrs: DeclAttributes ,
380- _ handle: RecoveryConsumptionHandle
400+ _ handle: RecoveryConsumptionHandle ,
401+ parseContext: DeclarationParsingContext
381402 ) -> RawExtensionDeclSyntax {
382403 let ( unexpectedBeforeExtensionKeyword, extensionKeyword) = self . eat ( handle)
383404 let type = self . parseType ( )
@@ -395,7 +416,12 @@ extension Parser {
395416 } else {
396417 whereClause = nil
397418 }
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+ }
399425 return RawExtensionDeclSyntax (
400426 attributes: attrs. attributes,
401427 modifiers: attrs. modifiers,
@@ -746,7 +772,7 @@ extension Parser {
746772 if self . at ( . poundSourceLocation) {
747773 decl = RawDeclSyntax ( self . parsePoundSourceLocationDirective ( ) )
748774 } else {
749- decl = self . parseDeclaration ( inMemberDeclList : true )
775+ decl = self . parseDeclaration ( in : . memberList )
750776 }
751777
752778 let semi = self . consume ( if: . semicolon)
0 commit comments