Skip to content

[Macros] Introduce CompilerPluginMessageListener #2301

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Apr 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Sources/SwiftCompilerPlugin/CompilerPlugin.swift
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ extension CompilerPlugin {
// Handle messages from the host until the input stream is closed,
// indicating that we're done.
let provider = MacroProviderAdapter(plugin: Self())
let impl = CompilerPluginMessageHandler(connection: connection, provider: provider)
let impl = CompilerPluginMessageListener(connection: connection, provider: provider)
do {
try impl.main()
} catch {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,50 +64,52 @@ struct HostCapability {
var hasExpandMacroResult: Bool { protocolVersion >= 5 }
}

/// 'CompilerPluginMessageHandler' is a type that listens to the message
/// connection and dispatches them to the actual plugin provider, then send back
/// 'CompilerPluginMessageListener' is a type that listens to the message
/// connection, delegate them to the message handler, then send back
/// the response.
///
/// The low level connection and the provider is injected by the client.
@_spi(PluginMessage)
public class CompilerPluginMessageHandler<Connection: MessageConnection, Provider: PluginProvider> {
public class CompilerPluginMessageListener<Connection: MessageConnection, Provider: PluginProvider> {
/// Message channel for bidirectional communication with the plugin host.
let connection: Connection

/// Object to provide actual plugin functions.
let provider: Provider

/// Plugin host capability
var hostCapability: HostCapability
let handler: CompilerPluginMessageHandler<Provider>

public init(connection: Connection, provider: Provider) {
self.connection = connection
self.provider = provider
self.hostCapability = HostCapability()
}
}

extension CompilerPluginMessageHandler {
func sendMessage(_ message: PluginToHostMessage) throws {
try connection.sendMessage(message)
}

func waitForNextMessage() throws -> HostToPluginMessage? {
try connection.waitForNextMessage(HostToPluginMessage.self)
self.handler = CompilerPluginMessageHandler(provider: provider)
}

/// Run the main message listener loop.
/// Returns when the message connection was closed.
/// Throws an error when it failed to send/receive the message, or failed
/// to serialize/deserialize the message.
public func main() throws {
while let message = try self.waitForNextMessage() {
try handleMessage(message)
while let message = try connection.waitForNextMessage(HostToPluginMessage.self) {
let result = handler.handleMessage(message)
try connection.sendMessage(result)
}
}
}

/// 'CompilerPluginMessageHandler' is a type that handle a message and do the
/// corresponding operation.
@_spi(PluginMessage)
public class CompilerPluginMessageHandler<Provider: PluginProvider> {
/// Object to provide actual plugin functions.
let provider: Provider

/// Plugin host capability
var hostCapability: HostCapability

public init(provider: Provider) {
self.provider = provider
self.hostCapability = HostCapability()
}

/// Handles a single message received from the plugin host.
fileprivate func handleMessage(_ message: HostToPluginMessage) throws {
public func handleMessage(_ message: HostToPluginMessage) -> PluginToHostMessage {
switch message {
case .getCapability(let hostCapability):
// Remember the peer capability if provided.
Expand All @@ -120,7 +122,7 @@ extension CompilerPluginMessageHandler {
protocolVersion: PluginMessage.PROTOCOL_VERSION_NUMBER,
features: provider.features.map({ $0.rawValue })
)
try self.sendMessage(.getCapabilityResult(capability: capability))
return .getCapabilityResult(capability: capability)

case .expandFreestandingMacro(
let macro,
Expand All @@ -129,7 +131,7 @@ extension CompilerPluginMessageHandler {
let expandingSyntax,
let lexicalContext
):
try expandFreestandingMacro(
return expandFreestandingMacro(
macro: macro,
macroRole: macroRole,
discriminator: discriminator,
Expand All @@ -148,7 +150,7 @@ extension CompilerPluginMessageHandler {
let conformanceListSyntax,
let lexicalContext
):
try expandAttachedMacro(
return expandAttachedMacro(
macro: macro,
macroRole: macroRole,
discriminator: discriminator,
Expand Down Expand Up @@ -176,7 +178,7 @@ extension CompilerPluginMessageHandler {
)
)
}
try self.sendMessage(.loadPluginLibraryResult(loaded: diags.isEmpty, diagnostics: diags))
return .loadPluginLibraryResult(loaded: diags.isEmpty, diagnostics: diags)
}
}
}
Expand Down
8 changes: 4 additions & 4 deletions Sources/SwiftCompilerPluginMessageHandling/Macros.swift
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ extension CompilerPluginMessageHandler {
discriminator: String,
expandingSyntax: PluginMessage.Syntax,
lexicalContext: [PluginMessage.Syntax]?
) throws {
) -> PluginToHostMessage {
let sourceManager = SourceManager()
let syntax = sourceManager.add(expandingSyntax, foldingWith: .standardOperators)

Expand Down Expand Up @@ -105,7 +105,7 @@ extension CompilerPluginMessageHandler {
// TODO: Remove this when all compilers have 'hasExpandMacroResult'.
response = .expandFreestandingMacroResult(expandedSource: expandedSource, diagnostics: diagnostics)
}
try self.sendMessage(response)
return response
}

/// Expand `@attached(XXX)` macros.
Expand All @@ -119,7 +119,7 @@ extension CompilerPluginMessageHandler {
extendedTypeSyntax: PluginMessage.Syntax?,
conformanceListSyntax: PluginMessage.Syntax?,
lexicalContext: [PluginMessage.Syntax]?
) throws {
) -> PluginToHostMessage {
let sourceManager = SourceManager()
let attributeNode = sourceManager.add(
attributeSyntax,
Expand Down Expand Up @@ -189,7 +189,7 @@ extension CompilerPluginMessageHandler {
} else {
response = .expandAttachedMacroResult(expandedSources: expandedSources, diagnostics: diagnostics)
}
try self.sendMessage(response)
return response
}
}

Expand Down