13
13
import SwiftDiagnostics
14
14
import SwiftSyntax
15
15
16
- protocol ASTGenError : DiagnosticMessage { }
16
+ extension ASTGenVisitor {
17
+ /// Emits the given ASTGen diagnostic via the C++ diagnostic engine.
18
+ func diagnose( _ message: ASTGenDiagnostic , highlights: [ Syntax ] ? = nil , notes: [ Note ] = [ ] , fixIts: [ FixIt ] = [ ] ) {
19
+ self . diagnose ( Diagnostic (
20
+ node: message. node,
21
+ message: message,
22
+ highlights: highlights,
23
+ notes: notes,
24
+ fixIts: fixIts
25
+ ) )
26
+ }
17
27
18
- extension ASTGenError {
19
- var diagnosticID : MessageID {
20
- MessageID ( domain: " ASTGen " , id: " \( Self . self) " )
28
+ /// Emits the given diagnostic via the C++ diagnostic engine.
29
+ func diagnose( _ diagnostic: Diagnostic ) {
30
+ emitDiagnostic (
31
+ diagnosticEngine: self . diagnosticEngine,
32
+ sourceFileBuffer: self . base,
33
+ diagnostic: diagnostic,
34
+ diagnosticSeverity: diagnostic. diagMessage. severity
35
+ )
21
36
}
22
37
23
- var severity : DiagnosticSeverity { . error }
38
+ /// Emits the given diagnostics via the C++ diagnostic engine.
39
+ func diagnoseAll( _ diagnostics: [ Diagnostic ] ) {
40
+ diagnostics. forEach ( diagnose)
41
+ }
24
42
}
25
43
26
- /// An error emitted when a token is of an unexpected kind.
27
- struct UnexpectedTokenKindError : ASTGenError {
28
- let token : TokenSyntax
29
- private let parent : Syntax
44
+ // Extract messageID from a string, particularly a function name.
45
+ private func baseName( _ name: String ) -> String {
46
+ if let idx = name. firstIndex ( of: " ( " ) {
47
+ return String ( name [ ..< idx] )
48
+ }
49
+ return name
50
+ }
30
51
31
- init ( token: TokenSyntax ) {
32
- guard let parent = token. parent else {
33
- preconditionFailure ( " Expected a child (not a root) token " )
34
- }
52
+ struct ASTGenDiagnostic : DiagnosticMessage {
53
+ var node : Syntax
54
+ var message : String
55
+ var severity : DiagnosticSeverity
56
+ var messageID : String
35
57
36
- self . token = token
37
- self . parent = parent
58
+ var diagnosticID : MessageID {
59
+ MessageID ( domain : " ASTGen " , id : messageID )
38
60
}
39
61
40
- var message : String {
41
- return """
42
- unexpected token kind for token:
43
- \( self . token. debugDescription)
44
- in parent:
45
- \( self . parent. debugDescription ( indentString: " " ) )
46
- """
62
+ init ( node: some SyntaxProtocol , message: String , severity: DiagnosticSeverity = . error, messageID: String ) {
63
+ self . node = Syntax ( node)
64
+ self . message = message
65
+ self . severity = severity
66
+ self . messageID = messageID
67
+ }
68
+
69
+ fileprivate init ( node: some SyntaxProtocol , message: String , severity: DiagnosticSeverity = . error, function: String = #function) {
70
+ // Extract messageID from the function name.
71
+ let messageID : String = String ( function. prefix ( while: { $0 != " ( " } ) )
72
+ self . init ( node: node, message: message, severity: severity, messageID: messageID)
47
73
}
48
74
}
49
75
50
- /// An error emitted when an optional child token is unexpectedly nil.
51
- struct MissingChildTokenError : ASTGenError {
52
- let parent : Syntax
53
- let kindOfTokenMissing : TokenKind
76
+ extension ASTGenDiagnostic {
77
+ /// An error emitted when a token is of an unexpected kind.
78
+ static func unexpectedTokenKind( token: TokenSyntax ) -> Self {
79
+ guard let parent = token. parent else {
80
+ preconditionFailure ( " Expected a child (not a root) token " )
81
+ }
54
82
55
- init ( parent: some SyntaxProtocol , kindOfTokenMissing: TokenKind ) {
56
- self . parent = Syntax ( parent)
57
- self . kindOfTokenMissing = kindOfTokenMissing
83
+ return Self (
84
+ node: token,
85
+ message: """
86
+ unexpected token kind for token:
87
+ \( token. debugDescription)
88
+ in parent:
89
+ \( parent. debugDescription ( indentString: " " ) )
90
+ """
91
+ )
58
92
}
59
93
60
- var message : String {
61
- """
62
- missing child token of kind ' \( self . kindOfTokenMissing) ' in:
63
- \( parent. debugDescription ( indentString: " " ) )
64
- """
94
+ /// An error emitted when an optional child token is unexpectedly nil.
95
+ static func missingChildToken( parent: some SyntaxProtocol , kindOfTokenMissing: TokenKind ) -> Self {
96
+ Self (
97
+ node: parent,
98
+ message: """
99
+ missing child token of kind ' \( kindOfTokenMissing) ' in:
100
+ \( parent. debugDescription ( indentString: " " ) )
101
+ """
102
+ )
65
103
}
66
- }
67
104
68
- /// An error emitted when a syntax collection entry is encountered that is considered a duplicate of a previous entry
69
- /// per the language grammar.
70
- struct DuplicateSyntaxError : ASTGenError {
71
- let duplicate : Syntax
72
- let original : Syntax
73
-
74
- init ( duplicate: some SyntaxProtocol , original: some SyntaxProtocol ) {
105
+ /// An error emitted when a syntax collection entry is encountered that is
106
+ /// considered a duplicate of a previous entry per the language grammar.
107
+ static func duplicateSyntax( duplicate: some SyntaxProtocol , original: some SyntaxProtocol ) -> Self {
75
108
precondition ( duplicate. kind == original. kind, " Expected duplicate and original to be of same kind " )
76
109
77
110
guard let duplicateParent = duplicate. parent, let originalParent = original. parent,
@@ -80,42 +113,28 @@ struct DuplicateSyntaxError: ASTGenError {
80
113
preconditionFailure ( " Expected a shared syntax collection parent " )
81
114
}
82
115
83
- self . duplicate = Syntax ( duplicate)
84
- self . original = Syntax ( original)
85
- }
86
-
87
- var message : String {
88
- """
89
- unexpected duplicate syntax in list:
90
- \( duplicate. debugDescription ( indentString: " " ) )
91
- previous syntax:
92
- \( original. debugDescription ( indentString: " " ) )
93
- """
94
- }
95
- }
96
-
97
- struct NonTrivialPatternForAccessorError : ASTGenError {
98
- var message : String {
99
- " getter/setter can only be defined for a single variable "
116
+ return Self (
117
+ node: duplicate,
118
+ message: """
119
+ unexpected duplicate syntax in list:
120
+ \( duplicate. debugDescription ( indentString: " " ) )
121
+ previous syntax:
122
+ \( original. debugDescription ( indentString: " " ) )
123
+ """
124
+ )
100
125
}
101
- }
102
126
103
- struct UnknownAccessorSpecifierError : ASTGenError {
104
- var specifier : TokenSyntax
105
- init ( _ specifier: TokenSyntax ) {
106
- self . specifier = specifier
127
+ static func nonTrivialPatternForAccessor( _ pattern: some SyntaxProtocol ) -> Self {
128
+ Self (
129
+ node: pattern,
130
+ message: " getter/setter can only be defined for a single variable "
131
+ )
107
132
}
108
133
109
- var message : String {
110
- " unknown accessor specifier ' \( specifier. text) ' "
134
+ static func unknownAccessorSpecifier( _ specifier: TokenSyntax ) -> Self {
135
+ Self (
136
+ node: specifier,
137
+ message: " unknown accessor specifier ' \( specifier. text) ' "
138
+ )
111
139
}
112
140
}
113
-
114
- struct RegexParserError : ASTGenError {
115
- var message : String
116
- init ( _ message: String ) {
117
- self . message = message
118
- }
119
-
120
- var severity : DiagnosticSeverity { . error }
121
- }
0 commit comments