Skip to content

Commit 0b2562a

Browse files
committed
[Parser] Attributes on MacroExpansionDeclSyntax
* Add `attributes` and `modifiers` to `MacroExpansionDeclSyntax` * Diagnose whitespaces between # and the macro name * Attach attributes to MacroExpansionDeclSyntax rdar://107386648
1 parent 8cd23e5 commit 0b2562a

File tree

12 files changed

+351
-113
lines changed

12 files changed

+351
-113
lines changed

CodeGeneration/Sources/SyntaxSupport/DeclNodes.swift

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1278,6 +1278,18 @@ public let DECL_NODES: [Node] = [
12781278
"FreestandingMacroExpansion"
12791279
],
12801280
children: [
1281+
Child(
1282+
name: "Attributes",
1283+
kind: .collection(kind: "AttributeList", collectionElementName: "Attribute"),
1284+
nameForDiagnostics: "attributes",
1285+
isOptional: true
1286+
),
1287+
Child(
1288+
name: "Modifiers",
1289+
kind: .collection(kind: "ModifierList", collectionElementName: "Modifier"),
1290+
nameForDiagnostics: "modifiers",
1291+
isOptional: true
1292+
),
12811293
Child(
12821294
name: "PoundToken",
12831295
kind: .token(choices: [.token(tokenKind: "PoundToken")]),

Sources/SwiftParser/Declarations.swift

Lines changed: 51 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -29,18 +29,25 @@ extension DeclarationModifier {
2929
}
3030

3131
extension TokenConsumer {
32+
mutating func atStartOfFreestandingMacroExpansion() -> Bool {
33+
if !self.at(.pound) {
34+
return false
35+
}
36+
if self.peek().rawTokenKind != .identifier && !self.peek().isLexerClassifiedKeyword {
37+
return false
38+
}
39+
if self.currentToken.trailingTriviaByteLength != 0 || self.peek().leadingTriviaByteLength != 0 {
40+
return false
41+
}
42+
return true
43+
}
44+
3245
mutating func atStartOfDeclaration(
3346
isAtTopLevel: Bool = false,
3447
allowInitDecl: Bool = true,
3548
allowRecovery: Bool = false
3649
) -> Bool {
3750
if self.at(anyIn: PoundDeclarationStart.self) != nil {
38-
// Don't treat freestanding macro expansions as declarations. They'll be
39-
// parsed as expressions.
40-
if self.at(.pound) {
41-
return false
42-
}
43-
4451
return true
4552
}
4653

@@ -113,6 +120,16 @@ extension TokenConsumer {
113120
case .macroKeyword:
114121
// macro Foo ...
115122
return subparser.peek().rawTokenKind == .identifier
123+
case .pound:
124+
// Force parsing '#<identifier>' after attributes as a macro expansion decl.
125+
if hasAttribute {
126+
return true
127+
}
128+
129+
// Otherwise, parse it as a expression.
130+
// FIXME: C++ parser returns true if this is a top-level non-"script" files.
131+
// But we don't have "is library" flag.
132+
return false
116133
case .some(_):
117134
// All other decl start keywords unconditonally start a decl.
118135
return true
@@ -203,10 +220,6 @@ extension Parser {
203220
return .decls(RawMemberDeclListSyntax(elements: elements, arena: parser.arena))
204221
}
205222
return RawDeclSyntax(directive)
206-
case (.pound, _)?:
207-
// FIXME: If we can have attributes for macro expansions, handle this
208-
// via DeclarationStart.
209-
return RawDeclSyntax(self.parseMacroExpansionDeclaration())
210223
case nil:
211224
break
212225
}
@@ -258,6 +271,8 @@ extension Parser {
258271
return RawDeclSyntax(self.parseNominalTypeDeclaration(for: RawActorDeclSyntax.self, attrs: attrs, introucerHandle: handle))
259272
case (.macroKeyword, let handle)?:
260273
return RawDeclSyntax(self.parseMacroDeclaration(attrs: attrs, introducerHandle: handle))
274+
case (.pound, let handle)?:
275+
return RawDeclSyntax(self.parseMacroExpansionDeclaration(attrs, handle))
261276
case nil:
262277
if inMemberDeclList {
263278
let isProbablyVarDecl = self.at(.identifier, .wildcard) && self.peek().rawTokenKind.is(.colon, .equal, .comma)
@@ -2023,9 +2038,29 @@ extension Parser {
20232038
/// =======
20242039
///
20252040
/// macro-expansion-declaration → '#' identifier expr-call-suffix?
2026-
mutating func parseMacroExpansionDeclaration() -> RawMacroExpansionDeclSyntax {
2027-
let poundKeyword = self.consumeAnyToken()
2028-
let (unexpectedBeforeMacro, macro) = self.expectIdentifier()
2041+
mutating func parseMacroExpansionDeclaration(
2042+
_ attrs: DeclAttributes,
2043+
_ handle: RecoveryConsumptionHandle
2044+
) -> RawMacroExpansionDeclSyntax {
2045+
2046+
let (unexpectedBeforePound, poundKeyword) = self.eat(handle)
2047+
// Don't allow space between '#' and the macro name.
2048+
if poundKeyword.trailingTriviaByteLength != 0 || self.currentToken.leadingTriviaByteLength != 0 {
2049+
return RawMacroExpansionDeclSyntax(
2050+
attributes: attrs.attributes,
2051+
modifiers: attrs.modifiers,
2052+
unexpectedBeforePound,
2053+
poundToken: poundKeyword,
2054+
macro: self.missingToken(.identifier),
2055+
genericArguments: nil,
2056+
leftParen: nil,
2057+
argumentList: .init(elements: [], arena: self.arena),
2058+
rightParen: nil, trailingClosure: nil,
2059+
additionalTrailingClosures: nil,
2060+
arena: self.arena
2061+
)
2062+
}
2063+
let (unexpectedBeforeMacro, macro) = self.expectIdentifier(keywordRecovery: true)
20292064

20302065
// Parse the optional generic argument list.
20312066
let generics: RawGenericArgumentClauseSyntax?
@@ -2063,6 +2098,9 @@ extension Parser {
20632098
}
20642099

20652100
return RawMacroExpansionDeclSyntax(
2101+
attributes: attrs.attributes,
2102+
modifiers: attrs.modifiers,
2103+
unexpectedBeforePound,
20662104
poundToken: poundKeyword,
20672105
unexpectedBeforeMacro,
20682106
macro: macro,

Sources/SwiftParser/Expressions.swift

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1394,8 +1394,21 @@ extension Parser {
13941394
pattern: PatternContext,
13951395
flavor: ExprFlavor
13961396
) -> RawMacroExpansionExprSyntax {
1397+
if !atStartOfFreestandingMacroExpansion() {
1398+
return RawMacroExpansionExprSyntax(
1399+
poundToken: self.consumeAnyToken(),
1400+
macro: self.missingToken(.identifier),
1401+
genericArguments: nil,
1402+
leftParen: nil,
1403+
argumentList: .init(elements: [], arena: self.arena),
1404+
rightParen: nil,
1405+
trailingClosure: nil,
1406+
additionalTrailingClosures: nil,
1407+
arena: self.arena
1408+
)
1409+
}
13971410
let poundKeyword = self.consumeAnyToken()
1398-
let (unexpectedBeforeMacro, macro) = self.expectIdentifier()
1411+
let (unexpectedBeforeMacro, macro) = self.expectIdentifier(keywordRecovery: true)
13991412

14001413
// Parse the optional generic argument list.
14011414
let generics: RawGenericArgumentClauseSyntax?

Sources/SwiftParser/TokenSpecSet.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -272,6 +272,7 @@ enum DeclarationStart: TokenSpecSet {
272272
case typealiasKeyword
273273
case varKeyword
274274
case inoutKeyword
275+
case pound
275276

276277
init?(lexeme: Lexer.Lexeme) {
277278
switch PrepareForKeywordMatch(lexeme) {
@@ -295,6 +296,7 @@ enum DeclarationStart: TokenSpecSet {
295296
case TokenSpec(.typealias): self = .typealiasKeyword
296297
case TokenSpec(.var): self = .varKeyword
297298
case TokenSpec(.inout): self = .inoutKeyword
299+
case TokenSpec(.pound): self = .pound
298300
default: return nil
299301
}
300302
}
@@ -321,6 +323,7 @@ enum DeclarationStart: TokenSpecSet {
321323
case .typealiasKeyword: return .keyword(.typealias)
322324
case .varKeyword: return .keyword(.var)
323325
case .inoutKeyword: return TokenSpec(.inout, recoveryPrecedence: .declKeyword)
326+
case .pound: return TokenSpec(.pound, recoveryPrecedence: .openingPoundIf)
324327
}
325328
}
326329
}
@@ -396,20 +399,17 @@ enum OperatorLike: TokenSpecSet {
396399

397400
enum PoundDeclarationStart: TokenSpecSet {
398401
case poundIfKeyword
399-
case pound
400402

401403
init?(lexeme: Lexer.Lexeme) {
402404
switch lexeme.rawTokenKind {
403405
case .poundIfKeyword: self = .poundIfKeyword
404-
case .pound: self = .pound
405406
default: return nil
406407
}
407408
}
408409

409410
var spec: TokenSpec {
410411
switch self {
411412
case .poundIfKeyword: return .poundIfKeyword
412-
case .pound: return .pound
413413
}
414414
}
415415
}

Sources/SwiftParserDiagnostics/generated/ChildNameForDiagnostics.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,10 @@ private func childNameForDiagnostics(_ keyPath: AnyKeyPath) -> String? {
236236
return "macro definition"
237237
case \MacroDeclSyntax.genericWhereClause:
238238
return "generic where clause"
239+
case \MacroExpansionDeclSyntax.attributes:
240+
return "attributes"
241+
case \MacroExpansionDeclSyntax.modifiers:
242+
return "modifiers"
239243
case \MemberAccessExprSyntax.base:
240244
return "base"
241245
case \MemberAccessExprSyntax.name:

Sources/SwiftSyntax/generated/ChildNameForKeyPath.swift

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1995,8 +1995,16 @@ public func childName(_ keyPath: AnyKeyPath) -> String? {
19951995
return "genericWhereClause"
19961996
case \MacroDeclSyntax.unexpectedAfterGenericWhereClause:
19971997
return "unexpectedAfterGenericWhereClause"
1998-
case \MacroExpansionDeclSyntax.unexpectedBeforePoundToken:
1999-
return "unexpectedBeforePoundToken"
1998+
case \MacroExpansionDeclSyntax.unexpectedBeforeAttributes:
1999+
return "unexpectedBeforeAttributes"
2000+
case \MacroExpansionDeclSyntax.attributes:
2001+
return "attributes"
2002+
case \MacroExpansionDeclSyntax.unexpectedBetweenAttributesAndModifiers:
2003+
return "unexpectedBetweenAttributesAndModifiers"
2004+
case \MacroExpansionDeclSyntax.modifiers:
2005+
return "modifiers"
2006+
case \MacroExpansionDeclSyntax.unexpectedBetweenModifiersAndPoundToken:
2007+
return "unexpectedBetweenModifiersAndPoundToken"
20002008
case \MacroExpansionDeclSyntax.poundToken:
20012009
return "poundToken"
20022010
case \MacroExpansionDeclSyntax.unexpectedBetweenPoundTokenAndMacro:

Sources/SwiftSyntax/generated/raw/RawSyntaxNodes.swift

Lines changed: 60 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -13322,7 +13322,11 @@ public struct RawMacroExpansionDeclSyntax: RawDeclSyntaxNodeProtocol {
1332213322
}
1332313323

1332413324
public init(
13325-
_ unexpectedBeforePoundToken: RawUnexpectedNodesSyntax? = nil,
13325+
_ unexpectedBeforeAttributes: RawUnexpectedNodesSyntax? = nil,
13326+
attributes: RawAttributeListSyntax?,
13327+
_ unexpectedBetweenAttributesAndModifiers: RawUnexpectedNodesSyntax? = nil,
13328+
modifiers: RawModifierListSyntax?,
13329+
_ unexpectedBetweenModifiersAndPoundToken: RawUnexpectedNodesSyntax? = nil,
1332613330
poundToken: RawTokenSyntax,
1332713331
_ unexpectedBetweenPoundTokenAndMacro: RawUnexpectedNodesSyntax? = nil,
1332813332
macro: RawTokenSyntax,
@@ -13342,95 +13346,115 @@ public struct RawMacroExpansionDeclSyntax: RawDeclSyntaxNodeProtocol {
1334213346
arena: __shared SyntaxArena
1334313347
) {
1334413348
let raw = RawSyntax.makeLayout(
13345-
kind: .macroExpansionDecl, uninitializedCount: 17, arena: arena) { layout in
13349+
kind: .macroExpansionDecl, uninitializedCount: 21, arena: arena) { layout in
1334613350
layout.initialize(repeating: nil)
13347-
layout[0] = unexpectedBeforePoundToken?.raw
13348-
layout[1] = poundToken.raw
13349-
layout[2] = unexpectedBetweenPoundTokenAndMacro?.raw
13350-
layout[3] = macro.raw
13351-
layout[4] = unexpectedBetweenMacroAndGenericArguments?.raw
13352-
layout[5] = genericArguments?.raw
13353-
layout[6] = unexpectedBetweenGenericArgumentsAndLeftParen?.raw
13354-
layout[7] = leftParen?.raw
13355-
layout[8] = unexpectedBetweenLeftParenAndArgumentList?.raw
13356-
layout[9] = argumentList.raw
13357-
layout[10] = unexpectedBetweenArgumentListAndRightParen?.raw
13358-
layout[11] = rightParen?.raw
13359-
layout[12] = unexpectedBetweenRightParenAndTrailingClosure?.raw
13360-
layout[13] = trailingClosure?.raw
13361-
layout[14] = unexpectedBetweenTrailingClosureAndAdditionalTrailingClosures?.raw
13362-
layout[15] = additionalTrailingClosures?.raw
13363-
layout[16] = unexpectedAfterAdditionalTrailingClosures?.raw
13351+
layout[0] = unexpectedBeforeAttributes?.raw
13352+
layout[1] = attributes?.raw
13353+
layout[2] = unexpectedBetweenAttributesAndModifiers?.raw
13354+
layout[3] = modifiers?.raw
13355+
layout[4] = unexpectedBetweenModifiersAndPoundToken?.raw
13356+
layout[5] = poundToken.raw
13357+
layout[6] = unexpectedBetweenPoundTokenAndMacro?.raw
13358+
layout[7] = macro.raw
13359+
layout[8] = unexpectedBetweenMacroAndGenericArguments?.raw
13360+
layout[9] = genericArguments?.raw
13361+
layout[10] = unexpectedBetweenGenericArgumentsAndLeftParen?.raw
13362+
layout[11] = leftParen?.raw
13363+
layout[12] = unexpectedBetweenLeftParenAndArgumentList?.raw
13364+
layout[13] = argumentList.raw
13365+
layout[14] = unexpectedBetweenArgumentListAndRightParen?.raw
13366+
layout[15] = rightParen?.raw
13367+
layout[16] = unexpectedBetweenRightParenAndTrailingClosure?.raw
13368+
layout[17] = trailingClosure?.raw
13369+
layout[18] = unexpectedBetweenTrailingClosureAndAdditionalTrailingClosures?.raw
13370+
layout[19] = additionalTrailingClosures?.raw
13371+
layout[20] = unexpectedAfterAdditionalTrailingClosures?.raw
1336413372
}
1336513373
self.init(unchecked: raw)
1336613374
}
1336713375

13368-
public var unexpectedBeforePoundToken: RawUnexpectedNodesSyntax? {
13376+
public var unexpectedBeforeAttributes: RawUnexpectedNodesSyntax? {
1336913377
layoutView.children[0].map(RawUnexpectedNodesSyntax.init(raw:))
1337013378
}
1337113379

13380+
public var attributes: RawAttributeListSyntax? {
13381+
layoutView.children[1].map(RawAttributeListSyntax.init(raw:))
13382+
}
13383+
13384+
public var unexpectedBetweenAttributesAndModifiers: RawUnexpectedNodesSyntax? {
13385+
layoutView.children[2].map(RawUnexpectedNodesSyntax.init(raw:))
13386+
}
13387+
13388+
public var modifiers: RawModifierListSyntax? {
13389+
layoutView.children[3].map(RawModifierListSyntax.init(raw:))
13390+
}
13391+
13392+
public var unexpectedBetweenModifiersAndPoundToken: RawUnexpectedNodesSyntax? {
13393+
layoutView.children[4].map(RawUnexpectedNodesSyntax.init(raw:))
13394+
}
13395+
1337213396
public var poundToken: RawTokenSyntax {
13373-
layoutView.children[1].map(RawTokenSyntax.init(raw:))!
13397+
layoutView.children[5].map(RawTokenSyntax.init(raw:))!
1337413398
}
1337513399

1337613400
public var unexpectedBetweenPoundTokenAndMacro: RawUnexpectedNodesSyntax? {
13377-
layoutView.children[2].map(RawUnexpectedNodesSyntax.init(raw:))
13401+
layoutView.children[6].map(RawUnexpectedNodesSyntax.init(raw:))
1337813402
}
1337913403

1338013404
public var macro: RawTokenSyntax {
13381-
layoutView.children[3].map(RawTokenSyntax.init(raw:))!
13405+
layoutView.children[7].map(RawTokenSyntax.init(raw:))!
1338213406
}
1338313407

1338413408
public var unexpectedBetweenMacroAndGenericArguments: RawUnexpectedNodesSyntax? {
13385-
layoutView.children[4].map(RawUnexpectedNodesSyntax.init(raw:))
13409+
layoutView.children[8].map(RawUnexpectedNodesSyntax.init(raw:))
1338613410
}
1338713411

1338813412
public var genericArguments: RawGenericArgumentClauseSyntax? {
13389-
layoutView.children[5].map(RawGenericArgumentClauseSyntax.init(raw:))
13413+
layoutView.children[9].map(RawGenericArgumentClauseSyntax.init(raw:))
1339013414
}
1339113415

1339213416
public var unexpectedBetweenGenericArgumentsAndLeftParen: RawUnexpectedNodesSyntax? {
13393-
layoutView.children[6].map(RawUnexpectedNodesSyntax.init(raw:))
13417+
layoutView.children[10].map(RawUnexpectedNodesSyntax.init(raw:))
1339413418
}
1339513419

1339613420
public var leftParen: RawTokenSyntax? {
13397-
layoutView.children[7].map(RawTokenSyntax.init(raw:))
13421+
layoutView.children[11].map(RawTokenSyntax.init(raw:))
1339813422
}
1339913423

1340013424
public var unexpectedBetweenLeftParenAndArgumentList: RawUnexpectedNodesSyntax? {
13401-
layoutView.children[8].map(RawUnexpectedNodesSyntax.init(raw:))
13425+
layoutView.children[12].map(RawUnexpectedNodesSyntax.init(raw:))
1340213426
}
1340313427

1340413428
public var argumentList: RawTupleExprElementListSyntax {
13405-
layoutView.children[9].map(RawTupleExprElementListSyntax.init(raw:))!
13429+
layoutView.children[13].map(RawTupleExprElementListSyntax.init(raw:))!
1340613430
}
1340713431

1340813432
public var unexpectedBetweenArgumentListAndRightParen: RawUnexpectedNodesSyntax? {
13409-
layoutView.children[10].map(RawUnexpectedNodesSyntax.init(raw:))
13433+
layoutView.children[14].map(RawUnexpectedNodesSyntax.init(raw:))
1341013434
}
1341113435

1341213436
public var rightParen: RawTokenSyntax? {
13413-
layoutView.children[11].map(RawTokenSyntax.init(raw:))
13437+
layoutView.children[15].map(RawTokenSyntax.init(raw:))
1341413438
}
1341513439

1341613440
public var unexpectedBetweenRightParenAndTrailingClosure: RawUnexpectedNodesSyntax? {
13417-
layoutView.children[12].map(RawUnexpectedNodesSyntax.init(raw:))
13441+
layoutView.children[16].map(RawUnexpectedNodesSyntax.init(raw:))
1341813442
}
1341913443

1342013444
public var trailingClosure: RawClosureExprSyntax? {
13421-
layoutView.children[13].map(RawClosureExprSyntax.init(raw:))
13445+
layoutView.children[17].map(RawClosureExprSyntax.init(raw:))
1342213446
}
1342313447

1342413448
public var unexpectedBetweenTrailingClosureAndAdditionalTrailingClosures: RawUnexpectedNodesSyntax? {
13425-
layoutView.children[14].map(RawUnexpectedNodesSyntax.init(raw:))
13449+
layoutView.children[18].map(RawUnexpectedNodesSyntax.init(raw:))
1342613450
}
1342713451

1342813452
public var additionalTrailingClosures: RawMultipleTrailingClosureElementListSyntax? {
13429-
layoutView.children[15].map(RawMultipleTrailingClosureElementListSyntax.init(raw:))
13453+
layoutView.children[19].map(RawMultipleTrailingClosureElementListSyntax.init(raw:))
1343013454
}
1343113455

1343213456
public var unexpectedAfterAdditionalTrailingClosures: RawUnexpectedNodesSyntax? {
13433-
layoutView.children[16].map(RawUnexpectedNodesSyntax.init(raw:))
13457+
layoutView.children[20].map(RawUnexpectedNodesSyntax.init(raw:))
1343413458
}
1343513459
}
1343613460

0 commit comments

Comments
 (0)