@@ -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
@@ -188,13 +194,9 @@ extension Parser {
188194 /// If `inMemberDeclList` is `true`, we know that the next item must be a
189195 /// declaration and thus start with a keyword. This allows futher recovery.
190196 mutating func parseDeclaration( inMemberDeclList: Bool = false ) -> RawDeclSyntax {
191- switch self . at ( anyIn: PoundDeclarationStart . self) {
192- case ( . poundIfKeyword, _) ? :
193- if self . withLookahead ( { $0. consumeIfConfigOfAttributes ( ) } ) {
194- // If we are at a `#if` of attributes, the `#if` directive should be
195- // parsed when we're parsing the attributes.
196- break
197- }
197+ // If we are at a `#if` of attributes, the `#if` directive should be
198+ // parsed when we're parsing the attributes.
199+ if self . at ( . poundIfKeyword) && !self . withLookahead ( { $0. consumeIfConfigOfAttributes ( ) } ) {
198200 let directive = self . parsePoundIfDirective { ( parser, _) in
199201 let parsedDecl = parser. parseDeclaration ( )
200202 let semicolon = parser. consume ( if: . semicolon)
@@ -220,8 +222,6 @@ extension Parser {
220222 return . decls( RawMemberDeclListSyntax ( elements: elements, arena: parser. arena) )
221223 }
222224 return RawDeclSyntax ( directive)
223- case nil :
224- break
225225 }
226226
227227 let attrs = DeclAttributes (
@@ -2096,25 +2096,24 @@ extension Parser {
20962096 _ handle: RecoveryConsumptionHandle
20972097 ) -> RawMacroExpansionDeclSyntax {
20982098
2099- let ( unexpectedBeforePound, poundKeyword ) = self . eat ( handle)
2100- // Don't allow space between '#' and the macro name.
2101- if poundKeyword . trailingTriviaByteLength != 0 || self . currentToken . leadingTriviaByteLength != 0 {
2102- return RawMacroExpansionDeclSyntax (
2103- attributes : attrs . attributes ,
2104- modifiers : attrs . modifiers ,
2105- unexpectedBeforePound ,
2106- poundToken : poundKeyword ,
2107- macro : self . missingToken ( . identifier ) ,
2108- genericArguments : nil ,
2109- leftParen : nil ,
2110- argumentList : . init ( elements : [ ] , arena: self . arena) ,
2111- rightParen : nil ,
2112- trailingClosure : nil ,
2113- additionalTrailingClosures : nil ,
2114- arena : self . arena
2115- )
2099+ var ( unexpectedBeforePound, pound ) = self . eat ( handle)
2100+ if pound . trailingTriviaByteLength != 0 {
2101+ // `#` and the macro name must not be separated by a newline.
2102+ unexpectedBeforePound = RawUnexpectedNodesSyntax ( combining : unexpectedBeforePound , pound , arena : self . arena )
2103+ pound = RawTokenSyntax ( missing : . pound , text : " # " , leadingTriviaPieces : pound . leadingTriviaPieces , arena : self . arena )
2104+ }
2105+ var unexpectedBeforeMacro : RawUnexpectedNodesSyntax ?
2106+ var macro : RawTokenSyntax
2107+ if ! self . currentToken . isAtStartOfLine {
2108+ ( unexpectedBeforeMacro , macro ) = self . expectIdentifier ( keywordRecovery : true )
2109+ if macro . leadingTriviaByteLength != 0 {
2110+ unexpectedBeforeMacro = RawUnexpectedNodesSyntax ( combining : unexpectedBeforeMacro , macro , arena: self . arena)
2111+ pound = self . missingToken ( . identifier , text : macro . tokenText )
2112+ }
2113+ } else {
2114+ unexpectedBeforeMacro = nil
2115+ macro = self . missingToken ( . identifier )
21162116 }
2117- let ( unexpectedBeforeMacro, macro) = self . expectIdentifier ( keywordRecovery: true )
21182117
21192118 // Parse the optional generic argument list.
21202119 let generics : RawGenericArgumentClauseSyntax ?
@@ -2155,7 +2154,7 @@ extension Parser {
21552154 attributes: attrs. attributes,
21562155 modifiers: attrs. modifiers,
21572156 unexpectedBeforePound,
2158- poundToken: poundKeyword ,
2157+ poundToken: pound ,
21592158 unexpectedBeforeMacro,
21602159 macro: macro,
21612160 genericArguments: generics,
0 commit comments