Skip to content

Commit ea71e1e

Browse files
committed
Support parsing of lifetime dependence specifiers
1 parent b32df0e commit ea71e1e

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+2129
-390
lines changed

CodeGeneration/Sources/SyntaxSupport/KeywordSpec.swift

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,9 @@ public enum Keyword: CaseIterable {
108108
case _Class
109109
case _compilerInitialized
110110
case _const
111+
case _consume
111112
case _consuming
113+
case _copy
112114
case _documentation
113115
case _dynamicReplacement
114116
case _effects
@@ -119,6 +121,7 @@ public enum Keyword: CaseIterable {
119121
case _local
120122
case _modify
121123
case _move
124+
case _mutate
122125
case _mutating
123126
case _NativeClass
124127
case _NativeRefCountedObject
@@ -328,6 +331,8 @@ public enum Keyword: CaseIterable {
328331
return KeywordSpec("_backDeploy")
329332
case ._borrow:
330333
return KeywordSpec("_borrow")
334+
case ._borrowing:
335+
return KeywordSpec("_borrowing", experimentalFeature: .referenceBindings, or: .borrowingSwitch)
331336
case ._BridgeObject:
332337
return KeywordSpec("_BridgeObject")
333338
case ._cdecl:
@@ -338,6 +343,12 @@ public enum Keyword: CaseIterable {
338343
return KeywordSpec("_compilerInitialized")
339344
case ._const:
340345
return KeywordSpec("_const")
346+
case ._consume:
347+
return KeywordSpec("_consume", experimentalFeature: .nonescapableTypes)
348+
case ._consuming:
349+
return KeywordSpec("_consuming", experimentalFeature: .referenceBindings)
350+
case ._copy:
351+
return KeywordSpec("_copy", experimentalFeature: .nonescapableTypes)
341352
case ._documentation:
342353
return KeywordSpec("_documentation")
343354
case ._dynamicReplacement:
@@ -358,6 +369,10 @@ public enum Keyword: CaseIterable {
358369
return KeywordSpec("_modify")
359370
case ._move:
360371
return KeywordSpec("_move")
372+
case ._mutate:
373+
return KeywordSpec("_mutate", experimentalFeature: .nonescapableTypes)
374+
case ._mutating:
375+
return KeywordSpec("_mutating", experimentalFeature: .referenceBindings)
361376
case ._NativeClass:
362377
return KeywordSpec("_NativeClass")
363378
case ._NativeRefCountedObject:
@@ -743,12 +758,6 @@ public enum Keyword: CaseIterable {
743758
return KeywordSpec("wrt")
744759
case .yield:
745760
return KeywordSpec("yield")
746-
case ._borrowing:
747-
return KeywordSpec("_borrowing", experimentalFeature: .referenceBindings, or: .borrowingSwitch)
748-
case ._consuming:
749-
return KeywordSpec("_consuming", experimentalFeature: .referenceBindings)
750-
case ._mutating:
751-
return KeywordSpec("_mutating", experimentalFeature: .referenceBindings)
752761
}
753762
}
754763
}

CodeGeneration/Sources/SyntaxSupport/SyntaxNodeKind.swift

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -99,8 +99,8 @@ public enum SyntaxNodeKind: String, CaseIterable {
9999
case dictionaryExpr
100100
case dictionaryType
101101
case differentiabilityArgument
102-
case differentiabilityArguments
103102
case differentiabilityArgumentList
103+
case differentiabilityArguments
104104
case differentiabilityWithRespectToArgument
105105
case differentiableAttributeArguments
106106
case discardAssignmentExpr
@@ -182,6 +182,9 @@ public enum SyntaxNodeKind: String, CaseIterable {
182182
case labeledSpecializeArgument
183183
case labeledStmt
184184
case layoutRequirement
185+
case lifetimeSpecifierArgument
186+
case lifetimeSpecifierArgumentList
187+
case lifetimeTypeSpecifier
185188
case macroDecl
186189
case macroExpansionDecl
187190
case macroExpansionExpr
@@ -244,14 +247,15 @@ public enum SyntaxNodeKind: String, CaseIterable {
244247
case returnStmt
245248
case sameTypeRequirement
246249
case sequenceExpr
250+
case simpleTypeSpecifier
251+
case simpleStringLiteralExpr
252+
case simpleStringLiteralSegmentList
247253
case someOrAnyType
248254
case sourceFile
249255
case specializeAttributeArgumentList
250256
case specializeAvailabilityArgument
251257
case specializeTargetFunctionArgument
252258
case stmt
253-
case simpleStringLiteralExpr
254-
case simpleStringLiteralSegmentList
255259
case stringLiteralExpr
256260
case stringLiteralSegmentList
257261
case stringSegment
@@ -286,6 +290,7 @@ public enum SyntaxNodeKind: String, CaseIterable {
286290
case typeExpr
287291
case typeInitializerClause
288292
case typeSpecifier
293+
case lifetimeSpecifierArguments
289294
case typeSpecifierList
290295
case unavailableFromAsyncAttributeArguments
291296
case underscorePrivateAttributeArguments
@@ -301,10 +306,10 @@ public enum SyntaxNodeKind: String, CaseIterable {
301306
case whereClause
302307
case whileStmt
303308
case wildcardPattern
304-
case yieldStmt
305309
case yieldedExpression
306-
case yieldedExpressionsClause
307310
case yieldedExpressionList
311+
case yieldedExpressionsClause
312+
case yieldStmt
308313

309314
// Nodes that have special handling throughout the codebase
310315

@@ -407,8 +412,8 @@ public enum SyntaxNodeKind: String, CaseIterable {
407412
case .derivativeAttributeArguments: return "derivativeRegistrationAttributeArguments"
408413
case .designatedType: return "designatedTypeElement"
409414
case .differentiabilityArgument: return "differentiabilityParam"
410-
case .differentiabilityArguments: return "differentiabilityParams"
411415
case .differentiabilityArgumentList: return "differentiabilityParamList"
416+
case .differentiabilityArguments: return "differentiabilityParams"
412417
case .differentiabilityWithRespectToArgument: return "differentiabilityParamsClause"
413418
case .documentationAttributeArgumentList: return "documentationAttributeArguments"
414419
case .dynamicReplacementAttributeArguments: return "dynamicReplacementArguments"
@@ -442,6 +447,7 @@ public enum SyntaxNodeKind: String, CaseIterable {
442447
case .precedenceGroupName: return "precedenceGroupNameElement"
443448
case .repeatStmt: return "repeatWhileStmt"
444449
case .someOrAnyType: return "constrainedSugarType"
450+
case .simpleTypeSpecifier: return "typeSpecifier"
445451
case .specializeAttributeArgumentList: return "specializeAttributeSpecList"
446452
case .specializeAvailabilityArgument: return "availabilityEntry"
447453
case .specializeTargetFunctionArgument: return "targetFunctionEntry"
@@ -453,8 +459,8 @@ public enum SyntaxNodeKind: String, CaseIterable {
453459
case .typeAliasDecl: return "typealiasDecl"
454460
case .unavailableFromAsyncAttributeArguments: return "unavailableFromAsyncArguments"
455461
case .yieldedExpression: return "yieldExprListElement"
456-
case .yieldedExpressionsClause: return "yieldList"
457462
case .yieldedExpressionList: return "yieldExprList"
463+
case .yieldedExpressionsClause: return "yieldList"
458464
default: return nil
459465
}
460466
}

CodeGeneration/Sources/SyntaxSupport/TypeNodes.swift

Lines changed: 101 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -496,9 +496,108 @@ public let TYPE_NODES: [Node] = [
496496
),
497497

498498
Node(
499-
kind: .typeSpecifier,
499+
kind: .lifetimeSpecifierArgument,
500500
base: .syntax,
501+
experimentalFeature: .nonescapableTypes,
501502
nameForDiagnostics: nil,
503+
documentation: """
504+
A single argument that can be added to a lifetime specifier like `borrow`, `mutate`, `consume` or `copy`.
505+
506+
### Example
507+
`data` in `func foo(data: Array<Item>) -> borrow(data) ComplexReferenceType`
508+
""",
509+
traits: [
510+
"WithTrailingComma"
511+
],
512+
children: [
513+
Child(
514+
name: "parameter",
515+
kind: .token(choices: [.token(.identifier), .keyword(.self), .token(.integerLiteral)]),
516+
nameForDiagnostics: "parameter reference",
517+
documentation: """
518+
The parameter on which the lifetime of this type depends.
519+
520+
This can be an identifier referring to an external parameter name, an integer literal to refer to an unnamed
521+
parameter or `self` if the type's lifetime depends on the object the method is called on.
522+
"""
523+
),
524+
Child(
525+
name: "trailingComma",
526+
kind: .token(choices: [.token(.comma)]),
527+
isOptional: true
528+
),
529+
]
530+
),
531+
532+
Node(
533+
kind: .lifetimeSpecifierArgumentList,
534+
base: .syntaxCollection,
535+
experimentalFeature: .nonescapableTypes,
536+
nameForDiagnostics: nil,
537+
elementChoices: [.lifetimeSpecifierArgument]
538+
),
539+
540+
Node(
541+
kind: .lifetimeSpecifierArguments,
542+
base: .syntax,
543+
experimentalFeature: .nonescapableTypes,
544+
nameForDiagnostics: nil,
545+
documentation: """
546+
An optional argument passed to a type parameter.
547+
548+
### Example
549+
`borrow(data)` in `func foo(data: Array<Item>) -> borrow(data) ComplexReferenceType`
550+
""",
551+
traits: [
552+
"Parenthesized"
553+
],
554+
children: [
555+
Child(
556+
name: "leftParen",
557+
kind: .token(choices: [.token(.leftParen)])
558+
),
559+
Child(
560+
name: "arguments",
561+
kind: .collection(kind: .lifetimeSpecifierArgumentList, collectionElementName: "Arguments"),
562+
documentation: """
563+
The function parameters that the lifetime of the annotated type depends on.
564+
"""
565+
),
566+
Child(
567+
name: "rightParen",
568+
kind: .token(choices: [.token(.rightParen)])
569+
),
570+
]
571+
),
572+
573+
Node(
574+
kind: .lifetimeTypeSpecifier,
575+
base: .syntax,
576+
experimentalFeature: .nonescapableTypes,
577+
nameForDiagnostics: "lifetime specifier",
578+
documentation: "A specifier that specifies function parameter on whose lifetime a type depends",
579+
children: [
580+
Child(
581+
name: "specifier",
582+
kind: .token(choices: [
583+
.keyword(._copy),
584+
.keyword(._consume),
585+
.keyword(._borrow),
586+
.keyword(._mutate),
587+
]),
588+
documentation: "The specifier token that's attached to the type."
589+
),
590+
Child(
591+
name: "arguments",
592+
kind: .node(kind: .lifetimeSpecifierArguments)
593+
),
594+
]
595+
),
596+
597+
Node(
598+
kind: .simpleTypeSpecifier,
599+
base: .syntax,
600+
nameForDiagnostics: "type specifier",
502601
documentation: "A specifier that can be attached to a type to eg. mark a parameter as `inout` or `consuming`",
503602
children: [
504603
Child(
@@ -523,6 +622,6 @@ public let TYPE_NODES: [Node] = [
523622
kind: .typeSpecifierList,
524623
base: .syntaxCollection,
525624
nameForDiagnostics: nil,
526-
elementChoices: [.typeSpecifier]
625+
elementChoices: [.simpleTypeSpecifier, .lifetimeTypeSpecifier]
527626
),
528627
]

CodeGeneration/Sources/generate-swift-syntax/templates/swiftsyntax/SwiftSyntaxDoccIndex.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ let nodesSections: String = {
5353
}
5454
return [node.kind.syntaxType.description]
5555
+ node.elementChoices
56-
.filter { SYNTAX_NODE_MAP[$0] != nil }
56+
.filter { SYNTAX_NODE_MAP[$0] != nil && !SYNTAX_NODE_MAP[$0]!.isExperimental }
5757
.map(\.syntaxType.description)
5858
.filter { !handledSyntaxTypes.contains($0) }
5959
})

CodeGeneration/Sources/generate-swift-syntax/templates/swiftsyntax/SyntaxCollectionsFile.swift

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,12 @@ let syntaxCollectionsFile = SourceFileSyntax(leadingTrivia: copyrightHeader) {
4141
) {
4242
for choiceName in node.elementChoices {
4343
let choice = SYNTAX_NODE_MAP[choiceName]!
44-
DeclSyntax("case `\(choice.varOrCaseName)`(\(choice.kind.syntaxType))")
44+
DeclSyntax(
45+
"""
46+
\(choice.apiAttributes())\
47+
case `\(choice.varOrCaseName)`(\(choice.kind.syntaxType))
48+
"""
49+
)
4550
}
4651

4752
try VariableDeclSyntax("public var _syntaxNode: Syntax") {
@@ -60,6 +65,7 @@ let syntaxCollectionsFile = SourceFileSyntax(leadingTrivia: copyrightHeader) {
6065
if choiceNode.kind.isBase {
6166
DeclSyntax(
6267
"""
68+
\(choiceNode.apiAttributes())\
6369
public init(_ node: some \(choiceNode.kind.protocolType)) {
6470
self = .\(choiceNode.varOrCaseName)(\(choiceNode.kind.syntaxType)(node))
6571
}
@@ -69,6 +75,7 @@ let syntaxCollectionsFile = SourceFileSyntax(leadingTrivia: copyrightHeader) {
6975
} else {
7076
DeclSyntax(
7177
"""
78+
\(choiceNode.apiAttributes())\
7279
public init(_ node: \(choiceNode.kind.syntaxType)) {
7380
self = .\(choiceNode.varOrCaseName)(node)
7481
}

CodeGeneration/Sources/generate-swift-syntax/templates/swiftsyntax/SyntaxNodeCasting.swift

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,14 @@ import SyntaxSupport
1616

1717
@MemberBlockItemListBuilder
1818
func choiceNodeCastingMethods(for syntaxNodeKind: SyntaxNodeKind) -> MemberBlockItemListSyntax {
19+
let apiAttributes = SYNTAX_NODE_MAP[syntaxNodeKind]?.apiAttributes() ?? []
1920
if syntaxNodeKind.isBase {
2021
DeclSyntax(
2122
"""
2223
/// Checks if the current syntax node can be cast to the type conforming to the ``\(syntaxNodeKind.protocolType)`` protocol.
2324
///
2425
/// - Returns: `true` if the node can be cast, `false` otherwise.
26+
\(apiAttributes)\
2527
public func `is`<S: \(syntaxNodeKind.protocolType)>(_ syntaxType: S.Type) -> Bool {
2628
return self.as(syntaxType) != nil
2729
}
@@ -33,6 +35,7 @@ func choiceNodeCastingMethods(for syntaxNodeKind: SyntaxNodeKind) -> MemberBlock
3335
/// Attempts to cast the current syntax node to the type conforming to the ``\(syntaxNodeKind.protocolType)`` protocol.
3436
///
3537
/// - Returns: An instance of the specialized type, or `nil` if the cast fails.
38+
\(apiAttributes)\
3639
public func `as`<S: \(syntaxNodeKind.protocolType)>(_ syntaxType: S.Type) -> S? {
3740
return S.init(self)
3841
}
@@ -45,6 +48,7 @@ func choiceNodeCastingMethods(for syntaxNodeKind: SyntaxNodeKind) -> MemberBlock
4548
///
4649
/// - Returns: An instance of the specialized type.
4750
/// - Warning: This function will crash if the cast is not possible. Use `as` to safely attempt a cast.
51+
\(apiAttributes)\
4852
public func cast<S: \(syntaxNodeKind.protocolType)>(_ syntaxType: S.Type) -> S {
4953
return self.as(S.self)!
5054
}
@@ -56,6 +60,7 @@ func choiceNodeCastingMethods(for syntaxNodeKind: SyntaxNodeKind) -> MemberBlock
5660
/// Checks if the current syntax node can be cast to ``\(syntaxNodeKind.syntaxType)``.
5761
///
5862
/// - Returns: `true` if the node can be cast, `false` otherwise.
63+
\(apiAttributes)\
5964
public func `is`(_ syntaxType: \(syntaxNodeKind.syntaxType).Type) -> Bool {
6065
return self.as(syntaxType) != nil
6166
}
@@ -67,6 +72,7 @@ func choiceNodeCastingMethods(for syntaxNodeKind: SyntaxNodeKind) -> MemberBlock
6772
/// Attempts to cast the current syntax node to ``\(syntaxNodeKind.syntaxType)``.
6873
///
6974
/// - Returns: An instance of ``\(syntaxNodeKind.syntaxType)``, or `nil` if the cast fails.
75+
\(apiAttributes)\
7076
public func `as`(_ syntaxType: \(syntaxNodeKind.syntaxType).Type) -> \(syntaxNodeKind.syntaxType)? {
7177
return \(syntaxNodeKind.syntaxType).init(self)
7278
}
@@ -79,6 +85,7 @@ func choiceNodeCastingMethods(for syntaxNodeKind: SyntaxNodeKind) -> MemberBlock
7985
///
8086
/// - Returns: An instance of ``\(syntaxNodeKind.syntaxType)``.
8187
/// - Warning: This function will crash if the cast is not possible. Use `as` to safely attempt a cast.
88+
\(apiAttributes)\
8289
public func cast(_ syntaxType: \(syntaxNodeKind.syntaxType).Type) -> \(syntaxNodeKind.syntaxType) {
8390
return self.as(\(syntaxNodeKind.syntaxType).self)!
8491
}

CodeGeneration/Sources/generate-swift-syntax/templates/swiftsyntaxbuilder/ResultBuildersFile.swift

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,9 @@ let resultBuildersFile = SourceFileSyntax(leadingTrivia: copyrightHeader) {
1919
DeclSyntax(
2020
"""
2121
#if swift(>=6)
22-
public import SwiftSyntax
22+
@_spi(ExperimentalLanguageFeatures) public import SwiftSyntax
2323
#else
24-
import SwiftSyntax
24+
@_spi(ExperimentalLanguageFeatures) import SwiftSyntax
2525
#endif
2626
"""
2727
)
@@ -48,6 +48,7 @@ let resultBuildersFile = SourceFileSyntax(leadingTrivia: copyrightHeader) {
4848
for elementChoice in node.elementChoices {
4949
DeclSyntax(
5050
"""
51+
\(SYNTAX_NODE_MAP[elementChoice]?.apiAttributes() ?? [])\
5152
public static func buildExpression(_ expression: \(elementChoice.syntaxType)) -> Component {
5253
buildExpression(.init(expression))
5354
}

0 commit comments

Comments
 (0)