@@ -30,24 +30,30 @@ extension DeclarationModifier {
30
30
31
31
extension TokenConsumer {
32
32
mutating func atStartOfFreestandingMacroExpansion( ) -> Bool {
33
+ // Check if "'#' <identifier>" where the identifier is on the sameline.
33
34
if !self . at ( . pound) {
34
35
return false
35
36
}
36
- if self . peek ( ) . rawTokenKind != . identifier && ! self . peek ( ) . isLexerClassifiedKeyword {
37
+ if self . peek ( ) . isAtStartOfLine {
37
38
return false
38
39
}
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 :
40
47
return false
41
48
}
42
- return true
43
49
}
44
50
45
51
mutating func atStartOfDeclaration(
46
52
isAtTopLevel: Bool = false ,
47
53
allowInitDecl: Bool = true ,
48
54
allowRecovery: Bool = false
49
55
) -> Bool {
50
- if self . at ( anyIn : PoundDeclarationStart . self ) != nil {
56
+ if self . at ( . poundIfKeyword ) {
51
57
return true
52
58
}
53
59
@@ -190,13 +196,9 @@ extension Parser {
190
196
/// declaration and thus start with a keyword. This allows futher recovery.
191
197
@_spi ( RawSyntax)
192
198
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 ( ) } ) {
200
202
let directive = self . parsePoundIfDirective { ( parser, _) in
201
203
let parsedDecl = parser. parseDeclaration ( )
202
204
let semicolon = parser. consume ( if: . semicolon)
@@ -222,8 +224,6 @@ extension Parser {
222
224
return . decls( RawMemberDeclListSyntax ( elements: elements, arena: parser. arena) )
223
225
}
224
226
return RawDeclSyntax ( directive)
225
- case nil :
226
- break
227
227
}
228
228
229
229
let attrs = DeclAttributes (
@@ -2045,25 +2045,24 @@ extension Parser {
2045
2045
_ handle: RecoveryConsumptionHandle
2046
2046
) -> RawMacroExpansionDeclSyntax {
2047
2047
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 )
2065
2065
}
2066
- let ( unexpectedBeforeMacro, macro) = self . expectIdentifier ( keywordRecovery: true )
2067
2066
2068
2067
// Parse the optional generic argument list.
2069
2068
let generics : RawGenericArgumentClauseSyntax ?
@@ -2104,7 +2103,7 @@ extension Parser {
2104
2103
attributes: attrs. attributes,
2105
2104
modifiers: attrs. modifiers,
2106
2105
unexpectedBeforePound,
2107
- poundToken: poundKeyword ,
2106
+ poundToken: pound ,
2108
2107
unexpectedBeforeMacro,
2109
2108
macro: macro,
2110
2109
genericArguments: generics,
0 commit comments