File tree Expand file tree Collapse file tree 5 files changed +78
-1
lines changed Expand file tree Collapse file tree 5 files changed +78
-1
lines changed Original file line number Diff line number Diff line change @@ -36,6 +36,8 @@ internal struct RawSyntaxData {
36
36
var byteLength : Int
37
37
/// Number of nodes in this subtree, excluding this node.
38
38
var descendantCount : Int
39
+ /// Whether the tree contained by this layout has any missing or unexpected nodes.
40
+ var hasError : Bool
39
41
}
40
42
41
43
fileprivate var payload : Payload
@@ -172,6 +174,13 @@ extension RawSyntax {
172
174
kind. isUnknown
173
175
}
174
176
177
+ var hasError : Bool {
178
+ switch rawData. payload {
179
+ case . materializedToken( _) : return self . presence == . missing
180
+ case . layout( let dat) : return dat. hasError
181
+ }
182
+ }
183
+
175
184
/// Child nodes.
176
185
var children : RawSyntaxBuffer {
177
186
switch rawData. payload {
@@ -736,9 +745,20 @@ extension RawSyntax {
736
745
arena: SyntaxArena
737
746
) -> RawSyntax {
738
747
validateLayout ( layout: layout, as: kind)
748
+ var hasError = false
749
+ if kind == . unexpectedNodes || kind. isMissing {
750
+ hasError = true
751
+ } else {
752
+ for node in layout {
753
+ if let node = node, node. hasError {
754
+ hasError = true
755
+ break
756
+ }
757
+ }
758
+ }
739
759
let payload = RawSyntaxData . Layout (
740
760
kind: kind, layout: layout,
741
- byteLength: byteLength, descendantCount: descendantCount)
761
+ byteLength: byteLength, descendantCount: descendantCount, hasError : hasError )
742
762
return RawSyntax ( arena: arena, payload: . layout( payload) )
743
763
}
744
764
Original file line number Diff line number Diff line change @@ -173,6 +173,11 @@ public extension SyntaxProtocol {
173
173
return raw. kind. isUnknown
174
174
}
175
175
176
+ /// Whether this tree contains a missing token or unexpected node.
177
+ var hasError : Bool {
178
+ return raw. hasError
179
+ }
180
+
176
181
/// The parent of this syntax node, or `nil` if this node is the root.
177
182
var parent : Syntax ? {
178
183
return data. parent
Original file line number Diff line number Diff line change @@ -49,6 +49,18 @@ internal enum SyntaxKind: CSyntaxKind {
49
49
default: return false
50
50
}
51
51
}
52
+
53
+ var isMissing : Bool {
54
+ switch self {
55
+ % for name in SYNTAX_BASE_KINDS:
56
+ % if name not in [ " Syntax " , " SyntaxCollection " ] :
57
+ case . missing${ name} : return true
58
+ % end
59
+ % end
60
+ case . missing: return true
61
+ default: return false
62
+ }
63
+ }
52
64
}
53
65
54
66
extension SyntaxKind {
Original file line number Diff line number Diff line change @@ -339,6 +339,18 @@ internal enum SyntaxKind: CSyntaxKind {
339
339
default : return false
340
340
}
341
341
}
342
+
343
+ var isMissing : Bool {
344
+ switch self {
345
+ case . missingDecl: return true
346
+ case . missingExpr: return true
347
+ case . missingPattern: return true
348
+ case . missingStmt: return true
349
+ case . missingType: return true
350
+ case . missing: return true
351
+ default : return false
352
+ }
353
+ }
342
354
}
343
355
344
356
extension SyntaxKind {
Original file line number Diff line number Diff line change
1
+ //===--- SyntaxTests.swift ------------------------------------------------===//
2
+ //
3
+ // This source file is part of the Swift.org open source project
4
+ //
5
+ // Copyright (c) 2014 - 2022 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 XCTest
14
+ import SwiftSyntax
15
+
16
+ public class SyntaxTests : XCTestCase {
17
+
18
+ public func testHasError( ) {
19
+ XCTAssertTrue ( TokenSyntax . funcKeyword ( presence: . missing) . hasError)
20
+ XCTAssertFalse ( TokenSyntax . funcKeyword ( presence: . present) . hasError)
21
+ XCTAssertTrue ( UnexpectedNodesSyntax ( [ ] ) . hasError)
22
+ XCTAssertTrue ( MissingExprSyntax ( ) . hasError)
23
+ XCTAssertFalse ( CodeBlockItemListSyntax ( [ ] ) . hasError)
24
+
25
+ XCTAssertTrue ( TokenListSyntax ( [ TokenSyntax . funcKeyword ( presence: . missing) ] ) . hasError)
26
+ XCTAssertFalse ( TokenListSyntax ( [ TokenSyntax . funcKeyword ( presence: . present) ] ) . hasError)
27
+ }
28
+ }
You can’t perform that action at this time.
0 commit comments