@@ -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 (
@@ -2022,25 +2022,24 @@ extension Parser {
2022
2022
_ handle: RecoveryConsumptionHandle
2023
2023
) -> RawMacroExpansionDeclSyntax {
2024
2024
2025
- let ( unexpectedBeforePound, poundKeyword ) = self . eat ( handle)
2026
- // Don't allow space between '#' and the macro name.
2027
- if poundKeyword . trailingTriviaByteLength != 0 || self . currentToken . leadingTriviaByteLength != 0 {
2028
- return RawMacroExpansionDeclSyntax (
2029
- attributes : attrs . attributes ,
2030
- modifiers : attrs . modifiers ,
2031
- unexpectedBeforePound ,
2032
- poundToken : poundKeyword ,
2033
- macro : self . missingToken ( . identifier ) ,
2034
- genericArguments : nil ,
2035
- leftParen : nil ,
2036
- argumentList : . init ( elements : [ ] , arena: self . arena) ,
2037
- rightParen : nil ,
2038
- trailingClosure : nil ,
2039
- additionalTrailingClosures : nil ,
2040
- arena : self . arena
2041
- )
2025
+ var ( unexpectedBeforePound, pound ) = self . eat ( handle)
2026
+ if pound . trailingTriviaByteLength != 0 {
2027
+ // `#` and the macro name must not be separated by a newline.
2028
+ unexpectedBeforePound = RawUnexpectedNodesSyntax ( combining : unexpectedBeforePound , pound , arena : self . arena )
2029
+ pound = RawTokenSyntax ( missing : . pound , text : " # " , leadingTriviaPieces : pound . leadingTriviaPieces , arena : self . arena )
2030
+ }
2031
+ var unexpectedBeforeMacro : RawUnexpectedNodesSyntax ?
2032
+ var macro : RawTokenSyntax
2033
+ if ! self . currentToken . isAtStartOfLine {
2034
+ ( unexpectedBeforeMacro , macro ) = self . expectIdentifier ( keywordRecovery : true )
2035
+ if macro . leadingTriviaByteLength != 0 {
2036
+ unexpectedBeforeMacro = RawUnexpectedNodesSyntax ( combining : unexpectedBeforeMacro , macro , arena: self . arena)
2037
+ pound = self . missingToken ( . identifier , text : macro . tokenText )
2038
+ }
2039
+ } else {
2040
+ unexpectedBeforeMacro = nil
2041
+ macro = self . missingToken ( . identifier )
2042
2042
}
2043
- let ( unexpectedBeforeMacro, macro) = self . expectIdentifier ( keywordRecovery: true )
2044
2043
2045
2044
// Parse the optional generic argument list.
2046
2045
let generics : RawGenericArgumentClauseSyntax ?
@@ -2081,7 +2080,7 @@ extension Parser {
2081
2080
attributes: attrs. attributes,
2082
2081
modifiers: attrs. modifiers,
2083
2082
unexpectedBeforePound,
2084
- poundToken: poundKeyword ,
2083
+ poundToken: pound ,
2085
2084
unexpectedBeforeMacro,
2086
2085
macro: macro,
2087
2086
genericArguments: generics,
0 commit comments