1313// https://github.com/apple/swift-package-manager/blob/main/Sources/PackagePlugin/Plugin.swift
1414
1515import SwiftSyntaxMacros
16+ @_implementationOnly import SwiftCompilerPluginMessageHandling
1617
1718@_implementationOnly import Foundation
1819#if os(Windows)
@@ -61,6 +62,37 @@ public protocol CompilerPlugin {
6162 var providingMacros : [ Macro . Type ] { get }
6263}
6364
65+ extension CompilerPlugin {
66+ func resolveMacro( moduleName: String , typeName: String ) -> Macro . Type ? {
67+ let qualifedName = " \( moduleName) . \( typeName) "
68+
69+ for type in providingMacros {
70+ // FIXME: Is `String(reflecting:)` stable?
71+ // Getting the module name and type name should be more robust.
72+ let name = String ( reflecting: type)
73+ if name == qualifedName {
74+ return type
75+ }
76+ }
77+ return nil
78+ }
79+
80+ // @testable
81+ public func _resolveMacro( moduleName: String , typeName: String ) -> Macro . Type ? {
82+ resolveMacro ( moduleName: moduleName, typeName: typeName)
83+ }
84+ }
85+
86+ struct MacroProviderAdapter < Plugin: CompilerPlugin > : PluginProvider {
87+ let plugin : Plugin
88+ init ( plugin: Plugin ) {
89+ self . plugin = plugin
90+ }
91+ func resolveMacro( moduleName: String , typeName: String ) -> Macro . Type ? {
92+ plugin. resolveMacro ( moduleName: moduleName, typeName: typeName)
93+ }
94+ }
95+
6496extension CompilerPlugin {
6597
6698 /// Main entry point of the plugin — sets up a communication channel with
@@ -105,18 +137,17 @@ extension CompilerPlugin {
105137 #endif
106138
107139 // Open a message channel for communicating with the plugin host.
108- pluginHostConnection = PluginHostConnection (
140+ let connection = PluginHostConnection (
109141 inputStream: FileHandle ( fileDescriptor: inputFD) ,
110142 outputStream: FileHandle ( fileDescriptor: outputFD)
111143 )
112144
113145 // Handle messages from the host until the input stream is closed,
114146 // indicating that we're done.
115- let instance = Self ( )
147+ let provider = MacroProviderAdapter ( plugin: Self ( ) )
148+ let impl = CompilerPluginMessageHandler ( connection: connection, provider: provider)
116149 do {
117- while let message = try pluginHostConnection. waitForNextMessage ( ) {
118- try instance. handleMessage ( message)
119- }
150+ try impl. main ( )
120151 } catch {
121152 // Emit a diagnostic and indicate failure to the plugin host,
122153 // and exit with an error code.
@@ -135,46 +166,13 @@ extension CompilerPlugin {
135166 if let cStr = strerror ( errno) { return String ( cString: cStr) }
136167 return String ( describing: errno)
137168 }
138-
139- /// Handles a single message received from the plugin host.
140- fileprivate func handleMessage( _ message: HostToPluginMessage ) throws {
141- switch message {
142- case . getCapability:
143- try pluginHostConnection. sendMessage (
144- . getCapabilityResult( capability: PluginMessage . capability)
145- )
146- break
147-
148- case . expandFreestandingMacro( let macro, let discriminator, let expandingSyntax) :
149- try expandFreestandingMacro (
150- macro: macro,
151- discriminator: discriminator,
152- expandingSyntax: expandingSyntax
153- )
154-
155- case . expandAttachedMacro( let macro, let macroRole, let discriminator, let attributeSyntax, let declSyntax, let parentDeclSyntax) :
156- try expandAttachedMacro (
157- macro: macro,
158- macroRole: macroRole,
159- discriminator: discriminator,
160- attributeSyntax: attributeSyntax,
161- declSyntax: declSyntax,
162- parentDeclSyntax: parentDeclSyntax
163- )
164- }
165- }
166169}
167170
168- /// Message channel for bidirectional communication with the plugin host.
169- internal fileprivate( set) var pluginHostConnection : PluginHostConnection !
170-
171- typealias PluginHostConnection = MessageConnection < PluginToHostMessage , HostToPluginMessage >
172-
173- internal struct MessageConnection < TX, RX> where TX: Encodable , RX: Decodable {
171+ internal struct PluginHostConnection : MessageConnection {
174172 let inputStream : FileHandle
175173 let outputStream : FileHandle
176174
177- func sendMessage( _ message: TX ) throws {
175+ func sendMessage< TX : Encodable > ( _ message: TX ) throws {
178176 // Encode the message as JSON.
179177 let payload = try JSONEncoder ( ) . encode ( message)
180178
@@ -188,7 +186,7 @@ internal struct MessageConnection<TX, RX> where TX: Encodable, RX: Decodable {
188186 try outputStream. _write ( contentsOf: payload)
189187 }
190188
191- func waitForNextMessage( ) throws -> RX ? {
189+ func waitForNextMessage< RX : Decodable > ( _ ty : RX . Type ) throws -> RX ? {
192190 // Read the header (a 64-bit length field in little endian byte order).
193191 guard
194192 let header = try inputStream. _read ( upToCount: 8 ) ,
0 commit comments