11
11
//===----------------------------------------------------------------------===//
12
12
13
13
#if swift(>=6)
14
+ private import _SwiftSyntaxCShims
14
15
public import SwiftSyntaxMacros
15
16
#else
17
+ @_implementationOnly import _SwiftSyntaxCShims
16
18
import SwiftSyntaxMacros
17
19
#endif
18
20
@@ -23,6 +25,8 @@ public enum PluginFeature: String {
23
25
}
24
26
25
27
/// A type that provides the actual plugin functions.
28
+ ///
29
+ /// Note that it's an implementation's responsibility to cache the API results as needed.
26
30
@_spi ( PluginMessage)
27
31
public protocol PluginProvider {
28
32
/// Resolve macro type by the module name and the type name.
@@ -64,50 +68,60 @@ struct HostCapability {
64
68
var hasExpandMacroResult : Bool { protocolVersion >= 5 }
65
69
}
66
70
67
- /// 'CompilerPluginMessageHandler ' is a type that listens to the message
68
- /// connection and dispatches them to the actual plugin provider , then send back
71
+ /// 'CompilerPluginMessageListener ' is a type that listens to the message
72
+ /// connection, delegate them to the message handler , then send back
69
73
/// the response.
70
74
///
71
75
/// The low level connection and the provider is injected by the client.
72
76
@_spi ( PluginMessage)
73
- public class CompilerPluginMessageHandler < Connection: MessageConnection , Provider: PluginProvider > {
77
+ public class CompilerPluginMessageListener < Connection: MessageConnection , Provider: PluginProvider > {
74
78
/// Message channel for bidirectional communication with the plugin host.
75
79
let connection : Connection
76
80
77
- /// Object to provide actual plugin functions.
78
- let provider : Provider
79
-
80
- /// Plugin host capability
81
- var hostCapability : HostCapability
81
+ let handler : CompilerPluginMessageHandler < Provider >
82
82
83
83
public init ( connection: Connection , provider: Provider ) {
84
84
self . connection = connection
85
- self . provider = provider
86
- self . hostCapability = HostCapability ( )
87
- }
88
- }
89
-
90
- extension CompilerPluginMessageHandler {
91
- func sendMessage( _ message: PluginToHostMessage ) throws {
92
- try connection. sendMessage ( message)
93
- }
94
-
95
- func waitForNextMessage( ) throws -> HostToPluginMessage ? {
96
- try connection. waitForNextMessage ( HostToPluginMessage . self)
85
+ self . handler = CompilerPluginMessageHandler ( provider: provider)
97
86
}
98
87
99
88
/// Run the main message listener loop.
100
89
/// Returns when the message connection was closed.
101
- /// Throws an error when it failed to send/receive the message, or failed
102
- /// to serialize/deserialize the message.
103
- public func main( ) throws {
104
- while let message = try self . waitForNextMessage ( ) {
105
- try handleMessage ( message)
90
+ ///
91
+ /// On internal errors, such as I/O errors or JSON serialization errors, print
92
+ /// an error message and `exit(1)`
93
+ public func main( ) {
94
+ do {
95
+ while let message = try connection. waitForNextMessage ( HostToPluginMessage . self) {
96
+ let result = handler. handleMessage ( message)
97
+ try connection. sendMessage ( result)
98
+ }
99
+ } catch {
100
+ // Emit a diagnostic and indicate failure to the plugin host,
101
+ // and exit with an error code.
102
+ fputs ( " Internal Error: \( error) \n " , _stderr)
103
+ exit ( 1 )
106
104
}
107
105
}
106
+ }
107
+
108
+ /// 'CompilerPluginMessageHandler' is a type that handle a message and do the
109
+ /// corresponding operation.
110
+ @_spi ( PluginMessage)
111
+ public class CompilerPluginMessageHandler < Provider: PluginProvider > {
112
+ /// Object to provide actual plugin functions.
113
+ let provider : Provider
114
+
115
+ /// Plugin host capability
116
+ var hostCapability : HostCapability
117
+
118
+ public init ( provider: Provider ) {
119
+ self . provider = provider
120
+ self . hostCapability = HostCapability ( )
121
+ }
108
122
109
123
/// Handles a single message received from the plugin host.
110
- fileprivate func handleMessage( _ message: HostToPluginMessage ) throws {
124
+ public func handleMessage( _ message: HostToPluginMessage ) -> PluginToHostMessage {
111
125
switch message {
112
126
case . getCapability( let hostCapability) :
113
127
// Remember the peer capability if provided.
@@ -120,7 +134,7 @@ extension CompilerPluginMessageHandler {
120
134
protocolVersion: PluginMessage . PROTOCOL_VERSION_NUMBER,
121
135
features: provider. features. map ( { $0. rawValue } )
122
136
)
123
- try self . sendMessage ( . getCapabilityResult( capability: capability) )
137
+ return . getCapabilityResult( capability: capability)
124
138
125
139
case . expandFreestandingMacro(
126
140
let macro,
@@ -129,7 +143,7 @@ extension CompilerPluginMessageHandler {
129
143
let expandingSyntax,
130
144
let lexicalContext
131
145
) :
132
- try expandFreestandingMacro (
146
+ return expandFreestandingMacro (
133
147
macro: macro,
134
148
macroRole: macroRole,
135
149
discriminator: discriminator,
@@ -148,7 +162,7 @@ extension CompilerPluginMessageHandler {
148
162
let conformanceListSyntax,
149
163
let lexicalContext
150
164
) :
151
- try expandAttachedMacro (
165
+ return expandAttachedMacro (
152
166
macro: macro,
153
167
macroRole: macroRole,
154
168
discriminator: discriminator,
@@ -176,7 +190,7 @@ extension CompilerPluginMessageHandler {
176
190
)
177
191
)
178
192
}
179
- try self . sendMessage ( . loadPluginLibraryResult( loaded: diags. isEmpty, diagnostics: diags) ) ;
193
+ return . loadPluginLibraryResult( loaded: diags. isEmpty, diagnostics: diags)
180
194
}
181
195
}
182
196
}
0 commit comments