@@ -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
@@ -188,13 +194,9 @@ extension Parser {
188
194
/// If `inMemberDeclList` is `true`, we know that the next item must be a
189
195
/// declaration and thus start with a keyword. This allows futher recovery.
190
196
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 ( ) } ) {
198
200
let directive = self . parsePoundIfDirective { ( parser, _) in
199
201
let parsedDecl = parser. parseDeclaration ( )
200
202
let semicolon = parser. consume ( if: . semicolon)
@@ -220,8 +222,6 @@ extension Parser {
220
222
return . decls( RawMemberDeclListSyntax ( elements: elements, arena: parser. arena) )
221
223
}
222
224
return RawDeclSyntax ( directive)
223
- case nil :
224
- break
225
225
}
226
226
227
227
let attrs = DeclAttributes (
@@ -2096,25 +2096,24 @@ extension Parser {
2096
2096
_ handle: RecoveryConsumptionHandle
2097
2097
) -> RawMacroExpansionDeclSyntax {
2098
2098
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 )
2116
2116
}
2117
- let ( unexpectedBeforeMacro, macro) = self . expectIdentifier ( keywordRecovery: true )
2118
2117
2119
2118
// Parse the optional generic argument list.
2120
2119
let generics : RawGenericArgumentClauseSyntax ?
@@ -2155,7 +2154,7 @@ extension Parser {
2155
2154
attributes: attrs. attributes,
2156
2155
modifiers: attrs. modifiers,
2157
2156
unexpectedBeforePound,
2158
- poundToken: poundKeyword ,
2157
+ poundToken: pound ,
2159
2158
unexpectedBeforeMacro,
2160
2159
macro: macro,
2161
2160
genericArguments: generics,
0 commit comments