Skip to content

Commit 27e8f91

Browse files
authored
Merge pull request #2558 from ahoppen/ahoppen/no-warnings-in-swiftsyntax
Make swift-syntax build without warnings
2 parents 1481235 + 24c8f91 commit 27e8f91

31 files changed

+327
-196
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: 6 additions & 12 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)
@@ -241,7 +233,11 @@ public class Node {
241233
// This will repeat the syntax type before and after the dot, which is
242234
// a little unfortunate, but it's the only way I found to get docc to
243235
// generate a fully-qualified type + member.
244-
return " - \($0.node.doccLink).``\($0.node.syntaxType)/\(childName)``"
236+
if $0.node.isAvailableInDocc {
237+
return " - \($0.node.doccLink).``\($0.node.syntaxType)/\(childName)``"
238+
} else {
239+
return " - \($0.node.doccLink).`\($0.node.syntaxType)/\(childName)`"
240+
}
245241
} else {
246242
return " - \($0.node.doccLink)"
247243
}
@@ -265,7 +261,7 @@ public class Node {
265261

266262
let list =
267263
SYNTAX_NODES
268-
.filter { $0.base == self.kind && !$0.isExperimental }
264+
.filter { $0.base == self.kind && !$0.isExperimental && !$0.kind.isDeprecated }
269265
.map { "- \($0.kind.doccLink)" }
270266
.joined(separator: "\n")
271267

@@ -288,7 +284,6 @@ public class Node {
288284
init(
289285
kind: SyntaxNodeKind,
290286
base: SyntaxNodeKind,
291-
deprecationMessage: String? = nil,
292287
experimentalFeature: ExperimentalFeature? = nil,
293288
nameForDiagnostics: String?,
294289
documentation: String? = nil,
@@ -298,7 +293,6 @@ public class Node {
298293
self.kind = kind
299294
precondition(base == .syntaxCollection)
300295
self.base = base
301-
self.deprecationMessage = deprecationMessage
302296
self.experimentalFeature = experimentalFeature
303297
self.nameForDiagnostics = nameForDiagnostics
304298
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: 38 additions & 5 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
@@ -355,14 +355,25 @@ public enum SyntaxNodeKind: String, CaseIterable {
355355
}
356356
}
357357

358+
/// Whether the node is public API and not underscored/deprecated and can thus be referenced in docc links.
359+
public var isAvailableInDocc: Bool {
360+
if let node = SYNTAX_NODE_MAP[self], node.isExperimental {
361+
return false
362+
} else if isDeprecated {
363+
return false
364+
} else {
365+
return true
366+
}
367+
}
368+
358369
/// If this node is non-experimental a docc link wrapped in two backticks.
359370
///
360371
/// For experimental nodes, the node's type name in code font.
361372
public var doccLink: String {
362-
if let node = SYNTAX_NODE_MAP[self], node.isExperimental {
363-
return "`\(syntaxType)`"
364-
} else {
373+
if isAvailableInDocc {
365374
return "``\(syntaxType)``"
375+
} else {
376+
return "`\(syntaxType)`"
366377
}
367378
}
368379

@@ -405,6 +416,8 @@ public enum SyntaxNodeKind: String, CaseIterable {
405416
/// deprecated.
406417
public var deprecatedRawValue: String? {
407418
switch self {
419+
case ._canImportExpr: return "canImportExpr"
420+
case ._canImportVersionInfo: return "canImportVersionInfo"
408421
case .accessorDeclList: return "accessorList"
409422
case .accessorParameters: return "accessorParameter"
410423
case .associatedTypeDecl: return "associatedtypeDecl"
@@ -475,4 +488,24 @@ public enum SyntaxNodeKind: String, CaseIterable {
475488
default: return nil
476489
}
477490
}
491+
492+
public var deprecationMessage: String? {
493+
switch self {
494+
case ._canImportExpr: return "'canImport' directives are now represented as a `FunctionCallExpr`"
495+
case ._canImportVersionInfo: return "'canImport' directives are now represented as a `FunctionCallExpr`"
496+
default: return nil
497+
}
498+
}
499+
500+
public var isDeprecated: Bool {
501+
return rawValue.first == "_"
502+
}
503+
504+
var deprecationAttribute: AttributeSyntax? {
505+
if let deprecationMessage = deprecationMessage {
506+
AttributeSyntax("@available(*, deprecated, message: \(literal: deprecationMessage)")
507+
} else {
508+
AttributeSyntax(#"@available(*, deprecated, renamed: "\#(syntaxType)")"#)
509+
}
510+
}
478511
}

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
"""

CodeGeneration/Tests/ValidateSyntaxNodes/ValidateSyntaxNodes.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@ class ValidateSyntaxNodes: XCTestCase {
136136
failures,
137137
expectedFailures: [
138138
ValidationFailure(
139-
node: .canImportVersionInfo,
139+
node: ._canImportVersionInfo,
140140
message: "has base kind 'ExprSyntax' but type name doesn’t have 'ExprSyntax' suffix"
141141
),
142142
ValidationFailure(
@@ -535,7 +535,7 @@ class ValidateSyntaxNodes: XCTestCase {
535535
expectedFailures: [
536536
ValidationFailure(node: .accessorParameters, message: "could conform to trait 'NamedDecl' but does not"),
537537
ValidationFailure(node: .availabilityCondition, message: "could conform to trait 'Parenthesized' but does not"),
538-
ValidationFailure(node: .canImportExpr, message: "could conform to trait 'Parenthesized' but does not"),
538+
ValidationFailure(node: ._canImportExpr, message: "could conform to trait 'Parenthesized' but does not"),
539539
ValidationFailure(
540540
node: .differentiabilityArguments,
541541
message: "could conform to trait 'Parenthesized' but does not"

Sources/SwiftBasicFormat/BasicFormat.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,7 @@ open class BasicFormat: SyntaxRewriter {
148148
return true
149149
case .ifConfigClauseList:
150150
return true
151-
case .memberDeclList:
151+
case .memberBlockItemList:
152152
return true
153153
case .switchCaseList:
154154
return true

Sources/SwiftParser/Declarations.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -711,7 +711,7 @@ extension Parser {
711711
extension Parser {
712712
mutating func parseMemberBlockItem() -> RawMemberBlockItemSyntax? {
713713
let startToken = self.currentToken
714-
if let syntax = self.loadCurrentSyntaxNodeFromCache(for: .memberDeclListItem) {
714+
if let syntax = self.loadCurrentSyntaxNodeFromCache(for: .memberBlockItem) {
715715
self.registerNodeForIncrementalParse(node: syntax.raw, startToken: startToken)
716716
return RawMemberBlockItemSyntax(syntax.raw)
717717
}

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

0 commit comments

Comments
 (0)