@@ -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 (
@@ -2090,25 +2090,24 @@ extension Parser {
2090
2090
_ handle: RecoveryConsumptionHandle
2091
2091
) -> RawMacroExpansionDeclSyntax {
2092
2092
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 )
2110
2110
}
2111
- let ( unexpectedBeforeMacro, macro) = self . expectIdentifier ( keywordRecovery: true )
2112
2111
2113
2112
// Parse the optional generic argument list.
2114
2113
let generics : RawGenericArgumentClauseSyntax ?
@@ -2149,7 +2148,7 @@ extension Parser {
2149
2148
attributes: attrs. attributes,
2150
2149
modifiers: attrs. modifiers,
2151
2150
unexpectedBeforePound,
2152
- poundToken: poundKeyword ,
2151
+ poundToken: pound ,
2153
2152
unexpectedBeforeMacro,
2154
2153
macro: macro,
2155
2154
genericArguments: generics,
0 commit comments