Skip to content

Commit e547074

Browse files
committed
Merge remote-tracking branch 'upstream/main' into rfc-upstream-sync
2 parents b1bed57 + 3eedb6d commit e547074

File tree

96 files changed

+3396
-3082
lines changed

Some content is hidden

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

96 files changed

+3396
-3082
lines changed

CodeGeneration/Sources/SyntaxSupport/AvailabilityNodes.swift

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,4 +182,29 @@ public let AVAILABILITY_NODES: [Node] = [
182182
]
183183
),
184184

185+
Node(
186+
kind: .availabilityMacroDefinition,
187+
base: .syntax,
188+
spi: "Compiler",
189+
nameForDiagnostics: "availability macro definition",
190+
documentation: "Syntax for '-define-availability' compiler arguments, never appear in Swift source code",
191+
parserFunction: "parseAvailabilityMacroDefinition",
192+
children: [
193+
Child(
194+
name: "platformVersion",
195+
kind: .node(kind: .platformVersion)
196+
),
197+
Child(
198+
name: "colon",
199+
kind: .token(choices: [.token(.colon)])
200+
),
201+
Child(
202+
name: "specs",
203+
kind: .collection(
204+
kind: .availabilityArgumentList,
205+
collectionElementName: "AvailabilityArgument"
206+
)
207+
),
208+
]
209+
),
185210
]

CodeGeneration/Sources/SyntaxSupport/KeywordSpec.swift

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -38,17 +38,12 @@ public struct KeywordSpec: IdentifierConvertible {
3838
///
3939
/// This is typically used to mark APIs as SPI when the keyword is part of an experimental language feature.
4040
public var apiAttributes: AttributeListSyntax {
41-
let attrList = AttributeListSyntax {
41+
AttributeListSyntax {
4242
if isExperimental {
43-
let experimentalSPI: AttributeListSyntax = """
44-
#if compiler(>=5.8)
45-
@_spi(ExperimentalLanguageFeatures)
46-
#endif
47-
"""
48-
experimentalSPI.with(\.trailingTrivia, .newline)
43+
AttributeSyntax("@_spi(ExperimentalLanguageFeatures)")
44+
.with(\.trailingTrivia, .newline)
4945
}
5046
}
51-
return attrList.with(\.trailingTrivia, attrList.isEmpty ? [] : .newline)
5247
}
5348

5449
/// Initializes a new `KeywordSpec` instance.

CodeGeneration/Sources/SyntaxSupport/Node.swift

Lines changed: 25 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,9 @@ public class Node: NodeChoiceConvertible {
4242

4343
public let experimentalFeature: ExperimentalFeature?
4444

45+
/// SPI name if this node is only available for the SPI.
46+
public let spi: TokenSyntax?
47+
4548
/// When the node name is printed for diagnostics, this name is used.
4649
/// If `nil`, `nameForDiagnostics` will print the parent node’s name.
4750
public let nameForDiagnostics: String?
@@ -93,21 +96,20 @@ public class Node: NodeChoiceConvertible {
9396
/// Retrieve the attributes that should be printed on any API for the
9497
/// generated node. If `forRaw` is true, this is for the raw syntax node.
9598
public func apiAttributes(forRaw: Bool = false) -> AttributeListSyntax {
96-
let attrList = AttributeListSyntax {
99+
AttributeListSyntax {
97100
if isExperimental {
98-
// SPI for enum cases currently requires Swift 5.8 to work correctly.
99-
let experimentalSPI: AttributeListSyntax = """
100-
#if compiler(>=5.8)
101-
@_spi(ExperimentalLanguageFeatures)
102-
#endif
103-
"""
104-
experimentalSPI.with(\.trailingTrivia, .newline)
101+
AttributeSyntax("@_spi(ExperimentalLanguageFeatures)")
102+
.with(\.trailingTrivia, .newline)
103+
}
104+
if let spi = self.spi {
105+
AttributeSyntax("@_spi(\(spi))")
106+
.with(\.trailingTrivia, .newline)
105107
}
106108
if forRaw {
107-
"@_spi(RawSyntax)"
109+
AttributeSyntax("@_spi(RawSyntax)")
110+
.with(\.trailingTrivia, .newline)
108111
}
109112
}
110-
return attrList.with(\.trailingTrivia, attrList.isEmpty ? [] : .newline)
111113
}
112114

113115
public var apiAttributes: AttributeListSyntax {
@@ -119,6 +121,7 @@ public class Node: NodeChoiceConvertible {
119121
kind: SyntaxNodeKind,
120122
base: SyntaxNodeKind,
121123
experimentalFeature: ExperimentalFeature? = nil,
124+
spi: TokenSyntax? = nil,
122125
nameForDiagnostics: String?,
123126
documentation: String? = nil,
124127
parserFunction: TokenSyntax? = nil,
@@ -132,6 +135,7 @@ public class Node: NodeChoiceConvertible {
132135
self.kind = kind
133136
self.base = base
134137
self.experimentalFeature = experimentalFeature
138+
self.spi = spi
135139
self.nameForDiagnostics = nameForDiagnostics
136140
self.documentation = SwiftSyntax.Trivia.docCommentTrivia(from: documentation)
137141
self.parserFunction = parserFunction
@@ -141,6 +145,10 @@ public class Node: NodeChoiceConvertible {
141145
self.data = .layout(children: childrenWithUnexpected, childHistory: childHistory, traits: traits)
142146
}
143147

148+
public var hiddenInDocumentation: Bool {
149+
self.isExperimental || self.spi != nil || self.kind.isDeprecated
150+
}
151+
144152
/// A doc comment that lists all the nodes in which this node occurs as a child in.
145153
public var containedIn: SwiftSyntax.Trivia {
146154
if kind == .unexpectedNodes {
@@ -149,7 +157,10 @@ public class Node: NodeChoiceConvertible {
149157
return []
150158
}
151159
var childIn: [(node: SyntaxNodeKind, child: Child?)] = []
152-
for node in SYNTAX_NODES where !node.isExperimental {
160+
for node in SYNTAX_NODES {
161+
if !self.hiddenInDocumentation && node.hiddenInDocumentation {
162+
continue
163+
}
153164
if let layout = node.layoutNode {
154165
for child in layout.children {
155166
if child.kinds.contains(self.kind) {
@@ -202,7 +213,7 @@ public class Node: NodeChoiceConvertible {
202213

203214
let list =
204215
SYNTAX_NODES
205-
.filter { $0.base == self.kind && !$0.isExperimental && !$0.kind.isDeprecated }
216+
.filter { $0.base == self.kind && (!$0.hiddenInDocumentation || self.hiddenInDocumentation) }
206217
.map { "- \($0.kind.doccLink)" }
207218
.joined(separator: "\n")
208219

@@ -226,6 +237,7 @@ public class Node: NodeChoiceConvertible {
226237
kind: SyntaxNodeKind,
227238
base: SyntaxNodeKind,
228239
experimentalFeature: ExperimentalFeature? = nil,
240+
spi: TokenSyntax? = nil,
229241
nameForDiagnostics: String?,
230242
documentation: String? = nil,
231243
parserFunction: TokenSyntax? = nil,
@@ -235,6 +247,7 @@ public class Node: NodeChoiceConvertible {
235247
precondition(base == .syntaxCollection)
236248
self.base = base
237249
self.experimentalFeature = experimentalFeature
250+
self.spi = spi
238251
self.nameForDiagnostics = nameForDiagnostics
239252
self.documentation = SwiftSyntax.Trivia.docCommentTrivia(from: documentation)
240253
self.parserFunction = parserFunction

CodeGeneration/Sources/SyntaxSupport/SyntaxNodeKind.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ public enum SyntaxNodeKind: String, CaseIterable, IdentifierConvertible, TypeCon
4444
case availabilityArgumentList
4545
case availabilityCondition
4646
case availabilityLabeledArgument
47+
case availabilityMacroDefinition
4748
case awaitExpr
4849
case backDeployedAttributeArguments
4950
case binaryOperatorExpr
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2025 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See https://swift.org/LICENSE.txt for license information
9+
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
import SwiftSyntax
14+
import SwiftSyntaxBuilder
15+
import SyntaxSupport
16+
17+
enum ImportAccessLevel {
18+
case `public`
19+
case `internal`
20+
}
21+
22+
func importSwiftSyntax(accessLevel: ImportAccessLevel = .internal) -> DeclSyntax {
23+
// Import all '@_spi'.
24+
let importingAttrs = AttributeListSyntax {
25+
var seen: Set<String> = []
26+
AttributeSyntax("@_spi(RawSyntax)").with(\.trailingTrivia, .space)
27+
AttributeSyntax("@_spi(ExperimentalLanguageFeatures)").with(\.trailingTrivia, .space)
28+
for node in NON_BASE_SYNTAX_NODES {
29+
if let spi = node.spi, seen.insert(spi.text).inserted {
30+
AttributeSyntax("@_spi(\(spi))").with(\.trailingTrivia, .space)
31+
}
32+
}
33+
}
34+
let visibilityKeyword: TokenSyntax
35+
switch accessLevel {
36+
case .internal:
37+
visibilityKeyword = "internal"
38+
case .public:
39+
visibilityKeyword = "public"
40+
}
41+
42+
return DeclSyntax(
43+
"""
44+
#if compiler(>=6)
45+
\(importingAttrs)\(visibilityKeyword) import SwiftSyntax
46+
#else
47+
\(importingAttrs)import SwiftSyntax
48+
#endif
49+
"""
50+
)
51+
}

CodeGeneration/Sources/generate-swift-syntax/templates/swiftparser/IsLexerClassifiedFile.swift

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -16,15 +16,7 @@ import SyntaxSupport
1616
import Utils
1717

1818
let isLexerClassifiedFile = SourceFileSyntax(leadingTrivia: copyrightHeader) {
19-
DeclSyntax(
20-
"""
21-
#if compiler(>=6)
22-
public import SwiftSyntax
23-
#else
24-
import SwiftSyntax
25-
#endif
26-
"""
27-
)
19+
importSwiftSyntax(accessLevel: .public)
2820

2921
try! ExtensionDeclSyntax(
3022
"""

CodeGeneration/Sources/generate-swift-syntax/templates/swiftparser/LayoutNodesParsableFile.swift

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -16,15 +16,7 @@ import SyntaxSupport
1616
import Utils
1717

1818
let layoutNodesParsableFile = SourceFileSyntax(leadingTrivia: copyrightHeader) {
19-
DeclSyntax(
20-
"""
21-
#if compiler(>=6)
22-
@_spi(RawSyntax) public import SwiftSyntax
23-
#else
24-
@_spi(RawSyntax) import SwiftSyntax
25-
#endif
26-
"""
27-
)
19+
importSwiftSyntax(accessLevel: .public)
2820

2921
DeclSyntax(
3022
"""
@@ -49,7 +41,7 @@ let layoutNodesParsableFile = SourceFileSyntax(leadingTrivia: copyrightHeader) {
4941
defer { withExtendedLifetime(parser) {} }
5042
let node = parser.\(parserFunction)()
5143
let raw = RawSyntax(parser.parseRemainder(into: node))
52-
return Syntax(raw: raw, rawNodeArena: parser.arena).cast(Self.self)
44+
return Syntax(raw: raw, rawNodeArena: raw.arena).cast(Self.self)
5345
}
5446
}
5547
"""

CodeGeneration/Sources/generate-swift-syntax/templates/swiftparser/ParserTokenSpecSetFile.swift

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -27,15 +27,7 @@ func tokenCaseMatch(
2727
}
2828

2929
let parserTokenSpecSetFile = SourceFileSyntax(leadingTrivia: copyrightHeader) {
30-
DeclSyntax(
31-
"""
32-
#if compiler(>=6)
33-
@_spi(RawSyntax) @_spi(ExperimentalLanguageFeatures) public import SwiftSyntax
34-
#else
35-
@_spi(RawSyntax) @_spi(ExperimentalLanguageFeatures) import SwiftSyntax
36-
#endif
37-
"""
38-
)
30+
importSwiftSyntax(accessLevel: .public)
3931

4032
for layoutNode in SYNTAX_NODES.compactMap(\.layoutNode) {
4133
for child in layoutNode.children {

CodeGeneration/Sources/generate-swift-syntax/templates/swiftparser/TokenSpecStaticMembersFile.swift

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -16,15 +16,7 @@ import SyntaxSupport
1616
import Utils
1717

1818
let tokenSpecStaticMembersFile = SourceFileSyntax(leadingTrivia: copyrightHeader) {
19-
DeclSyntax(
20-
"""
21-
#if compiler(>=6)
22-
@_spi(RawSyntax) internal import SwiftSyntax
23-
#else
24-
@_spi(RawSyntax) import SwiftSyntax
25-
#endif
26-
"""
27-
)
19+
importSwiftSyntax()
2820

2921
try! ExtensionDeclSyntax("extension TokenSpec") {
3022
for tokenSpec in Token.allCases.map(\.spec) where tokenSpec.kind != .keyword {

CodeGeneration/Sources/generate-swift-syntax/templates/swiftparserdiagnostics/ChildNameForDiagnosticsFile.swift

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -16,15 +16,7 @@ import SyntaxSupport
1616
import Utils
1717

1818
let childNameForDiagnosticFile = SourceFileSyntax(leadingTrivia: copyrightHeader) {
19-
DeclSyntax(
20-
"""
21-
#if compiler(>=6)
22-
@_spi(ExperimentalLanguageFeatures) internal import SwiftSyntax
23-
#else
24-
@_spi(ExperimentalLanguageFeatures) import SwiftSyntax
25-
#endif
26-
"""
27-
)
19+
importSwiftSyntax(accessLevel: .internal)
2820

2921
try! FunctionDeclSyntax(
3022
"private func childNameForDiagnostics(_ keyPath: AnyKeyPath) -> String?"

0 commit comments

Comments
 (0)