Skip to content

Commit aa0b9a7

Browse files
committed
Conform NamedDeclSyntax to DeclSyntaxProtocol
This is accurate for all NamedDeclSyntax conformers so far, so I feel comfortable doing it. This also improves the accuracy of the “conforms if it can” validation by also checking the trait’s base kind against the node. That eliminates several false positives in the test.
1 parent 0386d87 commit aa0b9a7

File tree

3 files changed

+27
-12
lines changed

3 files changed

+27
-12
lines changed

CodeGeneration/Sources/SyntaxSupport/Traits.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,7 @@ public let TRAITS: [Trait] = [
111111
),
112112
Trait(
113113
traitName: "NamedDecl",
114+
baseKind: .decl,
114115
children: [
115116
Child(name: "name", kind: .token(choices: [.token(.identifier)]))
116117
]

CodeGeneration/Tests/ValidateSyntaxNodes/ValidateSyntaxNodes.swift

Lines changed: 25 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,30 @@ fileprivate extension Array where Element: Hashable, Element: Comparable {
116116
}
117117
}
118118

119+
extension LayoutNode {
120+
/// True if `self` satisfies all of the requirements of `trait`, regardless
121+
/// of whether it actually declares conformance to it.
122+
func canConform(to trait: Trait) -> Bool {
123+
if let traitBaseKind = trait.baseKind {
124+
guard traitBaseKind == self.base else {
125+
return false
126+
}
127+
}
128+
129+
return trait.children.allSatisfy { traitChild in
130+
self.children.contains { nodeChild in
131+
traitChild.hasSameType(as: nodeChild)
132+
}
133+
}
134+
}
135+
136+
/// True if `self` declares conformance to `trait`, regardless of whether
137+
/// it satisfies the trait's requirements.
138+
func conforms(to trait: Trait) -> Bool {
139+
self.traits.contains(trait.traitName)
140+
}
141+
}
142+
119143
class ValidateSyntaxNodes: XCTestCase {
120144
/// All nodes with base kind e.g. `ExprSyntax` should end with `ExprSyntax`.
121145
func testBaseKindSuffix() {
@@ -514,12 +538,7 @@ class ValidateSyntaxNodes: XCTestCase {
514538

515539
for node in SYNTAX_NODES.compactMap(\.layoutNode) {
516540
for trait in TRAITS {
517-
let canConformToTrait = trait.children.allSatisfy { traitChild in
518-
node.children.contains { nodeChild in
519-
traitChild.hasSameType(as: nodeChild)
520-
}
521-
}
522-
if canConformToTrait && !node.traits.contains(trait.traitName) {
541+
if node.canConform(to: trait) && !node.conforms(to: trait) {
523542
failures.append(
524543
ValidationFailure(
525544
node: node.kind,
@@ -533,7 +552,6 @@ class ValidateSyntaxNodes: XCTestCase {
533552
assertFailuresMatchXFails(
534553
failures,
535554
expectedFailures: [
536-
ValidationFailure(node: .accessorParameters, message: "could conform to trait 'NamedDecl' but does not"),
537555
ValidationFailure(node: .availabilityCondition, message: "could conform to trait 'Parenthesized' but does not"),
538556
ValidationFailure(node: ._canImportExpr, message: "could conform to trait 'Parenthesized' but does not"),
539557
ValidationFailure(
@@ -542,10 +560,6 @@ class ValidateSyntaxNodes: XCTestCase {
542560
),
543561
ValidationFailure(node: .editorPlaceholderDecl, message: "could conform to trait 'MissingNode' but does not"),
544562
ValidationFailure(node: .editorPlaceholderExpr, message: "could conform to trait 'MissingNode' but does not"),
545-
ValidationFailure(node: .enumCaseElement, message: "could conform to trait 'NamedDecl' but does not"),
546-
ValidationFailure(node: .genericParameter, message: "could conform to trait 'NamedDecl' but does not"),
547-
ValidationFailure(node: .precedenceGroupName, message: "could conform to trait 'NamedDecl' but does not"),
548-
ValidationFailure(node: .primaryAssociatedType, message: "could conform to trait 'NamedDecl' but does not"),
549563
ValidationFailure(
550564
node: .yieldedExpressionsClause,
551565
message: "could conform to trait 'Parenthesized' but does not"

Sources/SwiftSyntax/generated/SyntaxTraits.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -278,7 +278,7 @@ extension SyntaxProtocol {
278278

279279
// MARK: - NamedDeclSyntax
280280

281-
public protocol NamedDeclSyntax: SyntaxProtocol {
281+
public protocol NamedDeclSyntax: SyntaxProtocol, DeclSyntaxProtocol {
282282
/// ### Tokens
283283
///
284284
/// For syntax trees generated by the parser, this is guaranteed to be `<identifier>`.

0 commit comments

Comments
 (0)