Skip to content

Commit 2e8bff5

Browse files
authored
Merge pull request #1913 from ahoppen/ahoppen/validate-listsyntax
Add validation that all syntax collections end with `ListSyntax`
2 parents 70cdb8e + bd5bcd3 commit 2e8bff5

38 files changed

+668
-532
lines changed

CodeGeneration/Sources/SyntaxSupport/AttributeNodes.swift

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ public let ATTRIBUTE_NODES: [Node] = [
8080
),
8181
Child(
8282
name: "ObjCName",
83-
kind: .node(kind: .objCSelector)
83+
kind: .node(kind: .objCSelectorPieceList)
8484
),
8585
Child(
8686
name: "ImplementsArguments",
@@ -132,11 +132,11 @@ public let ATTRIBUTE_NODES: [Node] = [
132132
),
133133
Child(
134134
name: "EffectsArguments",
135-
kind: .node(kind: .effectsArguments)
135+
kind: .node(kind: .effectsArgumentList)
136136
),
137137
Child(
138138
name: "DocumentationArguments",
139-
kind: .node(kind: .documentationAttributeArguments)
139+
kind: .node(kind: .documentationAttributeArgumentList)
140140
),
141141
]),
142142
documentation: "The arguments of the attribute. In case the attribute takes multiple arguments, they are gather in the appropriate takes first.",
@@ -562,7 +562,7 @@ public let ATTRIBUTE_NODES: [Node] = [
562562
),
563563

564564
Node(
565-
kind: .documentationAttributeArguments,
565+
kind: .documentationAttributeArgumentList,
566566
base: .syntaxCollection,
567567
nameForDiagnostics: "@_documentation arguments",
568568
documentation: "The arguments of the '@_documentation' attribute",
@@ -592,7 +592,7 @@ public let ATTRIBUTE_NODES: [Node] = [
592592
),
593593

594594
Node(
595-
kind: .effectsArguments,
595+
kind: .effectsArgumentList,
596596
base: .syntaxCollection,
597597
nameForDiagnostics: "@_effects arguments",
598598
documentation: "The arguments of the '@_effect' attribute. These will be parsed during the SIL stage.",
@@ -719,7 +719,7 @@ public let ATTRIBUTE_NODES: [Node] = [
719719

720720
// objc-selector -> objc-selector-piece objc-selector?
721721
Node(
722-
kind: .objCSelector,
722+
kind: .objCSelectorPieceList,
723723
base: .syntaxCollection,
724724
nameForDiagnostics: "Objective-C selector",
725725
elementChoices: [.objCSelectorPiece]

CodeGeneration/Sources/SyntaxSupport/DeclNodes.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ public let DECL_NODES: [Node] = [
3636
),
3737

3838
Node(
39-
kind: .importPath,
39+
kind: .importPathComponentList,
4040
base: .syntaxCollection,
4141
nameForDiagnostics: nil,
4242
elementChoices: [.importPathComponent]
@@ -1246,7 +1246,7 @@ public let DECL_NODES: [Node] = [
12461246
),
12471247
Child(
12481248
name: "Path",
1249-
kind: .collection(kind: .importPath, collectionElementName: "PathComponent"),
1249+
kind: .collection(kind: .importPathComponentList, collectionElementName: "PathComponent"),
12501250
documentation: "The path to the module, submodule or symbol being imported."
12511251
),
12521252
]

CodeGeneration/Sources/SyntaxSupport/ExprNodes.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1488,7 +1488,7 @@ public let EXPR_NODES: [Node] = [
14881488
),
14891489
Child(
14901490
name: "Segments",
1491-
kind: .collection(kind: .stringLiteralSegments, collectionElementName: "Segment")
1491+
kind: .collection(kind: .stringLiteralSegmentList, collectionElementName: "Segment")
14921492
),
14931493
Child(
14941494
name: "CloseQuote",
@@ -1503,7 +1503,7 @@ public let EXPR_NODES: [Node] = [
15031503
),
15041504

15051505
Node(
1506-
kind: .stringLiteralSegments,
1506+
kind: .stringLiteralSegmentList,
15071507
base: .syntaxCollection,
15081508
nameForDiagnostics: nil,
15091509
elementChoices: [.stringSegment, .expressionSegment]

CodeGeneration/Sources/SyntaxSupport/SyntaxNodeKind.swift

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -114,11 +114,11 @@ public enum SyntaxNodeKind: String, CaseIterable {
114114
case discardStmt
115115
case doStmt
116116
case documentationAttributeArgument
117-
case documentationAttributeArguments
117+
case documentationAttributeArgumentList
118118
case dynamicReplacementArguments
119119
case editorPlaceholderDecl
120120
case editorPlaceholderExpr
121-
case effectsArguments
121+
case effectsArgumentList
122122
case enumCaseDecl
123123
case enumCaseElementList
124124
case enumCaseElement
@@ -164,7 +164,7 @@ public enum SyntaxNodeKind: String, CaseIterable {
164164
case implicitlyUnwrappedOptionalType
165165
case importDecl
166166
case importPathComponent
167-
case importPath
167+
case importPathComponentList
168168
case inOutExpr
169169
case infixOperatorExpr
170170
case inheritedTypeList
@@ -207,7 +207,7 @@ public enum SyntaxNodeKind: String, CaseIterable {
207207
case namedOpaqueReturnType
208208
case nilLiteralExpr
209209
case objCSelectorPiece
210-
case objCSelector
210+
case objCSelectorPieceList
211211
case opaqueReturnTypeOfAttributeArguments
212212
case operatorDecl
213213
case operatorPrecedenceAndTypes
@@ -252,7 +252,7 @@ public enum SyntaxNodeKind: String, CaseIterable {
252252
case specializeExpr
253253
case stmt
254254
case stringLiteralExpr
255-
case stringLiteralSegments
255+
case stringLiteralSegmentList
256256
case stringSegment
257257
case structDecl
258258
case subscriptDecl
@@ -369,4 +369,23 @@ public enum SyntaxNodeKind: String, CaseIterable {
369369
return "Raw\(raw: rawValue.withFirstCharacterUppercased)SyntaxNodeProtocol"
370370
}
371371
}
372+
373+
public var deprecatedRawValue: String? {
374+
switch self {
375+
case .importPathComponentList:
376+
return "accessPath"
377+
case .importPathComponent:
378+
return "accessPathComponent"
379+
case .documentationAttributeArgumentList:
380+
return "documentationAttributeArguments"
381+
case .effectsArgumentList:
382+
return "effectsArguments"
383+
case .objCSelectorPieceList:
384+
return "objCSelector"
385+
case .stringLiteralSegmentList:
386+
return "stringLiteralSegments"
387+
default:
388+
return nil
389+
}
390+
}
372391
}

CodeGeneration/Sources/generate-swiftsyntax/GenerateSwiftSyntax.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@ struct GenerateSwiftSyntax: ParsableCommand {
9797
GeneratedFileSpec(swiftSyntaxGeneratedDir + ["raw", "RawSyntaxNodes.swift"], rawSyntaxNodesFile),
9898
GeneratedFileSpec(swiftSyntaxGeneratedDir + ["raw", "RawSyntaxValidation.swift"], rawSyntaxValidationFile),
9999
GeneratedFileSpec(swiftSyntaxGeneratedDir + ["RenamedChildrenCompatibility.swift"], renamedChildrenCompatibilityFile),
100+
GeneratedFileSpec(swiftSyntaxGeneratedDir + ["RenamedNodesCompatibility.swift"], renamedSyntaxNodesFile),
100101
GeneratedFileSpec(swiftSyntaxGeneratedDir + ["SyntaxAnyVisitor.swift"], syntaxAnyVisitorFile),
101102
GeneratedFileSpec(swiftSyntaxGeneratedDir + ["SyntaxBaseNodes.swift"], syntaxBaseNodesFile),
102103
GeneratedFileSpec(swiftSyntaxGeneratedDir + ["SyntaxCollections.swift"], syntaxCollectionsFile),
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2023 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+
import Utils
17+
18+
let renamedSyntaxNodesFile = SourceFileSyntax(leadingTrivia: copyrightHeader) {
19+
for syntaxKind in SyntaxNodeKind.allCases.sorted(by: { $0.deprecatedRawValue ?? "" < $1.deprecatedRawValue ?? "" }) {
20+
if let deprecatedName = syntaxKind.deprecatedRawValue {
21+
DeclSyntax(
22+
"""
23+
@available(*, deprecated, renamed: "\(syntaxKind.syntaxType)")
24+
public typealias \(raw: deprecatedName.withFirstCharacterUppercased)Syntax = \(syntaxKind.syntaxType)
25+
"""
26+
)
27+
}
28+
}
29+
30+
try! ExtensionDeclSyntax("public extension SyntaxKind") {
31+
for syntaxKind in SyntaxNodeKind.allCases.sorted(by: { $0.deprecatedRawValue ?? "" < $1.deprecatedRawValue ?? "" }) {
32+
if let deprecatedName = syntaxKind.deprecatedRawValue {
33+
DeclSyntax(
34+
"""
35+
static var \(raw: deprecatedName): Self {
36+
return .\(syntaxKind.varOrCaseName)
37+
}
38+
"""
39+
)
40+
}
41+
}
42+
}
43+
}

CodeGeneration/Tests/ValidateSyntaxNodes/ValidateSyntaxNodes.swift

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,28 @@ class ValidateSyntaxNodes: XCTestCase {
138138
)
139139
}
140140

141+
func testSyntaxCollectionsShouldEndWithList() {
142+
var failures: [ValidationFailure] = []
143+
144+
for node in SYNTAX_NODES.compactMap(\.collectionNode) {
145+
if !node.kind.syntaxType.description.hasSuffix("ListSyntax") {
146+
failures.append(
147+
ValidationFailure(
148+
node: node.kind,
149+
message: "is a collection but does not end with ListSyntax"
150+
)
151+
)
152+
}
153+
}
154+
155+
assertFailuresMatchXFails(
156+
failures,
157+
expectedFailures: [
158+
ValidationFailure(node: .unexpectedNodes, message: "is a collection but does not end with ListSyntax")
159+
]
160+
)
161+
}
162+
141163
/// Implementation detail of `testSingleTokenChoiceChildNaming`, validating a single child.
142164
///
143165
/// - Returns: A failure message if validation failed, otherwise `nil`

Sources/SwiftParser/Attributes.swift

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -290,7 +290,7 @@ extension Parser {
290290
while !parser.at(.rightParen, .endOfFile) {
291291
tokens.append(parser.consumeAnyToken())
292292
}
293-
return .effectsArguments(RawEffectsArgumentsSyntax(elements: tokens, arena: parser.arena))
293+
return .effectsArguments(RawEffectsArgumentListSyntax(elements: tokens, arena: parser.arena))
294294
}
295295
case ._cdecl:
296296
return parseAttribute(argumentMode: .required) { parser in
@@ -591,7 +591,7 @@ extension Parser {
591591
}
592592

593593
extension Parser {
594-
mutating func parseObjectiveCSelector() -> RawObjCSelectorSyntax {
594+
mutating func parseObjectiveCSelector() -> RawObjCSelectorPieceListSyntax {
595595
var elements = [RawObjCSelectorPieceSyntax]()
596596
var loopProgress = LoopProgressCondition()
597597
while self.hasProgressed(&loopProgress) {
@@ -633,7 +633,7 @@ extension Parser {
633633
break
634634
}
635635
}
636-
return RawObjCSelectorSyntax(elements: elements, arena: self.arena)
636+
return RawObjCSelectorPieceListSyntax(elements: elements, arena: self.arena)
637637
}
638638
}
639639

@@ -1069,7 +1069,7 @@ extension Parser {
10691069
}
10701070

10711071
extension Parser {
1072-
mutating func parseDocumentationAttributeArguments() -> RawDocumentationAttributeArgumentsSyntax {
1072+
mutating func parseDocumentationAttributeArguments() -> RawDocumentationAttributeArgumentListSyntax {
10731073
var arguments: [RawDocumentationAttributeArgumentSyntax] = []
10741074

10751075
var keepGoing: RawTokenSyntax? = nil
@@ -1138,7 +1138,7 @@ extension Parser {
11381138
)
11391139
} while keepGoing != nil
11401140

1141-
return RawDocumentationAttributeArgumentsSyntax(elements: arguments, arena: self.arena)
1141+
return RawDocumentationAttributeArgumentListSyntax(elements: arguments, arena: self.arena)
11421142
}
11431143
}
11441144

Sources/SwiftParser/Declarations.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -312,7 +312,7 @@ extension Parser {
312312
return self.consume(ifAnyIn: ImportDeclSyntax.ImportKindSpecifierOptions.self)
313313
}
314314

315-
mutating func parseImportPath() -> RawImportPathSyntax {
315+
mutating func parseImportPath() -> RawImportPathComponentListSyntax {
316316
var elements = [RawImportPathComponentSyntax]()
317317
var keepGoing: RawTokenSyntax? = nil
318318
var loopProgress = LoopProgressCondition()
@@ -327,7 +327,7 @@ extension Parser {
327327
)
328328
)
329329
} while keepGoing != nil && self.hasProgressed(&loopProgress)
330-
return RawImportPathSyntax(elements: elements, arena: self.arena)
330+
return RawImportPathComponentListSyntax(elements: elements, arena: self.arena)
331331
}
332332
}
333333

Sources/SwiftParser/StringLiterals.swift

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,7 @@ extension Parser {
164164
private func reclassifyNewlineOfLastSegmentAsTrivia(
165165
rawStringDelimitersToken: RawTokenSyntax?,
166166
openQuoteHasTrailingNewline: Bool,
167-
middleSegments: inout [RawStringLiteralSegmentsSyntax.Element]
167+
middleSegments: inout [RawStringLiteralSegmentListSyntax.Element]
168168
) -> Bool {
169169
switch middleSegments.last {
170170
case .stringSegment(let lastMiddleSegment):
@@ -229,7 +229,7 @@ extension Parser {
229229
/// attached to the string segment token.
230230
private func postProcessIndentationAndEscapedNewlineOfMiddleSegments(
231231
rawStringDelimitersToken: RawTokenSyntax?,
232-
middleSegments: inout [RawStringLiteralSegmentsSyntax.Element],
232+
middleSegments: inout [RawStringLiteralSegmentListSyntax.Element],
233233
isFirstSegmentOnNewLine: Bool,
234234
indentation: SyntaxText
235235
) {
@@ -303,12 +303,12 @@ extension Parser {
303303
private func postProcessMultilineStringLiteral(
304304
rawStringDelimitersToken: RawTokenSyntax?,
305305
openQuote: RawTokenSyntax,
306-
segments allSegments: [RawStringLiteralSegmentsSyntax.Element],
306+
segments allSegments: [RawStringLiteralSegmentListSyntax.Element],
307307
closeQuote: RawTokenSyntax
308308
) -> (
309309
unexpectedBeforeOpenQuote: [RawTokenSyntax],
310310
openQuote: RawTokenSyntax,
311-
segments: [RawStringLiteralSegmentsSyntax.Element],
311+
segments: [RawStringLiteralSegmentListSyntax.Element],
312312
unexpectedBeforeCloseQuote: [RawTokenSyntax],
313313
closeQuote: RawTokenSyntax
314314
) {
@@ -485,7 +485,7 @@ extension Parser {
485485
}
486486

487487
/// Parse segments.
488-
var segments: [RawStringLiteralSegmentsSyntax.Element] = []
488+
var segments: [RawStringLiteralSegmentListSyntax.Element] = []
489489
var loopProgress = LoopProgressCondition()
490490
while self.hasProgressed(&loopProgress) {
491491
// If we encounter a token with leading trivia, we're no longer in the
@@ -574,7 +574,7 @@ extension Parser {
574574
openDelimiter: openDelimiter,
575575
RawUnexpectedNodesSyntax(combining: unexpectedBeforeOpenQuote, postProcessed.unexpectedBeforeOpenQuote, arena: self.arena),
576576
openQuote: postProcessed.openQuote,
577-
segments: RawStringLiteralSegmentsSyntax(elements: postProcessed.segments, arena: self.arena),
577+
segments: RawStringLiteralSegmentListSyntax(elements: postProcessed.segments, arena: self.arena),
578578
RawUnexpectedNodesSyntax(combining: postProcessed.unexpectedBeforeCloseQuote, unexpectedBeforeCloseQuote, arena: self.arena),
579579
closeQuote: postProcessed.closeQuote,
580580
unexpectedBeforeCloseDelimiter,
@@ -586,7 +586,7 @@ extension Parser {
586586
openDelimiter: openDelimiter,
587587
unexpectedBeforeOpenQuote,
588588
openQuote: openQuote,
589-
segments: RawStringLiteralSegmentsSyntax(elements: segments, arena: self.arena),
589+
segments: RawStringLiteralSegmentListSyntax(elements: segments, arena: self.arena),
590590
unexpectedBeforeCloseQuote,
591591
closeQuote: closeQuote,
592592
unexpectedBeforeCloseDelimiter,

Sources/SwiftParserDiagnostics/ParserDiagnosticMessages.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -407,7 +407,7 @@ public struct MissingAttributeArgument: ParserError {
407407
}
408408

409409
public struct MissingBothStringQuotesOfStringSegments: ParserError {
410-
public let stringSegments: StringLiteralSegmentsSyntax
410+
public let stringSegments: StringLiteralSegmentListSyntax
411411

412412
public var message: String {
413413
return #"expected \#(stringSegments.shortSingleLineContentDescription) to be surrounded by '"'"#

Sources/SwiftParserDiagnostics/generated/SyntaxKindNameForDiagnostics.swift

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -147,17 +147,17 @@ extension SyntaxKind {
147147
return "'discard' statement"
148148
case .doStmt:
149149
return "'do' statement"
150+
case .documentationAttributeArgumentList:
151+
return "@_documentation arguments"
150152
case .documentationAttributeArgument:
151153
return "@_documentation argument"
152-
case .documentationAttributeArguments:
153-
return "@_documentation arguments"
154154
case .dynamicReplacementArguments:
155155
return "@_dynamicReplacement argument"
156156
case .editorPlaceholderDecl:
157157
return "editor placeholder"
158158
case .editorPlaceholderExpr:
159159
return "editor placeholder"
160-
case .effectsArguments:
160+
case .effectsArgumentList:
161161
return "@_effects arguments"
162162
case .enumCaseDecl:
163163
return "enum case"
@@ -287,10 +287,10 @@ extension SyntaxKind {
287287
return "trailing closure"
288288
case .namedOpaqueReturnType:
289289
return "named opaque return type"
290+
case .objCSelectorPieceList:
291+
return "Objective-C selector"
290292
case .objCSelectorPiece:
291293
return "Objective-C selector piece"
292-
case .objCSelector:
293-
return "Objective-C selector"
294294
case .opaqueReturnTypeOfAttributeArguments:
295295
return "opaque return type arguments"
296296
case .operatorDecl:

0 commit comments

Comments
 (0)