@@ -30,24 +30,30 @@ extension DeclarationModifier {
3030
3131extension TokenConsumer {
3232 mutating func atStartOfFreestandingMacroExpansion( ) -> Bool {
33+ // Check if "'#' <identifier>" where the identifier is on the sameline.
3334 if !self . at ( . pound) {
3435 return false
3536 }
36- if self . peek ( ) . rawTokenKind != . identifier && ! self . peek ( ) . isLexerClassifiedKeyword {
37+ if self . peek ( ) . isAtStartOfLine {
3738 return false
3839 }
39- if self . currentToken. trailingTriviaByteLength != 0 || self . peek ( ) . leadingTriviaByteLength != 0 {
40+ switch self . peek ( ) . rawTokenKind {
41+ case . identifier:
42+ return true
43+ case . keyword:
44+ // allow keywords right after '#' so we can diagnose it when parsing.
45+ return ( self . currentToken. trailingTriviaByteLength == 0 && self . peek ( ) . leadingTriviaByteLength == 0 )
46+ default :
4047 return false
4148 }
42- return true
4349 }
4450
4551 mutating func atStartOfDeclaration(
4652 isAtTopLevel: Bool = false ,
4753 allowInitDecl: Bool = true ,
4854 allowRecovery: Bool = false
4955 ) -> Bool {
50- if self . at ( anyIn : PoundDeclarationStart . self ) != nil {
56+ if self . at ( . poundIfKeyword ) {
5157 return true
5258 }
5359
@@ -190,13 +196,9 @@ extension Parser {
190196 /// declaration and thus start with a keyword. This allows futher recovery.
191197 @_spi ( RawSyntax)
192198 public mutating func parseDeclaration( inMemberDeclList: Bool = false ) -> RawDeclSyntax {
193- switch self . at ( anyIn: PoundDeclarationStart . self) {
194- case ( . poundIfKeyword, _) ? :
195- if self . withLookahead ( { $0. consumeIfConfigOfAttributes ( ) } ) {
196- // If we are at a `#if` of attributes, the `#if` directive should be
197- // parsed when we're parsing the attributes.
198- break
199- }
199+ // If we are at a `#if` of attributes, the `#if` directive should be
200+ // parsed when we're parsing the attributes.
201+ if self . at ( . poundIfKeyword) && !self . withLookahead ( { $0. consumeIfConfigOfAttributes ( ) } ) {
200202 let directive = self . parsePoundIfDirective { ( parser, _) in
201203 let parsedDecl = parser. parseDeclaration ( )
202204 let semicolon = parser. consume ( if: . semicolon)
@@ -222,8 +224,6 @@ extension Parser {
222224 return . decls( RawMemberDeclListSyntax ( elements: elements, arena: parser. arena) )
223225 }
224226 return RawDeclSyntax ( directive)
225- case nil :
226- break
227227 }
228228
229229 let attrs = DeclAttributes (
@@ -2045,25 +2045,24 @@ extension Parser {
20452045 _ handle: RecoveryConsumptionHandle
20462046 ) -> RawMacroExpansionDeclSyntax {
20472047
2048- let ( unexpectedBeforePound, poundKeyword ) = self . eat ( handle)
2049- // Don't allow space between '#' and the macro name.
2050- if poundKeyword . trailingTriviaByteLength != 0 || self . currentToken . leadingTriviaByteLength != 0 {
2051- return RawMacroExpansionDeclSyntax (
2052- attributes : attrs . attributes ,
2053- modifiers : attrs . modifiers ,
2054- unexpectedBeforePound ,
2055- poundToken : poundKeyword ,
2056- macro : self . missingToken ( . identifier ) ,
2057- genericArguments : nil ,
2058- leftParen : nil ,
2059- argumentList : . init ( elements : [ ] , arena: self . arena) ,
2060- rightParen : nil ,
2061- trailingClosure : nil ,
2062- additionalTrailingClosures : nil ,
2063- arena : self . arena
2064- )
2048+ var ( unexpectedBeforePound, pound ) = self . eat ( handle)
2049+ if pound . trailingTriviaByteLength != 0 {
2050+ // `#` and the macro name must not be separated by a newline.
2051+ unexpectedBeforePound = RawUnexpectedNodesSyntax ( combining : unexpectedBeforePound , pound , arena : self . arena )
2052+ pound = RawTokenSyntax ( missing : . pound , text : " # " , leadingTriviaPieces : pound . leadingTriviaPieces , arena : self . arena )
2053+ }
2054+ var unexpectedBeforeMacro : RawUnexpectedNodesSyntax ?
2055+ var macro : RawTokenSyntax
2056+ if ! self . currentToken . isAtStartOfLine {
2057+ ( unexpectedBeforeMacro , macro ) = self . expectIdentifier ( keywordRecovery : true )
2058+ if macro . leadingTriviaByteLength != 0 {
2059+ unexpectedBeforeMacro = RawUnexpectedNodesSyntax ( combining : unexpectedBeforeMacro , macro , arena: self . arena)
2060+ pound = self . missingToken ( . identifier , text : macro . tokenText )
2061+ }
2062+ } else {
2063+ unexpectedBeforeMacro = nil
2064+ macro = self . missingToken ( . identifier )
20652065 }
2066- let ( unexpectedBeforeMacro, macro) = self . expectIdentifier ( keywordRecovery: true )
20672066
20682067 // Parse the optional generic argument list.
20692068 let generics : RawGenericArgumentClauseSyntax ?
@@ -2104,7 +2103,7 @@ extension Parser {
21042103 attributes: attrs. attributes,
21052104 modifiers: attrs. modifiers,
21062105 unexpectedBeforePound,
2107- poundToken: poundKeyword ,
2106+ poundToken: pound ,
21082107 unexpectedBeforeMacro,
21092108 macro: macro,
21102109 genericArguments: generics,
0 commit comments