@@ -14,61 +14,62 @@ import SwiftSyntax
14
14
15
15
/// A SyntaxVisitor that searches for nodes that cannot be handled safely.
16
16
fileprivate class SyntaxValidatingVisitor : SyntaxVisitor {
17
- /// Tracks whether an invalid node has been encountered .
18
- var isValidSyntax = true
17
+ /// Stores the start position of the first node that contains invalid syntax .
18
+ var invalidSyntaxStartPosition : AbsolutePosition ?
19
19
20
20
override func visit( _ node: UnknownSyntax ) -> SyntaxVisitorContinueKind {
21
- isValidSyntax = false
21
+ invalidSyntaxStartPosition = node . positionAfterSkippingLeadingTrivia
22
22
return . skipChildren
23
23
}
24
24
25
25
override func visit( _ node: UnknownDeclSyntax ) -> SyntaxVisitorContinueKind {
26
- isValidSyntax = false
26
+ invalidSyntaxStartPosition = node . positionAfterSkippingLeadingTrivia
27
27
return . skipChildren
28
28
}
29
29
30
30
override func visit( _ node: UnknownExprSyntax ) -> SyntaxVisitorContinueKind {
31
- isValidSyntax = false
31
+ invalidSyntaxStartPosition = node . positionAfterSkippingLeadingTrivia
32
32
return . skipChildren
33
33
}
34
34
35
35
override func visit( _ node: UnknownStmtSyntax ) -> SyntaxVisitorContinueKind {
36
- isValidSyntax = false
36
+ invalidSyntaxStartPosition = node . positionAfterSkippingLeadingTrivia
37
37
return . skipChildren
38
38
}
39
39
40
40
override func visit( _ node: UnknownTypeSyntax ) -> SyntaxVisitorContinueKind {
41
- isValidSyntax = false
41
+ invalidSyntaxStartPosition = node . positionAfterSkippingLeadingTrivia
42
42
return . skipChildren
43
43
}
44
44
45
45
override func visit( _ node: UnknownPatternSyntax ) -> SyntaxVisitorContinueKind {
46
- isValidSyntax = false
46
+ invalidSyntaxStartPosition = node . positionAfterSkippingLeadingTrivia
47
47
return . skipChildren
48
48
}
49
49
50
50
override func visit( _ node: NonEmptyTokenListSyntax ) -> SyntaxVisitorContinueKind {
51
- isValidSyntax = false
51
+ invalidSyntaxStartPosition = node . positionAfterSkippingLeadingTrivia
52
52
return . skipChildren
53
53
}
54
54
55
55
override func visit( _ node: AttributeSyntax ) -> SyntaxVisitorContinueKind {
56
56
// The token list is used to collect any unexpected tokens. When it's missing or empty, then
57
57
// there were no unexpected tokens. Otherwise, the attribute is invalid.
58
58
guard node. tokenList? . isEmpty ?? true else {
59
- isValidSyntax = false
59
+ invalidSyntaxStartPosition = node . positionAfterSkippingLeadingTrivia
60
60
return . skipChildren
61
61
}
62
62
return . visitChildren
63
63
}
64
64
}
65
65
66
- /// Returns whether the given syntax contains any nodes which are invalid or unrecognized and
67
- /// cannot be handled safely.
66
+ /// Determines whether the given syntax has any nodes which are invalid or unrecognized, and, if
67
+ /// so, returns the starting position of the first such node. Otherwise, returns nil indicating the
68
+ /// syntax is valid.
68
69
///
69
70
/// - Parameter syntax: The root of a tree of syntax nodes to check for compatibility.
70
- func isSyntaxValidForProcessing ( _ syntax: Syntax ) -> Bool {
71
+ func firstInvalidSyntaxPosition ( in syntax: Syntax ) -> AbsolutePosition ? {
71
72
let visitor = SyntaxValidatingVisitor ( )
72
73
visitor. walk ( syntax)
73
- return visitor. isValidSyntax
74
+ return visitor. invalidSyntaxStartPosition
74
75
}
0 commit comments