Skip to content

Commit 272cbb1

Browse files
committed
Instead of marking syntax nodes as deprecated, introduce an underscored version and deprecate a typealias
This allows us to still use the underscored version internally (eg. when matching the syntax node kind during the creation of a `SyntaxEnum` and keep swift-syntax building without warnings.
1 parent d7a4b5f commit 272cbb1

26 files changed

+295
-183
lines changed

CodeGeneration/Sources/SyntaxSupport/ExprNodes.swift

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -214,9 +214,8 @@ public let EXPR_NODES: [Node] = [
214214
),
215215

216216
Node(
217-
kind: .canImportExpr,
217+
kind: ._canImportExpr,
218218
base: .expr,
219-
deprecationMessage: "'canImport' directives are now represented as a `FunctionCallExpr`",
220219
nameForDiagnostics: "'canImport' expression",
221220
children: [
222221
Child(
@@ -233,7 +232,7 @@ public let EXPR_NODES: [Node] = [
233232
),
234233
Child(
235234
name: "versionInfo",
236-
kind: .node(kind: .canImportVersionInfo),
235+
kind: .node(kind: ._canImportVersionInfo),
237236
isOptional: true
238237
),
239238
Child(
@@ -244,9 +243,8 @@ public let EXPR_NODES: [Node] = [
244243
),
245244

246245
Node(
247-
kind: .canImportVersionInfo,
246+
kind: ._canImportVersionInfo,
248247
base: .expr,
249-
deprecationMessage: "'canImport' directives are now represented as a `FunctionCallExpr`",
250248
nameForDiagnostics: nil,
251249
children: [
252250
Child(

CodeGeneration/Sources/SyntaxSupport/Node.swift

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -40,9 +40,6 @@ public class Node {
4040
/// The kind of node’s supertype. This kind must have `isBase == true`
4141
public let base: SyntaxNodeKind
4242

43-
/// If this syntax node has been deprecated, a message that describes the deprecation.
44-
public let deprecationMessage: String?
45-
4643
/// The experimental feature the node is part of, or `nil` if this isn't
4744
/// for an experimental feature.
4845
public let experimentalFeature: ExperimentalFeature?
@@ -109,9 +106,6 @@ public class Node {
109106
"""
110107
experimentalSPI.with(\.trailingTrivia, .newline)
111108
}
112-
if let deprecationMessage {
113-
"@available(*, deprecated, message: \(literal: deprecationMessage))"
114-
}
115109
if forRaw {
116110
"@_spi(RawSyntax)"
117111
}
@@ -133,7 +127,6 @@ public class Node {
133127
init(
134128
kind: SyntaxNodeKind,
135129
base: SyntaxNodeKind,
136-
deprecationMessage: String? = nil,
137130
experimentalFeature: ExperimentalFeature? = nil,
138131
nameForDiagnostics: String?,
139132
documentation: String? = nil,
@@ -146,7 +139,6 @@ public class Node {
146139

147140
self.kind = kind
148141
self.base = base
149-
self.deprecationMessage = deprecationMessage
150142
self.experimentalFeature = experimentalFeature
151143
self.nameForDiagnostics = nameForDiagnostics
152144
self.documentation = SwiftSyntax.Trivia.docCommentTrivia(from: documentation)
@@ -265,7 +257,7 @@ public class Node {
265257

266258
let list =
267259
SYNTAX_NODES
268-
.filter { $0.base == self.kind && !$0.isExperimental }
260+
.filter { $0.base == self.kind && !$0.isExperimental && !$0.kind.isDeprecated }
269261
.map { "- \($0.kind.doccLink)" }
270262
.joined(separator: "\n")
271263

@@ -288,7 +280,6 @@ public class Node {
288280
init(
289281
kind: SyntaxNodeKind,
290282
base: SyntaxNodeKind,
291-
deprecationMessage: String? = nil,
292283
experimentalFeature: ExperimentalFeature? = nil,
293284
nameForDiagnostics: String?,
294285
documentation: String? = nil,
@@ -298,7 +289,6 @@ public class Node {
298289
self.kind = kind
299290
precondition(base == .syntaxCollection)
300291
self.base = base
301-
self.deprecationMessage = deprecationMessage
302292
self.experimentalFeature = experimentalFeature
303293
self.nameForDiagnostics = nameForDiagnostics
304294
self.documentation = SwiftSyntax.Trivia.docCommentTrivia(from: documentation)

CodeGeneration/Sources/SyntaxSupport/String+Extensions.swift

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,18 @@
1111
//===----------------------------------------------------------------------===//
1212

1313
public extension StringProtocol {
14-
var withFirstCharacterLowercased: String { prefix(1).lowercased() + dropFirst() }
15-
var withFirstCharacterUppercased: String { prefix(1).uppercased() + dropFirst() }
14+
var withFirstCharacterLowercased: String {
15+
guard first?.isLetter ?? false else {
16+
return String(first!) + dropFirst().withFirstCharacterLowercased
17+
}
18+
return prefix(1).lowercased() + dropFirst()
19+
}
20+
var withFirstCharacterUppercased: String {
21+
guard first?.isLetter ?? false else {
22+
return String(first!) + dropFirst().withFirstCharacterUppercased
23+
}
24+
return prefix(1).uppercased() + dropFirst()
25+
}
1626
var backtickedIfNeeded: String {
1727
if Keyword.allCases.map(\.spec).contains(where: {
1828
$0.name == self && ($0.isLexerClassified || $0.name == "Type" || $0.name == "Protocol")
@@ -23,3 +33,12 @@ public extension StringProtocol {
2333
}
2434
}
2535
}
36+
37+
extension String {
38+
public var droppingLeadingUnderscores: String {
39+
if first == "_" {
40+
return String(self.dropFirst())
41+
}
42+
return self
43+
}
44+
}

CodeGeneration/Sources/SyntaxSupport/SyntaxNodeKind.swift

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ import SwiftSyntaxBuilder
2020
public enum SyntaxNodeKind: String, CaseIterable {
2121
// Please keep this list sorted alphabetically
2222

23+
case _canImportExpr
24+
case _canImportVersionInfo
2325
case accessorBlock
2426
case accessorDecl
2527
case accessorDeclList
@@ -47,8 +49,6 @@ public enum SyntaxNodeKind: String, CaseIterable {
4749
case booleanLiteralExpr
4850
case borrowExpr
4951
case breakStmt
50-
case canImportExpr
51-
case canImportVersionInfo
5252
case catchClause
5353
case catchClauseList
5454
case catchItem
@@ -405,6 +405,8 @@ public enum SyntaxNodeKind: String, CaseIterable {
405405
/// deprecated.
406406
public var deprecatedRawValue: String? {
407407
switch self {
408+
case ._canImportExpr: return "canImportExpr"
409+
case ._canImportVersionInfo: return "canImportVersionInfo"
408410
case .accessorDeclList: return "accessorList"
409411
case .accessorParameters: return "accessorParameter"
410412
case .associatedTypeDecl: return "associatedtypeDecl"
@@ -475,4 +477,24 @@ public enum SyntaxNodeKind: String, CaseIterable {
475477
default: return nil
476478
}
477479
}
480+
481+
public var deprecationMessage: String? {
482+
switch self {
483+
case ._canImportExpr: return "'canImport' directives are now represented as a `FunctionCallExpr`"
484+
case ._canImportVersionInfo: return "'canImport' directives are now represented as a `FunctionCallExpr`"
485+
default: return nil
486+
}
487+
}
488+
489+
public var isDeprecated: Bool {
490+
return rawValue.first == "_"
491+
}
492+
493+
var deprecationAttribute: AttributeSyntax? {
494+
if let deprecationMessage = deprecationMessage {
495+
AttributeSyntax("@available(*, deprecated, message: \(literal: deprecationMessage)")
496+
} else {
497+
AttributeSyntax(#"@available(*, deprecated, renamed: "\#(syntaxType)")"#)
498+
}
499+
}
478500
}

CodeGeneration/Sources/SyntaxSupport/SyntaxNodes.swift

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,16 +10,24 @@
1010
//
1111
//===----------------------------------------------------------------------===//
1212

13-
public let SYNTAX_NODES: [Node] =
14-
(COMMON_NODES
13+
private let unsortedSyntaxNodes: [Node] =
14+
COMMON_NODES
1515
+ EXPR_NODES
1616
+ DECL_NODES
1717
+ ATTRIBUTE_NODES
1818
+ STMT_NODES
1919
+ GENERIC_NODES
2020
+ TYPE_NODES
2121
+ PATTERN_NODES
22-
+ AVAILABILITY_NODES).sorted { $0.kind.syntaxType.description < $1.kind.syntaxType.description }
22+
+ AVAILABILITY_NODES
23+
24+
public let SYNTAX_NODES: [Node] =
25+
unsortedSyntaxNodes
26+
.sorted { (lhs: Node, rhs: Node) -> Bool in
27+
let lhsSortKey = lhs.kind.syntaxType.description.droppingLeadingUnderscores
28+
let rhsSortKey = rhs.kind.syntaxType.description.droppingLeadingUnderscores
29+
return lhsSortKey < rhsSortKey
30+
}
2331

2432
/// A lookup table of nodes indexed by their kind.
2533
public let SYNTAX_NODE_MAP: [SyntaxNodeKind: Node] = Dictionary(

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

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,10 @@ fileprivate extension Node {
4242
func rawSyntaxNodesFile(nodesStartingWith: [Character]) -> SourceFileSyntax {
4343
return SourceFileSyntax(leadingTrivia: copyrightHeader) {
4444
for node in SYNTAX_NODES
45-
where node.kind.isBase && nodesStartingWith.contains(node.kind.syntaxType.description.first!) {
45+
where node.kind.isBase
46+
&& nodesStartingWith.contains(node.kind.syntaxType.description.droppingLeadingUnderscores.first!)
47+
&& !node.kind.isDeprecated
48+
{
4649
DeclSyntax(
4750
"""
4851
\(node.apiAttributes(forRaw: true))\
@@ -51,7 +54,8 @@ func rawSyntaxNodesFile(nodesStartingWith: [Character]) -> SourceFileSyntax {
5154
)
5255
}
5356

54-
for node in SYNTAX_NODES where nodesStartingWith.contains(node.kind.syntaxType.description.first!) {
57+
for node in SYNTAX_NODES
58+
where nodesStartingWith.contains(node.kind.syntaxType.description.droppingLeadingUnderscores.first!) {
5559
try! StructDeclSyntax(
5660
"""
5761
\(node.apiAttributes(forRaw: true))\

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

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,19 @@ import SwiftSyntaxBuilder
1515
import SyntaxSupport
1616
import Utils
1717

18+
func deprecationAttribute(for syntaxKind: SyntaxNodeKind) -> AttributeSyntax {
19+
if let deprecationMessage = syntaxKind.deprecationMessage {
20+
return AttributeSyntax("@available(*, deprecated, message: \(literal: deprecationMessage))")
21+
}
22+
return AttributeSyntax(#"@available(*, deprecated, renamed: "\#(syntaxKind.syntaxType)")"#)
23+
}
24+
1825
let renamedSyntaxNodesFile = SourceFileSyntax(leadingTrivia: copyrightHeader) {
1926
for syntaxKind in SyntaxNodeKind.allCases.sorted(by: { $0.deprecatedRawValue ?? "" < $1.deprecatedRawValue ?? "" }) {
2027
if let deprecatedName = syntaxKind.deprecatedRawValue {
2128
DeclSyntax(
2229
"""
23-
@available(*, deprecated, renamed: "\(syntaxKind.syntaxType)")
30+
\(deprecationAttribute(for: syntaxKind))
2431
public typealias \(raw: deprecatedName.withFirstCharacterUppercased)Syntax = \(syntaxKind.syntaxType)
2532
"""
2633
)
@@ -33,6 +40,7 @@ let renamedSyntaxNodesFile = SourceFileSyntax(leadingTrivia: copyrightHeader) {
3340
if let deprecatedName = syntaxKind.deprecatedRawValue {
3441
DeclSyntax(
3542
"""
43+
\(deprecationAttribute(for: syntaxKind))
3644
static var \(raw: deprecatedName): Self {
3745
return .\(syntaxKind.varOrCaseName)
3846
}

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

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ let nodesSections: String = {
3939
let baseTypes = ["\(baseKind.syntaxType)", "\(baseKind.syntaxType)Protocol", "Missing\(baseKind.syntaxType)"]
4040
let leafTypes =
4141
SYNTAX_NODES
42-
.filter({ $0.base == baseKind && !$0.kind.isMissing && !$0.isExperimental })
42+
.filter({ $0.base == baseKind && !$0.kind.isMissing && !$0.isExperimental && !$0.kind.isDeprecated })
4343
.map(\.kind.syntaxType.description)
4444
addSection(heading: heading, types: baseTypes + leafTypes)
4545
}
@@ -56,22 +56,24 @@ let nodesSections: String = {
5656
}
5757
return [node.kind.syntaxType.description]
5858
+ node.elementChoices
59-
.filter { SYNTAX_NODE_MAP[$0] != nil && !SYNTAX_NODE_MAP[$0]!.isExperimental }
59+
.filter { SYNTAX_NODE_MAP[$0] != nil && !SYNTAX_NODE_MAP[$0]!.isExperimental && !$0.isDeprecated }
6060
.map(\.syntaxType.description)
6161
.filter { !handledSyntaxTypes.contains($0) }
6262
})
6363
)
6464

6565
addSection(
6666
heading: "Attributes",
67-
types: ATTRIBUTE_NODES.filter({ !$0.isExperimental }).map(\.kind.syntaxType.description).sorted()
67+
types: ATTRIBUTE_NODES.filter({ !$0.isExperimental && !$0.kind.isDeprecated }).map(\.kind.syntaxType.description)
68+
.sorted()
6869
)
6970

7071
addSection(
7172
heading: "Miscellaneous Syntax",
72-
types: SYNTAX_NODES.filter({ !$0.isExperimental }).map(\.kind.syntaxType.description).filter({
73-
!handledSyntaxTypes.contains($0)
74-
})
73+
types: SYNTAX_NODES.filter({ !$0.isExperimental && !$0.kind.isDeprecated }).map(\.kind.syntaxType.description)
74+
.filter({
75+
!handledSyntaxTypes.contains($0)
76+
})
7577
)
7678

7779
addSection(heading: "Traits", types: TRAITS.map { "\($0.protocolName)" })

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ import Utils
2222
func syntaxNode(nodesStartingWith: [Character]) -> SourceFileSyntax {
2323
SourceFileSyntax(leadingTrivia: copyrightHeader) {
2424
for node in SYNTAX_NODES.compactMap(\.layoutNode)
25-
where nodesStartingWith.contains(node.kind.syntaxType.description.first!) {
25+
where nodesStartingWith.contains(node.kind.syntaxType.description.droppingLeadingUnderscores.first!) {
2626
// We are actually handling this node now
2727
try! StructDeclSyntax(
2828
"""

Sources/SwiftParser/generated/Parser+TokenSpecSet.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -404,7 +404,7 @@ extension BooleanLiteralExprSyntax {
404404
}
405405
}
406406

407-
extension CanImportVersionInfoSyntax {
407+
extension _CanImportVersionInfoSyntax {
408408
@_spi(Diagnostics)
409409
public enum LabelOptions: TokenSpecSet {
410410
case _version

Sources/SwiftParserDiagnostics/generated/SyntaxKindNameForDiagnostics.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ extension SyntaxKind {
6161
return "'_borrow' expression"
6262
case .breakStmt:
6363
return "'break' statement"
64-
case .canImportExpr:
64+
case ._canImportExpr:
6565
return "'canImport' expression"
6666
case .catchClauseList:
6767
return "'catch' clause"

Sources/SwiftSyntax/Documentation.docc/generated/SwiftSyntax.md

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -102,8 +102,6 @@ These articles are intended for developers wishing to contribute to SwiftSyntax
102102
- <doc:SwiftSyntax/BinaryOperatorExprSyntax>
103103
- <doc:SwiftSyntax/BooleanLiteralExprSyntax>
104104
- <doc:SwiftSyntax/BorrowExprSyntax>
105-
- <doc:SwiftSyntax/CanImportExprSyntax>
106-
- <doc:SwiftSyntax/CanImportVersionInfoSyntax>
107105
- <doc:SwiftSyntax/ClosureExprSyntax>
108106
- <doc:SwiftSyntax/ConsumeExprSyntax>
109107
- <doc:SwiftSyntax/CopyExprSyntax>

Sources/SwiftSyntax/generated/ChildNameForKeyPath.swift

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -351,45 +351,45 @@ public func childName(_ keyPath: AnyKeyPath) -> String? {
351351
return "label"
352352
case \BreakStmtSyntax.unexpectedAfterLabel:
353353
return "unexpectedAfterLabel"
354-
case \CanImportExprSyntax.unexpectedBeforeCanImportKeyword:
354+
case \_CanImportExprSyntax.unexpectedBeforeCanImportKeyword:
355355
return "unexpectedBeforeCanImportKeyword"
356-
case \CanImportExprSyntax.canImportKeyword:
356+
case \_CanImportExprSyntax.canImportKeyword:
357357
return "canImportKeyword"
358-
case \CanImportExprSyntax.unexpectedBetweenCanImportKeywordAndLeftParen:
358+
case \_CanImportExprSyntax.unexpectedBetweenCanImportKeywordAndLeftParen:
359359
return "unexpectedBetweenCanImportKeywordAndLeftParen"
360-
case \CanImportExprSyntax.leftParen:
360+
case \_CanImportExprSyntax.leftParen:
361361
return "leftParen"
362-
case \CanImportExprSyntax.unexpectedBetweenLeftParenAndImportPath:
362+
case \_CanImportExprSyntax.unexpectedBetweenLeftParenAndImportPath:
363363
return "unexpectedBetweenLeftParenAndImportPath"
364-
case \CanImportExprSyntax.importPath:
364+
case \_CanImportExprSyntax.importPath:
365365
return "importPath"
366-
case \CanImportExprSyntax.unexpectedBetweenImportPathAndVersionInfo:
366+
case \_CanImportExprSyntax.unexpectedBetweenImportPathAndVersionInfo:
367367
return "unexpectedBetweenImportPathAndVersionInfo"
368-
case \CanImportExprSyntax.versionInfo:
368+
case \_CanImportExprSyntax.versionInfo:
369369
return "versionInfo"
370-
case \CanImportExprSyntax.unexpectedBetweenVersionInfoAndRightParen:
370+
case \_CanImportExprSyntax.unexpectedBetweenVersionInfoAndRightParen:
371371
return "unexpectedBetweenVersionInfoAndRightParen"
372-
case \CanImportExprSyntax.rightParen:
372+
case \_CanImportExprSyntax.rightParen:
373373
return "rightParen"
374-
case \CanImportExprSyntax.unexpectedAfterRightParen:
374+
case \_CanImportExprSyntax.unexpectedAfterRightParen:
375375
return "unexpectedAfterRightParen"
376-
case \CanImportVersionInfoSyntax.unexpectedBeforeComma:
376+
case \_CanImportVersionInfoSyntax.unexpectedBeforeComma:
377377
return "unexpectedBeforeComma"
378-
case \CanImportVersionInfoSyntax.comma:
378+
case \_CanImportVersionInfoSyntax.comma:
379379
return "comma"
380-
case \CanImportVersionInfoSyntax.unexpectedBetweenCommaAndLabel:
380+
case \_CanImportVersionInfoSyntax.unexpectedBetweenCommaAndLabel:
381381
return "unexpectedBetweenCommaAndLabel"
382-
case \CanImportVersionInfoSyntax.label:
382+
case \_CanImportVersionInfoSyntax.label:
383383
return "label"
384-
case \CanImportVersionInfoSyntax.unexpectedBetweenLabelAndColon:
384+
case \_CanImportVersionInfoSyntax.unexpectedBetweenLabelAndColon:
385385
return "unexpectedBetweenLabelAndColon"
386-
case \CanImportVersionInfoSyntax.colon:
386+
case \_CanImportVersionInfoSyntax.colon:
387387
return "colon"
388-
case \CanImportVersionInfoSyntax.unexpectedBetweenColonAndVersion:
388+
case \_CanImportVersionInfoSyntax.unexpectedBetweenColonAndVersion:
389389
return "unexpectedBetweenColonAndVersion"
390-
case \CanImportVersionInfoSyntax.version:
390+
case \_CanImportVersionInfoSyntax.version:
391391
return "version"
392-
case \CanImportVersionInfoSyntax.unexpectedAfterVersion:
392+
case \_CanImportVersionInfoSyntax.unexpectedAfterVersion:
393393
return "unexpectedAfterVersion"
394394
case \CatchClauseSyntax.unexpectedBeforeCatchKeyword:
395395
return "unexpectedBeforeCatchKeyword"

0 commit comments

Comments
 (0)