@@ -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 (
@@ -2090,25 +2090,24 @@ extension Parser {
20902090 _ handle: RecoveryConsumptionHandle
20912091 ) -> RawMacroExpansionDeclSyntax {
20922092
2093- let ( unexpectedBeforePound, poundKeyword ) = self . eat ( handle)
2094- // Don't allow space between '#' and the macro name.
2095- if poundKeyword . trailingTriviaByteLength != 0 || self . currentToken . leadingTriviaByteLength != 0 {
2096- return RawMacroExpansionDeclSyntax (
2097- attributes : attrs . attributes ,
2098- modifiers : attrs . modifiers ,
2099- unexpectedBeforePound ,
2100- poundToken : poundKeyword ,
2101- macro : self . missingToken ( . identifier ) ,
2102- genericArguments : nil ,
2103- leftParen : nil ,
2104- argumentList : . init ( elements : [ ] , arena: self . arena) ,
2105- rightParen : nil ,
2106- trailingClosure : nil ,
2107- additionalTrailingClosures : nil ,
2108- arena : self . arena
2109- )
2093+ var ( unexpectedBeforePound, pound ) = self . eat ( handle)
2094+ if pound . trailingTriviaByteLength != 0 {
2095+ // `#` and the macro name must not be separated by a newline.
2096+ unexpectedBeforePound = RawUnexpectedNodesSyntax ( combining : unexpectedBeforePound , pound , arena : self . arena )
2097+ pound = RawTokenSyntax ( missing : . pound , text : " # " , leadingTriviaPieces : pound . leadingTriviaPieces , arena : self . arena )
2098+ }
2099+ var unexpectedBeforeMacro : RawUnexpectedNodesSyntax ?
2100+ var macro : RawTokenSyntax
2101+ if ! self . currentToken . isAtStartOfLine {
2102+ ( unexpectedBeforeMacro , macro ) = self . expectIdentifier ( keywordRecovery : true )
2103+ if macro . leadingTriviaByteLength != 0 {
2104+ unexpectedBeforeMacro = RawUnexpectedNodesSyntax ( combining : unexpectedBeforeMacro , macro , arena: self . arena)
2105+ pound = self . missingToken ( . identifier , text : macro . tokenText )
2106+ }
2107+ } else {
2108+ unexpectedBeforeMacro = nil
2109+ macro = self . missingToken ( . identifier )
21102110 }
2111- let ( unexpectedBeforeMacro, macro) = self . expectIdentifier ( keywordRecovery: true )
21122111
21132112 // Parse the optional generic argument list.
21142113 let generics : RawGenericArgumentClauseSyntax ?
@@ -2149,7 +2148,7 @@ extension Parser {
21492148 attributes: attrs. attributes,
21502149 modifiers: attrs. modifiers,
21512150 unexpectedBeforePound,
2152- poundToken: poundKeyword ,
2151+ poundToken: pound ,
21532152 unexpectedBeforeMacro,
21542153 macro: macro,
21552154 genericArguments: generics,
0 commit comments