Skip to content

Commit 2e978f3

Browse files
authored
Merge pull request #1093 from DougGregor/macro-declarations
Macro declarations
2 parents 7b008fe + e29e4bc commit 2e978f3

29 files changed

+1672
-282
lines changed

CodeGeneration/Sources/SyntaxSupport/gyb_generated/DeclNodes.swift

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1502,6 +1502,79 @@ public let DECL_NODES: [Node] = [
15021502
])
15031503
]),
15041504

1505+
Node(name: "MacroDecl",
1506+
nameForDiagnostics: "macro",
1507+
kind: "Decl",
1508+
traits: [
1509+
"IdentifiedDecl"
1510+
],
1511+
children: [
1512+
Child(name: "Attributes",
1513+
kind: "AttributeList",
1514+
isOptional: true,
1515+
collectionElementName: "Attribute"),
1516+
Child(name: "Modifiers",
1517+
kind: "ModifierList",
1518+
isOptional: true,
1519+
collectionElementName: "Modifier"),
1520+
Child(name: "MacroKeyword",
1521+
kind: "ContextualKeywordToken",
1522+
tokenChoices: [
1523+
"ContextualKeyword"
1524+
],
1525+
textChoices: [
1526+
"macro"
1527+
]),
1528+
Child(name: "Identifier",
1529+
kind: "IdentifierToken",
1530+
tokenChoices: [
1531+
"Identifier"
1532+
]),
1533+
Child(name: "GenericParameterClause",
1534+
kind: "GenericParameterClause",
1535+
isOptional: true),
1536+
Child(name: "Signature",
1537+
kind: "Syntax",
1538+
nodeChoices: [
1539+
Child(name: "FunctionLike",
1540+
kind: "FunctionSignature"),
1541+
Child(name: "ValueLike",
1542+
kind: "TypeAnnotation")
1543+
]),
1544+
Child(name: "Equal",
1545+
kind: "EqualToken",
1546+
tokenChoices: [
1547+
"Equal"
1548+
]),
1549+
Child(name: "ExternalName",
1550+
kind: "ExternalMacroName",
1551+
isOptional: true),
1552+
Child(name: "GenericWhereClause",
1553+
kind: "GenericWhereClause",
1554+
isOptional: true)
1555+
]),
1556+
1557+
Node(name: "ExternalMacroName",
1558+
nameForDiagnostics: "external macro name",
1559+
kind: "Syntax",
1560+
children: [
1561+
Child(name: "ModuleName",
1562+
kind: "IdentifierToken",
1563+
tokenChoices: [
1564+
"Identifier"
1565+
]),
1566+
Child(name: "Period",
1567+
kind: "PeriodToken",
1568+
tokenChoices: [
1569+
"Period"
1570+
]),
1571+
Child(name: "MacroTypeName",
1572+
kind: "IdentifierToken",
1573+
tokenChoices: [
1574+
"Identifier"
1575+
])
1576+
]),
1577+
15051578
Node(name: "MacroExpansionDecl",
15061579
nameForDiagnostics: "pound literal declaration",
15071580
kind: "Decl",

Sources/SwiftParser/Declarations.swift

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,9 @@ extension TokenConsumer {
102102
return false
103103
case .initKeyword:
104104
return allowInitDecl
105+
case .macroContextualKeyword:
106+
// macro Foo ...
107+
return subparser.peek().tokenKind == .identifier
105108
case .some(_):
106109
// All other decl start keywords unconditonally start a decl.
107110
return true
@@ -149,6 +152,7 @@ extension Parser {
149152
/// declaration → subscript-declaration
150153
/// declaration → operator-declaration
151154
/// declaration → precedence-group-declaration
155+
/// declaration → macro-declaration
152156
///
153157
/// declarations → declaration declarations?
154158
///
@@ -236,6 +240,8 @@ extension Parser {
236240
return RawDeclSyntax(self.parsePrecedenceGroupDeclaration(attrs, handle))
237241
case (.actorContextualKeyword, let handle)?:
238242
return RawDeclSyntax(self.parseNominalTypeDeclaration(for: RawActorDeclSyntax.self, attrs: attrs, introucerHandle: handle))
243+
case (.macroContextualKeyword, let handle)?:
244+
return RawDeclSyntax(self.parseMacroDeclaration(attrs: attrs, introducerHandle: handle))
239245
case nil:
240246
if inMemberDeclList {
241247
let isProbablyVarDecl = self.at(any: [.identifier, .wildcardKeyword]) && self.peek().tokenKind.is(any: [.colon, .equal, .comma])
@@ -2007,6 +2013,65 @@ extension Parser {
20072013
}
20082014
}
20092015

2016+
/// Parse a macro declaration.
2017+
mutating func parseMacroDeclaration(
2018+
attrs: DeclAttributes,
2019+
introducerHandle: RecoveryConsumptionHandle
2020+
) -> RawMacroDeclSyntax {
2021+
let (unexpectedBeforeIntroducerKeyword, introducerKeyword) = self.eat(introducerHandle)
2022+
let (unexpectedBeforeName, name) = self.expectIdentifier(keywordRecovery: true)
2023+
2024+
// Optional generic parameters.
2025+
let genericParams: RawGenericParameterClauseSyntax?
2026+
if self.currentToken.starts(with: "<") {
2027+
genericParams = self.parseGenericParameters()
2028+
} else {
2029+
genericParams = nil
2030+
}
2031+
2032+
// Macro signature, which is either value-like or function-like.
2033+
let signature: RawMacroDeclSyntax.Signature
2034+
if let colon = self.consume(if: .colon) {
2035+
let type = self.parseType()
2036+
signature = .valueLike(
2037+
RawTypeAnnotationSyntax(colon: colon, type: type, arena: self.arena))
2038+
} else {
2039+
signature = .functionLike(self.parseFunctionSignature())
2040+
}
2041+
2042+
// External macro name
2043+
let (unexpectedBeforeEqual, equal) = self.expect(.equal)
2044+
let (unexpectedBeforeModuleName, moduleName) = self.expectIdentifier()
2045+
let (unexpectedBeforePeriod, period) = self.expect(.period)
2046+
let (unexpectedBeforeMacroTypeName, macroTypeName) = self.expectIdentifier()
2047+
2048+
let externalMacroName = RawExternalMacroNameSyntax(
2049+
unexpectedBeforeModuleName, moduleName: moduleName,
2050+
unexpectedBeforePeriod, period: period,
2051+
unexpectedBeforeMacroTypeName, macroTypeName: macroTypeName,
2052+
arena: self.arena
2053+
)
2054+
2055+
// Parse a 'where' clause if present.
2056+
let whereClause: RawGenericWhereClauseSyntax?
2057+
if self.at(.whereKeyword) {
2058+
whereClause = self.parseGenericWhereClause()
2059+
} else {
2060+
whereClause = nil
2061+
}
2062+
2063+
return RawMacroDeclSyntax(
2064+
attributes: attrs.attributes, modifiers: attrs.modifiers,
2065+
unexpectedBeforeIntroducerKeyword, macroKeyword: introducerKeyword,
2066+
unexpectedBeforeName, identifier: name,
2067+
genericParameterClause: genericParams,
2068+
signature: signature, unexpectedBeforeEqual, equal: equal,
2069+
externalName: externalMacroName,
2070+
genericWhereClause: whereClause,
2071+
arena: self.arena
2072+
)
2073+
}
2074+
20102075
/// Parse a macro expansion as an declaration.
20112076
///
20122077
///

Sources/SwiftParser/RawTokenKindSubset.swift

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,7 @@ enum DeclarationStart: RawTokenKindSubset {
223223
case importKeyword
224224
case initKeyword
225225
case letKeyword
226+
case macroContextualKeyword
226227
case operatorKeyword
227228
case precedencegroupKeyword
228229
case protocolKeyword
@@ -234,6 +235,7 @@ enum DeclarationStart: RawTokenKindSubset {
234235
init?(lexeme: Lexer.Lexeme) {
235236
switch lexeme.tokenKind {
236237
case .identifier where lexeme.tokenText == "actor": self = .actorContextualKeyword
238+
case .identifier where lexeme.tokenText == "macro": self = .macroContextualKeyword
237239
case .associatedtypeKeyword: self = .associatedtypeKeyword
238240
case .caseKeyword: self = .caseKeyword
239241
case .classKeyword: self = .classKeyword
@@ -268,6 +270,7 @@ enum DeclarationStart: RawTokenKindSubset {
268270
case .importKeyword: return .importKeyword
269271
case .initKeyword: return .initKeyword
270272
case .letKeyword: return .letKeyword
273+
case .macroContextualKeyword: return .identifier
271274
case .operatorKeyword: return .operatorKeyword
272275
case .precedencegroupKeyword: return .precedencegroupKeyword
273276
case .protocolKeyword: return .protocolKeyword
@@ -281,6 +284,7 @@ enum DeclarationStart: RawTokenKindSubset {
281284
var contextualKeyword: SyntaxText? {
282285
switch self {
283286
case .actorContextualKeyword: return "actor"
287+
case .macroContextualKeyword: return "macro"
284288
default: return nil
285289
}
286290
}
@@ -289,6 +293,7 @@ enum DeclarationStart: RawTokenKindSubset {
289293
switch self {
290294
case .actorContextualKeyword: return .declKeyword
291295
case .caseKeyword: return .declKeyword
296+
case .macroContextualKeyword: return .declKeyword
292297
default: return nil
293298
}
294299
}

Sources/SwiftSyntax/Documentation.docc/gyb_generated/SwiftSyntax.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ allows Swift tools to parse, inspect, generate, and transform Swift source code.
7575
- <doc:SwiftSyntax/EnumDeclSyntax>
7676
- <doc:SwiftSyntax/OperatorDeclSyntax>
7777
- <doc:SwiftSyntax/PrecedenceGroupDeclSyntax>
78+
- <doc:SwiftSyntax/MacroDeclSyntax>
7879
- <doc:SwiftSyntax/MacroExpansionDeclSyntax>
7980

8081
### Statements
@@ -355,6 +356,7 @@ allows Swift tools to parse, inspect, generate, and transform Swift source code.
355356
- <doc:SwiftSyntax/PrecedenceGroupNameElementSyntax>
356357
- <doc:SwiftSyntax/PrecedenceGroupAssignmentSyntax>
357358
- <doc:SwiftSyntax/PrecedenceGroupAssociativitySyntax>
359+
- <doc:SwiftSyntax/ExternalMacroNameSyntax>
358360
- <doc:SwiftSyntax/TokenListSyntax>
359361
- <doc:SwiftSyntax/NonEmptyTokenListSyntax>
360362
- <doc:SwiftSyntax/CustomAttributeSyntax>

0 commit comments

Comments
 (0)