Skip to content

Commit f515bfa

Browse files
committed
Move layout validation to RawSyntax.
Validate the layout whenever the layout node is created.
1 parent 6963709 commit f515bfa

20 files changed

+2287
-12768
lines changed

Package.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ let package = Package(
5656
exclude: [
5757
"Misc.swift.gyb",
5858
"RawSyntaxNodes.swift.gyb",
59+
"RawSyntaxValidation.swift.gyb",
5960
"SyntaxAnyVisitor.swift.gyb",
6061
"SyntaxBaseNodes.swift.gyb",
6162
"SyntaxClassification.swift.gyb",

Sources/SwiftSyntax/RawSyntax.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -735,6 +735,7 @@ extension RawSyntax {
735735
descendantCount: Int,
736736
arena: SyntaxArena
737737
) -> RawSyntax {
738+
validateLayout(layout: layout, as: kind)
738739
let payload = RawSyntaxData.Layout(
739740
kind: kind, layout: layout,
740741
byteLength: byteLength, descendantCount: descendantCount)
@@ -757,7 +758,6 @@ extension RawSyntax {
757758
// Allocate and initialize the list.
758759
let layoutBuffer = arena.allocateRawSyntaxBuffer(count: count)
759760
initializer(layoutBuffer)
760-
// validateLayout(layout: RawSyntaxBuffer(layoutBuffer), as: kind)
761761

762762
// Calculate the "byte width".
763763
var byteLength = 0
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
%{
2+
from gyb_syntax_support import *
3+
# -*- mode: Swift -*-
4+
# Ignore the following admonition; it applies to the resulting .swift file only
5+
}%
6+
//// Automatically Generated From RawSyntaxValidation.swift.gyb.
7+
//// Do Not Edit Directly!
8+
//===----------- RawSyntaxValidation.swift - Layout validation ------------===//
9+
//
10+
// This source file is part of the Swift.org open source project
11+
//
12+
// Copyright (c) 2014 - 2022 Apple Inc. and the Swift project authors
13+
// Licensed under Apache License v2.0 with Runtime Library Exception
14+
//
15+
// See https://swift.org/LICENSE.txt for license information
16+
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
17+
//
18+
//===----------------------------------------------------------------------===//
19+
20+
21+
/// Check that the `layout` is valid for the given 'SyntaxKind'.
22+
///
23+
/// Note that this only validates the immediate children.
24+
/// Results in an assertion failure if the layout is invalid.
25+
func validateLayout(layout: RawSyntaxBuffer, as kind: SyntaxKind) {
26+
#if DEBUG
27+
func _verify<Node: RawSyntaxNodeProtocol>(_ raw: RawSyntax?, as _: Node.Type, file: StaticString = #file, line: UInt = #line) {
28+
assert(raw != nil, file: file, line: line)
29+
assert(Node.isKindOf(raw!), file: file, line: line)
30+
}
31+
func _verify<Node: RawSyntaxNodeProtocol>(_ raw: RawSyntax?, as _: Node?.Type, file: StaticString = #file, line: UInt = #line) {
32+
raw.map { assert(Node.isKindOf($0), file: file, line: line) }
33+
}
34+
switch kind {
35+
case .unknown:
36+
break
37+
case .token:
38+
assertionFailure("validateLayout for .token kind is not supported")
39+
% for node in NON_BASE_SYNTAX_NODES:
40+
case .${node.swift_syntax_kind}:
41+
% if node.is_buildable() or node.is_missing():
42+
assert(layout.count == ${len(node.children)})
43+
% for (idx, child) in enumerate(node.children):
44+
_verify(layout[${idx}], as: Raw${child.type_name}${"?" if child.is_optional else ""}.self)
45+
% end
46+
% elif node.is_syntax_collection():
47+
for element in layout {
48+
_verify(element, as: Raw${node.collection_element_type}.self)
49+
}
50+
% end
51+
break
52+
% end
53+
}
54+
#endif
55+
}

Sources/SwiftSyntax/Syntax.swift

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -29,11 +29,6 @@ public struct Syntax: SyntaxProtocol, SyntaxHashable {
2929
self.init(.forRoot(raw))
3030
}
3131

32-
public func _validateLayout() {
33-
// Check the layout of the concrete type
34-
return self.asProtocol(SyntaxProtocol.self)._validateLayout()
35-
}
36-
3732
/// Create a `Syntax` node from a specialized syntax node.
3833
public init<S: SyntaxProtocol>(_ syntax: S) {
3934
self = syntax._syntaxNode
@@ -119,11 +114,6 @@ public protocol SyntaxProtocol: CustomStringConvertible,
119114
/// conversion is not possible.
120115
init?(_ syntaxNode: Syntax)
121116

122-
/// Check that the raw layout of this node is valid. Used to verify a node's
123-
/// integrity after it has been rewritten by the syntax rewriter.
124-
/// Results in an assertion failure if the layout is invalid.
125-
func _validateLayout()
126-
127117
/// Returns the underlying syntax node type.
128118
var syntaxNodeType: SyntaxProtocol.Type { get }
129119
}

Sources/SwiftSyntax/SyntaxBaseNodes.swift.gyb

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -103,11 +103,6 @@ public struct ${node.name}: ${node.name}Protocol, SyntaxHashable {
103103
return _syntaxNode.syntaxNodeType
104104
}
105105

106-
public func _validateLayout() {
107-
// Check the layout of the concrete type
108-
return Syntax(self)._validateLayout()
109-
}
110-
111106
public func `is`<S: ${node.name}Protocol>(_ syntaxType: S.Type) -> Bool {
112107
return self.as(syntaxType) != nil
113108
}

Sources/SwiftSyntax/SyntaxCollections.swift.gyb

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -217,13 +217,6 @@ public struct ${node.name}: SyntaxCollection, SyntaxHashable {
217217
self = withTrailingTrivia(newValue ?? [])
218218
}
219219
}
220-
221-
public func _validateLayout() {
222-
// Check that all children match the expected element type
223-
assert(self.allSatisfy { node in
224-
return Syntax(node).is(${node.collection_element_type}.self)
225-
})
226-
}
227220
}
228221

229222
/// Conformance for `${node.name}` to the `BidirectionalCollection` protocol.

Sources/SwiftSyntax/SyntaxNodes.swift.gyb.template

Lines changed: 0 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -189,33 +189,6 @@ public struct ${node.name}: ${base_type}Protocol, SyntaxHashable {
189189
return ${node.name}(newData)
190190
}
191191
% end
192-
193-
% # ===================
194-
% # Validate layout
195-
% # ===================
196-
197-
public func _validateLayout() {
198-
% if node.is_unknown():
199-
// We are verifying an unknown node. Since we don’t know anything about it
200-
// we need to assume it’s valid.
201-
% else:
202-
let rawChildren = Array(RawSyntaxChildren(Syntax(self)))
203-
assert(rawChildren.count == ${len(node.children)})
204-
% for i, child in enumerate(node.children):
205-
// Check child #${i} child is ${child.type_name} ${"or missing" if child.is_optional else ""}
206-
% if not child.is_optional:
207-
assert(rawChildren[${i}].raw != nil)
208-
% end
209-
if let raw = rawChildren[${i}].raw {
210-
let info = rawChildren[${i}].syntaxInfo
211-
let absoluteRaw = AbsoluteRawSyntax(raw: raw, info: info)
212-
let syntaxData = SyntaxData(absoluteRaw, parent: Syntax(self))
213-
let syntaxChild = Syntax(syntaxData)
214-
assert(syntaxChild.is(${child.type_name}.self))
215-
}
216-
% end
217-
% end
218-
}
219192
}
220193

221194
extension ${node.name}: CustomReflectable {

Sources/SwiftSyntax/SyntaxOtherNodes.swift

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -29,11 +29,6 @@ public struct UnknownSyntax: SyntaxProtocol, SyntaxHashable {
2929
return Swift.type(of: self)
3030
}
3131

32-
public func _validateLayout() {
33-
// We are verifying an unknown node. Since we don’t know anything about it
34-
// we need to assume it’s valid.
35-
}
36-
3732
/// Creates an `UnknownSyntax` node from the given `SyntaxData`. This assumes
3833
/// that the `SyntaxData` is of the correct kind. If it is not, the behaviour
3934
/// is undefined.
@@ -93,10 +88,6 @@ public struct TokenSyntax: SyntaxProtocol, SyntaxHashable {
9388
return Swift.type(of: self)
9489
}
9590

96-
public func _validateLayout() {
97-
/// A token is always valid as it has no children. Nothing to do here.
98-
}
99-
10091
public var presence: SourcePresence {
10192
return raw.presence
10293
}

Sources/SwiftSyntax/SyntaxRewriter.swift.gyb

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -255,11 +255,6 @@ open class SyntaxRewriter {
255255

256256
let newRaw = node.raw.replacingLayout(Array(newLayout))
257257
let newNode = SyntaxType(Syntax(SyntaxData.forRoot(newRaw)))!
258-
assert({
259-
// In assertion builds inovoke the _validateLayout method
260-
newNode._validateLayout()
261-
return true
262-
}())
263258
return newNode
264259
} else {
265260
// No child node was rewritten. So no need to change this node as well.

0 commit comments

Comments
 (0)